Merge cherrypicks of [15624565, 16740079, 20227703, 18029563, 17325442, 20224386, 19697302, 19815423, 19941483, 19970184, 19886856, 20026360, 19949706, 17637345, 20225686, 20013777, 20079399, 20051190, 20105519, 19902682] into sc-platform-release.

Change-Id: I017d87868822a22b3a8547443cea6c8bf17bcb8d
diff --git a/Android.bp b/Android.bp
index 3af2f07..3f7581c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -113,6 +113,7 @@
         ":gatekeeper_aidl",
         ":gsiservice_aidl",
         ":idmap2_aidl",
+        ":guiconstants_aidl",
         ":idmap2_core_aidl",
         ":incidentcompanion_aidl",
         ":inputconstants_aidl",
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 6553b61..748f874 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -124,8 +124,13 @@
     /**
      * The maximum length for text fields in a NotificationChannel. Fields will be truncated at this
      * limit.
+     * @hide
      */
-    private static final int MAX_TEXT_LENGTH = 1000;
+    public static final int MAX_TEXT_LENGTH = 1000;
+    /**
+     * @hide
+     */
+    public static final int MAX_VIBRATION_LENGTH = 1000;
 
     private static final String TAG_CHANNEL = "channel";
     private static final String ATT_NAME = "name";
@@ -284,17 +289,17 @@
      */
     protected NotificationChannel(Parcel in) {
         if (in.readByte() != 0) {
-            mId = in.readString();
+            mId = getTrimmedString(in.readString());
         } else {
             mId = null;
         }
         if (in.readByte() != 0) {
-            mName = in.readString();
+            mName = getTrimmedString(in.readString());
         } else {
             mName = null;
         }
         if (in.readByte() != 0) {
-            mDesc = in.readString();
+            mDesc = getTrimmedString(in.readString());
         } else {
             mDesc = null;
         }
@@ -303,18 +308,22 @@
         mLockscreenVisibility = in.readInt();
         if (in.readByte() != 0) {
             mSound = Uri.CREATOR.createFromParcel(in);
+            mSound = Uri.parse(getTrimmedString(mSound.toString()));
         } else {
             mSound = null;
         }
         mLights = in.readByte() != 0;
         mVibration = in.createLongArray();
+        if (mVibration != null && mVibration.length > MAX_VIBRATION_LENGTH) {
+            mVibration = Arrays.copyOf(mVibration, MAX_VIBRATION_LENGTH);
+        }
         mUserLockedFields = in.readInt();
         mFgServiceShown = in.readByte() != 0;
         mVibrationEnabled = in.readByte() != 0;
         mShowBadge = in.readByte() != 0;
         mDeleted = in.readByte() != 0;
         if (in.readByte() != 0) {
-            mGroup = in.readString();
+            mGroup = getTrimmedString(in.readString());
         } else {
             mGroup = null;
         }
@@ -324,8 +333,8 @@
         mAllowBubbles = in.readInt();
         mImportanceLockedByOEM = in.readBoolean();
         mOriginalImportance = in.readInt();
-        mParentId = in.readString();
-        mConversationId = in.readString();
+        mParentId = getTrimmedString(in.readString());
+        mConversationId = getTrimmedString(in.readString());
         mDemoted = in.readBoolean();
         mImportantConvo = in.readBoolean();
         mDeletedTime = in.readLong();
diff --git a/core/java/android/app/NotificationChannelGroup.java b/core/java/android/app/NotificationChannelGroup.java
index cd6df0b..39e4844 100644
--- a/core/java/android/app/NotificationChannelGroup.java
+++ b/core/java/android/app/NotificationChannelGroup.java
@@ -43,8 +43,9 @@
     /**
      * The maximum length for text fields in a NotificationChannelGroup. Fields will be truncated at
      * this limit.
+     * @hide
      */
-    private static final int MAX_TEXT_LENGTH = 1000;
+    public static final int MAX_TEXT_LENGTH = 1000;
 
     private static final String TAG_GROUP = "channelGroup";
     private static final String ATT_NAME = "name";
@@ -90,13 +91,17 @@
      */
     protected NotificationChannelGroup(Parcel in) {
         if (in.readByte() != 0) {
-            mId = in.readString();
+            mId = getTrimmedString(in.readString());
         } else {
             mId = null;
         }
-        mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         if (in.readByte() != 0) {
-            mDescription = in.readString();
+            mName = getTrimmedString(in.readString());
+        } else {
+            mName = "";
+        }
+        if (in.readByte() != 0) {
+            mDescription = getTrimmedString(in.readString());
         } else {
             mDescription = null;
         }
@@ -120,7 +125,12 @@
         } else {
             dest.writeByte((byte) 0);
         }
-        TextUtils.writeToParcel(mName, dest, flags);
+        if (mName != null) {
+            dest.writeByte((byte) 1);
+            dest.writeString(mName.toString());
+        } else {
+            dest.writeByte((byte) 0);
+        }
         if (mDescription != null) {
             dest.writeByte((byte) 1);
             dest.writeString(mDescription);
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 18c6381..a432b8d 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -1130,7 +1130,9 @@
      * @param intent        The intent of the service which will be providing the data to the
      *                      RemoteViewsAdapter.
      * @param connection    The callback interface to be notified when a connection is made or lost.
-     * @param flags         Flags used for binding to the service
+     * @param flags         Flags used for binding to the service. Currently only
+     *                     {@link Context#BIND_AUTO_CREATE} and
+     *                     {@link Context#BIND_FOREGROUND_SERVICE_WHILE_AWAKE} are supported.
      *
      * @see Context#getServiceDispatcher(ServiceConnection, Handler, int)
      * @hide
diff --git a/core/java/android/service/notification/Condition.java b/core/java/android/service/notification/Condition.java
index 4f324f9..9a2a86a 100644
--- a/core/java/android/service/notification/Condition.java
+++ b/core/java/android/service/notification/Condition.java
@@ -91,6 +91,12 @@
     public final int icon;
 
     /**
+     * The maximum string length for any string contained in this condition.
+     * @hide
+     */
+    public static final int MAX_STRING_LENGTH = 1000;
+
+    /**
      * An object representing the current state of a {@link android.app.AutomaticZenRule}.
      * @param id the {@link android.app.AutomaticZenRule#getConditionId()} of the zen rule
      * @param summary a user visible description of the rule state.
@@ -104,16 +110,19 @@
         if (id == null) throw new IllegalArgumentException("id is required");
         if (summary == null) throw new IllegalArgumentException("summary is required");
         if (!isValidState(state)) throw new IllegalArgumentException("state is invalid: " + state);
-        this.id = id;
-        this.summary = summary;
-        this.line1 = line1;
-        this.line2 = line2;
+        this.id = getTrimmedUri(id);
+        this.summary = getTrimmedString(summary);
+        this.line1 = getTrimmedString(line1);
+        this.line2 = getTrimmedString(line2);
         this.icon = icon;
         this.state = state;
         this.flags = flags;
     }
 
     public Condition(Parcel source) {
+        // This constructor passes all fields directly into the constructor that takes all the
+        // fields as arguments; that constructor will trim each of the input strings to
+        // max length if necessary.
         this((Uri)source.readParcelable(Condition.class.getClassLoader()),
                 source.readString(),
                 source.readString(),
@@ -240,4 +249,25 @@
             return new Condition[size];
         }
     };
+
+    /**
+     * Returns a truncated copy of the string if the string is longer than MAX_STRING_LENGTH.
+     */
+    private static String getTrimmedString(String input) {
+        if (input != null && input.length() > MAX_STRING_LENGTH) {
+            return input.substring(0, MAX_STRING_LENGTH);
+        }
+        return input;
+    }
+
+    /**
+     * Returns a truncated copy of the Uri by trimming the string representation to the maximum
+     * string length.
+     */
+    private static Uri getTrimmedUri(Uri input) {
+        if (input != null && input.toString().length() > MAX_STRING_LENGTH) {
+            return Uri.parse(getTrimmedString(input.toString()));
+        }
+        return input;
+    }
 }
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 3517389..1e29092 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -41,6 +41,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.gui.DropInputMode;
 import android.hardware.HardwareBuffer;
 import android.hardware.display.DeviceProductInfo;
 import android.hardware.display.DisplayedContentSample;
@@ -150,7 +151,8 @@
             float childRelativeTop, float childRelativeRight, float childRelativeBottom);
     private static native void nativeSetTrustedOverlay(long transactionObj, long nativeObject,
             boolean isTrustedOverlay);
-
+    private static native void nativeSetDropInputMode(
+            long transactionObj, long nativeObject, int flags);
     private static native boolean nativeClearContentFrameStats(long nativeObject);
     private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats);
     private static native boolean nativeClearAnimationFrameStats();
@@ -3428,6 +3430,17 @@
         }
 
         /**
+         * Sets the input event drop mode on this SurfaceControl and its children. The caller must
+         * hold the ACCESS_SURFACE_FLINGER permission. See {@code InputEventDropMode}.
+         * @hide
+         */
+        public Transaction setDropInputMode(SurfaceControl sc, @DropInputMode int mode) {
+            checkPreconditions(sc);
+            nativeSetDropInputMode(mNativeObject, sc.mNativeObject, mode);
+            return this;
+        }
+
+        /**
          * @hide
          */
         public void sanitize() {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index f831caa..4cb258d 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -868,6 +868,13 @@
     transaction->setFixedTransformHint(ctrl, transformHint);
 }
 
+static void nativeSetDropInputMode(JNIEnv* env, jclass clazz, jlong transactionObj,
+                                   jlong nativeObject, jint mode) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
+    transaction->setDropInputMode(ctrl, static_cast<gui::DropInputMode>(mode));
+}
+
 static void nativeSanitize(JNIEnv* env, jclass clazz, jlong transactionObj) {
     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
     transaction->sanitize();
@@ -1999,6 +2006,8 @@
             (void*)nativeGetTransformHint },
     {"nativeSetTrustedOverlay", "(JJZ)V",
             (void*)nativeSetTrustedOverlay },
+    {"nativeSetDropInputMode", "(JJI)V",
+            (void*)nativeSetDropInputMode},
     {"nativeSanitize", "(J)V",
             (void*) nativeSanitize }
         // clang-format on
diff --git a/core/tests/coretests/src/android/app/NotificationChannelGroupTest.java b/core/tests/coretests/src/android/app/NotificationChannelGroupTest.java
new file mode 100644
index 0000000..625c66a
--- /dev/null
+++ b/core/tests/coretests/src/android/app/NotificationChannelGroupTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertTrue;
+
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+import android.text.TextUtils;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.google.common.base.Strings;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NotificationChannelGroupTest {
+    private final String CLASS = "android.app.NotificationChannelGroup";
+
+    @Test
+    public void testLongStringFields() {
+        NotificationChannelGroup group = new NotificationChannelGroup("my_group_01", "groupName");
+
+        try {
+            String longString = Strings.repeat("A", 65536);
+            Field mName = Class.forName(CLASS).getDeclaredField("mName");
+            mName.setAccessible(true);
+            mName.set(group, longString);
+            Field mId = Class.forName(CLASS).getDeclaredField("mId");
+            mId.setAccessible(true);
+            mId.set(group, longString);
+            Field mDescription = Class.forName(CLASS).getDeclaredField("mDescription");
+            mDescription.setAccessible(true);
+            mDescription.set(group, longString);
+        } catch (NoSuchFieldException e) {
+            e.printStackTrace();
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        }
+
+        Parcel parcel = Parcel.obtain();
+        group.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+
+        NotificationChannelGroup fromParcel =
+                NotificationChannelGroup.CREATOR.createFromParcel(parcel);
+        assertEquals(NotificationChannelGroup.MAX_TEXT_LENGTH, fromParcel.getId().length());
+        assertEquals(NotificationChannelGroup.MAX_TEXT_LENGTH, fromParcel.getName().length());
+        assertEquals(NotificationChannelGroup.MAX_TEXT_LENGTH,
+                fromParcel.getDescription().length());
+    }
+
+    @Test
+    public void testNullableFields() {
+        NotificationChannelGroup group = new NotificationChannelGroup("my_group_01", null);
+
+        Parcel parcel = Parcel.obtain();
+        group.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+
+        NotificationChannelGroup fromParcel =
+                NotificationChannelGroup.CREATOR.createFromParcel(parcel);
+        assertEquals(group.getId(), fromParcel.getId());
+        assertTrue(TextUtils.isEmpty(fromParcel.getName()));
+    }
+}
diff --git a/core/tests/coretests/src/android/app/NotificationChannelTest.java b/core/tests/coretests/src/android/app/NotificationChannelTest.java
new file mode 100644
index 0000000..647bfe8
--- /dev/null
+++ b/core/tests/coretests/src/android/app/NotificationChannelTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import static junit.framework.TestCase.assertEquals;
+
+import android.net.Uri;
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.google.common.base.Strings;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NotificationChannelTest {
+    private final String CLASS = "android.app.NotificationChannel";
+
+    @Test
+    public void testLongStringFields() {
+        NotificationChannel channel = new NotificationChannel("id", "name", 3);
+
+        try {
+            String longString = Strings.repeat("A", 65536);
+            Field mName = Class.forName(CLASS).getDeclaredField("mName");
+            mName.setAccessible(true);
+            mName.set(channel, longString);
+            Field mId = Class.forName(CLASS).getDeclaredField("mId");
+            mId.setAccessible(true);
+            mId.set(channel, longString);
+            Field mDesc = Class.forName(CLASS).getDeclaredField("mDesc");
+            mDesc.setAccessible(true);
+            mDesc.set(channel, longString);
+            Field mParentId = Class.forName(CLASS).getDeclaredField("mParentId");
+            mParentId.setAccessible(true);
+            mParentId.set(channel, longString);
+            Field mGroup = Class.forName(CLASS).getDeclaredField("mGroup");
+            mGroup.setAccessible(true);
+            mGroup.set(channel, longString);
+            Field mConversationId = Class.forName(CLASS).getDeclaredField("mConversationId");
+            mConversationId.setAccessible(true);
+            mConversationId.set(channel, longString);
+        } catch (NoSuchFieldException e) {
+            e.printStackTrace();
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        }
+
+        Parcel parcel = Parcel.obtain();
+        channel.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+
+        NotificationChannel fromParcel = NotificationChannel.CREATOR.createFromParcel(parcel);
+        assertEquals(NotificationChannel.MAX_TEXT_LENGTH, fromParcel.getId().length());
+        assertEquals(NotificationChannel.MAX_TEXT_LENGTH, fromParcel.getName().length());
+        assertEquals(NotificationChannel.MAX_TEXT_LENGTH,
+                fromParcel.getDescription().length());
+        assertEquals(NotificationChannel.MAX_TEXT_LENGTH,
+                fromParcel.getParentChannelId().length());
+        assertEquals(NotificationChannel.MAX_TEXT_LENGTH,
+                fromParcel.getGroup().length());
+        assertEquals(NotificationChannel.MAX_TEXT_LENGTH,
+                fromParcel.getConversationId().length());
+    }
+
+    @Test
+    public void testLongAlertFields() {
+        NotificationChannel channel = new NotificationChannel("id", "name", 3);
+
+        channel.setSound(Uri.parse("content://" + Strings.repeat("A",65536)),
+                Notification.AUDIO_ATTRIBUTES_DEFAULT);
+        channel.setVibrationPattern(new long[65550/2]);
+
+        Parcel parcel = Parcel.obtain();
+        channel.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+
+        NotificationChannel fromParcel = NotificationChannel.CREATOR.createFromParcel(parcel);
+        assertEquals(NotificationChannel.MAX_VIBRATION_LENGTH,
+                fromParcel.getVibrationPattern().length);
+        assertEquals(NotificationChannel.MAX_TEXT_LENGTH,
+                fromParcel.getSound().toString().length());
+    }
+}
diff --git a/core/tests/coretests/src/android/service/notification/ConditionTest.java b/core/tests/coretests/src/android/service/notification/ConditionTest.java
new file mode 100644
index 0000000..42629ba
--- /dev/null
+++ b/core/tests/coretests/src/android/service/notification/ConditionTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.notification;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.fail;
+
+import android.net.Uri;
+import android.os.Parcel;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.base.Strings;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ConditionTest {
+    private static final String CLASS = "android.service.notification.Condition";
+
+    @Test
+    public void testLongFields_inConstructors() {
+        String longString = Strings.repeat("A", 65536);
+        Uri longUri = Uri.parse("uri://" + Strings.repeat("A", 65530));
+
+        // Confirm strings are truncated via short constructor
+        Condition cond1 = new Condition(longUri, longString, Condition.STATE_TRUE);
+
+        assertEquals(Condition.MAX_STRING_LENGTH, cond1.id.toString().length());
+        assertEquals(Condition.MAX_STRING_LENGTH, cond1.summary.length());
+
+        // Confirm strings are truncated via long constructor
+        Condition cond2 = new Condition(longUri, longString, longString, longString,
+                -1, Condition.STATE_TRUE, Condition.FLAG_RELEVANT_ALWAYS);
+
+        assertEquals(Condition.MAX_STRING_LENGTH, cond2.id.toString().length());
+        assertEquals(Condition.MAX_STRING_LENGTH, cond2.summary.length());
+        assertEquals(Condition.MAX_STRING_LENGTH, cond2.line1.length());
+        assertEquals(Condition.MAX_STRING_LENGTH, cond2.line2.length());
+    }
+
+    @Test
+    public void testLongFields_viaParcel() {
+        // Set fields via reflection to force them to be long, then parcel and unparcel to make sure
+        // it gets truncated upon unparcelling.
+        Condition cond = new Condition(Uri.parse("uri://placeholder"), "placeholder",
+                Condition.STATE_TRUE);
+
+        try {
+            String longString = Strings.repeat("A", 65536);
+            Uri longUri = Uri.parse("uri://" + Strings.repeat("A", 65530));
+            Field id = Class.forName(CLASS).getDeclaredField("id");
+            id.setAccessible(true);
+            id.set(cond, longUri);
+            Field summary = Class.forName(CLASS).getDeclaredField("summary");
+            summary.setAccessible(true);
+            summary.set(cond, longString);
+            Field line1 = Class.forName(CLASS).getDeclaredField("line1");
+            line1.setAccessible(true);
+            line1.set(cond, longString);
+            Field line2 = Class.forName(CLASS).getDeclaredField("line2");
+            line2.setAccessible(true);
+            line2.set(cond, longString);
+        } catch (NoSuchFieldException e) {
+            fail(e.toString());
+        } catch (ClassNotFoundException e) {
+            fail(e.toString());
+        } catch (IllegalAccessException e) {
+            fail(e.toString());
+        }
+
+        Parcel parcel = Parcel.obtain();
+        cond.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+
+        Condition fromParcel = new Condition(parcel);
+        assertEquals(Condition.MAX_STRING_LENGTH, fromParcel.id.toString().length());
+        assertEquals(Condition.MAX_STRING_LENGTH, fromParcel.summary.length());
+        assertEquals(Condition.MAX_STRING_LENGTH, fromParcel.line1.length());
+        assertEquals(Condition.MAX_STRING_LENGTH, fromParcel.line2.length());
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java b/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
index c346142..0c6cd04 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
@@ -21,8 +21,8 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
@@ -266,13 +266,13 @@
     }
 
     private boolean startSystemActivityForResult(Intent intent, int code) {
-        ActivityInfo info = intent.resolveActivityInfo(mActivity.getPackageManager(),
-                PackageManager.MATCH_SYSTEM_ONLY);
-        if (info == null) {
+        List<ResolveInfo> resolveInfos = mActivity.getPackageManager()
+                .queryIntentActivities(intent, PackageManager.MATCH_SYSTEM_ONLY);
+        if (resolveInfos.isEmpty()) {
             Log.w(TAG, "No system package activity could be found for code " + code);
             return false;
         }
-        intent.setPackage(info.packageName);
+        intent.setPackage(resolveInfos.get(0).activityInfo.packageName);
         mActivityStarter.startActivityForResult(intent, code);
         return true;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index c26782b..28ab225 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -28,6 +28,7 @@
 import android.content.pm.ActivityInfo;
 import android.graphics.PixelFormat;
 import android.os.Binder;
+import android.os.Build;
 import android.os.RemoteException;
 import android.os.Trace;
 import android.util.Log;
@@ -319,6 +320,16 @@
             Trace.setCounter("display_max_refresh_rate",
                     (long) mLpChanged.preferredMaxDisplayRefreshRate);
         }
+
+        if (state.mBouncerShowing && !isDebuggable()) {
+            mLpChanged.flags |= LayoutParams.FLAG_SECURE;
+        } else {
+            mLpChanged.flags &= ~LayoutParams.FLAG_SECURE;
+        }
+    }
+
+    protected boolean isDebuggable() {
+        return Build.IS_DEBUGGABLE;
     }
 
     private void adjustScreenOrientation(State state) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
index 90b8a74..df844d4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
@@ -18,6 +18,7 @@
 
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -89,7 +90,12 @@
                 mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
                 mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController,
                 mColorExtractor, mDumpManager, mKeyguardStateController,
-                mUnlockedScreenOffAnimationController, mAuthController);
+                mUnlockedScreenOffAnimationController, mAuthController) {
+                    @Override
+                    protected boolean isDebuggable() {
+                        return false;
+                    }
+            };
         mNotificationShadeWindowController.setScrimsVisibilityListener((visibility) -> {});
         mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
 
@@ -225,4 +231,20 @@
         assertThat((mLayoutParameters.getValue().flags & FLAG_NOT_FOCUSABLE) != 0).isTrue();
         assertThat((mLayoutParameters.getValue().flags & FLAG_ALT_FOCUSABLE_IM) == 0).isTrue();
     }
+
+    @Test
+    public void setKeyguardShowing_enablesSecureFlag() {
+        mNotificationShadeWindowController.setBouncerShowing(true);
+
+        verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
+        assertThat((mLayoutParameters.getValue().flags & FLAG_SECURE) != 0).isTrue();
+    }
+
+    @Test
+    public void setKeyguardNotShowing_disablesSecureFlag() {
+        mNotificationShadeWindowController.setBouncerShowing(false);
+
+        verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
+        assertThat((mLayoutParameters.getValue().flags & FLAG_SECURE) == 0).isTrue();
+    }
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index f631988..1a742ff 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -926,7 +926,8 @@
             final List<AccessibilityServiceInfo> result = new ArrayList<>(serviceCount);
             for (int i = 0; i < serviceCount; ++i) {
                 final AccessibilityServiceConnection service = services.get(i);
-                if ((service.mFeedbackType & feedbackType) != 0) {
+                if ((service.mFeedbackType & feedbackType) != 0
+                        || feedbackType == AccessibilityServiceInfo.FEEDBACK_ALL_MASK) {
                     result.add(service.getServiceInfo());
                 }
             }
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index c32543a..f5063ac 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -1199,11 +1199,12 @@
             try {
                 // Ask ActivityManager to bind it. Notice that we are binding the service with the
                 // caller app instead of DevicePolicyManagerService.
-                if(ActivityManager.getService().bindService(
+                if (ActivityManager.getService().bindService(
                         caller, activtiyToken, intent,
                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                        connection, flags, mContext.getOpPackageName(),
-                        widget.provider.getUserId()) != 0) {
+                        connection, flags & (Context.BIND_AUTO_CREATE
+                                | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE),
+                        mContext.getOpPackageName(), widget.provider.getUserId()) != 0) {
 
                     // Add it to the mapping of RemoteViewsService to appWidgetIds so that we
                     // can determine when we can call back to the RemoteViewsService later to
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index ae2f934..a8672ff 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -88,6 +88,7 @@
 import android.os.UserManager;
 import android.stats.devicepolicy.DevicePolicyEnums;
 import android.text.TextUtils;
+import android.util.EventLog;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
@@ -3097,7 +3098,7 @@
                              */
                             if (!checkKeyIntent(
                                     Binder.getCallingUid(),
-                                    intent)) {
+                                    result)) {
                                 onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
                                         "invalid intent in bundle returned");
                                 return;
@@ -3516,7 +3517,7 @@
                     && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
                 if (!checkKeyIntent(
                         Binder.getCallingUid(),
-                        intent)) {
+                        result)) {
                     onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
                             "invalid intent in bundle returned");
                     return;
@@ -4867,7 +4868,13 @@
          * into launching arbitrary intents on the device via by tricking to click authenticator
          * supplied entries in the system Settings app.
          */
-         protected boolean checkKeyIntent(int authUid, Intent intent) {
+        protected boolean checkKeyIntent(int authUid, Bundle bundle) {
+            if (!checkKeyIntentParceledCorrectly(bundle)) {
+            	EventLog.writeEvent(0x534e4554, "250588548", authUid, "");
+                return false;
+            }
+
+            Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
             // Explicitly set an empty ClipData to ensure that we don't offer to
             // promote any Uris contained inside for granting purposes
             if (intent.getClipData() == null) {
@@ -4904,6 +4911,25 @@
             }
         }
 
+        /**
+         * Simulate the client side's deserialization of KEY_INTENT value, to make sure they don't
+         * violate our security policy.
+         *
+         * In particular we want to make sure the Authenticator doesn't trick users
+         * into launching arbitrary intents on the device via exploiting any other Parcel read/write
+         * mismatch problems.
+         */
+        private boolean checkKeyIntentParceledCorrectly(Bundle bundle) {
+            Parcel p = Parcel.obtain();
+            p.writeBundle(bundle);
+            p.setDataPosition(0);
+            Bundle simulateBundle = p.readBundle();
+            p.recycle();
+            Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
+            Intent simulateIntent = simulateBundle.getParcelable(AccountManager.KEY_INTENT);
+            return (intent.filterEquals(simulateIntent));
+        }
+
         private boolean isExportedSystemActivity(ActivityInfo activityInfo) {
             String className = activityInfo.name;
             return "android".equals(activityInfo.packageName) &&
@@ -5050,7 +5076,7 @@
                     && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) {
                 if (!checkKeyIntent(
                         Binder.getCallingUid(),
-                        intent)) {
+                        result)) {
                     onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
                             "invalid intent in bundle returned");
                     return;
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 185c023..72b75f3 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -97,7 +97,7 @@
     private static final String NON_BLOCKABLE_CHANNEL_DELIM = ":";
 
     @VisibleForTesting
-    static final int NOTIFICATION_CHANNEL_COUNT_LIMIT = 50000;
+    static final int NOTIFICATION_CHANNEL_COUNT_LIMIT = 5000;
 
     private static final int NOTIFICATION_PREFERENCES_PULL_LIMIT = 1000;
     private static final int NOTIFICATION_CHANNEL_PULL_LIMIT = 2000;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d03aaee..dc3e28a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -21359,6 +21359,20 @@
 
         final String packageName = versionedPackage.getPackageName();
         final long versionCode = versionedPackage.getLongVersionCode();
+
+        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
+            mHandler.post(() -> {
+                try {
+                    Slog.w(TAG, "Attempted to delete protected package: " + packageName);
+                    observer.onPackageDeleted(packageName,
+                            PackageManager.DELETE_FAILED_INTERNAL_ERROR, null);
+                } catch (RemoteException re) {
+                }
+            });
+            return;
+        }
+
+
         final String internalPackageName;
 
         try {
@@ -21662,7 +21676,8 @@
                 return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
             }
 
-            if (isSystemApp(uninstalledPs)) {
+            if (isSystemApp(uninstalledPs)
+                    && (deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0) {
                 UserInfo userInfo = mUserManager.getUserInfo(userId);
                 if (userInfo == null || !userInfo.isAdmin()) {
                     Slog.w(TAG, "Not removing package " + packageName
@@ -24152,6 +24167,9 @@
                     } else {
                         Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
                                 + className + " does not exist in " + packageName);
+                        // Safetynet logging for b/240936919
+                        EventLog.writeEvent(0x534e4554, "240936919", callingUid);
+                        return;
                     }
                 }
                 switch (newState) {
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index b4bd086..3506fd9 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -1967,10 +1967,15 @@
 
                         continue;
                     case TAG_SHORTCUT:
-                        final ShortcutInfo si = parseShortcut(parser, packageName,
-                                shortcutUser.getUserId(), fromBackup);
-                        // Don't use addShortcut(), we don't need to save the icon.
-                        ret.mShortcuts.put(si.getId(), si);
+                        try {
+                            final ShortcutInfo si = parseShortcut(parser, packageName,
+                                    shortcutUser.getUserId(), fromBackup);
+                            // Don't use addShortcut(), we don't need to save the icon.
+                            ret.mShortcuts.put(si.getId(), si);
+                        } catch (Exception e) {
+                            // b/246540168 malformed shortcuts should be ignored
+                            Slog.e(TAG, "Failed parsing shortcut.", e);
+                        }
                         continue;
                     case TAG_SHARE_TARGET:
                         ret.mShareTargets.add(ShareTargetInfo.loadFromXml(parser));
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 09c6b50..92abc486 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -88,6 +88,7 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
+import android.util.EventLog;
 import android.util.IndentingPrintWriter;
 import android.util.IntArray;
 import android.util.Slog;
@@ -4499,6 +4500,13 @@
     public void setApplicationRestrictions(String packageName, Bundle restrictions,
             @UserIdInt int userId) {
         checkSystemOrRoot("set application restrictions");
+        String validationResult = validateName(packageName);
+        if (validationResult != null) {
+            if (packageName.contains("../")) {
+                EventLog.writeEvent(0x534e4554, "239701237", -1, "");
+            }
+            throw new IllegalArgumentException("Invalid package name: " + validationResult);
+        }
         if (restrictions != null) {
             restrictions.setDefusable(true);
         }
@@ -4525,6 +4533,39 @@
         mContext.sendBroadcastAsUser(changeIntent, UserHandle.of(userId));
     }
 
+    /**
+     * Check if the given name is valid.
+     *
+     * Note: the logic is taken from FrameworkParsingPackageUtils in master, edited to remove
+     * unnecessary parts. Copied here for a security fix.
+     *
+     * @param name The name to check.
+     * @return null if it's valid, error message if not
+     */
+    @VisibleForTesting
+    static String validateName(String name) {
+        final int n = name.length();
+        boolean front = true;
+        for (int i = 0; i < n; i++) {
+            final char c = name.charAt(i);
+            if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+                front = false;
+                continue;
+            }
+            if (!front) {
+                if ((c >= '0' && c <= '9') || c == '_') {
+                    continue;
+                }
+                if (c == '.') {
+                    front = true;
+                    continue;
+                }
+            }
+            return "bad character '" + c + "'";
+        }
+        return null;
+    }
+
     private int getUidForPackage(String packageName) {
         final long ident = Binder.clearCallingIdentity();
         try {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 9918c7a..e4c63fd 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -775,6 +775,13 @@
 
     private AppSaturationInfo mLastAppSaturationInfo;
 
+    private final ActivityRecordInputSink mActivityRecordInputSink;
+
+    // Activities with this uid are allowed to not create an input sink while being in the same
+    // task and directly above this ActivityRecord. This field is updated whenever a new activity
+    // is launched from this ActivityRecord. Touches are always allowed within the same uid.
+    int mAllowedTouchUid;
+
     private final ColorDisplayService.ColorTransformController mColorTransformController =
             (matrix, translation) -> mWmService.mH.post(() -> {
                 synchronized (mWmService.mGlobalLock) {
@@ -1722,6 +1729,8 @@
             createTime = _createTime;
         }
         mAtmService.mPackageConfigPersister.updateConfigIfNeeded(this, mUserId, packageName);
+
+        mActivityRecordInputSink = new ActivityRecordInputSink(this, sourceRecord);
     }
 
     /**
@@ -3558,6 +3567,7 @@
             destroyImmediately("removeImmediately");
         }
         onRemovedFromDisplay();
+        mActivityRecordInputSink.releaseSurfaceControl();
         super.removeImmediately();
     }
 
@@ -6692,6 +6702,9 @@
             } else if (!show && mLastSurfaceShowing) {
                 getSyncTransaction().hide(mSurfaceControl);
             }
+            if (show) {
+                mActivityRecordInputSink.applyChangesToSurfaceIfChanged(getSyncTransaction());
+            }
         }
         if (mThumbnail != null) {
             mThumbnail.setShowing(getPendingTransaction(), show);
diff --git a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
new file mode 100644
index 0000000..95b5cec
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.os.Process;
+import android.view.InputWindowHandle;
+import android.view.SurfaceControl;
+import android.view.WindowManager;
+
+/**
+ * Creates a InputWindowHandle that catches all touches that would otherwise pass through an
+ * Activity.
+ */
+class ActivityRecordInputSink {
+
+    private final ActivityRecord mActivityRecord;
+    private final String mName;
+
+    private InputWindowHandle mInputWindowHandle;
+    private SurfaceControl mSurfaceControl;
+
+    ActivityRecordInputSink(ActivityRecord activityRecord, ActivityRecord sourceRecord) {
+        mActivityRecord = activityRecord;
+        mName = Integer.toHexString(System.identityHashCode(this)) + " ActivityRecordInputSink "
+                + mActivityRecord.mActivityComponent.flattenToShortString();
+        if (sourceRecord != null) {
+            sourceRecord.mAllowedTouchUid = mActivityRecord.getUid();
+        }
+    }
+
+    public void applyChangesToSurfaceIfChanged(SurfaceControl.Transaction transaction) {
+        boolean windowHandleChanged = updateInputWindowHandle();
+        if (mSurfaceControl == null) {
+            mSurfaceControl = createSurface(transaction);
+        }
+        if (windowHandleChanged) {
+            transaction.setInputWindowInfo(mSurfaceControl, mInputWindowHandle);
+        }
+    }
+
+    private SurfaceControl createSurface(SurfaceControl.Transaction t) {
+        SurfaceControl surfaceControl = mActivityRecord.makeChildSurface(null)
+                .setName(mName)
+                .setHidden(false)
+                .setCallsite("ActivityRecordInputSink.createSurface")
+                .build();
+        // Put layer below all siblings (and the parent surface too)
+        t.setLayer(surfaceControl, Integer.MIN_VALUE);
+        return surfaceControl;
+    }
+
+    private boolean updateInputWindowHandle() {
+        boolean changed = false;
+        if (mInputWindowHandle == null) {
+            mInputWindowHandle = createInputWindowHandle();
+            changed = true;
+        }
+        // Don't block touches from passing through to an activity below us in the same task, if
+        // that activity is either from the same uid or if that activity has launched an activity
+        // in our uid.
+        final ActivityRecord activityBelowInTask =
+                mActivityRecord.getTask().getActivityBelow(mActivityRecord);
+        final boolean allowPassthrough = activityBelowInTask != null && (
+                activityBelowInTask.mAllowedTouchUid == mActivityRecord.getUid()
+                        || activityBelowInTask.isUid(mActivityRecord.getUid()));
+        boolean notTouchable = (mInputWindowHandle.layoutParamsFlags
+                & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0;
+        if (allowPassthrough || mActivityRecord.isAppTransitioning()) {
+            mInputWindowHandle.layoutParamsFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+            changed |= !notTouchable;
+        } else {
+            mInputWindowHandle.layoutParamsFlags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+            changed |= notTouchable;
+        }
+        return changed;
+    }
+
+    private InputWindowHandle createInputWindowHandle() {
+        InputWindowHandle inputWindowHandle = new InputWindowHandle(null,
+                mActivityRecord.getDisplayId());
+        inputWindowHandle.replaceTouchableRegionWithCrop = true;
+        inputWindowHandle.name = mName;
+        inputWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
+        inputWindowHandle.ownerUid = Process.myUid();
+        inputWindowHandle.ownerPid = Process.myPid();
+        inputWindowHandle.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+        inputWindowHandle.inputFeatures =
+                WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
+        return inputWindowHandle;
+    }
+
+    void releaseSurfaceControl() {
+        if (mSurfaceControl != null) {
+            mSurfaceControl.release();
+            mSurfaceControl = null;
+        }
+    }
+
+}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index d0457b0..6fcbf26 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -124,6 +124,7 @@
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.gui.DropInputMode;
 import android.hardware.power.Boost;
 import android.os.Handler;
 import android.os.IBinder;
@@ -930,6 +931,20 @@
     }
 
     /**
+     * Add additional policy if needed to ensure the window or its children should not receive any
+     * input.
+     */
+    public void setDropInputModePolicy(WindowState win, LayoutParams attrs) {
+        if (attrs.type == TYPE_TOAST
+                && (attrs.privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) == 0) {
+            // Toasts should not receive input. These windows should not have any children, so
+            // force this hierarchy of windows to drop all input.
+            mService.mTransactionFactory.get()
+                    .setDropInputMode(win.getSurfaceControl(), DropInputMode.ALL).apply();
+        }
+    }
+
+    /**
      * Check if a window can be added to the system.
      *
      * Currently enforces that two window types are singletons per display:
diff --git a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
index 2626b87..7e47967 100644
--- a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
+++ b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
@@ -146,15 +146,16 @@
             return false;
 
         } else {
-            mResultActivities.add(r);
             if (r.resultTo != null) {
                 // If this activity is sending a reply to a previous activity, we can't do
                 // anything with it now until we reach the start of the reply chain.
                 // NOTE: that we are assuming the result is always to the previous activity,
                 // which is almost always the case but we really shouldn't count on.
+                mResultActivities.add(r);
                 return false;
             } else if (mTargetTaskFound && allowTaskReparenting && mTargetTask.affinity != null
                     && mTargetTask.affinity.equals(r.taskAffinity)) {
+                mResultActivities.add(r);
                 // This activity has an affinity for our task. Either remove it if we are
                 // clearing or move it over to our task. Note that we currently punt on the case
                 // where we are resetting a task that is not at the top but who has activities
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c14c97c..04d9d69 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1780,6 +1780,7 @@
 
             win.mToken.addWindow(win);
             displayPolicy.addWindowLw(win, attrs);
+            displayPolicy.setDropInputModePolicy(win, win.mAttrs);
             if (type == TYPE_INPUT_METHOD) {
                 displayContent.setInputMethodWindowLocked(win);
                 imMayMove = false;
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
index 6c1c019..658f168 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -86,6 +86,13 @@
         }
     }
 
+    public void testValidateName() {
+        assertNull(UserManagerService.validateName("android"));
+        assertNull(UserManagerService.validateName("com.company.myapp"));
+        assertNotNull(UserManagerService.validateName("/../../data"));
+        assertNotNull(UserManagerService.validateName("/dir"));
+    }
+
     private Bundle createBundle() {
         Bundle result = new Bundle();
         // Tests for 6 allowed types: Integer, Boolean, String, String[], Bundle and Parcelable[]