CTS testing 2nd activity launch is blocked when activity in bg

This tests the fix for the vulnerability found in the bug linked where an
activity in the bg can fire 2 intents simulteneously to circumvent bg activity
restriction, allowing the 2nd activity to be brought to fg.

Bug: 138583650
Test: 1) atest BackgroundActivityLaunchTest#testSecondActivityBlockedWhenBackgroundActivityLaunch
         Without topic CL built and verify it fails
      2) atest BackgroundActivityLaunchTest#testSecondActivityBlockedWhenBackgroundActivityLaunch
         With topic CL built and verify it passes
Change-Id: I7132e64177112fb3f4d7c7cbfdfdcd04065f10a5
diff --git a/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/Components.java b/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/Components.java
index 56aa319..5023481 100644
--- a/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/Components.java
+++ b/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/Components.java
@@ -46,6 +46,10 @@
                 "START_ACTIVITY_FROM_FG_ACTIVITY_DELAY_MS_EXTRA";
         public static final String START_ACTIVITY_FROM_FG_ACTIVITY_NEW_TASK_EXTRA =
                 "START_ACTIVITY_FROM_FG_ACTIVITY_NEW_TASK_EXTRA";
+        public static final String LAUNCH_INTENTS_EXTRA = "LAUNCH_INTENTS_EXTRA";
+
+        public static final String ACTION_LAUNCH_BACKGROUND_ACTIVITIES =
+                Components.class.getPackage().getName() + ".ACTION_LAUNCH_BACKGROUND_ACTIVITIES";
     }
 
     /** Extra key constants for {@link #APP_A_SEND_PENDING_INTENT_RECEIVER} */
diff --git a/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/ForegroundActivity.java b/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/ForegroundActivity.java
index 377cabf..1413fbc 100644
--- a/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/ForegroundActivity.java
+++ b/tests/framework/base/windowmanager/backgroundactivity/AppA/src/android/server/wm/backgroundactivity/appa/ForegroundActivity.java
@@ -16,17 +16,25 @@
 
 package android.server.wm.backgroundactivity.appa;
 
+import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.ACTION_LAUNCH_BACKGROUND_ACTIVITIES;
 import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.LAUNCH_BACKGROUND_ACTIVITY_EXTRA;
+import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.LAUNCH_INTENTS_EXTRA;
 import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.LAUNCH_SECOND_BACKGROUND_ACTIVITY_EXTRA;
 import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.RELAUNCH_FOREGROUND_ACTIVITY_EXTRA;
 import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.START_ACTIVITY_FROM_FG_ACTIVITY_DELAY_MS_EXTRA;
 import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.START_ACTIVITY_FROM_FG_ACTIVITY_NEW_TASK_EXTRA;
 
 import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.os.Bundle;
+import android.os.Parcelable;
 import android.os.SystemClock;
 
+import java.util.Arrays;
+
 /**
  * Foreground activity that makes AppA as foreground.
  */
@@ -34,6 +42,16 @@
 
     private boolean mRelaunch = false;
 
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // Need to copy as a new array instead of just casting to Intent[] since a new array of
+            // type Parcelable[] is created when deserializing.
+            Parcelable[] intents = intent.getParcelableArrayExtra(LAUNCH_INTENTS_EXTRA);
+            startActivities(Arrays.copyOf(intents, intents.length, Intent[].class));
+        }
+    };
+
     @Override
     public void onCreate(Bundle bundle) {
         super.onCreate(bundle);
@@ -66,6 +84,7 @@
             newIntent.setClass(this, SecondBackgroundActivity.class);
             startActivity(newIntent);
         }
+        registerReceiver(mReceiver, new IntentFilter(ACTION_LAUNCH_BACKGROUND_ACTIVITIES));
     }
 
     @Override
@@ -78,4 +97,10 @@
             startActivity(getIntent());
         }
     }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        unregisterReceiver(mReceiver);
+    }
 }
diff --git a/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java b/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java
index b1a559f..b4d3ee9 100644
--- a/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java
+++ b/tests/framework/base/windowmanager/backgroundactivity/src/android/server/wm/BackgroundActivityLaunchTest.java
@@ -30,7 +30,9 @@
 import static android.server.wm.backgroundactivity.appa.Components.APP_A_SEND_PENDING_INTENT_RECEIVER;
 import static android.server.wm.backgroundactivity.appa.Components.APP_A_SIMPLE_ADMIN_RECEIVER;
 import static android.server.wm.backgroundactivity.appa.Components.APP_A_START_ACTIVITY_RECEIVER;
+import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.ACTION_LAUNCH_BACKGROUND_ACTIVITIES;
 import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.LAUNCH_BACKGROUND_ACTIVITY_EXTRA;
+import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.LAUNCH_INTENTS_EXTRA;
 import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.LAUNCH_SECOND_BACKGROUND_ACTIVITY_EXTRA;
 import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.RELAUNCH_FOREGROUND_ACTIVITY_EXTRA;
 import static android.server.wm.backgroundactivity.appa.Components.ForegroundActivity.START_ACTIVITY_FROM_FG_ACTIVITY_DELAY_MS_EXTRA;
@@ -216,9 +218,7 @@
         pressHomeButton();
         mAmWmState.waitForHomeActivityVisible();
 
-        // Any activity launch will be blocked for 5s because of app switching protection.
-        SystemClock.sleep(7000);
-
+        waitToPreventAppSwitchProtection();
         result = waitForActivityFocused(APP_A_FOREGROUND_ACTIVITY);
         assertFalse("Previously foreground Activity should not be able to relaunch itself", result);
         result = waitForActivityFocused(APP_A_BACKGROUND_ACTIVITY);
@@ -248,9 +248,7 @@
         pressHomeButton();
         mAmWmState.waitForHomeActivityVisible();
 
-        // Any activity launch will be blocked for 5s because of app switching protection.
-        SystemClock.sleep(7000);
-
+        waitToPreventAppSwitchProtection();
         result = waitForActivityFocused(APP_A_FOREGROUND_ACTIVITY);
         assertFalse("Previously foreground Activity should not be able to relaunch itself", result);
         result = waitForActivityFocused(APP_A_BACKGROUND_ACTIVITY);
@@ -276,9 +274,7 @@
         pressHomeButton();
         mAmWmState.waitForHomeActivityVisible();
 
-        // Any activity launch will be blocked for 5s because of app switching protection.
-        SystemClock.sleep(5000);
-
+        waitToPreventAppSwitchProtection();
         result = waitForActivityFocused(APP_A_FOREGROUND_ACTIVITY);
         assertFalse("Previously foreground Activity should not be able to relaunch itself", result);
         assertTaskStack(new ComponentName[]{APP_A_FOREGROUND_ACTIVITY}, APP_A_FOREGROUND_ACTIVITY);
@@ -306,6 +302,39 @@
     }
 
     @Test
+    public void testSecondActivityBlockedWhenBackgroundActivityLaunch() throws Exception {
+        Intent baseActivityIntent = new Intent();
+        baseActivityIntent.setComponent(APP_A_FOREGROUND_ACTIVITY);
+        baseActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(baseActivityIntent);
+        boolean result = waitForActivityFocused(APP_A_FOREGROUND_ACTIVITY);
+        assertTrue("Not able to start foreground activity", result);
+        assertTaskStack(new ComponentName[]{APP_A_FOREGROUND_ACTIVITY}, APP_A_FOREGROUND_ACTIVITY);
+        pressHomeButton();
+        mAmWmState.waitForHomeActivityVisible();
+        waitToPreventAppSwitchProtection();
+
+        // The activity, now in the background, will attempt to start 2 activities in quick
+        // succession
+        Intent broadcastIntent = new Intent(ACTION_LAUNCH_BACKGROUND_ACTIVITIES);
+        Intent bgActivity1 = new Intent();
+        bgActivity1.setComponent(APP_A_BACKGROUND_ACTIVITY);
+        Intent bgActivity2 = new Intent();
+        bgActivity2.setComponent(APP_A_SECOND_BACKGROUND_ACTIVITY);
+        broadcastIntent.putExtra(LAUNCH_INTENTS_EXTRA, new Intent[]{bgActivity1, bgActivity2});
+        mContext.sendBroadcast(broadcastIntent);
+
+        // There should be 2 activities in the background (not focused) INITIALIZING
+        result = waitForActivityFocused(APP_A_BACKGROUND_ACTIVITY);
+        assertFalse("Activity should not have been launched in the foreground", result);
+        result = waitForActivityFocused(APP_A_SECOND_BACKGROUND_ACTIVITY);
+        assertFalse("Second activity should not have been launched in the foreground", result);
+        assertTaskStack(
+                new ComponentName[]{APP_A_SECOND_BACKGROUND_ACTIVITY, APP_A_BACKGROUND_ACTIVITY,
+                        APP_A_FOREGROUND_ACTIVITY}, APP_A_FOREGROUND_ACTIVITY);
+    }
+
+    @Test
     public void testPendingIntentActivityBlocked() throws Exception {
         // Cannot start activity by pending intent, as both appA and appB are in background
         sendPendingIntentActivity();
@@ -399,6 +428,11 @@
         assertTaskStack(new ComponentName[]{APP_A_BACKGROUND_ACTIVITY}, APP_A_BACKGROUND_ACTIVITY);
     }
 
+    private void waitToPreventAppSwitchProtection() {
+        // Any activity launch will be blocked for 5s because of app switching protection.
+        SystemClock.sleep(7000);
+    }
+
     private void assertTaskStack(ComponentName[] expectedComponents,
             ComponentName sourceComponent) {
         if (expectedComponents == null) {