Merge "Add an api to get active staged session"
diff --git a/Android.bp b/Android.bp
index a6745a9..d2d8a36 100644
--- a/Android.bp
+++ b/Android.bp
@@ -318,6 +318,7 @@
         "core/java/android/service/vr/IVrListener.aidl",
         "core/java/android/service/vr/IVrManager.aidl",
         "core/java/android/service/vr/IVrStateCallbacks.aidl",
+        "core/java/android/service/watchdog/IExplicitHealthCheckService.aidl",
         "core/java/android/print/ILayoutResultCallback.aidl",
         "core/java/android/print/IPrinterDiscoveryObserver.aidl",
         "core/java/android/print/IPrintDocumentAdapter.aidl",
diff --git a/api/system-current.txt b/api/system-current.txt
index 7f6a005..a4cf10d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1740,7 +1740,7 @@
   }
 
   public class ShortcutManager {
-    method @NonNull public java.util.List<android.content.pm.ShortcutManager.ShareShortcutInfo> getShareTargets(@NonNull android.content.IntentFilter);
+    method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_APP_PREDICTIONS) public java.util.List<android.content.pm.ShortcutManager.ShareShortcutInfo> getShareTargets(@NonNull android.content.IntentFilter);
     method public boolean hasShareTargets(@NonNull String);
   }
 
@@ -6322,8 +6322,8 @@
     ctor public AttentionService();
     method public final void disableSelf();
     method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
-    method public abstract void onCancelAttentionCheck(int);
-    method public abstract void onCheckAttention(int, @NonNull android.service.attention.AttentionService.AttentionCallback);
+    method public abstract void onCancelAttentionCheck(@NonNull android.service.attention.AttentionService.AttentionCallback);
+    method public abstract void onCheckAttention(@NonNull android.service.attention.AttentionService.AttentionCallback);
     field public static final int ATTENTION_FAILURE_CAMERA_PERMISSION_ABSENT = 6; // 0x6
     field public static final int ATTENTION_FAILURE_CANCELLED = 3; // 0x3
     field public static final int ATTENTION_FAILURE_PREEMPTED = 4; // 0x4
@@ -6335,8 +6335,8 @@
   }
 
   public static final class AttentionService.AttentionCallback {
-    method public void onFailure(int, int);
-    method public void onSuccess(int, int, long);
+    method public void onFailure(int);
+    method public void onSuccess(int, long);
   }
 
 }
@@ -6895,6 +6895,22 @@
 
 }
 
+package android.service.watchdog {
+
+  public abstract class ExplicitHealthCheckService extends android.app.Service {
+    ctor public ExplicitHealthCheckService();
+    method public final void notifyHealthCheckPassed(@NonNull String);
+    method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
+    method public abstract void onCancelHealthCheck(@NonNull String);
+    method @NonNull public abstract java.util.List<java.lang.String> onGetRequestedPackages();
+    method @NonNull public abstract java.util.List<java.lang.String> onGetSupportedPackages();
+    method public abstract void onRequestHealthCheck(@NonNull String);
+    field public static final String BIND_PERMISSION = "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE";
+    field public static final String SERVICE_INTERFACE = "android.service.watchdog.ExplicitHealthCheckService";
+  }
+
+}
+
 package android.telecom {
 
   @Deprecated public class AudioState implements android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index d3ec216..9817a97 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2150,9 +2150,9 @@
     method @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA) public static long getContributedMediaSize(android.content.Context, String, android.os.UserHandle) throws java.io.IOException;
     method @NonNull public static java.io.File getVolumePath(@NonNull String) throws java.io.FileNotFoundException;
     method @NonNull public static java.util.Collection<java.io.File> getVolumeScanPaths(@NonNull String) throws java.io.FileNotFoundException;
-    field public static final String EXTRA_ORIGINATED_FROM_SHELL = "android.intent.extra.originated_from_shell";
-    field public static final String SCAN_FILE_CALL = "scan_file";
-    field public static final String SCAN_VOLUME_CALL = "scan_volume";
+    method public static android.net.Uri scanFile(android.content.Context, java.io.File);
+    method public static android.net.Uri scanFileFromShell(android.content.Context, java.io.File);
+    method public static void scanVolume(android.content.Context, java.io.File);
   }
 
   public final class Settings {
diff --git a/core/java/android/attention/AttentionManagerInternal.java b/core/java/android/attention/AttentionManagerInternal.java
index ac19504..fa3d3b8 100644
--- a/core/java/android/attention/AttentionManagerInternal.java
+++ b/core/java/android/attention/AttentionManagerInternal.java
@@ -30,25 +30,21 @@
     /**
      * Checks whether user attention is at the screen and calls in the provided callback.
      *
-     * @param requestCode   a code associated with the attention check request; this code would be
-     *                      used to call back in {@link AttentionCallbackInternal#onSuccess} and
-     *                      {@link AttentionCallbackInternal#onFailure}
      * @param timeoutMillis a budget for the attention check; if it takes longer - {@link
      *                      AttentionCallbackInternal#onFailure} would be called with the {@link
      *                      android.service.attention.AttentionService#ATTENTION_FAILURE_TIMED_OUT}
      *                      code
      * @param callback      a callback for when the attention check has completed
-     * @return {@code true} if the attention check should succeed; {@false} otherwise.
+     * @return {@code true} if the attention check should succeed.
      */
-    public abstract boolean checkAttention(int requestCode,
-            long timeoutMillis, AttentionCallbackInternal callback);
+    public abstract boolean checkAttention(long timeoutMillis, AttentionCallbackInternal callback);
 
     /**
      * Cancels the specified attention check in case it's no longer needed.
      *
-     * @param requestCode a code provided during {@link #checkAttention}
+     * @param callback a callback that was used in {@link #checkAttention}
      */
-    public abstract void cancelAttentionCheck(int requestCode);
+    public abstract void cancelAttentionCheck(AttentionCallbackInternal callback);
 
     /**
      * Disables the dependants.
@@ -62,19 +58,17 @@
         /**
          * Provides the result of the attention check, if the check was successful.
          *
-         * @param requestCode a code provided in {@link #checkAttention}
          * @param result      an int with the result of the check
          * @param timestamp   a {@code SystemClock.uptimeMillis()} timestamp associated with the
          *                    attention check
          */
-        public abstract void onSuccess(int requestCode, int result, long timestamp);
+        public abstract void onSuccess(int result, long timestamp);
 
         /**
          * Provides the explanation for why the attention check had failed.
          *
-         * @param requestCode a code provided in {@link #checkAttention}
          * @param error       an int with the reason for failure
          */
-        public abstract void onFailure(int requestCode, int error);
+        public abstract void onFailure(int error);
     }
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 032e5ac..d87171e 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3115,21 +3115,14 @@
      * <p>
      * The path to the file is contained in {@link Intent#getData()}.
      *
-     * @deprecated Starting in the {@link android.os.Build.VERSION_CODES#Q}
-     *             release, shared storage paths are sandboxed per application,
-     *             and this broadcast cannot correctly translate those sandboxed
-     *             paths. Callers will need to instead migrate to using
-     *             {@link MediaScannerConnection}.
+     * @deprecated Callers should migrate to inserting items directly into
+     *             {@link MediaStore}, where they will be automatically scanned
+     *             after each mutation.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     @Deprecated
     public static final String ACTION_MEDIA_SCANNER_SCAN_FILE = "android.intent.action.MEDIA_SCANNER_SCAN_FILE";
 
-    /** @hide */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @Deprecated
-    public static final String ACTION_MEDIA_SCANNER_SCAN_VOLUME = "android.intent.action.MEDIA_SCANNER_SCAN_VOLUME";
-
    /**
      * Broadcast Action:  The "Media Button" was pressed.  Includes a single
      * extra field, {@link #EXTRA_KEY_EVENT}, containing the key event that
diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java
index df67117..f851799 100644
--- a/core/java/android/content/pm/ShortcutManager.java
+++ b/core/java/android/content/pm/ShortcutManager.java
@@ -15,8 +15,10 @@
  */
 package android.content.pm;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
@@ -565,6 +567,7 @@
      */
     @NonNull
     @SystemApi
+    @RequiresPermission(Manifest.permission.MANAGE_APP_PREDICTIONS)
     public List<ShareShortcutInfo> getShareTargets(@NonNull IntentFilter filter) {
         try {
             return mService.getShareTargets(mContext.getPackageName(), filter,
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 6a01e56..7cc7ccd 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -30,6 +30,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.os.storage.IStorageManager;
 import android.provider.Settings;
 import android.telephony.euicc.EuiccManager;
 import android.text.TextUtils;
@@ -38,6 +39,8 @@
 import android.view.Display;
 import android.view.WindowManager;
 
+import com.android.internal.content.PackageHelper;
+
 import libcore.io.Streams;
 
 import java.io.ByteArrayInputStream;
@@ -854,6 +857,21 @@
     /** {@hide} */
     public static void rebootPromptAndWipeUserData(Context context, String reason)
             throws IOException {
+        boolean checkpointing = false;
+
+        // If we are running in checkpointing mode, we should not prompt a wipe.
+        // Checkpointing may save us. If it doesn't, we will wind up here again.
+        try {
+            IStorageManager storageManager = PackageHelper.getStorageManager();
+            if (storageManager.needsCheckpoint()) {
+                Log.i(TAG, "Rescue Party requested wipe. Aborting update instead.");
+                storageManager.abortChanges("rescueparty", false);
+            }
+            return;
+        } catch (RemoteException e) {
+            Log.i(TAG, "Failed to handle with checkpointing. Continuing with wipe.");
+        }
+
         String reasonArg = null;
         if (!TextUtils.isEmpty(reason)) {
             reasonArg = "--reason=" + sanitizeArg(reason);
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 25f67f8..9db4111 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -193,4 +193,6 @@
     void commitChanges() = 83;
     boolean supportsCheckpoint() = 84;
     void startCheckpoint(int numTries) = 85;
+    boolean needsCheckpoint() = 86;
+    void abortChanges(in String message, boolean retry) = 87;
 }
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index dc5fdc0..7feeeee 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -115,9 +115,9 @@
      */
     public static final String VOLUME_EXTERNAL = "external";
 
-    /** {@hide} */ @TestApi
+    /** {@hide} */
     public static final String SCAN_FILE_CALL = "scan_file";
-    /** {@hide} */ @TestApi
+    /** {@hide} */
     public static final String SCAN_VOLUME_CALL = "scan_volume";
 
     /**
@@ -126,7 +126,6 @@
      *
      * {@hide}
      */
-    @TestApi
     public static final String EXTRA_ORIGINATED_FROM_SHELL =
             "android.intent.extra.originated_from_shell";
 
@@ -3539,12 +3538,32 @@
     }
 
     /** @hide */
+    @TestApi
     public static Uri scanFile(Context context, File file) {
+        return scan(context, SCAN_FILE_CALL, file, false);
+    }
+
+    /** @hide */
+    @TestApi
+    public static Uri scanFileFromShell(Context context, File file) {
+        return scan(context, SCAN_FILE_CALL, file, true);
+    }
+
+    /** @hide */
+    @TestApi
+    public static void scanVolume(Context context, File file) {
+        scan(context, SCAN_VOLUME_CALL, file, false);
+    }
+
+    /** @hide */
+    private static Uri scan(Context context, String method, File file,
+            boolean originatedFromShell) {
         final ContentResolver resolver = context.getContentResolver();
         try (ContentProviderClient client = resolver.acquireContentProviderClient(AUTHORITY)) {
             final Bundle in = new Bundle();
             in.putParcelable(Intent.EXTRA_STREAM, Uri.fromFile(file));
-            final Bundle out = client.call(SCAN_FILE_CALL, null, in);
+            in.putBoolean(EXTRA_ORIGINATED_FROM_SHELL, originatedFromShell);
+            final Bundle out = client.call(method, null, in);
             return out.getParcelable(Intent.EXTRA_STREAM);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 53c7eda..702dc74 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8045,17 +8045,6 @@
                 BOOLEAN_VALIDATOR;
 
         /**
-         * Whether the swipe up gesture to switch apps should be enabled.
-         *
-         * @hide
-         */
-        public static final String SWIPE_UP_TO_SWITCH_APPS_ENABLED =
-                "swipe_up_to_switch_apps_enabled";
-
-        private static final Validator SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR =
-                BOOLEAN_VALIDATOR;
-
-        /**
          * Whether or not the smart camera lift trigger that launches the camera when the user moves
          * the phone into a position for taking photos should be enabled.
          *
@@ -8739,7 +8728,6 @@
             DISPLAY_WHITE_BALANCE_ENABLED,
             SYNC_PARENT_SOUNDS,
             CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
-            SWIPE_UP_TO_SWITCH_APPS_ENABLED,
             CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
             SYSTEM_NAVIGATION_KEYS_ENABLED,
             QS_TILES,
@@ -8902,8 +8890,6 @@
             VALIDATORS.put(SYNC_PARENT_SOUNDS, SYNC_PARENT_SOUNDS_VALIDATOR);
             VALIDATORS.put(CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
                     CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED_VALIDATOR);
-            VALIDATORS.put(SWIPE_UP_TO_SWITCH_APPS_ENABLED,
-                    SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR);
             VALIDATORS.put(CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
                     CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED_VALIDATOR);
             VALIDATORS.put(SYSTEM_NAVIGATION_KEYS_ENABLED,
diff --git a/core/java/android/service/attention/AttentionService.java b/core/java/android/service/attention/AttentionService.java
index 84f440f..6172ce5 100644
--- a/core/java/android/service/attention/AttentionService.java
+++ b/core/java/android/service/attention/AttentionService.java
@@ -40,7 +40,7 @@
  * The system's default AttentionService implementation is configured in
  * {@code config_AttentionComponent}. If this config has no value, a stub is returned.
  *
- * See: {@link AttentionManagerService}.
+ * See: {@link com.android.server.attention.AttentionManagerService}.
  *
  * <pre>
  * {@literal
@@ -109,15 +109,16 @@
 
         /** {@inheritDoc} */
         @Override
-        public void checkAttention(int requestCode, IAttentionCallback callback) {
+        public void checkAttention(IAttentionCallback callback) {
             Preconditions.checkNotNull(callback);
-            AttentionService.this.onCheckAttention(requestCode, new AttentionCallback(callback));
+            AttentionService.this.onCheckAttention(new AttentionCallback(callback));
         }
 
         /** {@inheritDoc} */
         @Override
-        public void cancelAttentionCheck(int requestCode) {
-            AttentionService.this.onCancelAttentionCheck(requestCode);
+        public void cancelAttentionCheck(IAttentionCallback callback) {
+            Preconditions.checkNotNull(callback);
+            AttentionService.this.onCancelAttentionCheck(new AttentionCallback(callback));
         }
     };
 
@@ -146,35 +147,43 @@
     /**
      * Checks the user attention and calls into the provided callback.
      *
-     * @param requestCode an identifier that could be used to cancel the request
-     * @param callback    the callback to return the result to
+     * @param callback the callback to return the result to
      */
-    public abstract void onCheckAttention(int requestCode, @NonNull AttentionCallback callback);
+    public abstract void onCheckAttention(@NonNull AttentionCallback callback);
 
-    /** Cancels the attention check for a given request code. */
-    public abstract void onCancelAttentionCheck(int requestCode);
+    /**
+     * Cancels pending work for a given callback.
+     *
+     * Implementation must call back with a failure code of {@link #ATTENTION_FAILURE_CANCELLED}.
+     */
+    public abstract void onCancelAttentionCheck(@NonNull AttentionCallback callback);
 
     /** Callbacks for AttentionService results. */
     public static final class AttentionCallback {
-        private final IAttentionCallback mCallback;
+        @NonNull private final IAttentionCallback mCallback;
 
-        private AttentionCallback(IAttentionCallback callback) {
+        private AttentionCallback(@NonNull IAttentionCallback callback) {
             mCallback = callback;
         }
 
-        /** Returns the result. */
-        public void onSuccess(int requestCode, @AttentionSuccessCodes int result, long timestamp) {
+        /**
+         * Signals a success and provides the result code.
+         *
+         * @param timestamp of when the attention signal was computed; system throttles the requests
+         *                  so this is useful to know how fresh the result is.
+         */
+        public void onSuccess(@AttentionSuccessCodes int result, long timestamp) {
             try {
-                mCallback.onSuccess(requestCode, result, timestamp);
+                mCallback.onSuccess(result, timestamp);
             } catch (RemoteException e) {
                 e.rethrowFromSystemServer();
             }
         }
 
-        /** Signals a failure. */
-        public void onFailure(int requestCode, @AttentionFailureCodes int error) {
+        /** Signals a failure and provides the error code. */
+        public void onFailure(@AttentionFailureCodes int error) {
             try {
-                mCallback.onFailure(requestCode, error);
+                mCallback.onFailure(error);
             } catch (RemoteException e) {
                 e.rethrowFromSystemServer();
             }
diff --git a/core/java/android/service/attention/IAttentionCallback.aidl b/core/java/android/service/attention/IAttentionCallback.aidl
index 0e8a1e7..f65b9c0 100644
--- a/core/java/android/service/attention/IAttentionCallback.aidl
+++ b/core/java/android/service/attention/IAttentionCallback.aidl
@@ -22,6 +22,6 @@
  * @hide
  */
 oneway interface IAttentionCallback {
-    void onSuccess(int requestCode, int result, long timestamp);
-    void onFailure(int requestCode, int error);
+    void onSuccess(int result, long timestamp);
+    void onFailure(int error);
 }
diff --git a/core/java/android/service/attention/IAttentionService.aidl b/core/java/android/service/attention/IAttentionService.aidl
index c3b6f48..99e7997 100644
--- a/core/java/android/service/attention/IAttentionService.aidl
+++ b/core/java/android/service/attention/IAttentionService.aidl
@@ -24,6 +24,6 @@
  * @hide
  */
 oneway interface IAttentionService {
-    void checkAttention(int requestCode, IAttentionCallback callback);
-    void cancelAttentionCheck(int requestCode);
+    void checkAttention(IAttentionCallback callback);
+    void cancelAttentionCheck(IAttentionCallback callback);
 }
\ No newline at end of file
diff --git a/core/java/android/service/watchdog/ExplicitHealthCheckService.java b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
new file mode 100644
index 0000000..015fba1
--- /dev/null
+++ b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.watchdog;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A service to provide packages supporting explicit health checks and route checks to these
+ * packages on behalf of the package watchdog.
+ *
+ * <p>To extend this class, you must declare the service in your manifest file with the
+ * {@link android.Manifest.permission#BIND_EXPLICIT_HEALTH_CHECK_SERVICE} permission,
+ * and include an intent filter with the {@link #SERVICE_INTERFACE} action. In adddition,
+ * your implementation must live in {@link PackageManger#SYSTEM_SHARED_LIBRARY_SERVICES}.
+ * For example:</p>
+ * <pre>
+ *     &lt;service android:name=".FooExplicitHealthCheckService"
+ *             android:exported="true"
+ *             android:priority="100"
+ *             android:permission="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"&gt;
+ *         &lt;intent-filter&gt;
+ *             &lt;action android:name="android.service.watchdog.ExplicitHealthCheckService" /&gt;
+ *         &lt;/intent-filter&gt;
+ *     &lt;/service&gt;
+ * </pre>
+ * @hide
+ */
+@SystemApi
+public abstract class ExplicitHealthCheckService extends Service {
+
+    private static final String TAG = "ExplicitHealthCheckService";
+
+    /**
+     * {@link Bundle} key for a {@link List} of {@link String} value.
+     *
+     * {@hide}
+     */
+    public static final String EXTRA_SUPPORTED_PACKAGES =
+            "android.service.watchdog.extra.supported_packages";
+
+    /**
+     * {@link Bundle} key for a {@link List} of {@link String} value.
+     *
+     * {@hide}
+     */
+    public static final String EXTRA_REQUESTED_PACKAGES =
+            "android.service.watchdog.extra.requested_packages";
+
+    /**
+     * {@link Bundle} key for a {@link String} value.
+     *
+     * {@hide}
+     */
+    public static final String EXTRA_HEALTH_CHECK_PASSED_PACKAGE =
+            "android.service.watchdog.extra.health_check_passed_package";
+
+    /**
+     * The Intent action that a service must respond to. Add it to the intent filter of the service
+     * in its manifest.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE =
+            "android.service.watchdog.ExplicitHealthCheckService";
+
+    /**
+     * The permission that a service must require to ensure that only Android system can bind to it.
+     * If this permission is not enforced in the AndroidManifest of the service, the system will
+     * skip that service.
+     */
+    public static final String BIND_PERMISSION =
+            "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE";
+
+    private final ExplicitHealthCheckServiceWrapper mWrapper =
+            new ExplicitHealthCheckServiceWrapper();
+
+    /**
+     * Called when the system requests an explicit health check for {@code packageName}.
+     *
+     * <p> When {@code packageName} passes the check, implementors should call
+     * {@link #notifyHealthCheckPassed} to inform the system.
+     *
+     * <p> It could take many hours before a {@code packageName} passes a check and implementors
+     * should never drop requests unless {@link onCancel} is called or the service dies.
+     *
+     * <p> Requests should not be queued and additional calls while expecting a result for
+     * {@code packageName} should have no effect.
+     */
+    public abstract void onRequestHealthCheck(@NonNull String packageName);
+
+    /**
+     * Called when the system cancels the explicit health check request for {@code packageName}.
+     * Should do nothing if there are is no active request for {@code packageName}.
+     */
+    public abstract void onCancelHealthCheck(@NonNull String packageName);
+
+    /**
+     * Called when the system requests for all the packages supporting explicit health checks. The
+     * system may request an explicit health check for any of these packages with
+     * {@link #onRequestHealthCheck}.
+     *
+     * @return all packages supporting explicit health checks
+     */
+    @NonNull public abstract List<String> onGetSupportedPackages();
+
+    /**
+     * Called when the system requests for all the packages that it has currently requested
+     * an explicit health check for.
+     *
+     * @return all packages expecting an explicit health check result
+     */
+    @NonNull public abstract List<String> onGetRequestedPackages();
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);
+    @Nullable private RemoteCallback mCallback;
+
+    @Override
+    @NonNull
+    public final IBinder onBind(@NonNull Intent intent) {
+        return mWrapper;
+    }
+
+    /**
+     * Implementors should call this to notify the system when explicit health check passes
+     * for {@code packageName};
+     */
+    public final void notifyHealthCheckPassed(@NonNull String packageName) {
+        mHandler.post(() -> {
+            if (mCallback != null) {
+                Objects.requireNonNull(packageName,
+                        "Package passing explicit health check must be non-null");
+                Bundle bundle = new Bundle();
+                bundle.putString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE, packageName);
+                mCallback.sendResult(bundle);
+            } else {
+                Log.wtf(TAG, "System missed explicit health check result for " + packageName);
+            }
+        });
+    }
+
+    private class ExplicitHealthCheckServiceWrapper extends IExplicitHealthCheckService.Stub {
+        @Override
+        public void setCallback(RemoteCallback callback) throws RemoteException {
+            mHandler.post(() -> {
+                mCallback = callback;
+            });
+        }
+
+        @Override
+        public void request(String packageName) throws RemoteException {
+            mHandler.post(() -> ExplicitHealthCheckService.this.onRequestHealthCheck(packageName));
+        }
+
+        @Override
+        public void cancel(String packageName) throws RemoteException {
+            mHandler.post(() -> ExplicitHealthCheckService.this.onCancelHealthCheck(packageName));
+        }
+
+        @Override
+        public void getSupportedPackages(RemoteCallback callback) throws RemoteException {
+            mHandler.post(() -> sendPackages(callback, EXTRA_SUPPORTED_PACKAGES,
+                    ExplicitHealthCheckService.this.onGetSupportedPackages()));
+        }
+
+        @Override
+        public void getRequestedPackages(RemoteCallback callback) throws RemoteException {
+            mHandler.post(() -> sendPackages(callback, EXTRA_REQUESTED_PACKAGES,
+                    ExplicitHealthCheckService.this.onGetRequestedPackages()));
+        }
+
+        private void sendPackages(RemoteCallback callback, String key, List<String> packages) {
+            Objects.requireNonNull(packages,
+                    "Supported and requested package list must be non-null");
+            Bundle bundle = new Bundle();
+            bundle.putStringArrayList(key, new ArrayList<>(packages));
+            callback.sendResult(bundle);
+        }
+    }
+}
diff --git a/core/java/android/service/watchdog/IExplicitHealthCheckService.aidl b/core/java/android/service/watchdog/IExplicitHealthCheckService.aidl
new file mode 100644
index 0000000..78c0328d
--- /dev/null
+++ b/core/java/android/service/watchdog/IExplicitHealthCheckService.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.watchdog;
+
+import android.os.RemoteCallback;
+
+/**
+ * @hide
+ */
+oneway interface IExplicitHealthCheckService
+{
+    void setCallback(in @nullable RemoteCallback callback);
+    void request(String packageName);
+    void cancel(String packageName);
+    void getSupportedPackages(in RemoteCallback callback);
+    void getRequestedPackages(in RemoteCallback callback);
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cb8ece7..8bfa038 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4426,6 +4426,13 @@
     <permission android:name="android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE"
         android:protectionLevel="signature" />
 
+    <!-- Must be required by an {@link android.service.watchdog.ExplicitHealthCheckService} to
+         ensure that only the system can bind to it.
+         @hide This is not a third-party API (intended for OEMs and system apps).
+    -->
+    <permission android:name="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"
+        android:protectionLevel="signature|privileged" />
+
     <!-- @hide Permission that allows configuring appops.
      <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MANAGE_APPOPS"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9db75f2..dc0ec03 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3760,9 +3760,6 @@
     <!-- Package name for ManagedProvisioning which is responsible for provisioning work profiles. -->
     <string name="config_managed_provisioning_package" translatable="false">com.android.managedprovisioning</string>
 
-    <!-- Whether or not swipe up gesture is enabled by default -->
-    <bool name="config_swipe_up_gesture_default">false</bool>
-
     <!-- Whether or not swipe up gesture's opt-in setting is available on this device -->
     <bool name="config_swipe_up_gesture_setting_available">false</bool>
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8168933..bb47370 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4838,10 +4838,10 @@
     <string name="confirm_battery_saver">Confirm</string>
 
     <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, with a "learn more" link. -->
-    <string name="battery_saver_description_with_learn_more">To extend your battery life, Battery Saver turns off some device features and restricts apps. <annotation id="url">Learn More</annotation></string>
+    <string name="battery_saver_description_with_learn_more">Battery Saver turns off or restricts background activity, some visual effects \u0026 other high-power features to extend battery life. <annotation id="url">Learn More</annotation></string>
 
     <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, without a "learn more" link. -->
-    <string name="battery_saver_description">To extend your battery life, Battery Saver turns off some device features and restricts apps.</string>
+    <string name="battery_saver_description">Battery Saver turns off or restricts background activity, some visual effects \u0026 other high-power features to extend battery life.</string>
 
     <!-- [CHAR_LIMIT=NONE] Data saver: Feature description -->
     <string name="data_saver_description">To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them.</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7ec5b5b..ae54a6a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3515,7 +3515,6 @@
   <java-symbol type="string" name="shortcut_restore_signature_mismatch" />
   <java-symbol type="string" name="shortcut_restore_unknown_issue" />
 
-  <java-symbol type="bool" name="config_swipe_up_gesture_default" />
   <java-symbol type="bool" name="config_swipe_up_gesture_setting_available" />
 
   <!-- From media projection -->
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
index fe2d41e..ceab407 100644
--- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
@@ -65,7 +65,6 @@
     VkFunctorDrawParams params{
       .width = mImageInfo.width(),
       .height = mImageInfo.height(),
-      .is_layer = false,  // TODO(boliu): Populate is_layer.
       .color_space_ptr = mImageInfo.colorSpace(),
       .clip_left = mClip.fLeft,
       .clip_top = mClip.fTop,
diff --git a/libs/hwui/private/hwui/DrawVkInfo.h b/libs/hwui/private/hwui/DrawVkInfo.h
index fb55f5c..4ae0f5a 100644
--- a/libs/hwui/private/hwui/DrawVkInfo.h
+++ b/libs/hwui/private/hwui/DrawVkInfo.h
@@ -42,9 +42,6 @@
   int width;
   int height;
 
-  // Input: is the render target a FBO
-  bool is_layer;
-
   // Input: current transform matrix
   float transform[16];
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java
index 2492109..ed2eebf 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java
@@ -40,14 +40,14 @@
     private Instrumentation mInst = null;
     private boolean mWriteToFile = true;
 
-
     public CameraTestResultPrinter(Instrumentation instrumentation, boolean writeToFile) {
         mInst = instrumentation;
         mWriteToFile = writeToFile;
 
         // Create a log directory if not exists.
         File baseDir = new File(RESULT_DIR);
-        if (!baseDir.exists() && !baseDir.mkdirs()) {
+        baseDir.mkdirs();
+        if (!baseDir.isDirectory()) {
             throw new IllegalStateException("Couldn't create directory for logs: " + baseDir);
         }
         Log.v(TAG, String.format("Saving test results under: %s", baseDir.getAbsolutePath()));
diff --git a/native/webview/plat_support/draw_fn.h b/native/webview/plat_support/draw_fn.h
index 5b3e496..42cad43 100644
--- a/native/webview/plat_support/draw_fn.h
+++ b/native/webview/plat_support/draw_fn.h
@@ -44,23 +44,8 @@
   int width;
   int height;
 
-  // Input: is the View rendered into an independent layer.
-  // If false, the surface is likely to hold to the full screen contents, with
-  // the scissor box set by the caller to the actual View location and size.
-  // Also the transformation matrix will contain at least a translation to the
-  // position of the View to render, plus any other transformations required as
-  // part of any ongoing View animation. View translucency (alpha) is ignored,
-  // although the framework will set is_layer to true for non-opaque cases.
-  // Can be requested via the View.setLayerType(View.LAYER_TYPE_NONE, ...)
-  // Android API method.
-  //
-  // If true, the surface is dedicated to the View and should have its size.
-  // The viewport and scissor box are set by the caller to the whole surface.
-  // Animation transformations are handled by the caller and not reflected in
-  // the provided transformation matrix. Translucency works normally.
-  // Can be requested via the View.setLayerType(View.LAYER_TYPE_HARDWARE, ...)
-  // Android API method.
-  bool is_layer;
+  // Used to be is_layer.
+  bool deprecated_0;
 
   // Input: current transformation matrix in surface pixels.
   // Uses the column-based OpenGL matrix format.
@@ -102,8 +87,7 @@
   int width;
   int height;
 
-  // Input: is the render target a FBO
-  bool is_layer;
+  bool deprecated_0;
 
   // Input: current transform matrix
   float transform[16];
diff --git a/native/webview/plat_support/draw_functor.cpp b/native/webview/plat_support/draw_functor.cpp
index e43a60c..7cce61b 100644
--- a/native/webview/plat_support/draw_functor.cpp
+++ b/native/webview/plat_support/draw_functor.cpp
@@ -65,7 +65,7 @@
       .clip_bottom = draw_gl_params.clipBottom,
       .width = draw_gl_params.width,
       .height = draw_gl_params.height,
-      .is_layer = draw_gl_params.isLayer,
+      .deprecated_0 = false,
       .transfer_function_g = gabcdef[0],
       .transfer_function_a = gabcdef[1],
       .transfer_function_b = gabcdef[2],
@@ -126,7 +126,7 @@
       .version = kAwDrawFnVersion,
       .width = draw_vk_params.width,
       .height = draw_vk_params.height,
-      .is_layer = draw_vk_params.is_layer,
+      .deprecated_0 = false,
       .secondary_command_buffer = draw_vk_params.secondary_command_buffer,
       .color_attachment_index = draw_vk_params.color_attachment_index,
       .compatible_render_pass = draw_vk_params.compatible_render_pass,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index de7202c..e374db3 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2410,12 +2410,6 @@
                 Settings.Secure.WAKE_GESTURE_ENABLED,
                 SecureSettingsProto.WAKE_GESTURE_ENABLED);
 
-        final long launcherToken = p.start(SecureSettingsProto.LAUNCHER);
-        dumpSetting(s, p,
-                Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED,
-                SecureSettingsProto.Launcher.SWIPE_UP_TO_SWITCH_APPS_ENABLED);
-        p.end(launcherToken);
-
         final long zenToken = p.start(SecureSettingsProto.ZEN);
         dumpSetting(s, p,
                 Settings.Secure.ZEN_DURATION,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index e8d726e..4b342b3 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -4329,7 +4329,7 @@
                     // Migrate the swipe up setting only if it is set
                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
                     final Setting swipeUpSetting = secureSettings.getSettingLocked(
-                            Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED);
+                            "swipe_up_to_switch_apps_enabled");
                     if (swipeUpSetting != null && !swipeUpSetting.isNull()) {
                         navBarMode = swipeUpSetting.getValue().equals("1")
                                 ? NAV_BAR_MODE_2BUTTON
diff --git a/packages/SystemUI/res/layout-land/volume_dialog.xml b/packages/SystemUI/res/layout-land/volume_dialog.xml
index c1e74ef..9acfbaf 100644
--- a/packages/SystemUI/res/layout-land/volume_dialog.xml
+++ b/packages/SystemUI/res/layout-land/volume_dialog.xml
@@ -15,6 +15,7 @@
   -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:sysui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/volume_dialog_container"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
@@ -116,16 +117,17 @@
             android:clipToPadding="false"
             android:translationZ="@dimen/volume_dialog_elevation"
             android:background="@drawable/rounded_bg_full">
-            <com.android.keyguard.AlphaOptimizedImageButton
+            <com.android.systemui.volume.CaptionsToggleImageButton
                 android:id="@+id/odi_captions_icon"
                 android:src="@drawable/ic_volume_odi_captions_disabled"
                 style="@style/VolumeButtons"
                 android:background="@drawable/rounded_ripple"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
-                android:tint="@color/accent_tint_color_selector"
+                android:tint="@color/caption_tint_color_selector"
                 android:layout_gravity="center"
-                android:soundEffectsEnabled="false" />
+                android:soundEffectsEnabled="false"
+                sysui:optedOut="false"/>
         </FrameLayout>
 
         <ViewStub
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 62309fd..3aba6a0 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -165,6 +165,12 @@
     <!-- Message of USB contaminant presence dialog [CHAR LIMIT=NONE] -->
     <string name="usb_contaminant_message">To protect your device from liquid or debris, the USB port is disabled and won\u2019t detect any accessories.\n\nYou\u2019ll be notified when it\u2019s safe to use the USB port again.</string>
 
+    <!-- Toast for enabling ports from USB contaminant dialog [CHAR LIMIT=NONE] -->
+    <string name="usb_port_enabled">USB port enabled to detect chargers and accessories</string>
+
+    <!-- Button text to disable contaminant detection [CHAR LIMIT=NONE] -->
+    <string name="usb_disable_contaminant_detection">Enable USB</string>
+
     <!-- Checkbox label for application compatibility mode ON (zooming app to look like it's running
          on a phone).  [CHAR LIMIT=25] -->
     <string name="compat_mode_on">Zoom to fill screen</string>
@@ -2228,6 +2234,9 @@
     <!-- Quick settings tile secondary label format combining roaming with the mobile data type. [CHAR LIMIT=NONE] -->
     <string name="mobile_data_text_format"><xliff:g name="roaming_status" example="Roaming">%1$s</xliff:g> \u2014 <xliff:g name="mobile_data_type" example="LTE">%2$s</xliff:g></string>
 
+    <!-- Quick settings tile secondary label format combining carrier name with the mobile data tye. [CHAR LIMIT=NONE] -->
+    <string name="mobile_carrier_text_format"><xliff:g id="carrier_name" example="Test">%1$s</xliff:g>, <xliff:g id="mobile_data_type" example="LTE">%2$s</xliff:g></string>
+
     <!-- Label for when wifi is off in QS detail panel [CHAR LIMIT=NONE] -->
     <string name="wifi_is_off">Wi-Fi is off</string>
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
index b363b4a..8d6f830 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
@@ -21,12 +21,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
-/**
- * TODO: Remove this class
- */
 public class NavigationBarCompat extends QuickStepContract {
 
-
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({HIT_TARGET_NONE, HIT_TARGET_BACK, HIT_TARGET_HOME, HIT_TARGET_OVERVIEW})
     public @interface HitTarget{}
@@ -59,4 +55,6 @@
      * Interaction type: show/hide the overview button while this service is connected to launcher
      */
     public static final int FLAG_SHOW_OVERVIEW_BUTTON = 0x4;
+
+
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
index 6d7abd0..46f4c86 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
@@ -16,7 +16,13 @@
 
 package com.android.systemui.shared.system;
 
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
+
+import android.content.Context;
 import android.content.res.Resources;
+import android.view.WindowManagerPolicyConstants;
 
 /**
  * Various shared constants between Launcher and SysUI as part of quickstep
@@ -28,6 +34,13 @@
     public static final String KEY_EXTRA_WINDOW_CORNER_RADIUS = "extra_window_corner_radius";
     public static final String KEY_EXTRA_SUPPORTS_WINDOW_CORNERS = "extra_supports_window_corners";
 
+    public static final String NAV_BAR_MODE_2BUTTON_OVERLAY =
+            WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
+    public static final String NAV_BAR_MODE_3BUTTON_OVERLAY =
+            WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
+    public static final String NAV_BAR_MODE_GESTURAL_OVERLAY =
+            WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
+
     /**
      * Touch slopes and thresholds for quick step operations. Drag slop is the point where the
      * home button press/long press over are ignored and will start to drag when exceeded and the
@@ -49,4 +62,54 @@
     private static int convertDpToPixel(float dp) {
         return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
     }
+
+    /**
+     * @return whether this nav bar mode is edge to edge
+     */
+    public static boolean isGesturalMode(int mode) {
+        return mode == NAV_BAR_MODE_GESTURAL;
+    }
+
+    /**
+     * @return whether the current nav bar mode is gestural
+     */
+    public static boolean isGesturalMode(Context context) {
+        return isGesturalMode(getCurrentInteractionMode(context));
+    }
+
+    /**
+     * @return whether this nav bar mode is swipe up
+     */
+    public static boolean isSwipeUpMode(int mode) {
+        return mode == NAV_BAR_MODE_2BUTTON;
+    }
+
+    /**
+     * @return whether the current nav bar mode is swipe up
+     */
+    public static boolean isSwipeUpMode(Context context) {
+        return isSwipeUpMode(getCurrentInteractionMode(context));
+    }
+
+    /**
+     * @return whether this nav bar mode is 3 button
+     */
+    public static boolean isLegacyMode(int mode) {
+        return mode == NAV_BAR_MODE_3BUTTON;
+    }
+
+    /**
+     * @return whether this nav bar mode is 3 button
+     */
+    public static boolean isLegacyMode(Context context) {
+        return isLegacyMode(getCurrentInteractionMode(context));
+    }
+
+    /**
+     * @return the current nav bar interaction mode
+     */
+    public static int getCurrentInteractionMode(Context context) {
+        return context.getResources().getInteger(
+                com.android.internal.R.integer.config_navBarInteractionMode);
+    }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java
deleted file mode 100644
index c16cf92..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2018 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.systemui.shared.system;
-
-import android.provider.Settings;
-
-public class SettingsCompat {
-
-    public static final String SWIPE_UP_SETTING_NAME
-            = Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED;
-}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
index 2fa87d8..8731b6b 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
@@ -226,9 +226,6 @@
     protected final HashMap<DynamicAnimation.ViewProperty, Runnable> mEndActionForProperty =
             new HashMap<>();
 
-    /** Set of currently rendered transient views. */
-    private final Set<View> mTransientViews = new HashSet<>();
-
     /** The currently active animation controller. */
     private PhysicsAnimationController mController;
 
@@ -328,18 +325,6 @@
         removeView(getChildAt(index));
     }
 
-    @Override
-    public void addTransientView(View view, int index) {
-        super.addTransientView(view, index);
-        mTransientViews.add(view);
-    }
-
-    @Override
-    public void removeTransientView(View view) {
-        super.removeTransientView(view);
-        mTransientViews.remove(view);
-    }
-
     /** Immediately moves the view from wherever it currently is, to the given index. */
     public void moveViewTo(View view, int index) {
         super.removeView(view);
@@ -363,7 +348,9 @@
             // Tell the controller to animate this view out, and call the callback when it's
             // finished.
             mController.onChildRemoved(view, index, () -> {
-                // Done animating, remove the transient view.
+                // The controller says it's done with the transient view, cancel animations in case
+                // any are still running and then remove it.
+                cancelAnimationsOnView(view);
                 removeTransientView(view);
 
                 if (callback != null) {
@@ -470,13 +457,11 @@
             DynamicAnimation.ViewProperty property, View child, int index) {
         SpringAnimation newAnim = new SpringAnimation(child, property);
         newAnim.addUpdateListener((animation, value, velocity) -> {
+            final int indexOfChild = indexOfChild(child);
             final int nextAnimInChain =
-                    mController.getNextAnimationInChain(property, indexOfChild(child));
+                    mController.getNextAnimationInChain(property, indexOfChild);
 
-            // If the controller doesn't want us to chain, or if we're a transient view in the
-            // process of being removed, don't chain.
-            if (nextAnimInChain == PhysicsAnimationController.NONE
-                    || mTransientViews.contains(child)) {
+            if (nextAnimInChain == PhysicsAnimationController.NONE || indexOfChild < 0) {
                 return;
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index c587a39..db79e4d7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -25,11 +25,7 @@
 import android.content.res.Resources;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
-import android.text.SpannableString;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
 import android.text.TextUtils;
-import android.text.style.TextAppearanceSpan;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -192,8 +188,10 @@
             state.secondaryLabel = r.getString(R.string.status_bar_airplane);
         } else if (mobileDataEnabled) {
             state.state = Tile.STATE_ACTIVE;
-            state.secondaryLabel = appendMobileDataType(getMobileDataSubscriptionName(cb),
-                    cb.dataContentDescription);
+            state.secondaryLabel = appendMobileDataType(
+                    // Only show carrier name if there are more than 1 subscription
+                    cb.multipleSubs ? cb.dataSubscriptionName : "",
+                    getMobileDataContentName(cb));
         } else {
             state.state = Tile.STATE_INACTIVE;
             state.secondaryLabel = r.getString(R.string.cell_data_off);
@@ -216,24 +214,22 @@
         if (TextUtils.isEmpty(dataType)) {
             return current;
         }
-        SpannableString type = new SpannableString(dataType);
-        SpannableStringBuilder builder = new SpannableStringBuilder(current);
-        builder.append(" ");
-        builder.append(type, new TextAppearanceSpan(mContext, R.style.TextAppearance_RATBadge),
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-        return builder;
+        if (TextUtils.isEmpty(current)) {
+            return dataType;
+        }
+        return mContext.getString(R.string.mobile_carrier_text_format, current, dataType);
     }
 
-    private CharSequence getMobileDataSubscriptionName(CallbackInfo cb) {
-        if (cb.roaming && !TextUtils.isEmpty(cb.dataSubscriptionName)) {
+    private CharSequence getMobileDataContentName(CallbackInfo cb) {
+        if (cb.roaming && !TextUtils.isEmpty(cb.dataContentDescription)) {
             String roaming = mContext.getString(R.string.data_connection_roaming);
-            String dataDescription = cb.dataSubscriptionName.toString();
+            String dataDescription = cb.dataContentDescription.toString();
             return mContext.getString(R.string.mobile_data_text_format, roaming, dataDescription);
         }
         if (cb.roaming) {
             return mContext.getString(R.string.data_connection_roaming);
         }
-        return cb.dataSubscriptionName;
+        return cb.dataContentDescription;
     }
 
     @Override
@@ -254,6 +250,7 @@
         boolean activityOut;
         boolean noSim;
         boolean roaming;
+        boolean multipleSubs;
     }
 
     private final class CellSignalCallback implements SignalCallback {
@@ -272,6 +269,7 @@
             mInfo.activityIn = activityIn;
             mInfo.activityOut = activityOut;
             mInfo.roaming = roaming;
+            mInfo.multipleSubs = mController.getNumberSubscriptions() > 1;
             refreshState(mInfo);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 9219594..494e6cd 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -46,7 +46,6 @@
 import android.os.PatternMatcher;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.provider.Settings;
 import android.util.Log;
 import android.view.InputChannel;
 import android.view.MotionEvent;
@@ -60,6 +59,7 @@
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.InputChannelCompat.InputEventDispatcher;
+import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.CallbackController;
@@ -589,11 +589,9 @@
 
     private int getDefaultInteractionFlags() {
         // If there is no settings available use device default or get it from settings
-        final boolean defaultState = getSwipeUpDefaultValue();
-        final boolean swipeUpEnabled = getSwipeUpSettingAvailable()
-                ? getSwipeUpEnabledFromSettings(defaultState)
-                : defaultState;
-        return swipeUpEnabled ? 0 : DEFAULT_DISABLE_SWIPE_UP_STATE;
+        return QuickStepContract.isLegacyMode(mContext)
+                ? DEFAULT_DISABLE_SWIPE_UP_STATE
+                : 0;
     }
 
     private void notifyBackButtonAlphaChanged(float alpha, boolean animate) {
@@ -638,21 +636,6 @@
                 ActivityManagerWrapper.getInstance().getCurrentUserId()) != null;
     }
 
-    private boolean getSwipeUpDefaultValue() {
-        return mContext.getResources()
-                .getBoolean(com.android.internal.R.bool.config_swipe_up_gesture_default);
-    }
-
-    private boolean getSwipeUpSettingAvailable() {
-        return mContext.getResources()
-                .getBoolean(com.android.internal.R.bool.config_swipe_up_gesture_setting_available);
-    }
-
-    private boolean getSwipeUpEnabledFromSettings(boolean defaultValue) {
-        return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED, defaultValue ? 1 : 0) == 1;
-    }
-
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println(TAG_OPS + " state:");
@@ -665,11 +648,8 @@
 
         pw.print("  quickStepIntent="); pw.println(mQuickStepIntent);
         pw.print("  quickStepIntentResolved="); pw.println(isEnabled());
-
-        final boolean swipeUpDefaultValue = getSwipeUpDefaultValue();
-        final boolean swipeUpEnabled = getSwipeUpEnabledFromSettings(swipeUpDefaultValue);
-        pw.print("  swipeUpSetting="); pw.println(swipeUpEnabled);
-        pw.print("  swipeUpSettingDefault="); pw.println(swipeUpDefaultValue);
+        pw.print("  navBarMode=");
+        pw.println(QuickStepContract.getCurrentInteractionMode(mContext));
     }
 
     public interface OverviewProxyListener {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java
index 2d54970..9cfb1aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java
@@ -21,10 +21,11 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.os.Handler;
-import android.provider.Settings;
 import android.view.CompositionSamplingListener;
 import android.view.View;
 
+import com.android.systemui.shared.system.QuickStepContract;
+
 import java.io.PrintWriter;
 
 /**
@@ -166,9 +167,6 @@
 
     public static boolean isEnabled(Context context) {
         return context.getDisplayId() == DEFAULT_DISPLAY
-                && Settings.Global.getInt(context.getContentResolver(),
-                        NavigationPrototypeController.NAV_COLOR_ADAPT_ENABLE_SETTING, 0) == 1
-                && Settings.Global.getInt(context.getContentResolver(),
-                        NavigationPrototypeController.SHOW_HOME_HANDLE_SETTING, 0) == 1;
+                && QuickStepContract.isGesturalMode(context);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java
index 1478a07..c77b16b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java
@@ -71,7 +71,7 @@
 
     @Override
     protected void onGestureStart(MotionEvent event) {
-        if (!QuickStepController.shouldhideBackButton(getContext())) {
+        if (!QuickStepController.shouldHideBackButton(getContext())) {
             mNavigationBarView.getBackButton().setAlpha(0 /* alpha */, true /* animate */,
                     BACK_BUTTON_FADE_OUT_ALPHA);
         }
@@ -85,7 +85,7 @@
     @Override
     protected void onGestureEnd() {
         mHandler.removeCallbacks(mExecuteBackRunnable);
-        if (!QuickStepController.shouldhideBackButton(getContext())) {
+        if (!QuickStepController.shouldHideBackButton(getContext())) {
             mNavigationBarView.getBackButton().setAlpha(
                     mProxySender.getBackButtonAlpha(), true /* animate */);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index ea30451..cbb5d54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -201,7 +201,7 @@
         @Override
         public void onBackButtonAlphaChanged(float alpha, boolean animate) {
             final ButtonDispatcher backButton = mNavigationBarView.getBackButton();
-            if (QuickStepController.shouldhideBackButton(getContext())) {
+            if (QuickStepController.shouldHideBackButton(getContext())) {
                 // If property was changed to hide/show back button, going home will trigger
                 // launcher to to change the back button alpha to reflect property change
                 backButton.setVisibility(View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index faa2ab1..26aa617 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -38,6 +38,7 @@
 import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseRelativeLayout;
 import com.android.systemui.statusbar.policy.KeyButtonView;
 import com.android.systemui.tuner.TunerService;
@@ -136,10 +137,12 @@
     }
 
     protected String getDefaultLayout() {
-        final int defaultResource = mOverviewProxyService.shouldShowSwipeUpUI()
-                ? R.string.config_navBarLayoutQuickstep
-                : R.string.config_navBarLayout;
-        return mContext.getString(defaultResource);
+        final int defaultResource = QuickStepContract.isGesturalMode(getContext())
+                ? R.string.config_navBarLayoutHandle
+                : mOverviewProxyService.shouldShowSwipeUpUI()
+                        ? R.string.config_navBarLayoutQuickstep
+                        : R.string.config_navBarLayout;
+        return getContext().getString(defaultResource);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index e9a9606..f809b62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static android.content.Intent.ACTION_OVERLAY_CHANGED;
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
@@ -41,7 +42,10 @@
 import android.annotation.IntDef;
 import android.annotation.SuppressLint;
 import android.app.StatusBarManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ParceledListSlice;
 import android.content.res.Configuration;
 import android.graphics.Canvas;
@@ -88,6 +92,7 @@
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.NavigationBarCompat;
+import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 import com.android.systemui.statusbar.phone.NavigationPrototypeController.GestureAction;
 import com.android.systemui.statusbar.phone.NavigationPrototypeController.OnPrototypeChangedListener;
@@ -280,6 +285,7 @@
         }
     };
 
+    // TODO(b/112934365): To be removed
     private OnPrototypeChangedListener mPrototypeListener = new OnPrototypeChangedListener() {
         @Override
         public void onGestureRemap(int[] actions) {
@@ -289,13 +295,15 @@
         @Override
         public void onBackButtonVisibilityChanged(boolean visible) {
             if (!inScreenPinning()) {
-                getBackButton().setVisibility(visible ? VISIBLE : GONE);
+                getBackButton().setVisibility(QuickStepController.shouldHideBackButton(getContext())
+                        ? GONE : VISIBLE);
             }
         }
 
         @Override
         public void onHomeButtonVisibilityChanged(boolean visible) {
-            getHomeButton().setVisibility(visible ? VISIBLE : GONE);
+            getHomeButton().setVisibility(QuickStepController.shouldHideHomeButton(getContext())
+                    ? GONE : VISIBLE);
         }
 
         @Override
@@ -319,7 +327,7 @@
 
         @Override
         public void onHomeHandleVisiblilityChanged(boolean visible) {
-            showHomeHandle(visible);
+            showHomeHandle(QuickStepController.showHomeHandle(getContext()));
         }
 
         @Override
@@ -368,6 +376,13 @@
         }
     };
 
+    private BroadcastReceiver mOverlaysChangedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            showHomeHandle(QuickStepController.showHomeHandle(getContext()));
+        }
+    };
+
     public NavigationBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
 
@@ -421,10 +436,14 @@
                 mQuickScrubAction, null /* swipeLeftEdgeAction */, null /* swipeRightEdgeAction */
         };
 
-        mPrototypeController = new NavigationPrototypeController(mContext);
+        mPrototypeController = new NavigationPrototypeController(context);
         mPrototypeController.register();
         mPrototypeController.setOnPrototypeChangedListener(mPrototypeListener);
         mColorAdaptionController = new NavBarTintController(this, getLightTransitionsController());
+
+        IntentFilter filter = new IntentFilter(ACTION_OVERLAY_CHANGED);
+        filter.addDataScheme("package");
+        context.registerReceiver(mOverlaysChangedReceiver, filter);
     }
 
     public NavBarTintController getColorAdaptionController() {
@@ -459,7 +478,12 @@
 
     private void updateNavigationGestures() {
         if (mGestureHelper instanceof QuickStepController) {
-            final int[] assignedMap = mPrototypeController.getGestureActionMap();
+            // TODO: Clarify this when we remove the prototype controller
+            final int[] gesturalMap = {0, 7, 1, 1, 3, 3};
+            final int[] normalMap = {0, 0, 0, 0, 0, 0};
+            final int[] assignedMap = QuickStepContract.isGesturalMode(getContext())
+                    ? gesturalMap
+                    : normalMap;
             ((QuickStepController) mGestureHelper).setGestureActions(
                     getNavigationActionFromType(assignedMap[0], mDefaultGestureMap[0]),
                     getNavigationActionFromType(assignedMap[1], mDefaultGestureMap[1]),
@@ -616,6 +640,7 @@
     }
 
     public boolean isQuickScrubEnabled() {
+        // TODO(b/112934365): Remove this sys prop flag
         return SystemProperties.getBoolean("persist.quickstep.scrub.enabled", true)
                 && mOverviewProxyService.isEnabled() && isOverviewEnabled()
                 && ((mOverviewProxyService.getInteractionFlags() & FLAG_DISABLE_QUICK_SCRUB) == 0);
@@ -762,17 +787,17 @@
 
         mBarTransitions.reapplyDarkIntensity();
 
-        boolean disableHome = ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
+        boolean disableHome = QuickStepController.shouldHideHomeButton(getContext())
+                || ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
 
         // TODO(b/113914868): investigation log for disappearing home button
         Log.i(TAG, "updateNavButtonIcons (b/113914868): home disabled=" + disableHome
                 + " mDisabledFlags=" + mDisabledFlags);
-        disableHome |= mPrototypeController.hideHomeButton();
 
         // Always disable recents when alternate car mode UI is active and for secondary displays.
         boolean disableRecent = isRecentsButtonDisabled();
 
-        boolean disableBack = QuickStepController.shouldhideBackButton(getContext())
+        boolean disableBack = QuickStepController.shouldHideBackButton(getContext())
                 || (((mDisabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0) && !useAltBack);
 
         // When screen pinning, don't hide back and home when connected service or back and
@@ -791,7 +816,7 @@
             disableBack = disableRecent = false;
         }
 
-        ViewGroup navButtons = (ViewGroup) getCurrentView().findViewById(R.id.nav_buttons);
+        ViewGroup navButtons = getCurrentView().findViewById(R.id.nav_buttons);
         if (navButtons != null) {
             LayoutTransition lt = navButtons.getLayoutTransition();
             if (lt != null) {
@@ -946,8 +971,7 @@
     }
 
     private void showHomeHandle(boolean visible) {
-        mNavigationInflaterView.onTuningChanged(NAV_BAR_VIEWS,
-                visible ? getContext().getString(R.string.config_navBarLayoutHandle) : null);
+        mNavigationInflaterView.onTuningChanged(NAV_BAR_VIEWS, null);
 
         // Color adaption is tied with showing home handle, only avaliable if visible
         if (visible) {
@@ -964,7 +988,7 @@
 
     // TODO(b/112934365): move this back to NavigationBarFragment when prototype is removed
     private void updateAssistantAvailability() {
-        boolean available = mAssistantAvailable && mPrototypeController.isAssistantGestureEnabled();
+        boolean available = mAssistantAvailable && QuickStepContract.isGesturalMode(getContext());
         if (mOverviewProxyService.getProxy() != null) {
             try {
                 mOverviewProxyService.getProxy().onAssistantAvailable(available);
@@ -1267,7 +1291,7 @@
                 NavGesture.class, false /* Only one */);
         setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled());
 
-        if (mPrototypeController.isEnabled()) {
+        if (QuickStepContract.isGesturalMode(getContext())) {
             WindowManager wm = (WindowManager) getContext()
                     .getSystemService(Context.WINDOW_SERVICE);
             int width = mPrototypeController.getEdgeSensitivityWidth();
@@ -1298,6 +1322,7 @@
             mGestureHelper.destroy();
         }
         mPrototypeController.unregister();
+        getContext().unregisterReceiver(mOverlaysChangedReceiver);
         setUpSwipeUpOnboarding(false);
         for (int i = 0; i < mButtonDispatchers.size(); ++i) {
             mButtonDispatchers.valueAt(i).onDestroy();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
index 9ea8b64..7ea72c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
@@ -130,7 +130,8 @@
      * @return the width for edge swipe
      */
     public int getEdgeSensitivityWidth() {
-        return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_WIDTH_SETTING, 0));
+        // TODO: Move into resource
+        return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_WIDTH_SETTING, 48));
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index 3398fd34..25cb7d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -58,6 +58,7 @@
 import com.android.systemui.shared.recents.utilities.Utilities;
 import com.android.systemui.shared.system.InputChannelCompat.InputEventDispatcher;
 import com.android.systemui.shared.system.NavigationBarCompat;
+import com.android.systemui.shared.system.QuickStepContract;
 
 import java.io.PrintWriter;
 
@@ -72,6 +73,7 @@
 
     /** Experiment to swipe home button left to execute a back key press */
     private static final String HIDE_BACK_BUTTON_PROP = "quickstepcontroller_hideback";
+    private static final String HIDE_HOME_BUTTON_PROP = "quickstepcontroller_hidehome";
     private static final String ENABLE_CLICK_THROUGH_NAV_PROP = "quickstepcontroller_clickthrough";
     private static final String GESTURE_REGION_THRESHOLD_SETTING = "gesture_region_threshold";
     private static final long BACK_BUTTON_FADE_IN_ALPHA = 150;
@@ -148,7 +150,7 @@
     public void setComponents(NavigationBarView navigationBarView) {
         mNavigationBarView = navigationBarView;
 
-        mNavigationBarView.getBackButton().setVisibility(shouldhideBackButton(mContext)
+        mNavigationBarView.getBackButton().setVisibility(shouldHideBackButton(mContext)
                 ? View.GONE
                 : View.VISIBLE);
     }
@@ -355,7 +357,7 @@
                         if (mCurrentAction != null) {
                             mCurrentAction.endGesture();
                         }
-                    } else if (getBoolGlobalSetting(mContext, ENABLE_CLICK_THROUGH_NAV_PROP)
+                    } else if (QuickStepContract.isGesturalMode(mContext)
                             && !mClickThroughPressed) {
                         // Enable click through functionality where no gesture has been detected and
                         // not passed the drag slop so inject a touch event at the same location
@@ -700,6 +702,8 @@
         return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
     }
 
+    // TODO(112934365): Clean up following methods when cleaning up nav bar experiments
+
     static boolean getBoolGlobalSetting(Context context, String key) {
         return Settings.Global.getInt(context.getContentResolver(), key, 0) != 0;
     }
@@ -708,7 +712,24 @@
         return Settings.Global.getInt(context.getContentResolver(), key, defaultValue);
     }
 
-    public static boolean shouldhideBackButton(Context context) {
-        return getBoolGlobalSetting(context, HIDE_BACK_BUTTON_PROP);
+    /**
+     * @return whether to hide the back button.
+     */
+    public static boolean shouldHideBackButton(Context context) {
+        return QuickStepContract.isGesturalMode(context);
+    }
+
+    /**
+     * @return whether to hide the home button.
+     */
+    public static boolean shouldHideHomeButton(Context context) {
+        return QuickStepContract.isGesturalMode(context);
+    }
+
+    /**
+     * @return whether to show the home handle.
+     */
+    public static boolean showHomeHandle(Context context) {
+        return QuickStepContract.isGesturalMode(context);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 5bd394f..c5996a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -470,10 +470,16 @@
             mNetworkController.recalculateEmergency();
         }
         // Fill in the network name if we think we have it.
-        if (mCurrentState.networkName == mNetworkNameDefault && mServiceState != null
+        if (mCurrentState.networkName.equals(mNetworkNameDefault) && mServiceState != null
                 && !TextUtils.isEmpty(mServiceState.getOperatorAlphaShort())) {
             mCurrentState.networkName = mServiceState.getOperatorAlphaShort();
         }
+        // If this is the data subscription, update the currentState data name
+        if (mCurrentState.networkNameData.equals(mNetworkNameDefault) && mServiceState != null
+                && mCurrentState.dataSim
+                && !TextUtils.isEmpty(mServiceState.getDataOperatorAlphaShort())) {
+            mCurrentState.networkNameData = mServiceState.getDataOperatorAlphaShort();
+        }
 
         notifyListenersIfNecessary();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 51fef7d..71db618 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -37,6 +37,7 @@
     DataUsageController getMobileDataController();
     DataSaverController getDataSaverController();
     String getMobileDataNetworkName();
+    int getNumberSubscriptions();
 
     boolean hasVoiceCallingFeature();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index ef39912..d01430a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -376,6 +376,11 @@
         return controller != null ? controller.getState().networkNameData : "";
     }
 
+    @Override
+    public int getNumberSubscriptions() {
+        return mMobileSignalControllers.size();
+    }
+
     public boolean isEmergencyOnly() {
         if (mMobileSignalControllers.size() == 0) {
             // When there are no active subscriptions, determine emengency state from last
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java
index fa4b3fe..ecf608b 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java
@@ -16,14 +16,17 @@
 
 package com.android.systemui.usb;
 
+import android.app.AlertDialog;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.hardware.usb.ParcelableUsbPort;
 import android.hardware.usb.UsbManager;
 import android.hardware.usb.UsbPort;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.Window;
 import android.view.WindowManager;
+import android.widget.Toast;
 
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
@@ -36,7 +39,6 @@
                                   implements DialogInterface.OnClickListener {
     private static final String TAG = "UsbContaminantActivity";
 
-    private UsbDisconnectedReceiver mDisconnectedReceiver;
     private UsbPort mUsbPort;
 
     @Override
@@ -55,8 +57,10 @@
         final AlertController.AlertParams ap = mAlertParams;
         ap.mTitle = getString(R.string.usb_contaminant_title);
         ap.mMessage = getString(R.string.usb_contaminant_message);
-        ap.mPositiveButtonText = getString(android.R.string.ok);
-        ap.mPositiveButtonListener = this;
+        ap.mNegativeButtonText = getString(android.R.string.ok);
+        ap.mNeutralButtonText = getString(R.string.usb_disable_contaminant_detection);
+        ap.mNegativeButtonListener = this;
+        ap.mNeutralButtonListener = this;
 
         setupAlert();
     }
@@ -68,6 +72,15 @@
 
     @Override
     public void onClick(DialogInterface dialog, int which) {
+        if (which == AlertDialog.BUTTON_NEUTRAL) {
+            try {
+                mUsbPort.enableContaminantDetection(false);
+                Toast.makeText(this, R.string.usb_port_enabled,
+                    Toast.LENGTH_SHORT).show();
+            } catch (Exception e) {
+                Log.e(TAG, "Unable to notify Usb service", e);
+            }
+        }
         finish();
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 5cafc02..4fe18b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -448,7 +448,12 @@
         }
     }
 
-   protected void assertNetworkNameEquals(String expected) {
+    protected void assertNetworkNameEquals(String expected) {
        assertEquals("Network name", expected, mMobileSignalController.getState().networkName);
-   }
+    }
+
+    protected void assertDataNetworkNameEquals(String expected) {
+        assertEquals("Data network name", expected, mNetworkController.getMobileDataNetworkName());
+    }
+
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 68323c9..cd0a0441 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -285,6 +285,15 @@
         testDataActivity(TelephonyManager.DATA_ACTIVITY_INOUT, true, true);
     }
 
+    @Test
+    public void testUpdateDataNetworkName() {
+        setupDefaultSignal();
+        String newDataName = "TestDataName";
+        when(mServiceState.getDataOperatorAlphaShort()).thenReturn(newDataName);
+        updateServiceState();
+        assertDataNetworkNameEquals(newDataName);
+    }
+
     private void testDataActivity(int direction, boolean in, boolean out) {
         updateDataActivity(direction);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index bcbba8b..ac6544e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -20,6 +20,7 @@
 import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import android.content.Intent;
 import android.net.ConnectivityManager;
@@ -55,7 +56,7 @@
     @Test
     public void testNoIconWithoutMobile() {
         // Turn off mobile network support.
-        Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
+        when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
@@ -117,7 +118,7 @@
     @Test
     public void testNoSimlessIconWithoutMobile() {
         // Turn off mobile network support.
-        Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
+        when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
@@ -253,14 +254,14 @@
 
             // Generate a list of subscriptions we will tell the NetworkController to use.
             SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
-            Mockito.when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
+            when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
             subscriptions.add(mockSubInfo);
         }
         assertTrue(mNetworkController.hasCorrectMobileControllers(subscriptions));
 
         // Add a subscription that the NetworkController doesn't know about.
         SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
-        Mockito.when(mockSubInfo.getSubscriptionId()).thenReturn(notTestSubscription);
+        when(mockSubInfo.getSubscriptionId()).thenReturn(notTestSubscription);
         subscriptions.add(mockSubInfo);
         assertFalse(mNetworkController.hasCorrectMobileControllers(subscriptions));
     }
@@ -290,8 +291,8 @@
             if (i != indexToSkipSubscription) {
                 // Generate a list of subscriptions we will tell the NetworkController to use.
                 SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
-                Mockito.when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
-                Mockito.when(mockSubInfo.getSimSlotIndex()).thenReturn(testSubscriptions[i]);
+                when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
+                when(mockSubInfo.getSimSlotIndex()).thenReturn(testSubscriptions[i]);
                 subscriptions.add(mockSubInfo);
             }
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java
index 5385f6d..d5ba381 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java
@@ -93,4 +93,9 @@
     public String getMobileDataNetworkName() {
         return "";
     }
+
+    @Override
+    public int getNumberSubscriptions() {
+        return 0;
+    }
 }
diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk
index b522344..c57d4e9 100644
--- a/packages/overlays/Android.mk
+++ b/packages/overlays/Android.mk
@@ -48,14 +48,6 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := frameworks-base-overlays-debug
-LOCAL_REQUIRED_MODULES := \
-	ExperimentNavigationBarFloatingOverlay \
-	ExperimentNavigationBarVisualInsetOverlay \
-	ExperimentNavigationBarDefaultOverlay \
-	ExperimentNavigationBarSlimOverlay32 \
-	ExperimentNavigationBarSlimOverlay40 \
-	ExperimentNavigationBarLargeOverlay56 \
-	ExperimentNavigationBarLargeOverlay64
 
 include $(BUILD_PHONY_PACKAGE)
 include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
new file mode 100644
index 0000000..721d11b
--- /dev/null
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2019, 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.
+ */
+-->
+<resources>
+    <!-- Height of the bottom navigation / system bar. -->
+    <dimen name="navigation_bar_height">16dp</dimen>
+    <!-- Width of the navigation bar when it is placed vertically on the screen -->
+    <dimen name="navigation_bar_width">16dp</dimen>
+    <!-- Height of the bottom navigation / system bar. -->
+    <dimen name="navigation_bar_frame_height">48dp</dimen>
+    <!-- Width of the navigation bar when it is placed vertically on the screen -->
+    <dimen name="navigation_bar_frame_width">48dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 98311fc..5b9c1f8 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -2881,6 +2881,32 @@
         mVold.commitChanges();
     }
 
+    /**
+     * Check if we should be mounting with checkpointing or are checkpointing now
+     */
+    @Override
+    public boolean needsCheckpoint() throws RemoteException {
+        // Only the system process is permitted to commit checkpoints
+        if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
+            throw new SecurityException("no permission to commit checkpoint changes");
+        }
+
+        return mVold.needsCheckpoint();
+    }
+
+    /**
+     * Abort the current set of changes and either try again, or abort entirely
+     */
+    @Override
+    public void abortChanges(String message, boolean retry) throws RemoteException {
+        // Only the system process is permitted to abort checkpoints
+        if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
+            throw new SecurityException("no permission to commit checkpoint changes");
+        }
+
+        mVold.abortChanges(message, retry);
+    }
+
     @Override
     public String getPassword() throws RemoteException {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
@@ -3871,6 +3897,7 @@
                         case "com.jrtstudio.AnotherMusicPlayer": // b/129084562
                         case "ak.alizandro.smartaudiobookplayer": // b/129084042
                         case "com.campmobile.snow": // b/128803870
+                        case "com.qnap.qfile": // b/126374406
                             return Zygote.MOUNT_EXTERNAL_LEGACY;
                     }
                 }
diff --git a/services/core/java/com/android/server/accounts/AccountsDb.java b/services/core/java/com/android/server/accounts/AccountsDb.java
index 712edcc..da66590 100644
--- a/services/core/java/com/android/server/accounts/AccountsDb.java
+++ b/services/core/java/com/android/server/accounts/AccountsDb.java
@@ -58,7 +58,6 @@
     private static final int CE_DATABASE_VERSION = 10;
     private static final int DE_DATABASE_VERSION = 3; // Added visibility support in O
 
-
     static final String TABLE_ACCOUNTS = "accounts";
     private static final String ACCOUNTS_ID = "_id";
     private static final String ACCOUNTS_NAME = "name";
@@ -267,6 +266,13 @@
         }
 
         @Override
+        public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.e(TAG, "onDowngrade: recreate accounts CE table");
+            resetDatabase(db);
+            onCreate(db);
+        }
+
+        @Override
         public void onOpen(SQLiteDatabase db) {
             if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "opened database " + CE_DATABASE_NAME);
         }
@@ -616,6 +622,13 @@
             }
         }
 
+        @Override
+        public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.e(TAG, "onDowngrade: recreate accounts DE table");
+            resetDatabase(db);
+            onCreate(db);
+        }
+
         public SQLiteDatabase getReadableDatabaseUserIsUnlocked() {
             if(!mCeAttached) {
                 Log.wtf(TAG, "getReadableDatabaseUserIsUnlocked called while user " + mUserId
@@ -1399,4 +1412,26 @@
         return new AccountsDb(deDatabaseHelper, context, preNDatabaseFile);
     }
 
+    /**
+     * Removes all tables and triggers created by AccountManager.
+     */
+    private static void resetDatabase(SQLiteDatabase db) {
+        try (Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type ='table'", null)) {
+            while (c.moveToNext()) {
+                String name = c.getString(0);
+                // Skip tables managed by SQLiteDatabase
+                if ("android_metadata".equals(name) || "sqlite_sequence".equals(name)) {
+                    continue;
+                }
+                db.execSQL("DROP TABLE IF EXISTS " + name);
+            }
+        }
+
+        try (Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type ='trigger'", null)) {
+            while (c.moveToNext()) {
+                String name = c.getString(0);
+                db.execSQL("DROP TRIGGER IF EXISTS " + name);
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index e357ce8..1878d00 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1805,7 +1805,7 @@
                                 || (callerApp.getCurProcState() <= ActivityManager.PROCESS_STATE_TOP
                                         && (flags & Context.BIND_TREAT_LIKE_ACTIVITY) != 0),
                         b.client);
-                mAm.updateOomAdjLocked(s.app, true);
+                mAm.updateOomAdjLocked();
             }
 
             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index b447c53..1681c5b 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -18,6 +18,7 @@
 
 import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE;
 import static android.provider.Settings.System.ADAPTIVE_SLEEP;
+import static android.service.attention.AttentionService.ATTENTION_FAILURE_CANCELLED;
 
 import android.Manifest;
 import android.annotation.NonNull;
@@ -156,9 +157,8 @@
      *
      * @return {@code true} if the framework was able to send the provided callback to the service
      */
-    private boolean checkAttention(int requestCode, long timeout,
-            AttentionCallbackInternal callback) {
-        Preconditions.checkNotNull(callback);
+    private boolean checkAttention(long timeout, AttentionCallbackInternal callbackInternal) {
+        Preconditions.checkNotNull(callbackInternal);
 
         if (!isAttentionServiceSupported()) {
             Slog.w(LOG_TAG, "Trying to call checkAttention() on an unsupported device.");
@@ -172,6 +172,7 @@
 
         synchronized (mLock) {
             final long now = SystemClock.uptimeMillis();
+            // schedule shutting down the connection if no one resets this timer
             freeIfInactiveLocked();
 
             final UserState userState = getOrCreateCurrentUserStateLocked();
@@ -184,46 +185,50 @@
                 // make sure every callback is called back
                 if (userState.mPendingAttentionCheck != null) {
                     userState.mPendingAttentionCheck.cancel(
-                            AttentionService.ATTENTION_FAILURE_UNKNOWN);
+                            ATTENTION_FAILURE_CANCELLED);
                 }
-                userState.mPendingAttentionCheck = new PendingAttentionCheck(requestCode,
-                        callback, () -> checkAttention(requestCode, timeout, callback));
+                // fire the check when the service is started
+                userState.mPendingAttentionCheck = new PendingAttentionCheck(
+                        callbackInternal, () -> checkAttention(timeout, callbackInternal));
             } else {
                 try {
                     // throttle frequent requests
-                    final AttentionCheckCache attentionCheckCache = userState.mAttentionCheckCache;
-                    if (attentionCheckCache != null && now
-                            < attentionCheckCache.mLastComputed + STALE_AFTER_MILLIS) {
-                        callback.onSuccess(requestCode, attentionCheckCache.mResult,
-                                attentionCheckCache.mTimestamp);
+                    final AttentionCheckCache cache = userState.mAttentionCheckCache;
+                    if (cache != null && now < cache.mLastComputed + STALE_AFTER_MILLIS) {
+                        callbackInternal.onSuccess(cache.mResult, cache.mTimestamp);
                         return true;
                     }
 
+                    // schedule request cancellation if not returned by that point yet
                     cancelAfterTimeoutLocked(timeout);
 
-                    userState.mCurrentAttentionCheckRequestCode = requestCode;
-                    userState.mService.checkAttention(requestCode, new IAttentionCallback.Stub() {
-                        @Override
-                        public void onSuccess(int requestCode, int result, long timestamp) {
-                            callback.onSuccess(requestCode, result, timestamp);
-                            synchronized (mLock) {
-                                userState.mAttentionCheckCache = new AttentionCheckCache(
-                                        SystemClock.uptimeMillis(), result,
-                                        timestamp);
-                                userState.mCurrentAttentionCheckIsFulfilled = true;
-                            }
-                            StatsLog.write(StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED,
-                                    result);
-                        }
+                    userState.mCurrentAttentionCheck = new AttentionCheck(callbackInternal,
+                            new IAttentionCallback.Stub() {
+                                @Override
+                                public void onSuccess(int result, long timestamp) {
+                                    callbackInternal.onSuccess(result, timestamp);
+                                    synchronized (mLock) {
+                                        userState.mAttentionCheckCache = new AttentionCheckCache(
+                                                SystemClock.uptimeMillis(), result,
+                                                timestamp);
+                                        userState.mCurrentAttentionCheckIsFulfilled = true;
+                                    }
+                                    StatsLog.write(
+                                            StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED,
+                                            result);
+                                }
 
-                        @Override
-                        public void onFailure(int requestCode, int error) {
-                            callback.onFailure(requestCode, error);
-                            userState.mCurrentAttentionCheckIsFulfilled = true;
-                            StatsLog.write(StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED,
-                                    error);
-                        }
-                    });
+                                @Override
+                                public void onFailure(int error) {
+                                    callbackInternal.onFailure(error);
+                                    userState.mCurrentAttentionCheckIsFulfilled = true;
+                                    StatsLog.write(
+                                            StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED,
+                                            error);
+                                }
+                            });
+                    userState.mService.checkAttention(
+                            userState.mCurrentAttentionCheck.mIAttentionCallback);
                 } catch (RemoteException e) {
                     Slog.e(LOG_TAG, "Cannot call into the AttentionService");
                     return false;
@@ -234,7 +239,7 @@
     }
 
     /** Cancels the specified attention check. */
-    private void cancelAttentionCheck(int requestCode) {
+    private void cancelAttentionCheck(AttentionCallbackInternal callbackInternal) {
         synchronized (mLock) {
             final UserState userState = peekCurrentUserStateLocked();
             if (userState == null) {
@@ -242,15 +247,21 @@
             }
             if (userState.mService == null) {
                 if (userState.mPendingAttentionCheck != null
-                        && userState.mPendingAttentionCheck.mRequestCode == requestCode) {
+                        && userState.mPendingAttentionCheck.mCallbackInternal.equals(
+                        callbackInternal)) {
                     userState.mPendingAttentionCheck = null;
                 }
                 return;
             }
-            try {
-                userState.mService.cancelAttentionCheck(requestCode);
-            } catch (RemoteException e) {
-                Slog.e(LOG_TAG, "Cannot call into the AttentionService");
+            if (userState.mCurrentAttentionCheck.mCallbackInternal.equals(callbackInternal)) {
+                try {
+                    userState.mService.cancelAttentionCheck(
+                            userState.mCurrentAttentionCheck.mIAttentionCallback);
+                } catch (RemoteException e) {
+                    Slog.e(LOG_TAG, "Cannot call into the AttentionService");
+                }
+            } else {
+                Slog.e(LOG_TAG, "Cannot cancel a non-current request");
             }
         }
     }
@@ -387,14 +398,13 @@
         }
 
         @Override
-        public boolean checkAttention(int requestCode, long timeout,
-                AttentionCallbackInternal callback) {
-            return AttentionManagerService.this.checkAttention(requestCode, timeout, callback);
+        public boolean checkAttention(long timeout, AttentionCallbackInternal callbackInternal) {
+            return AttentionManagerService.this.checkAttention(timeout, callbackInternal);
         }
 
         @Override
-        public void cancelAttentionCheck(int requestCode) {
-            AttentionManagerService.this.cancelAttentionCheck(requestCode);
+        public void cancelAttentionCheck(AttentionCallbackInternal callbackInternal) {
+            AttentionManagerService.this.cancelAttentionCheck(callbackInternal);
         }
 
         @Override
@@ -417,19 +427,17 @@
     }
 
     private static final class PendingAttentionCheck {
-        private final int mRequestCode;
-        private final AttentionCallbackInternal mCallback;
+        private final AttentionCallbackInternal mCallbackInternal;
         private final Runnable mRunnable;
 
-        PendingAttentionCheck(int requestCode, AttentionCallbackInternal callback,
+        PendingAttentionCheck(AttentionCallbackInternal callbackInternal,
                 Runnable runnable) {
-            mRequestCode = requestCode;
-            mCallback = callback;
+            mCallbackInternal = callbackInternal;
             mRunnable = runnable;
         }
 
         void cancel(@AttentionFailureCodes int failureCode) {
-            mCallback.onFailure(mRequestCode, failureCode);
+            mCallbackInternal.onFailure(failureCode);
         }
 
         void run() {
@@ -437,6 +445,17 @@
         }
     }
 
+    private static final class AttentionCheck {
+        private final AttentionCallbackInternal mCallbackInternal;
+        private final IAttentionCallback mIAttentionCallback;
+
+        AttentionCheck(AttentionCallbackInternal callbackInternal,
+                IAttentionCallback iAttentionCallback) {
+            mCallbackInternal = callbackInternal;
+            mIAttentionCallback = iAttentionCallback;
+        }
+    }
+
     private static final class UserState {
         final ComponentName mComponentName;
         final AttentionServiceConnection mConnection = new AttentionServiceConnection();
@@ -446,12 +465,12 @@
         @GuardedBy("mLock")
         boolean mBinding;
         @GuardedBy("mLock")
-        int mCurrentAttentionCheckRequestCode;
+        AttentionCheck mCurrentAttentionCheck;
         @GuardedBy("mLock")
         boolean mCurrentAttentionCheckIsFulfilled;
+
         @GuardedBy("mLock")
         PendingAttentionCheck mPendingAttentionCheck;
-
         @GuardedBy("mLock")
         AttentionCheckCache mAttentionCheckCache;
 
@@ -569,8 +588,7 @@
                         if (userState != null) {
                             // If not called back already.
                             if (!userState.mCurrentAttentionCheckIsFulfilled) {
-                                cancel(userState,
-                                        AttentionService.ATTENTION_FAILURE_TIMED_OUT);
+                                cancel(userState, AttentionService.ATTENTION_FAILURE_TIMED_OUT);
                             }
 
                         }
@@ -588,13 +606,14 @@
         if (userState.mService != null) {
             try {
                 userState.mService.cancelAttentionCheck(
-                        userState.mCurrentAttentionCheckRequestCode);
+                        userState.mCurrentAttentionCheck.mIAttentionCallback);
             } catch (RemoteException e) {
                 Slog.e(LOG_TAG, "Unable to cancel attention check");
             }
 
             if (userState.mPendingAttentionCheck != null) {
                 userState.mPendingAttentionCheck.cancel(failureCode);
+                userState.mPendingAttentionCheck = null;
             }
         }
     }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e43fc1f..dddb7ef 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4106,11 +4106,19 @@
         if (r == null) {
             return;
         }
-        if (mAssistants.isAdjustmentAllowed(adjustment.getKey())) {
-            if (adjustment.getSignals() != null) {
-                Bundle.setDefusable(adjustment.getSignals(), true);
-                r.addAdjustment(adjustment);
+        if (adjustment.getSignals() != null) {
+            final Bundle adjustments = adjustment.getSignals();
+            Bundle.setDefusable(adjustments, true);
+            List<String> toRemove = new ArrayList<>();
+            for (String potentialKey : adjustments.keySet()) {
+                if (!mAssistants.isAdjustmentAllowed(potentialKey)) {
+                    toRemove.add(potentialKey);
+                }
             }
+            for (String removeKey : toRemove) {
+                adjustments.remove(removeKey);
+            }
+            r.addAdjustment(adjustment);
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 73b000e..10c30e3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1141,11 +1141,22 @@
                     switch (userStatus) {
                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
                             if (!verified) {
-                                // updatedStatus is already UNDEFINED
-                                needUpdate = true;
+                                // Don't demote if sysconfig says 'always'
+                                SystemConfig systemConfig = SystemConfig.getInstance();
+                                ArraySet<String> packages = systemConfig.getLinkedApps();
+                                if (!packages.contains(packageName)) {
+                                    // updatedStatus is already UNDEFINED
+                                    needUpdate = true;
 
-                                if (DEBUG_DOMAIN_VERIFICATION) {
-                                    Slog.d(TAG, "Formerly validated but now failing; demoting");
+                                    if (DEBUG_DOMAIN_VERIFICATION) {
+                                        Slog.d(TAG, "Formerly validated but now failing; demoting");
+                                    }
+                                } else {
+                                    if (DEBUG_DOMAIN_VERIFICATION) {
+                                        Slog.d(TAG, "Updating bundled package " + packageName
+                                                + " failed autoVerify, but sysconfig supersedes");
+                                    }
+                                    // leave needUpdate == false here intentionally
                                 }
                             }
                             break;
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 0a17e130..212df43 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -189,11 +189,8 @@
     @Deprecated
     private static final Set<String> STORAGE_PERMISSIONS = new ArraySet<>();
     static {
-        // STOPSHIP(b/112545973): remove once feature enabled by default
-        if (!StorageManager.hasIsolatedStorage()) {
-            STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
-            STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
-        }
+        STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
+        STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
     }
 
     private static final Set<String> MEDIA_AURAL_PERMISSIONS = new ArraySet<>();
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 40f2a2b..3029f51 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1666,18 +1666,6 @@
             for (int i = 0; i < numPerms; i++) {
                 String permission = pkg.requestedPermissions.get(i);
 
-                int op = permissionToOpCode(permission);
-                if (op == OP_NONE) {
-                    continue;
-                }
-
-                // Runtime permissions are per uid, not per package, hence per package app-op
-                // modes should never have been set. It is possible to set them via the shell
-                // though. Revert such settings during boot to get the device back into a good
-                // state.
-                LocalServices.getService(AppOpsManagerInternal.class).setAllPkgModesToDefault(
-                        op, getUid(userId, getAppId(pkg.applicationInfo.uid)));
-
                 // For pre-M apps the runtime permission do not store the state
                 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
                     continue;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 55af357..1c5c7a3 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3807,6 +3807,9 @@
             }
 
             case KeyEvent.KEYCODE_POWER: {
+                Slog.d(TAG, "interceptKeyBeforeQueueing: KEYCODE_POWER "
+                        + KeyEvent.actionToString(event.getAction())
+                        + " mPowerKeyHandled=" + mPowerKeyHandled + " b/128933363");
                 // Any activity on the power button stops the accessibility shortcut
                 cancelPendingAccessibilityShortcutAction();
                 result &= ~ACTION_PASS_TO_USER;
diff --git a/services/core/java/com/android/server/power/AttentionDetector.java b/services/core/java/com/android/server/power/AttentionDetector.java
index 701e5af..d9d21ba 100644
--- a/services/core/java/com/android/server/power/AttentionDetector.java
+++ b/services/core/java/com/android/server/power/AttentionDetector.java
@@ -34,6 +34,7 @@
 import com.android.server.LocalServices;
 
 import java.io.PrintWriter;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 
 /**
@@ -65,6 +66,11 @@
     private final Object mLock;
 
     /**
+     * If we're currently waiting for an attention callback
+     */
+    private final AtomicBoolean mRequested;
+
+    /**
      * {@link android.service.attention.AttentionService} API timeout.
      */
     private long mMaxAttentionApiTimeoutMillis;
@@ -78,11 +84,6 @@
     protected AttentionManagerInternal mAttentionManager;
 
     /**
-     * If we're currently waiting for an attention callback
-     */
-    private boolean mRequested;
-
-    /**
      * Current wakefulness of the device. {@see PowerManagerInternal}
      */
     private int mWakefulness;
@@ -94,14 +95,11 @@
 
     @VisibleForTesting
     final AttentionCallbackInternal mCallback = new AttentionCallbackInternal() {
-
         @Override
-        public void onSuccess(int requestCode, int result, long timestamp) {
-            Slog.v(TAG, "onSuccess: " + requestCode + ", " + result
-                    + " - current requestCode: " + getRequestCode());
-            synchronized (mLock) {
-                if (requestCode == getRequestCode() && mRequested) {
-                    mRequested = false;
+        public void onSuccess(int result, long timestamp) {
+            Slog.v(TAG, "onSuccess: " + result);
+            if (mRequested.getAndSet(false)) {
+                synchronized (mLock) {
                     if (mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) {
                         if (DEBUG) Slog.d(TAG, "Device slept before receiving callback.");
                         return;
@@ -116,19 +114,16 @@
         }
 
         @Override
-        public void onFailure(int requestCode, int error) {
+        public void onFailure(int error) {
             Slog.i(TAG, "Failed to check attention: " + error);
-            synchronized (mLock) {
-                if (requestCode == getRequestCode()) {
-                    mRequested = false;
-                }
-            }
+            mRequested.set(false);
         }
     };
 
     public AttentionDetector(Runnable onUserAttention, Object lock) {
         mOnUserAttention = onUserAttention;
         mLock = lock;
+        mRequested = new AtomicBoolean(false);
 
         // Device starts with an awake state upon boot.
         mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
@@ -181,9 +176,11 @@
                         + (whenToCheck - whenToStopExtending));
             }
             return nextScreenDimming;
-        } else if (mRequested) {
+        } else if (mRequested.get()) {
             if (DEBUG) {
-                Slog.d(TAG, "Pending attention callback, wait. " + getRequestCode());
+                // TODO(b/128134941): consider adding a member ID increasing counter in
+                //  AttentionCallbackInternal to track this better.
+                Slog.d(TAG, "Pending attention callback, wait.");
             }
             return whenToCheck;
         }
@@ -192,14 +189,13 @@
         // callback might arrive before #checkAttention returns (if there are cached results.)
         // This means that we must assume that the request was successful, and then cancel it
         // afterwards if AttentionManager couldn't deliver it.
-        mRequested = true;
-        final boolean sent = mAttentionManager.checkAttention(getRequestCode(),
-                getAttentionTimeout(), mCallback);
+        mRequested.set(true);
+        final boolean sent = mAttentionManager.checkAttention(getAttentionTimeout(), mCallback);
         if (!sent) {
-            mRequested = false;
+            mRequested.set(false);
         }
 
-        Slog.v(TAG, "Checking user attention with request code: " + getRequestCode());
+        Slog.v(TAG, "Checking user attention");
         return whenToCheck;
     }
 
@@ -241,9 +237,9 @@
     }
 
     private void cancelCurrentRequestIfAny() {
-        if (mRequested) {
-            mAttentionManager.cancelAttentionCheck(getRequestCode());
-            mRequested = false;
+        if (mRequested.get()) {
+            mAttentionManager.cancelAttentionCheck(mCallback);
+            mRequested.set(false);
         }
     }
 
@@ -255,11 +251,6 @@
     }
 
     @VisibleForTesting
-    int getRequestCode() {
-        return (int) (mLastUserActivityTime % Integer.MAX_VALUE);
-    }
-
-    @VisibleForTesting
     long getAttentionTimeout() {
         return mMaxAttentionApiTimeoutMillis;
     }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index 58055e5..5a9ca0f 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -353,8 +353,8 @@
 
         // Verify DPM gets notified about new device lock
         mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler
-        PasswordMetrics metric = PasswordMetrics.computeForPassword(pattern);
-        metric.quality = PASSWORD_QUALITY_SOMETHING;
+        final PasswordMetrics metric = PasswordMetrics.computeForCredential(
+                LockPatternUtils.CREDENTIAL_TYPE_PATTERN, pattern);
         verify(mDevicePolicyManager).setActivePasswordState(metric, PRIMARY_USER_ID);
 
         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
diff --git a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
index a1a58b4..5de41ea 100644
--- a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
@@ -21,7 +21,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
@@ -29,6 +28,7 @@
 import static org.mockito.Mockito.when;
 
 import android.attention.AttentionManagerInternal;
+import android.attention.AttentionManagerInternal.AttentionCallbackInternal;
 import android.os.PowerManager;
 import android.os.PowerManagerInternal;
 import android.os.SystemClock;
@@ -41,14 +41,17 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
 public class AttentionDetectorTest extends AndroidTestCase {
 
-    private @Mock AttentionManagerInternal mAttentionManagerInternal;
-    private @Mock Runnable mOnUserAttention;
+    @Mock
+    private AttentionManagerInternal mAttentionManagerInternal;
+    @Mock
+    private Runnable mOnUserAttention;
     private TestableAttentionDetector mAttentionDetector;
     private long mAttentionTimeout;
     private long mNextDimming;
@@ -57,7 +60,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        when(mAttentionManagerInternal.checkAttention(anyInt(), anyLong(), any()))
+        when(mAttentionManagerInternal.checkAttention(anyLong(), any()))
                 .thenReturn(true);
         mAttentionDetector = new TestableAttentionDetector();
         mAttentionDetector.onWakefulnessChangeStarted(PowerManagerInternal.WAKEFULNESS_AWAKE);
@@ -82,7 +85,7 @@
     @Test
     public void testOnUserActivity_checksAttention() {
         long when = registerAttention();
-        verify(mAttentionManagerInternal).checkAttention(anyInt(), anyLong(), any());
+        verify(mAttentionManagerInternal).checkAttention(anyLong(), any());
         assertThat(when).isLessThan(mNextDimming);
     }
 
@@ -92,7 +95,7 @@
                 Settings.System.ADAPTIVE_SLEEP, 0, UserHandle.USER_CURRENT);
         mAttentionDetector.updateEnabledFromSettings(getContext());
         long when = registerAttention();
-        verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
+        verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
         assertThat(mNextDimming).isEqualTo(when);
     }
 
@@ -100,7 +103,7 @@
     public void testOnUserActivity_doesntCheckIfNotSupported() {
         mAttentionDetector.setAttentionServiceSupported(false);
         long when = registerAttention();
-        verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
+        verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
         assertThat(mNextDimming).isEqualTo(when);
     }
 
@@ -129,7 +132,7 @@
         mNextDimming = now;
         mAttentionDetector.onUserActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH);
         mAttentionDetector.updateUserActivity(mNextDimming + 5000L);
-        verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
+        verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
     }
 
     @Test
@@ -146,7 +149,7 @@
         long now = SystemClock.uptimeMillis();
         mAttentionDetector.onUserActivity(now - 15000L, PowerManager.USER_ACTIVITY_EVENT_TOUCH);
         mAttentionDetector.updateUserActivity(now + 2000L);
-        verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
+        verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
     }
 
     @Test
@@ -154,7 +157,7 @@
         registerAttention();
         reset(mAttentionManagerInternal);
         long when = mAttentionDetector.updateUserActivity(mNextDimming);
-        verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
+        verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
         assertThat(when).isLessThan(mNextDimming);
     }
 
@@ -162,32 +165,35 @@
     public void testOnWakefulnessChangeStarted_cancelsRequestWhenNotAwake() {
         registerAttention();
         mAttentionDetector.onWakefulnessChangeStarted(PowerManagerInternal.WAKEFULNESS_ASLEEP);
-        verify(mAttentionManagerInternal).cancelAttentionCheck(anyInt());
+
+        ArgumentCaptor<AttentionCallbackInternal> callbackCaptor = ArgumentCaptor.forClass(
+                AttentionCallbackInternal.class);
+        verify(mAttentionManagerInternal).cancelAttentionCheck(callbackCaptor.capture());
+        assertEquals(callbackCaptor.getValue(), mAttentionDetector.mCallback);
     }
 
     @Test
     public void testCallbackOnSuccess_ignoresIfNoAttention() {
         registerAttention();
-        mAttentionDetector.mCallback.onSuccess(mAttentionDetector.getRequestCode(),
-                AttentionService.ATTENTION_SUCCESS_ABSENT, SystemClock.uptimeMillis());
+        mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_ABSENT,
+                SystemClock.uptimeMillis());
         verify(mOnUserAttention, never()).run();
     }
 
     @Test
     public void testCallbackOnSuccess_callsCallback() {
         registerAttention();
-        mAttentionDetector.mCallback.onSuccess(mAttentionDetector.getRequestCode(),
-                AttentionService.ATTENTION_SUCCESS_PRESENT, SystemClock.uptimeMillis());
+        mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_PRESENT,
+                SystemClock.uptimeMillis());
         verify(mOnUserAttention).run();
     }
 
     @Test
     public void testCallbackOnFailure_unregistersCurrentRequestCode() {
         registerAttention();
-        mAttentionDetector.mCallback.onFailure(mAttentionDetector.getRequestCode(),
-                AttentionService.ATTENTION_FAILURE_UNKNOWN);
-        mAttentionDetector.mCallback.onSuccess(mAttentionDetector.getRequestCode(),
-                AttentionService.ATTENTION_SUCCESS_PRESENT, SystemClock.uptimeMillis());
+        mAttentionDetector.mCallback.onFailure(AttentionService.ATTENTION_FAILURE_UNKNOWN);
+        mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_PRESENT,
+                SystemClock.uptimeMillis());
         verify(mOnUserAttention, never()).run();
     }
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 426122a..987d46a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -40,6 +40,8 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Build.VERSION_CODES.O_MR1;
 import static android.os.Build.VERSION_CODES.P;
+import static android.service.notification.Adjustment.KEY_IMPORTANCE;
+import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
 
@@ -492,6 +494,19 @@
         return answers;
     }
 
+    private void clearDeviceConfig() {
+        DeviceConfig.resetToDefaults(
+                Settings.RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_SYSTEMUI);
+    }
+
+    private void setDefaultAssistantInDeviceConfig(String componentName) {
+        DeviceConfig.setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE,
+                componentName,
+                false);
+    }
+
     @Test
     public void testCreateNotificationChannels_SingleChannel() throws Exception {
         final NotificationChannel channel =
@@ -831,7 +846,7 @@
         mService.addEnqueuedNotification(r);
 
         Bundle bundle = new Bundle();
-        bundle.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_NONE);
+        bundle.putInt(KEY_IMPORTANCE, IMPORTANCE_NONE);
         Adjustment adjustment = new Adjustment(
                 r.sbn.getPackageName(), r.getKey(), bundle, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
@@ -2826,7 +2841,7 @@
         mService.setHandler(handler);
 
         Bundle signals = new Bundle();
-        signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_NONE);
+        signals.putInt(KEY_IMPORTANCE, IMPORTANCE_NONE);
         Adjustment adjustment = new Adjustment(
                 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
@@ -2867,7 +2882,7 @@
         when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
 
         Bundle signals = new Bundle();
-        signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW);
+        signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
         Adjustment adjustment = new Adjustment(
                 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
@@ -2885,13 +2900,13 @@
         when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
 
         Bundle signals = new Bundle();
-        signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW);
+        signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
         Adjustment adjustment = new Adjustment(
                 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
 
         assertEquals(IMPORTANCE_DEFAULT, r.getImportance());
-        assertFalse(r.hasAdjustment(Adjustment.KEY_IMPORTANCE));
+        assertFalse(r.hasAdjustment(KEY_IMPORTANCE));
     }
 
     @Test
@@ -4275,18 +4290,7 @@
                 .onGranted(eq(xmlConfig), eq(0), eq(true));
     }
 
-    private void clearDeviceConfig() {
-        DeviceConfig.resetToDefaults(
-                Settings.RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_SYSTEMUI);
-    }
 
-    private void setDefaultAssistantInDeviceConfig(String componentName) {
-        DeviceConfig.setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE,
-                componentName,
-                false);
-    }
 
     public void testGetAllowedAssistantCapabilities() throws Exception {
         List<String> capabilities = mBinderService.getAllowedAssistantCapabilities(null);
@@ -4301,4 +4305,23 @@
             assertFalse(currentCapabilities.contains(capability));
         }
     }
+
+    public void testAdjustRestrictedKey() throws Exception {
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+
+        when(mAssistants.isAdjustmentAllowed(KEY_IMPORTANCE)).thenReturn(true);
+        when(mAssistants.isAdjustmentAllowed(KEY_USER_SENTIMENT)).thenReturn(false);
+
+        Bundle signals = new Bundle();
+        signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
+        signals.putInt(KEY_USER_SENTIMENT, USER_SENTIMENT_NEGATIVE);
+        Adjustment adjustment = new Adjustment(r.sbn.getPackageName(), r.getKey(), signals,
+               "", r.getUser().getIdentifier());
+
+        mBinderService.applyAdjustmentFromAssistant(null, adjustment);
+        r.applyAdjustments();
+
+        assertEquals(IMPORTANCE_LOW, r.getAssistantImportance());
+        assertEquals(USER_SENTIMENT_NEUTRAL, r.getUserSentiment());
+    }
 }
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index ae05750..96e12ce 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -150,8 +150,8 @@
     private NotificationManager mNotificationManager;
 
     /**
-     * If there currently is a notification about contaminated USB port shown the id of the
-     * notification, or 0 if there is none.
+     * If there currently is a notification related to contaminated USB port management
+     * shown the id of the notification, or 0 if there is none.
      */
     private int mIsPortContaminatedNotificationId;
 
@@ -191,18 +191,24 @@
     private void updateContaminantNotification() {
         PortInfo currentPortInfo = null;
         Resources r = mContext.getResources();
+        int contaminantStatus = UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED;
 
         // Not handling multiple ports here. Showing the notification
         // for the first port that returns CONTAMINANT_PRESENCE_DETECTED.
         for (PortInfo portInfo : mPorts.values()) {
-            if (portInfo.mUsbPortStatus.getContaminantDetectionStatus()
-                    == UsbPortStatus.CONTAMINANT_DETECTION_DETECTED) {
+            contaminantStatus = portInfo.mUsbPortStatus.getContaminantDetectionStatus();
+            if (contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_DETECTED
+                    || contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_DISABLED) {
                 currentPortInfo = portInfo;
                 break;
             }
         }
 
-        if (currentPortInfo != null && mIsPortContaminatedNotificationId
+        // Current contminant status is detected while "safe to use usb port"
+        // notification is displayed. Remove safe to use usb port notification
+        // and push contaminant detected notification.
+        if (contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_DETECTED
+                    && mIsPortContaminatedNotificationId
                     != SystemMessage.NOTE_USB_CONTAMINANT_DETECTED) {
             if (mIsPortContaminatedNotificationId
                     == SystemMessage.NOTE_USB_CONTAMINANT_NOT_DETECTED) {
@@ -242,32 +248,41 @@
             Notification notification = builder.build();
             mNotificationManager.notifyAsUser(null, mIsPortContaminatedNotificationId, notification,
                     UserHandle.ALL);
-        } else if (currentPortInfo == null && mIsPortContaminatedNotificationId
+        // No contaminant is detected but contaminant detection notification is displayed.
+        // Remove contaminant detection notification and push safe to use USB port notification.
+        } else if (contaminantStatus != UsbPortStatus.CONTAMINANT_DETECTION_DETECTED
+                && mIsPortContaminatedNotificationId
                 == SystemMessage.NOTE_USB_CONTAMINANT_DETECTED) {
             mNotificationManager.cancelAsUser(null, mIsPortContaminatedNotificationId,
                     UserHandle.ALL);
+            mIsPortContaminatedNotificationId = 0;
 
-            mIsPortContaminatedNotificationId = SystemMessage.NOTE_USB_CONTAMINANT_NOT_DETECTED;
-            int titleRes = com.android.internal.R.string.usb_contaminant_not_detected_title;
-            CharSequence title = r.getText(titleRes);
-            String channel = SystemNotificationChannels.ALERTS;
-            CharSequence message = r.getText(
-                    com.android.internal.R.string.usb_contaminant_not_detected_message);
+            // Dont show safe to use notification when contaminant detection is disabled.
+            // Show only when the status is changing from detected to not detected.
+            if (contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED) {
+                mIsPortContaminatedNotificationId =
+                        SystemMessage.NOTE_USB_CONTAMINANT_NOT_DETECTED;
+                int titleRes = com.android.internal.R.string.usb_contaminant_not_detected_title;
+                CharSequence title = r.getText(titleRes);
+                String channel = SystemNotificationChannels.ALERTS;
+                CharSequence message = r.getText(
+                        com.android.internal.R.string.usb_contaminant_not_detected_message);
 
-            Notification.Builder builder = new Notification.Builder(mContext, channel)
-                    .setSmallIcon(com.android.internal.R.drawable.ic_usb_48dp)
-                    .setTicker(title)
-                    .setColor(mContext.getColor(
-                           com.android.internal.R.color
-                           .system_notification_accent_color))
-                    .setContentTitle(title)
-                    .setContentText(message)
-                    .setVisibility(Notification.VISIBILITY_PUBLIC)
-                    .setStyle(new Notification.BigTextStyle()
-                    .bigText(message));
-            Notification notification = builder.build();
-            mNotificationManager.notifyAsUser(null, mIsPortContaminatedNotificationId, notification,
-                    UserHandle.ALL);
+                Notification.Builder builder = new Notification.Builder(mContext, channel)
+                        .setSmallIcon(com.android.internal.R.drawable.ic_usb_48dp)
+                        .setTicker(title)
+                        .setColor(mContext.getColor(
+                               com.android.internal.R.color
+                               .system_notification_accent_color))
+                        .setContentTitle(title)
+                        .setContentText(message)
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .setStyle(new Notification.BigTextStyle()
+                        .bigText(message));
+                Notification notification = builder.build();
+                mNotificationManager.notifyAsUser(null, mIsPortContaminatedNotificationId,
+                        notification, UserHandle.ALL);
+            }
         }
     }
 
@@ -319,8 +334,8 @@
         }
 
         try {
-            // Oneway call into the hal
-            android.hardware.usb.V1_2.IUsb proxy = (android.hardware.usb.V1_2.IUsb) mProxy;
+            // Oneway call into the hal. Use the castFrom method from HIDL.
+            android.hardware.usb.V1_2.IUsb proxy = android.hardware.usb.V1_2.IUsb.castFrom(mProxy);
             proxy.enableContaminantPresenceDetection(portId, enable);
         } catch (RemoteException e) {
             logAndPrintException(pw, "Failed to set contaminant detection", e);
@@ -948,22 +963,26 @@
         }
     }
 
+    private void handlePortLocked(PortInfo portInfo, IndentingPrintWriter pw) {
+        sendPortChangedBroadcastLocked(portInfo);
+        enableContaminantDetectionIfNeeded(portInfo, pw);
+        logToStatsd(portInfo, pw);
+        updateContaminantNotification();
+    }
+
     private void handlePortAddedLocked(PortInfo portInfo, IndentingPrintWriter pw) {
         logAndPrint(Log.INFO, pw, "USB port added: " + portInfo);
-        sendPortChangedBroadcastLocked(portInfo);
-        updateContaminantNotification();
+        handlePortLocked(portInfo, pw);
     }
 
     private void handlePortChangedLocked(PortInfo portInfo, IndentingPrintWriter pw) {
         logAndPrint(Log.INFO, pw, "USB port changed: " + portInfo);
-        sendPortChangedBroadcastLocked(portInfo);
-        updateContaminantNotification();
+        handlePortLocked(portInfo, pw);
     }
 
     private void handlePortRemovedLocked(PortInfo portInfo, IndentingPrintWriter pw) {
         logAndPrint(Log.INFO, pw, "USB port removed: " + portInfo);
-        sendPortChangedBroadcastLocked(portInfo);
-        updateContaminantNotification();
+        handlePortLocked(portInfo, pw);
     }
 
     // Constants have to be converted between USB HAL V1.2 ContaminantDetectionStatus
@@ -996,9 +1015,25 @@
         // instead of from within the critical section.
         mHandler.post(() -> mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
                 Manifest.permission.MANAGE_USB));
+    }
 
-        // Log to statsd
+    private void enableContaminantDetectionIfNeeded(PortInfo portInfo, IndentingPrintWriter pw) {
+        if (!mConnected.containsKey(portInfo.mUsbPort.getId())) {
+            return;
+        }
 
+        if (mConnected.get(portInfo.mUsbPort.getId())
+                && !portInfo.mUsbPortStatus.isConnected()
+                && portInfo.mUsbPortStatus.getContaminantDetectionStatus()
+                == UsbPortStatus.CONTAMINANT_DETECTION_DISABLED) {
+            // Contaminant detection might have been temporarily disabled by the user
+            // through SystemUI.
+            // Re-enable contaminant detection when the accessory is unplugged.
+            enableContaminantDetection(portInfo.mUsbPort.getId(), true, pw);
+        }
+    }
+
+    private void logToStatsd(PortInfo portInfo, IndentingPrintWriter pw) {
         // Port is removed
         if (portInfo.mUsbPortStatus == null) {
             if (mConnected.containsKey(portInfo.mUsbPort.getId())) {