Merge "Add nullability annotations to some InputDevice APIs"
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index 91fa3c4..251cf56 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -1974,8 +1974,8 @@
             case 2: return "FREQUENT";
             case 3: return "RARE";
             case 4: return "NEVER";
-            case 5:
-                return "RESTRICTED";
+            case 5: return "RESTRICTED";
+            case 6: return "EXEMPTED";
             default:
                 return "Unknown: " + standbyBucket;
         }
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 0f54ce5..709272c 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -365,6 +365,9 @@
     private static final String KEY_DISMISS_KEYGUARD_IF_INSECURE =
             "android.activity.dismissKeyguardIfInsecure";
 
+    private static final String KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE =
+            "android.activity.ignorePendingIntentCreatorForegroundState";
+
     /**
      * @see #setLaunchCookie
      * @hide
@@ -462,6 +465,7 @@
     private boolean mTransientLaunch;
     private PictureInPictureParams mLaunchIntoPipParams;
     private boolean mDismissKeyguardIfInsecure;
+    private boolean mIgnorePendingIntentCreatorForegroundState;
 
     /**
      * Create an ActivityOptions specifying a custom animation to run when
@@ -1260,6 +1264,8 @@
         mIsEligibleForLegacyPermissionPrompt =
                 opts.getBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE);
         mDismissKeyguardIfInsecure = opts.getBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE);
+        mIgnorePendingIntentCreatorForegroundState = opts.getBoolean(
+                KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE);
     }
 
     /**
@@ -1877,6 +1883,23 @@
     }
 
     /**
+     * Sets background activity launch logic won't use pending intent creator foreground state.
+     * @hide
+     */
+    public void setIgnorePendingIntentCreatorForegroundState(boolean state) {
+        mIgnorePendingIntentCreatorForegroundState = state;
+    }
+
+    /**
+     * @return whether background activity launch logic should use pending intent creator
+     * foreground state.
+     * @hide
+     */
+    public boolean getIgnorePendingIntentCreatorForegroundState() {
+        return mIgnorePendingIntentCreatorForegroundState;
+    }
+
+    /**
      * Update the current values in this ActivityOptions from those supplied
      * in <var>otherOptions</var>.  Any values
      * defined in <var>otherOptions</var> replace those in the base options.
@@ -2140,6 +2163,10 @@
         if (mDismissKeyguardIfInsecure) {
             b.putBoolean(KEY_DISMISS_KEYGUARD_IF_INSECURE, mDismissKeyguardIfInsecure);
         }
+        if (mIgnorePendingIntentCreatorForegroundState) {
+            b.putBoolean(KEY_IGNORE_PENDING_INTENT_CREATOR_FOREGROUND_STATE,
+                    mIgnorePendingIntentCreatorForegroundState);
+        }
         return b;
     }
 
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 646a709..497bfa6 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1681,18 +1681,13 @@
     }
 
     /** {@hide}
-     * Is this device encryptable or already encrypted?
-     * @return true for encryptable or encrypted
-     *         false not encrypted and not encryptable
-     */
-    public static boolean isEncryptable() {
-        return RoSystemProperties.CRYPTO_ENCRYPTABLE;
-    }
-
-    /** {@hide}
-     * Is this device already encrypted?
-     * @return true for encrypted. (Implies isEncryptable() == true)
-     *         false not encrypted
+     * Is this device encrypted?
+     * <p>
+     * Note: all devices launching with Android 10 (API level 29) or later are
+     * required to be encrypted.  This should only ever return false for
+     * in-development devices on which encryption has not yet been configured.
+     *
+     * @return true if encrypted, false if not encrypted
      */
     public static boolean isEncrypted() {
         return RoSystemProperties.CRYPTO_ENCRYPTED;
@@ -1701,7 +1696,7 @@
     /** {@hide}
      * Is this device file encrypted?
      * @return true for file encrypted. (Implies isEncrypted() == true)
-     *         false not encrypted or block encrypted
+     *         false not encrypted or using "managed" encryption
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public static boolean isFileEncryptedNativeOnly() {
@@ -1711,54 +1706,6 @@
         return RoSystemProperties.CRYPTO_FILE_ENCRYPTED;
     }
 
-    /** {@hide}
-     * Is this device block encrypted?
-     * @return true for block encrypted. (Implies isEncrypted() == true)
-     *         false not encrypted or file encrypted
-     */
-    public static boolean isBlockEncrypted() {
-        return false;
-    }
-
-    /** {@hide}
-     * Is this device block encrypted with credentials?
-     * @return true for crediential block encrypted.
-     *         (Implies isBlockEncrypted() == true)
-     *         false not encrypted, file encrypted or default block encrypted
-     */
-    public static boolean isNonDefaultBlockEncrypted() {
-        return false;
-    }
-
-    /** {@hide}
-     * Is this device in the process of being block encrypted?
-     * @return true for encrypting.
-     *         false otherwise
-     * Whether device isEncrypted at this point is undefined
-     * Note that only system services and CryptKeeper will ever see this return
-     * true - no app will ever be launched in this state.
-     * Also note that this state will not change without a teardown of the
-     * framework, so no service needs to check for changes during their lifespan
-     */
-    public static boolean isBlockEncrypting() {
-        return false;
-    }
-
-    /** {@hide}
-     * Is this device non default block encrypted and in the process of
-     * prompting for credentials?
-     * @return true for prompting for credentials.
-     *         (Implies isNonDefaultBlockEncrypted() == true)
-     *         false otherwise
-     * Note that only system services and CryptKeeper will ever see this return
-     * true - no app will ever be launched in this state.
-     * Also note that this state will not change without a teardown of the
-     * framework, so no service needs to check for changes during their lifespan
-     */
-    public static boolean inCryptKeeperBounce() {
-        return false;
-    }
-
     /** {@hide} */
     public static boolean isFileEncryptedEmulatedOnly() {
         return SystemProperties.getBoolean(StorageManager.PROP_EMULATE_FBE, false);
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 8dca7ab..0e5a65c 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -425,6 +425,7 @@
             private double mLatitude = Double.NaN;
             private double mLongitude = Double.NaN;
             private Uri mPictureUri;
+            private int mIsPhoneAccountMigrationPending;
 
             /**
              * @param callerInfo the CallerInfo object to get the target contact from.
@@ -634,6 +635,15 @@
             }
 
             /**
+             * @param isPhoneAccountMigrationPending whether the phone account migration is pending
+             */
+            public @NonNull AddCallParametersBuilder setIsPhoneAccountMigrationPending(
+                    int isPhoneAccountMigrationPending) {
+                mIsPhoneAccountMigrationPending = isPhoneAccountMigrationPending;
+                return this;
+            }
+
+            /**
              * Builds the object
              */
             public @NonNull AddCallParams build() {
@@ -641,7 +651,8 @@
                         mPresentation, mCallType, mFeatures, mAccountHandle, mStart, mDuration,
                         mDataUsage, mAddForAllUsers, mUserToBeInsertedTo, mIsRead, mCallBlockReason,
                         mCallScreeningAppName, mCallScreeningComponentName, mMissedReason,
-                        mPriority, mSubject, mLatitude, mLongitude, mPictureUri);
+                        mPriority, mSubject, mLatitude, mLongitude, mPictureUri,
+                        mIsPhoneAccountMigrationPending);
             }
         }
 
@@ -668,6 +679,7 @@
         private double mLatitude = Double.NaN;
         private double mLongitude = Double.NaN;
         private Uri mPictureUri;
+        private int mIsPhoneAccountMigrationPending;
 
         private AddCallParams(CallerInfo callerInfo, String number, String postDialDigits,
                 String viaNumber, int presentation, int callType, int features,
@@ -676,7 +688,8 @@
                 int callBlockReason,
                 CharSequence callScreeningAppName, String callScreeningComponentName,
                 long missedReason,
-                int priority, String subject, double latitude, double longitude, Uri pictureUri) {
+                int priority, String subject, double latitude, double longitude, Uri pictureUri,
+                int isPhoneAccountMigrationPending) {
             mCallerInfo = callerInfo;
             mNumber = number;
             mPostDialDigits = postDialDigits;
@@ -700,6 +713,7 @@
             mLatitude = latitude;
             mLongitude = longitude;
             mPictureUri = pictureUri;
+            mIsPhoneAccountMigrationPending = isPhoneAccountMigrationPending;
         }
 
     }
@@ -1482,6 +1496,21 @@
         public static final String LOCATION = "location";
 
         /**
+         * A reference to indicate whether phone account migration process is pending.
+         *
+         * Before Android 13, {@link PhoneAccountHandle#getId()} returns the ICCID for Telephony
+         * PhoneAccountHandle. Starting from Android 13, {@link PhoneAccountHandle#getId()} returns
+         * the Subscription ID for Telephony PhoneAccountHandle. A phone account migration process
+         * is to ensure this PhoneAccountHandle migration process cross the Android versions in
+         * the CallLog database.
+         *
+         * <p>Type: INTEGER</p>
+         * @hide
+         */
+        public static final String IS_PHONE_ACCOUNT_MIGRATION_PENDING =
+                "is_call_log_phone_account_migration_pending";
+
+        /**
          * Adds a call to the call log.
          *
          * @param ci the CallerInfo object to get the target contact from.  Can be null
@@ -1498,6 +1527,7 @@
          * @param duration call duration in seconds
          * @param dataUsage data usage for the call in bytes, null if data usage was not tracked for
          *                  the call.
+         * @param isPhoneAccountMigrationPending whether the PhoneAccountHandle ID need to migrate
          * @result The URI of the call log entry belonging to the user that made or received this
          *        call.
          * {@hide}
@@ -1505,13 +1535,14 @@
         public static Uri addCall(CallerInfo ci, Context context, String number,
                 int presentation, int callType, int features,
                 PhoneAccountHandle accountHandle,
-                long start, int duration, Long dataUsage, long missedReason) {
+                long start, int duration, Long dataUsage, long missedReason,
+                int isPhoneAccountMigrationPending) {
             return addCall(ci, context, number, "" /* postDialDigits */, "" /* viaNumber */,
                 presentation, callType, features, accountHandle, start, duration,
                 dataUsage, false /* addForAllUsers */, null /* userToBeInsertedTo */,
                 false /* isRead */, Calls.BLOCK_REASON_NOT_BLOCKED /* callBlockReason */,
                 null /* callScreeningAppName */, null /* callScreeningComponentName */,
-                    missedReason);
+                    missedReason, isPhoneAccountMigrationPending);
         }
 
 
@@ -1539,6 +1570,7 @@
          * @param userToBeInsertedTo {@link UserHandle} of user that the call is going to be
          *                           inserted to. null if it is inserted to the current user. The
          *                           value is ignored if @{link addForAllUsers} is true.
+         * @param isPhoneAccountMigrationPending whether the PhoneAccountHandle ID need to migrate
          * @result The URI of the call log entry belonging to the user that made or received this
          *        call.
          * {@hide}
@@ -1547,12 +1579,13 @@
                 String postDialDigits, String viaNumber, int presentation, int callType,
                 int features, PhoneAccountHandle accountHandle, long start, int duration,
                 Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo,
-                long missedReason) {
+                long missedReason, int isPhoneAccountMigrationPending) {
             return addCall(ci, context, number, postDialDigits, viaNumber, presentation, callType,
                 features, accountHandle, start, duration, dataUsage, addForAllUsers,
                 userToBeInsertedTo, false /* isRead */ , Calls.BLOCK_REASON_NOT_BLOCKED
                 /* callBlockReason */, null /* callScreeningAppName */,
-                null /* callScreeningComponentName */, missedReason);
+                null /* callScreeningComponentName */, missedReason,
+                isPhoneAccountMigrationPending);
         }
 
 
@@ -1588,6 +1621,7 @@
          * @param callScreeningAppName The call screening application name which block the call.
          * @param callScreeningComponentName The call screening component name which block the call.
          * @param missedReason The encoded missed information of the call.
+         * @param isPhoneAccountMigrationPending whether the PhoneAccountHandle ID need to migrate
          *
          * @result The URI of the call log entry belonging to the user that made or received this
          *        call.  This could be of the shadow provider.  Do not return it to non-system apps,
@@ -1600,7 +1634,8 @@
                 int features, PhoneAccountHandle accountHandle, long start, int duration,
                 Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo,
                 boolean isRead, int callBlockReason, CharSequence callScreeningAppName,
-                String callScreeningComponentName, long missedReason) {
+                String callScreeningComponentName, long missedReason,
+                int isPhoneAccountMigrationPending) {
             AddCallParams.AddCallParametersBuilder builder =
                     new AddCallParams.AddCallParametersBuilder();
             builder.setCallerInfo(ci);
@@ -1621,6 +1656,7 @@
             builder.setCallScreeningAppName(callScreeningAppName);
             builder.setCallScreeningComponentName(callScreeningComponentName);
             builder.setMissedReason(missedReason);
+            builder.setIsPhoneAccountMigrationPending(isPhoneAccountMigrationPending);
 
             return addCall(context, builder.build());
         }
@@ -1692,6 +1728,7 @@
             if (params.mPictureUri != null) {
                 values.put(COMPOSER_PHOTO_URI, params.mPictureUri.toString());
             }
+            values.put(IS_PHONE_ACCOUNT_MIGRATION_PENDING, params.mIsPhoneAccountMigrationPending);
 
             if ((params.mCallerInfo != null) && (params.mCallerInfo.getContactId() > 0)) {
                 // Update usage information for the number associated with the contact ID.
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index b9f5144..3c1b4ba 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -4337,6 +4337,20 @@
         public static final int CARRIER_PRESENCE_VT_CAPABLE = 0x01;
 
         /**
+         * A reference to indicate whether phone account migration process is pending.
+         *
+         * Before Android 13, {@link PhoneAccountHandle#getId()} returns the ICCID for Telephony
+         * PhoneAccountHandle. Starting from Android 13, {@link PhoneAccountHandle#getId()} returns
+         * the Subscription ID for Telephony PhoneAccountHandle. A phone account migration process
+         * is to ensure this PhoneAccountHandle migration process cross the Android versions in
+         * the ContactsContract database.
+         *
+         * <p>Type: INTEGER</p>
+         * @hide
+         */
+        String IS_PHONE_ACCOUNT_MIGRATION_PENDING = "is_preferred_phone_account_migration_pending";
+
+        /**
          * The flattened {@link android.content.ComponentName} of a  {@link
          * android.telecom.PhoneAccountHandle} that is the preferred {@code PhoneAccountHandle} to
          * call the contact with.
diff --git a/core/java/android/util/SparseSetArray.java b/core/java/android/util/SparseSetArray.java
index f85280f..6646f01 100644
--- a/core/java/android/util/SparseSetArray.java
+++ b/core/java/android/util/SparseSetArray.java
@@ -63,6 +63,19 @@
     }
 
     /**
+     * Add a set of values for key n.
+     */
+    public void addAll(int n, ArraySet<T> values) {
+        ArraySet<T> set = mData.get(n);
+        if (set == null) {
+            set = new ArraySet<>(values);
+            mData.put(n, set);
+            return;
+        }
+        set.addAll(values);
+    }
+
+    /**
      * Removes all mappings from this SparseSetArray.
      */
     public void clear() {
@@ -109,6 +122,7 @@
     public void remove(int n) {
         mData.remove(n);
     }
+
     public int size() {
         return mData.size();
     }
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 12a736d..3a68404 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -26,11 +26,9 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SuppressLint;
 import android.annotation.TestApi;
-import android.app.ActivityThread;
 import android.app.KeyguardManager;
 import android.app.WindowConfiguration;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.content.ComponentName;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -52,14 +50,11 @@
 import android.util.DisplayMetrics;
 import android.util.Log;
 
-import com.android.internal.R;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Optional;
 
 /**
  * Provides information about the size and density of a logical display.
@@ -116,12 +111,6 @@
     private int mCachedAppHeightCompat;
 
     /**
-     * Cache if the application is the recents component.
-     * TODO(b/179308296) Remove once Launcher addresses issue
-     */
-    private Optional<Boolean> mIsRecentsComponent = Optional.empty();
-
-    /**
      * The default Display id, which is the id of the primary display assuming there is one.
      */
     public static final int DEFAULT_DISPLAY = 0;
@@ -1585,36 +1574,7 @@
             return false;
         }
         final Configuration config = mResources.getConfiguration();
-        // TODO(b/179308296) Temporarily exclude Launcher from being given max bounds, by checking
-        // if the caller is the recents component.
-        return config != null && !config.windowConfiguration.getMaxBounds().isEmpty()
-                && !isRecentsComponent();
-    }
-
-    /**
-     * Returns {@code true} when the calling package is the recents component.
-     * TODO(b/179308296) Remove once Launcher addresses issue
-     */
-    boolean isRecentsComponent() {
-        if (mIsRecentsComponent.isPresent()) {
-            return mIsRecentsComponent.get();
-        }
-        if (mResources == null) {
-            return false;
-        }
-        try {
-            String recentsComponent = mResources.getString(R.string.config_recentsComponentName);
-            if (recentsComponent == null) {
-                return false;
-            }
-            String recentsPackage = ComponentName.unflattenFromString(recentsComponent)
-                    .getPackageName();
-            mIsRecentsComponent = Optional.of(recentsPackage != null
-                    && recentsPackage.equals(ActivityThread.currentPackageName()));
-            return mIsRecentsComponent.get();
-        } catch (Resources.NotFoundException e) {
-            return false;
-        }
+        return config != null && !config.windowConfiguration.getMaxBounds().isEmpty();
     }
 
     /**
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 7098602..649accd 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -37,7 +37,7 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Transaction;
 import android.window.ClientWindowFrames;
-import android.window.IOnBackInvokedCallback;
+import android.window.OnBackInvokedCallbackInfo;
 
 import java.util.List;
 
@@ -371,14 +371,14 @@
             in String hashAlgorithm, in RemoteCallback callback);
 
     /**
-     * Sets the {@link IOnBackInvokedCallback} to be invoked for a window when back is triggered.
+     * Sets the {@link OnBackInvokedCallbackInfo} containing the callback to be invoked for
+     * a window when back is triggered.
      *
      * @param window The token for the window to set the callback to.
-     * @param callback The {@link IOnBackInvokedCallback} to set.
-     * @param priority The priority of the callback.
+     * @param callbackInfo The {@link OnBackInvokedCallbackInfo} to set.
      */
-    oneway void setOnBackInvokedCallback(
-            IWindow window, IOnBackInvokedCallback callback, int priority);
+    oneway void setOnBackInvokedCallbackInfo(
+            IWindow window, in OnBackInvokedCallbackInfo callbackInfo);
 
     /**
      * Clears a touchable region set by {@link #setInsets}.
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index 406281d..75e8080 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -264,14 +264,8 @@
     /** @hide */
     public SurfaceControlViewHost(@NonNull Context c, @NonNull Display d,
             @NonNull WindowlessWindowManager wwm) {
-        this(c, d, wwm, false /* useSfChoreographer */);
-    }
-
-    /** @hide */
-    public SurfaceControlViewHost(@NonNull Context c, @NonNull Display d,
-            @NonNull WindowlessWindowManager wwm, boolean useSfChoreographer) {
         mWm = wwm;
-        mViewRoot = new ViewRootImpl(c, d, mWm, useSfChoreographer);
+        mViewRoot = new ViewRootImpl(c, d, mWm);
         WindowManagerGlobal.getInstance().addWindowlessRoot(mViewRoot);
 
         mAccessibilityEmbeddedConnection = mViewRoot.getAccessibilityEmbeddedConnection();
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 1297331..f310e7f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -852,16 +852,10 @@
     private String mTag = TAG;
 
     public ViewRootImpl(Context context, Display display) {
-        this(context, display, WindowManagerGlobal.getWindowSession(),
-                false /* useSfChoreographer */);
+        this(context, display, WindowManagerGlobal.getWindowSession());
     }
 
     public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session) {
-        this(context, display, session, false /* useSfChoreographer */);
-    }
-
-    public ViewRootImpl(@UiContext Context context, Display display, IWindowSession session,
-            boolean useSfChoreographer) {
         mContext = context;
         mWindowSession = session;
         mDisplay = display;
@@ -893,8 +887,7 @@
         mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
         mFallbackEventHandler = new PhoneFallbackEventHandler(context);
         // TODO(b/222696368): remove getSfInstance usage and use vsyncId for transactions
-        mChoreographer = useSfChoreographer
-                ? Choreographer.getSfInstance() : Choreographer.getInstance();
+        mChoreographer = Choreographer.getInstance();
         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
         mInsetsController = new InsetsController(new ViewRootInsetsControllerHost(this));
         mHandwritingInitiator = new HandwritingInitiator(
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 30ae520..a212348 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -31,7 +31,7 @@
 import android.util.Log;
 import android.util.MergedConfiguration;
 import android.window.ClientWindowFrames;
-import android.window.IOnBackInvokedCallback;
+import android.window.OnBackInvokedCallbackInfo;
 
 import java.util.HashMap;
 import java.util.List;
@@ -529,8 +529,8 @@
     }
 
     @Override
-    public void setOnBackInvokedCallback(IWindow iWindow,
-            IOnBackInvokedCallback iOnBackInvokedCallback, int priority) throws RemoteException { }
+    public void setOnBackInvokedCallbackInfo(IWindow iWindow,
+            OnBackInvokedCallbackInfo callbackInfo) throws RemoteException { }
 
     @Override
     public boolean dropForAccessibility(IWindow window, int x, int y) {
diff --git a/core/java/android/window/OnBackInvokedCallbackInfo.aidl b/core/java/android/window/OnBackInvokedCallbackInfo.aidl
new file mode 100644
index 0000000..2f55bb1
--- /dev/null
+++ b/core/java/android/window/OnBackInvokedCallbackInfo.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2021 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.window;
+
+/** @hide */
+parcelable OnBackInvokedCallbackInfo;
diff --git a/core/java/android/window/OnBackInvokedCallbackInfo.java b/core/java/android/window/OnBackInvokedCallbackInfo.java
new file mode 100644
index 0000000..6480da3
--- /dev/null
+++ b/core/java/android/window/OnBackInvokedCallbackInfo.java
@@ -0,0 +1,85 @@
+/*
+ * 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.window;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Data object to hold an {@link IOnBackInvokedCallback} and its priority.
+ * @hide
+ */
+public final class OnBackInvokedCallbackInfo implements Parcelable {
+    @NonNull
+    private final IOnBackInvokedCallback mCallback;
+    private @OnBackInvokedDispatcher.Priority int mPriority;
+
+    public OnBackInvokedCallbackInfo(@NonNull IOnBackInvokedCallback callback, int priority) {
+        mCallback = callback;
+        mPriority = priority;
+    }
+
+    private OnBackInvokedCallbackInfo(@NonNull Parcel in) {
+        mCallback = IOnBackInvokedCallback.Stub.asInterface(in.readStrongBinder());
+        mPriority = in.readInt();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeStrongInterface(mCallback);
+        dest.writeInt(mPriority);
+    }
+
+    public static final Creator<OnBackInvokedCallbackInfo> CREATOR =
+            new Creator<OnBackInvokedCallbackInfo>() {
+                @Override
+                public OnBackInvokedCallbackInfo createFromParcel(Parcel in) {
+                    return new OnBackInvokedCallbackInfo(in);
+                }
+
+                @Override
+                public OnBackInvokedCallbackInfo[] newArray(int size) {
+                    return new OnBackInvokedCallbackInfo[size];
+                }
+            };
+
+    public boolean isSystemCallback() {
+        return mPriority == OnBackInvokedDispatcher.PRIORITY_SYSTEM;
+    }
+
+    @NonNull
+    public IOnBackInvokedCallback getCallback() {
+        return mCallback;
+    }
+
+    @OnBackInvokedDispatcher.Priority
+    public int getPriority() {
+        return mPriority;
+    }
+
+    @Override
+    public String toString() {
+        return "OnBackInvokedCallbackInfo{"
+                + "mCallback=" + mCallback + ", mPriority=" + mPriority + '}';
+    }
+}
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index cad8b9b..781859c 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -161,11 +161,12 @@
         }
         try {
             if (callback == null) {
-                mWindowSession.setOnBackInvokedCallback(mWindow, null, PRIORITY_DEFAULT);
+                mWindowSession.setOnBackInvokedCallbackInfo(mWindow, null);
             } else {
                 int priority = mAllCallbacks.get(callback);
-                mWindowSession.setOnBackInvokedCallback(
-                        mWindow, new OnBackInvokedCallbackWrapper(callback), priority);
+                mWindowSession.setOnBackInvokedCallbackInfo(
+                        mWindow, new OnBackInvokedCallbackInfo(
+                                new OnBackInvokedCallbackWrapper(callback), priority));
             }
             if (DEBUG && callback == null) {
                 Log.d(TAG, TextUtils.formatSimple("setTopOnBackInvokedCallback(null) Callers:%s",
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index 40ca9fb..43be031 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.accessibility;
 
+import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
 import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
 
@@ -107,6 +108,8 @@
 
     private final Context mContext;
     private final Handler mHandler;
+    private final UserSetupCompleteObserver  mUserSetupCompleteObserver;
+
     private AlertDialog mAlertDialog;
     private boolean mIsShortcutEnabled;
     private boolean mEnabledOnLockScreen;
@@ -114,11 +117,11 @@
 
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({
-            DialogStaus.NOT_SHOWN,
-            DialogStaus.SHOWN,
+            DialogStatus.NOT_SHOWN,
+            DialogStatus.SHOWN,
     })
     /** Denotes the user shortcut type. */
-    private @interface DialogStaus {
+    private @interface DialogStatus {
         int NOT_SHOWN = 0;
         int SHOWN  = 1;
     }
@@ -163,6 +166,7 @@
         mContext = context;
         mHandler = handler;
         mUserId = initialUserId;
+        mUserSetupCompleteObserver = new UserSetupCompleteObserver(handler, initialUserId);
 
         // Keep track of state of shortcut settings
         final ContentObserver co = new ContentObserver(handler) {
@@ -188,6 +192,7 @@
     public void setCurrentUser(int currentUserId) {
         mUserId = currentUserId;
         onSettingsChanged();
+        mUserSetupCompleteObserver.onUserSwitched(currentUserId);
     }
 
     /**
@@ -206,7 +211,7 @@
         final ContentResolver cr = mContext.getContentResolver();
         // Enable the shortcut from the lockscreen by default if the dialog has been shown
         final int dialogAlreadyShown = Settings.Secure.getIntForUser(
-                cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStaus.NOT_SHOWN,
+                cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStatus.NOT_SHOWN,
                 mUserId);
         mEnabledOnLockScreen = Settings.Secure.getIntForUser(
                 cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN,
@@ -222,7 +227,7 @@
         final ContentResolver cr = mContext.getContentResolver();
         final int userId = ActivityManager.getCurrentUser();
         final int dialogAlreadyShown = Settings.Secure.getIntForUser(
-                cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStaus.NOT_SHOWN,
+                cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStatus.NOT_SHOWN,
                 userId);
         // Play a notification vibration
         Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
@@ -234,7 +239,7 @@
             vibrator.vibrate(vibePattern, -1, VIBRATION_ATTRIBUTES);
         }
 
-        if (dialogAlreadyShown == 0) {
+        if (dialogAlreadyShown == DialogStatus.NOT_SHOWN) {
             // The first time, we show a warning rather than toggle the service to give the user a
             // chance to turn off this feature before stuff gets enabled.
             mAlertDialog = createShortcutWarningDialog(userId);
@@ -250,7 +255,7 @@
             w.setAttributes(attr);
             mAlertDialog.show();
             Settings.Secure.putIntForUser(
-                    cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStaus.SHOWN,
+                    cr, Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, DialogStatus.SHOWN,
                     userId);
         } else {
             playNotificationTone();
@@ -320,13 +325,13 @@
                             // If canceled, treat as if the dialog has never been shown
                             Settings.Secure.putIntForUser(mContext.getContentResolver(),
                                     Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
-                                    DialogStaus.NOT_SHOWN, userId);
+                                    DialogStatus.NOT_SHOWN, userId);
                         })
                 .setOnCancelListener((DialogInterface d) -> {
                     // If canceled, treat as if the dialog has never been shown
                     Settings.Secure.putIntForUser(mContext.getContentResolver(),
                             Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
-                            DialogStaus.NOT_SHOWN, userId);
+                            DialogStatus.NOT_SHOWN, userId);
                 })
                 .create();
         return alertDialog;
@@ -398,7 +403,7 @@
         AccessibilityManager accessibilityManager =
                 mFrameworkObjectProvider.getAccessibilityManagerInstance(mContext);
         return accessibilityManager.getEnabledAccessibilityServiceList(
-                AccessibilityServiceInfo.FEEDBACK_ALL_MASK).contains(serviceInfo);
+                FEEDBACK_ALL_MASK).contains(serviceInfo);
     }
 
     private boolean hasFeatureLeanback() {
@@ -559,6 +564,97 @@
         }
     }
 
+    private class UserSetupCompleteObserver extends ContentObserver {
+
+        private boolean mIsRegistered = false;
+        private int mUserId;
+
+        /**
+         * Creates a content observer.
+         *
+         * @param handler The handler to run {@link #onChange} on, or null if none.
+         * @param userId The current user id.
+         */
+        UserSetupCompleteObserver(Handler handler, int userId) {
+            super(handler);
+            mUserId = userId;
+            if (!isUserSetupComplete()) {
+                registerObserver();
+            }
+        }
+
+        private boolean isUserSetupComplete() {
+            return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.USER_SETUP_COMPLETE, 0, mUserId) == 1;
+        }
+
+        private void registerObserver() {
+            if (mIsRegistered) {
+                return;
+            }
+            mContext.getContentResolver().registerContentObserver(
+                    Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE),
+                    false, this, mUserId);
+            mIsRegistered = true;
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            if (isUserSetupComplete()) {
+                unregisterObserver();
+                setEmptyShortcutTargetIfNeeded();
+            }
+        }
+
+        private void unregisterObserver() {
+            if (!mIsRegistered) {
+                return;
+            }
+            mContext.getContentResolver().unregisterContentObserver(this);
+            mIsRegistered = false;
+        }
+
+        /**
+         * Sets empty shortcut target if shortcut targets is not assigned and there is no any
+         * enabled service matching the default target after the setup wizard completed.
+         *
+         */
+        private void setEmptyShortcutTargetIfNeeded() {
+            final ContentResolver contentResolver = mContext.getContentResolver();
+
+            final String shortcutTargets = Settings.Secure.getStringForUser(contentResolver,
+                    Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, mUserId);
+            if (shortcutTargets != null) {
+                return;
+            }
+
+            final String defaultShortcutTarget = mContext.getString(
+                    R.string.config_defaultAccessibilityService);
+            final List<AccessibilityServiceInfo> enabledServices =
+                    mFrameworkObjectProvider.getAccessibilityManagerInstance(
+                            mContext).getEnabledAccessibilityServiceList(FEEDBACK_ALL_MASK);
+            for (int i = enabledServices.size() - 1; i >= 0; i--) {
+                if (TextUtils.equals(defaultShortcutTarget, enabledServices.get(i).getId())) {
+                    return;
+                }
+            }
+
+            Settings.Secure.putStringForUser(contentResolver,
+                    Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "", mUserId);
+        }
+
+        void onUserSwitched(int userId) {
+            if (mUserId == userId) {
+                return;
+            }
+            unregisterObserver();
+            mUserId = userId;
+            if (!isUserSetupComplete()) {
+                registerObserver();
+            }
+        }
+    }
+
     /**
      * Immutable class to hold info about framework features that can be controlled by shortcut
      */
diff --git a/core/java/com/android/internal/app/LocalePickerWithRegion.java b/core/java/com/android/internal/app/LocalePickerWithRegion.java
index 213af26..9fe4d67 100644
--- a/core/java/com/android/internal/app/LocalePickerWithRegion.java
+++ b/core/java/com/android/internal/app/LocalePickerWithRegion.java
@@ -63,6 +63,7 @@
     private int mFirstVisiblePosition = 0;
     private int mTopDistance = 0;
     private String mAppPackageName;
+    private CharSequence mTitle = null;
 
     /**
      * Other classes can register to be notified when a locale was selected.
@@ -213,6 +214,7 @@
             return;
         }
 
+        mTitle = getActivity().getTitle();
         final boolean countryMode = mParentLocale != null;
         final Locale sortingLocale = countryMode ? mParentLocale.getLocale() : Locale.getDefault();
         mAdapter = new SuggestedLocaleAdapter(mLocaleList, countryMode, mAppPackageName);
@@ -248,7 +250,7 @@
         if (mParentLocale != null) {
             getActivity().setTitle(mParentLocale.getFullNameNative());
         } else {
-            getActivity().setTitle(R.string.language_selection_title);
+            getActivity().setTitle(mTitle);
         }
 
         getListView().requestFocus();
diff --git a/core/java/com/android/internal/os/RoSystemProperties.java b/core/java/com/android/internal/os/RoSystemProperties.java
index 8b659f9..98d81c9 100644
--- a/core/java/com/android/internal/os/RoSystemProperties.java
+++ b/core/java/com/android/internal/os/RoSystemProperties.java
@@ -60,14 +60,10 @@
     public static final CryptoProperties.type_values CRYPTO_TYPE =
             CryptoProperties.type().orElse(CryptoProperties.type_values.NONE);
     // These are pseudo-properties
-    public static final boolean CRYPTO_ENCRYPTABLE =
-            CRYPTO_STATE != CryptoProperties.state_values.UNSUPPORTED;
     public static final boolean CRYPTO_ENCRYPTED =
             CRYPTO_STATE == CryptoProperties.state_values.ENCRYPTED;
     public static final boolean CRYPTO_FILE_ENCRYPTED =
             CRYPTO_TYPE == CryptoProperties.type_values.FILE;
-    public static final boolean CRYPTO_BLOCK_ENCRYPTED =
-            CRYPTO_TYPE == CryptoProperties.type_values.BLOCK;
 
     public static final boolean CONTROL_PRIVAPP_PERMISSIONS_LOG =
             "log".equalsIgnoreCase(CONTROL_PRIVAPP_PERMISSIONS);
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d5fc14e..8aed76f 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -234,9 +234,9 @@
     <!-- Displayed to tell the user that they should switch their network preference. -->
     <string name="NetworkPreferenceSwitchSummary">Try changing preferred network. Tap to change.</string>
     <!-- Displayed to tell the user that emergency calls might not be available. -->
-    <string name="EmergencyCallWarningTitle">Emergency calls may be unavailable</string>
+    <string name="EmergencyCallWarningTitle">Emergency calling unavailable</string>
     <!-- Displayed to tell the user that emergency calls might not be available. -->
-    <string name="EmergencyCallWarningSummary"><xliff:g id="spn" example="Operator">%s</xliff:g> doesn\'t support emergency calls over Wi-Fi. Tap for details.</string>
+    <string name="EmergencyCallWarningSummary">Can\u2019t make emergency calls over Wi\u2011Fi</string>
 
     <!-- Telephony notification channel name for a channel containing network alert notifications. -->
     <string name="notification_channel_network_alert">Alerts</string>
diff --git a/core/tests/coretests/src/android/util/SparseSetArrayTest.java b/core/tests/coretests/src/android/util/SparseSetArrayTest.java
new file mode 100644
index 0000000..e781547
--- /dev/null
+++ b/core/tests/coretests/src/android/util/SparseSetArrayTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.util;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link SparseSetArray}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SparseSetArrayTest {
+    @Test
+    public void testAddAll() {
+        final SparseSetArray<Integer> sparseSetArray = new SparseSetArray<>();
+
+        for (int i = 0; i < 5; ++i) {
+            final ArraySet<Integer> array = new ArraySet<>();
+            for (int j = 100; j < 110; ++j) {
+                array.add(j);
+                // Test that addAll with some duplicates won't result in duplicates inside the
+                // data structure.
+                if (i % 2 == 0) {
+                    sparseSetArray.add(i, j);
+                }
+            }
+            sparseSetArray.addAll(i, array);
+            assertThat(sparseSetArray.get(i)).isEqualTo(array);
+        }
+
+        assertThat(sparseSetArray.size()).isEqualTo(5);
+    }
+}
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index 6aa5be5..c57aa74 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -16,6 +16,7 @@
 
 package android.window;
 
+import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
@@ -73,24 +74,23 @@
 
     @Test
     public void propagatesTopCallback_samePriority() throws RemoteException {
-        ArgumentCaptor<IOnBackInvokedCallback> captor =
-                ArgumentCaptor.forClass(IOnBackInvokedCallback.class);
+        ArgumentCaptor<OnBackInvokedCallbackInfo> captor =
+                ArgumentCaptor.forClass(OnBackInvokedCallbackInfo.class);
 
         mDispatcher.registerOnBackInvokedCallback(
                 OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCallback1);
         mDispatcher.registerOnBackInvokedCallback(
                 OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCallback2);
 
-        verify(mWindowSession, times(2)).setOnBackInvokedCallback(
+        verify(mWindowSession, times(2)).setOnBackInvokedCallbackInfo(
                 Mockito.eq(mWindow),
-                captor.capture(),
-                Mockito.eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT));
-        captor.getAllValues().get(0).onBackStarted();
+                captor.capture());
+        captor.getAllValues().get(0).getCallback().onBackStarted();
         waitForIdle();
         verify(mCallback1).onBackStarted();
         verifyZeroInteractions(mCallback2);
 
-        captor.getAllValues().get(1).onBackStarted();
+        captor.getAllValues().get(1).getCallback().onBackStarted();
         waitForIdle();
         verify(mCallback2).onBackStarted();
         verifyNoMoreInteractions(mCallback1);
@@ -98,19 +98,19 @@
 
     @Test
     public void propagatesTopCallback_differentPriority() throws RemoteException {
-        ArgumentCaptor<IOnBackInvokedCallback> captor =
-                ArgumentCaptor.forClass(IOnBackInvokedCallback.class);
+        ArgumentCaptor<OnBackInvokedCallbackInfo> captor =
+                ArgumentCaptor.forClass(OnBackInvokedCallbackInfo.class);
 
         mDispatcher.registerOnBackInvokedCallback(
                 OnBackInvokedDispatcher.PRIORITY_OVERLAY, mCallback1);
         mDispatcher.registerOnBackInvokedCallback(
                 OnBackInvokedDispatcher.PRIORITY_DEFAULT, mCallback2);
 
-        verify(mWindowSession).setOnBackInvokedCallback(
-                Mockito.eq(mWindow), captor.capture(),
-                Mockito.eq(OnBackInvokedDispatcher.PRIORITY_OVERLAY));
+        verify(mWindowSession).setOnBackInvokedCallbackInfo(
+                Mockito.eq(mWindow), captor.capture());
         verifyNoMoreInteractions(mWindowSession);
-        captor.getValue().onBackStarted();
+        assertEquals(captor.getValue().getPriority(), OnBackInvokedDispatcher.PRIORITY_OVERLAY);
+        captor.getValue().getCallback().onBackStarted();
         waitForIdle();
         verify(mCallback1).onBackStarted();
     }
@@ -127,17 +127,14 @@
         verifyZeroInteractions(mWindowSession);
 
         mDispatcher.unregisterOnBackInvokedCallback(mCallback2);
-        verify(mWindowSession).setOnBackInvokedCallback(
-                Mockito.eq(mWindow),
-                isNull(),
-                Mockito.eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT));
+        verify(mWindowSession).setOnBackInvokedCallbackInfo(Mockito.eq(mWindow), isNull());
     }
 
 
     @Test
     public void propagatesTopCallback_sameInstanceAddedTwice() throws RemoteException {
-        ArgumentCaptor<IOnBackInvokedCallback> captor =
-                ArgumentCaptor.forClass(IOnBackInvokedCallback.class);
+        ArgumentCaptor<OnBackInvokedCallbackInfo> captor =
+                ArgumentCaptor.forClass(OnBackInvokedCallbackInfo.class);
 
         mDispatcher.registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_OVERLAY,
                 mCallback1
@@ -150,11 +147,8 @@
         reset(mWindowSession);
         mDispatcher.registerOnBackInvokedCallback(
                 OnBackInvokedDispatcher.PRIORITY_OVERLAY, mCallback2);
-        verify(mWindowSession).setOnBackInvokedCallback(
-                Mockito.eq(mWindow),
-                captor.capture(),
-                Mockito.eq(OnBackInvokedDispatcher.PRIORITY_OVERLAY));
-        captor.getValue().onBackStarted();
+        verify(mWindowSession).setOnBackInvokedCallbackInfo(Mockito.eq(mWindow), captor.capture());
+        captor.getValue().getCallback().onBackStarted();
         waitForIdle();
         verify(mCallback2).onBackStarted();
     }
diff --git a/data/etc/displayconfig/default_television.xml b/data/etc/displayconfig/default_television.xml
index 2540f59..0d66110 100644
--- a/data/etc/displayconfig/default_television.xml
+++ b/data/etc/displayconfig/default_television.xml
@@ -1,5 +1,5 @@
 <displayConfiguration>
-    <densityMap>
+    <densityMapping>
          <density>
             <height>480</height>
             <width>720</width>
@@ -20,5 +20,5 @@
             <width>3840</width>
             <density>640</density>
          </density>
-    </densityMap>
+    </densityMapping>
 </displayConfiguration>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 80b144a..eb16394 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1351,12 +1351,6 @@
       "group": "WM_DEBUG_FOCUS_LIGHT",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
-    "-767349300": {
-      "message": "%s: Setting back callback %s. Client IWindow %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/WindowState.java"
-    },
     "-766059044": {
       "message": "Display id=%d selected orientation %s (%d), got rotation %s (%d)",
       "level": "VERBOSE",
@@ -1909,6 +1903,12 @@
       "group": "WM_DEBUG_SYNC_ENGINE",
       "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
     },
+    "-228813488": {
+      "message": "%s: Setting back callback %s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_BACK_PREVIEW",
+      "at": "com\/android\/server\/wm\/WindowState.java"
+    },
     "-208825711": {
       "message": "shouldWaitAnimatingExit: isWallpaperTarget: %s",
       "level": "DEBUG",
@@ -2377,12 +2377,6 @@
       "group": "WM_DEBUG_REMOTE_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
     },
-    "250620778": {
-      "message": "startBackNavigation task=%s, topRunningActivity=%s, applicationBackCallback=%s, systemBackCallback=%s, currentFocus=%s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
-    },
     "251812577": {
       "message": "Register display organizer=%s uid=%d",
       "level": "VERBOSE",
@@ -2785,12 +2779,6 @@
       "group": "WM_DEBUG_APP_TRANSITIONS",
       "at": "com\/android\/server\/wm\/WindowState.java"
     },
-    "599897753": {
-      "message": "Previous Activity is %s. Back type is %s",
-      "level": "DEBUG",
-      "group": "WM_DEBUG_BACK_PREVIEW",
-      "at": "com\/android\/server\/wm\/BackNavigationController.java"
-    },
     "600140673": {
       "message": "checkBootAnimationComplete: Waiting for anim complete",
       "level": "INFO",
@@ -3061,6 +3049,12 @@
       "group": "WM_DEBUG_REMOTE_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
     },
+    "878005951": {
+      "message": "startBackNavigation task=%s, topRunningActivity=%s, callbackInfo=%s, currentFocus=%s",
+      "level": "DEBUG",
+      "group": "WM_DEBUG_BACK_PREVIEW",
+      "at": "com\/android\/server\/wm\/BackNavigationController.java"
+    },
     "892244061": {
       "message": "Waiting for drawn %s: removed=%b visible=%b mHasSurface=%b drawState=%d",
       "level": "INFO",
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
index d5875c0..e270edb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
@@ -221,8 +221,7 @@
             }
             final Display display = mDisplayController.getDisplay(mDisplayId);
             SurfaceControlViewHost viewRoot =
-                    new SurfaceControlViewHost(
-                            view.getContext(), display, wwm, true /* useSfChoreographer */);
+                    new SurfaceControlViewHost(view.getContext(), display, wwm);
             attrs.flags |= FLAG_HARDWARE_ACCELERATED;
             viewRoot.setView(view, attrs);
             mViewRoots.put(view, viewRoot);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java
index 8f9636c..5a94fb6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellConcurrencyModule.java
@@ -19,7 +19,6 @@
 import static android.os.Process.THREAD_PRIORITY_DISPLAY;
 import static android.os.Process.THREAD_PRIORITY_TOP_APP_BOOST;
 
-import android.animation.AnimationHandler;
 import android.content.Context;
 import android.os.Build;
 import android.os.Handler;
@@ -29,11 +28,9 @@
 
 import androidx.annotation.Nullable;
 
-import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.HandlerExecutor;
 import com.android.wm.shell.common.ShellExecutor;
-import com.android.wm.shell.common.annotations.ChoreographerSfVsync;
 import com.android.wm.shell.common.annotations.ExternalMainThread;
 import com.android.wm.shell.common.annotations.ShellAnimationThread;
 import com.android.wm.shell.common.annotations.ShellMainThread;
@@ -171,28 +168,4 @@
         shellSplashscreenThread.start();
         return new HandlerExecutor(shellSplashscreenThread.getThreadHandler());
     }
-
-    /**
-     * Provide a Shell main-thread AnimationHandler.  The AnimationHandler can be set on
-     * {@link android.animation.ValueAnimator}s and will ensure that the animation will run on
-     * the Shell main-thread with the SF vsync.
-     */
-    @WMSingleton
-    @Provides
-    @ChoreographerSfVsync
-    public static AnimationHandler provideShellMainExecutorSfVsyncAnimationHandler(
-            @ShellMainThread ShellExecutor mainExecutor) {
-        try {
-            AnimationHandler handler = new AnimationHandler();
-            mainExecutor.executeBlocking(() -> {
-                // This is called on the animation thread since it calls
-                // Choreographer.getSfInstance() which returns a thread-local Choreographer instance
-                // that uses the SF vsync
-                handler.setProvider(new SfVsyncFrameCallbackProvider());
-            });
-            return handler;
-        } catch (InterruptedException e) {
-            throw new RuntimeException("Failed to initialize SfVsync animation handler in 1s", e);
-        }
-    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 7f9ecca2..965bd26 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -16,7 +16,6 @@
 
 package com.android.wm.shell.dagger;
 
-import android.animation.AnimationHandler;
 import android.content.Context;
 import android.content.pm.LauncherApps;
 import android.os.Handler;
@@ -42,7 +41,6 @@
 import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.common.TransactionPool;
-import com.android.wm.shell.common.annotations.ChoreographerSfVsync;
 import com.android.wm.shell.common.annotations.ShellMainThread;
 import com.android.wm.shell.freeform.FreeformTaskListener;
 import com.android.wm.shell.fullscreen.FullscreenUnfoldController;
@@ -182,11 +180,10 @@
             DisplayImeController displayImeController, TransactionPool transactionPool,
             ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue,
             TaskStackListenerImpl taskStackListener, Transitions transitions,
-            @ShellMainThread ShellExecutor mainExecutor,
-            @ChoreographerSfVsync AnimationHandler sfVsyncAnimationHandler) {
+            @ShellMainThread ShellExecutor mainExecutor) {
         return new LegacySplitScreenController(context, displayController, systemWindows,
                 displayImeController, transactionPool, shellTaskOrganizer, syncQueue,
-                taskStackListener, transitions, mainExecutor, sfVsyncAnimationHandler);
+                taskStackListener, transitions, mainExecutor);
     }
 
     @WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java
index 067f808..e28c58c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java
@@ -25,7 +25,6 @@
 import static com.android.wm.shell.common.split.DividerView.TOUCH_ANIMATION_DURATION;
 import static com.android.wm.shell.common.split.DividerView.TOUCH_RELEASE_ANIMATION_DURATION;
 
-import android.animation.AnimationHandler;
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
@@ -142,7 +141,6 @@
     private DividerImeController mImeController;
     private DividerCallbacks mCallback;
 
-    private AnimationHandler mSfVsyncAnimationHandler;
     private ValueAnimator mCurrentAnimator;
     private boolean mEntranceAnimationRunning;
     private boolean mExitAnimationRunning;
@@ -279,10 +277,6 @@
         mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
     }
 
-    public void setAnimationHandler(AnimationHandler sfVsyncAnimationHandler) {
-        mSfVsyncAnimationHandler = sfVsyncAnimationHandler;
-    }
-
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
@@ -674,7 +668,6 @@
             }
         });
         mCurrentAnimator = anim;
-        mCurrentAnimator.setAnimationHandler(mSfVsyncAnimationHandler);
         return anim;
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
index 67e487d..8b66792 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java
@@ -25,7 +25,6 @@
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.view.Display.DEFAULT_DISPLAY;
 
-import android.animation.AnimationHandler;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityTaskManager;
@@ -82,7 +81,6 @@
     private final DividerState mDividerState = new DividerState();
     private final ForcedResizableInfoActivityController mForcedResizableController;
     private final ShellExecutor mMainExecutor;
-    private final AnimationHandler mSfVsyncAnimationHandler;
     private final LegacySplitScreenTaskListener mSplits;
     private final SystemWindows mSystemWindows;
     final TransactionPool mTransactionPool;
@@ -118,13 +116,12 @@
             DisplayImeController imeController, TransactionPool transactionPool,
             ShellTaskOrganizer shellTaskOrganizer, SyncTransactionQueue syncQueue,
             TaskStackListenerImpl taskStackListener, Transitions transitions,
-            ShellExecutor mainExecutor, AnimationHandler sfVsyncAnimationHandler) {
+            ShellExecutor mainExecutor) {
         mContext = context;
         mDisplayController = displayController;
         mSystemWindows = systemWindows;
         mImeController = imeController;
         mMainExecutor = mainExecutor;
-        mSfVsyncAnimationHandler = sfVsyncAnimationHandler;
         mForcedResizableController = new ForcedResizableInfoActivityController(context, this,
                 mainExecutor);
         mTransactionPool = transactionPool;
@@ -314,7 +311,6 @@
         Context dctx = mDisplayController.getDisplayContext(mContext.getDisplayId());
         mView = (DividerView)
                 LayoutInflater.from(dctx).inflate(R.layout.docked_stack_divider, null);
-        mView.setAnimationHandler(mSfVsyncAnimationHandler);
         DisplayLayout displayLayout = mDisplayController.getDisplayLayout(mContext.getDisplayId());
         mView.injectDependencies(this, mWindowManager, mDividerState, mForcedResizableController,
                 mSplits, mSplitLayout, mImePositionProcessor, mWindowManagerProxy);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt
index 239ea38e..4e8e71b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipKeepClearAlgorithm.kt
@@ -416,7 +416,7 @@
         return stashCandidates.minByOrNull {
             val dx = abs(it.left - bounds.left)
             val dy = abs(it.top - bounds.top)
-            dx * bounds.height() + dy * bounds.width()
+            return@minByOrNull dx + dy
         }!!
     }
 
diff --git a/packages/SettingsLib/res/drawable/settings_input_antenna.xml b/packages/SettingsLib/res/drawable/settings_input_antenna.xml
new file mode 100644
index 0000000..4822680
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/settings_input_antenna.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp"
+        android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"
+        android:tint="?attr/colorControlNormal">
+    <path android:fillColor="@android:color/white"
+          android:pathData="M9,22.4 L7.6,21 11,17.6V14.3Q10.325,14 9.913,13.375Q9.5,12.75 9.5,12Q9.5,10.95 10.225,10.225Q10.95,9.5 12,9.5Q13.05,9.5 13.775,10.225Q14.5,10.95 14.5,12Q14.5,12.75 14.088,13.375Q13.675,14 13,14.3V17.6L16.4,21L15,22.4L12,19.4ZM5,12Q5,9.05 7.05,7.025Q9.1,5 12,5Q14.9,5 16.95,7.025Q19,9.05 19,12H17Q17,9.925 15.538,8.462Q14.075,7 12,7Q9.925,7 8.463,8.462Q7,9.925 7,12ZM1,12Q1,9.7 1.863,7.7Q2.725,5.7 4.225,4.212Q5.725,2.725 7.725,1.862Q9.725,1 12,1Q14.275,1 16.275,1.862Q18.275,2.725 19.775,4.212Q21.275,5.7 22.138,7.7Q23,9.7 23,12H21Q21,10.125 20.288,8.487Q19.575,6.85 18.35,5.625Q17.125,4.4 15.488,3.7Q13.85,3 12,3Q10.15,3 8.512,3.7Q6.875,4.4 5.65,5.625Q4.425,6.85 3.712,8.487Q3,10.125 3,12Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 42cfeb1..6951c10 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1627,4 +1627,13 @@
     <string name="bt_le_audio_scan_qr_code_scanner">To start listening, center the QR code below</string>
     <!-- [CHAR LIMIT=NONE] Hint for QR code process failure -->
     <string name="bt_le_audio_qr_code_is_not_valid_format">QR code isn\u0027t a valid format</string>
+
+    <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, title -->
+    <string name="bt_le_audio_broadcast_dialog_title">Stop broadcasting <xliff:g id="app_name" example="App Name 1">%1$s</xliff:g>?</string>
+    <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, sub-title -->
+    <string name="bt_le_audio_broadcast_dialog_sub_title">If you broadcast <xliff:g id="switchApp" example="App Name 2">%1$s</xliff:g> or change the output, your current broadcast will stop</string>
+    <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, switch to others app. -->
+    <string name="bt_le_audio_broadcast_dialog_switch_app">Broadcast <xliff:g id="switchApp" example="App Name 2">%1$s</xliff:g></string>
+    <!-- [CHAR LIMIT=NONE] Le audio broadcast dialog, different output. -->
+    <string name="bt_le_audio_broadcast_dialog_different_output">Change output</string>
 </resources>
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
index 179a498..5399f8a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/MediaDeviceTest.java
@@ -224,14 +224,14 @@
     }
 
     @Test
-    public void compareTo_carKit_phone_carKitFirst() {
+    public void compareTo_carKit_phone_phoneFirst() {
         when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass);
-        mMediaDevices.add(mPhoneMediaDevice);
         mMediaDevices.add(mBluetoothMediaDevice1);
+        mMediaDevices.add(mPhoneMediaDevice);
 
-        assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice);
-        Collections.sort(mMediaDevices, COMPARATOR);
         assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1);
+        Collections.sort(mMediaDevices, COMPARATOR);
+        assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice);
     }
 
     @Test
@@ -305,13 +305,13 @@
     }
 
     @Test
-    public void compareTo_bluetooth_phone_bluetoothFirst() {
-        mMediaDevices.add(mPhoneMediaDevice);
+    public void compareTo_bluetooth_phone_phoneFirst() {
         mMediaDevices.add(mBluetoothMediaDevice1);
+        mMediaDevices.add(mPhoneMediaDevice);
 
-        assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice);
-        Collections.sort(mMediaDevices, COMPARATOR);
         assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1);
+        Collections.sort(mMediaDevices, COMPARATOR);
+        assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice);
     }
 
     @Test
@@ -384,7 +384,7 @@
     // 5.mBluetoothMediaDevice2: * 2 times usage
     // 6.mBluetoothMediaDevice3: * 1 time usage
     // 7.mPhoneMediaDevice:      * 0 time usage
-    // Order: 2 -> 5 -> 6 -> 1 -> 3 -> 4 -> 7
+    // Order: 7 -> 2 -> 5 -> 6 -> 1 -> 3 -> 4
     @Test
     public void compareTo_mixedDevices_carKitFirst() {
         when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass);
@@ -406,13 +406,13 @@
         mInfoMediaDevice1.connect();
 
         Collections.sort(mMediaDevices, COMPARATOR);
-        assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice1);
-        assertThat(mMediaDevices.get(1)).isEqualTo(mBluetoothMediaDevice2);
-        assertThat(mMediaDevices.get(2)).isEqualTo(mBluetoothMediaDevice3);
-        assertThat(mMediaDevices.get(3)).isEqualTo(mInfoMediaDevice1);
-        assertThat(mMediaDevices.get(4)).isEqualTo(mInfoMediaDevice2);
-        assertThat(mMediaDevices.get(5)).isEqualTo(mInfoMediaDevice3);
-        assertThat(mMediaDevices.get(6)).isEqualTo(mPhoneMediaDevice);
+        assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice);
+        assertThat(mMediaDevices.get(1)).isEqualTo(mBluetoothMediaDevice1);
+        assertThat(mMediaDevices.get(2)).isEqualTo(mBluetoothMediaDevice2);
+        assertThat(mMediaDevices.get(3)).isEqualTo(mBluetoothMediaDevice3);
+        assertThat(mMediaDevices.get(4)).isEqualTo(mInfoMediaDevice1);
+        assertThat(mMediaDevices.get(5)).isEqualTo(mInfoMediaDevice2);
+        assertThat(mMediaDevices.get(6)).isEqualTo(mInfoMediaDevice3);
     }
 
     // 1.mInfoMediaDevice1:      Last Selected device
@@ -422,7 +422,7 @@
     // 5.mBluetoothMediaDevice2: * 4 times usage not connected
     // 6.mBluetoothMediaDevice3: * 1 time usage
     // 7.mPhoneMediaDevice:      * 0 time usage
-    // Order: 6 -> 1 -> 3 -> 4 -> 7 -> 2 -> 5
+    // Order: 7 -> 6 -> 1 -> 3 -> 4 -> 2 -> 5
     @Test
     public void compareTo_mixedDevices_connectDeviceFirst() {
         when(mDevice1.getBluetoothClass()).thenReturn(mCarkitClass);
@@ -448,11 +448,11 @@
         mInfoMediaDevice1.connect();
 
         Collections.sort(mMediaDevices, COMPARATOR);
-        assertThat(mMediaDevices.get(0)).isEqualTo(mBluetoothMediaDevice3);
-        assertThat(mMediaDevices.get(1)).isEqualTo(mInfoMediaDevice1);
-        assertThat(mMediaDevices.get(2)).isEqualTo(mInfoMediaDevice2);
-        assertThat(mMediaDevices.get(3)).isEqualTo(mInfoMediaDevice3);
-        assertThat(mMediaDevices.get(4)).isEqualTo(mPhoneMediaDevice);
+        assertThat(mMediaDevices.get(0)).isEqualTo(mPhoneMediaDevice);
+        assertThat(mMediaDevices.get(1)).isEqualTo(mBluetoothMediaDevice3);
+        assertThat(mMediaDevices.get(2)).isEqualTo(mInfoMediaDevice1);
+        assertThat(mMediaDevices.get(3)).isEqualTo(mInfoMediaDevice2);
+        assertThat(mMediaDevices.get(4)).isEqualTo(mInfoMediaDevice3);
         assertThat(mMediaDevices.get(5)).isEqualTo(mBluetoothMediaDevice1);
         assertThat(mMediaDevices.get(6)).isEqualTo(mBluetoothMediaDevice2);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index fab19d6..0f45a75 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -327,7 +327,8 @@
     private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() {
         @Override
         public void onConnectionChanged(boolean isConnected) {
-            mView.updateStates();
+            mView.onOverviewProxyConnectionChange(
+                    mOverviewProxyService.isEnabled(), mOverviewProxyService.shouldShowSwipeUpUI());
             updateScreenPinningGestures();
         }
 
@@ -557,11 +558,10 @@
 
     @Override
     public void onInit() {
-        // TODO: A great deal of this code should probalby live in onViewAttached.
+        // TODO: A great deal of this code should probably live in onViewAttached.
         // It should also has corresponding cleanup in onViewDetached.
         mView.setTouchHandler(mTouchHandler);
         mView.setNavBarMode(mNavBarMode);
-
         mView.updateRotationButton();
 
         mView.setVisibility(
@@ -637,6 +637,12 @@
         mView.setWindowVisible(isNavBarWindowVisible());
         mView.setBehavior(mBehavior);
         mView.setNavBarMode(mNavBarMode);
+        mView.setUpdateActiveTouchRegionsCallback(
+                () -> mOverviewProxyService.onActiveNavBarRegionChanges(
+                        mView.getButtonLocations(
+                                true /* includeFloatingButtons */,
+                                true /* inScreen */,
+                                true /* useNearestRegion */)));
 
         mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
 
@@ -697,6 +703,7 @@
         final RotationButtonController rotationButtonController =
                 mView.getRotationButtonController();
         rotationButtonController.setRotationCallback(null);
+        mView.setUpdateActiveTouchRegionsCallback(null);
         mView.getBarTransitions().destroy();
         mView.getLightTransitionsController().destroy(mContext);
         mOverviewProxyService.removeCallback(mOverviewProxyListener);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index 40265a3..abff914 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -77,7 +77,6 @@
 import com.android.systemui.navigationbar.buttons.NearestTouchFrame;
 import com.android.systemui.navigationbar.buttons.RotationContextButton;
 import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
-import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
 import com.android.systemui.shared.rotation.FloatingRotationButton;
@@ -142,7 +141,6 @@
     private final DeadZone mDeadZone;
     private boolean mDeadZoneConsuming = false;
     private final NavigationBarTransitions mBarTransitions;
-    private final OverviewProxyService mOverviewProxyService;
     @Nullable
     private AutoHideController mAutoHideController;
 
@@ -198,6 +196,9 @@
      */
     private final boolean mImeCanRenderGesturalNavButtons = canImeRenderGesturalNavButtons();
     private Gefingerpoken mTouchHandler;
+    private boolean mOverviewProxyEnabled;
+    private boolean mShowSwipeUpUi;
+    private UpdateActiveTouchRegionsCallback mUpdateActiveTouchRegionsCallback;
 
     private class NavTransitionListener implements TransitionListener {
         private boolean mBackTransitioning;
@@ -364,8 +365,6 @@
                 R.drawable.ic_sysbar_rotate_button_cw_start_90,
                 () -> getDisplay().getRotation());
 
-        mOverviewProxyService = Dependency.get(OverviewProxyService.class);
-
         mConfiguration = new Configuration();
         mTmpLastConfiguration = new Configuration();
         mConfiguration.updateFrom(context.getResources().getConfiguration());
@@ -562,7 +561,7 @@
     }
 
     private boolean isQuickStepSwipeUpEnabled() {
-        return mOverviewProxyService.shouldShowSwipeUpUI() && isOverviewEnabled();
+        return mShowSwipeUpUi && isOverviewEnabled();
     }
 
     private void reloadNavIcons() {
@@ -616,8 +615,7 @@
     }
 
     public KeyButtonDrawable getHomeDrawable() {
-        final boolean quickStepEnabled = mOverviewProxyService.shouldShowSwipeUpUI();
-        KeyButtonDrawable drawable = quickStepEnabled
+        KeyButtonDrawable drawable = mShowSwipeUpUi
                 ? getDrawable(R.drawable.ic_sysbar_home_quick_step)
                 : getDrawable(R.drawable.ic_sysbar_home);
         orientHomeButton(drawable);
@@ -640,7 +638,7 @@
 
         // Animate the back button's rotation to the new degrees and only in portrait move up the
         // back button to line up with the other buttons
-        float targetY = !mOverviewProxyService.shouldShowSwipeUpUI() && !mIsVertical && useAltBack
+        float targetY = !mShowSwipeUpUi && !mIsVertical && useAltBack
                 ? - getResources().getDimension(R.dimen.navbar_back_button_ime_offset)
                 : 0;
         ObjectAnimator navBarAnimator = ObjectAnimator.ofPropertyValuesHolder(drawable,
@@ -657,8 +655,7 @@
 
     private @DrawableRes int chooseNavigationIconDrawableRes(@DrawableRes int icon,
             @DrawableRes int quickStepIcon) {
-        final boolean quickStepEnabled = mOverviewProxyService.shouldShowSwipeUpUI();
-        return quickStepEnabled ? quickStepIcon : icon;
+        return mShowSwipeUpUi ? quickStepIcon : icon;
     }
 
     private KeyButtonDrawable getDrawable(@DrawableRes int icon) {
@@ -770,7 +767,7 @@
         // recents buttons when disconnected from launcher service in screen pinning mode,
         // as they are used for exiting.
         final boolean pinningActive = ActivityManagerWrapper.getInstance().isScreenPinningActive();
-        if (mOverviewProxyService.isEnabled()) {
+        if (mOverviewProxyEnabled) {
             // Force disable recents when not in legacy mode
             disableRecent |= !QuickStepContract.isLegacyMode(mNavBarMode);
             if (pinningActive && !QuickStepContract.isGesturalMode(mNavBarMode)) {
@@ -891,9 +888,14 @@
         }
     }
 
-    public void updateStates() {
-        final boolean showSwipeUpUI = mOverviewProxyService.shouldShowSwipeUpUI();
+    void onOverviewProxyConnectionChange(boolean enabled, boolean showSwipeUpUi) {
+        mOverviewProxyEnabled = enabled;
+        mShowSwipeUpUi = showSwipeUpUi;
+        updateStates();
+    }
 
+    /** */
+    public void updateStates() {
         if (mNavigationInflaterView != null) {
             // Reinflate the navbar if needed, no-op unless the swipe up state changes
             mNavigationInflaterView.onLikelyDefaultLayoutChange();
@@ -902,9 +904,10 @@
         updateSlippery();
         reloadNavIcons();
         updateNavButtonIcons();
-        WindowManagerWrapper.getInstance().setNavBarVirtualKeyHapticFeedbackEnabled(!showSwipeUpUI);
+        WindowManagerWrapper.getInstance().setNavBarVirtualKeyHapticFeedbackEnabled(
+                !mShowSwipeUpUi);
         getHomeButton().setAccessibilityDelegate(
-                showSwipeUpUI ? mQuickStepAccessibilityDelegate : null);
+                mShowSwipeUpUi ? mQuickStepAccessibilityDelegate : null);
     }
 
     /**
@@ -1010,9 +1013,14 @@
      * Notifies the overview service of the active touch regions.
      */
     public void notifyActiveTouchRegions() {
-        mOverviewProxyService.onActiveNavBarRegionChanges(
-                getButtonLocations(true /* includeFloatingButtons */, true /* inScreen */,
-                        true /* useNearestRegion */));
+        if (mUpdateActiveTouchRegionsCallback != null) {
+            mUpdateActiveTouchRegionsCallback.update();
+        }
+    }
+
+    void setUpdateActiveTouchRegionsCallback(UpdateActiveTouchRegionsCallback callback) {
+        mUpdateActiveTouchRegionsCallback = callback;
+        notifyActiveTouchRegions();
     }
 
     private void updateButtonTouchRegionCache() {
@@ -1030,8 +1038,10 @@
      * @param useNearestRegion Whether to use the nearest region instead of the actual button bounds
      * @return
      */
-    private Region getButtonLocations(boolean includeFloatingButtons, boolean inScreenSpace,
+    Region getButtonLocations(boolean includeFloatingButtons, boolean inScreenSpace,
             boolean useNearestRegion) {
+        // TODO: move this method to NavigationBar.
+        // TODO: don't use member variables for temp storage like mTmpRegion.
         if (useNearestRegion && !inScreenSpace) {
             // We currently don't support getting the nearest region in anything but screen space
             useNearestRegion = false;
@@ -1426,4 +1436,8 @@
             mRegionSamplingHelper.stop();
         }
     }
+
+    interface UpdateActiveTouchRegionsCallback {
+        void update();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
index 8f2a432..fc20ac2 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
@@ -138,7 +138,7 @@
 
         ensureOverlayRemoved()
 
-        val newRoot = SurfaceControlViewHost(context, context.display!!, wwm, false)
+        val newRoot = SurfaceControlViewHost(context, context.display!!, wwm)
         val newView =
             LightRevealScrim(context, null).apply {
                 revealEffect = createLightRevealEffect()
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 312105a..d7554cc 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -26,6 +26,7 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
+import android.app.ActivityOptions;
 import android.app.AlarmManager;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
@@ -970,13 +971,16 @@
             intent.setComponent(provider.getInfoLocked(mContext).configure);
             intent.setFlags(secureFlags);
 
+            final ActivityOptions options = ActivityOptions.makeBasic();
+            options.setIgnorePendingIntentCreatorForegroundState(true);
+
             // All right, create the sender.
             final long identity = Binder.clearCallingIdentity();
             try {
                 return PendingIntent.getActivityAsUser(
                         mContext, 0, intent, PendingIntent.FLAG_ONE_SHOT
                                 | PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT,
-                                null, new UserHandle(provider.getUserId()))
+                                options.toBundle(), new UserHandle(provider.getUserId()))
                         .getIntentSender();
             } finally {
                 Binder.restoreCallingIdentity(identity);
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 7ab3008..991c7a9 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -55,6 +55,7 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
+import android.app.ActivityOptions;
 import android.app.AnrController;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
@@ -3534,9 +3535,12 @@
                     appInfo.manageSpaceActivityName);
             intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
 
+            final ActivityOptions options = ActivityOptions.makeBasic();
+            options.setIgnorePendingIntentCreatorForegroundState(true);
+
             PendingIntent activity = PendingIntent.getActivity(targetAppContext, requestCode,
                     intent,
-                    FLAG_ONE_SHOT | FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE);
+                    FLAG_ONE_SHOT | FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE, options.toBundle());
             return activity;
         } catch (PackageManager.NameNotFoundException e) {
             throw new IllegalArgumentException(
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index 78df983..a562afb 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.os.Environment;
 import android.os.SystemClock;
@@ -162,16 +163,17 @@
     /**
      * Returns true if the jar is in a test APEX.
      */
-    private static boolean isJarInTestApex(String pathStr) {
+    private boolean isJarInTestApex(String pathStr) {
         Path path = Paths.get(pathStr);
         if (path.getNameCount() >= 2 && path.getName(0).toString().equals("apex")) {
             String apexModuleName = path.getName(1).toString();
             ApexManager apexManager = ApexManager.getInstance();
             String packageName = apexManager.getActivePackageNameForApexModuleName(apexModuleName);
-            PackageInfo packageInfo = apexManager.getPackageInfo(
-                    packageName, ApexManager.MATCH_ACTIVE_PACKAGE);
-            if (packageInfo != null) {
+            try {
+                PackageInfo packageInfo =  mContext.getPackageManager().getPackageInfo(packageName,
+                        PackageManager.PackageInfoFlags.of(PackageManager.MATCH_APEX));
                 return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_TEST_ONLY) != 0;
+            } catch (Exception ignore) {
             }
         }
         return false;
diff --git a/services/core/java/com/android/server/WallpaperUpdateReceiver.java b/services/core/java/com/android/server/WallpaperUpdateReceiver.java
index 629e882..9917892 100644
--- a/services/core/java/com/android/server/WallpaperUpdateReceiver.java
+++ b/services/core/java/com/android/server/WallpaperUpdateReceiver.java
@@ -16,13 +16,17 @@
 
 package com.android.server;
 
+import android.annotation.RequiresPermission;
 import android.app.ActivityThread;
+import android.app.WallpaperInfo;
 import android.app.WallpaperManager;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.os.AsyncTask;
+import android.os.ParcelFileDescriptor;
 import android.util.Slog;
 
 /**
@@ -50,6 +54,10 @@
             ActivityThread currentActivityThread = ActivityThread.currentActivityThread();
             Context uiContext = currentActivityThread.getSystemUiContext();
             WallpaperManager wallpaperManager = WallpaperManager.getInstance(uiContext);
+            if (isUserSetWallpaper(wallpaperManager, uiContext)) {
+                Slog.i(TAG, "User has set wallpaper, skip to resetting");
+                return;
+            }
             if (DEBUG) Slog.d(TAG, "Set customized default_wallpaper.");
             Bitmap blank = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
             // set a blank wallpaper to force a redraw of default_wallpaper
@@ -59,4 +67,32 @@
             Slog.w(TAG, "Failed to customize system wallpaper." + e);
         }
     }
+
+    /**
+     * A function to validate if users have set customized (live)wallpaper
+     * <p>
+     * return true if users have customized their wallpaper
+     **/
+    @RequiresPermission(android.Manifest.permission.READ_WALLPAPER_INTERNAL)
+    private boolean isUserSetWallpaper(WallpaperManager wm, Context context) {
+        WallpaperInfo info = wm.getWallpaperInfo();
+        if (info == null) {
+            //Image Wallpaper
+            ParcelFileDescriptor sysWallpaper =
+                    wm.getWallpaperFile(WallpaperManager.FLAG_SYSTEM);
+            ParcelFileDescriptor lockWallpaper =
+                    wm.getWallpaperFile(WallpaperManager.FLAG_LOCK);
+            if (sysWallpaper != null || lockWallpaper != null) {
+                return true;
+            }
+        } else {
+            //live wallpaper
+            ComponentName currCN = info.getComponent();
+            ComponentName defaultCN = WallpaperManager.getDefaultWallpaperComponent(context);
+            if (!currCN.equals(defaultCN)) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index 38de9a7..c835d2f 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -16,6 +16,8 @@
 
 package com.android.server.display;
 
+import static android.text.TextUtils.formatSimple;
+
 import android.annotation.Nullable;
 import android.content.pm.ApplicationInfo;
 import android.content.res.Resources;
@@ -36,6 +38,7 @@
 
 import java.io.PrintWriter;
 import java.util.Arrays;
+import java.util.Locale;
 import java.util.Objects;
 
 /**
@@ -994,25 +997,25 @@
                 Arrays.sort(luxes);
             }
 
-            StringBuffer sbLux = null;
-            StringBuffer sbNits = null;
-            StringBuffer sbLong = null;
-            StringBuffer sbShort = null;
-            StringBuffer sbBrightness = null;
-            StringBuffer sbPercent = null;
-            StringBuffer sbPercentHbm = null;
+            StringBuilder sbLux = null;
+            StringBuilder sbNits = null;
+            StringBuilder sbLong = null;
+            StringBuilder sbShort = null;
+            StringBuilder sbBrightness = null;
+            StringBuilder sbPercent = null;
+            StringBuilder sbPercentHbm = null;
             boolean needsHeaders = true;
             String separator = "";
             for (int i = 0; i < luxes.length; i++) {
                 float lux = luxes[i];
                 if (needsHeaders) {
-                    sbLux = new StringBuffer("           lux: ");
-                    sbNits = new StringBuffer("       default: ");
-                    sbLong = new StringBuffer("     long-term: ");
-                    sbShort = new StringBuffer("       current: ");
-                    sbBrightness = new StringBuffer("   current(bl): ");
-                    sbPercent = new StringBuffer("    current(%): ");
-                    sbPercentHbm = new StringBuffer(" current(%hbm): ");
+                    sbLux = new StringBuilder("            lux: ");
+                    sbNits = new StringBuilder("        default: ");
+                    sbLong = new StringBuilder("      long-term: ");
+                    sbShort = new StringBuilder("        current: ");
+                    sbBrightness = new StringBuilder("    current(bl): ");
+                    sbPercent = new StringBuilder("     current(%): ");
+                    sbPercentHbm = new StringBuilder("  current(hbm%): ");
                     needsHeaders = false;
                 }
 
@@ -1042,13 +1045,13 @@
                 String format = separator + "%" + maxLen + "s";
                 separator = ", ";
 
-                sbLux.append(String.format(format, strLux));
-                sbNits.append(String.format(format, strNits));
-                sbLong.append(String.format(format, strLong));
-                sbShort.append(String.format(format, strShort));
-                sbBrightness.append(String.format(format, strBrightness));
-                sbPercent.append(String.format(format, strPercent));
-                sbPercentHbm.append(String.format(format, strPercentHbm));
+                sbLux.append(formatSimple(format, strLux));
+                sbNits.append(formatSimple(format, strNits));
+                sbLong.append(formatSimple(format, strLong));
+                sbShort.append(formatSimple(format, strShort));
+                sbBrightness.append(formatSimple(format, strBrightness));
+                sbPercent.append(formatSimple(format, strPercent));
+                sbPercentHbm.append(formatSimple(format, strPercentHbm));
 
                 // At 80 chars, start another row
                 if (sbLux.length() > 80 || (i == luxes.length - 1)) {
@@ -1072,13 +1075,13 @@
             if (value == 0.0f) {
                 return "0";
             } else if (value < 0.1f) {
-                return String.format("%.3f", value);
+                return String.format(Locale.US, "%.3f", value);
             } else if (value < 1) {
-                return String.format("%.2f", value);
+                return String.format(Locale.US, "%.2f", value);
             } else if (value < 10) {
-                return String.format("%.1f", value);
+                return String.format(Locale.US, "%.1f", value);
             } else {
-                return String.format("%d", Math.round(value));
+                return formatSimple("%d", Math.round(value));
             }
         }
 
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index ed05aa6..aa30c08 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -74,7 +74,7 @@
  *  <pre>
  *  {@code
  *    <displayConfiguration>
- *      <densityMap>
+ *      <densityMapping>
  *        <density>
  *          <height>480</height>
  *          <width>720</width>
@@ -95,7 +95,7 @@
  *          <width>3840</width>
  *          <density>640</density>
  *        </density>
- *      </densityMap>
+ *      </densityMapping>
  *
  *      <screenBrightnessMap>
  *        <point>
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 42fed36..9e5da45 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -1179,8 +1179,15 @@
         @Override
         public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
                 String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
-            (new MediaShellCommand()).exec(this, in, out, err, args, callback,
-                    resultReceiver);
+            String[] packageNames =
+                    mContext.getPackageManager().getPackagesForUid(Binder.getCallingUid());
+            String packageName = packageNames != null && packageNames.length > 0
+                    ? packageNames[0]
+                    : "com.android.shell"; // We should not need this branch, but defaulting to the
+                                           // current shell package name for robustness. See
+                                           // b/227109905.
+            new MediaShellCommand(packageName)
+                    .exec(this, in, out, err, args, callback, resultReceiver);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/media/MediaShellCommand.java b/services/core/java/com/android/server/media/MediaShellCommand.java
index 103cdd9..d175d87 100644
--- a/services/core/java/com/android/server/media/MediaShellCommand.java
+++ b/services/core/java/com/android/server/media/MediaShellCommand.java
@@ -47,15 +47,19 @@
  * ShellCommand for MediaSessionService.
  */
 public class MediaShellCommand extends ShellCommand {
-    // This doesn't belongs to any package. Setting the package name to empty string.
-    private static final String PACKAGE_NAME = "";
     private static ActivityThread sThread;
     private static MediaSessionManager sMediaSessionManager;
+
+    private final String mPackageName;
     private ISessionManager mSessionService;
     private PrintWriter mWriter;
     private PrintWriter mErrorWriter;
     private InputStream mInput;
 
+    public MediaShellCommand(String packageName) {
+        mPackageName = packageName;
+    }
+
     @Override
     public int onCommand(String cmd) {
         mWriter = getOutPrintWriter();
@@ -110,7 +114,7 @@
         mWriter.println();
         mWriter.println("media_session dispatch: dispatch a media key to the system.");
         mWriter.println("                KEY may be: play, pause, play-pause, mute, headsethook,");
-        mWriter.println("                stop, next, previous, rewind, record, fast-forword.");
+        mWriter.println("                stop, next, previous, rewind, record, fast-forward.");
         mWriter.println("media_session list-sessions: print a list of the current sessions.");
         mWriter.println("media_session monitor: monitor updates to the specified session.");
         mWriter.println("                       Use the tag from list-sessions.");
@@ -120,7 +124,8 @@
 
     private void sendMediaKey(KeyEvent event) {
         try {
-            mSessionService.dispatchMediaKeyEvent(PACKAGE_NAME, false, event, false);
+            mSessionService.dispatchMediaKeyEvent(
+                    mPackageName, /* asSystemService= */ false, event, /* needWakeLock= */ false);
         } catch (RemoteException e) {
         }
     }
diff --git a/services/core/java/com/android/server/pm/dex/OdsignStatsLogger.java b/services/core/java/com/android/server/pm/dex/OdsignStatsLogger.java
new file mode 100644
index 0000000..fa08add
--- /dev/null
+++ b/services/core/java/com/android/server/pm/dex/OdsignStatsLogger.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 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.pm.dex;
+
+import android.util.Slog;
+
+import com.android.internal.art.ArtStatsLog;
+import com.android.internal.os.BackgroundThread;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+/**
+ * This class is responsible for reading metrics files generated by odsign and sending them to
+ * statsd. odsign can't send the stats directly to statsd, because statsd can't run until after
+ * odsign has completed. The code here is intended to run once per boot, since odsign runs at boot
+ * time.
+ */
+public class OdsignStatsLogger {
+    private static final String TAG = "OdsignStatsLogger";
+
+    // These need to be kept in sync with system/security/ondevice-signing/StatsReporter.{h, cpp}.
+    private static final String METRICS_FILE = "/data/misc/odsign/metrics/odsign-metrics.txt";
+    private static final String COMPOS_METRIC_NAME = "comp_os_artifacts_check_record";
+
+    /**
+     * Arrange for stats to be uploaded in the background.
+     */
+    public static void triggerStatsWrite() {
+        BackgroundThread.getExecutor().execute(OdsignStatsLogger::writeStats);
+    }
+
+    private static void writeStats() {
+        try {
+            String lines = IoUtils.readFileAsString(METRICS_FILE);
+
+            // Delete the file now so we don't upload it more than once, and don't keep trying
+            // to re-parse it if there is a problem.
+            if (!new File(METRICS_FILE).delete()) {
+                Slog.w(TAG, "Failed to delete metrics file");
+            }
+
+            // The format is simple - each line is a series of space separated tokens. The first is
+            // the metric name and subsequent ones are the metric values. The logic here must be
+            // kept in sync with system/security/ondevice-signing/StatsReporter.cpp.
+
+            for (String line : lines.split("\n")) {
+                String[] metrics = line.split(" ");
+
+                if (metrics.length != 4 || !metrics[0].equals(COMPOS_METRIC_NAME)) {
+                    Slog.w(TAG, "Malformed metrics file");
+                    break;
+                }
+
+                boolean currentArtifactsOk = metrics[1].equals("1");
+                boolean compOsPendingArtifactsExists = metrics[2].equals("1");
+                boolean useCompOsGeneratedArtifacts = metrics[3].equals("1");
+
+                ArtStatsLog.write(ArtStatsLog.EARLY_BOOT_COMP_OS_ARTIFACTS_CHECK_REPORTED,
+                        currentArtifactsOk, compOsPendingArtifactsExists,
+                        useCompOsGeneratedArtifacts);
+            }
+        } catch (FileNotFoundException e) {
+            // This is normal and probably means no new metrics have been generated.
+        } catch (IOException e) {
+            Slog.w(TAG, "Reading metrics file failed", e);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index c524fb7..a963280 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -47,7 +47,6 @@
 import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
 import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED;
 
-import static com.android.server.pm.ApexManager.MATCH_ACTIVE_PACKAGE;
 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
 import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
 import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
@@ -3240,9 +3239,7 @@
         }
         // Only enforce the allowlist on boot
         if (!mSystemReady) {
-            final boolean isInUpdatedApex = containingApexPackageName != null
-                    && !apexManager.isFactory(apexManager.getPackageInfo(containingApexPackageName,
-                    MATCH_ACTIVE_PACKAGE));
+            final boolean isInUpdatedApex = packageSetting.isApkInUpdatedApex();
             // Apps that are in updated apexs' do not need to be allowlisted
             if (!isInUpdatedApex) {
                 Slog.w(TAG, "Privileged permission " + permissionName + " for package "
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 22bfcc4..2be9b34 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1403,6 +1403,9 @@
                             + "activityRecord=%s", this);
             return false;
         }
+        if (onTop) {
+            app.addToPendingTop();
+        }
         try {
             ProtoLog.v(WM_DEBUG_STATES, "Sending position change to %s, onTop: %b",
                     this, onTop);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index f639655..d72e0ba 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1268,29 +1268,36 @@
             boolean allowBackgroundActivityStart, Intent intent, ActivityOptions checkedOptions) {
         // don't abort for the most important UIDs
         final int callingAppId = UserHandle.getAppId(callingUid);
-        if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID
-                || callingAppId == Process.NFC_UID) {
-            if (DEBUG_ACTIVITY_STARTS) {
-                Slog.d(TAG, "Activity start allowed for important callingUid (" + callingUid + ")");
+        final boolean useCallingUidState =
+                originatingPendingIntent == null || checkedOptions == null
+                        || !checkedOptions.getIgnorePendingIntentCreatorForegroundState();
+        if (useCallingUidState) {
+            if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID
+                    || callingAppId == Process.NFC_UID) {
+                if (DEBUG_ACTIVITY_STARTS) {
+                    Slog.d(TAG,
+                            "Activity start allowed for important callingUid (" + callingUid + ")");
+                }
+                return false;
             }
-            return false;
-        }
 
-        // Always allow home application to start activities.
-        if (isHomeApp(callingUid, callingPackage)) {
-            if (DEBUG_ACTIVITY_STARTS) {
-                Slog.d(TAG, "Activity start allowed for home app callingUid (" + callingUid + ")");
+            // Always allow home application to start activities.
+            if (isHomeApp(callingUid, callingPackage)) {
+                if (DEBUG_ACTIVITY_STARTS) {
+                    Slog.d(TAG,
+                            "Activity start allowed for home app callingUid (" + callingUid + ")");
+                }
+                return false;
             }
-            return false;
-        }
 
-        // IME should always be allowed to start activity, like IME settings.
-        final WindowState imeWindow = mRootWindowContainer.getCurrentInputMethodWindow();
-        if (imeWindow != null && callingAppId == imeWindow.mOwnerUid) {
-            if (DEBUG_ACTIVITY_STARTS) {
-                Slog.d(TAG, "Activity start allowed for active ime (" + callingUid + ")");
+            // IME should always be allowed to start activity, like IME settings.
+            final WindowState imeWindow = mRootWindowContainer.getCurrentInputMethodWindow();
+            if (imeWindow != null && callingAppId == imeWindow.mOwnerUid) {
+                if (DEBUG_ACTIVITY_STARTS) {
+                    Slog.d(TAG, "Activity start allowed for active ime (" + callingUid + ")");
+                }
+                return false;
             }
-            return false;
         }
 
         // This is used to block background activity launch even if the app is still
@@ -1310,9 +1317,11 @@
         // is allowed, or apps like live wallpaper with non app visible window will be allowed.
         final boolean appSwitchAllowedOrFg =
                 appSwitchState == APP_SWITCH_ALLOW || appSwitchState == APP_SWITCH_FG_ONLY;
-        if (((appSwitchAllowedOrFg || mService.mActiveUids.hasNonAppVisibleWindow(callingUid))
+        final boolean allowCallingUidStartActivity =
+                ((appSwitchAllowedOrFg || mService.mActiveUids.hasNonAppVisibleWindow(callingUid))
                 && callingUidHasAnyVisibleWindow)
-                || isCallingUidPersistentSystemProcess) {
+                || isCallingUidPersistentSystemProcess;
+        if (useCallingUidState && allowCallingUidStartActivity) {
             if (DEBUG_ACTIVITY_STARTS) {
                 Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid
                         + ", isCallingUidPersistentSystemProcess = "
@@ -1400,47 +1409,52 @@
                 return false;
             }
         }
-        // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
-        if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
-                == PERMISSION_GRANTED) {
-            if (DEBUG_ACTIVITY_STARTS) {
-                Slog.d(TAG,
-                        "Background activity start allowed: START_ACTIVITIES_FROM_BACKGROUND "
-                                + "permission granted for uid "
-                                + callingUid);
+        if (useCallingUidState) {
+            // don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
+            if (mService.checkPermission(
+                    START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
+                    == PERMISSION_GRANTED) {
+                if (DEBUG_ACTIVITY_STARTS) {
+                    Slog.d(TAG,
+                            "Background activity start allowed: START_ACTIVITIES_FROM_BACKGROUND "
+                                    + "permission granted for uid "
+                                    + callingUid);
+                }
+                return false;
             }
-            return false;
-        }
-        // don't abort if the caller has the same uid as the recents component
-        if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
-            if (DEBUG_ACTIVITY_STARTS) {
-                Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
-                        + ") is recents");
+            // don't abort if the caller has the same uid as the recents component
+            if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
+                if (DEBUG_ACTIVITY_STARTS) {
+                    Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
+                            + ") is recents");
+                }
+                return false;
             }
-            return false;
-        }
-        // don't abort if the callingUid is the device owner
-        if (mService.isDeviceOwner(callingUid)) {
-            if (DEBUG_ACTIVITY_STARTS) {
-                Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
-                        + ") is device owner");
+            // don't abort if the callingUid is the device owner
+            if (mService.isDeviceOwner(callingUid)) {
+                if (DEBUG_ACTIVITY_STARTS) {
+                    Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
+                            + ") is device owner");
+                }
+                return false;
             }
-            return false;
-        }
-        // don't abort if the callingUid has companion device
-        final int callingUserId = UserHandle.getUserId(callingUid);
-        if (mService.isAssociatedCompanionApp(callingUserId, callingUid)) {
-            if (DEBUG_ACTIVITY_STARTS) {
-                Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
-                        + ") is companion app");
+            // don't abort if the callingUid has companion device
+            final int callingUserId = UserHandle.getUserId(callingUid);
+            if (mService.isAssociatedCompanionApp(callingUserId,
+                    callingUid)) {
+                if (DEBUG_ACTIVITY_STARTS) {
+                    Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
+                            + ") is companion app");
+                }
+                return false;
             }
-            return false;
-        }
-        // don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
-        if (mService.hasSystemAlertWindowPermission(callingUid, callingPid, callingPackage)) {
-            Slog.w(TAG, "Background activity start for " + callingPackage
-                    + " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
-            return false;
+            // don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
+            if (mService.hasSystemAlertWindowPermission(callingUid,
+                    callingPid, callingPackage)) {
+                Slog.w(TAG, "Background activity start for " + callingPackage
+                        + " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
+                return false;
+            }
         }
         // If we don't have callerApp at this point, no caller was provided to startActivity().
         // That's the case for PendingIntent-based starts, since the creator's process might not be
@@ -1452,7 +1466,7 @@
             callerAppUid = realCallingUid;
         }
         // don't abort if the callerApp or other processes of that uid are allowed in any way
-        if (callerApp != null) {
+        if (callerApp != null && useCallingUidState) {
             // first check the original calling process
             if (callerApp.areBackgroundActivityStartsAllowed(appSwitchState)) {
                 if (DEBUG_ACTIVITY_STARTS) {
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 66c625e..f70dc52 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -34,7 +34,7 @@
 import android.view.RemoteAnimationTarget;
 import android.view.SurfaceControl;
 import android.window.BackNavigationInfo;
-import android.window.IOnBackInvokedCallback;
+import android.window.OnBackInvokedCallbackInfo;
 import android.window.TaskSnapshot;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -152,36 +152,30 @@
             }
 
             // Now let's find if this window has a callback from the client side.
-            IOnBackInvokedCallback applicationCallback = null;
-            IOnBackInvokedCallback systemCallback = null;
+            OnBackInvokedCallbackInfo callbackInfo = null;
             if (window != null) {
                 activityRecord = window.mActivityRecord;
                 task = window.getTask();
-                applicationCallback = window.getApplicationOnBackInvokedCallback();
-                if (applicationCallback != null) {
-                    backType = BackNavigationInfo.TYPE_CALLBACK;
-                    infoBuilder.setOnBackInvokedCallback(applicationCallback);
-                } else {
-                    systemCallback = window.getSystemOnBackInvokedCallback();
-                    infoBuilder.setOnBackInvokedCallback(systemCallback);
+                callbackInfo = window.getOnBackInvokedCallbackInfo();
+                if (callbackInfo == null) {
+                    Slog.e(TAG, "No callback registered, returning null.");
+                    return null;
                 }
+                if (!callbackInfo.isSystemCallback()) {
+                    backType = BackNavigationInfo.TYPE_CALLBACK;
+                }
+                infoBuilder.setOnBackInvokedCallback(callbackInfo.getCallback());
             }
 
             ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "startBackNavigation task=%s, "
-                            + "topRunningActivity=%s, applicationBackCallback=%s, "
-                            + "systemBackCallback=%s, currentFocus=%s",
-                    task, activityRecord, applicationCallback, systemCallback, window);
+                            + "topRunningActivity=%s, callbackInfo=%s, currentFocus=%s",
+                    task, activityRecord, callbackInfo, window);
 
             if (window == null) {
                 Slog.e(TAG, "Window is null, returning null.");
                 return null;
             }
 
-            if (systemCallback == null && applicationCallback == null) {
-                Slog.e(TAG, "No callback registered, returning null.");
-                return null;
-            }
-
             // If we don't need to set up the animation, we return early. This is the case when
             // - We have an application callback.
             // - We don't have any ActivityRecord or Task to animate.
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index dcec914..30b5083 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -74,8 +74,7 @@
 import android.view.View;
 import android.view.WindowManager;
 import android.window.ClientWindowFrames;
-import android.window.IOnBackInvokedCallback;
-import android.window.OnBackInvokedDispatcher;
+import android.window.OnBackInvokedCallbackInfo;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.logging.MetricsLoggerWrapper;
@@ -937,18 +936,16 @@
     }
 
     @Override
-    public void setOnBackInvokedCallback(
+    public void setOnBackInvokedCallbackInfo(
             IWindow window,
-            IOnBackInvokedCallback onBackInvokedCallback,
-            @OnBackInvokedDispatcher.Priority int priority) {
+            OnBackInvokedCallbackInfo callbackInfo) {
         synchronized (mService.mGlobalLock) {
             WindowState windowState = mService.windowForClientLocked(this, window, false);
             if (windowState == null) {
                 Slog.e(TAG_WM,
-                        "setOnBackInvokedCallback(): No window state for package:"
-                                + mPackageName);
+                        "setOnBackInvokedCallback(): No window state for package:" + mPackageName);
             } else {
-                windowState.setOnBackInvokedCallback(onBackInvokedCallback, priority);
+                windowState.setOnBackInvokedCallbackInfo(callbackInfo);
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 900963e..b96b461 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1232,6 +1232,7 @@
 
             // This activity is now becoming visible.
             if (!next.mVisibleRequested || next.stopped || lastActivityTranslucent) {
+                next.app.addToPendingTop();
                 next.setVisibility(true);
             }
 
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 57ca620..70545c9 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -602,7 +602,7 @@
 
     void onTaskVanished(ITaskOrganizer organizer, Task task) {
         final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
-        if (state != null && state.removeTask(task, false /* removeFromSystem */)) {
+        if (state != null && state.removeTask(task, task.mRemoveWithTaskOrganizer)) {
             onTaskVanishedInternal(organizer, task);
         }
     }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 0a310f44..e7d4877 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -249,8 +249,7 @@
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.window.ClientWindowFrames;
-import android.window.IOnBackInvokedCallback;
-import android.window.WindowOnBackInvokedDispatcher;
+import android.window.OnBackInvokedCallbackInfo;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.KeyInterceptionInfo;
@@ -821,12 +820,9 @@
     };
 
     /**
-     * @see #setOnBackInvokedCallback(IOnBackInvokedCallback)
+     * @see #setOnBackInvokedCallbackInfo(OnBackInvokedCallbackInfo)
      */
-    // TODO(b/224856664): Consolidate application and system callback into one.
-    private IOnBackInvokedCallback mApplicationOnBackInvokedCallback;
-    private IOnBackInvokedCallback mSystemOnBackInvokedCallback;
-
+    private OnBackInvokedCallbackInfo mOnBackInvokedCallbackInfo;
     @Override
     WindowState asWindowState() {
         return this;
@@ -1083,28 +1079,16 @@
      * called when a back navigation action is initiated.
      * @see BackNavigationController
      */
-    void setOnBackInvokedCallback(
-            @Nullable IOnBackInvokedCallback onBackInvokedCallback, int priority) {
-        ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "WindowState: Setting back callback %s (priority: %d) "
-                        + "(Client IWindow: %s). (WindowState: %s)",
-                onBackInvokedCallback, priority, mClient, this);
-        if (priority >= WindowOnBackInvokedDispatcher.PRIORITY_DEFAULT) {
-            mApplicationOnBackInvokedCallback = onBackInvokedCallback;
-            mSystemOnBackInvokedCallback = null;
-        } else {
-            mApplicationOnBackInvokedCallback = null;
-            mSystemOnBackInvokedCallback = onBackInvokedCallback;
-        }
+    void setOnBackInvokedCallbackInfo(
+            @Nullable OnBackInvokedCallbackInfo callbackInfo) {
+        ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "%s: Setting back callback %s",
+                this, callbackInfo);
+        mOnBackInvokedCallbackInfo = callbackInfo;
     }
 
     @Nullable
-    IOnBackInvokedCallback getApplicationOnBackInvokedCallback() {
-        return mApplicationOnBackInvokedCallback;
-    }
-
-    @Nullable
-    IOnBackInvokedCallback getSystemOnBackInvokedCallback() {
-        return mSystemOnBackInvokedCallback;
+    OnBackInvokedCallbackInfo getOnBackInvokedCallbackInfo() {
+        return mOnBackInvokedCallbackInfo;
     }
 
     interface PowerManagerWrapper {
@@ -2496,8 +2480,7 @@
         dc.getDisplayPolicy().removeWindowLw(this);
 
         disposeInputChannel();
-        mSystemOnBackInvokedCallback = null;
-        mApplicationOnBackInvokedCallback = null;
+        mOnBackInvokedCallbackInfo = null;
 
         mSession.windowRemovedLocked();
         try {
@@ -2551,8 +2534,7 @@
 
         try {
             disposeInputChannel();
-            mSystemOnBackInvokedCallback = null;
-            mApplicationOnBackInvokedCallback = null;
+            mOnBackInvokedCallbackInfo = null;
 
             ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
                     "Remove %s: mSurfaceController=%s mAnimatingExit=%b mRemoveOnExit=%b "
@@ -3519,6 +3501,7 @@
                     "Setting visibility of " + this + ": " + clientVisible);
             mClient.dispatchAppVisibility(clientVisible);
         } catch (RemoteException e) {
+            Slog.w(TAG, "Exception thrown during dispatchAppVisibility " + this, e);
         }
     }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 13bd9fd8..b7005a5 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -1544,23 +1544,6 @@
             return StorageManager.isFileEncryptedNativeOnly();
         }
 
-        boolean storageManagerIsNonDefaultBlockEncrypted() {
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                return StorageManager.isNonDefaultBlockEncrypted();
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-
-        boolean storageManagerIsEncrypted() {
-            return StorageManager.isEncrypted();
-        }
-
-        boolean storageManagerIsEncryptable() {
-            return StorageManager.isEncryptable();
-        }
-
         Looper getMyLooper() {
             return Looper.myLooper();
         }
@@ -7823,21 +7806,12 @@
 
     /**
      * Hook to low-levels:  Reporting the current status of encryption.
-     * @return A value such as {@link DevicePolicyManager#ENCRYPTION_STATUS_UNSUPPORTED},
-     * {@link DevicePolicyManager#ENCRYPTION_STATUS_INACTIVE},
-     * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY},
-     * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE_PER_USER}, or
-     * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE}.
+     * @return Either {@link DevicePolicyManager#ENCRYPTION_STATUS_UNSUPPORTED}
+     * or {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE_PER_USER}.
      */
     private int getEncryptionStatus() {
         if (mInjector.storageManagerIsFileBasedEncryptionEnabled()) {
             return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER;
-        } else if (mInjector.storageManagerIsNonDefaultBlockEncrypted()) {
-            return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE;
-        } else if (mInjector.storageManagerIsEncrypted()) {
-            return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY;
-        } else if (mInjector.storageManagerIsEncryptable()) {
-            return DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
         } else {
             return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
         }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 73f0a74..2b431b6 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -164,6 +164,7 @@
 import com.android.server.pm.PackageManagerService;
 import com.android.server.pm.ShortcutService;
 import com.android.server.pm.UserManagerService;
+import com.android.server.pm.dex.OdsignStatsLogger;
 import com.android.server.pm.dex.SystemServerDexLoadReporter;
 import com.android.server.pm.verify.domain.DomainVerificationService;
 import com.android.server.policy.AppOpsPolicy;
@@ -3042,6 +3043,14 @@
                 setIncrementalServiceSystemReady(mIncrementalServiceHandle);
                 t.traceEnd();
             }
+
+            t.traceBegin("OdsignStatsLogger");
+            try {
+                OdsignStatsLogger.triggerStatsWrite();
+            } catch (Throwable e) {
+                reportWtf("Triggering OdsignStatsLogger", e);
+            }
+            t.traceEnd();
         }, t);
 
         t.traceBegin("StartSystemUI");
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index ef9f90f..4f87f9d 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -255,21 +255,6 @@
         }
 
         @Override
-        boolean storageManagerIsNonDefaultBlockEncrypted() {
-            return services.storageManager.isNonDefaultBlockEncrypted();
-        }
-
-        @Override
-        boolean storageManagerIsEncrypted() {
-            return services.storageManager.isEncrypted();
-        }
-
-        @Override
-        boolean storageManagerIsEncryptable() {
-            return services.storageManager.isEncryptable();
-        }
-
-        @Override
         String getDevicePolicyFilePathForSystemUser() {
             return services.systemUserDataDir.getAbsolutePath() + "/";
         }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
index 21fb2da..34c9f7c 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -501,18 +501,6 @@
         public boolean isFileBasedEncryptionEnabled() {
             return false;
         }
-
-        public boolean isNonDefaultBlockEncrypted() {
-            return false;
-        }
-
-        public boolean isEncrypted() {
-            return false;
-        }
-
-        public boolean isEncryptable() {
-            return false;
-        }
     }
 
     // We have to keep track of broadcast receivers registered for a given intent ourselves as the
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index a4a62a4..fe59185a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -44,6 +44,7 @@
 import android.window.BackNavigationInfo;
 import android.window.IOnBackInvokedCallback;
 import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedCallbackInfo;
 import android.window.OnBackInvokedDispatcher;
 import android.window.TaskSnapshot;
 import android.window.WindowOnBackInvokedDispatcher;
@@ -104,7 +105,8 @@
         WindowState window = createAppWindow(task, FIRST_APPLICATION_WINDOW, "window");
         addToWindowMap(window, true);
         IOnBackInvokedCallback callback = createOnBackInvokedCallback();
-        window.setOnBackInvokedCallback(callback, OnBackInvokedDispatcher.PRIORITY_SYSTEM);
+        window.setOnBackInvokedCallbackInfo(
+                new OnBackInvokedCallbackInfo(callback, OnBackInvokedDispatcher.PRIORITY_SYSTEM));
         BackNavigationInfo backNavigationInfo = startBackNavigation();
         assertWithMessage("BackNavigationInfo").that(backNavigationInfo).isNotNull();
         assertThat(typeToString(backNavigationInfo.getType()))
@@ -130,7 +132,8 @@
         addToWindowMap(window, true);
 
         IOnBackInvokedCallback callback = createOnBackInvokedCallback();
-        window.setOnBackInvokedCallback(callback, OnBackInvokedDispatcher.PRIORITY_DEFAULT);
+        window.setOnBackInvokedCallbackInfo(
+                new OnBackInvokedCallbackInfo(callback, OnBackInvokedDispatcher.PRIORITY_DEFAULT));
 
         BackNavigationInfo backNavigationInfo = startBackNavigation();
         assertWithMessage("BackNavigationInfo").that(backNavigationInfo).isNotNull();
@@ -169,11 +172,9 @@
         WindowState appWindow = task.getTopVisibleAppMainWindow();
         WindowOnBackInvokedDispatcher dispatcher = new WindowOnBackInvokedDispatcher();
         doAnswer(invocation -> {
-            appWindow.setOnBackInvokedCallback(invocation.getArgument(1),
-                    invocation.getArgument(2));
+            appWindow.setOnBackInvokedCallbackInfo(invocation.getArgument(1));
             return null;
-        }).when(appWindow.mSession).setOnBackInvokedCallback(eq(appWindow.mClient), any(),
-                anyInt());
+        }).when(appWindow.mSession).setOnBackInvokedCallbackInfo(eq(appWindow.mClient), any());
 
         addToWindowMap(appWindow, true);
         dispatcher.attachToWindow(appWindow.mSession, appWindow.mClient);
@@ -216,15 +217,15 @@
 
     private IOnBackInvokedCallback withSystemCallback(Task task) {
         IOnBackInvokedCallback callback = createOnBackInvokedCallback();
-        task.getTopMostActivity().getTopChild().setOnBackInvokedCallback(callback,
-                OnBackInvokedDispatcher.PRIORITY_SYSTEM);
+        task.getTopMostActivity().getTopChild().setOnBackInvokedCallbackInfo(
+                new OnBackInvokedCallbackInfo(callback, OnBackInvokedDispatcher.PRIORITY_SYSTEM));
         return callback;
     }
 
     private IOnBackInvokedCallback withAppCallback(Task task) {
         IOnBackInvokedCallback callback = createOnBackInvokedCallback();
-        task.getTopMostActivity().getTopChild().setOnBackInvokedCallback(callback,
-                OnBackInvokedDispatcher.PRIORITY_DEFAULT);
+        task.getTopMostActivity().getTopChild().setOnBackInvokedCallbackInfo(
+                new OnBackInvokedCallbackInfo(callback, OnBackInvokedDispatcher.PRIORITY_DEFAULT));
         return callback;
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index eb91d5e..832bd2d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -247,6 +247,42 @@
     }
 
     @Test
+    public void testRemoveWithOrganizerRemovesTask() throws RemoteException {
+        final ITaskOrganizer organizer = registerMockOrganizer();
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask);
+        rootTask.mRemoveWithTaskOrganizer = true;
+
+        mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
+        verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
+        assertTrue(rootTask.isOrganized());
+
+        spyOn(mWm.mAtmService);
+        rootTask.setTaskOrganizer(null);
+        mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
+
+        verify(mWm.mAtmService).removeTask(eq(rootTask.mTaskId));
+    }
+
+    @Test
+    public void testNoRemoveWithOrganizerNoRemoveTask() throws RemoteException {
+        final ITaskOrganizer organizer = registerMockOrganizer();
+        final Task rootTask = createRootTask();
+        final Task task = createTask(rootTask);
+        rootTask.mRemoveWithTaskOrganizer = false;
+
+        mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
+        verify(organizer).onTaskAppeared(any(RunningTaskInfo.class), any(SurfaceControl.class));
+        assertTrue(rootTask.isOrganized());
+
+        spyOn(mWm.mAtmService);
+        rootTask.setTaskOrganizer(null);
+        mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
+
+        verify(mWm.mAtmService, never()).removeTask(eq(rootTask.mTaskId));
+    }
+
+    @Test
     public void testUnregisterOrganizer() throws RemoteException {
         final ITaskOrganizer organizer = registerMockOrganizer();
         final Task rootTask = createRootTask();
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 84bc21ce..01a9652 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -95,6 +95,7 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
+import android.util.SparseSetArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -183,8 +184,7 @@
     static final int MSG_PACKAGE_REMOVED = 6;
     static final int MSG_ON_START = 7;
     static final int MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK = 8;
-    static final int MSG_NOTIFY_ESTIMATED_LAUNCH_TIME_CHANGED = 9;
-    static final int MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED = 10;
+    static final int MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED = 9;
 
     private final Object mLock = new Object();
     Handler mHandler;
@@ -225,6 +225,8 @@
             new ArraySet<>();
     private final CopyOnWriteArraySet<UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener>
             mEstimatedLaunchTimeChangedListeners = new CopyOnWriteArraySet<>();
+    @GuardedBy("mPendingLaunchTimeChangePackages")
+    private final SparseSetArray<String> mPendingLaunchTimeChangePackages = new SparseSetArray<>();
 
     private BroadcastResponseStatsTracker mResponseStatsTracker;
 
@@ -233,6 +235,7 @@
         private final String mTaskRootClass;
         private final String mUsageSourcePackage;
         public int lastEvent = Event.NONE;
+
         private ActivityData(String taskRootPackage, String taskRootClass, String sourcePackage) {
             mTaskRootPackage = taskRootPackage;
             mTaskRootClass = taskRootClass;
@@ -537,9 +540,10 @@
                         + expired.toString());
             }
             if (expired.size() > 0) {
-                mHandler.obtainMessage(
-                        MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED, mUserId, 0, expired)
-                        .sendToTarget();
+                synchronized (mPendingLaunchTimeChangePackages) {
+                    mPendingLaunchTimeChangePackages.addAll(mUserId, expired);
+                }
+                mHandler.sendEmptyMessage(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED);
             }
         }
     }
@@ -1058,9 +1062,9 @@
                                     + " app launch resetting future launch estimate");
                         }
                         mAppStandby.setEstimatedLaunchTime(event.mPackage, userId, 0);
-                        mHandler.obtainMessage(
-                                MSG_NOTIFY_ESTIMATED_LAUNCH_TIME_CHANGED, userId, 0, event.mPackage)
-                                .sendToTarget();
+                        if (stageChangedEstimatedLaunchTime(userId, event.mPackage)) {
+                            mHandler.sendEmptyMessage(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED);
+                        }
                     }
                     break;
                 case Event.ACTIVITY_PAUSED:
@@ -1212,7 +1216,7 @@
     }
 
     /**
-     * Called by the Binder stub.
+     * Called by the Handler for message MSG_USER_REMOVED.
      */
     void onUserRemoved(int userId) {
         synchronized (mLock) {
@@ -1225,6 +1229,11 @@
                 mLaunchTimeAlarmQueues.remove(userId);
             }
         }
+        // Since this is only called from the Handler, we don't have to worry about modifying the
+        // pending change list while the handler is iterating to notify listeners.
+        synchronized (mPendingLaunchTimeChangePackages) {
+            mPendingLaunchTimeChangePackages.remove(userId);
+        }
         mAppStandby.onUserRemoved(userId);
         // Cancel any scheduled jobs for this user since the user is being removed.
         UsageStatsIdleService.cancelJob(getContext(), userId);
@@ -1235,6 +1244,15 @@
      * Called by the Handler for message MSG_PACKAGE_REMOVED.
      */
     private void onPackageRemoved(int userId, String packageName) {
+        // Since this is only called from the Handler, we don't have to worry about modifying the
+        // pending change list while the handler is iterating to notify listeners.
+        synchronized (mPendingLaunchTimeChangePackages) {
+            final ArraySet<String> pkgNames = mPendingLaunchTimeChangePackages.get(userId);
+            if (pkgNames != null) {
+                pkgNames.remove(packageName);
+            }
+        }
+
         final int tokenRemoved;
         synchronized (mLock) {
             final long timeRemoved = System.currentTimeMillis();
@@ -1547,7 +1565,7 @@
                         userId, getContext(), BackgroundThread.get().getLooper());
                 mLaunchTimeAlarmQueues.put(userId, alarmQueue);
             }
-            final ArraySet<String> changedTimes = new ArraySet<>();
+            boolean changedTimes = false;
             for (boolean unprocessedEvent = events.getNextEvent(event); unprocessedEvent;
                     unprocessedEvent = events.getNextEvent(event)) {
                 final String packageName = event.getPackageName();
@@ -1577,15 +1595,13 @@
                             Slog.d(TAG, "User " + userId + " unlock resulting in"
                                     + " estimated launch time change for " + packageName);
                         }
-                        changedTimes.add(packageName);
+                        changedTimes |= stageChangedEstimatedLaunchTime(userId, packageName);
                     }
                     alarmQueue.addAlarm(packageName, nowElapsed + (estimatedLaunchTime - now));
                 }
             }
-            if (changedTimes.size() > 0) {
-                mHandler.obtainMessage(
-                        MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED, userId, 0, changedTimes)
-                        .sendToTarget();
+            if (changedTimes) {
+                mHandler.sendEmptyMessage(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED);
             }
         }
     }
@@ -1603,14 +1619,14 @@
         final long oldEstimatedLaunchTime = mAppStandby.getEstimatedLaunchTime(packageName, userId);
         if (estimatedLaunchTime != oldEstimatedLaunchTime) {
             mAppStandby.setEstimatedLaunchTime(packageName, userId, estimatedLaunchTime);
-            mHandler.obtainMessage(
-                    MSG_NOTIFY_ESTIMATED_LAUNCH_TIME_CHANGED, userId, 0, packageName)
-                    .sendToTarget();
+            if (stageChangedEstimatedLaunchTime(userId, packageName)) {
+                mHandler.sendEmptyMessage(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED);
+            }
         }
     }
 
     private void setEstimatedLaunchTimes(int userId, List<AppLaunchEstimateInfo> launchEstimates) {
-        final ArraySet<String> changedTimes = new ArraySet<>();
+        boolean changedTimes = false;
         final long now = System.currentTimeMillis();
         for (int i = launchEstimates.size() - 1; i >= 0; --i) {
             AppLaunchEstimateInfo estimate = launchEstimates.get(i);
@@ -1626,13 +1642,17 @@
             if (estimate.estimatedLaunchTime != oldEstimatedLaunchTime) {
                 mAppStandby.setEstimatedLaunchTime(
                         estimate.packageName, userId, estimate.estimatedLaunchTime);
-                changedTimes.add(estimate.packageName);
+                changedTimes |= stageChangedEstimatedLaunchTime(userId, estimate.packageName);
             }
         }
-        if (changedTimes.size() > 0) {
-            mHandler.obtainMessage(
-                    MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED, userId, 0, changedTimes)
-                    .sendToTarget();
+        if (changedTimes) {
+            mHandler.sendEmptyMessage(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED);
+        }
+    }
+
+    private boolean stageChangedEstimatedLaunchTime(int userId, String packageName) {
+        synchronized (mPendingLaunchTimeChangePackages) {
+            return mPendingLaunchTimeChangePackages.add(userId, packageName);
         }
     }
 
@@ -1946,35 +1966,45 @@
                     handleEstimatedLaunchTimesOnUserUnlock(userId);
                 }
                 break;
-                case MSG_NOTIFY_ESTIMATED_LAUNCH_TIME_CHANGED: {
-                    final int userId = msg.arg1;
-                    final String pkgName = (String) msg.obj;
-                    final long nextEstimatedLaunchTime =
-                            getEstimatedPackageLaunchTime(userId, pkgName);
-                    if (DEBUG) {
-                        Slog.d(TAG, "Notifying listener for " + userId + ":" + pkgName);
-                    }
-                    for (UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener listener :
-                            mEstimatedLaunchTimeChangedListeners) {
-                        listener.onEstimatedLaunchTimeChanged(
-                                userId, pkgName, nextEstimatedLaunchTime);
-                    }
-                }
-                break;
                 case MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED: {
-                    final int userId = msg.arg1;
-                    final ArraySet<String> pkgNames = (ArraySet<String>) msg.obj;
-                    if (DEBUG) {
-                        Slog.d(TAG, "Notifying listeners for " + userId + "-->" + pkgNames);
+                    removeMessages(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED);
+
+                    // Note that this method of getting the list's size outside and then using it
+                    // for iteration outside of the lock implies possible issue if the set is
+                    // modified during iteration. However, at the time of implementation, this is
+                    // not an issue.
+                    // For addition (increasing the size): if something is added after we get the
+                    // size, then there will be a new MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED
+                    // message in the handler's queue, which means we will iterate over the list
+                    // once again and process the addition
+                    // For removal (decreasing the size): removals only ever happen via the handler,
+                    // which means this iteration code cannot happen at the same time as a removal.
+                    // We go through hoops to avoid holding locks when calling out to listeners.
+                    final int numUsers;
+                    final ArraySet<String> pkgNames = new ArraySet();
+                    synchronized (mPendingLaunchTimeChangePackages) {
+                        numUsers = mPendingLaunchTimeChangePackages.size();
                     }
-                    for (int p = pkgNames.size() - 1; p >= 0; --p) {
-                        final String pkgName = pkgNames.valueAt(p);
-                        final long nextEstimatedLaunchTime =
-                                getEstimatedPackageLaunchTime(userId, pkgName);
-                        for (UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener listener :
-                                mEstimatedLaunchTimeChangedListeners) {
-                            listener.onEstimatedLaunchTimeChanged(
-                                    userId, pkgName, nextEstimatedLaunchTime);
+                    for (int u = numUsers - 1; u >= 0; --u) {
+                        pkgNames.clear();
+                        final int userId;
+                        synchronized (mPendingLaunchTimeChangePackages) {
+                            userId = mPendingLaunchTimeChangePackages.keyAt(u);
+                            pkgNames.addAll(mPendingLaunchTimeChangePackages.get(userId));
+                            mPendingLaunchTimeChangePackages.remove(userId);
+                        }
+                        if (DEBUG) {
+                            Slog.d(TAG, "Notifying listeners for " + userId + "-->" + pkgNames);
+                        }
+                        for (int p = pkgNames.size() - 1; p >= 0; --p) {
+                            final String pkgName = pkgNames.valueAt(p);
+                            final long nextEstimatedLaunchTime =
+                                    getEstimatedPackageLaunchTime(userId, pkgName);
+                            for (UsageStatsManagerInternal.EstimatedLaunchTimeChangedListener
+                                    listener : mEstimatedLaunchTimeChangedListeners) {
+                                listener.onEstimatedLaunchTimeChanged(
+                                        userId, pkgName, nextEstimatedLaunchTime);
+                            }
                         }
                     }
                 }
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 8143da5..e97342b 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -24,6 +24,7 @@
 import android.database.Cursor;
 import android.hardware.radio.V1_5.ApnTypes;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.provider.Telephony;
@@ -2183,6 +2184,14 @@
                 || TextUtils.isEmpty(mApnName) || TextUtils.isEmpty(mEntryName)) {
                 return null;
             }
+            if ((mApnTypeBitmask & TYPE_MMS) != 0 && !TextUtils.isEmpty(mMmsProxyAddress)
+                    && mMmsProxyAddress.startsWith("http")) {
+                if (Build.IS_DEBUGGABLE) {
+                    throw new IllegalArgumentException("mms proxy(" +  mMmsProxyAddress
+                            + ") should be a hostname, not a url");
+                }
+                return null;
+            }
             return new ApnSetting(this);
         }
 
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index 546d2ce..b905212 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -424,24 +424,4 @@
      */
     @Deprecated
     public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE = "defaultNetworkAvailable";
-
-    /**
-     * <p>Broadcast sent to show Emergency notification due to Voice Over Wifi availability
-     *
-     * <p class="note">
-     * You can <em>not</em> receive this through components declared
-     * in manifests, only by explicitly registering for it with
-     * {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver,
-     * android.content.IntentFilter) Context.registerReceiver()}.
-     *
-     * <p class="note">
-     * Requires no permission.
-     *
-     * <p class="note">This is a protected intent that can only be sent
-     * by the system.
-     *
-     * @hide
-     */
-    public static final String ACTION_VOWIFI_ENABLED
-            = "com.android.internal.telephony.ACTION_VOWIFI_ENABLED";
 }