STS test for Android Security CVE-2021-0339

Test: sts-tradefed run sts-engbuild-no-spl-lock -m CtsSecurityTestCases -t android.security.cts.CVE_2021_0339
Bug: 175817167
Bug: 145728687
Change-Id: I9c879729d60446812d99b812a213067970064d94
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index ad23b07..a8cf61a 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -102,6 +102,25 @@
                 <data android:mimeType="application/vnd.android.package-archive" />
             </intent-filter>
         </receiver>
+
+        <activity android:name="android.security.cts.CVE_2021_0339$FirstActivity"
+             android:label="TAT Anim1"
+             android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+
+        <activity android:name="android.security.cts.CVE_2021_0339$SecondActivity"
+             android:label="TAT Anim2"
+             android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/security/res/anim/translate1.xml b/tests/tests/security/res/anim/translate1.xml
new file mode 100644
index 0000000..e8c562e
--- /dev/null
+++ b/tests/tests/security/res/anim/translate1.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<translate
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:fromYDelta="0%"
+    android:toYDelta="-100%"
+    android:interpolator="@android:anim/linear_interpolator"
+    android:duration="6000" />
diff --git a/tests/tests/security/res/anim/translate2.xml b/tests/tests/security/res/anim/translate2.xml
new file mode 100644
index 0000000..7156c56
--- /dev/null
+++ b/tests/tests/security/res/anim/translate2.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<translate
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:fromYDelta="100%"
+    android:toYDelta="0%"
+    android:interpolator="@android:anim/linear_interpolator"
+    android:duration="6000" />
diff --git a/tests/tests/security/src/android/security/cts/CVE_2021_0339.java b/tests/tests/security/src/android/security/cts/CVE_2021_0339.java
new file mode 100644
index 0000000..66eadad
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/CVE_2021_0339.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import static org.junit.Assert.assertTrue;
+import android.test.AndroidTestCase;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.platform.test.annotations.SecurityTest;
+import android.os.SystemClock;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+import android.util.Log;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SecurityTest
+@RunWith(AndroidJUnit4.class)
+public class CVE_2021_0339 {
+
+    static final String TAG = CVE_2021_0339.class.getSimpleName();
+    private static final String SECURITY_CTS_PACKAGE_NAME = "android.security.cts";
+    static final int MAX_TRANSITION_DURATION_MS = 3000;
+    static final int TIME_MEASUREMENT_DELAY_MS = 150;
+    public static boolean testCompleted;
+
+    public FirstActivity fActivity;
+    public SecondActivity sActivity;
+
+    private void launchActivity(Class<? extends Activity> clazz) {
+        final Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        final Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setClassName(SECURITY_CTS_PACKAGE_NAME, clazz.getName());
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        context.startActivity(intent);
+    }
+
+    /**
+     * b/175817167
+     */
+    @Test
+    @SecurityTest
+    public void testPocCVE_2021_0339() throws Exception {
+
+        Log.d(TAG, "test start");
+        testCompleted = false;
+        launchActivity(FirstActivity.class);
+
+        //wait for SecondActivity animation to complete
+        synchronized(CVE_2021_0339.class){
+          if(!testCompleted)
+            CVE_2021_0339.class.wait();
+        }
+        Log.d(TAG, "test completed");
+
+        //A duration of a transition from "FirstActivity" to "Second Activity"
+        //is set in this test to 6000 ms
+        // (res/anim/translate1.xml and res/anim/translate2.xml)
+        //The fix is supposed to limit the duration to 3000 ms
+        assertTrue(SecondActivity.duration < MAX_TRANSITION_DURATION_MS +
+          TIME_MEASUREMENT_DELAY_MS);
+    }
+
+    public static class FirstActivity extends Activity {
+
+      @Override
+      public void onEnterAnimationComplete() {
+        super.onEnterAnimationComplete();
+        Intent intent = new Intent(this, SecondActivity.class);
+        intent.putExtra("STARTED_TIMESTAMP", SystemClock.uptimeMillis());
+        startActivity(intent);
+        overridePendingTransition(R.anim.translate2,R.anim.translate1);
+        Log.d(TAG,this.getLocalClassName()+" onEnterAnimationComplete()");
+      }
+    }
+
+    public static class SecondActivity extends Activity{
+      public static int duration = 0;
+
+      @Override
+      public void onEnterAnimationComplete() {
+        super.onEnterAnimationComplete();
+        long completedTs = SystemClock.uptimeMillis();
+        long startedTs = getIntent().getLongExtra("STARTED_TIMESTAMP", 0);
+        duration = (int)(completedTs - startedTs);
+        Log.d(TAG, this.getLocalClassName()
+          + " onEnterAnimationComplete() duration=" + Long.toString(duration));
+
+        //Notify main thread that the test is completed
+        synchronized(CVE_2021_0339.class){
+          CVE_2021_0339.testCompleted = true;
+          CVE_2021_0339.class.notifyAll();
+        }
+      }
+    }
+}