CTS test for launching to the side.

Bug: 26141281
Bug: 19225708
Change-Id: I2381e5e543a835ddf42f34d6cb00c03bed646cfb
diff --git a/hostsidetests/services/activitymanager/OldAndroidTest.xml b/hostsidetests/services/activitymanager/OldAndroidTest.xml
index 669fe02..ba9d998 100644
--- a/hostsidetests/services/activitymanager/OldAndroidTest.xml
+++ b/hostsidetests/services/activitymanager/OldAndroidTest.xml
@@ -15,5 +15,6 @@
 -->
 <configuration description="CTS package preparer for install/uninstall of the apk used as a test operation target">
     <include name="common-config" />
-    <option name="cts-apk-installer:test-file-name" value="CtsDeviceServicesTestApp.apk" />
+    <!-- This will tell tradefed to install the test apk. -->
+    <option name="cts-apk-installer:test-file-name" value="CtsServicesTestApp.apk" />
 </configuration>
diff --git a/hostsidetests/services/activitymanager/app/AndroidManifest.xml b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
index 027a73d..1998e5f 100755
--- a/hostsidetests/services/activitymanager/app/AndroidManifest.xml
+++ b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
@@ -23,6 +23,10 @@
                 android:resizeable="true"
                 android:supportsPictureInPicture="true"
                 />
+        <activity android:name=".LaunchToSideActivity"
+                android:resizeable="true"
+                android:supportsPictureInPicture="true"
+        />
     </application>
 </manifest>
 
diff --git a/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchToSideActivity.java b/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchToSideActivity.java
new file mode 100644
index 0000000..31c169e
--- /dev/null
+++ b/hostsidetests/services/activitymanager/app/src/android/server/app/LaunchToSideActivity.java
@@ -0,0 +1,24 @@
+package android.server.app;
+
+import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_TO_SIDE;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+public class LaunchToSideActivity extends Activity {
+    private static final String TAG = "LaunchToSide";
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        final Bundle extras = intent.getExtras();
+         if (extras != null && extras.getBoolean("launch_to_the_side")) {
+            Intent newIntent = new Intent("android.settings.SETTINGS");
+            newIntent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_LAUNCH_TO_SIDE);
+            startActivity(newIntent);
+        }
+    }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTests.java
index b31a945..98df5a6 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTests.java
@@ -20,6 +20,7 @@
 import com.android.tradefed.device.CollectingOutputReceiver;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil;
 import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.testtype.DeviceTestCase;
 
@@ -48,10 +49,15 @@
     private static final String TASK_ID_PREFIX = "taskId";
 
     private static final String TEST_ACTIVITY_NAME = "TestActivity";
+    private static final String LAUNCH_TO_SIDE_ACTIVITY_NAME = "LaunchToSideActivity";
 
     private static final String AM_STACK_LIST = "am stack list";
-    private static final String AM_START_ACTIVITY = "am start -n android.server.app/.TestActivity";
-    private static final String AM_FORCE_STOP = "am force-stop android.server.app";
+    private static final String AM_START_TEST_ACTIVITY =
+            "am start -n android.server.app/.TestActivity";
+    private static final String AM_START_LAUNCH_TO_SIDE_ACTIVITY =
+            "am start -n android.server.app/.LaunchToSideActivity";
+    private static final String AM_FORCE_STOP_TEST = "am force-stop android.server.app";
+    private static final String AM_FORCE_STOP_SETTINGS = "com.android.settings";
     private static final String AM_MOVE_TASK = "am stack movetask ";
 
     /**
@@ -70,27 +76,17 @@
     @Override
     protected void tearDown() {
         try {
-            mDevice.executeShellCommand(AM_FORCE_STOP);
+            mDevice.executeShellCommand(AM_FORCE_STOP_TEST);
+            mDevice.executeShellCommand(AM_FORCE_STOP_SETTINGS);
         } catch (DeviceNotAvailableException e) {
         }
     }
 
     public void testStackList() throws Exception {
-        mDevice.executeShellCommand(AM_START_ACTIVITY);
+        mDevice.executeShellCommand(AM_START_TEST_ACTIVITY);
         CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
         mDevice.executeShellCommand(AM_STACK_LIST, outputReceiver);
-        String output = outputReceiver.getOutput();
-        HashSet<Integer> stacks = new HashSet<>();
-        for (String line : output.split("\\n")) {
-            CLog.logAndDisplay(LogLevel.INFO, line);
-            if (line.startsWith(STACK_ID_PREFIX)) {
-                final String sub = line.substring(STACK_ID_PREFIX.length());
-                final int index = sub.indexOf(" ");
-                final int currentStack = Integer.parseInt(sub.substring(0, index));
-                stacks.add(currentStack);
-            } else if (line.startsWith(TASK_ID_PREFIX)) {
-            }
-        }
+        HashSet<Integer> stacks = collectStacks(outputReceiver);
         assertTrue("At least two stacks expected, home and fullscreen.", stacks.size() >= 2);
         assertTrue("Stacks must contain home stack.", stacks.contains(HOME_STACK_ID));
         assertTrue("Stacks must contain fullscreen stack.", stacks.contains(
@@ -107,12 +103,12 @@
         }
     }
 
-    private int getTestActivityTaskId() throws DeviceNotAvailableException {
+    private int getActivityTaskId(String name) throws DeviceNotAvailableException {
         CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
         mDevice.executeShellCommand(AM_STACK_LIST, outputReceiver);
         final String output = outputReceiver.getOutput();
         for (String line : output.split("\\n")) {
-            if (line.contains(TEST_ACTIVITY_NAME)) {
+            if (line.contains(name)) {
                 for (String word : line.split("\\s+")) {
                     if (word.startsWith(TASK_ID_PREFIX)) {
                         final String withColon = word.split("=")[1];
@@ -125,12 +121,36 @@
     }
 
     public void testDockActivity() throws Exception {
-        mDevice.executeShellCommand(AM_START_ACTIVITY);
-        final int taskId = getTestActivityTaskId();
+        mDevice.executeShellCommand(AM_START_TEST_ACTIVITY);
+        final int taskId = getActivityTaskId(TEST_ACTIVITY_NAME);
         final String cmd = AM_MOVE_TASK + taskId + " " + DOCKED_STACK_ID + " true";
         mDevice.executeShellCommand(cmd);
         CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
         mDevice.executeShellCommand(AM_STACK_LIST, outputReceiver);
+        HashSet<Integer> stacks = collectStacks(outputReceiver);
+        assertTrue("At least two stacks expected, home and docked.", stacks.size() >= 2);
+        assertTrue("Stacks must contain home stack.", stacks.contains(HOME_STACK_ID));
+        assertTrue("Stacks must contain docked stack.", stacks.contains(DOCKED_STACK_ID));
+    }
+
+    public void testLaunchToSide() throws Exception {
+        mDevice.executeShellCommand(AM_START_LAUNCH_TO_SIDE_ACTIVITY);
+        final int taskId = getActivityTaskId(LAUNCH_TO_SIDE_ACTIVITY_NAME);
+        final String cmd = AM_MOVE_TASK + taskId + " " + DOCKED_STACK_ID + " true";
+        mDevice.executeShellCommand(cmd);
+        printStacksAndTasks();
+        mDevice.executeShellCommand(AM_START_LAUNCH_TO_SIDE_ACTIVITY
+                + " -f 0x20000000 --ez launch_to_the_side true");
+        CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
+        mDevice.executeShellCommand(AM_STACK_LIST, outputReceiver);
+        HashSet<Integer> stacks = collectStacks(outputReceiver);
+        assertTrue("At least two stacks expected, docked and fullscreen.", stacks.size() >= 2);
+        assertTrue("Stacks must contain fullescreen stack.", stacks.contains(
+                FULLSCREEN_WORKSPACE_STACK_ID));
+        assertTrue("Stacks must contain docked stack.", stacks.contains(DOCKED_STACK_ID));
+    }
+
+    private HashSet<Integer> collectStacks(CollectingOutputReceiver outputReceiver) {
         final String output = outputReceiver.getOutput();
         HashSet<Integer> stacks = new HashSet<>();
         for (String line : output.split("\\n")) {
@@ -142,8 +162,6 @@
                 stacks.add(currentStack);
             }
         }
-        assertTrue("At least two stacks expected, home and docked.", stacks.size() >= 2);
-        assertTrue("Stacks must contain home stack.", stacks.contains(HOME_STACK_ID));
-        assertTrue("Stacks must contain docked stack.", stacks.contains(DOCKED_STACK_ID));
+        return stacks;
     }
 }