Merge "Add system config to specify Multi-Display support" into oc-dev
diff --git a/core/res/res/values-watch/config.xml b/core/res/res/values-watch/config.xml
index ac7b236..98dc4cf 100644
--- a/core/res/res/values-watch/config.xml
+++ b/core/res/res/values-watch/config.xml
@@ -66,4 +66,8 @@
     <!-- The small screens of watch devices makes multi-window support undesireable. -->
     <bool name="config_supportsMultiWindow">false</bool>
     <bool name="config_supportsSplitScreenMultiWindow">false</bool>
+
+    <!-- Disable Multi-Display because of small screen space and lack of external display connection
+         options. -->
+    <bool name="config_supportsMultiDisplay">false</bool>
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 221e308..3dd7ad4 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2651,6 +2651,9 @@
     <!-- True if the device supports split screen as a form of multi-window. -->
     <bool name="config_supportsSplitScreenMultiWindow">true</bool>
 
+    <!-- True if the device supports running activities on secondary displays. -->
+    <bool name="config_supportsMultiDisplay">true</bool>
+
     <!-- True if the device has no home screen. That is a launcher activity
          where the user can launch other applications from.  -->
     <bool name="config_noHomeScreen">false</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index d0057d4..379c376 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -313,6 +313,7 @@
   <java-symbol type="bool" name="config_freeformWindowManagement" />
   <java-symbol type="bool" name="config_supportsMultiWindow" />
   <java-symbol type="bool" name="config_supportsSplitScreenMultiWindow" />
+  <java-symbol type="bool" name="config_supportsMultiDisplay" />
   <java-symbol type="bool" name="config_noHomeScreen" />
   <java-symbol type="bool" name="config_guestUserEphemeral" />
   <java-symbol type="bool" name="config_localDisplaysMirrorContent" />
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3f2fdb0..be5ff80 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1490,6 +1490,7 @@
     boolean mSupportsSplitScreenMultiWindow;
     boolean mSupportsFreeformWindowManagement;
     boolean mSupportsPictureInPicture;
+    boolean mSupportsMultiDisplay;
     boolean mSupportsLeanbackOnly;
     IActivityController mController = null;
     boolean mControllerIsAMonkey = false;
@@ -13827,6 +13828,8 @@
                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
             }
             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
+            mSupportsMultiDisplay = res.getBoolean(
+                    com.android.internal.R.bool.config_supportsMultiDisplay);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 748aa6f..6011418 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -247,6 +247,8 @@
                     return runSupportsMultiwindow(pw);
                 case "supports-split-screen-multi-window":
                     return runSupportsSplitScreenMultiwindow(pw);
+                case "supports-multi-display":
+                    return runSupportsMultiDisplay(pw);
                 case "update-appinfo":
                     return runUpdateApplicationInfo(pw);
                 case "no-home-screen":
@@ -2398,6 +2400,15 @@
         return 0;
     }
 
+    int runSupportsMultiDisplay(PrintWriter pw) throws RemoteException {
+        final Resources res = getResources(pw);
+        if (res == null) {
+            return -1;
+        }
+        pw.println(res.getBoolean(com.android.internal.R.bool.config_supportsMultiDisplay));
+        return 0;
+    }
+
     int runUpdateApplicationInfo(PrintWriter pw) throws RemoteException {
         int userid = UserHandle.parseUserArg(getNextArgRequired());
         ArrayList<String> packages = new ArrayList<>();
@@ -2627,6 +2638,8 @@
             pw.println("      Returns true if the device supports multiwindow.");
             pw.println("  supports-split-screen-multi-window");
             pw.println("      Returns true if the device supports split screen multiwindow.");
+            pw.println("  supports-multi-display");
+            pw.println("      Returns true if the device supports multi-display.");
             pw.println("  suppress-resize-config-changes <true|false>");
             pw.println("      Suppresses configuration changes due to user resizing an activity/task.");
             pw.println("  set-inactive [--user <USER_ID>] <PACKAGE> true|false");
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 3e3fee5..30e33c8 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2782,6 +2782,15 @@
                     + " reparent task=" + task + " to stackId=" + stackId);
         }
 
+        // Ensure that we're not moving a task to a dynamic stack if device doesn't support
+        // multi-display.
+        // TODO(multi-display): Support non-dynamic stacks on secondary displays.
+        // TODO: Check ActivityView after fixing b/35349678.
+        if (StackId.isDynamicStack(stackId) && !mService.mSupportsMultiDisplay) {
+            throw new IllegalArgumentException("Device doesn't support multi-display, can not"
+                    + " reparent task=" + task + " to stackId=" + stackId);
+        }
+
         // Ensure that we aren't trying to move into a freeform stack without freeform
         // support
         if (stackId == FREEFORM_WORKSPACE_STACK_ID && !mService.mSupportsFreeformWindowManagement) {
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index b408569..bb5f588 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -2178,7 +2178,8 @@
             case ASSISTANT_STACK_ID:
                 return r.isAssistantActivity();
             default:
-                if (StackId.isDynamicStack(stackId)) {
+                // TODO: Check ActivityView after fixing b/35349678.
+                if (StackId.isDynamicStack(stackId) && mService.mSupportsMultiDisplay) {
                     return true;
                 }
                 Slog.e(TAG, "isValidLaunchStackId: Unexpected stackId=" + stackId);