Merge cherrypicks of [11834993, 11835120, 11834645, 11834934, 11834935, 11834936, 11834646, 11834647, 11834648, 11834649, 11834650, 11834651, 11834652, 11834653, 11834970, 11834857, 11835121, 11835122, 11835158] into qt-d4-release

Change-Id: I5ed1c9e5f02fa364d954653ad49bca4b53e89c8a
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/core/java/android/os/AppZygote.java b/core/java/android/os/AppZygote.java
index 6daa5b4..66f50e4 100644
--- a/core/java/android/os/AppZygote.java
+++ b/core/java/android/os/AppZygote.java
@@ -90,10 +90,9 @@
     @GuardedBy("mLock")
     private void stopZygoteLocked() {
         if (mZygote != null) {
-            // Close the connection and kill the zygote process. This will not cause
-            // child processes to be killed by itself.
             mZygote.close();
-            Process.killProcess(mZygote.getPid());
+            // use killProcessGroup() here, so we kill all untracked children as well.
+            Process.killProcessGroup(mZygoteUid, mZygote.getPid());
             mZygote = null;
         }
     }
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 2143a0d..643df69 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -1260,6 +1260,7 @@
 
             out.putParcelable(DocumentsContract.EXTRA_RESULT, path);
         } else if (METHOD_GET_DOCUMENT_METADATA.equals(method)) {
+            enforceReadPermissionInner(documentUri, getCallingPackage(), null);
             return getDocumentMetadata(documentId);
         } else {
             throw new UnsupportedOperationException("Method not supported " + method);
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 82c27f0..d03ef8a 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -429,8 +429,16 @@
 
 // Calls POSIX setgroups() using the int[] object as an argument.
 // A nullptr argument is tolerated.
-static void SetGids(JNIEnv* env, jintArray managed_gids, fail_fn_t fail_fn) {
+static void SetGids(JNIEnv* env, jintArray managed_gids, jboolean is_child_zygote,
+                    fail_fn_t fail_fn) {
   if (managed_gids == nullptr) {
+    if (is_child_zygote) {
+      // For child zygotes like webview and app zygote, we want to clear out
+      // any supplemental groups the parent zygote had.
+      if (setgroups(0, NULL) == -1) {
+        fail_fn(CREATE_ERROR("Failed to remove supplementary groups for child zygote"));
+      }
+    }
     return;
   }
 
@@ -1015,7 +1023,7 @@
     }
   }
 
-  SetGids(env, gids, fail_fn);
+  SetGids(env, gids, is_child_zygote, fail_fn);
   SetRLimits(env, rlimits, fail_fn);
 
   if (use_native_bridge) {
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
index 626d0cf..c1de21b 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
@@ -167,7 +167,7 @@
     private void setupTexture(Bitmap bitmap) {
         final int[] tids = new int[1];
 
-        if (bitmap == null) {
+        if (bitmap == null || bitmap.isRecycled()) {
             Log.w(TAG, "setupTexture: invalid bitmap");
             return;
         }
@@ -179,16 +179,20 @@
             return;
         }
 
-        // Bind a named texture to a target.
-        glBindTexture(GL_TEXTURE_2D, tids[0]);
-        // Load the bitmap data and copy it over into the texture object that is currently bound.
-        GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
-        // Use bilinear texture filtering when minification.
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-        // Use bilinear texture filtering when magnification.
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
-        mTextureId = tids[0];
+        try {
+            // Bind a named texture to a target.
+            glBindTexture(GL_TEXTURE_2D, tids[0]);
+            // Load the bitmap data and copy it over into the texture object
+            // that is currently bound.
+            GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
+            // Use bilinear texture filtering when minification.
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+            // Use bilinear texture filtering when magnification.
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+            mTextureId = tids[0];
+        } catch (IllegalArgumentException e) {
+            Log.w(TAG, "Failed uploading texture: " + e.getLocalizedMessage());
+        }
     }
 
     void useTexture() {
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
index 24a4b9e..231779d 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
@@ -86,7 +86,13 @@
         protected Float doInBackground(Bitmap... bitmaps) {
             Bitmap bitmap = bitmaps[0];
             if (bitmap != null) {
-                return new Threshold().compute(bitmap);
+                try {
+                    return new Threshold().compute(bitmap);
+                } catch (RuntimeException e) {
+                    Log.e(TAG, "Failed at computing threshold, color space="
+                            + bitmap.getColorSpace(), e);
+                    return DEFAULT_THRESHOLD;
+                }
             }
             Log.e(TAG, "ThresholdComputeTask: Can't get bitmap");
             return DEFAULT_THRESHOLD;
@@ -116,7 +122,8 @@
             int width = bitmap.getWidth();
             int height = bitmap.getHeight();
 
-            Bitmap grayscale = Bitmap.createBitmap(width, height, bitmap.getConfig());
+            Bitmap grayscale = Bitmap.createBitmap(width, height,
+                    bitmap.getConfig(), false, bitmap.getColorSpace());
             Canvas canvas = new Canvas(grayscale);
             ColorMatrix cm = new ColorMatrix(LUMINOSITY_MATRIX);
             Paint paint = new Paint();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
index c67512c..ffe51ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
@@ -269,7 +269,7 @@
                         0,
                         new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                                 .setData(Uri.fromParts("package", pkg, null)),
-                        0,
+                        PendingIntent.FLAG_IMMUTABLE,
                         null,
                         user);
         Notification.Action action =
@@ -282,7 +282,7 @@
                                 mContext,
                                 0,
                                 new Intent(Intent.ACTION_VIEW).setData(Uri.parse(helpUrl)),
-                                0,
+                                PendingIntent.FLAG_IMMUTABLE,
                                 null,
                                 user)
                         : null;
@@ -303,7 +303,7 @@
                             mContext,
                             0 /* requestCode */,
                             browserIntent,
-                            0 /* flags */,
+                            PendingIntent.FLAG_IMMUTABLE /* flags */,
                             null,
                             user);
             ComponentName aiaComponent = null;
@@ -325,8 +325,8 @@
                             .putExtra(Intent.EXTRA_LONG_VERSION_CODE, appInfo.longVersionCode)
                             .putExtra(Intent.EXTRA_INSTANT_APP_FAILURE, pendingIntent);
 
-            PendingIntent webPendingIntent =
-                    PendingIntent.getActivityAsUser(mContext, 0, goToWebIntent, 0, null, user);
+            PendingIntent webPendingIntent = PendingIntent.getActivityAsUser(mContext, 0,
+                    goToWebIntent, PendingIntent.FLAG_IMMUTABLE, null, user);
             Notification.Action webAction =
                     new Notification.Action.Builder(
                                     null, mContext.getString(R.string.go_to_web), webPendingIntent)
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index bbd2d34..055ee1e 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -383,7 +383,11 @@
             // and then the delayed summary kill will be a no-op.
             final ProcessRecord p = proc;
             mService.mHandler.postDelayed(
-                    () -> killAppImmediateLocked(p, "forced", "killed for invalid state"),
+                    () -> {
+                        synchronized (mService) {
+                            killAppImmediateLocked(p, "forced", "killed for invalid state");
+                        }
+                    },
                     5000L);
         }
     }
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