RESTRICT AUTOMERGE

This change is the union of
I2aaab1903dee54190338f7b6e49888aa51437108 and I58834636e092f992e403342e36b475dc60e8f20a

Original CL descriptions:

*** I2aaab1903dee54190338f7b6e49888aa51437108
Block TYPE_PRESENTATION windows on default display

... and any other display that isn't considered a public presentation
display, as per Display.isPublicPresentation()

*** I58834636e092f992e403342e36b475dc60e8f20a
Use TYPE_PRIVATE_PRESENTATION for private presentations

Detect if the Presenation is targeting a private virtual display, and if they
are use the windowType TYPE_PRIVATE_PRESENTATION.
***

Bug: 141745510
Test: atest CtsWindowManagerDeviceTestCases:android.server.wm.PresentationTest CtsDisplayTestCases:android.display.cts.VirtualDisplayTest

Change-Id: I9f1c4b140ab4bc6183151aafc5501e8648fbc3fa
diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java
index cb72d4d..36c42e1 100644
--- a/core/java/android/app/Presentation.java
+++ b/core/java/android/app/Presentation.java
@@ -19,6 +19,7 @@
 import static android.content.Context.DISPLAY_SERVICE;
 import static android.content.Context.WINDOW_SERVICE;
 import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
+import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
 
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
@@ -26,18 +27,18 @@
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
 import android.os.Binder;
+import android.os.Handler;
 import android.os.IBinder;
+import android.os.Message;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.TypedValue;
 import android.view.ContextThemeWrapper;
 import android.view.Display;
 import android.view.Gravity;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerImpl;
-import android.os.Handler;
-import android.os.Message;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.TypedValue;
 
 /**
  * Base class for presentations.
@@ -116,7 +117,9 @@
  * The display manager keeps track of all displays in the system.  However, not all
  * displays are appropriate for showing presentations.  For example, if an activity
  * attempted to show a presentation on the main display it might obscure its own content
- * (it's like opening a dialog on top of your activity).
+ * (it's like opening a dialog on top of your activity).  Creating a presentation on the main
+ * display will result in {@link android.view.WindowManager.InvalidDisplayException} being thrown
+ * when invoking {@link #show()}.
  * </p><p>
  * Here's how to identify suitable displays for showing presentations using
  * {@link DisplayManager#getDisplays(String)} and the
@@ -189,12 +192,16 @@
         mDisplay = display;
         mDisplayManager = (DisplayManager)getContext().getSystemService(DISPLAY_SERVICE);
 
+        final int windowType =
+                (display.getFlags() & Display.FLAG_PRIVATE) != 0 ? TYPE_PRIVATE_PRESENTATION
+                        : TYPE_PRESENTATION;
+
         final Window w = getWindow();
         final WindowManager.LayoutParams attr = w.getAttributes();
         attr.token = mToken;
         w.setAttributes(attr);
         w.setGravity(Gravity.FILL);
-        w.setType(TYPE_PRESENTATION);
+        w.setType(windowType);
         setCanceledOnTouchOutside(false);
     }
 
@@ -243,7 +250,7 @@
     /**
      * Inherited from {@link Dialog#show}. Will throw
      * {@link android.view.WindowManager.InvalidDisplayException} if the specified secondary
-     * {@link Display} can't be found.
+     * {@link Display} can't be found or if it does not have {@link Display#FLAG_PRESENTATION} set.
      */
     @Override
     public void show() {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 529936a..a9f157d 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -61,6 +61,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
@@ -1297,6 +1298,13 @@
                 return WindowManagerGlobal.ADD_PERMISSION_DENIED;
             }
 
+            if (type == TYPE_PRESENTATION && !displayContent.getDisplay().isPublicPresentation()) {
+                Slog.w(TAG_WM,
+                        "Attempted to add presentation window to a non-suitable display.  "
+                                + "Aborting.");
+                return WindowManagerGlobal.ADD_INVALID_DISPLAY;
+            }
+
             AppWindowToken atoken = null;
             final boolean hasParent = parentWindow != null;
             // Use existing parent window token for child windows since they go in the same token