Merge "Add new SystemApi methods for mainline"
diff --git a/Android.bp b/Android.bp
index d04eb17..3721947 100644
--- a/Android.bp
+++ b/Android.bp
@@ -958,8 +958,7 @@
 
 metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.xml) " +
     "--ignore-classes-on-classpath " +
-    "--hide-package com.android.okhttp " +
-    "--hide-package com.android.org.conscrypt --hide-package com.android.server " +
+    "--hide-package com.android.server " +
     "--error UnhiddenSystemApi " +
     "--hide RequiresPermission " +
     "--hide CallbackInterface " +
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index e731138..6831117 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,8 +1,6 @@
 [Hook Scripts]
 checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
 
-api_lint_hook = ${REPO_ROOT}/frameworks/base/tools/apilint/apilint_sha.sh ${PREUPLOAD_COMMIT}
-
 strings_lint_hook = ${REPO_ROOT}/frameworks/base/tools/stringslint/stringslint_sha.sh ${PREUPLOAD_COMMIT}
 
 hidden_api_txt_checksorted_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
diff --git a/api/current.txt b/api/current.txt
index e5acc40..de60a27 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -34183,31 +34183,31 @@
 
 package android.os {
 
-  public abstract class AsyncTask<Params, Progress, Result> {
-    ctor public AsyncTask();
-    method public final boolean cancel(boolean);
-    method @WorkerThread protected abstract Result doInBackground(Params...);
-    method @MainThread public final android.os.AsyncTask<Params,Progress,Result> execute(Params...);
-    method @MainThread public static void execute(Runnable);
-    method @MainThread public final android.os.AsyncTask<Params,Progress,Result> executeOnExecutor(java.util.concurrent.Executor, Params...);
-    method public final Result get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
-    method public final Result get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
-    method public final android.os.AsyncTask.Status getStatus();
-    method public final boolean isCancelled();
-    method @MainThread protected void onCancelled(Result);
-    method @MainThread protected void onCancelled();
-    method @MainThread protected void onPostExecute(Result);
-    method @MainThread protected void onPreExecute();
-    method @MainThread protected void onProgressUpdate(Progress...);
-    method @WorkerThread protected final void publishProgress(Progress...);
-    field public static final java.util.concurrent.Executor SERIAL_EXECUTOR;
-    field public static final java.util.concurrent.Executor THREAD_POOL_EXECUTOR;
+  @Deprecated public abstract class AsyncTask<Params, Progress, Result> {
+    ctor @Deprecated public AsyncTask();
+    method @Deprecated public final boolean cancel(boolean);
+    method @Deprecated @WorkerThread protected abstract Result doInBackground(Params...);
+    method @Deprecated @MainThread public final android.os.AsyncTask<Params,Progress,Result> execute(Params...);
+    method @Deprecated @MainThread public static void execute(Runnable);
+    method @Deprecated @MainThread public final android.os.AsyncTask<Params,Progress,Result> executeOnExecutor(java.util.concurrent.Executor, Params...);
+    method @Deprecated public final Result get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
+    method @Deprecated public final Result get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method @Deprecated public final android.os.AsyncTask.Status getStatus();
+    method @Deprecated public final boolean isCancelled();
+    method @Deprecated @MainThread protected void onCancelled(Result);
+    method @Deprecated @MainThread protected void onCancelled();
+    method @Deprecated @MainThread protected void onPostExecute(Result);
+    method @Deprecated @MainThread protected void onPreExecute();
+    method @Deprecated @MainThread protected void onProgressUpdate(Progress...);
+    method @Deprecated @WorkerThread protected final void publishProgress(Progress...);
+    field @Deprecated public static final java.util.concurrent.Executor SERIAL_EXECUTOR;
+    field @Deprecated public static final java.util.concurrent.Executor THREAD_POOL_EXECUTOR;
   }
 
-  public enum AsyncTask.Status {
-    enum_constant public static final android.os.AsyncTask.Status FINISHED;
-    enum_constant public static final android.os.AsyncTask.Status PENDING;
-    enum_constant public static final android.os.AsyncTask.Status RUNNING;
+  @Deprecated public enum AsyncTask.Status {
+    enum_constant @Deprecated public static final android.os.AsyncTask.Status FINISHED;
+    enum_constant @Deprecated public static final android.os.AsyncTask.Status PENDING;
+    enum_constant @Deprecated public static final android.os.AsyncTask.Status RUNNING;
   }
 
   public class BadParcelableException extends android.util.AndroidRuntimeException {
@@ -44280,6 +44280,9 @@
     field public static final int DATA_CYCLE_THRESHOLD_DISABLED = -2; // 0xfffffffe
     field public static final String EXTRA_SLOT_INDEX = "android.telephony.extra.SLOT_INDEX";
     field public static final String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX";
+    field public static final String KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrp_thresholds_int_array";
+    field public static final String KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrq_thresholds_int_array";
+    field public static final String KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY = "5g_nr_sssinr_thresholds_int_array";
     field public static final String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
     field public static final String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
     field public static final String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL = "allow_add_call_during_video_call";
@@ -44411,6 +44414,7 @@
     field public static final String KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT = "opportunistic_network_entry_threshold_rssnr_int";
     field public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSRP_INT = "opportunistic_network_exit_threshold_rsrp_int";
     field public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT = "opportunistic_network_exit_threshold_rssnr_int";
+    field public static final String KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT = "parameters_use_for_5g_nr_signal_bar_int";
     field public static final String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
     field public static final String KEY_PREVENT_CLIR_ACTIVATION_AND_DEACTIVATION_CODE_BOOL = "prevent_clir_activation_and_deactivation_code_bool";
     field public static final String KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY = "radio_restart_failure_causes_int_array";
@@ -52647,10 +52651,12 @@
     field public static final int MOVEMENT_GRANULARITY_WORD = 2; // 0x2
   }
 
-  public static final class AccessibilityNodeInfo.AccessibilityAction {
+  public static final class AccessibilityNodeInfo.AccessibilityAction implements android.os.Parcelable {
     ctor public AccessibilityNodeInfo.AccessibilityAction(int, @Nullable CharSequence);
+    method public int describeContents();
     method public int getId();
     method public CharSequence getLabel();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_ACCESSIBILITY_FOCUS;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_CLEAR_ACCESSIBILITY_FOCUS;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_CLEAR_FOCUS;
@@ -52688,6 +52694,7 @@
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SET_TEXT;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_ON_SCREEN;
     field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_SHOW_TOOLTIP;
+    field @NonNull public static final android.os.Parcelable.Creator<android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction> CREATOR;
   }
 
   public static final class AccessibilityNodeInfo.CollectionInfo {
diff --git a/api/system-current.txt b/api/system-current.txt
index f906ee4..5d3ecf5 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -250,6 +250,7 @@
 
   public static final class R.drawable {
     field public static final int ic_info = 17301684; // 0x10800b4
+    field public static final int stat_notify_wifi_in_range = 17301685; // 0x10800b5
   }
 
   public static final class R.raw {
@@ -268,6 +269,9 @@
     field public static final int config_helpIntentNameKey = 17039390; // 0x104001e
     field public static final int config_helpPackageNameKey = 17039387; // 0x104001b
     field public static final int config_helpPackageNameValue = 17039388; // 0x104001c
+    field public static final int notification_channel_network_alerts = 17039398; // 0x1040026
+    field public static final int notification_channel_network_available = 17039399; // 0x1040027
+    field public static final int notification_channel_network_status = 17039397; // 0x1040025
   }
 
   public static final class R.style {
@@ -1278,9 +1282,13 @@
     method public boolean disableBLE();
     method public boolean enableBLE();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean enableNoAutoConnect();
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean factoryReset();
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public long getDiscoveryEndMillis();
     method public boolean isBleScanAlwaysAvailable();
     method public boolean isLeEnabled();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean removeOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean setScanMode(int, int);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean setScanMode(int);
     field public static final String ACTION_BLE_STATE_CHANGED = "android.bluetooth.adapter.action.BLE_STATE_CHANGED";
     field public static final String ACTION_REQUEST_BLE_SCAN_ALWAYS_AVAILABLE = "android.bluetooth.adapter.action.REQUEST_BLE_SCAN_ALWAYS_AVAILABLE";
   }
@@ -1371,6 +1379,14 @@
 
 }
 
+package android.companion {
+
+  public final class CompanionDeviceManager {
+    method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean isDeviceAssociated(@NonNull String, @NonNull android.net.MacAddress, @NonNull android.os.UserHandle);
+  }
+
+}
+
 package android.content {
 
   public class ContentProviderClient implements java.lang.AutoCloseable {
@@ -4816,6 +4832,8 @@
     method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_WIFI_STATE, android.Manifest.permission.READ_WIFI_CREDENTIAL}) public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public android.net.wifi.WifiConfiguration getWifiApConfiguration();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public int getWifiApState();
+    method public boolean isApMacRandomizationSupported();
+    method public boolean isConnectedMacRandomizationSupported();
     method @Deprecated public boolean isDeviceToDeviceRttSupported();
     method public boolean isPortableHotspotSupported();
     method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled();
@@ -5147,6 +5165,7 @@
     field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2
     field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4
     field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.rtt.ResponderConfig> CREATOR;
+    field public static final int PREAMBLE_HE = 3; // 0x3
     field public static final int PREAMBLE_HT = 1; // 0x1
     field public static final int PREAMBLE_LEGACY = 0; // 0x0
     field public static final int PREAMBLE_VHT = 2; // 0x2
@@ -8340,6 +8359,7 @@
   }
 
   public final class SmsCbLocation implements android.os.Parcelable {
+    ctor public SmsCbLocation(@NonNull String, int, int);
     method public int describeContents();
     method public int getCid();
     method public int getLac();
diff --git a/api/test-current.txt b/api/test-current.txt
index c213736..242ec27 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -643,6 +643,14 @@
 
 }
 
+package android.companion {
+
+  public final class CompanionDeviceManager {
+    method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean isDeviceAssociated(@NonNull String, @NonNull android.net.MacAddress, @NonNull android.os.UserHandle);
+  }
+
+}
+
 package android.content {
 
   public final class AutofillOptions implements android.os.Parcelable {
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 3cb2273..3d4eea5 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -793,7 +793,6 @@
 Lcom/android/internal/R$id;->message:I
 Lcom/android/internal/R$id;->minute:I
 Lcom/android/internal/R$id;->month:I
-Lcom/android/internal/R$id;->name:I
 Lcom/android/internal/R$id;->notification_header:I
 Lcom/android/internal/R$id;->ok:I
 Lcom/android/internal/R$id;->overlay:I
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 738e90a..65f9678 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2572,6 +2572,9 @@
      * entirely drawn your UI and populated with all of the significant data.  You
      * can safely call this method any time after first launch as well, in which case
      * it will simply be ignored.
+     * <p>If this method is called before the activity's window is <em>first</em> drawn
+     * and displayed as measured by the system, the reported time here will be shifted
+     * to the system measured time.
      */
     public void reportFullyDrawn() {
         if (mDoReportFullyDrawn) {
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index fbf1f59..79ab67a 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -16,94 +16,58 @@
 
 package android.app;
 
-import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
-import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
-import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
-import static android.view.Display.INVALID_DISPLAY;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
-import android.app.ActivityManager.StackInfo;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Insets;
 import android.graphics.Matrix;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
-import android.hardware.display.DisplayManager;
-import android.hardware.display.VirtualDisplay;
-import android.hardware.input.InputManager;
-import android.os.RemoteException;
-import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.AttributeSet;
-import android.util.DisplayMetrics;
 import android.util.Log;
+import android.view.IWindow;
 import android.view.IWindowManager;
-import android.view.InputDevice;
-import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.SurfaceControl;
 import android.view.SurfaceHolder;
-import android.view.SurfaceSession;
 import android.view.SurfaceView;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewParent;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-import android.view.inputmethod.InputMethodManager;
 
 import dalvik.system.CloseGuard;
 
-import java.util.List;
-
 /**
- * Activity container that allows launching activities into itself.
+ * Task container that allows launching activities into itself.
  * <p>Activity launching into this container is restricted by the same rules that apply to launching
  * on VirtualDisplays.
  * @hide
  */
 @TestApi
-public class ActivityView extends ViewGroup {
+public class ActivityView extends ViewGroup implements TaskEmbedder.Host {
 
-    private static final String DISPLAY_NAME = "ActivityViewVirtualDisplay";
     private static final String TAG = "ActivityView";
 
-    private VirtualDisplay mVirtualDisplay;
+    private TaskEmbedder mTaskEmbedder;
+
     private final SurfaceView mSurfaceView;
-
-    /**
-     * This is the root surface for the VirtualDisplay. The VirtualDisplay child surfaces will be
-     * re-parented to this surface. This will also be a child of the SurfaceView's SurfaceControl.
-     */
-    private SurfaceControl mRootSurfaceControl;
-
     private final SurfaceCallback mSurfaceCallback;
-    private StateCallback mActivityViewCallback;
-
-    private IActivityTaskManager mActivityTaskManager;
-    // Temp container to store view coordinates in window.
-    private final int[] mLocationInWindow = new int[2];
-
-    // The latest tap exclude region that we've sent to WM.
-    private final Region mTapExcludeRegion = new Region();
-
-    private TaskStackListener mTaskStackListener;
 
     private final CloseGuard mGuard = CloseGuard.get();
     private boolean mOpened; // Protected by mGuard.
 
     private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
 
-    /** The ActivityView is only allowed to contain one task. */
-    private final boolean mSingleTaskInstance;
-
-    private Insets mForwardedInsets;
-
-    private float mCornerRadius;
+    // For Host
+    private final Point mWindowPosition = new Point();
+    private final int[] mTmpArray = new int[2];
+    private final Matrix mScreenSurfaceMatrix = new Matrix();
+    private final Region mTapExcludeRegion = new Region();
 
     public ActivityView(Context context) {
         this(context, null /* attrs */);
@@ -120,9 +84,7 @@
     public ActivityView(
             Context context, AttributeSet attrs, int defStyle, boolean singleTaskInstance) {
         super(context, attrs, defStyle);
-        mSingleTaskInstance = singleTaskInstance;
-
-        mActivityTaskManager = ActivityTaskManager.getService();
+        mTaskEmbedder = new TaskEmbedder(getContext(), this, singleTaskInstance);
         mSurfaceView = new SurfaceView(context);
         // Since ActivityView#getAlpha has been overridden, we should use parent class's alpha
         // as master to synchronize surface view's alpha value.
@@ -189,11 +151,11 @@
      * @see #startActivity(Intent)
      */
     public void setCallback(StateCallback callback) {
-        mActivityViewCallback = callback;
-
-        if (mVirtualDisplay != null && mActivityViewCallback != null) {
-            mActivityViewCallback.onActivityViewReady(this);
+        if (callback == null) {
+            mTaskEmbedder.setListener(null);
+            return;
         }
+        mTaskEmbedder.setListener(new StateCallbackAdapter(callback));
     }
 
     /**
@@ -262,8 +224,7 @@
      * @see #startActivity(PendingIntent)
      */
     public void startActivity(@NonNull Intent intent) {
-        final ActivityOptions options = prepareActivityOptions();
-        getContext().startActivity(intent, options.toBundle());
+        mTaskEmbedder.startActivity(intent);
     }
 
     /**
@@ -284,8 +245,7 @@
      * @see #startActivity(PendingIntent)
      */
     public void startActivity(@NonNull Intent intent, UserHandle user) {
-        final ActivityOptions options = prepareActivityOptions();
-        getContext().startActivityAsUser(intent, options.toBundle(), user);
+        mTaskEmbedder.startActivity(intent, user);
     }
 
     /**
@@ -304,14 +264,7 @@
      * @see #startActivity(Intent)
      */
     public void startActivity(@NonNull PendingIntent pendingIntent) {
-        final ActivityOptions options = prepareActivityOptions();
-        try {
-            pendingIntent.send(null /* context */, 0 /* code */, null /* intent */,
-                    null /* onFinished */, null /* handler */, null /* requiredPermission */,
-                    options.toBundle());
-        } catch (PendingIntent.CanceledException e) {
-            throw new RuntimeException(e);
-        }
+        mTaskEmbedder.startActivity(pendingIntent);
     }
 
     /**
@@ -333,28 +286,7 @@
      */
     public void startActivity(@NonNull PendingIntent pendingIntent, @Nullable Intent fillInIntent,
             @NonNull ActivityOptions options) {
-        options.setLaunchDisplayId(mVirtualDisplay.getDisplay().getDisplayId());
-        try {
-            pendingIntent.send(getContext(), 0 /* code */, fillInIntent,
-                    null /* onFinished */, null /* handler */, null /* requiredPermission */,
-                    options.toBundle());
-        } catch (PendingIntent.CanceledException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Check if container is ready to launch and create {@link ActivityOptions} to target the
-     * virtual display.
-     */
-    private ActivityOptions prepareActivityOptions() {
-        if (mVirtualDisplay == null) {
-            throw new IllegalStateException(
-                    "Trying to start activity before ActivityView is ready.");
-        }
-        final ActivityOptions options = ActivityOptions.makeBasic();
-        options.setLaunchDisplayId(mVirtualDisplay.getDisplay().getDisplayId());
-        return options;
+        mTaskEmbedder.startActivity(pendingIntent, fillInIntent, options);
     }
 
     /**
@@ -366,7 +298,7 @@
      * @see StateCallback
      */
     public void release() {
-        if (mVirtualDisplay == null) {
+        if (!mTaskEmbedder.isInitialized()) {
             throw new IllegalStateException(
                     "Trying to release container that is not initialized.");
         }
@@ -378,15 +310,7 @@
      * regions and avoid focus switches by touches on this view.
      */
     public void onLocationChanged() {
-        updateLocationAndTapExcludeRegion();
-    }
-
-    private void clearActivityViewGeometryForIme() {
-        if (mVirtualDisplay == null) {
-            return;
-        }
-        final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
-        mContext.getSystemService(InputMethodManager.class).reportActivityView(displayId, null);
+        mTaskEmbedder.notifyBoundsChanged();
     }
 
     @Override
@@ -419,102 +343,31 @@
     public boolean gatherTransparentRegion(Region region) {
         // The tap exclude region may be affected by any view on top of it, so we detect the
         // possible change by monitoring this function.
-        updateLocationAndTapExcludeRegion();
+        mTaskEmbedder.notifyBoundsChanged();
         return super.gatherTransparentRegion(region);
     }
 
-    /**
-     * Sends current location in window and tap exclude region to WM for this view.
-     */
-    private void updateLocationAndTapExcludeRegion() {
-        if (mVirtualDisplay == null || !isAttachedToWindow()) {
-            return;
-        }
-        try {
-            int x = mLocationInWindow[0];
-            int y = mLocationInWindow[1];
-            getLocationInWindow(mLocationInWindow);
-            if (x != mLocationInWindow[0] || y != mLocationInWindow[1]) {
-                x = mLocationInWindow[0];
-                y = mLocationInWindow[1];
-                final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
-                WindowManagerGlobal.getWindowSession().updateDisplayContentLocation(
-                        getWindow(), x, y, displayId);
-
-                // Also report this geometry information to InputMethodManagerService.
-                // TODO(b/115693908): Unify this logic into the above WMS-based one.
-                // TODO(b/138175283): Address the location update when the host of this view is
-                //  moving.
-                final Matrix matrix = new Matrix();
-                final int[] locationOnScreen = new int[2];
-                getLocationOnScreen(locationOnScreen);
-                final int dx = locationOnScreen[0];
-                final int dy = locationOnScreen[1];
-                matrix.set(getMatrix());
-                matrix.postTranslate(dx, dy);
-                mContext.getSystemService(InputMethodManager.class)
-                        .reportActivityView(displayId, matrix);
-            }
-            updateTapExcludeRegion(x, y);
-        } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
-        }
-    }
-
-    /** Computes and sends current tap exclude region to WM for this view. */
-    private void updateTapExcludeRegion(int x, int y) throws RemoteException {
-        if (!canReceivePointerEvents()) {
-            cleanTapExcludeRegion();
-            return;
-        }
-        mTapExcludeRegion.set(x, y, x + getWidth(), y + getHeight());
-
-        // There might be views on top of us. We need to subtract those areas from the tap
-        // exclude region.
-        final ViewParent parent = getParent();
-        if (parent != null) {
-            parent.subtractObscuredTouchableRegion(mTapExcludeRegion, this);
-        }
-
-        WindowManagerGlobal.getWindowSession().updateTapExcludeRegion(getWindow(), hashCode(),
-                mTapExcludeRegion);
-    }
-
     private class SurfaceCallback implements SurfaceHolder.Callback {
         @Override
         public void surfaceCreated(SurfaceHolder surfaceHolder) {
-            if (mVirtualDisplay == null) {
-                initVirtualDisplay(new SurfaceSession());
-                if (mVirtualDisplay != null && mActivityViewCallback != null) {
-                    mActivityViewCallback.onActivityViewReady(ActivityView.this);
-                }
+            if (!mTaskEmbedder.isInitialized()) {
+                initTaskEmbedder(mSurfaceView.getSurfaceControl());
             } else {
-                mTmpTransaction.reparent(mRootSurfaceControl,
+                mTmpTransaction.reparent(mTaskEmbedder.getSurfaceControl(),
                         mSurfaceView.getSurfaceControl()).apply();
             }
-
-            if (mVirtualDisplay != null) {
-                mVirtualDisplay.setDisplayState(true);
-            }
-
-            updateLocationAndTapExcludeRegion();
+            mTaskEmbedder.start();
         }
 
         @Override
         public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
-            if (mVirtualDisplay != null) {
-                mVirtualDisplay.resize(width, height, getBaseDisplayDensity());
-            }
-            updateLocationAndTapExcludeRegion();
+            mTaskEmbedder.resizeTask(width, height);
+            mTaskEmbedder.notifyBoundsChanged();
         }
 
         @Override
         public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
-            if (mVirtualDisplay != null) {
-                mVirtualDisplay.setDisplayState(false);
-            }
-            clearActivityViewGeometryForIme();
-            cleanTapExcludeRegion();
+            mTaskEmbedder.stop();
         }
     }
 
@@ -528,10 +381,7 @@
      * @return the display id of the virtual display.
      */
     public int getVirtualDisplayId() {
-        if (mVirtualDisplay != null) {
-            return mVirtualDisplay.getDisplay().getDisplayId();
-        }
-        return INVALID_DISPLAY;
+        return mTaskEmbedder.getDisplayId();
     }
 
     /**
@@ -539,135 +389,36 @@
      * virtual display.
      */
     public void performBackPress() {
-        if (mVirtualDisplay == null) {
-            return;
-        }
-        final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
-        final InputManager im = InputManager.getInstance();
-        im.injectInputEvent(createKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, displayId),
-                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
-        im.injectInputEvent(createKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK, displayId),
-                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+        mTaskEmbedder.performBackPress();
     }
 
-    private static KeyEvent createKeyEvent(int action, int code, int displayId) {
-        long when = SystemClock.uptimeMillis();
-        final KeyEvent ev = new KeyEvent(when, when, action, code, 0 /* repeat */,
-                0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */,
-                KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
-                InputDevice.SOURCE_KEYBOARD);
-        ev.setDisplayId(displayId);
-        return ev;
-    }
-
-    private void initVirtualDisplay(SurfaceSession surfaceSession) {
-        if (mVirtualDisplay != null) {
-            throw new IllegalStateException("Trying to initialize for the second time.");
-        }
-
-        final int width = mSurfaceView.getWidth();
-        final int height = mSurfaceView.getHeight();
-        final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
-
-        mVirtualDisplay = displayManager.createVirtualDisplay(
-                DISPLAY_NAME + "@" + System.identityHashCode(this), width, height,
-                getBaseDisplayDensity(), null,
-                VIRTUAL_DISPLAY_FLAG_PUBLIC | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
-                        | VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL);
-        if (mVirtualDisplay == null) {
+    /**
+     * Initializes the task embedder.
+     *
+     * @param parent control for the surface to parent to
+     * @return true if the task embedder has been initialized
+     */
+    private boolean initTaskEmbedder(SurfaceControl parent) {
+        if (!mTaskEmbedder.initialize(parent)) {
             Log.e(TAG, "Failed to initialize ActivityView");
-            return;
+            return false;
         }
-
-        final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
-        final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
-
-        mRootSurfaceControl = new SurfaceControl.Builder(surfaceSession)
-                .setContainerLayer()
-                .setParent(mSurfaceView.getSurfaceControl())
-                .setName(DISPLAY_NAME)
-                .build();
-
-        try {
-            // TODO: Find a way to consolidate these calls to the server.
-            WindowManagerGlobal.getWindowSession().reparentDisplayContent(
-                    getWindow(), mRootSurfaceControl, displayId);
-            wm.dontOverrideDisplayInfo(displayId);
-            if (mSingleTaskInstance) {
-                mActivityTaskManager.setDisplayToSingleTaskInstance(displayId);
-            }
-            wm.setForwardedInsets(displayId, mForwardedInsets);
-        } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
-        }
-
-        mTmpTransaction.show(mRootSurfaceControl).apply();
-        mTaskStackListener = new TaskStackListenerImpl();
-        try {
-            mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to register task stack listener", e);
-        }
+        mTmpTransaction.show(mTaskEmbedder.getSurfaceControl()).apply();
+        return true;
     }
 
     private void performRelease() {
         if (!mOpened) {
             return;
         }
-
         mSurfaceView.getHolder().removeCallback(mSurfaceCallback);
-
-        cleanTapExcludeRegion();
-
-        if (mTaskStackListener != null) {
-            try {
-                mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to unregister task stack listener", e);
-            }
-            mTaskStackListener = null;
-        }
-
-        final boolean displayReleased;
-        if (mVirtualDisplay != null) {
-            mVirtualDisplay.release();
-            mVirtualDisplay = null;
-            displayReleased = true;
-        } else {
-            displayReleased = false;
-        }
-
-        if (displayReleased && mActivityViewCallback != null) {
-            mActivityViewCallback.onActivityViewDestroyed(this);
-        }
+        mTaskEmbedder.setListener(null);
+        mTaskEmbedder.release();
 
         mGuard.close();
         mOpened = false;
     }
 
-    /** Report to server that tap exclude region on hosting display should be cleared. */
-    private void cleanTapExcludeRegion() {
-        if (!isAttachedToWindow() || mTapExcludeRegion.isEmpty()) {
-            return;
-        }
-        // Update tap exclude region with a null region to clean the state on server.
-        try {
-            WindowManagerGlobal.getWindowSession().updateTapExcludeRegion(getWindow(), hashCode(),
-                    null /* region */);
-            mTapExcludeRegion.setEmpty();
-        } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
-        }
-    }
-
-    /** Get density of the hosting display. */
-    private int getBaseDisplayDensity() {
-        final WindowManager wm = mContext.getSystemService(WindowManager.class);
-        final DisplayMetrics metrics = new DisplayMetrics();
-        wm.getDefaultDisplay().getMetrics(metrics);
-        return metrics.densityDpi;
-    }
-
     @Override
     protected void finalize() throws Throwable {
         try {
@@ -686,108 +437,100 @@
      * @see IWindowManager#setForwardedInsets
      */
     public void setForwardedInsets(Insets insets) {
-        mForwardedInsets = insets;
-        if (mVirtualDisplay == null) {
-            return;
-        }
-        try {
-            final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
-            wm.setForwardedInsets(mVirtualDisplay.getDisplay().getDisplayId(), mForwardedInsets);
-        } catch (RemoteException e) {
-            e.rethrowAsRuntimeException();
+        mTaskEmbedder.setForwardedInsets(insets);
+    }
+
+    // Host
+
+    /** @hide */
+    @Override
+    public void onTaskBackgroundColorChanged(TaskEmbedder ts, int bgColor) {
+        if (mSurfaceView != null) {
+            mSurfaceView.setResizeBackgroundColor(bgColor);
         }
     }
 
-    /**
-     * A task change listener that detects background color change of the topmost stack on our
-     * virtual display and updates the background of the surface view. This background will be shown
-     * when surface view is resized, but the app hasn't drawn its content in new size yet.
-     * It also calls StateCallback.onTaskMovedToFront to notify interested parties that the stack
-     * associated with the {@link ActivityView} has had a Task moved to the front. This is useful
-     * when needing to also bring the host Activity to the foreground at the same time.
-     */
-    private class TaskStackListenerImpl extends TaskStackListener {
+    /** @hide */
+    @Override
+    public Region getTapExcludeRegion() {
+        if (isAttachedToWindow() && canReceivePointerEvents()) {
+            Point windowPos = getPositionInWindow();
+            mTapExcludeRegion.set(
+                    windowPos.x,
+                    windowPos.y,
+                    windowPos.x + getWidth(),
+                    windowPos.y + getHeight());
+            // There might be views on top of us. We need to subtract those areas from the tap
+            // exclude region.
+            final ViewParent parent = getParent();
+            if (parent != null) {
+                parent.subtractObscuredTouchableRegion(mTapExcludeRegion, this);
+            }
+        } else {
+            mTapExcludeRegion.setEmpty();
+        }
+        return mTapExcludeRegion;
+    }
 
-        @Override
-        public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo)
-                throws RemoteException {
-            if (mVirtualDisplay == null
-                    || taskInfo.displayId != mVirtualDisplay.getDisplay().getDisplayId()) {
-                return;
-            }
+    /** @hide */
+    @Override
+    public Matrix getScreenToTaskMatrix() {
+        getLocationOnScreen(mTmpArray);
+        mScreenSurfaceMatrix.set(getMatrix());
+        mScreenSurfaceMatrix.postTranslate(mTmpArray[0], mTmpArray[1]);
+        return mScreenSurfaceMatrix;
+    }
 
-            StackInfo stackInfo = getTopMostStackInfo();
-            if (stackInfo == null) {
-                return;
-            }
-            // Found the topmost stack on target display. Now check if the topmost task's
-            // description changed.
-            if (taskInfo.taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
-                mSurfaceView.setResizeBackgroundColor(
-                        taskInfo.taskDescription.getBackgroundColor());
-            }
+    /** @hide */
+    @Override
+    public Point getPositionInWindow() {
+        getLocationInWindow(mTmpArray);
+        mWindowPosition.set(mTmpArray[0], mTmpArray[1]);
+        return mWindowPosition;
+    }
+
+    /** @hide */
+    @Override
+    public IWindow getWindow() {
+        return super.getWindow();
+    }
+
+    /** @hide */
+    @Override
+    public boolean canReceivePointerEvents() {
+        return super.canReceivePointerEvents();
+    }
+
+    private final class StateCallbackAdapter implements TaskEmbedder.Listener {
+        private final StateCallback mCallback;
+
+        private StateCallbackAdapter(ActivityView.StateCallback cb) {
+            mCallback = cb;
         }
 
         @Override
-        public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo)
-                throws RemoteException {
-            if (mActivityViewCallback  == null || mVirtualDisplay == null
-                    || taskInfo.displayId != mVirtualDisplay.getDisplay().getDisplayId()) {
-                return;
-            }
-
-            StackInfo stackInfo = getTopMostStackInfo();
-            // if StackInfo was null or unrelated to the "move to front" then there's no use
-            // notifying the callback
-            if (stackInfo != null
-                    && taskInfo.taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
-                mActivityViewCallback.onTaskMovedToFront(taskInfo.taskId);
-            }
+        public void onInitialized() {
+            mCallback.onActivityViewReady(ActivityView.this);
         }
 
         @Override
-        public void onTaskCreated(int taskId, ComponentName componentName) throws RemoteException {
-            if (mActivityViewCallback == null || mVirtualDisplay == null) {
-                return;
-            }
-
-            StackInfo stackInfo = getTopMostStackInfo();
-            // if StackInfo was null or unrelated to the task creation then there's no use
-            // notifying the callback
-            if (stackInfo != null
-                    && taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
-                mActivityViewCallback.onTaskCreated(taskId, componentName);
-            }
+        public void onReleased() {
+            mCallback.onActivityViewDestroyed(ActivityView.this);
         }
 
         @Override
-        public void onTaskRemovalStarted(ActivityManager.RunningTaskInfo taskInfo)
-                throws RemoteException {
-            if (mActivityViewCallback == null || mVirtualDisplay == null
-                    || taskInfo.displayId != mVirtualDisplay.getDisplay().getDisplayId()) {
-                return;
-            }
-            mActivityViewCallback.onTaskRemovalStarted(taskInfo.taskId);
+        public void onTaskCreated(int taskId, ComponentName name) {
+            mCallback.onTaskCreated(taskId, name);
         }
 
-        private StackInfo getTopMostStackInfo() throws RemoteException {
-            // Find the topmost task on our virtual display - it will define the background
-            // color of the surface view during resizing.
-            final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
-            final List<StackInfo> stackInfoList = mActivityTaskManager.getAllStackInfos();
+        @Override
+        public void onTaskMovedToFront(int taskId) {
+            mCallback.onTaskMovedToFront(taskId);
+        }
 
-            // Iterate through stacks from top to bottom.
-            final int stackCount = stackInfoList.size();
-            for (int i = 0; i < stackCount; i++) {
-                final StackInfo stackInfo = stackInfoList.get(i);
-                // Only look for stacks on our virtual display.
-                if (stackInfo.displayId != displayId) {
-                    continue;
-                }
-                // Found the topmost stack on target display.
-                return stackInfo;
-            }
-            return null;
+        @Override
+        public void onTaskRemovalStarted(int taskId) {
+            mCallback.onTaskRemovalStarted(taskId);
         }
     }
 }
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 629c2bb..36d899e 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -170,6 +170,7 @@
 import android.telephony.TelephonyRegistryManager;
 import android.telephony.euicc.EuiccCardManager;
 import android.telephony.euicc.EuiccManager;
+import android.telephony.ims.ImsManager;
 import android.telephony.ims.RcsMessageManager;
 import android.util.ArrayMap;
 import android.util.Log;
@@ -631,6 +632,14 @@
                     }
                 });
 
+        registerService(Context.TELEPHONY_IMS_SERVICE, ImsManager.class,
+                new CachedServiceFetcher<ImsManager>() {
+                    @Override
+                    public ImsManager createService(ContextImpl ctx) {
+                        return new ImsManager(ctx.getOuterContext());
+                    }
+                });
+
         registerService(Context.CARRIER_CONFIG_SERVICE, CarrierConfigManager.class,
                 new CachedServiceFetcher<CarrierConfigManager>() {
             @Override
diff --git a/core/java/android/app/TaskEmbedder.java b/core/java/android/app/TaskEmbedder.java
new file mode 100644
index 0000000..a1389bd
--- /dev/null
+++ b/core/java/android/app/TaskEmbedder.java
@@ -0,0 +1,674 @@
+/*
+ * 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.app;
+
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Insets;
+import android.graphics.Matrix;
+import android.graphics.Point;
+import android.graphics.Region;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.VirtualDisplay;
+import android.hardware.input.InputManager;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Display;
+import android.view.IWindow;
+import android.view.IWindowManager;
+import android.view.IWindowSession;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.SurfaceControl;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+import android.view.inputmethod.InputMethodManager;
+
+import dalvik.system.CloseGuard;
+
+import java.util.List;
+
+/**
+ * A component which handles embedded display of tasks within another window. The embedded task can
+ * be presented using the SurfaceControl provided from {@link #getSurfaceControl()}.
+ *
+ * @hide
+ */
+public class TaskEmbedder {
+    private static final String TAG = "TaskEmbedder";
+    private static final String DISPLAY_NAME = "TaskVirtualDisplay";
+
+    /**
+     * A component which will host the task.
+     */
+    public interface Host {
+        /** @return the screen area where touches should be dispatched to the embedded Task */
+        Region getTapExcludeRegion();
+
+        /** @return a matrix which transforms from screen-space to the embedded task surface */
+        Matrix getScreenToTaskMatrix();
+
+        /** @return the window containing the parent surface, if attached and available */
+        @Nullable IWindow getWindow();
+
+        /** @return the x/y offset from the origin of the window to the surface */
+        Point getPositionInWindow();
+
+        /** @return whether this surface is able to receive pointer events */
+        boolean canReceivePointerEvents();
+
+        /** @return the width of the container for the embedded task */
+        int getWidth();
+
+        /** @return the height of the container for the embedded task */
+        int getHeight();
+
+        /**
+         * Called to inform the host of the task's background color. This can be used to
+         * fill unpainted areas if necessary.
+         */
+        void onTaskBackgroundColorChanged(TaskEmbedder ts, int bgColor);
+    }
+
+    /**
+     * Describes changes to the state of the TaskEmbedder as well the tasks within.
+     */
+    public interface Listener {
+        /** Called when the container is ready for launching activities. */
+        default void onInitialized() {}
+
+        /** Called when the container can no longer launch activities. */
+        default void onReleased() {}
+
+        /** Called when a task is created inside the container. */
+        default void onTaskCreated(int taskId, ComponentName name) {}
+
+        /** Called when a task is moved to the front of the stack inside the container. */
+        default void onTaskMovedToFront(int taskId) {}
+
+        /** Called when a task is about to be removed from the stack inside the container. */
+        default void onTaskRemovalStarted(int taskId) {}
+    }
+
+    private IActivityTaskManager mActivityTaskManager = ActivityTaskManager.getService();
+
+    private final Context mContext;
+    private TaskEmbedder.Host mHost;
+    private int mDisplayDensityDpi;
+    private final boolean mSingleTaskInstance;
+    private SurfaceControl.Transaction mTransaction;
+    private SurfaceControl mSurfaceControl;
+    private VirtualDisplay mVirtualDisplay;
+    private Insets mForwardedInsets;
+    private TaskStackListener mTaskStackListener;
+    private Listener mListener;
+    private boolean mOpened; // Protected by mGuard.
+
+    private final CloseGuard mGuard = CloseGuard.get();
+
+
+    /**
+     * Constructs a new TaskEmbedder.
+     *
+     * @param context the context
+     * @param host the host for this embedded task
+     * @param singleTaskInstance whether to apply a single-task constraint to this container
+     */
+    public TaskEmbedder(Context context, TaskEmbedder.Host host, boolean singleTaskInstance) {
+        mContext = context;
+        mHost = host;
+        mSingleTaskInstance = singleTaskInstance;
+    }
+
+    /**
+     * Whether this container has been initialized.
+     *
+     * @return true if initialized
+     */
+    public boolean isInitialized() {
+        return mVirtualDisplay != null;
+    }
+
+    /**
+     * Initialize this container.
+     *
+     * @param parent the surface control for the parent surface
+     * @return true if initialized successfully
+     */
+    public boolean initialize(SurfaceControl parent) {
+        if (mVirtualDisplay != null) {
+            throw new IllegalStateException("Trying to initialize for the second time.");
+        }
+
+        mTransaction = new SurfaceControl.Transaction();
+
+        final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
+        mDisplayDensityDpi = getBaseDisplayDensity();
+
+        mVirtualDisplay = displayManager.createVirtualDisplay(
+                DISPLAY_NAME + "@" + System.identityHashCode(this), mHost.getWidth(),
+                mHost.getHeight(), mDisplayDensityDpi, null,
+                VIRTUAL_DISPLAY_FLAG_PUBLIC | VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
+                        | VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL);
+
+        if (mVirtualDisplay == null) {
+            Log.e(TAG, "Failed to initialize TaskEmbedder");
+            return false;
+        }
+
+        // Create a container surface to which the ActivityDisplay will be reparented
+        final String name = "TaskEmbedder - " + Integer.toHexString(System.identityHashCode(this));
+        mSurfaceControl = new SurfaceControl.Builder()
+                .setContainerLayer()
+                .setParent(parent)
+                .setName(name)
+                .build();
+
+        final int displayId = getDisplayId();
+
+        final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+        try {
+            // TODO: Find a way to consolidate these calls to the server.
+            WindowManagerGlobal.getWindowSession().reparentDisplayContent(
+                    mHost.getWindow(), mSurfaceControl, displayId);
+            wm.dontOverrideDisplayInfo(displayId);
+            if (mSingleTaskInstance) {
+                mContext.getSystemService(ActivityTaskManager.class)
+                        .setDisplayToSingleTaskInstance(displayId);
+            }
+            setForwardedInsets(mForwardedInsets);
+            if (mHost.getWindow() != null) {
+                updateLocationAndTapExcludeRegion();
+            }
+            mTaskStackListener = new TaskStackListenerImpl();
+            try {
+                mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to register task stack listener", e);
+            }
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+        if (mListener != null && mVirtualDisplay != null) {
+            mListener.onInitialized();
+        }
+        mOpened = true;
+        mGuard.open("release");
+        return true;
+    }
+
+    /**
+     * Returns the surface control for the task surface. This should be parented to a screen
+     * surface for display/embedding purposes.
+     *
+     * @return the surface control for the task
+     */
+    public SurfaceControl getSurfaceControl() {
+        return mSurfaceControl;
+    }
+
+    /**
+     * Set forwarded insets on the virtual display.
+     *
+     * @see IWindowManager#setForwardedInsets
+     */
+    public void setForwardedInsets(Insets insets) {
+        mForwardedInsets = insets;
+        if (mVirtualDisplay == null) {
+            return;
+        }
+        try {
+            final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+            wm.setForwardedInsets(getDisplayId(), mForwardedInsets);
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /** An opaque unique identifier for this task surface among others being managed by the app. */
+    public int getId() {
+        return getDisplayId();
+    }
+
+    int getDisplayId() {
+        if (mVirtualDisplay != null) {
+            return mVirtualDisplay.getDisplay().getDisplayId();
+        }
+        return Display.INVALID_DISPLAY;
+    }
+
+    /**
+     * Set the callback to be notified about state changes.
+     * <p>This class must finish initializing before {@link #startActivity(Intent)} can be called.
+     * <p>Note: If the instance was ready prior to this call being made, then
+     * {@link Listener#onInitialized()} will be called from within this method call.
+     *
+     * @param listener The listener to report events to.
+     *
+     * @see ActivityView.StateCallback
+     * @see #startActivity(Intent)
+     */
+    void setListener(TaskEmbedder.Listener listener) {
+        mListener = listener;
+        if (mListener != null && isInitialized()) {
+            mListener.onInitialized();
+        }
+    }
+
+    /**
+     * Launch a new activity into this container.
+     *
+     * @param intent Intent used to launch an activity
+     *
+     * @see #startActivity(PendingIntent)
+     */
+    public void startActivity(@NonNull Intent intent) {
+        final ActivityOptions options = prepareActivityOptions();
+        mContext.startActivity(intent, options.toBundle());
+    }
+
+    /**
+     * Launch a new activity into this container.
+     *
+     * @param intent Intent used to launch an activity
+     * @param user The UserHandle of the user to start this activity for
+     *
+     * @see #startActivity(PendingIntent)
+     */
+    public void startActivity(@NonNull Intent intent, UserHandle user) {
+        final ActivityOptions options = prepareActivityOptions();
+        mContext.startActivityAsUser(intent, options.toBundle(), user);
+    }
+
+    /**
+     * Launch a new activity into this container.
+     *
+     * @param pendingIntent Intent used to launch an activity
+     *
+     * @see #startActivity(Intent)
+     */
+    public void startActivity(@NonNull PendingIntent pendingIntent) {
+        final ActivityOptions options = prepareActivityOptions();
+        try {
+            pendingIntent.send(null /* context */, 0 /* code */, null /* intent */,
+                    null /* onFinished */, null /* handler */, null /* requiredPermission */,
+                    options.toBundle());
+        } catch (PendingIntent.CanceledException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Launch a new activity into this container.
+     *
+     * @param pendingIntent Intent used to launch an activity
+     * @param fillInIntent Additional Intent data, see {@link Intent#fillIn Intent.fillIn()}
+     * @param options options for the activity
+     *
+     * @see #startActivity(Intent)
+     */
+    public void startActivity(@NonNull PendingIntent pendingIntent, @Nullable Intent fillInIntent,
+            @NonNull ActivityOptions options) {
+
+        options.setLaunchDisplayId(mVirtualDisplay.getDisplay().getDisplayId());
+        try {
+            pendingIntent.send(mContext, 0 /* code */, fillInIntent,
+                    null /* onFinished */, null /* handler */, null /* requiredPermission */,
+                    options.toBundle());
+        } catch (PendingIntent.CanceledException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Check if container is ready to launch and create {@link ActivityOptions} to target the
+     * virtual display.
+     */
+    private ActivityOptions prepareActivityOptions() {
+        if (mVirtualDisplay == null) {
+            throw new IllegalStateException(
+                    "Trying to start activity before ActivityView is ready.");
+        }
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(getDisplayId());
+        return options;
+    }
+
+    /**
+     * Stops presentation of tasks in this container.
+     */
+    public void stop() {
+        if (mVirtualDisplay != null) {
+            mVirtualDisplay.setDisplayState(false);
+            clearActivityViewGeometryForIme();
+            clearTapExcludeRegion();
+        }
+    }
+
+    /**
+     * Starts presentation of tasks in this container.
+     */
+    public void start() {
+        if (mVirtualDisplay != null) {
+            mVirtualDisplay.setDisplayState(true);
+            updateLocationAndTapExcludeRegion();
+        }
+    }
+
+    /**
+     * This should be called whenever the position or size of the surface changes
+     * or if touchable areas above the surface are added or removed.
+     */
+    public void notifyBoundsChanged() {
+        updateLocationAndTapExcludeRegion();
+    }
+
+    /**
+     * Updates position and bounds information needed by WM and IME to manage window
+     * focus and touch events properly.
+     * <p>
+     * This should be called whenever the position or size of the surface changes
+     * or if touchable areas above the surface are added or removed.
+     */
+    private void updateLocationAndTapExcludeRegion() {
+        if (mVirtualDisplay == null || mHost.getWindow() == null) {
+            return;
+        }
+        reportLocation(mHost.getScreenToTaskMatrix(), mHost.getPositionInWindow());
+        applyTapExcludeRegion(mHost.getWindow(), hashCode(), mHost.getTapExcludeRegion());
+    }
+
+    /**
+     * Call to update the position and transform matrix for the embedded surface.
+     * <p>
+     * This should not normally be called directly, but through
+     * {@link #updateLocationAndTapExcludeRegion()}. This method
+     * is provided as an optimization when managing multiple TaskSurfaces within a view.
+     *
+     * @param screenToViewMatrix the matrix/transform from screen space to view space
+     * @param positionInWindow the window-relative position of the surface
+     *
+     * @see InputMethodManager#reportActivityView(int, Matrix)
+     */
+    private void reportLocation(Matrix screenToViewMatrix, Point positionInWindow) {
+        try {
+            final int displayId = getDisplayId();
+            mContext.getSystemService(InputMethodManager.class)
+                    .reportActivityView(displayId, screenToViewMatrix);
+            IWindowSession session = WindowManagerGlobal.getWindowSession();
+            session.updateDisplayContentLocation(mHost.getWindow(), positionInWindow.x,
+                    positionInWindow.y, displayId);
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Call to update the tap exclude region for the window.
+     * <p>
+     * This should not normally be called directly, but through
+     * {@link #updateLocationAndTapExcludeRegion()}. This method
+     * is provided as an optimization when managing multiple TaskSurfaces within a view.
+     *
+     * @see IWindowSession#updateTapExcludeRegion(IWindow, int, Region)
+     */
+    private void applyTapExcludeRegion(IWindow window, int regionId,
+            @Nullable Region tapExcludeRegion) {
+        try {
+            IWindowSession session = WindowManagerGlobal.getWindowSession();
+            session.updateTapExcludeRegion(window, regionId, tapExcludeRegion);
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * @see InputMethodManager#reportActivityView(int, Matrix)
+     */
+    private void clearActivityViewGeometryForIme() {
+        final int displayId = getDisplayId();
+        mContext.getSystemService(InputMethodManager.class).reportActivityView(displayId, null);
+    }
+
+    /**
+     * Removes the tap exclude region set by {@link #updateLocationAndTapExcludeRegion()}.
+     */
+    private void clearTapExcludeRegion() {
+        if (mHost.getWindow() == null) {
+            Log.w(TAG, "clearTapExcludeRegion: not attached to window!");
+            return;
+        }
+        applyTapExcludeRegion(mHost.getWindow(), hashCode(), null);
+    }
+
+    /**
+     * Called to update the dimensions whenever the host size changes.
+     *
+     * @param width the new width of the surface
+     * @param height the new height of the surface
+     */
+    public void resizeTask(int width, int height) {
+        mDisplayDensityDpi = getBaseDisplayDensity();
+        if (mVirtualDisplay != null) {
+            mVirtualDisplay.resize(width, height, mDisplayDensityDpi);
+        }
+    }
+
+    /**
+     * Injects a pair of down/up key events with keycode {@link KeyEvent#KEYCODE_BACK} to the
+     * virtual display.
+     */
+    public void performBackPress() {
+        if (mVirtualDisplay == null) {
+            return;
+        }
+        final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
+        final InputManager im = InputManager.getInstance();
+        im.injectInputEvent(createKeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, displayId),
+                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+        im.injectInputEvent(createKeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK, displayId),
+                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+    }
+
+    private static KeyEvent createKeyEvent(int action, int code, int displayId) {
+        long when = SystemClock.uptimeMillis();
+        final KeyEvent ev = new KeyEvent(when, when, action, code, 0 /* repeat */,
+                0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */,
+                KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
+                InputDevice.SOURCE_KEYBOARD);
+        ev.setDisplayId(displayId);
+        return ev;
+    }
+
+    /**
+     * Releases the resources for this TaskEmbedder. Tasks will no longer be launchable
+     * within this container.
+     *
+     * <p>Note: Calling this method is allowed after {@link Listener#onInitialized()} callback is
+     * triggered and before {@link Listener#onReleased()}.
+     */
+    public void release() {
+        if (mVirtualDisplay == null) {
+            throw new IllegalStateException(
+                    "Trying to release container that is not initialized.");
+        }
+        performRelease();
+    }
+
+    private boolean performRelease() {
+        if (!mOpened) {
+            return false;
+        }
+        mTransaction.reparent(mSurfaceControl, null).apply();
+        mSurfaceControl.release();
+
+        // Clear activity view geometry for IME on this display
+        clearActivityViewGeometryForIme();
+
+        // Clear tap-exclude region (if any) for this window.
+        clearTapExcludeRegion();
+
+        if (mTaskStackListener != null) {
+            try {
+                mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to unregister task stack listener", e);
+            }
+            mTaskStackListener = null;
+        }
+
+        boolean reportReleased = false;
+        if (mVirtualDisplay != null) {
+            mVirtualDisplay.release();
+            mVirtualDisplay = null;
+            reportReleased = true;
+
+        }
+
+        if (mListener != null && reportReleased) {
+            mListener.onReleased();
+        }
+        mOpened = false;
+        mGuard.close();
+        return true;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+                performRelease();
+            }
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /** Get density of the hosting display. */
+    private int getBaseDisplayDensity() {
+        final WindowManager wm = mContext.getSystemService(WindowManager.class);
+        final DisplayMetrics metrics = new DisplayMetrics();
+        wm.getDefaultDisplay().getMetrics(metrics);
+        return metrics.densityDpi;
+    }
+
+    /**
+     * A task change listener that detects background color change of the topmost stack on our
+     * virtual display and updates the background of the surface view. This background will be shown
+     * when surface view is resized, but the app hasn't drawn its content in new size yet.
+     * It also calls StateCallback.onTaskMovedToFront to notify interested parties that the stack
+     * associated with the {@link ActivityView} has had a Task moved to the front. This is useful
+     * when needing to also bring the host Activity to the foreground at the same time.
+     */
+    private class TaskStackListenerImpl extends TaskStackListener {
+
+        @Override
+        public void onTaskDescriptionChanged(ActivityManager.RunningTaskInfo taskInfo)
+                throws RemoteException {
+            if (!isInitialized()
+                    || taskInfo.displayId != getDisplayId()) {
+                return;
+            }
+
+            ActivityManager.StackInfo stackInfo = getTopMostStackInfo();
+            if (stackInfo == null) {
+                return;
+            }
+            // Found the topmost stack on target display. Now check if the topmost task's
+            // description changed.
+            if (taskInfo.taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
+                mHost.onTaskBackgroundColorChanged(TaskEmbedder.this,
+                        taskInfo.taskDescription.getBackgroundColor());
+            }
+        }
+
+        @Override
+        public void onTaskMovedToFront(ActivityManager.RunningTaskInfo taskInfo)
+                throws RemoteException {
+            if (!isInitialized() || mListener == null
+                    || taskInfo.displayId != getDisplayId()) {
+                return;
+            }
+
+            ActivityManager.StackInfo stackInfo = getTopMostStackInfo();
+            // if StackInfo was null or unrelated to the "move to front" then there's no use
+            // notifying the callback
+            if (stackInfo != null
+                    && taskInfo.taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
+                mListener.onTaskMovedToFront(taskInfo.taskId);
+            }
+        }
+
+        @Override
+        public void onTaskCreated(int taskId, ComponentName componentName) throws RemoteException {
+            if (mListener == null || !isInitialized()) {
+                return;
+            }
+
+            ActivityManager.StackInfo stackInfo = getTopMostStackInfo();
+            // if StackInfo was null or unrelated to the task creation then there's no use
+            // notifying the callback
+            if (stackInfo != null
+                    && taskId == stackInfo.taskIds[stackInfo.taskIds.length - 1]) {
+                mListener.onTaskCreated(taskId, componentName);
+            }
+        }
+
+        @Override
+        public void onTaskRemovalStarted(ActivityManager.RunningTaskInfo taskInfo)
+                throws RemoteException {
+            if (mListener == null || !isInitialized()
+                    || taskInfo.displayId != getDisplayId()) {
+                return;
+            }
+            mListener.onTaskRemovalStarted(taskInfo.taskId);
+        }
+
+        private ActivityManager.StackInfo getTopMostStackInfo() throws RemoteException {
+            // Find the topmost task on our virtual display - it will define the background
+            // color of the surface view during resizing.
+            final int displayId = getDisplayId();
+            final List<ActivityManager.StackInfo> stackInfoList =
+                    mActivityTaskManager.getAllStackInfos();
+
+            // Iterate through stacks from top to bottom.
+            final int stackCount = stackInfoList.size();
+            for (int i = 0; i < stackCount; i++) {
+                final ActivityManager.StackInfo stackInfo = stackInfoList.get(i);
+                // Only look for stacks on our virtual display.
+                if (stackInfo.displayId != displayId) {
+                    continue;
+                }
+                // Found the topmost stack on target display.
+                return stackInfo;
+            }
+            return null;
+        }
+    }
+}
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index e7ba85a..566b387 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1189,13 +1189,11 @@
     /**
      * Factory reset bluetooth settings.
      *
-     * <p>Requires the {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}
-     * permission
-     *
      * @return true to indicate that the config file was successfully cleared
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean factoryReset() {
         try {
             mServiceLock.readLock().lock();
@@ -1214,13 +1212,12 @@
     /**
      * Get the UUIDs supported by the local Bluetooth adapter.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
-     *
      * @return the UUIDs supported by the local Bluetooth Adapter.
      * @hide
      */
     @UnsupportedAppUsage
-    public ParcelUuid[] getUuids() {
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    public @NonNull ParcelUuid[] getUuids() {
         if (getState() != STATE_ON) {
             return null;
         }
@@ -1476,7 +1473,6 @@
      * will return false. After turning on Bluetooth,
      * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
      * to get the updated value.
-     * <p>Requires {@link android.Manifest.permission#WRITE_SECURE_SETTINGS}
      * <p>Applications cannot set the scan mode. They should use
      * <code>startActivityForResult(
      * BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE})
@@ -1488,8 +1484,8 @@
      * @return true if the scan mode was set, false otherwise
      * @hide
      */
-    @UnsupportedAppUsage(publicAlternatives = "Use {@link #ACTION_REQUEST_DISCOVERABLE}, which "
-            + "shows UI that confirms the user wants to go into discoverable mode.")
+    @SystemApi
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
     public boolean setScanMode(@ScanMode int mode, int duration) {
         if (getState() != STATE_ON) {
             return false;
@@ -1507,9 +1503,34 @@
         return false;
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
-    public boolean setScanMode(int mode) {
+    /**
+     * Set the Bluetooth scan mode of the local Bluetooth adapter.
+     * <p>The Bluetooth scan mode determines if the local adapter is
+     * connectable and/or discoverable from remote Bluetooth devices.
+     * <p>For privacy reasons, discoverable mode is automatically turned off
+     * after <code>duration</code> seconds. For example, 120 seconds should be
+     * enough for a remote device to initiate and complete its discovery
+     * process.
+     * <p>Valid scan mode values are:
+     * {@link #SCAN_MODE_NONE},
+     * {@link #SCAN_MODE_CONNECTABLE},
+     * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE}.
+     * <p>If Bluetooth state is not {@link #STATE_ON}, this API
+     * will return false. After turning on Bluetooth,
+     * wait for {@link #ACTION_STATE_CHANGED} with {@link #STATE_ON}
+     * to get the updated value.
+     * <p>Applications cannot set the scan mode. They should use
+     * <code>startActivityForResult(
+     * BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE})
+     * </code>instead.
+     *
+     * @param mode valid scan mode
+     * @return true if the scan mode was set, false otherwise
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
+    public boolean setScanMode(@ScanMode int mode) {
         if (getState() != STATE_ON) {
             return false;
         }
@@ -1562,6 +1583,8 @@
      * been called recently.
      * @hide
      */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.BLUETOOTH)
     public long getDiscoveryEndMillis() {
         try {
             mServiceLock.readLock().lock();
@@ -2060,7 +2083,7 @@
      * BluetoothProfile}.
      * @hide
      */
-    public List<Integer> getSupportedProfiles() {
+    public @NonNull List<Integer> getSupportedProfiles() {
         final ArrayList<Integer> supportedProfiles = new ArrayList<Integer>();
 
         try {
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 9cb73f9..28cc1f8 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -21,7 +21,10 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.annotation.TestApi;
 import android.app.Activity;
 import android.app.Application;
 import android.app.PendingIntent;
@@ -29,9 +32,11 @@
 import android.content.Context;
 import android.content.IntentSender;
 import android.content.pm.PackageManager;
+import android.net.MacAddress;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.service.notification.NotificationListenerService;
 import android.util.Log;
 
@@ -252,6 +257,38 @@
         }
     }
 
+    /**
+     * Check if a given package was {@link #associate associated} with a device with given
+     * mac address by given user.
+     *
+     * @param packageName the package to check for
+     * @param macAddress the mac address or BSSID of the device to check for
+     * @param user the user to check for
+     * @return whether a corresponding association record exists
+     *
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES)
+    public boolean isDeviceAssociated(
+            @NonNull String packageName,
+            @NonNull MacAddress macAddress,
+            @NonNull UserHandle user) {
+        if (!checkFeaturePresent()) {
+            return false;
+        }
+        checkNotNull(packageName, "package name cannot be null");
+        checkNotNull(macAddress, "mac address cannot be null");
+        checkNotNull(user, "user cannot be null");
+        try {
+            return mService.isDeviceAssociated(
+                    packageName, macAddress.toString(), user.getIdentifier());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     private boolean checkFeaturePresent() {
         boolean featurePresent = mService != null;
         if (!featurePresent && DEBUG) {
diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl
index 561342e..2e1ff0b 100644
--- a/core/java/android/companion/ICompanionDeviceManager.aidl
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -39,4 +39,6 @@
 
     boolean hasNotificationAccess(in ComponentName component);
     PendingIntent requestNotificationAccess(in ComponentName component);
+
+    boolean isDeviceAssociated(in String packageName, in String macAddress, int userId);
 }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 862ec50..0b0fe79 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4762,6 +4762,13 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve an
+     * {@link android.telephony.ims.ImsManager}.
+     * @hide
+     */
+    public static final String TELEPHONY_IMS_SERVICE = "telephony_ims";
+
+    /**
+     * Use with {@link #getSystemService(String)} to retrieve an
      * {@link android.telephony.ims.RcsMessageManager}.
      * @hide
      */
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 6174018..714e9fb 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -929,6 +929,12 @@
         return mBase.getUserId();
     }
 
+    /** @hide */
+    @Override
+    public UserHandle getUser() {
+        return mBase.getUser();
+    }
+
     @Override
     public Context createConfigurationContext(Configuration overrideConfiguration) {
         return mBase.createConfigurationContext(overrideConfiguration);
diff --git a/core/java/android/content/SyncStats.java b/core/java/android/content/SyncStats.java
index 03b2250e..9596a60 100644
--- a/core/java/android/content/SyncStats.java
+++ b/core/java/android/content/SyncStats.java
@@ -58,7 +58,7 @@
      * attempted to update or delete a version of a resource on the server. This is expected
      * to clear itself automatically once the new state is retrieved from the server,
      * though it may remain until the user intervenes manually, perhaps by clearing the
-     * local storage and starting over frmo scratch. This is considered a hard error.
+     * local storage and starting over from scratch. This is considered a hard error.
      */
     public long numConflictDetectedExceptions;
 
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index 535bf67..64f20b8 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -49,8 +49,8 @@
  * limited to a local network over Multicast DNS. DNS service discovery is described at
  * http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
  *
- * <p> The API is asynchronous and responses to requests from an application are on listener
- * callbacks on a seperate internal thread.
+ * <p> The API is asynchronous, and responses to requests from an application are on listener
+ * callbacks on a separate internal thread.
  *
  * <p> There are three main operations the API supports - registration, discovery and resolution.
  * <pre>
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index d259f38..b37e176 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -38,9 +38,11 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
- * <p>AsyncTask enables proper and easy use of the UI thread. This class allows you
- * to perform background operations and publish results on the UI thread without
- * having to manipulate threads and/or handlers.</p>
+ * <p>AsyncTask was intended to enable proper and easy use of the UI thread. However, the most
+ * common use case was for integrating into UI, and that would cause Context leaks, missed
+ * callbacks, or crashes on configuration changes. It also has inconsistent behavior on different
+ * versions of the platform, swallows exceptions from {@code doInBackground}, and does not provide
+ * much utility over using {@link Executor}s directly.</p>
  *
  * <p>AsyncTask is designed to be a helper class around {@link Thread} and {@link Handler}
  * and does not constitute a generic threading framework. AsyncTasks should ideally be
@@ -188,7 +190,12 @@
  * <p>If you truly want parallel execution, you can invoke
  * {@link #executeOnExecutor(java.util.concurrent.Executor, Object[])} with
  * {@link #THREAD_POOL_EXECUTOR}.</p>
+ *
+ * @deprecated Use the standard <code>java.util.concurrent</code> or
+ *   <a href="https://developer.android.com/topic/libraries/architecture/coroutines">
+ *   Kotlin concurrency utilities</a> instead.
  */
+@Deprecated
 public abstract class AsyncTask<Params, Progress, Result> {
     private static final String LOG_TAG = "AsyncTask";
 
@@ -240,7 +247,13 @@
 
     /**
      * An {@link Executor} that can be used to execute tasks in parallel.
+     *
+     * @deprecated Using a single thread pool for a general purpose results in suboptimal behavior
+     *   for different tasks. Small, CPU-bound tasks benefit from a bounded pool and queueing, and
+     *   long-running blocking tasks, such as network operations, benefit from many threads. Use or
+     *   create an {@link Executor} configured for your use case.
      */
+    @Deprecated
     public static final Executor THREAD_POOL_EXECUTOR;
 
     static {
@@ -254,7 +267,10 @@
     /**
      * An {@link Executor} that executes tasks one at a time in serial
      * order.  This serialization is global to a particular process.
+     *
+     * @deprecated Globally serializing tasks results in excessive queuing for unrelated operations.
      */
+    @Deprecated
     public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
 
     private static final int MESSAGE_POST_RESULT = 0x1;
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 3476b18..b096049 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -2486,6 +2486,8 @@
 
     /**
      * Return the number of users currently created on the device.
+     * <p>This API is not for use by third-party apps. It requires the {@code MANAGE_USERS}
+     * permission.</p>
      */
     public int getUserCount() {
         List<UserInfo> users = getUsers();
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 9e914d4..6a099d57 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -23,7 +23,6 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.graphics.Point;
 import android.os.Build;
 import android.os.RemoteException;
 import android.provider.Settings;
@@ -398,11 +397,7 @@
         mWindowTouchSlop = (int) (sizeAndDensity * WINDOW_TOUCH_SLOP + 0.5f);
 
         // Size of the screen in bytes, in ARGB_8888 format
-        final WindowManager win = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
-        final Display display = win.getDefaultDisplay();
-        final Point size = new Point();
-        display.getRealSize(size);
-        mMaximumDrawingCacheSize = 4 * size.x * size.y;
+        mMaximumDrawingCacheSize = 4 * metrics.heightPixels * metrics.widthPixels;
 
         mOverscrollDistance = (int) (sizeAndDensity * OVERSCROLL_DISTANCE + 0.5f);
         mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f);
@@ -842,6 +837,7 @@
      * The maximum drawing cache size expressed in bytes.
      *
      * @return the maximum size of View's drawing cache expressed in bytes
+     *
      */
     public int getScaledMaximumDrawingCacheSize() {
         return mMaximumDrawingCacheSize;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.aidl b/core/java/android/view/accessibility/AccessibilityNodeInfo.aidl
index 59175ce..dbc9903 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.aidl
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.aidl
@@ -17,3 +17,4 @@
 package android.view.accessibility;
 
 parcelable AccessibilityNodeInfo;
+parcelable AccessibilityNodeInfo.AccessibilityAction;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 06e9d0d..b33fdbb 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -3570,8 +3570,7 @@
                 for (int i = 0; i < actionCount; i++) {
                     AccessibilityAction action = mActions.get(i);
                     if (!isDefaultStandardAction(action)) {
-                        parcel.writeInt(action.getId());
-                        parcel.writeCharSequence(action.getLabel());
+                        action.writeToParcel(parcel, flags);
                     }
                 }
             } else {
@@ -3777,8 +3776,8 @@
             addStandardActions(standardActions);
             final int nonStandardActionCount = parcel.readInt();
             for (int i = 0; i < nonStandardActionCount; i++) {
-                final AccessibilityAction action = new AccessibilityAction(
-                        parcel.readInt(), parcel.readCharSequence());
+                final AccessibilityAction action =
+                        AccessibilityAction.CREATOR.createFromParcel(parcel);
                 addActionUnchecked(action);
             }
         }
@@ -4177,7 +4176,7 @@
      * can discover the set of supported actions.
      * </p>
      */
-    public static final class AccessibilityAction {
+    public static final class AccessibilityAction implements Parcelable {
 
         /** @hide */
         public static final ArraySet<AccessibilityAction> sStandardActions = new ArraySet<>();
@@ -4654,6 +4653,38 @@
         public String toString() {
             return "AccessibilityAction: " + getActionSymbolicName(mActionId) + " - " + mLabel;
         }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        /**
+         * Write data into a parcel.
+         */
+        public void writeToParcel(@NonNull Parcel out, int flags) {
+            out.writeInt(mActionId);
+            out.writeCharSequence(mLabel);
+        }
+
+        public static final @NonNull Parcelable.Creator<AccessibilityAction> CREATOR =
+                new Parcelable.Creator<AccessibilityAction>() {
+                    public AccessibilityAction createFromParcel(Parcel in) {
+                        return new AccessibilityAction(in);
+                    }
+
+                    public AccessibilityAction[] newArray(int size) {
+                        return new AccessibilityAction[size];
+                    }
+                };
+
+        private AccessibilityAction(Parcel in) {
+            mActionId = in.readInt();
+            mLabel = in.readCharSequence();
+        }
     }
 
     /**
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 1cb1148..3a197e2 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -120,10 +120,6 @@
  * <a href="{@docRoot}training/improving-layouts/smooth-scrolling.html">
  * Making ListView Scrolling Smooth</a> for more ways to ensure a smooth user experience.</p>
  *
- * <p>For a more complete example of creating a custom adapter, see the
- * <a href="{@docRoot}samples/CustomChoiceList/index.html">
- *     Custom Choice List</a> sample app.</p>
- *
  * <p>To specify an action when a user clicks or taps on a single list item, see
  * <a href="{@docRoot}guide/topics/ui/declaring-layout.html#HandlingUserSelections">
  *     Handling click events</a>.</p>
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 6b324a5..167010b 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -73,7 +73,7 @@
  *
  * <p>This behavior has been preserved for apps that set <code>android:targetSdkVersion="17"</code>
  * or older in their manifest's <code>uses-sdk</code> tag for compatibility. Apps targeting SDK
- * version 18 or newer will receive the correct behavior</p>
+ * version 18 or newer will receive the correct behavior.</p>
  *
  * <p>See the <a href="{@docRoot}guide/topics/ui/layout/relative.html">Relative
  * Layout</a> guide.</p>
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 3ab0b0d2..99bf93e 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -31,19 +31,19 @@
     // be kept in sync with frameworks/native/libs/binder/include/binder/IAppOpsService.h
     // and not be reordered
     int checkOperation(int code, int uid, String packageName);
-    int noteOperation(int code, int uid, String packageName, String featureId);
-    int startOperation(IBinder token, int code, int uid, String packageName, String featureId,
-            boolean startIfModeDefault);
+    int noteOperation(int code, int uid, String packageName, @nullable String featureId);
+    int startOperation(IBinder token, int code, int uid, String packageName,
+            @nullable String featureId, boolean startIfModeDefault);
     @UnsupportedAppUsage
     void finishOperation(IBinder token, int code, int uid, String packageName,
-            String featureId);
+            @nullable String featureId);
     void startWatchingMode(int op, String packageName, IAppOpsCallback callback);
     void stopWatchingMode(IAppOpsCallback callback);
     IBinder getToken(IBinder clientToken);
     int permissionToOpCode(String permission);
     int checkAudioOperation(int code, int usage, int uid, String packageName);
-    void noteAsyncOp(String callingPackageName, int uid, String packageName, int opCode,
-            String featureId, String message);
+    void noteAsyncOp(@nullable String callingPackageName, int uid, @nullable String packageName,
+            int opCode, @nullable String featureId, String message);
     boolean shouldCollectNotes(int opCode);
     void setCameraAudioRestriction(int mode);
     // End of methods also called by native code.
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index a587936..0286aa6 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -634,8 +634,7 @@
                 subLabel = null;
             }
 
-            if (!TextUtils.equals(text2.getText(), subLabel)
-                    && !TextUtils.isEmpty(subLabel)) {
+            if (!TextUtils.equals(text2.getText(), subLabel)) {
                 text2.setVisibility(View.VISIBLE);
                 text2.setText(subLabel);
             }
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 36a7a9c..58e80c7 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -47,6 +47,20 @@
      */
     public static final String NAS_MAX_SUGGESTIONS = "nas_max_suggestions";
 
+    // Flags related to screenshot intelligence
+
+    /**
+     * (bool) Whether to enable smart actions in screenshot notifications.
+     */
+    public static final String ENABLE_SCREENSHOT_NOTIFICATION_SMART_ACTIONS =
+            "enable_screenshot_notification_smart_actions";
+
+    /**
+     * (int) Timeout value in ms to get smart actions for screenshot notification.
+     */
+    public static final String SCREENSHOT_NOTIFICATION_SMART_ACTIONS_TIMEOUT_MS =
+            "screenshot_notification_smart_actions_timeout_ms";
+
     // Flags related to controls
 
     /**
diff --git a/core/java/com/android/internal/util/CollectionUtils.java b/core/java/com/android/internal/util/CollectionUtils.java
index f9cf23b..4165f20 100644
--- a/core/java/com/android/internal/util/CollectionUtils.java
+++ b/core/java/com/android/internal/util/CollectionUtils.java
@@ -231,6 +231,15 @@
     }
 
     /**
+     * Returns whether there exists at least one element in the set for which
+     * condition {@code predicate} is true
+     */
+    public static <T> boolean any(@Nullable Set<T> items,
+            java.util.function.Predicate<T> predicate) {
+        return find(items, predicate) != null;
+    }
+
+    /**
      * Returns the first element from the list for which
      * condition {@code predicate} is true, or null if there is no such element
      */
@@ -245,6 +254,37 @@
     }
 
     /**
+     * Returns the first element from the set for which
+     * condition {@code predicate} is true, or null if there is no such element
+     */
+    public static @Nullable <T> T find(@Nullable Set<T> cur,
+            java.util.function.Predicate<T> predicate) {
+        if (cur == null || predicate == null) return null;
+        int size = cur.size();
+        if (size == 0) return null;
+        try {
+            if (cur instanceof ArraySet) {
+                ArraySet<T> arraySet = (ArraySet<T>) cur;
+                for (int i = 0; i < size; i++) {
+                    T item = arraySet.valueAt(i);
+                    if (predicate.test(item)) {
+                        return item;
+                    }
+                }
+            } else {
+                for (T t : cur) {
+                    if (predicate.test(t)) {
+                        return t;
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw ExceptionUtils.propagate(e);
+        }
+        return null;
+    }
+
+    /**
      * Similar to {@link List#add}, but with support for list values of {@code null} and
      * {@link Collections#emptyList}
      */
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index d9428c5..30edc37 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -246,6 +246,7 @@
                 "libmediametrics",
                 "libmeminfo",
                 "libaudioclient",
+                "libaudiofoundation",
                 "libaudiopolicy",
                 "libusbhost",
                 "libpdfium",
@@ -258,6 +259,7 @@
                 "libmemunreachable",
                 "libhidlbase",
                 "libvintf",
+                "libnativedisplay",
                 "libnativewindow",
                 "libdl",
                 "libdl_android",
@@ -437,6 +439,7 @@
             ],
             shared_libs: [
                 "libandroidfw",
+                "libnativedisplay",
                 "libnativewindow",
                 "libgui",
                 "libpdfium",
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 686a919..6417b28 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -27,6 +27,7 @@
 #include "core_jni_helpers.h"
 
 #include <audiomanager/AudioManager.h>
+#include <media/AudioDeviceTypeAddr.h>
 #include <media/AudioSystem.h>
 #include <media/AudioPolicy.h>
 #include <media/MicrophoneInfo.h>
@@ -2015,9 +2016,10 @@
         if (!env->IsInstanceOf(addrJobj, stringClass)) {
             return (jint) AUDIO_JAVA_BAD_VALUE;
         }
-        String8 address = String8(env->GetStringUTFChars((jstring) addrJobj, NULL));
+        const char* address = env->GetStringUTFChars((jstring) addrJobj, NULL);
         AudioDeviceTypeAddr dev = AudioDeviceTypeAddr(typesPtr[i], address);
         deviceVector.add(dev);
+        env->ReleaseStringUTFChars((jstring) addrJobj, address);
     }
     env->ReleaseIntArrayElements(deviceTypes, typesPtr, 0);
 
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 49c5cad..ee6e8c4 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -207,7 +207,7 @@
         return;
     }
 
-    int res = SetTaskProfiles(tid, {get_sched_policy_name((SchedPolicy)grp)}, true) ? 0 : -1;
+    int res = SetTaskProfiles(tid, {get_sched_policy_profile_name((SchedPolicy)grp)}, true) ? 0 : -1;
 
     if (res != NO_ERROR) {
         signalExceptionForGroupError(env, -res, tid);
diff --git a/core/proto/android/server/appwindowthumbnail.proto b/core/proto/android/server/windowcontainerthumbnail.proto
similarity index 89%
rename from core/proto/android/server/appwindowthumbnail.proto
rename to core/proto/android/server/windowcontainerthumbnail.proto
index f22cdc5..9f8ea60 100644
--- a/core/proto/android/server/appwindowthumbnail.proto
+++ b/core/proto/android/server/windowcontainerthumbnail.proto
@@ -23,9 +23,9 @@
 option java_multiple_files = true;
 
 /**
- * Represents a {@link com.android.server.wm.AppWindowThumbnail} object.
+ * Represents a {@link com.android.server.wm.WindowContainerThumbnailProto} object.
  */
-message AppWindowThumbnailProto {
+message WindowContainerThumbnailProto {
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
     optional int32 width = 1;
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 69e67d1..c9a1829 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -20,7 +20,7 @@
 import "frameworks/base/core/proto/android/content/activityinfo.proto";
 import "frameworks/base/core/proto/android/content/configuration.proto";
 import "frameworks/base/core/proto/android/graphics/rect.proto";
-import "frameworks/base/core/proto/android/server/appwindowthumbnail.proto";
+import "frameworks/base/core/proto/android/server/windowcontainerthumbnail.proto";
 import "frameworks/base/core/proto/android/server/surfaceanimator.proto";
 import "frameworks/base/core/proto/android/view/displaycutout.proto";
 import "frameworks/base/core/proto/android/view/displayinfo.proto";
@@ -232,7 +232,7 @@
     optional bool last_surface_showing = 3;
     optional bool is_waiting_for_transition_start = 4;
     optional bool is_animating = 5;
-    optional AppWindowThumbnailProto thumbnail = 6;
+    optional WindowContainerThumbnailProto thumbnail = 6;
     optional bool fills_parent = 7;
     optional bool app_stopped = 8;
     optional bool hidden_requested = 9;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8a735c7..b357b3e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3553,7 +3553,7 @@
     <!-- Allows an application to manage the companion devices.
          @hide -->
     <permission android:name="android.permission.MANAGE_COMPANION_DEVICES"
-                android:protectionLevel="signature" />
+                android:protectionLevel="signature|wifi" />
 
     <!-- @SystemApi Allows an application to use SurfaceFlinger's low level features.
          <p>Not for use by third-party applications.
diff --git a/core/res/res/drawable/ic_wifi_settings.xml b/core/res/res/drawable/ic_wifi_settings.xml
deleted file mode 100644
index c678ad4..0000000
--- a/core/res/res/drawable/ic_wifi_settings.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2017 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24"
-    android:viewportHeight="24">
-
-    <path
-        android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M12.584,15.93c0.026-0.194,0.044-0.397,0.044-0.608c0-0.211-0.018-0.405-0.044-0.608l1.304-1.022
-c0.115-0.088,0.15-0.256,0.071-0.397l-1.234-2.133c-0.071-0.132-0.238-0.185-0.379-0.132l-1.533,0.617
-c-0.317-0.247-0.67-0.449-1.04-0.608L9.535,9.4c-0.018-0.132-0.141-0.247-0.3-0.247H6.768c-0.15,0-0.282,0.115-0.3,0.256
-L6.23,11.048c-0.379,0.159-0.723,0.361-1.04,0.608l-1.533-0.617c-0.141-0.053-0.3,0-0.379,0.132l-1.234,2.133
-c-0.079,0.132-0.044,0.3,0.07,0.397l1.304,1.022c-0.026,0.194-0.044,0.405-0.044,0.608s0.018,0.405,0.044,0.608l-1.304,1.022
-c-0.115,0.088-0.15,0.256-0.07,0.397l1.234,2.133c0.07,0.132,0.238,0.185,0.379,0.132l1.533-0.617
-c0.317,0.247,0.67,0.449,1.04,0.608l0.238,1.639c0.018,0.15,0.15,0.256,0.3,0.256h2.467c0.159,0,0.282-0.115,0.3-0.256
-l0.238-1.639c0.379-0.15,0.723-0.361,1.04-0.608l1.533,0.617c0.141,0.053,0.3,0,0.379-0.132l1.234-2.133
-c0.071-0.132,0.044-0.3-0.07-0.397L12.584,15.93z
-M8.002,17.481c-1.19,0-2.159-0.969-2.159-2.159s0.969-2.159,2.159-2.159
-s2.159,0.969,2.159,2.159C10.161,16.512,9.191,17.481,8.002,17.481z" />
-    <path
-        android:fillColor="#000000"
-        android:pathData="M16.003,12.026l5.995-7.474c-0.229-0.172-2.537-2.06-6-2.06s-5.771,1.889-6,2.06l5.995,7.469l0.005,0.01L16.003,12.026z" />
-</vector>
\ No newline at end of file
diff --git a/core/res/res/layout/wifi_p2p_dialog.xml b/core/res/res/layout/wifi_p2p_dialog.xml
deleted file mode 100644
index 86dcbfa..0000000
--- a/core/res/res/layout/wifi_p2p_dialog.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content">
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical">
-
-        <LinearLayout android:id="@+id/info"
-            style="@style/wifi_section" />
-
-        <LinearLayout android:id="@+id/enter_pin_section"
-            style="@style/wifi_section"
-            android:visibility="gone">
-
-            <LinearLayout
-                style="@style/wifi_item">
-                <TextView
-                    android:text="@string/wifi_p2p_enter_pin_message"
-                    style="@style/wifi_item_label" />
-
-                <EditText android:id="@+id/wifi_p2p_wps_pin"
-                        android:singleLine="true"
-                        android:maxLines="8"
-                        android:inputType="number"
-                        style="@style/wifi_item_content" />
-            </LinearLayout>
-        </LinearLayout>
-    </LinearLayout>
-
-</ScrollView>
diff --git a/core/res/res/layout/wifi_p2p_dialog_row.xml b/core/res/res/layout/wifi_p2p_dialog_row.xml
deleted file mode 100644
index 2c88b10..0000000
--- a/core/res/res/layout/wifi_p2p_dialog_row.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/wifi_item">
-    <TextView
-            style="@style/wifi_item_label"
-            android:id="@+id/name" />
-
-    <TextView
-            android:id="@+id/value"
-            style="@style/wifi_item_content"
-            android:textStyle="bold"
-            android:textAlignment="viewStart" />
-</LinearLayout>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9ca98c5..b5e14d6 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -570,209 +570,6 @@
     <string-array translatable="false" name="config_cdma_dun_supported_types">
     </string-array>
 
-    <!-- Boolean indicating whether the wifi chipset has dual frequency band support -->
-    <bool translatable="false" name="config_wifi_dual_band_support">false</bool>
-
-    <!-- Maximum number of concurrent WiFi interfaces in AP mode -->
-    <integer translatable="false" name="config_wifi_max_ap_interfaces">1</integer>
-
-    <!-- Boolean indicating whether the wifi chipset requires the softap band be -->
-    <!-- converted from 5GHz to ANY due to hardware restrictions -->
-    <bool translatable="false" name="config_wifi_convert_apband_5ghz_to_any">false</bool>
-
-    <!-- Boolean indicating whether 802.11r Fast BSS Transition is enabled on this platform -->
-    <bool translatable="false" name="config_wifi_fast_bss_transition_enabled">false</bool>
-
-    <!-- Device type information conforming to Annex B format in WiFi Direct specification.
-         The default represents a dual-mode smartphone -->
-    <string translatable="false" name="config_wifi_p2p_device_type">10-0050F204-5</string>
-
-    <!-- Boolean indicating whether the wifi chipset supports background scanning mechanism.
-         This mechanism allows the host to remain in suspend state and the dongle to actively
-         scan and wake the host when a configured SSID is detected by the dongle. This chipset
-         capability can provide power savings when wifi needs to be always kept on. -->
-    <bool translatable="false" name="config_wifi_background_scan_support">false</bool>
-
-    <!-- Boolean indicating we re-try re-associating once upon disconnection and RSSI is high failure  -->
-    <bool translatable="true" name="config_wifi_enable_disconnection_debounce">true</bool>
-
-    <!-- Boolean indicating whether or not to revert to default country code when cellular
-         radio is unable to find any MCC information to infer wifi country code from -->
-    <bool translatable="false" name="config_wifi_revert_country_code_on_cellular_loss">false</bool>
-
-    <!-- Integer size limit, in KB, for a single WifiLogger ringbuffer, in default logging mode -->
-    <integer translatable="false" name="config_wifi_logger_ring_buffer_default_size_limit_kb">32</integer>
-
-    <!-- Integer size limit, in KB, for a single WifiLogger ringbuffer, in verbose logging mode -->
-    <integer translatable="false" name="config_wifi_logger_ring_buffer_verbose_size_limit_kb">1024</integer>
-
-    <!-- Array indicating wifi fatal firmware alert error code list from driver -->
-    <integer-array translatable="false" name="config_wifi_fatal_firmware_alert_error_code_list">
-        <!-- Example:
-        <item>0</item>
-        <item>1</item>
-        <item>2</item>
-        -->
-    </integer-array>
-
-    <!-- Boolean indicating whether or not wifi should turn off when emergency call is made -->
-    <bool translatable="false" name="config_wifi_turn_off_during_emergency_call">false</bool>
-
-    <!-- Integer specifying the basic autojoin parameters -->
-    <integer translatable="false" name="config_wifi_framework_5GHz_preference_boost_threshold">-65</integer>
-    <integer translatable="false" name="config_wifi_framework_5GHz_preference_boost_factor">40</integer>
-    <integer translatable="false" name="config_wifi_framework_5GHz_preference_penalty_threshold">-75</integer>
-    <integer translatable="false" name="config_wifi_framework_RSSI_SCORE_OFFSET">85</integer>
-    <integer translatable="false" name="config_wifi_framework_RSSI_SCORE_SLOPE">4</integer>
-    <integer translatable="false" name="config_wifi_framework_SAME_BSSID_AWARD">24</integer>
-    <integer translatable="false" name="config_wifi_framework_LAST_SELECTION_AWARD">480</integer>
-    <integer translatable="false" name="config_wifi_framework_PASSPOINT_SECURITY_AWARD">40</integer>
-    <integer translatable="false" name="config_wifi_framework_SECURITY_AWARD">80</integer>
-    <!-- Integer specifying the base interval in seconds for the exponential backoff scan for autojoin -->
-    <integer translatable="false" name="config_wifi_framework_exponential_backoff_scan_base_interval">20</integer>
-    <!-- Integers specifying the max packet Tx/Rx rates for full scan -->
-    <integer translatable="false" name="config_wifi_framework_max_tx_rate_for_full_scan">8</integer>
-    <integer translatable="false" name="config_wifi_framework_max_rx_rate_for_full_scan">16</integer>
-    <!-- Integers specifying the min packet Tx/Rx rates in packets per second for staying on the same network -->
-    <integer translatable="false" name="config_wifi_framework_min_tx_rate_for_staying_on_network">16</integer>
-    <integer translatable="false" name="config_wifi_framework_min_rx_rate_for_staying_on_network">16</integer>
-    <!-- Integer parameters of the wifi to cellular handover feature
-         wifi should not stick to bad networks -->
-    <!-- Integer threshold for low network score, should be somewhat less than the entry threshhold -->
-    <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz">-80</integer>
-    <!-- Integer threshold, do not connect to APs with RSSI lower than the entry threshold -->
-    <integer translatable="false" name="config_wifi_framework_wifi_score_entry_rssi_threshold_5GHz">-77</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_low_rssi_threshold_5GHz">-70</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_good_rssi_threshold_5GHz">-57</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz">-83</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_entry_rssi_threshold_24GHz">-80</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_low_rssi_threshold_24GHz">-73</integer>
-    <integer translatable="false" name="config_wifi_framework_wifi_score_good_rssi_threshold_24GHz">-60</integer>
-
-    <!-- Integer delay in milliseconds before shutting down soft AP when there
-         are no connected devices. Framework will enforce a minimum limit on
-         this value and this setting will be overridden if the provided value is
-         smaller than the limit. -->
-    <integer translatable="false" name="config_wifi_framework_soft_ap_timeout_delay">600000</integer>
-
-    <string  translatable="false" name="config_wifi_random_mac_oui">DA-A1-19</string>
-    <string  translatable="false" name="config_wifi_framework_sap_2G_channel_list">1,6,11</string>
-
-    <bool translatable="false" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment">true</bool>
-
-    <!-- Integer packet threshold used to allow scan while associated -->
-    <integer translatable="false" name="config_wifi_framework_associated_full_scan_tx_packet_threshold">5</integer>
-    <integer translatable="false" name="config_wifi_framework_associated_full_scan_rx_packet_threshold">10</integer>
-    <integer translatable="false" name="config_wifi_framework_associated_partial_scan_tx_packet_threshold">40</integer>
-    <integer translatable="false" name="config_wifi_framework_associated_partial_scan_rx_packet_threshold">80</integer>
-    <integer translatable="false" name="config_wifi_framework_network_switch_tx_packet_threshold">2</integer>
-    <integer translatable="false" name="config_wifi_framework_network_switch_rx_packet_threshold">20</integer>
-
-    <!-- Integer indicating wpa_supplicant scan interval in milliseconds -->
-    <integer translatable="false" name="config_wifi_supplicant_scan_interval">15000</integer>
-
-    <!-- Integer indicating amount of time failed networks areblacklisted for the purpose
-         of network switching in milliseconds -->
-    <integer translatable="false" name="config_wifi_network_switching_blacklist_time">172800000</integer>
-
-    <!-- Integer indicating wpa_supplicant scan interval when p2p is connected in milliseconds -->
-    <integer translatable="false" name="config_wifi_scan_interval_p2p_connected">60000</integer>
-
-    <!-- Integer indicating disconnect mode short scan interval in milliseconds -->
-    <integer translatable="false" name="config_wifi_disconnected_short_scan_interval">15000</integer>
-
-    <!-- Integer indicating associated partial scan short interval in milliseconds -->
-    <integer translatable="false" name="config_wifi_associated_short_scan_interval">20000</integer>
-
-    <!-- Integer indicating associated full scan backoff, representing a fraction: xx/8 -->
-    <integer translatable="false" name="config_wifi_framework_associated_full_scan_backoff">12</integer>
-
-    <!-- Integer indicating associated full scan max interval in milliseconds -->
-    <integer translatable="false" name="config_wifi_framework_associated_full_scan_max_interval">300000</integer>
-
-    <!-- Integer indicating associated full scan max total dwell time in milliseconds -->
-    <integer translatable="false" name="config_wifi_framework_associated_full_scan_max_total_dwell_time">500</integer>
-
-    <!-- Integer indicating associated full scan max num active channels -->
-    <integer translatable="false" name="config_wifi_framework_associated_partial_scan_max_num_active_channels">6</integer>
-
-    <!-- Integer indicating RSSI boost given to current network -->
-    <integer translatable="false" name="config_wifi_framework_current_network_boost">16</integer>
-
-    <!-- Integer delay in milliseconds before set wlan interface up during watchdog recovery -->
-    <integer translatable="false" name="config_wifi_framework_recovery_timeout_delay">2000</integer>
-
-    <!-- Integer indicating how to handle beacons with uninitialized RSSI value of 0 -->
-    <integer translatable="false" name="config_wifi_framework_scan_result_rssi_level_patchup_value">-85</integer>
-
-    <!-- Boolean indicating associated network selection is allowed -->
-    <bool translatable="false" name="config_wifi_framework_enable_associated_network_selection">true</bool>
-
-    <!-- Boolean indicating whether single radio chain scan results are to be used for network selection -->
-    <bool translatable="false" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection">true</bool>
-
-    <!-- Boolean indicating that wifi only link configuratios that have exact same credentials (i.e PSK) -->
-    <bool translatable="false" name="config_wifi_only_link_same_credential_configurations">true</bool>
-
-    <!-- Boolean indicating whether framework needs to set the tx power limit for meeting SAR requirements -->
-    <bool translatable="false" name="config_wifi_framework_enable_sar_tx_power_limit">false</bool>
-
-    <!-- Boolean indicating whether framework should use detection of softAP mode to set the tx
-         power limit for meeting SAR requirements -->
-    <bool translatable="false" name="config_wifi_framework_enable_soft_ap_sar_tx_power_limit">false</bool>
-
-    <!-- Boolean indicating whether framework needs to use body proximity to set the tx power limit
-         for meeting SAR requirements -->
-    <bool translatable="false" name="config_wifi_framework_enable_body_proximity_sar_tx_power_limit">false</bool>
-
-    <!-- String for the sensor type for body/head proximity for SAR -->
-    <string translatable="false" name="config_wifi_sar_sensor_type"></string>
-
-    <!-- Integer indicating event id by sar sensor for free space -->
-    <integer translatable="false" name="config_wifi_framework_sar_free_space_event_id">1</integer>
-
-    <!-- Integer indicating event id by sar sensor for near hand -->
-    <integer translatable="false" name="config_wifi_framework_sar_near_hand_event_id">2</integer>
-
-    <!-- Integer indicating event id by sar sensor for near head -->
-    <integer translatable="false" name="config_wifi_framework_sar_near_head_event_id">3</integer>
-
-    <!-- Integer indicating event id by sar sensor for near body -->
-    <integer translatable="false" name="config_wifi_framework_sar_near_body_event_id">4</integer>
-
-    <!-- Wifi driver supports batched scan -->
-    <bool translatable="false" name="config_wifi_batched_scan_supported">false</bool>
-
-    <!-- Wifi driver supports Automatic channel selection (ACS) for softap -->
-    <bool translatable="false" name="config_wifi_softap_acs_supported">false</bool>
-
-    <!-- Channel list restriction to Automatic channel selection (ACS) for softap. If the device
-         doesn't want to restrict channels this should be empty. Value is a comma separated channel
-         string and/or channel range string like '1-6,11' -->
-    <string translatable="false" name="config_wifi_softap_acs_supported_channel_list"></string>
-
-    <!-- Wifi driver supports IEEE80211AC for softap -->
-    <bool translatable="false" name="config_wifi_softap_ieee80211ac_supported">false</bool>
-
-    <!-- Indicates that local-only hotspot should be brought up at 5GHz.  This option is
-         for automotive builds only (the one that have PackageManager#FEATURE_AUTOMOTIVE) -->
-    <bool translatable="false" name="config_wifi_local_only_hotspot_5ghz">false</bool>
-
-    <!-- Indicates that connected MAC randomization is supported on this device -->
-    <bool translatable="false" name="config_wifi_connected_mac_randomization_supported">false</bool>
-
-    <!-- Indicates that p2p MAC randomization is supported on this device -->
-    <bool translatable="false" name="config_wifi_p2p_mac_randomization_supported">false</bool>
-
-    <!-- Indicates that AP mode MAC randomization is supported on this device -->
-    <bool translatable="false" name="config_wifi_ap_mac_randomization_supported">true</bool>
-
-    <!-- flag for activating paranoid MAC randomization on a limited set of SSIDs -->
-    <bool translatable="false" name="config_wifi_aggressive_randomization_ssid_whitelist_enabled">false</bool>
-
-    <!-- Indicates that wifi link probing is supported on this device -->
-    <bool translatable="false" name="config_wifi_link_probing_supported">false</bool>
-
     <!-- Flag indicating whether we should enable the automatic brightness.
          Software implementation will be used if config_hardware_auto_brightness_available is not set -->
     <bool name="config_automatic_brightness_available">false</bool>
@@ -2613,10 +2410,6 @@
          rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max -->
     <string name="config_ethernet_tcp_buffers" translatable="false">524288,1048576,3145728,524288,1048576,2097152</string>
 
-    <!-- Configure wifi tcp buffersizes in the form:
-         rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max -->
-    <string name="config_wifi_tcp_buffers" translatable="false">524288,1048576,2097152,262144,524288,1048576</string>
-
     <!-- Whether WiFi display is supported by this device.
          There are many prerequisites for this feature to work correctly.
          Here are a few of them:
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 9724c41..9b89eab 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3005,6 +3005,8 @@
     </public-group>
 
     <public-group type="drawable" first-id="0x010800b5">
+      <!-- @hide @SystemApi -->
+      <public name="stat_notify_wifi_in_range" />
     </public-group>
 
     <public-group type="style" first-id="0x010302e5">
@@ -3014,6 +3016,12 @@
     </public-group>
 
     <public-group type="string" first-id="0x01040025">
+      <!-- @hide @SystemApi -->
+      <public name="notification_channel_network_status" />
+      <!-- @hide @SystemApi -->
+      <public name="notification_channel_network_alerts" />
+      <!-- @hide @SystemApi -->
+      <public name="notification_channel_network_available" />
     </public-group>
 
     <public-group type="bool" first-id="0x01110005">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 585c4bb..5f2bbac 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3379,52 +3379,6 @@
     <!-- If there is ever a ringtone set for some setting, but that ringtone can no longer be resolved, t his is shown instead.  For example, if the ringtone was on a SD card and it had been removed, this woudl be shown for ringtones on that SD card. -->
     <string name="ringtone_unknown">Unknown</string>
 
-    <!-- A notification is shown when there are open wireless networks nearby.  This is the notification's title. -->
-    <plurals name="wifi_available">
-        <item quantity="one">Wi-Fi network available</item>
-        <item quantity="other">Wi-Fi networks available</item>
-    </plurals>
-    <!-- A notification is shown when there are open wireless networks nearby.  This is the notification's message. -->
-    <plurals name="wifi_available_detailed">
-        <item quantity="one">Open Wi-Fi network available</item>
-        <item quantity="other">Open Wi-Fi networks available</item>
-    </plurals>
-
-    <!-- Notification title for a nearby open wireless network.-->
-    <string name="wifi_available_title">Connect to open Wi\u2011Fi network</string>
-    <!-- Notification title when the system is connecting to the specified network. The network name is specified in the notification content. -->
-    <string name="wifi_available_title_connecting">Connecting to Wi\u2011Fi network</string>
-    <!-- Notification title when the system has connected to the network. The network name is specified in the notification content. -->
-    <string name="wifi_available_title_connected">Connected to Wi\u2011Fi network</string>
-    <!-- Notification title when the system failed to connect to the specified network. -->
-    <string name="wifi_available_title_failed_to_connect">Could not connect to Wi\u2011Fi network</string>
-    <!-- Notification content when the system failed to connect to the specified network. This informs the user that tapping on this notification will open the wifi picker. -->
-    <string name="wifi_available_content_failed_to_connect">Tap to see all networks</string>
-    <!-- Notification action name for connecting to the network specified in the notification body. -->
-    <string name="wifi_available_action_connect">Connect</string>
-    <!-- Notification action name for opening the wifi picker, showing the user all the nearby networks. -->
-    <string name="wifi_available_action_all_networks">All networks</string>
-
-    <!-- Notification title for a connection to a app suggested wireless network.-->
-    <string name="wifi_suggestion_title">Allow suggested Wi\u2011Fi networks?</string>
-    <!-- Notification content for a connection to a app suggested wireless network.-->
-    <string name="wifi_suggestion_content"><xliff:g id="name" example="App123">%s</xliff:g> suggested networks. Device may connect automatically. </string>
-    <!-- Notification action for allowing app specified in the notification body.-->
-    <string name="wifi_suggestion_action_allow_app">Allow</string>
-    <!-- Notification action for disallowing app specified in the notification body.-->
-    <string name="wifi_suggestion_action_disallow_app">No thanks</string>
-
-    <!--Notification title for Wi-Fi Wake onboarding. This is displayed the first time a user disables Wi-Fi with the feature enabled. -->
-    <string name="wifi_wakeup_onboarding_title">Wi\u2011Fi will turn on automatically</string>
-    <!--Notification subtext for Wi-Fi Wake onboarding.-->
-    <string name="wifi_wakeup_onboarding_subtext">When you\'re near a high quality saved network</string>
-    <!--Notification action to disable Wi-Fi Wake during onboarding.-->
-    <string name="wifi_wakeup_onboarding_action_disable">Don\'t turn back on</string>
-    <!--Notification title for when Wi-Fi Wake enables Wi-Fi.-->
-    <string name="wifi_wakeup_enabled_title">Wi\u2011Fi turned on automatically</string>
-    <!--Notification content for when Wi-Fi Wake enables Wi-Fi. %1$s is the SSID of the nearby saved network that triggered the wakeup. -->
-    <string name="wifi_wakeup_enabled_content">You\u0027re near a saved network: <xliff:g id="network_ssid">%1$s</xliff:g></string>
-
     <!-- A notification is shown when a wifi captive portal network is detected.  This is the notification's title. -->
     <string name="wifi_available_sign_in">Sign in to Wi-Fi network</string>
 
@@ -3457,21 +3411,6 @@
     <!-- A notification is shown when the user connects to a network that doesn't have access to some services (e.g. Push notifications may not work). This is the notification's message. [CHAR LIMIT=50] -->
     <string name="network_partial_connectivity_detailed">Tap to connect anyway</string>
 
-    <!-- A notification is shown when the user's softap config has been changed due to underlying
-         hardware restrictions. This is the notifications's title.
-         [CHAR_LIMIT=NONE] -->
-    <string name="wifi_softap_config_change">Changes to your hotspot settings</string>
-
-    <!-- A notification is shown when the user's softap config has been changed due to underlying
-         hardware restrictions. This is the notification's summary message.
-         [CHAR_LIMIT=NONE] -->
-    <string name="wifi_softap_config_change_summary">Your hotspot band has changed.</string>
-
-    <!-- A notification is shown when the user's softap config has been changed due to underlying
-         hardware restrictions. This is the notification's full message.
-         [CHAR_LIMIT=NONE] -->
-    <string name="wifi_softap_config_change_detailed">This device doesn\u2019t support your preference for 5GHz only. Instead, this device will use the 5GHz band when available.</string>
-
     <!-- A notification might be shown if the device switches to another network type (e.g., mobile data) because it detects that the network it was using (e.g., Wi-Fi) has lost Internet connectivity. This is the notification's title. %1$s is the network type that the device switched to, e.g., cellular data. It is one of the strings in the network_switch_type_name array. -->
     <string name="network_switch_metered">Switched to <xliff:g id="network_type">%1$s</xliff:g></string>
 
@@ -3493,43 +3432,8 @@
     <!-- Network type name displayed if one of the types is not found in network_switch_type_name. -->
     <string name="network_switch_type_name_unknown">an unknown network type</string>
 
-     <!-- A notification is shown when a user's selected SSID is later disabled due to connectivity problems.  This is the notification's title / ticker. -->
-     <string name="wifi_watchdog_network_disabled">Couldn\'t connect to Wi-Fi</string>
-     <!-- A notification is shown when a user's selected SSID is later disabled due to connectivity problems.  The complete alert msg is: <hotspot name> + this string, i.e. "Linksys has a poor internet connection" -->
-    <string name="wifi_watchdog_network_disabled_detailed">\u0020has a poor internet connection.</string>
-
-    <!-- Do not translate. Default access point SSID used for tethering -->
-    <string name="wifi_tether_configure_ssid_default" translatable="false">AndroidAP</string>
-    <!-- Do not translate. Default access point SSID used for local only hotspot -->
-    <string name="wifi_localhotspot_configure_ssid_default" translatable="false">AndroidShare</string>
-
-    <!-- A notification is shown the first time a connection is attempted on an app owned AP -->
-    <!-- title for this message -->
-    <string name="wifi_connect_alert_title">Allow connection?</string>
-    <!-- message explaining who is connecting to what -->
-    <string name="wifi_connect_alert_message">Application %1$s would like to connect to Wifi Network %2$s</string>
-    <!-- default application in case name can not be found -->
-    <string name="wifi_connect_default_application">An application</string>
-
-    <string name="wifi_p2p_dialog_title">Wi-Fi Direct</string>
-    <string name="wifi_p2p_turnon_message">Start Wi-Fi Direct. This will turn off Wi-Fi client/hotspot.</string>
-    <string name="wifi_p2p_failed_message">Couldn\'t start Wi-Fi Direct.</string>
-    <string name="wifi_p2p_enabled_notification_title">Wi-Fi Direct is on</string>
-    <string name="wifi_p2p_enabled_notification_message">Tap for settings</string>
-
     <string name="accept">Accept</string>
     <string name="decline">Decline</string>
-    <string name="wifi_p2p_invitation_sent_title">Invitation sent</string>
-    <string name="wifi_p2p_invitation_to_connect_title">Invitation to connect</string>
-
-    <string name="wifi_p2p_from_message">From: </string>
-    <string name="wifi_p2p_to_message">To: </string>
-    <string name="wifi_p2p_enter_pin_message">Type the required PIN: </string>
-    <string name="wifi_p2p_show_pin_message">PIN: </string>
-
-    <string name="wifi_p2p_frequency_conflict_message" product="tablet">The tablet will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
-    <string name="wifi_p2p_frequency_conflict_message" product="tv">Your Android TV device will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
-    <string name="wifi_p2p_frequency_conflict_message" product="default">The phone will temporarily disconnect from Wi-Fi while it\'s connected to <xliff:g id="device_name">%1$s</xliff:g></string>
 
     <!-- Name of the dialog that lets the user choose an accented character to insert -->
     <string name="select_character">Insert character</string>
@@ -4869,10 +4773,10 @@
     <string name="confirm_battery_saver">OK</string>
 
     <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, with a "learn more" link. -->
-    <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>
+    <string name="battery_saver_description_with_learn_more">To extend battery life, Battery Saver:\n&#183;Turns on Dark theme\n&#183;Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d\n\n<annotation id="url">Learn more</annotation></string>
 
     <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, without a "learn more" link. -->
-    <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>
+    <string name="battery_saver_description">To extend battery life, Battery Saver:\n&#183;Turns on Dark theme\n&#183;Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d</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/styles.xml b/core/res/res/values/styles.xml
index 18f7e48..bcce1f0 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1443,39 +1443,6 @@
         <item name="drawableTintMode">src_atop</item>
     </style>
 
-    <!-- Wifi dialog styles -->
-    <!-- @hide -->
-    <style name="wifi_item">
-        <item name="layout_width">200dip</item>
-        <item name="layout_height">wrap_content</item>
-        <item name="layout_marginTop">8dip</item>
-        <item name="layout_marginStart">16dip</item>
-        <item name="layout_marginEnd">16dip</item>
-        <item name="orientation">vertical</item>
-        <item name="gravity">start</item>
-    </style>
-
-    <!-- @hide -->
-    <style name="wifi_item_label">
-        <item name="layout_width">wrap_content</item>
-        <item name="layout_height">wrap_content</item>
-        <item name="textSize">14sp</item>
-    </style>
-
-    <!-- @hide -->
-    <style name="wifi_item_content">
-        <item name="layout_width">match_parent</item>
-        <item name="layout_height">wrap_content</item>
-        <item name="textSize">18sp</item>
-    </style>
-
-    <!-- @hide -->
-    <style name="wifi_section">
-        <item name="layout_width">match_parent</item>
-        <item name="layout_height">wrap_content</item>
-        <item name="orientation">vertical</item>
-    </style>
-
     <style name="Widget.FastScroll">
         <item name="thumbDrawable">?attr/fastScrollThumbDrawable</item>
         <item name="trackDrawable">?attr/fastScrollTrackDrawable</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1313912..8e10b00 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -82,7 +82,6 @@
   <java-symbol type="id" name="divider" />
   <java-symbol type="id" name="edit_query" />
   <java-symbol type="id" name="edittext_container" />
-  <java-symbol type="id" name="enter_pin_section" />
   <java-symbol type="id" name="expand_activities_button" />
   <java-symbol type="id" name="expires_on" />
   <java-symbol type="id" name="find_next" />
@@ -100,7 +99,6 @@
   <java-symbol type="id" name="image" />
   <java-symbol type="id" name="increment" />
   <java-symbol type="id" name="internalEmpty" />
-  <java-symbol type="id" name="info" />
   <java-symbol type="id" name="inputExtractAccessories" />
   <java-symbol type="id" name="inputExtractAction" />
   <java-symbol type="id" name="issued_on" />
@@ -117,7 +115,6 @@
   <java-symbol type="id" name="mode_normal" />
   <java-symbol type="id" name="month" />
   <java-symbol type="id" name="month_name" />
-  <java-symbol type="id" name="name" />
   <java-symbol type="id" name="next" />
   <java-symbol type="id" name="next_button" />
   <java-symbol type="id" name="new_app_action" />
@@ -193,7 +190,6 @@
   <java-symbol type="id" name="up" />
   <java-symbol type="id" name="value" />
   <java-symbol type="id" name="websearch" />
-  <java-symbol type="id" name="wifi_p2p_wps_pin" />
   <java-symbol type="id" name="year" />
   <java-symbol type="id" name="zoomControls" />
   <java-symbol type="id" name="zoomIn" />
@@ -356,10 +352,6 @@
   <java-symbol type="bool" name="config_requireRadioPowerOffOnSimRefreshReset" />
   <java-symbol type="bool" name="config_speed_up_audio_on_mt_calls" />
   <java-symbol type="bool" name="config_useFixedVolume" />
-  <java-symbol type="bool" name="config_wifi_batched_scan_supported" />
-  <java-symbol type="bool" name="config_wifi_softap_acs_supported" />
-  <java-symbol type="string" name="config_wifi_softap_acs_supported_channel_list" />
-  <java-symbol type="bool" name="config_wifi_softap_ieee80211ac_supported" />
   <java-symbol type="bool" name="config_enableMultiUserUI"/>
   <java-symbol type="bool" name="config_enableNewAutoSelectNetworkUI"/>
   <java-symbol type="bool" name="config_disableUsbPermissionDialogs"/>
@@ -376,23 +368,6 @@
   <java-symbol type="integer" name="config_activeTaskDurationHours" />
   <java-symbol type="bool" name="config_windowShowCircularMask" />
   <java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" />
-  <java-symbol type="bool" name="config_wifi_framework_enable_associated_network_selection" />
-  <java-symbol type="bool" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection" />
-  <java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" />
-  <java-symbol type="bool" name="config_wifi_framework_enable_sar_tx_power_limit" />
-  <java-symbol type="bool" name="config_wifi_framework_enable_soft_ap_sar_tx_power_limit" />
-  <java-symbol type="bool" name="config_wifi_framework_enable_body_proximity_sar_tx_power_limit" />
-  <java-symbol type="string" name="config_wifi_sar_sensor_type" />
-  <java-symbol type="integer" name="config_wifi_framework_sar_free_space_event_id" />
-  <java-symbol type="integer" name="config_wifi_framework_sar_near_hand_event_id" />
-  <java-symbol type="integer" name="config_wifi_framework_sar_near_head_event_id" />
-  <java-symbol type="integer" name="config_wifi_framework_sar_near_body_event_id" />
-  <java-symbol type="bool" name="config_wifi_enable_disconnection_debounce" />
-  <java-symbol type="bool" name="config_wifi_revert_country_code_on_cellular_loss" />
-  <java-symbol type="integer" name="config_wifi_logger_ring_buffer_default_size_limit_kb" />
-  <java-symbol type="integer" name="config_wifi_logger_ring_buffer_verbose_size_limit_kb" />
-  <java-symbol type="array" name="config_wifi_fatal_firmware_alert_error_code_list" />
-  <java-symbol type="bool" name="config_wifi_turn_off_during_emergency_call" />
   <java-symbol type="bool" name="config_supportMicNearUltrasound" />
   <java-symbol type="bool" name="config_supportSpeakerNearUltrasound" />
   <java-symbol type="bool" name="config_supportAudioSourceUnprocessed" />
@@ -416,51 +391,6 @@
   <java-symbol type="dimen" name="config_pictureInPictureMinAspectRatio" />
   <java-symbol type="dimen" name="config_pictureInPictureMaxAspectRatio" />
   <java-symbol type="dimen" name="config_closeToSquareDisplayMaxAspectRatio" />
-  <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_boost_factor" />
-  <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_penalty_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_5GHz_preference_penalty_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_RSSI_SCORE_OFFSET" />
-  <java-symbol type="integer" name="config_wifi_framework_RSSI_SCORE_SLOPE" />
-  <java-symbol type="integer" name="config_wifi_framework_SAME_BSSID_AWARD" />
-  <java-symbol type="integer" name="config_wifi_framework_LAST_SELECTION_AWARD" />
-  <java-symbol type="integer" name="config_wifi_framework_PASSPOINT_SECURITY_AWARD" />
-  <java-symbol type="integer" name="config_wifi_framework_SECURITY_AWARD" />
-  <java-symbol type="integer" name="config_wifi_disconnected_short_scan_interval" />
-  <java-symbol type="integer" name="config_wifi_associated_short_scan_interval" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_backoff" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_max_interval" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_max_total_dwell_time" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_partial_scan_max_num_active_channels" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_entry_rssi_threshold_24GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_low_rssi_threshold_24GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_good_rssi_threshold_24GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_entry_rssi_threshold_5GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_low_rssi_threshold_5GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_wifi_score_good_rssi_threshold_5GHz" />
-  <java-symbol type="integer" name="config_wifi_framework_scan_result_rssi_level_patchup_value" />
-  <java-symbol type="integer" name="config_wifi_framework_current_network_boost" />
-  <java-symbol type="string"  name="config_wifi_random_mac_oui" />
-  <java-symbol type="integer"  name="config_wifi_network_switching_blacklist_time" />
-  <java-symbol type="string"  name="config_wifi_framework_sap_2G_channel_list" />
-  <java-symbol type="integer" name="config_wifi_framework_max_tx_rate_for_full_scan" />
-  <java-symbol type="integer" name="config_wifi_framework_max_rx_rate_for_full_scan" />
-  <java-symbol type="integer" name="config_wifi_framework_min_tx_rate_for_staying_on_network" />
-  <java-symbol type="integer" name="config_wifi_framework_min_rx_rate_for_staying_on_network" />
-
-  <java-symbol type="integer" name="config_wifi_framework_soft_ap_timeout_delay" />
-
-  <java-symbol type="bool" name="config_wifi_framework_cellular_handover_enable_user_triggered_adjustment" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_tx_packet_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_full_scan_rx_packet_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_partial_scan_tx_packet_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_associated_partial_scan_rx_packet_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_network_switch_tx_packet_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_network_switch_rx_packet_threshold" />
-  <java-symbol type="integer" name="config_wifi_framework_current_network_boost" />
-  <java-symbol type="integer" name="config_wifi_framework_recovery_timeout_delay" />
   <java-symbol type="integer" name="config_bluetooth_max_advertisers" />
   <java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
   <java-symbol type="integer" name="config_bluetooth_max_connected_audio_devices" />
@@ -499,8 +429,6 @@
   <java-symbol type="integer" name="config_toastDefaultGravity" />
   <java-symbol type="integer" name="config_triplePressOnPowerBehavior" />
   <java-symbol type="integer" name="config_shortPressOnSleepBehavior" />
-  <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
-  <java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" />
   <java-symbol type="integer" name="config_windowOutsetBottom" />
   <java-symbol type="integer" name="db_connection_pool_size" />
   <java-symbol type="integer" name="db_journal_size_limit" />
@@ -757,7 +685,6 @@
   <java-symbol type="string" name="config_mms_user_agent_profile_url" />
   <java-symbol type="string" name="config_ntpServer" />
   <java-symbol type="string" name="config_useragentprofile_url" />
-  <java-symbol type="string" name="config_wifi_p2p_device_type" />
   <java-symbol type="string" name="config_appsNotReportingCrashes" />
   <java-symbol type="string" name="contentServiceSync" />
   <java-symbol type="string" name="contentServiceSyncNotificationTitle" />
@@ -1119,27 +1046,6 @@
   <java-symbol type="string" name="network_switch_type_name_unknown" />
   <java-symbol type="string" name="wifi_no_internet" />
   <java-symbol type="string" name="wifi_no_internet_detailed" />
-  <java-symbol type="string" name="wifi_softap_config_change" />
-  <java-symbol type="string" name="wifi_softap_config_change_summary" />
-  <java-symbol type="string" name="wifi_softap_config_change_detailed" />
-  <java-symbol type="string" name="wifi_connect_alert_title" />
-  <java-symbol type="string" name="wifi_connect_alert_message" />
-  <java-symbol type="string" name="wifi_connect_default_application" />
-  <java-symbol type="string" name="wifi_p2p_dialog_title" />
-  <java-symbol type="string" name="wifi_p2p_enabled_notification_message" />
-  <java-symbol type="string" name="wifi_p2p_enabled_notification_title" />
-  <java-symbol type="string" name="wifi_p2p_failed_message" />
-  <java-symbol type="string" name="wifi_p2p_from_message" />
-  <java-symbol type="string" name="wifi_p2p_invitation_sent_title" />
-  <java-symbol type="string" name="wifi_p2p_invitation_to_connect_title" />
-  <java-symbol type="string" name="wifi_p2p_show_pin_message" />
-  <java-symbol type="string" name="wifi_p2p_to_message" />
-  <java-symbol type="string" name="wifi_p2p_turnon_message" />
-  <java-symbol type="string" name="wifi_p2p_frequency_conflict_message" />
-  <java-symbol type="string" name="wifi_tether_configure_ssid_default" />
-  <java-symbol type="string" name="wifi_localhotspot_configure_ssid_default" />
-  <java-symbol type="string" name="wifi_watchdog_network_disabled" />
-  <java-symbol type="string" name="wifi_watchdog_network_disabled_detailed" />
   <java-symbol type="string" name="imei" />
   <java-symbol type="string" name="meid" />
   <java-symbol type="string" name="granularity_label_character" />
@@ -1289,7 +1195,6 @@
   <java-symbol type="string" name="lockscreen_transport_play_description" />
   <java-symbol type="string" name="lockscreen_transport_pause_description" />
   <java-symbol type="string" name="config_ethernet_tcp_buffers" />
-  <java-symbol type="string" name="config_wifi_tcp_buffers" />
   <java-symbol type="string" name="demo_starting_message" />
   <java-symbol type="string" name="demo_restarting_message" />
   <java-symbol type="string" name="conference_call" />
@@ -1417,8 +1322,6 @@
   <java-symbol type="drawable" name="picture_emergency" />
   <java-symbol type="drawable" name="platlogo" />
   <java-symbol type="drawable" name="stat_notify_sync_error" />
-  <java-symbol type="drawable" name="stat_notify_wifi_in_range" />
-  <java-symbol type="drawable" name="ic_wifi_settings" />
   <java-symbol type="drawable" name="ic_wifi_signal_0" />
   <java-symbol type="drawable" name="ic_wifi_signal_1" />
   <java-symbol type="drawable" name="ic_wifi_signal_2" />
@@ -1611,8 +1514,6 @@
   <java-symbol type="layout" name="web_text_view_dropdown" />
   <java-symbol type="layout" name="webview_find" />
   <java-symbol type="layout" name="webview_select_singlechoice" />
-  <java-symbol type="layout" name="wifi_p2p_dialog" />
-  <java-symbol type="layout" name="wifi_p2p_dialog_row" />
   <java-symbol type="layout" name="zoom_container" />
   <java-symbol type="layout" name="zoom_controls" />
   <java-symbol type="layout" name="zoom_magnify" />
@@ -1968,17 +1869,6 @@
   <java-symbol type="bool" name="config_allowTheaterModeWakeFromWindowLayout" />
   <java-symbol type="bool" name="config_goToSleepOnButtonPressTheaterMode" />
   <java-symbol type="bool" name="config_supportLongPressPowerWhenNonInteractive" />
-  <java-symbol type="bool" name="config_wifi_background_scan_support" />
-  <java-symbol type="bool" name="config_wifi_dual_band_support" />
-  <java-symbol type="integer" name="config_wifi_max_ap_interfaces" />
-  <java-symbol type="bool" name="config_wifi_convert_apband_5ghz_to_any" />
-  <java-symbol type="bool" name="config_wifi_local_only_hotspot_5ghz" />
-  <java-symbol type="bool" name="config_wifi_connected_mac_randomization_supported" />
-  <java-symbol type="bool" name="config_wifi_p2p_mac_randomization_supported" />
-  <java-symbol type="bool" name="config_wifi_ap_mac_randomization_supported" />
-  <java-symbol type="bool" name="config_wifi_aggressive_randomization_ssid_whitelist_enabled" />
-  <java-symbol type="bool" name="config_wifi_link_probing_supported" />
-  <java-symbol type="bool" name="config_wifi_fast_bss_transition_enabled" />
   <java-symbol type="bool" name="config_wimaxEnabled" />
   <java-symbol type="bool" name="show_ongoing_ime_switcher" />
   <java-symbol type="color" name="config_defaultNotificationColor" />
@@ -2078,24 +1968,6 @@
   <java-symbol type="layout" name="safe_mode" />
   <java-symbol type="layout" name="simple_list_item_2_single_choice" />
   <java-symbol type="layout" name="app_error_dialog" />
-  <java-symbol type="plurals" name="wifi_available" />
-  <java-symbol type="plurals" name="wifi_available_detailed" />
-  <java-symbol type="string" name="wifi_available_title" />
-  <java-symbol type="string" name="wifi_available_title_connecting" />
-  <java-symbol type="string" name="wifi_available_title_connected" />
-  <java-symbol type="string" name="wifi_available_title_failed_to_connect" />
-  <java-symbol type="string" name="wifi_available_content_failed_to_connect" />
-  <java-symbol type="string" name="wifi_available_action_connect" />
-  <java-symbol type="string" name="wifi_available_action_all_networks" />
-  <java-symbol type="string" name="wifi_suggestion_title" />
-  <java-symbol type="string" name="wifi_suggestion_content" />
-  <java-symbol type="string" name="wifi_suggestion_action_allow_app" />
-  <java-symbol type="string" name="wifi_suggestion_action_disallow_app" />
-  <java-symbol type="string" name="wifi_wakeup_onboarding_title" />
-  <java-symbol type="string" name="wifi_wakeup_onboarding_subtext" />
-  <java-symbol type="string" name="wifi_wakeup_onboarding_action_disable" />
-  <java-symbol type="string" name="wifi_wakeup_enabled_title" />
-  <java-symbol type="string" name="wifi_wakeup_enabled_content" />
   <java-symbol type="string" name="accessibility_binding_label" />
   <java-symbol type="string" name="adb_active_notification_message" />
   <java-symbol type="string" name="adb_active_notification_title" />
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 1326952..5b9b703 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -301,12 +301,6 @@
       "group": "WM_DEBUG_REMOTE_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
     },
-    "-1483752006": {
-      "message": "  THUMBNAIL %s: CREATE",
-      "level": "INFO",
-      "group": "WM_SHOW_TRANSACTIONS",
-      "at": "com\/android\/server\/wm\/AppWindowThumbnail.java"
-    },
     "-1471946192": {
       "message": "Marking app token %s with replacing child windows.",
       "level": "DEBUG",
@@ -1297,6 +1291,12 @@
       "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
       "at": "com\/android\/server\/wm\/AppTransition.java"
     },
+    "531242746": {
+      "message": "  THUMBNAIL %s: CREATE",
+      "level": "INFO",
+      "group": "WM_SHOW_TRANSACTIONS",
+      "at": "com\/android\/server\/wm\/WindowContainerThumbnail.java"
+    },
     "539077569": {
       "message": "Clear freezing of %s force=%b",
       "level": "VERBOSE",
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index b7316ab..109d863 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1114,7 +1114,7 @@
      * Return the width for stroking.
      * <p />
      * A value of 0 strokes in hairline mode.
-     * Hairlines always draws a single pixel independent of the canva's matrix.
+     * Hairlines always draws a single pixel independent of the canvas's matrix.
      *
      * @return the paint's stroke width, used whenever the paint's style is
      *         Stroke or StrokeAndFill.
@@ -1126,7 +1126,7 @@
     /**
      * Set the width for stroking.
      * Pass 0 to stroke in hairline mode.
-     * Hairlines always draws a single pixel independent of the canva's matrix.
+     * Hairlines always draws a single pixel independent of the canvas's matrix.
      *
      * @param width set the paint's stroke width, used whenever the paint's
      *              style is Stroke or StrokeAndFill.
@@ -1958,8 +1958,8 @@
      * <code>
      *   Paint paint = new Paint();
      *   paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_INSERT_HYPHEN);
-     *   paint.measureText("abc", 0, 3);  // Returns the width of "‐abc"
-     *   Canvas.drawText("abc", 0, 3, 0f, 0f, paint);  // Draws "‐abc"
+     *   paint.measureText("abc", 0, 3);  // Returns the width of "-abc"
+     *   Canvas.drawText("abc", 0, 3, 0f, 0f, paint);  // Draws "-abc"
      * </code>
      * </pre>
      *
@@ -1985,8 +1985,8 @@
      * <code>
      *   Paint paint = new Paint();
      *   paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_INSERT_HYPHEN);
-     *   paint.measureText("abc", 0, 3);  // Returns the width of "abc‐"
-     *   Canvas.drawText("abc", 0, 3, 0f, 0f, paint);  // Draws "abc‐"
+     *   paint.measureText("abc", 0, 3);  // Returns the width of "abc-"
+     *   Canvas.drawText("abc", 0, 3, 0f, 0f, paint);  // Draws "abc-"
      * </code>
      * </pre>
      *
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 2041e7a..ecfaec2 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -90,6 +90,7 @@
                 "libvulkan",
                 "libui",
                 "libgui",
+                "libnativedisplay",
                 "libnativewindow",
                 "libprotobuf-cpp-lite",
                 "libft2",
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
index a0d3ff9..41e9b4b 100644
--- a/libs/hwui/DeviceInfo.cpp
+++ b/libs/hwui/DeviceInfo.cpp
@@ -15,74 +15,21 @@
  */
 
 #include <DeviceInfo.h>
-
-#include "Properties.h"
-
 #include <gui/SurfaceComposerClient.h>
+#include <log/log.h>
 #include <ui/GraphicTypes.h>
 
 #include <mutex>
 #include <thread>
 
-#include <log/log.h>
+#include "Properties.h"
 
 namespace android {
 namespace uirenderer {
 
-static constexpr android::DisplayInfo sDummyDisplay{
-        1080,   // w
-        1920,   // h
-        320.0,  // xdpi
-        320.0,  // ydpi
-        60.0,   // fps
-        2.0,    // density
-        0,      // orientation
-        false,  // secure?
-        0,      // appVsyncOffset
-        0,      // presentationDeadline
-        1080,   // viewportW
-        1920,   // viewportH
-};
-
 DeviceInfo* DeviceInfo::get() {
-        static DeviceInfo sDeviceInfo;
-        return &sDeviceInfo;
-}
-
-static DisplayInfo QueryDisplayInfo() {
-    if (Properties::isolatedProcess) {
-        return sDummyDisplay;
-    }
-
-    const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
-    LOG_ALWAYS_FATAL_IF(token == nullptr,
-                        "Failed to get display info because internal display is disconnected");
-
-    DisplayInfo displayInfo;
-    status_t status = SurfaceComposerClient::getDisplayInfo(token, &displayInfo);
-    LOG_ALWAYS_FATAL_IF(status, "Failed to get display info, error %d", status);
-    return displayInfo;
-}
-
-static float QueryMaxRefreshRate() {
-    if (Properties::isolatedProcess) {
-        return sDummyDisplay.fps;
-    }
-
-    const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
-    LOG_ALWAYS_FATAL_IF(token == nullptr,
-                        "Failed to get display info because internal display is disconnected");
-
-    Vector<DisplayInfo> configs;
-    configs.reserve(10);
-    status_t status = SurfaceComposerClient::getDisplayConfigs(token, &configs);
-    LOG_ALWAYS_FATAL_IF(status, "Failed to getDisplayConfigs, error %d", status);
-    LOG_ALWAYS_FATAL_IF(configs.size() == 0, "getDisplayConfigs returned 0 configs?");
-    float max = 0.0f;
-    for (auto& info : configs) {
-        max = std::max(max, info.fps);
-    }
-    return max;
+    static DeviceInfo sDeviceInfo;
+    return &sDeviceInfo;
 }
 
 static void queryWideColorGamutPreference(sk_sp<SkColorSpace>* colorSpace, SkColorType* colorType) {
@@ -123,14 +70,17 @@
     }
 }
 
-DeviceInfo::DeviceInfo() : mMaxRefreshRate(QueryMaxRefreshRate()) {
+DeviceInfo::DeviceInfo() {
 #if HWUI_NULL_GPU
         mMaxTextureSize = NULL_GPU_MAX_TEXTURE_SIZE;
 #else
         mMaxTextureSize = -1;
 #endif
-    mDisplayInfo = QueryDisplayInfo();
-    queryWideColorGamutPreference(&mWideColorSpace, &mWideColorType);
+        updateDisplayInfo();
+        queryWideColorGamutPreference(&mWideColorSpace, &mWideColorType);
+}
+DeviceInfo::~DeviceInfo() {
+    ADisplay_release(mDisplays);
 }
 
 int DeviceInfo::maxTextureSize() const {
@@ -143,7 +93,36 @@
 }
 
 void DeviceInfo::onDisplayConfigChanged() {
-    mDisplayInfo = QueryDisplayInfo();
+    updateDisplayInfo();
+}
+
+void DeviceInfo::updateDisplayInfo() {
+    if (Properties::isolatedProcess) {
+        return;
+    }
+
+    if (mCurrentConfig == nullptr) {
+        mDisplaysSize = ADisplay_acquirePhysicalDisplays(&mDisplays);
+        LOG_ALWAYS_FATAL_IF(mDisplays == nullptr || mDisplaysSize <= 0,
+                            "Failed to get physical displays: no connected display: %d!", mDisplaysSize);
+        for (size_t i = 0; i < mDisplaysSize; i++) {
+            ADisplayType type = ADisplay_getDisplayType(mDisplays[i]);
+            if (type == ADisplayType::DISPLAY_TYPE_INTERNAL) {
+                mPhysicalDisplayIndex = i;
+                break;
+            }
+        }
+        LOG_ALWAYS_FATAL_IF(mPhysicalDisplayIndex < 0, "Failed to find a connected physical display!");
+        mMaxRefreshRate = ADisplay_getMaxSupportedFps(mDisplays[mPhysicalDisplayIndex]);
+    }
+    status_t status = ADisplay_getCurrentConfig(mDisplays[mPhysicalDisplayIndex], &mCurrentConfig);
+    LOG_ALWAYS_FATAL_IF(status, "Failed to get display config, error %d", status);
+    mWidth = ADisplayConfig_getWidth(mCurrentConfig);
+    mHeight = ADisplayConfig_getHeight(mCurrentConfig);
+    mDensity = ADisplayConfig_getDensity(mCurrentConfig);
+    mRefreshRate = ADisplayConfig_getFps(mCurrentConfig);
+    mCompositorOffset = ADisplayConfig_getCompositorOffsetNanos(mCurrentConfig);
+    mAppOffset = ADisplayConfig_getAppVsyncOffsetNanos(mCurrentConfig);
 }
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
index 0e3f119..3431583 100644
--- a/libs/hwui/DeviceInfo.h
+++ b/libs/hwui/DeviceInfo.h
@@ -16,8 +16,8 @@
 #ifndef DEVICEINFO_H
 #define DEVICEINFO_H
 
+#include <apex/display.h>
 #include <SkImageInfo.h>
-#include <ui/DisplayInfo.h>
 
 #include "utils/Macros.h"
 
@@ -33,28 +33,44 @@
 
 public:
     static DeviceInfo* get();
+    static float getMaxRefreshRate() { return get()->mMaxRefreshRate; }
+    static int32_t getWidth() { return get()->mWidth; }
+    static int32_t getHeight() { return get()->mHeight; }
+    static float getDensity() { return get()->mDensity; }
+    static float getRefreshRate() { return get()->mRefreshRate; }
+    static int64_t getCompositorOffset() { return get()->mCompositorOffset; }
+    static int64_t getAppOffset() { return get()->mAppOffset; }
 
     // this value is only valid after the GPU has been initialized and there is a valid graphics
     // context or if you are using the HWUI_NULL_GPU
     int maxTextureSize() const;
-    const DisplayInfo& displayInfo() const { return mDisplayInfo; }
     sk_sp<SkColorSpace> getWideColorSpace() const { return mWideColorSpace; }
     SkColorType getWideColorType() const { return mWideColorType; }
-    float getMaxRefreshRate() const { return mMaxRefreshRate; }
 
     void onDisplayConfigChanged();
 
 private:
     friend class renderthread::RenderThread;
     static void setMaxTextureSize(int maxTextureSize);
+    void updateDisplayInfo();
 
     DeviceInfo();
+    ~DeviceInfo();
 
     int mMaxTextureSize;
-    DisplayInfo mDisplayInfo;
     sk_sp<SkColorSpace> mWideColorSpace;
     SkColorType mWideColorType;
-    const float mMaxRefreshRate;
+    ADisplayConfig* mCurrentConfig = nullptr;
+    ADisplay** mDisplays = nullptr;
+    int mDisplaysSize = 0;
+    int mPhysicalDisplayIndex = -1;
+    float mMaxRefreshRate = 60.0;
+    int32_t mWidth = 1080;
+    int32_t mHeight = 1920;
+    float mDensity = 2.0;
+    float mRefreshRate = 60.0;
+    int64_t mCompositorOffset = 0;
+    int64_t mAppOffset = 0;
 };
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index eae3584..10e7160 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -16,8 +16,10 @@
 
 #include "JankTracker.h"
 
+#include <cutils/ashmem.h>
 #include <errno.h>
 #include <inttypes.h>
+#include <log/log.h>
 #include <statslog.h>
 #include <sys/mman.h>
 
@@ -25,11 +27,9 @@
 #include <cmath>
 #include <cstdio>
 #include <limits>
-
-#include <cutils/ashmem.h>
-#include <log/log.h>
 #include <sstream>
 
+#include "DeviceInfo.h"
 #include "Properties.h"
 #include "utils/TimeUtils.h"
 #include "utils/Trace.h"
@@ -79,11 +79,11 @@
 // and filter it out of the frame profile data
 static FrameInfoIndex sFrameStart = FrameInfoIndex::IntendedVsync;
 
-JankTracker::JankTracker(ProfileDataContainer* globalData, const DisplayInfo& displayInfo) {
+JankTracker::JankTracker(ProfileDataContainer* globalData) {
     mGlobalData = globalData;
-    nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1_s / displayInfo.fps);
-    nsecs_t sfOffset = frameIntervalNanos - (displayInfo.presentationDeadline - 1_ms);
-    nsecs_t offsetDelta = sfOffset - displayInfo.appVsyncOffset;
+    nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1_s / DeviceInfo::getRefreshRate());
+    nsecs_t sfOffset = DeviceInfo::getCompositorOffset();
+    nsecs_t offsetDelta = sfOffset - DeviceInfo::getAppOffset();
     // There are two different offset cases. If the offsetDelta is positive
     // and small, then the intention is to give apps extra time by leveraging
     // pipelining between the UI & RT threads. If the offsetDelta is large or
diff --git a/libs/hwui/JankTracker.h b/libs/hwui/JankTracker.h
index 08059268..4460266 100644
--- a/libs/hwui/JankTracker.h
+++ b/libs/hwui/JankTracker.h
@@ -23,7 +23,6 @@
 #include "utils/RingBuffer.h"
 
 #include <cutils/compiler.h>
-#include <ui/DisplayInfo.h>
 
 #include <array>
 #include <memory>
@@ -49,7 +48,7 @@
 // TODO: Replace DrawProfiler with this
 class JankTracker {
 public:
-    explicit JankTracker(ProfileDataContainer* globalData, const DisplayInfo& displayInfo);
+    explicit JankTracker(ProfileDataContainer* globalData);
 
     void setDescription(JankTrackerType type, const std::string&& name) {
         mDescription.type = type;
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 4e7df88..446e81e 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -16,7 +16,6 @@
 
 #include "Properties.h"
 #include "Debug.h"
-#include "DeviceInfo.h"
 #ifdef __ANDROID__
 #include "HWUIProperties.sysprop.h"
 #endif
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index e979448..24f6035 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -16,7 +16,10 @@
 
 #pragma once
 
+#ifdef __ANDROID__ // Layoutlib does not support device info
 #include "DeviceInfo.h"
+#endif // __ANDROID__
+
 #include "Outline.h"
 #include "Rect.h"
 #include "RevealClip.h"
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index b366a80..eaed46c 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -16,6 +16,7 @@
 
 #include "CacheManager.h"
 
+#include "DeviceInfo.h"
 #include "Layer.h"
 #include "Properties.h"
 #include "RenderThread.h"
@@ -42,8 +43,8 @@
 #define SURFACE_SIZE_MULTIPLIER (5.0f * 4.0f)
 #define BACKGROUND_RETENTION_PERCENTAGE (0.5f)
 
-CacheManager::CacheManager(const DisplayInfo& display)
-        : mMaxSurfaceArea(display.w * display.h)
+CacheManager::CacheManager()
+        : mMaxSurfaceArea(DeviceInfo::getWidth() * DeviceInfo::getHeight())
         , mMaxResourceBytes(mMaxSurfaceArea * SURFACE_SIZE_MULTIPLIER)
         , mBackgroundResourceBytes(mMaxResourceBytes * BACKGROUND_RETENTION_PERCENTAGE)
         // This sets the maximum size for a single texture atlas in the GPU font cache. If
@@ -52,9 +53,9 @@
         , mMaxGpuFontAtlasBytes(GrNextSizePow2(mMaxSurfaceArea))
         // This sets the maximum size of the CPU font cache to be at least the same size as the
         // total number of GPU font caches (i.e. 4 separate GPU atlases).
-        , mMaxCpuFontCacheBytes(std::max(mMaxGpuFontAtlasBytes*4, SkGraphics::GetFontCacheLimit()))
+        , mMaxCpuFontCacheBytes(
+                  std::max(mMaxGpuFontAtlasBytes * 4, SkGraphics::GetFontCacheLimit()))
         , mBackgroundCpuFontCacheBytes(mMaxCpuFontCacheBytes * BACKGROUND_RETENTION_PERCENTAGE) {
-
     SkGraphics::SetFontCacheLimit(mMaxCpuFontCacheBytes);
 }
 
diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h
index 857710b..968251e 100644
--- a/libs/hwui/renderthread/CacheManager.h
+++ b/libs/hwui/renderthread/CacheManager.h
@@ -21,7 +21,6 @@
 #include <GrContext.h>
 #endif
 #include <SkSurface.h>
-#include <ui/DisplayInfo.h>
 #include <utils/String8.h>
 #include <vector>
 
@@ -55,7 +54,7 @@
 private:
     friend class RenderThread;
 
-    explicit CacheManager(const DisplayInfo& display);
+    explicit CacheManager();
 
 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
     void reset(sk_sp<GrContext> grContext);
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 15e0c8d..826a8ea 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -102,13 +102,13 @@
         , mGenerationID(0)
         , mOpaque(!translucent)
         , mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord()))
-        , mJankTracker(&thread.globalProfileData(), DeviceInfo::get()->displayInfo())
+        , mJankTracker(&thread.globalProfileData())
         , mProfiler(mJankTracker.frames(), thread.timeLord().frameIntervalNanos())
         , mContentDrawBounds(0, 0, 0, 0)
         , mRenderPipeline(std::move(renderPipeline)) {
     rootRenderNode->makeRoot();
     mRenderNodes.emplace_back(rootRenderNode);
-    mProfiler.setDensity(DeviceInfo::get()->displayInfo().density);
+    mProfiler.setDensity(DeviceInfo::getDensity());
     setRenderAheadDepth(Properties::defaultRenderAhead);
 }
 
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index ee1a7ce..a446858 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -179,12 +179,11 @@
     mEglManager = new EglManager();
     mRenderState = new RenderState(*this);
     mVkManager = new VulkanManager();
-    mCacheManager = new CacheManager(DeviceInfo::get()->displayInfo());
+    mCacheManager = new CacheManager();
 }
 
 void RenderThread::setupFrameInterval() {
-    auto& displayInfo = DeviceInfo::get()->displayInfo();
-    nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1000000000 / displayInfo.fps);
+    nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1000000000 / DeviceInfo::getRefreshRate());
     mTimeLord.setFrameInterval(frameIntervalNanos);
     mDispatchFrameDelay = static_cast<nsecs_t>(frameIntervalNanos * .25f);
 }
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 5aa1af3..bdd80721 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -29,7 +29,6 @@
 #include <GrContext.h>
 #include <SkBitmap.h>
 #include <cutils/compiler.h>
-#include <ui/DisplayInfo.h>
 #include <utils/Looper.h>
 #include <utils/Thread.h>
 
diff --git a/libs/hwui/tests/unit/CacheManagerTests.cpp b/libs/hwui/tests/unit/CacheManagerTests.cpp
index 3f1ef93..c83a3c8 100644
--- a/libs/hwui/tests/unit/CacheManagerTests.cpp
+++ b/libs/hwui/tests/unit/CacheManagerTests.cpp
@@ -33,7 +33,8 @@
 }
 
 RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, trimMemory) {
-    DisplayInfo displayInfo = DeviceInfo::get()->displayInfo();
+    int32_t width = DeviceInfo::get()->getWidth();
+    int32_t height = DeviceInfo::get()->getHeight();
     GrContext* grContext = renderThread.getGrContext();
     ASSERT_TRUE(grContext != nullptr);
 
@@ -42,7 +43,7 @@
     std::vector<sk_sp<SkSurface>> surfaces;
 
     while (getCacheUsage(grContext) <= renderThread.cacheManager().getBackgroundCacheSize()) {
-        SkImageInfo info = SkImageInfo::MakeA8(displayInfo.w, displayInfo.h);
+        SkImageInfo info = SkImageInfo::MakeA8(width, height);
         sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kYes, info);
         surface->getCanvas()->drawColor(SK_AlphaTRANSPARENT);
 
@@ -52,8 +53,7 @@
     }
 
     // create an image and pin it so that we have something with a unique key in the cache
-    sk_sp<Bitmap> bitmap =
-            Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(displayInfo.w, displayInfo.h));
+    sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(width, height));
     sk_sp<SkImage> image = bitmap->makeImage();
     ASSERT_TRUE(SkImage_pinAsTexture(image.get(), grContext));
 
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index b7dd543..c48f6e8 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1890,7 +1890,7 @@
     @Deprecated
     @RequiresPermission(ACCESS_FINE_LOCATION)
     public boolean registerGnssStatusCallback(@NonNull GnssStatus.Callback callback) {
-        return registerGnssStatusCallback(callback, null);
+        return registerGnssStatusCallback(Runnable::run, callback);
     }
 
     /**
@@ -1985,7 +1985,7 @@
     @Deprecated
     @RequiresPermission(ACCESS_FINE_LOCATION)
     public boolean addNmeaListener(@NonNull OnNmeaMessageListener listener) {
-        return addNmeaListener(listener, null);
+        return addNmeaListener(Runnable::run, listener);
     }
 
     /**
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index 70a343f..7ba122b 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -395,7 +395,7 @@
          * <p>The row stride for this color plane, in bytes.</p>
          *
          * <p>This is the distance between the start of two consecutive rows of
-         * pixels in the image. Note that row stried is undefined for some formats
+         * pixels in the image. Note that row stride is undefined for some formats
          * such as
          * {@link android.graphics.ImageFormat#RAW_PRIVATE RAW_PRIVATE},
          * and calling getRowStride on images of these formats will
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index ce18ab3..cb6c126 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -18,10 +18,14 @@
 
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
 import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.content.Context;
 import android.content.Intent;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
@@ -30,6 +34,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 
+import java.lang.annotation.Retention;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -40,12 +45,40 @@
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.Executor;
 
-
 /**
  * A new Media Router
  * @hide
  */
 public class MediaRouter2 {
+
+    /** @hide */
+    @Retention(SOURCE)
+    @IntDef(value = {
+            SELECT_REASON_UNKNOWN,
+            SELECT_REASON_USER_SELECTED,
+            SELECT_REASON_FALLBACK})
+    public @interface SelectReason {}
+
+    /**
+     * Passed to {@link Callback#onRouteSelected(MediaRoute2Info, int, Bundle)} when the reason
+     * the route was selected is unknown.
+     */
+    public static final int SELECT_REASON_UNKNOWN = 0;
+
+    /**
+     * Passed to {@link Callback#onRouteSelected(MediaRoute2Info, int, Bundle)} when the route
+     * is selected in response to a user's request. For example, when a user has selected
+     * a different device to play media to.
+     */
+    public static final int SELECT_REASON_USER_SELECTED = 1;
+
+    /**
+     * Passed to {@link Callback#onRouteSelected(MediaRoute2Info, int, Bundle)} when the route
+     * is selected as a fallback route. For example, when Wi-Fi is disconnected, the device speaker
+     * may be selected as a fallback route.
+     */
+    public static final int SELECT_REASON_FALLBACK = 2;
+
     private static final String TAG = "MR2";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     private static final Object sLock = new Object();
@@ -457,10 +490,31 @@
         public void onRoutesRemoved(@NonNull List<MediaRoute2Info> routes) {}
 
         /**
-         * Called when routes are changed.
+         * Called when routes are changed. For example, it is called when the route's name
+         * or volume have been changed.
+         *
+         * TODO: Write here what the developers should do when this method is called.
+         * How they can find the exact point how a route is changed?
+         * It can be a volume, name, client package name, ....
+         *
          * @param routes the list of routes that have been changed. It's never empty.
          */
         public void onRoutesChanged(@NonNull List<MediaRoute2Info> routes) {}
+
+        // TODO: Make this callback be called when we add requestSelectRoute().
+        /**
+         * Called when a route is selected. Exactly one route can be selected at a time.
+         * @param route the selected route.
+         * @param reason the reason why the route is selected.
+         * @param connectionHints An optional bundle of provider-specific arguments which may be
+         *                        used to control the selected route. Can be empty.
+         * @see #SELECT_REASON_UNKNOWN
+         * @see #SELECT_REASON_USER_SELECTED
+         * @see #SELECT_REASON_FALLBACK
+         * @see #getSelectedRoute()
+         */
+        public void onRouteSelected(@NonNull MediaRoute2Info route, @SelectReason int reason,
+                @NonNull Bundle connectionHints) {}
     }
 
     final class CallbackRecord {
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
index d3d9b28..0bd2e06 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -24,6 +24,8 @@
 import com.android.systemui.power.PowerUI;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsModule;
+import com.android.systemui.shortcut.ShortcutKeyDispatcher;
+import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.car.CarStatusBar;
 import com.android.systemui.statusbar.car.CarStatusBarModule;
 import com.android.systemui.statusbar.notification.InstantAppNotifier;
@@ -45,7 +47,13 @@
     @Binds
     @IntoMap
     @ClassKey(AuthController.class)
-    public abstract SystemUI bindAuthController(AuthController service);
+    public abstract SystemUI bindAuthController(AuthController sysui);
+
+    /** Inject into Divider. */
+    @Binds
+    @IntoMap
+    @ClassKey(Divider.class)
+    public abstract SystemUI bindDivider(Divider sysui);
 
     /** */
     @Binds
@@ -57,7 +65,7 @@
     @Binds
     @IntoMap
     @ClassKey(GarbageMonitor.Service.class)
-    public abstract SystemUI bindGarbageMonitorService(GarbageMonitor.Service service);
+    public abstract SystemUI bindGarbageMonitorService(GarbageMonitor.Service sysui);
 
     /** Inject into GlobalActionsComponent. */
     @Binds
@@ -107,6 +115,12 @@
     @ClassKey(ScreenDecorations.class)
     public abstract SystemUI bindScreenDecorations(ScreenDecorations sysui);
 
+    /** Inject into ShortcutKeyDispatcher. */
+    @Binds
+    @IntoMap
+    @ClassKey(ShortcutKeyDispatcher.class)
+    public abstract SystemUI bindsShortcutKeyDispatcher(ShortcutKeyDispatcher sysui);
+
     /** Inject into SizeCompatModeActivityController. */
     @Binds
     @IntoMap
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
index be4b889..c35303e 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
@@ -18,12 +18,8 @@
 
 import android.content.Context;
 
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.dagger.SystemUIRootComponent;
 import com.android.systemui.navigationbar.car.CarFacetButtonController;
-import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 
 import javax.inject.Singleton;
 
@@ -50,11 +46,6 @@
         return mCarDependencyComponent;
     }
 
-    public StatusBarKeyguardViewManager createStatusBarKeyguardViewManager(Context context,
-            ViewMediatorCallback viewMediatorCallback, LockPatternUtils lockPatternUtils) {
-        return new CarStatusBarKeyguardViewManager(context, viewMediatorCallback, lockPatternUtils);
-    }
-
     @Singleton
     @Component(modules = ContextHolder.class)
     public interface CarDependencyComponent {
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index d3a6cde..3b63e79 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -28,15 +28,21 @@
 import com.android.systemui.dock.DockManagerImpl;
 import com.android.systemui.power.EnhancedEstimates;
 import com.android.systemui.power.EnhancedEstimatesImpl;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.RecentsImplementation;
+import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
 import com.android.systemui.statusbar.car.CarStatusBar;
+import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.collection.NotificationData;
 import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.volume.CarVolumeDialogComponent;
 import com.android.systemui.volume.VolumeDialogComponent;
 
@@ -70,6 +76,12 @@
 
     @Singleton
     @Provides
+    static Divider provideDivider(Context context) {
+        return new Divider(context);
+    }
+
+    @Singleton
+    @Provides
     @Named(LEAK_REPORT_EMAIL_NAME)
     static String provideLeakReportEmail() {
         return "buganizer-system+181579@google.com";
@@ -95,6 +107,13 @@
         return SysUiServiceProvider.getComponent(context, StatusBar.class);
     }
 
+    @Provides
+    @Singleton
+    static Recents provideRecents(Context context, RecentsImplementation recentsImplementation,
+            CommandQueue commandQueue) {
+        return new Recents(context, recentsImplementation, commandQueue);
+    }
+
     @Binds
     abstract SystemUIRootComponent bindSystemUIRootComponent(
             CarSystemUIRootComponent systemUIRootComponent);
@@ -105,4 +124,8 @@
     @Binds
     abstract VolumeDialogComponent bindVolumeDialogComponent(
             CarVolumeDialogComponent carVolumeDialogComponent);
+
+    @Binds
+    abstract StatusBarKeyguardViewManager bindStatusBarKeyguardViewManager(
+            CarStatusBarKeyguardViewManager keyguardViewManager);
 }
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index fc0b317..1d14c34 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -55,22 +55,21 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.statusbar.RegisterStatusBarResult;
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.CarSystemUIFactory;
 import com.android.systemui.Dependency;
-import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.doze.DozeLog;
 import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -81,6 +80,7 @@
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.car.CarQSFragment;
 import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.FeatureFlags;
 import com.android.systemui.statusbar.FlingAnimationUtils;
@@ -103,7 +103,6 @@
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.phone.AutoHideController;
@@ -115,12 +114,14 @@
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.LightsOutNotifController;
 import com.android.systemui.statusbar.phone.LockscreenWallpaper;
 import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -131,11 +132,11 @@
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
 import com.android.systemui.statusbar.policy.RemoteInputUriController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.Map;
+import java.util.Optional;
 
 import javax.inject.Named;
 
@@ -243,7 +244,6 @@
             AutoHideController autoHideController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             StatusBarIconController statusBarIconController,
-            DozeLog dozeLog,
             PulseExpansionHandler pulseExpansionHandler,
             NotificationWakeUpCoordinator notificationWakeUpCoordinator,
             KeyguardBypassController keyguardBypassController,
@@ -261,10 +261,7 @@
             NotificationEntryManager notificationEntryManager,
             NotificationInterruptionStateProvider notificationInterruptionStateProvider,
             NotificationViewHierarchyManager notificationViewHierarchyManager,
-            ForegroundServiceController foregroundServiceController,
-            AppOpsController appOpsController,
             KeyguardViewMediator keyguardViewMediator,
-            ZenModeController zenModeController,
             NotificationAlertingManager notificationAlertingManager,
             DisplayMetrics displayMetrics,
             MetricsLogger metricsLogger,
@@ -291,7 +288,6 @@
             ConfigurationController configurationController,
             StatusBarWindowController statusBarWindowController,
             StatusBarWindowViewController.Builder statusBarWindowViewControllerBuild,
-            NotifLog notifLog,
             DozeParameters dozeParameters,
             ScrimController scrimController,
             Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
@@ -302,7 +298,12 @@
             CommandQueue commandQueue,
             PluginManager pluginManager,
             RemoteInputUriController remoteInputUriController,
+            Optional<Divider> dividerOptional,
             SuperStatusBarViewFactory superStatusBarViewFactory,
+            LightsOutNotifController lightsOutNotifController,
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+            ViewMediatorCallback viewMediatorCallback,
+            DismissCallbackRegistry dismissCallbackRegistry,
             /* Car Settings injected components. */
             CarNavigationBarController carNavigationBarController) {
         super(
@@ -312,7 +313,6 @@
                 autoHideController,
                 keyguardUpdateMonitor,
                 statusBarIconController,
-                dozeLog,
                 pulseExpansionHandler,
                 notificationWakeUpCoordinator,
                 keyguardBypassController,
@@ -330,10 +330,7 @@
                 notificationEntryManager,
                 notificationInterruptionStateProvider,
                 notificationViewHierarchyManager,
-                foregroundServiceController,
-                appOpsController,
                 keyguardViewMediator,
-                zenModeController,
                 notificationAlertingManager,
                 displayMetrics,
                 metricsLogger,
@@ -360,7 +357,6 @@
                 configurationController,
                 statusBarWindowController,
                 statusBarWindowViewControllerBuild,
-                notifLog,
                 dozeParameters,
                 scrimController,
                 null /* keyguardLiftController */,
@@ -372,7 +368,12 @@
                 commandQueue,
                 pluginManager,
                 remoteInputUriController,
-                superStatusBarViewFactory);
+                dividerOptional,
+                lightsOutNotifController,
+                superStatusBarViewFactory,
+                statusBarKeyguardViewManager,
+                viewMediatorCallback,
+                dismissCallbackRegistry);
         mScrimController = scrimController;
         mCarNavigationBarController = carNavigationBarController;
     }
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
index 5921868..0ad0992 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
@@ -20,18 +20,43 @@
 import android.view.View;
 
 import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.R;
+import com.android.systemui.dock.DockManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.phone.NavigationModeController;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarWindowController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/** Car implementation of the {@link StatusBarKeyguardViewManager}. */
+@Singleton
 public class CarStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager {
 
     protected boolean mShouldHideNavBar;
 
+    @Inject
     public CarStatusBarKeyguardViewManager(Context context,
             ViewMediatorCallback callback,
-            LockPatternUtils lockPatternUtils) {
-        super(context, callback, lockPatternUtils);
+            LockPatternUtils lockPatternUtils,
+            SysuiStatusBarStateController sysuiStatusBarStateController,
+            ConfigurationController configurationController,
+            KeyguardUpdateMonitor keyguardUpdateMonitor,
+            NavigationModeController navigationModeController,
+            DockManager dockManager,
+            StatusBarWindowController statusBarWindowController,
+            KeyguardStateController keyguardStateController,
+            NotificationMediaManager notificationMediaManager) {
+        super(context, callback, lockPatternUtils, sysuiStatusBarStateController,
+                configurationController, keyguardUpdateMonitor, navigationModeController,
+                dockManager, statusBarWindowController, keyguardStateController,
+                notificationMediaManager);
         mShouldHideNavBar = context.getResources()
                 .getBoolean(R.bool.config_hideNavWhenKeyguardBouncerShown);
     }
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
index b19fae8..542fa44 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
@@ -24,20 +24,20 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.ForegroundServiceController;
+import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.doze.DozeLog;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.navigationbar.car.CarNavigationBarController;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.FeatureFlags;
 import com.android.systemui.statusbar.NavigationBarController;
@@ -59,7 +59,6 @@
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.phone.AutoHideController;
@@ -70,11 +69,13 @@
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.LightsOutNotifController;
 import com.android.systemui.statusbar.phone.LockscreenWallpaper;
 import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -85,7 +86,8 @@
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
 import com.android.systemui.statusbar.policy.RemoteInputUriController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
+
+import java.util.Optional;
 
 import javax.inject.Named;
 import javax.inject.Singleton;
@@ -111,7 +113,6 @@
             AutoHideController autoHideController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             StatusBarIconController statusBarIconController,
-            DozeLog dozeLog,
             PulseExpansionHandler pulseExpansionHandler,
             NotificationWakeUpCoordinator notificationWakeUpCoordinator,
             KeyguardBypassController keyguardBypassController,
@@ -129,10 +130,7 @@
             NotificationEntryManager notificationEntryManager,
             NotificationInterruptionStateProvider notificationInterruptionStateProvider,
             NotificationViewHierarchyManager notificationViewHierarchyManager,
-            ForegroundServiceController foregroundServiceController,
-            AppOpsController appOpsController,
             KeyguardViewMediator keyguardViewMediator,
-            ZenModeController zenModeController,
             NotificationAlertingManager notificationAlertingManager,
             DisplayMetrics displayMetrics,
             MetricsLogger metricsLogger,
@@ -159,7 +157,6 @@
             ConfigurationController configurationController,
             StatusBarWindowController statusBarWindowController,
             StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder,
-            NotifLog notifLog,
             DozeParameters dozeParameters,
             ScrimController scrimController,
             Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
@@ -170,7 +167,12 @@
             CommandQueue commandQueue,
             PluginManager pluginManager,
             RemoteInputUriController remoteInputUriController,
+            Optional<Divider> dividerOptional,
             SuperStatusBarViewFactory superStatusBarViewFactory,
+            LightsOutNotifController lightsOutNotifController,
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+            ViewMediatorCallback viewMediatorCallback,
+            DismissCallbackRegistry dismissCallbackRegistry,
             CarNavigationBarController carNavigationBarController) {
         return new CarStatusBar(
                 context,
@@ -179,7 +181,6 @@
                 autoHideController,
                 keyguardUpdateMonitor,
                 statusBarIconController,
-                dozeLog,
                 pulseExpansionHandler,
                 notificationWakeUpCoordinator,
                 keyguardBypassController,
@@ -197,10 +198,7 @@
                 notificationEntryManager,
                 notificationInterruptionStateProvider,
                 notificationViewHierarchyManager,
-                foregroundServiceController,
-                appOpsController,
                 keyguardViewMediator,
-                zenModeController,
                 notificationAlertingManager,
                 displayMetrics,
                 metricsLogger,
@@ -227,7 +225,6 @@
                 configurationController,
                 statusBarWindowController,
                 statusBarWindowViewControllerBuilder,
-                notifLog,
                 dozeParameters,
                 scrimController,
                 lockscreenWallpaperLazy,
@@ -238,7 +235,12 @@
                 commandQueue,
                 pluginManager,
                 remoteInputUriController,
+                dividerOptional,
                 superStatusBarViewFactory,
+                lightsOutNotifController,
+                statusBarKeyguardViewManager,
+                viewMediatorCallback,
+                dismissCallbackRegistry,
                 carNavigationBarController);
     }
 }
diff --git a/packages/ExternalStorageProvider/res/values-af/strings.xml b/packages/ExternalStorageProvider/res/values-af/strings.xml
index 96b25a4..b7684a7 100644
--- a/packages/ExternalStorageProvider/res/values-af/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-af/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Eksterne berging"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Plaaslike berging"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Interne berging"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumente"</string>
+    <string name="app_label" msgid="748293919008814871">"Eksterne berging"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Plaaslike berging"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Interne berging"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumente"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-am/strings.xml b/packages/ExternalStorageProvider/res/values-am/strings.xml
index f2d308c..49de54d 100644
--- a/packages/ExternalStorageProvider/res/values-am/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-am/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"ውጫዊ ማከማቻ"</string>
-    <string name="storage_description" msgid="8541974407321172792">"አካባቢያዊ ማከማቻ"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"ውስጣዊ ማከማቻ"</string>
-    <string name="root_documents" msgid="4051252304075469250">"ሰነዶች"</string>
+    <string name="app_label" msgid="748293919008814871">"ውጫዊ ማከማቻ"</string>
+    <string name="storage_description" msgid="9176081505553938524">"አካባቢያዊ ማከማቻ"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"ውስጣዊ ማከማቻ"</string>
+    <string name="root_documents" msgid="5695037589229175941">"ሰነዶች"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-ar/strings.xml b/packages/ExternalStorageProvider/res/values-ar/strings.xml
index a01fc02..878f560 100644
--- a/packages/ExternalStorageProvider/res/values-ar/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ar/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"وحدة تخزين خارجية"</string>
-    <string name="storage_description" msgid="8541974407321172792">"التخزين المحلي"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"وحدة تخزين داخلية"</string>
-    <string name="root_documents" msgid="4051252304075469250">"مستندات"</string>
+    <string name="app_label" msgid="748293919008814871">"وحدة تخزين خارجية"</string>
+    <string name="storage_description" msgid="9176081505553938524">"التخزين المحلي"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"وحدة تخزين داخلية"</string>
+    <string name="root_documents" msgid="5695037589229175941">"مستندات"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-as/strings.xml b/packages/ExternalStorageProvider/res/values-as/strings.xml
index 278b84e..92bb1aa 100644
--- a/packages/ExternalStorageProvider/res/values-as/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-as/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"বাহ্যিক সঞ্চয়াগাৰ"</string>
-    <string name="storage_description" msgid="8541974407321172792">"স্থানীয় সঞ্চয়াগাৰ"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"আভ্যন্তৰীণ সঞ্চয়াগাৰ"</string>
-    <string name="root_documents" msgid="4051252304075469250">"নথিপত্রসমূহ"</string>
+    <string name="app_label" msgid="748293919008814871">"বাহ্যিক সঞ্চয়াগাৰ"</string>
+    <string name="storage_description" msgid="9176081505553938524">"স্থানীয় সঞ্চয়াগাৰ"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"আভ্যন্তৰীণ সঞ্চয়াগাৰ"</string>
+    <string name="root_documents" msgid="5695037589229175941">"নথিপত্রসমূহ"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-az/strings.xml b/packages/ExternalStorageProvider/res/values-az/strings.xml
index d8c17ee..605a11a 100644
--- a/packages/ExternalStorageProvider/res/values-az/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-az/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Xarici Yaddaş"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Yerli yaddaş"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Daxili yaddaş"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Sənədlər"</string>
+    <string name="app_label" msgid="748293919008814871">"Xarici Yaddaş"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Yerli yaddaş"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Daxili yaddaş"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Sənədlər"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml b/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml
index 235b621..88e34fe 100644
--- a/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-b+sr+Latn/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Spoljna memorija"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Lokalni memorijski prostor"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Interna memorija"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
+    <string name="app_label" msgid="748293919008814871">"Spoljna memorija"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Lokalni memorijski prostor"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Interna memorija"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumenti"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-be/strings.xml b/packages/ExternalStorageProvider/res/values-be/strings.xml
index 911ff54..07c7da5 100644
--- a/packages/ExternalStorageProvider/res/values-be/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-be/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Вонкавае сховішча"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Лакальнае сховішча"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Унутранае сховішча"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Дакументы"</string>
+    <string name="app_label" msgid="748293919008814871">"Вонкавае сховішча"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Лакальнае сховішча"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Унутранае сховішча"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Дакументы"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-bg/strings.xml b/packages/ExternalStorageProvider/res/values-bg/strings.xml
index e3b58e4..ca89dc5 100644
--- a/packages/ExternalStorageProvider/res/values-bg/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-bg/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Външно хранилище"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Локално хранилище"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Вътрешно хранилище"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Документи"</string>
+    <string name="app_label" msgid="748293919008814871">"Външно хранилище"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Локално хранилище"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Вътрешно хранилище"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Документи"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-bn/strings.xml b/packages/ExternalStorageProvider/res/values-bn/strings.xml
index 264d82a..2b7f6ad 100644
--- a/packages/ExternalStorageProvider/res/values-bn/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-bn/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"এক্সটারনাল স্টোরেজ"</string>
-    <string name="storage_description" msgid="8541974407321172792">"স্থানীয় স্টোরেজ"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"ইন্টারনাল স্টোরেজ"</string>
-    <string name="root_documents" msgid="4051252304075469250">"দস্তাবেজগুলি"</string>
+    <string name="app_label" msgid="748293919008814871">"এক্সটারনাল স্টোরেজ"</string>
+    <string name="storage_description" msgid="9176081505553938524">"স্থানীয় স্টোরেজ"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"ইন্টারনাল স্টোরেজ"</string>
+    <string name="root_documents" msgid="5695037589229175941">"দস্তাবেজগুলি"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-bs/strings.xml b/packages/ExternalStorageProvider/res/values-bs/strings.xml
index 1eb3020..2c42df7 100644
--- a/packages/ExternalStorageProvider/res/values-bs/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-bs/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Aplikacija za vanjsku pohranu"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Lokalna pohrana"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Interna pohrana"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
+    <string name="app_label" msgid="748293919008814871">"Aplikacija za vanjsku pohranu"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Lokalna pohrana"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Interna pohrana"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumenti"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-ca/strings.xml b/packages/ExternalStorageProvider/res/values-ca/strings.xml
index a67de7d..117a416 100644
--- a/packages/ExternalStorageProvider/res/values-ca/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ca/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Emmagatzematge extern"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Emmagatzematge local"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Emmagatzematge intern"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+    <string name="app_label" msgid="748293919008814871">"Emmagatzematge extern"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Emmagatzematge local"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Emmagatzematge intern"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-cs/strings.xml b/packages/ExternalStorageProvider/res/values-cs/strings.xml
index b9c54b8..761533d 100644
--- a/packages/ExternalStorageProvider/res/values-cs/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-cs/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Externí úložiště"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Místní úložiště"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Interní úložiště"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumenty"</string>
+    <string name="app_label" msgid="748293919008814871">"Externí úložiště"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Místní úložiště"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Interní úložiště"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumenty"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-da/strings.xml b/packages/ExternalStorageProvider/res/values-da/strings.xml
index 4da1419..9d89c80 100644
--- a/packages/ExternalStorageProvider/res/values-da/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-da/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Ekstern lagerplads"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Lokalt lager"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Intern lagerplads"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumenter"</string>
+    <string name="app_label" msgid="748293919008814871">"Ekstern lagerplads"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Lokalt lager"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Intern lagerplads"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumenter"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-de/strings.xml b/packages/ExternalStorageProvider/res/values-de/strings.xml
index 846152b..cb22276 100644
--- a/packages/ExternalStorageProvider/res/values-de/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-de/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Externer Speicher"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Lokaler Speicher"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Interner Speicher"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumente"</string>
+    <string name="app_label" msgid="748293919008814871">"Externer Speicher"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Lokaler Speicher"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Interner Speicher"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumente"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-el/strings.xml b/packages/ExternalStorageProvider/res/values-el/strings.xml
index 1e78e53..02123db 100644
--- a/packages/ExternalStorageProvider/res/values-el/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-el/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Εξωτερικός αποθηκευτικός χώρος"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Τοπικός χώρος αποθήκευσης"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Εσωτερικός αποθηκευτικός χώρος"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Έγγραφα"</string>
+    <string name="app_label" msgid="748293919008814871">"Εξωτερικός αποθηκευτικός χώρος"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Τοπικός χώρος αποθήκευσης"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Εσωτερικός αποθηκευτικός χώρος"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Έγγραφα"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-en-rAU/strings.xml b/packages/ExternalStorageProvider/res/values-en-rAU/strings.xml
index beaaf0d..b6bdd4a 100644
--- a/packages/ExternalStorageProvider/res/values-en-rAU/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-en-rAU/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"External Storage"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Local storage"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+    <string name="app_label" msgid="748293919008814871">"External Storage"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Local storage"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Internal storage"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-en-rCA/strings.xml b/packages/ExternalStorageProvider/res/values-en-rCA/strings.xml
index beaaf0d..b6bdd4a 100644
--- a/packages/ExternalStorageProvider/res/values-en-rCA/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-en-rCA/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"External Storage"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Local storage"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+    <string name="app_label" msgid="748293919008814871">"External Storage"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Local storage"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Internal storage"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-en-rGB/strings.xml b/packages/ExternalStorageProvider/res/values-en-rGB/strings.xml
index beaaf0d..b6bdd4a 100644
--- a/packages/ExternalStorageProvider/res/values-en-rGB/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-en-rGB/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"External Storage"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Local storage"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+    <string name="app_label" msgid="748293919008814871">"External Storage"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Local storage"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Internal storage"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-en-rIN/strings.xml b/packages/ExternalStorageProvider/res/values-en-rIN/strings.xml
index beaaf0d..b6bdd4a 100644
--- a/packages/ExternalStorageProvider/res/values-en-rIN/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-en-rIN/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"External Storage"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Local storage"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+    <string name="app_label" msgid="748293919008814871">"External Storage"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Local storage"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Internal storage"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-en-rXC/strings.xml b/packages/ExternalStorageProvider/res/values-en-rXC/strings.xml
index 5034d21..afec109 100644
--- a/packages/ExternalStorageProvider/res/values-en-rXC/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-en-rXC/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎External Storage‎‏‎‎‏‎"</string>
-    <string name="storage_description" msgid="8541974407321172792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‎‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎Local storage‎‏‎‎‏‎"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‏‎Internal storage‎‏‎‎‏‎"</string>
-    <string name="root_documents" msgid="4051252304075469250">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‎‎Documents‎‏‎‎‏‎"</string>
+    <string name="app_label" msgid="748293919008814871">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‏‎External Storage‎‏‎‎‏‎"</string>
+    <string name="storage_description" msgid="9176081505553938524">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‏‎‏‎‎‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎Local storage‎‏‎‎‏‎"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‏‏‎‎‎‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎Internal storage‎‏‎‎‏‎"</string>
+    <string name="root_documents" msgid="5695037589229175941">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‏‏‎‎‎‏‎‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎Documents‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-es-rUS/strings.xml b/packages/ExternalStorageProvider/res/values-es-rUS/strings.xml
index 8262422..39392a5 100644
--- a/packages/ExternalStorageProvider/res/values-es-rUS/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-es-rUS/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Almacenamiento externo"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Almacenamiento local"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Almacenamiento interno"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+    <string name="app_label" msgid="748293919008814871">"Almacenamiento externo"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Almacenamiento local"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Almacenamiento interno"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documentos"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-es/strings.xml b/packages/ExternalStorageProvider/res/values-es/strings.xml
index 8262422..39392a5 100644
--- a/packages/ExternalStorageProvider/res/values-es/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-es/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Almacenamiento externo"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Almacenamiento local"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Almacenamiento interno"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+    <string name="app_label" msgid="748293919008814871">"Almacenamiento externo"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Almacenamiento local"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Almacenamiento interno"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documentos"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-et/strings.xml b/packages/ExternalStorageProvider/res/values-et/strings.xml
index 095202f..7bc135b 100644
--- a/packages/ExternalStorageProvider/res/values-et/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-et/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Väline talletusruum"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Kohalik salvestusruum"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Sisemine salvestusruum"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumendid"</string>
+    <string name="app_label" msgid="748293919008814871">"Väline talletusruum"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Kohalik salvestusruum"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Sisemine salvestusruum"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumendid"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-eu/strings.xml b/packages/ExternalStorageProvider/res/values-eu/strings.xml
index c0e8cdd..fb43894 100644
--- a/packages/ExternalStorageProvider/res/values-eu/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-eu/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Kanpoko memoria"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Biltegi lokala"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Barneko memoria"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumentuak"</string>
+    <string name="app_label" msgid="748293919008814871">"Kanpoko memoria"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Biltegi lokala"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Barneko memoria"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumentuak"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-fa/strings.xml b/packages/ExternalStorageProvider/res/values-fa/strings.xml
index 0de4d4d..9eabfd0 100644
--- a/packages/ExternalStorageProvider/res/values-fa/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-fa/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"حافظه خارجی"</string>
-    <string name="storage_description" msgid="8541974407321172792">"فضای ذخیره‌سازی محلی"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"حافظهٔ داخلی"</string>
-    <string name="root_documents" msgid="4051252304075469250">"اسناد"</string>
+    <string name="app_label" msgid="748293919008814871">"حافظه خارجی"</string>
+    <string name="storage_description" msgid="9176081505553938524">"فضای ذخیره‌سازی محلی"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"حافظهٔ داخلی"</string>
+    <string name="root_documents" msgid="5695037589229175941">"اسناد"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-fi/strings.xml b/packages/ExternalStorageProvider/res/values-fi/strings.xml
index 6619568..bbb1c4f 100644
--- a/packages/ExternalStorageProvider/res/values-fi/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-fi/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Ulkoinen tallennustila"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Paikallinen tallennustila"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Sisäinen tallennustila"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumentit"</string>
+    <string name="app_label" msgid="748293919008814871">"Ulkoinen tallennustila"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Paikallinen tallennustila"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Sisäinen tallennustila"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumentit"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-fr-rCA/strings.xml b/packages/ExternalStorageProvider/res/values-fr-rCA/strings.xml
index e1e8f17..6c07457 100644
--- a/packages/ExternalStorageProvider/res/values-fr-rCA/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-fr-rCA/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Stockage externe"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Stockage local"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Mémoire de stockage interne"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+    <string name="app_label" msgid="748293919008814871">"Stockage externe"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Stockage local"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Mémoire de stockage interne"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-fr/strings.xml b/packages/ExternalStorageProvider/res/values-fr/strings.xml
index e1e8f17..6c07457 100644
--- a/packages/ExternalStorageProvider/res/values-fr/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-fr/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Stockage externe"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Stockage local"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Mémoire de stockage interne"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+    <string name="app_label" msgid="748293919008814871">"Stockage externe"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Stockage local"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Mémoire de stockage interne"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documents"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-gl/strings.xml b/packages/ExternalStorageProvider/res/values-gl/strings.xml
index eeb2f51..91d9571 100644
--- a/packages/ExternalStorageProvider/res/values-gl/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-gl/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Almacenamento externo"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Almacenamento local"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Almacenamento interno"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+    <string name="app_label" msgid="748293919008814871">"Almacenamento externo"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Almacenamento local"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Almacenamento interno"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documentos"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-gu/strings.xml b/packages/ExternalStorageProvider/res/values-gu/strings.xml
index 3f59dd3..fc9a34d 100644
--- a/packages/ExternalStorageProvider/res/values-gu/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-gu/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"બાહ્ય સંગ્રહ"</string>
-    <string name="storage_description" msgid="8541974407321172792">"સ્થાનિક સ્ટોરેજ"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"આંતરિક સ્ટોરેજ"</string>
-    <string name="root_documents" msgid="4051252304075469250">"દસ્તાવેજો"</string>
+    <string name="app_label" msgid="748293919008814871">"બાહ્ય સંગ્રહ"</string>
+    <string name="storage_description" msgid="9176081505553938524">"સ્થાનિક સ્ટોરેજ"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"આંતરિક સ્ટોરેજ"</string>
+    <string name="root_documents" msgid="5695037589229175941">"દસ્તાવેજો"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-hi/strings.xml b/packages/ExternalStorageProvider/res/values-hi/strings.xml
index f424871..76f27ff 100644
--- a/packages/ExternalStorageProvider/res/values-hi/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-hi/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"बाहरी मेमोरी"</string>
-    <string name="storage_description" msgid="8541974407321172792">"स्थानीय जगह"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"मोबाइल मेमोरी"</string>
-    <string name="root_documents" msgid="4051252304075469250">"दस्तावेज़"</string>
+    <string name="app_label" msgid="748293919008814871">"बाहरी मेमोरी"</string>
+    <string name="storage_description" msgid="9176081505553938524">"स्थानीय जगह"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"मोबाइल मेमोरी"</string>
+    <string name="root_documents" msgid="5695037589229175941">"दस्तावेज़"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-hr/strings.xml b/packages/ExternalStorageProvider/res/values-hr/strings.xml
index 1dd696e..bf0ad0c 100644
--- a/packages/ExternalStorageProvider/res/values-hr/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-hr/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Vanjska pohrana"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Lokalna pohrana"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Unutarnja pohrana"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
+    <string name="app_label" msgid="748293919008814871">"Vanjska pohrana"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Lokalna pohrana"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Unutarnja pohrana"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumenti"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-hu/strings.xml b/packages/ExternalStorageProvider/res/values-hu/strings.xml
index 8201630..021a8bb 100644
--- a/packages/ExternalStorageProvider/res/values-hu/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-hu/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Külső tárhely"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Helyi tárhely"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Belső tárhely"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumentumok"</string>
+    <string name="app_label" msgid="748293919008814871">"Külső tárhely"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Helyi tárhely"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Belső tárhely"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumentumok"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-hy/strings.xml b/packages/ExternalStorageProvider/res/values-hy/strings.xml
index b8c2ea7..b846d28 100644
--- a/packages/ExternalStorageProvider/res/values-hy/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-hy/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Արտաքին պահոց"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Սարքի հիշողություն"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Ներքին պահոց"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Փաստաթղթեր"</string>
+    <string name="app_label" msgid="748293919008814871">"Արտաքին պահոց"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Սարքի հիշողություն"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Ներքին պահոց"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Փաստաթղթեր"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-in/strings.xml b/packages/ExternalStorageProvider/res/values-in/strings.xml
index f91d1a5..950e906 100644
--- a/packages/ExternalStorageProvider/res/values-in/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-in/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Penyimpanan Eksternal"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Penyimpanan lokal"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Penyimpanan internal"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumen"</string>
+    <string name="app_label" msgid="748293919008814871">"Penyimpanan Eksternal"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Penyimpanan lokal"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Penyimpanan internal"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumen"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-is/strings.xml b/packages/ExternalStorageProvider/res/values-is/strings.xml
index adaf0d4..cac2edb 100644
--- a/packages/ExternalStorageProvider/res/values-is/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-is/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Ytri geymsla"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Staðbundin vistun"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Innbyggð geymsla"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Skjöl"</string>
+    <string name="app_label" msgid="748293919008814871">"Ytri geymsla"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Staðbundin vistun"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Innbyggð geymsla"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Skjöl"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-it/strings.xml b/packages/ExternalStorageProvider/res/values-it/strings.xml
index 35ba7f3..3a59bed 100644
--- a/packages/ExternalStorageProvider/res/values-it/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-it/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Archivio esterno"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Archiviazione locale"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Memoria interna"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documenti"</string>
+    <string name="app_label" msgid="748293919008814871">"Archivio esterno"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Archiviazione locale"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Memoria interna"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documenti"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-iw/strings.xml b/packages/ExternalStorageProvider/res/values-iw/strings.xml
index f98f439..3027a40 100644
--- a/packages/ExternalStorageProvider/res/values-iw/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-iw/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"אחסון חיצוני"</string>
-    <string name="storage_description" msgid="8541974407321172792">"אחסון מקומי"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"אחסון פנימי"</string>
-    <string name="root_documents" msgid="4051252304075469250">"מסמכים"</string>
+    <string name="app_label" msgid="748293919008814871">"אחסון חיצוני"</string>
+    <string name="storage_description" msgid="9176081505553938524">"אחסון מקומי"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"אחסון פנימי"</string>
+    <string name="root_documents" msgid="5695037589229175941">"מסמכים"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-ja/strings.xml b/packages/ExternalStorageProvider/res/values-ja/strings.xml
index c1623d4..ad04123 100644
--- a/packages/ExternalStorageProvider/res/values-ja/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ja/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"外部ストレージ"</string>
-    <string name="storage_description" msgid="8541974407321172792">"ローカル ストレージ"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"内部ストレージ"</string>
-    <string name="root_documents" msgid="4051252304075469250">"ドキュメント"</string>
+    <string name="app_label" msgid="748293919008814871">"外部ストレージ"</string>
+    <string name="storage_description" msgid="9176081505553938524">"ローカル ストレージ"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"内部ストレージ"</string>
+    <string name="root_documents" msgid="5695037589229175941">"ドキュメント"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-ka/strings.xml b/packages/ExternalStorageProvider/res/values-ka/strings.xml
index 3886efa..e320aca 100644
--- a/packages/ExternalStorageProvider/res/values-ka/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ka/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"გარე მეხსიერება"</string>
-    <string name="storage_description" msgid="8541974407321172792">"ადგილობრივი მეხსიერება"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"შიდა მეხსიერება"</string>
-    <string name="root_documents" msgid="4051252304075469250">"დოკუმენტები"</string>
+    <string name="app_label" msgid="748293919008814871">"გარე მეხსიერება"</string>
+    <string name="storage_description" msgid="9176081505553938524">"ადგილობრივი მეხსიერება"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"შიდა მეხსიერება"</string>
+    <string name="root_documents" msgid="5695037589229175941">"დოკუმენტები"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-kk/strings.xml b/packages/ExternalStorageProvider/res/values-kk/strings.xml
index f6ad94d..825b2d1 100644
--- a/packages/ExternalStorageProvider/res/values-kk/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-kk/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Сыртқы жад"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Жергілікті жад"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Ішкі жад"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Құжаттар"</string>
+    <string name="app_label" msgid="748293919008814871">"Сыртқы жад"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Жергілікті жад"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Ішкі жад"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Құжаттар"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-km/strings.xml b/packages/ExternalStorageProvider/res/values-km/strings.xml
index a2bb928..cd87a055 100644
--- a/packages/ExternalStorageProvider/res/values-km/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-km/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"ឧបករណ៍​​ផ្ទុក​ខាងក្រៅ"</string>
-    <string name="storage_description" msgid="8541974407321172792">"ទំហំផ្ទុកមូលដ្ឋាន"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង"</string>
-    <string name="root_documents" msgid="4051252304075469250">"ឯកសារ"</string>
+    <string name="app_label" msgid="748293919008814871">"ឧបករណ៍​​ផ្ទុក​ខាងក្រៅ"</string>
+    <string name="storage_description" msgid="9176081505553938524">"ទំហំផ្ទុកមូលដ្ឋាន"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"ឧបករណ៍​ផ្ទុក​ខាង​ក្នុង"</string>
+    <string name="root_documents" msgid="5695037589229175941">"ឯកសារ"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-kn/strings.xml b/packages/ExternalStorageProvider/res/values-kn/strings.xml
index 2883e06..fe35079 100644
--- a/packages/ExternalStorageProvider/res/values-kn/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-kn/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"ಬಾಹ್ಯ ಸಂಗ್ರಹಣೆ"</string>
-    <string name="storage_description" msgid="8541974407321172792">"ಸ್ಥಳೀಯ ಸಂಗ್ರಹಣೆ"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"ಆಂತರಿಕ ಸಂಗ್ರಹಣೆ"</string>
-    <string name="root_documents" msgid="4051252304075469250">"ಡಾಕ್ಯುಮೆಂಟ್‌ಗಳು"</string>
+    <string name="app_label" msgid="748293919008814871">"ಬಾಹ್ಯ ಸಂಗ್ರಹಣೆ"</string>
+    <string name="storage_description" msgid="9176081505553938524">"ಸ್ಥಳೀಯ ಸಂಗ್ರಹಣೆ"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"ಆಂತರಿಕ ಸಂಗ್ರಹಣೆ"</string>
+    <string name="root_documents" msgid="5695037589229175941">"ಡಾಕ್ಯುಮೆಂಟ್‌ಗಳು"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-ko/strings.xml b/packages/ExternalStorageProvider/res/values-ko/strings.xml
index 1fa3189..6a255eb 100644
--- a/packages/ExternalStorageProvider/res/values-ko/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ko/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"외부 저장소"</string>
-    <string name="storage_description" msgid="8541974407321172792">"로컬 저장소"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"내부 저장소"</string>
-    <string name="root_documents" msgid="4051252304075469250">"문서"</string>
+    <string name="app_label" msgid="748293919008814871">"외부 저장소"</string>
+    <string name="storage_description" msgid="9176081505553938524">"로컬 저장소"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"내부 저장소"</string>
+    <string name="root_documents" msgid="5695037589229175941">"문서"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-ky/strings.xml b/packages/ExternalStorageProvider/res/values-ky/strings.xml
index e7e34cb..d11daec 100644
--- a/packages/ExternalStorageProvider/res/values-ky/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ky/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Тышкы сактагыч"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Жергиликтүү сактагыч"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Ички сактагыч"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Документтер"</string>
+    <string name="app_label" msgid="748293919008814871">"Тышкы сактагыч"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Жергиликтүү сактагыч"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Ички сактагыч"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Документтер"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-lo/strings.xml b/packages/ExternalStorageProvider/res/values-lo/strings.xml
index ba344e3..26f7a6e 100644
--- a/packages/ExternalStorageProvider/res/values-lo/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-lo/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"ບ່ອນຈັດເກັບຂໍ້ມູນພາຍນອກ"</string>
-    <string name="storage_description" msgid="8541974407321172792">"ບ່ອນຈັດເກັບຂໍ້ມູນໃນເຄື່ອງ"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"ບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
-    <string name="root_documents" msgid="4051252304075469250">"ເອ​ກະ​ສານ"</string>
+    <string name="app_label" msgid="748293919008814871">"ບ່ອນຈັດເກັບຂໍ້ມູນພາຍນອກ"</string>
+    <string name="storage_description" msgid="9176081505553938524">"ບ່ອນຈັດເກັບຂໍ້ມູນໃນເຄື່ອງ"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"ບ່ອນຈັດເກັບຂໍ້ມູນພາຍໃນ"</string>
+    <string name="root_documents" msgid="5695037589229175941">"ເອ​ກະ​ສານ"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-lt/strings.xml b/packages/ExternalStorageProvider/res/values-lt/strings.xml
index a345673..beca24e 100644
--- a/packages/ExternalStorageProvider/res/values-lt/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-lt/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Išorinė atmintinė"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Vietinė saugykla"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Vidinė atmintinė"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumentai"</string>
+    <string name="app_label" msgid="748293919008814871">"Išorinė atmintinė"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Vietinė saugykla"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Vidinė atmintinė"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumentai"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-lv/strings.xml b/packages/ExternalStorageProvider/res/values-lv/strings.xml
index a3a3ed8..9e362c4 100644
--- a/packages/ExternalStorageProvider/res/values-lv/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-lv/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Ārējā krātuve"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Lokālā krātuve"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Iekšējā atmiņa"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
+    <string name="app_label" msgid="748293919008814871">"Ārējā krātuve"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Lokālā krātuve"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Iekšējā atmiņa"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumenti"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-mk/strings.xml b/packages/ExternalStorageProvider/res/values-mk/strings.xml
index 5ebf8a6..76c6d91 100644
--- a/packages/ExternalStorageProvider/res/values-mk/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-mk/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Надворешна меморија"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Локална меморија"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Внатрешен капацитет"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Документи"</string>
+    <string name="app_label" msgid="748293919008814871">"Надворешна меморија"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Локална меморија"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Внатрешен капацитет"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Документи"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-ml/strings.xml b/packages/ExternalStorageProvider/res/values-ml/strings.xml
index 2f88c79..fab3f16 100644
--- a/packages/ExternalStorageProvider/res/values-ml/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ml/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"ബാഹ്യ സ്റ്റോറേജ്"</string>
-    <string name="storage_description" msgid="8541974407321172792">"ലോക്കൽ സ്റ്റോറേജ്"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"ആന്തരിക സ്റ്റോറേജ്"</string>
-    <string name="root_documents" msgid="4051252304075469250">"പ്രമാണങ്ങൾ"</string>
+    <string name="app_label" msgid="748293919008814871">"ബാഹ്യ സ്റ്റോറേജ്"</string>
+    <string name="storage_description" msgid="9176081505553938524">"ലോക്കൽ സ്റ്റോറേജ്"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"ആന്തരിക സ്റ്റോറേജ്"</string>
+    <string name="root_documents" msgid="5695037589229175941">"പ്രമാണങ്ങൾ"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-mn/strings.xml b/packages/ExternalStorageProvider/res/values-mn/strings.xml
index afd5d64..e227b7e 100644
--- a/packages/ExternalStorageProvider/res/values-mn/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-mn/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Гадаад сан"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Дотоод сан"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Дотоод сан"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Документүүд"</string>
+    <string name="app_label" msgid="748293919008814871">"Гадаад сан"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Дотоод сан"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Дотоод сан"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Документүүд"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-mr/strings.xml b/packages/ExternalStorageProvider/res/values-mr/strings.xml
index 7927440..3059610 100644
--- a/packages/ExternalStorageProvider/res/values-mr/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-mr/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"बाह्य संचयन"</string>
-    <string name="storage_description" msgid="8541974407321172792">"स्थानिक स्टोरेज"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"अंतर्गत स्टोरेज"</string>
-    <string name="root_documents" msgid="4051252304075469250">"दस्तऐवज"</string>
+    <string name="app_label" msgid="748293919008814871">"बाह्य संचयन"</string>
+    <string name="storage_description" msgid="9176081505553938524">"स्थानिक स्टोरेज"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"अंतर्गत स्टोरेज"</string>
+    <string name="root_documents" msgid="5695037589229175941">"दस्तऐवज"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-ms/strings.xml b/packages/ExternalStorageProvider/res/values-ms/strings.xml
index 4196acd..ebc3ce2 100644
--- a/packages/ExternalStorageProvider/res/values-ms/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ms/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Storan Luaran"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Storan setempat"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Storan dalaman"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumen"</string>
+    <string name="app_label" msgid="748293919008814871">"Storan Luaran"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Storan setempat"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Storan dalaman"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumen"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-my/strings.xml b/packages/ExternalStorageProvider/res/values-my/strings.xml
index 1c7a276..6078194 100644
--- a/packages/ExternalStorageProvider/res/values-my/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-my/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"ပြင်ပသိုလှောင်ရာပစ္စည်း"</string>
-    <string name="storage_description" msgid="8541974407321172792">"စက်တွင်း သိုလှောင်ခန်း"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"စက်တွင်း သိုလှောင်ထားမှု"</string>
-    <string name="root_documents" msgid="4051252304075469250">"စာရွက်စာတန်းများ"</string>
+    <string name="app_label" msgid="748293919008814871">"ပြင်ပသိုလှောင်ရာပစ္စည်း"</string>
+    <string name="storage_description" msgid="9176081505553938524">"စက်တွင်း သိုလှောင်ခန်း"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"စက်တွင်း သိုလှောင်ထားမှု"</string>
+    <string name="root_documents" msgid="5695037589229175941">"စာရွက်စာတန်းများ"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-nb/strings.xml b/packages/ExternalStorageProvider/res/values-nb/strings.xml
index 979cb30..1992f72 100644
--- a/packages/ExternalStorageProvider/res/values-nb/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-nb/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Ekstern lagring"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Lokal lagring"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Intern lagring"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumenter"</string>
+    <string name="app_label" msgid="748293919008814871">"Ekstern lagring"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Lokal lagring"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Intern lagring"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumenter"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-ne/strings.xml b/packages/ExternalStorageProvider/res/values-ne/strings.xml
index bbe9c42..bc8871c 100644
--- a/packages/ExternalStorageProvider/res/values-ne/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ne/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"बाह्य भण्डारण"</string>
-    <string name="storage_description" msgid="8541974407321172792">"स्थानीय भण्डारण"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"आन्तरिक भण्डारण"</string>
-    <string name="root_documents" msgid="4051252304075469250">"कागजातहरू"</string>
+    <string name="app_label" msgid="748293919008814871">"बाह्य भण्डारण"</string>
+    <string name="storage_description" msgid="9176081505553938524">"स्थानीय भण्डारण"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"आन्तरिक भण्डारण"</string>
+    <string name="root_documents" msgid="5695037589229175941">"कागजातहरू"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-nl/strings.xml b/packages/ExternalStorageProvider/res/values-nl/strings.xml
index cea2e9c..455ea50 100644
--- a/packages/ExternalStorageProvider/res/values-nl/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-nl/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Externe opslag"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Lokale opslag"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Interne opslag"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documenten"</string>
+    <string name="app_label" msgid="748293919008814871">"Externe opslag"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Lokale opslag"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Interne opslag"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documenten"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-or/strings.xml b/packages/ExternalStorageProvider/res/values-or/strings.xml
index 5387dc7..ba9b811 100644
--- a/packages/ExternalStorageProvider/res/values-or/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-or/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"ଏକ୍ସଟର୍ନଲ୍‌ ଷ୍ଟୋରେଜ୍‌"</string>
-    <string name="storage_description" msgid="8541974407321172792">"ଲୋକାଲ୍‍ ଷ୍ଟୋରେଜ୍‍"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"ଇଣ୍ଟର୍ନଲ୍‌ ଷ୍ଟୋରେଜ୍‌"</string>
-    <string name="root_documents" msgid="4051252304075469250">"ଡକ୍ୟୁମେଣ୍ଟ"</string>
+    <string name="app_label" msgid="748293919008814871">"ଏକ୍ସଟର୍ନଲ୍‌ ଷ୍ଟୋରେଜ୍‌"</string>
+    <string name="storage_description" msgid="9176081505553938524">"ଲୋକାଲ୍‍ ଷ୍ଟୋରେଜ୍‍"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"ଇଣ୍ଟର୍ନଲ୍‌ ଷ୍ଟୋରେଜ୍‌"</string>
+    <string name="root_documents" msgid="5695037589229175941">"ଡକ୍ୟୁମେଣ୍ଟ"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-pa/strings.xml b/packages/ExternalStorageProvider/res/values-pa/strings.xml
index 4e9d777..becd075 100644
--- a/packages/ExternalStorageProvider/res/values-pa/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-pa/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"ਬਾਹਰੀ ਸਟੋਰੇਜ"</string>
-    <string name="storage_description" msgid="8541974407321172792">"ਸਥਾਨਕ ਸਟੋਰੇਜ"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"ਅੰਦਰੂਨੀ ਸਟੋਰੇਜ"</string>
-    <string name="root_documents" msgid="4051252304075469250">"ਦਸਤਾਵੇਜ਼"</string>
+    <string name="app_label" msgid="748293919008814871">"ਬਾਹਰੀ ਸਟੋਰੇਜ"</string>
+    <string name="storage_description" msgid="9176081505553938524">"ਸਥਾਨਕ ਸਟੋਰੇਜ"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"ਅੰਦਰੂਨੀ ਸਟੋਰੇਜ"</string>
+    <string name="root_documents" msgid="5695037589229175941">"ਦਸਤਾਵੇਜ਼"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-pl/strings.xml b/packages/ExternalStorageProvider/res/values-pl/strings.xml
index f710bad..885f25c 100644
--- a/packages/ExternalStorageProvider/res/values-pl/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-pl/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Pamięć zewnętrzna"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Pamięć lokalna"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Pamięć wewnętrzna"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumenty"</string>
+    <string name="app_label" msgid="748293919008814871">"Pamięć zewnętrzna"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Pamięć lokalna"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Pamięć wewnętrzna"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumenty"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-pt-rBR/strings.xml b/packages/ExternalStorageProvider/res/values-pt-rBR/strings.xml
index 96046ad..aa745f1 100644
--- a/packages/ExternalStorageProvider/res/values-pt-rBR/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-pt-rBR/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Armazenamento externo"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Armazenamento local"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Armazenamento interno"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+    <string name="app_label" msgid="748293919008814871">"Armazenamento externo"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Armazenamento local"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Armazenamento interno"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documentos"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml b/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml
index 35de8ef..9683b4c 100644
--- a/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-pt-rPT/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Armazenamento externo"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Armazenamento local"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Armazenamento interno"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Docs"</string>
+    <string name="app_label" msgid="748293919008814871">"Armazenamento externo"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Armazenamento local"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Armazenamento interno"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Docs"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-pt/strings.xml b/packages/ExternalStorageProvider/res/values-pt/strings.xml
index 96046ad..aa745f1 100644
--- a/packages/ExternalStorageProvider/res/values-pt/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-pt/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Armazenamento externo"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Armazenamento local"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Armazenamento interno"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+    <string name="app_label" msgid="748293919008814871">"Armazenamento externo"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Armazenamento local"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Armazenamento interno"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documentos"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-ro/strings.xml b/packages/ExternalStorageProvider/res/values-ro/strings.xml
index aaa9e41..d060654 100644
--- a/packages/ExternalStorageProvider/res/values-ro/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ro/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Stocare externă"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Stocare locală"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Stocare internă"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Documente"</string>
+    <string name="app_label" msgid="748293919008814871">"Stocare externă"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Stocare locală"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Stocare internă"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Documente"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-ru/strings.xml b/packages/ExternalStorageProvider/res/values-ru/strings.xml
index 222532f..55a7550 100644
--- a/packages/ExternalStorageProvider/res/values-ru/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ru/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Внешний накопитель"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Локальное хранилище"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Внутренний накопитель"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Документы"</string>
+    <string name="app_label" msgid="748293919008814871">"Внешний накопитель"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Локальное хранилище"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Внутренний накопитель"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Документы"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-si/strings.xml b/packages/ExternalStorageProvider/res/values-si/strings.xml
index 1adebec..deaa65f 100644
--- a/packages/ExternalStorageProvider/res/values-si/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-si/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"බාහිර ආචයනය"</string>
-    <string name="storage_description" msgid="8541974407321172792">"පෙදෙසි ආචයනය"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"අභ්‍යන්තර ආචයනය"</string>
-    <string name="root_documents" msgid="4051252304075469250">"ලේඛන"</string>
+    <string name="app_label" msgid="748293919008814871">"බාහිර ආචයනය"</string>
+    <string name="storage_description" msgid="9176081505553938524">"පෙදෙසි ආචයනය"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"අභ්‍යන්තර ආචයනය"</string>
+    <string name="root_documents" msgid="5695037589229175941">"ලේඛන"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-sk/strings.xml b/packages/ExternalStorageProvider/res/values-sk/strings.xml
index f94a726..b51210f 100644
--- a/packages/ExternalStorageProvider/res/values-sk/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-sk/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Externý ukladací priestor"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Miestne úložisko"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Interné úložisko"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumenty"</string>
+    <string name="app_label" msgid="748293919008814871">"Externý ukladací priestor"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Miestne úložisko"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Interné úložisko"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumenty"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-sl/strings.xml b/packages/ExternalStorageProvider/res/values-sl/strings.xml
index 7992e97..262c2b7 100644
--- a/packages/ExternalStorageProvider/res/values-sl/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-sl/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Zunanja shramba"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Lokalna shramba"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Notranja shramba"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
+    <string name="app_label" msgid="748293919008814871">"Zunanja shramba"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Lokalna shramba"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Notranja shramba"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumenti"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-sq/strings.xml b/packages/ExternalStorageProvider/res/values-sq/strings.xml
index f73cff1..2a5c557 100644
--- a/packages/ExternalStorageProvider/res/values-sq/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-sq/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Hapësirë e jashtme ruajtjeje"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Hapësira ruajtëse lokale"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Hapësira e brendshme ruajtëse"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokumente"</string>
+    <string name="app_label" msgid="748293919008814871">"Hapësirë e jashtme ruajtjeje"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Hapësira ruajtëse lokale"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Hapësira e brendshme ruajtëse"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokumente"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-sr/strings.xml b/packages/ExternalStorageProvider/res/values-sr/strings.xml
index 6a7be4c..b44ce18 100644
--- a/packages/ExternalStorageProvider/res/values-sr/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-sr/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Спољна меморија"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Локални меморијски простор"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Интерна меморија"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Документи"</string>
+    <string name="app_label" msgid="748293919008814871">"Спољна меморија"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Локални меморијски простор"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Интерна меморија"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Документи"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-sv/strings.xml b/packages/ExternalStorageProvider/res/values-sv/strings.xml
index 103e830..11afb19 100644
--- a/packages/ExternalStorageProvider/res/values-sv/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-sv/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Extern lagring"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Lokal lagring"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Intern lagring"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokument"</string>
+    <string name="app_label" msgid="748293919008814871">"Extern lagring"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Lokal lagring"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Intern lagring"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokument"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-sw/strings.xml b/packages/ExternalStorageProvider/res/values-sw/strings.xml
index fec928c..94231ff 100644
--- a/packages/ExternalStorageProvider/res/values-sw/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-sw/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Hifadhi ya Nje"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Hifadhi ya ndani"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Hifadhi ya ndani"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Hati"</string>
+    <string name="app_label" msgid="748293919008814871">"Hifadhi ya Nje"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Hifadhi ya ndani"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Hifadhi ya ndani"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Hati"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-ta/strings.xml b/packages/ExternalStorageProvider/res/values-ta/strings.xml
index 5d56940..1f25d9e 100644
--- a/packages/ExternalStorageProvider/res/values-ta/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ta/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"வெளிப்புறச் சேமிப்பிடம்"</string>
-    <string name="storage_description" msgid="8541974407321172792">"சாதனச் சேமிப்பகம்"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"அகச் சேமிப்பிடம்"</string>
-    <string name="root_documents" msgid="4051252304075469250">"ஆவணங்கள்"</string>
+    <string name="app_label" msgid="748293919008814871">"வெளிப்புறச் சேமிப்பிடம்"</string>
+    <string name="storage_description" msgid="9176081505553938524">"சாதனச் சேமிப்பகம்"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"அகச் சேமிப்பிடம்"</string>
+    <string name="root_documents" msgid="5695037589229175941">"ஆவணங்கள்"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-te/strings.xml b/packages/ExternalStorageProvider/res/values-te/strings.xml
index 97ca29d..773ae0e 100644
--- a/packages/ExternalStorageProvider/res/values-te/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-te/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"బాహ్య నిల్వ"</string>
-    <string name="storage_description" msgid="8541974407321172792">"స్థానిక నిల్వ"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"అంతర్గత నిల్వ"</string>
-    <string name="root_documents" msgid="4051252304075469250">"పత్రాలు"</string>
+    <string name="app_label" msgid="748293919008814871">"బాహ్య నిల్వ"</string>
+    <string name="storage_description" msgid="9176081505553938524">"స్థానిక నిల్వ"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"అంతర్గత నిల్వ"</string>
+    <string name="root_documents" msgid="5695037589229175941">"పత్రాలు"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-th/strings.xml b/packages/ExternalStorageProvider/res/values-th/strings.xml
index 3a3304f..570a91a 100644
--- a/packages/ExternalStorageProvider/res/values-th/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-th/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"ที่จัดเก็บข้อมูลภายนอก"</string>
-    <string name="storage_description" msgid="8541974407321172792">"พื้นที่เก็บข้อมูลในเครื่อง"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"ที่จัดเก็บข้อมูลภายใน"</string>
-    <string name="root_documents" msgid="4051252304075469250">"เอกสาร"</string>
+    <string name="app_label" msgid="748293919008814871">"ที่จัดเก็บข้อมูลภายนอก"</string>
+    <string name="storage_description" msgid="9176081505553938524">"พื้นที่เก็บข้อมูลในเครื่อง"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"ที่จัดเก็บข้อมูลภายใน"</string>
+    <string name="root_documents" msgid="5695037589229175941">"เอกสาร"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-tl/strings.xml b/packages/ExternalStorageProvider/res/values-tl/strings.xml
index 7b66436d6..0a35373 100644
--- a/packages/ExternalStorageProvider/res/values-tl/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-tl/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"External Storage"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Lokal na storage"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Internal storage"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Mga Dokumento"</string>
+    <string name="app_label" msgid="748293919008814871">"External Storage"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Lokal na storage"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Internal storage"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Mga Dokumento"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-tr/strings.xml b/packages/ExternalStorageProvider/res/values-tr/strings.xml
index 39cd4da..2e35805 100644
--- a/packages/ExternalStorageProvider/res/values-tr/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-tr/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Harici Depolama"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Yerel depolama"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Dahili depolama"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Dokümanlar"</string>
+    <string name="app_label" msgid="748293919008814871">"Harici Depolama"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Yerel depolama"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Dahili depolama"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Dokümanlar"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-uk/strings.xml b/packages/ExternalStorageProvider/res/values-uk/strings.xml
index 25acf03..f01ad81 100644
--- a/packages/ExternalStorageProvider/res/values-uk/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-uk/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Зовнішня пам’ять"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Локальна пам’ять"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Внутрішня пам’ять"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Документи"</string>
+    <string name="app_label" msgid="748293919008814871">"Зовнішня пам’ять"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Локальна пам’ять"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Внутрішня пам’ять"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Документи"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-ur/strings.xml b/packages/ExternalStorageProvider/res/values-ur/strings.xml
index c22afd9..1aafdd9 100644
--- a/packages/ExternalStorageProvider/res/values-ur/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-ur/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"بیرونی اسٹوریج"</string>
-    <string name="storage_description" msgid="8541974407321172792">"مقامی اسٹوریج"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"داخلی اسٹوریج"</string>
-    <string name="root_documents" msgid="4051252304075469250">"دستاویزات"</string>
+    <string name="app_label" msgid="748293919008814871">"بیرونی اسٹوریج"</string>
+    <string name="storage_description" msgid="9176081505553938524">"مقامی اسٹوریج"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"داخلی اسٹوریج"</string>
+    <string name="root_documents" msgid="5695037589229175941">"دستاویزات"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-uz/strings.xml b/packages/ExternalStorageProvider/res/values-uz/strings.xml
index 48f8fed..87ab668 100644
--- a/packages/ExternalStorageProvider/res/values-uz/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-uz/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Tashqi xotira"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Mahalliy xotira"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Ichki xotira"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Hujjatlar"</string>
+    <string name="app_label" msgid="748293919008814871">"Tashqi xotira"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Mahalliy xotira"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Ichki xotira"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Hujjatlar"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-vi/strings.xml b/packages/ExternalStorageProvider/res/values-vi/strings.xml
index f7479c0..e898d2c 100644
--- a/packages/ExternalStorageProvider/res/values-vi/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-vi/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Bộ nhớ ngoài"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Bộ nhớ cục bộ"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Bộ nhớ trong"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Tài liệu"</string>
+    <string name="app_label" msgid="748293919008814871">"Bộ nhớ ngoài"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Bộ nhớ cục bộ"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Bộ nhớ trong"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Tài liệu"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-zh-rCN/strings.xml b/packages/ExternalStorageProvider/res/values-zh-rCN/strings.xml
index aa6789f..5be6132 100644
--- a/packages/ExternalStorageProvider/res/values-zh-rCN/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-zh-rCN/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"外部存储设备"</string>
-    <string name="storage_description" msgid="8541974407321172792">"本地存储空间"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"内部存储空间"</string>
-    <string name="root_documents" msgid="4051252304075469250">"文档"</string>
+    <string name="app_label" msgid="748293919008814871">"外部存储设备"</string>
+    <string name="storage_description" msgid="9176081505553938524">"本地存储空间"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"内部存储空间"</string>
+    <string name="root_documents" msgid="5695037589229175941">"文档"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-zh-rHK/strings.xml b/packages/ExternalStorageProvider/res/values-zh-rHK/strings.xml
index 3458c64..1671796 100644
--- a/packages/ExternalStorageProvider/res/values-zh-rHK/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-zh-rHK/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"外部儲存空間"</string>
-    <string name="storage_description" msgid="8541974407321172792">"本機儲存空間"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"內部儲存空間"</string>
-    <string name="root_documents" msgid="4051252304075469250">"文件"</string>
+    <string name="app_label" msgid="748293919008814871">"外部儲存空間"</string>
+    <string name="storage_description" msgid="9176081505553938524">"本機儲存空間"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"內部儲存空間"</string>
+    <string name="root_documents" msgid="5695037589229175941">"文件"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-zh-rTW/strings.xml b/packages/ExternalStorageProvider/res/values-zh-rTW/strings.xml
index 3458c64..1671796 100644
--- a/packages/ExternalStorageProvider/res/values-zh-rTW/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-zh-rTW/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"外部儲存空間"</string>
-    <string name="storage_description" msgid="8541974407321172792">"本機儲存空間"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"內部儲存空間"</string>
-    <string name="root_documents" msgid="4051252304075469250">"文件"</string>
+    <string name="app_label" msgid="748293919008814871">"外部儲存空間"</string>
+    <string name="storage_description" msgid="9176081505553938524">"本機儲存空間"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"內部儲存空間"</string>
+    <string name="root_documents" msgid="5695037589229175941">"文件"</string>
 </resources>
diff --git a/packages/ExternalStorageProvider/res/values-zu/strings.xml b/packages/ExternalStorageProvider/res/values-zu/strings.xml
index 96f454b..3878591 100644
--- a/packages/ExternalStorageProvider/res/values-zu/strings.xml
+++ b/packages/ExternalStorageProvider/res/values-zu/strings.xml
@@ -16,8 +16,8 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="7123375275748530234">"Isitoreji sangaphandle"</string>
-    <string name="storage_description" msgid="8541974407321172792">"Isitoreji sasendaweni"</string>
-    <string name="root_internal_storage" msgid="827844243068584127">"Isitoreji sangaphakathi"</string>
-    <string name="root_documents" msgid="4051252304075469250">"Amadokhumenti"</string>
+    <string name="app_label" msgid="748293919008814871">"Isitoreji sangaphandle"</string>
+    <string name="storage_description" msgid="9176081505553938524">"Isitoreji sasendaweni"</string>
+    <string name="root_internal_storage" msgid="4980477711224234931">"Isitoreji sangaphakathi"</string>
+    <string name="root_documents" msgid="5695037589229175941">"Amadokhumenti"</string>
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index 0d972c5..e660e43 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -150,7 +150,7 @@
                     context.getContentResolver().takePersistableUriPermission(iconUri,
                             Intent.FLAG_GRANT_READ_URI_PERMISSION);
                 } catch (SecurityException e) {
-                    Log.e(TAG, "Failed to take persistable permission for: " + iconUri);
+                    Log.e(TAG, "Failed to take persistable permission for: " + iconUri, e);
                 }
                 try {
                     final Bitmap bitmap = MediaStore.Images.Media.getBitmap(
@@ -165,6 +165,8 @@
                     }
                 } catch (IOException e) {
                     Log.e(TAG, "Failed to get drawable for: " + iconUri, e);
+                } catch (SecurityException e) {
+                    Log.e(TAG, "Failed to get permission for: " + iconUri, e);
                 }
             }
         }
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b288eb7..cd64a388 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -60,6 +60,9 @@
     <uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
     <uses-permission android:name="android.permission.USE_RESERVED_DISK" />
 
+    <!-- to invoke ContentSuggestionsService -->
+    <uses-permission android:name="android.permission.MANAGE_CONTENT_SUGGESTIONS"/>
+
     <!-- Networking and telephony -->
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
index 795a8ce3..c2d090e 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
@@ -15,12 +15,14 @@
 package com.android.systemui;
 
 import android.annotation.Nullable;
+import android.app.AppOpsManager;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.util.ArraySet;
 import android.util.SparseArray;
 
 import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.systemui.appops.AppOpsController;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
@@ -33,14 +35,21 @@
  */
 @Singleton
 public class ForegroundServiceController {
+    private static final int[] APP_OPS = new int[] {AppOpsManager.OP_CAMERA,
+            AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
+            AppOpsManager.OP_RECORD_AUDIO,
+            AppOpsManager.OP_COARSE_LOCATION,
+            AppOpsManager.OP_FINE_LOCATION};
 
     private final SparseArray<ForegroundServicesUserState> mUserServices = new SparseArray<>();
     private final Object mMutex = new Object();
     private final NotificationEntryManager mEntryManager;
 
     @Inject
-    public ForegroundServiceController(NotificationEntryManager entryManager) {
+    public ForegroundServiceController(NotificationEntryManager entryManager,
+            AppOpsController appOpsController) {
         mEntryManager = entryManager;
+        appOpsController.addCallback(APP_OPS, this::onAppOpChanged);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 0a547b6..0d400fe 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -33,6 +33,7 @@
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider;
 import com.android.systemui.statusbar.KeyguardIndicationController;
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
@@ -42,7 +43,6 @@
 import com.android.systemui.statusbar.phone.LockIcon;
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
 import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import dagger.Module;
@@ -119,9 +119,13 @@
         return mRootComponent;
     }
 
-    public StatusBarKeyguardViewManager createStatusBarKeyguardViewManager(Context context,
-            ViewMediatorCallback viewMediatorCallback, LockPatternUtils lockPatternUtils) {
-        return new StatusBarKeyguardViewManager(context, viewMediatorCallback, lockPatternUtils);
+    /**
+     * Creates an instance of ScreenshotNotificationSmartActionsProvider.
+     * This method is overridden in vendor specific implementation of Sys UI.
+     */
+    public ScreenshotNotificationSmartActionsProvider
+            createScreenshotNotificationSmartActionsProvider() {
+        return new ScreenshotNotificationSmartActionsProvider();
     }
 
     public KeyguardBouncer createKeyguardBouncer(Context context, ViewMediatorCallback callback,
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
index 24357a7..d50666c 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
@@ -27,6 +27,8 @@
 import android.util.ArrayMap
 import android.util.ArraySet
 import android.util.Log
+import androidx.annotation.MainThread
+import com.android.internal.util.Preconditions
 import com.android.systemui.Dumpable
 import java.io.FileDescriptor
 import java.io.PrintWriter
@@ -72,7 +74,14 @@
 
     internal fun isRegistered() = registered.get()
 
-    private val registerReceiver = Runnable {
+    // Only modify in BG thread
+    private val actionsToReceivers = ArrayMap<String, MutableSet<ReceiverData>>()
+    private val receiverToReceiverData = ArrayMap<BroadcastReceiver, MutableSet<ReceiverData>>()
+
+    // Only call on BG thread as it reads from the maps
+    private fun createFilter(): IntentFilter {
+        Preconditions.checkState(bgHandler.looper.isCurrentThread,
+                "This method should only be called from BG thread")
         val categories = mutableSetOf<String>()
         receiverToReceiverData.values.flatten().forEach {
             it.filter.categoriesIterator()?.asSequence()?.let {
@@ -80,30 +89,13 @@
             }
         }
         val intentFilter = IntentFilter().apply {
-            actionsToReceivers.keys.forEach { addAction(it) }
+            // The keys of the arrayMap are of type String! so null check is needed
+            actionsToReceivers.keys.forEach { if (it != null) addAction(it) else Unit }
             categories.forEach { addCategory(it) }
         }
-
-        if (registered.get()) {
-            context.unregisterReceiver(this)
-            registered.set(false)
-        }
-        // Short interval without receiver, this can be problematic
-        if (intentFilter.countActions() > 0 && !registered.get()) {
-            context.registerReceiverAsUser(
-                    this,
-                    UserHandle.of(userId),
-                    intentFilter,
-                    null,
-                    bgHandler)
-            registered.set(true)
-        }
+        return intentFilter
     }
 
-    // Only modify in BG thread
-    private val actionsToReceivers = ArrayMap<String, MutableSet<ReceiverData>>()
-    private val receiverToReceiverData = ArrayMap<BroadcastReceiver, MutableSet<ReceiverData>>()
-
     override fun onReceive(context: Context, intent: Intent) {
         val id = if (DEBUG) index.getAndIncrement() else 0
         if (DEBUG) Log.w(TAG, "[$id] Received $intent")
@@ -126,6 +118,8 @@
     }
 
     private fun handleRegisterReceiver(receiverData: ReceiverData) {
+        Preconditions.checkState(bgHandler.looper.isCurrentThread,
+                "This method should only be called from BG thread")
         if (DEBUG) Log.w(TAG, "Register receiver: ${receiverData.receiver}")
         receiverToReceiverData.getOrPut(receiverData.receiver, { ArraySet() }).add(receiverData)
         var changed = false
@@ -138,11 +132,13 @@
             }.add(receiverData)
         }
         if (changed) {
-            mainHandler.post(registerReceiver)
+            createFilterAndRegisterReceiverBG()
         }
     }
 
     private fun handleUnregisterReceiver(receiver: BroadcastReceiver) {
+        Preconditions.checkState(bgHandler.looper.isCurrentThread,
+                "This method should only be called from BG thread")
         if (DEBUG) Log.w(TAG, "Unregister receiver: $receiver")
         val actions = receiverToReceiverData.getOrElse(receiver) { return }
                 .flatMap { it.filter.actionsIterator().asSequence().asIterable() }.toSet()
@@ -156,10 +152,16 @@
             }
         }
         if (changed) {
-            mainHandler.post(registerReceiver)
+            createFilterAndRegisterReceiverBG()
         }
     }
 
+    // Only call this from a BG thread
+    private fun createFilterAndRegisterReceiverBG() {
+        val intentFilter = createFilter()
+        mainHandler.post(RegisterReceiverRunnable(intentFilter))
+    }
+
     override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
         pw.println("  Registered=${registered.get()}")
         actionsToReceivers.forEach { (action, list) ->
@@ -191,4 +193,30 @@
                     }
         }
     }
+
+    private inner class RegisterReceiverRunnable(val intentFilter: IntentFilter) : Runnable {
+
+        /*
+         * Registers and unregisters the BroadcastReceiver
+         *
+         * Must be called from Main Thread
+         */
+        @MainThread
+        override fun run() {
+            if (registered.get()) {
+                context.unregisterReceiver(this@UserBroadcastDispatcher)
+                registered.set(false)
+            }
+            // Short interval without receiver, this can be problematic
+            if (intentFilter.countActions() > 0 && !registered.get()) {
+                context.registerReceiverAsUser(
+                        this@UserBroadcastDispatcher,
+                        UserHandle.of(userId),
+                        intentFilter,
+                        null,
+                        bgHandler)
+                registered.set(true)
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 6d61b2f..741c95f 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -35,12 +35,14 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.BgHandler;
 import com.android.systemui.dagger.qualifiers.BgLooper;
 import com.android.systemui.dagger.qualifiers.MainHandler;
 import com.android.systemui.dagger.qualifiers.MainLooper;
 import com.android.systemui.doze.AlwaysOnDisplayPolicy;
+import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.plugins.PluginInitializerImpl;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.shared.plugins.PluginManagerImpl;
@@ -249,4 +251,10 @@
     public UserManager providesUserManager(Context context) {
         return context.getSystemService(UserManager.class);
     }
+
+    /** */
+    @Provides
+    public ViewMediatorCallback providesViewMediatorCallback(KeyguardViewMediator viewMediator) {
+        return viewMediator.getViewMediatorCallback();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index 9f54937..3cf14d6 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -28,6 +28,8 @@
 import com.android.systemui.power.PowerUI;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsModule;
+import com.android.systemui.shortcut.ShortcutKeyDispatcher;
+import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.notification.InstantAppNotifier;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarModule;
@@ -52,11 +54,17 @@
     @ClassKey(AuthController.class)
     public abstract SystemUI bindAuthController(AuthController service);
 
+    /** Inject into Divider. */
+    @Binds
+    @IntoMap
+    @ClassKey(Divider.class)
+    public abstract SystemUI bindDivider(Divider sysui);
+
     /** Inject into GarbageMonitor.Service. */
     @Binds
     @IntoMap
     @ClassKey(GarbageMonitor.Service.class)
-    public abstract SystemUI bindGarbageMonitorService(GarbageMonitor.Service service);
+    public abstract SystemUI bindGarbageMonitorService(GarbageMonitor.Service sysui);
 
     /** Inject into GlobalActionsComponent. */
     @Binds
@@ -106,6 +114,12 @@
     @ClassKey(ScreenDecorations.class)
     public abstract SystemUI bindScreenDecorations(ScreenDecorations sysui);
 
+    /** Inject into ShortcutKeyDispatcher. */
+    @Binds
+    @IntoMap
+    @ClassKey(ShortcutKeyDispatcher.class)
+    public abstract SystemUI bindsShortcutKeyDispatcher(ShortcutKeyDispatcher sysui);
+
     /** Inject into SizeCompatModeActivityController. */
     @Binds
     @IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
index 7b8d3bc..f86aaf1 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
@@ -19,12 +19,18 @@
 import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
 import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
 
+import android.content.Context;
+
 import androidx.annotation.Nullable;
 
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dock.DockManagerImpl;
 import com.android.systemui.power.EnhancedEstimates;
 import com.android.systemui.power.EnhancedEstimatesImpl;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.RecentsImplementation;
+import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
 import com.android.systemui.statusbar.notification.collection.NotificationData;
@@ -77,4 +83,17 @@
     static boolean provideAllowNotificationLongPress() {
         return true;
     }
+
+    @Singleton
+    @Provides
+    static Divider provideDivider(Context context) {
+        return new Divider(context);
+    }
+
+    @Provides
+    @Singleton
+    static Recents provideRecents(Context context, RecentsImplementation recentsImplementation,
+            CommandQueue commandQueue) {
+        return new Recents(context, recentsImplementation, commandQueue);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index b3a5181..6ae21b3 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -25,6 +25,8 @@
 import com.android.systemui.assist.AssistModule;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.notification.people.PeopleHubModule;
 import com.android.systemui.statusbar.phone.KeyguardLiftController;
@@ -75,5 +77,11 @@
     abstract CommandQueue optionalCommandQueue();
 
     @BindsOptionalOf
+    abstract Divider optionalDivider();
+
+    @BindsOptionalOf
+    abstract Recents optionalRecents();
+
+    @BindsOptionalOf
     abstract StatusBar optionalStatusBar();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java b/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
index 7bec5c0..25ac8f8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/DismissCallbackRegistry.java
@@ -22,14 +22,21 @@
 
 import java.util.ArrayList;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /**
  * Registry holding the current set of {@link IKeyguardDismissCallback}s.
  */
+@Singleton
 public class DismissCallbackRegistry {
 
     private final ArrayList<DismissCallbackWrapper> mDismissCallbacks = new ArrayList<>();
     private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
 
+    @Inject
+    public DismissCallbackRegistry() {}
+
     public void addCallback(IKeyguardDismissCallback callback) {
         mDismissCallbacks.add(new DismissCallbackWrapper(callback));
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 3b1edcc..c876fa6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -68,7 +68,6 @@
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.policy.IKeyguardDrawnCallback;
 import com.android.internal.policy.IKeyguardExitCallback;
@@ -104,6 +103,8 @@
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
+import dagger.Lazy;
+
 /**
  * Mediates requests related to the keyguard.  This includes queries about the
  * state of the keyguard, power management events that effect whether the keyguard
@@ -236,7 +237,7 @@
      */
     private PowerManager.WakeLock mShowKeyguardWakeLock;
 
-    private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    private final Lazy<StatusBarKeyguardViewManager> mStatusBarKeyguardViewManagerLazy;
 
     // these are protected by synchronized (this)
 
@@ -282,7 +283,7 @@
      * var being non-null as an indicator that there is an in progress request.
      */
     private IKeyguardExitCallback mExitSecureCallback;
-    private final DismissCallbackRegistry mDismissCallbackRegistry = new DismissCallbackRegistry();
+    private final DismissCallbackRegistry mDismissCallbackRegistry;
 
     // the properties of the keyguard
 
@@ -587,7 +588,7 @@
 
         @Override
         public void setNeedsInput(boolean needsInput) {
-            mStatusBarKeyguardViewManager.setNeedsInput(needsInput);
+            mStatusBarKeyguardViewManagerLazy.get().setNeedsInput(needsInput);
         }
 
         @Override
@@ -601,7 +602,8 @@
             mKeyguardDonePending = true;
             mHideAnimationRun = true;
             mHideAnimationRunning = true;
-            mStatusBarKeyguardViewManager.startPreHideAnimation(mHideAnimationFinishedRunnable);
+            mStatusBarKeyguardViewManagerLazy.get()
+                    .startPreHideAnimation(mHideAnimationFinishedRunnable);
             mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_PENDING_TIMEOUT,
                     KEYGUARD_DONE_PENDING_TIMEOUT_MS);
             Trace.endSection();
@@ -631,7 +633,7 @@
 
         @Override
         public void onCancelClicked() {
-            mStatusBarKeyguardViewManager.onCancelClicked();
+            mStatusBarKeyguardViewManagerLazy.get().onCancelClicked();
         }
 
         @Override
@@ -688,26 +690,15 @@
             Context context,
             FalsingManager falsingManager,
             LockPatternUtils lockPatternUtils,
-            BroadcastDispatcher broadcastDispatcher) {
-        this(context, falsingManager, lockPatternUtils, broadcastDispatcher,
-                SystemUIFactory.getInstance());
-    }
-
-    @VisibleForTesting
-    KeyguardViewMediator(
-            Context context,
-            FalsingManager falsingManager,
-            LockPatternUtils lockPatternUtils,
             BroadcastDispatcher broadcastDispatcher,
-            SystemUIFactory systemUIFactory) {
+            Lazy<StatusBarKeyguardViewManager> statusBarKeyguardViewManagerLazy,
+            DismissCallbackRegistry dismissCallbackRegistry) {
         super(context);
         mFalsingManager = falsingManager;
         mLockPatternUtils = lockPatternUtils;
         mBroadcastDispatcher = broadcastDispatcher;
-        mStatusBarKeyguardViewManager = systemUIFactory.createStatusBarKeyguardViewManager(
-                mContext,
-                mViewMediatorCallback,
-                mLockPatternUtils);
+        mStatusBarKeyguardViewManagerLazy = statusBarKeyguardViewManagerLazy;
+        mDismissCallbackRegistry = dismissCallbackRegistry;
     }
 
     public void userActivity() {
@@ -1259,7 +1250,7 @@
             if (mOccluded != isOccluded) {
                 mOccluded = isOccluded;
                 mUpdateMonitor.setKeyguardOccluded(isOccluded);
-                mStatusBarKeyguardViewManager.setOccluded(isOccluded, animate
+                mStatusBarKeyguardViewManagerLazy.get().setOccluded(isOccluded, animate
                         && mDeviceInteractive);
                 adjustStatusBarLocked();
             }
@@ -1330,7 +1321,7 @@
         }
 
         // if the keyguard is already showing, don't bother
-        if (mStatusBarKeyguardViewManager.isShowing()) {
+        if (mStatusBarKeyguardViewManagerLazy.get().isShowing()) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
             resetStateLocked();
             return;
@@ -1394,7 +1385,7 @@
                 mDismissCallbackRegistry.addCallback(callback);
             }
             mCustomMessage = message;
-            mStatusBarKeyguardViewManager.dismissAndCollapse();
+            mStatusBarKeyguardViewManagerLazy.get().dismissAndCollapse();
         } else if (callback != null) {
             new DismissCallbackWrapper(callback).notifyDismissError();
         }
@@ -1661,7 +1652,8 @@
         } else if (!mHideAnimationRun) {
             mHideAnimationRun = true;
             mHideAnimationRunning = true;
-            mStatusBarKeyguardViewManager.startPreHideAnimation(mHideAnimationFinishedRunnable);
+            mStatusBarKeyguardViewManagerLazy.get()
+                    .startPreHideAnimation(mHideAnimationFinishedRunnable);
         }
     }
 
@@ -1817,7 +1809,7 @@
             mHiding = false;
             mWakeAndUnlocking = false;
             setShowingLocked(true);
-            mStatusBarKeyguardViewManager.show(options);
+            mStatusBarKeyguardViewManagerLazy.get().show(options);
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
             adjustStatusBarLocked();
@@ -1835,22 +1827,22 @@
         public void run() {
             Trace.beginSection("KeyguardViewMediator.mKeyGuardGoingAwayRunnable");
             if (DEBUG) Log.d(TAG, "keyguardGoingAway");
-            mStatusBarKeyguardViewManager.keyguardGoingAway();
+            mStatusBarKeyguardViewManagerLazy.get().keyguardGoingAway();
 
             int flags = 0;
-            if (mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock()
+            if (mStatusBarKeyguardViewManagerLazy.get().shouldDisableWindowAnimationsForUnlock()
                     || (mWakeAndUnlocking && !mPulsing)) {
                 flags |= WindowManagerPolicyConstants
                         .KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
             }
-            if (mStatusBarKeyguardViewManager.isGoingToNotificationShade()
+            if (mStatusBarKeyguardViewManagerLazy.get().isGoingToNotificationShade()
                     || (mWakeAndUnlocking && mPulsing)) {
                 flags |= WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
             }
-            if (mStatusBarKeyguardViewManager.isUnlockWithWallpaper()) {
+            if (mStatusBarKeyguardViewManagerLazy.get().isUnlockWithWallpaper()) {
                 flags |= WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
             }
-            if (mStatusBarKeyguardViewManager.shouldSubtleWindowAnimationsForUnlock()) {
+            if (mStatusBarKeyguardViewManagerLazy.get().shouldSubtleWindowAnimationsForUnlock()) {
                 flags |= WindowManagerPolicyConstants
                         .KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS;
             }
@@ -1936,7 +1928,7 @@
                 // Hack level over 9000: To speed up wake-and-unlock sequence, force it to report
                 // the next draw from here so we don't have to wait for window manager to signal
                 // this to our ViewRootImpl.
-                mStatusBarKeyguardViewManager.getViewRootImpl().setReportNextDraw();
+                mStatusBarKeyguardViewManagerLazy.get().getViewRootImpl().setReportNextDraw();
                 notifyDrawn(mDrawnCallback);
                 mDrawnCallback = null;
             }
@@ -1950,7 +1942,7 @@
             setShowingLocked(false);
             mWakeAndUnlocking = false;
             mDismissCallbackRegistry.notifyDismissSucceeded();
-            mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
+            mStatusBarKeyguardViewManagerLazy.get().hide(startTime, fadeoutDuration);
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
             adjustStatusBarLocked();
@@ -1996,7 +1988,7 @@
     private void handleReset() {
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleReset");
-            mStatusBarKeyguardViewManager.reset(true /* hideBouncerWhenShowing */);
+            mStatusBarKeyguardViewManagerLazy.get().reset(true /* hideBouncerWhenShowing */);
         }
     }
 
@@ -2009,7 +2001,7 @@
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
             setShowingLocked(true);
-            mStatusBarKeyguardViewManager.dismissAndCollapse();
+            mStatusBarKeyguardViewManagerLazy.get().dismissAndCollapse();
         }
         Trace.endSection();
     }
@@ -2017,7 +2009,7 @@
     private void handleNotifyStartedGoingToSleep() {
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleNotifyStartedGoingToSleep");
-            mStatusBarKeyguardViewManager.onStartedGoingToSleep();
+            mStatusBarKeyguardViewManagerLazy.get().onStartedGoingToSleep();
         }
     }
 
@@ -2028,7 +2020,7 @@
     private void handleNotifyFinishedGoingToSleep() {
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleNotifyFinishedGoingToSleep");
-            mStatusBarKeyguardViewManager.onFinishedGoingToSleep();
+            mStatusBarKeyguardViewManagerLazy.get().onFinishedGoingToSleep();
         }
     }
 
@@ -2036,7 +2028,7 @@
         Trace.beginSection("KeyguardViewMediator#handleMotifyStartedWakingUp");
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleNotifyWakingUp");
-            mStatusBarKeyguardViewManager.onStartedWakingUp();
+            mStatusBarKeyguardViewManagerLazy.get().onStartedWakingUp();
         }
         Trace.endSection();
     }
@@ -2045,7 +2037,7 @@
         Trace.beginSection("KeyguardViewMediator#handleNotifyScreenTurningOn");
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleNotifyScreenTurningOn");
-            mStatusBarKeyguardViewManager.onScreenTurningOn();
+            mStatusBarKeyguardViewManagerLazy.get().onScreenTurningOn();
             if (callback != null) {
                 if (mWakeAndUnlocking) {
                     mDrawnCallback = callback;
@@ -2064,7 +2056,7 @@
         }
         synchronized (this) {
             if (DEBUG) Log.d(TAG, "handleNotifyScreenTurnedOn");
-            mStatusBarKeyguardViewManager.onScreenTurnedOn();
+            mStatusBarKeyguardViewManagerLazy.get().onScreenTurnedOn();
         }
         Trace.endSection();
     }
@@ -2113,10 +2105,10 @@
             ViewGroup container, NotificationPanelView panelView,
             BiometricUnlockController biometricUnlockController, ViewGroup lockIconContainer,
             View notificationContainer, KeyguardBypassController bypassController) {
-        mStatusBarKeyguardViewManager.registerStatusBar(statusBar, container, panelView,
+        mStatusBarKeyguardViewManagerLazy.get().registerStatusBar(statusBar, container, panelView,
                 biometricUnlockController, mDismissCallbackRegistry, lockIconContainer,
                 notificationContainer, bypassController, mFalsingManager);
-        return mStatusBarKeyguardViewManager;
+        return mStatusBarKeyguardViewManagerLazy.get();
     }
 
     public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java b/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
index 4d18312..4501b8f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
@@ -65,6 +65,8 @@
         mMobileRoaming = findViewById(R.id.mobile_roaming);
         mCarrierText = findViewById(R.id.qs_carrier_text);
 
+        mMobileSignal.setImageDrawable(new SignalDrawable(mContext));
+
         int colorForeground = Utils.getColorAttrDefaultColor(mContext,
                 android.R.attr.colorForeground);
         mColorForegroundStateList = ColorStateList.valueOf(colorForeground);
@@ -78,7 +80,6 @@
             ColorStateList colorStateList = ColorStateList.valueOf(
                     mDualToneHandler.getSingleColor(mColorForegroundIntensity));
             mMobileRoaming.setImageTintList(colorStateList);
-            mMobileSignal.setImageDrawable(new SignalDrawable(mContext));
             mMobileSignal.setImageTintList(colorStateList);
             mMobileSignal.setImageLevel(state.mobileSignalIconId);
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
index 7f11e56..60bc6b6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
@@ -57,8 +57,8 @@
     private final static String TAG = "OverviewProxyRecentsImpl";
     @Nullable
     private final Lazy<StatusBar> mStatusBarLazy;
+    private final Optional<Divider> mDividerOptional;
 
-    private SysUiServiceProvider mSysUiServiceProvider;
     private Context mContext;
     private Handler mHandler;
     private TrustManager mTrustManager;
@@ -66,14 +66,15 @@
 
     @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
     @Inject
-    public OverviewProxyRecentsImpl(Optional<Lazy<StatusBar>> statusBarLazy) {
+    public OverviewProxyRecentsImpl(Optional<Lazy<StatusBar>> statusBarLazy,
+            Optional<Divider> dividerOptional) {
         mStatusBarLazy = statusBarLazy.orElse(null);
+        mDividerOptional = dividerOptional;
     }
 
     @Override
     public void onStart(Context context, SysUiServiceProvider sysUiServiceProvider) {
         mContext = context;
-        mSysUiServiceProvider = sysUiServiceProvider;
         mHandler = new Handler();
         mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
         mOverviewProxyService = Dependency.get(OverviewProxyService.class);
@@ -164,10 +165,8 @@
                         runningTask.id, stackCreateMode, initialBounds)) {
                     // The overview service is handling split screen, so just skip the wait for the
                     // first draw and notify the divider to start animating now
-                    final Divider divider = mSysUiServiceProvider.getComponent(Divider.class);
-                    if (divider != null) {
-                        divider.onRecentsDrawn();
-                    }
+                    mDividerOptional.ifPresent(Divider::onRecentsDrawn);
+
                     return true;
                 }
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 3fc1398..ba9fc3d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -80,6 +80,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -102,6 +103,7 @@
 
     private final Context mContext;
     private final PipUI mPipUI;
+    private final Optional<Divider> mDividerOptional;
     private SysUiState mSysUiState;
     private final Handler mHandler;
     private final NavigationBarController mNavBarController;
@@ -208,10 +210,7 @@
             }
             long token = Binder.clearCallingIdentity();
             try {
-                Divider divider = SysUiServiceProvider.getComponent(mContext, Divider.class);
-                if (divider != null) {
-                    divider.onDockedFirstAnimationFrame();
-                }
+                mDividerOptional.ifPresent(Divider::onDockedFirstAnimationFrame);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -241,11 +240,9 @@
             }
             long token = Binder.clearCallingIdentity();
             try {
-                Divider divider = SysUiServiceProvider.getComponent(mContext, Divider.class);
-                if (divider != null) {
-                    return divider.getView().getNonMinimizedSplitScreenSecondaryBounds();
-                }
-                return null;
+                return mDividerOptional.map(
+                        divider -> divider.getView().getNonMinimizedSplitScreenSecondaryBounds())
+                        .orElse(null);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -475,11 +472,12 @@
     private final IBinder.DeathRecipient mOverviewServiceDeathRcpt
             = this::cleanupAfterDeath;
 
+    @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
     @Inject
     public OverviewProxyService(Context context, DeviceProvisionedController provisionController,
             NavigationBarController navBarController, NavigationModeController navModeController,
-            StatusBarWindowController statusBarWinController,
-            SysUiState sysUiState, PipUI pipUI) {
+            StatusBarWindowController statusBarWinController, SysUiState sysUiState, PipUI pipUI,
+            Optional<Divider> dividerOptional) {
         mContext = context;
         mPipUI = pipUI;
         mHandler = new Handler();
@@ -487,6 +485,7 @@
         mStatusBarWinController = statusBarWinController;
         mDeviceProvisionedController = provisionController;
         mConnectionBackoffAttempts = 0;
+        mDividerOptional = dividerOptional;
         mRecentsComponentName = ComponentName.unflattenFromString(context.getString(
                 com.android.internal.R.string.config_recentsComponentName));
         mQuickStepIntent = new Intent(ACTION_QUICKSTEP)
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index a8ecc12..882930b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -28,19 +28,14 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
 /**
  * A proxy to a Recents implementation.
  */
-@Singleton
 public class Recents extends SystemUI implements CommandQueue.Callbacks {
 
     private final RecentsImplementation mImpl;
     private final CommandQueue mCommandQueue;
 
-    @Inject
     public Recents(Context context, RecentsImplementation impl, CommandQueue commandQueue) {
         super(context);
         mImpl = impl;
@@ -50,7 +45,6 @@
     @Override
     public void start() {
         mCommandQueue.addCallback(this);
-        putComponent(Recents.class, this);
         mImpl.onStart(mContext, this);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 68a2417..3ff6d0d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -17,6 +17,7 @@
 package com.android.systemui.screenshot;
 
 import static android.content.Context.NOTIFICATION_SERVICE;
+import static android.os.AsyncTask.THREAD_POOL_EXECUTOR;
 import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 
@@ -29,7 +30,9 @@
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.annotation.Nullable;
+import android.app.ActivityManager;
 import android.app.ActivityOptions;
+import android.app.ActivityTaskManager;
 import android.app.Notification;
 import android.app.Notification.BigPictureStyle;
 import android.app.NotificationManager;
@@ -42,6 +45,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -64,7 +68,10 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.Process;
+import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.DeviceConfig;
 import android.provider.MediaStore;
 import android.text.TextUtils;
@@ -82,9 +89,12 @@
 import android.widget.ImageView;
 import android.widget.Toast;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
+import com.android.systemui.SystemUIFactory;
 import com.android.systemui.dagger.qualifiers.MainResources;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.statusbar.phone.StatusBar;
@@ -97,8 +107,11 @@
 import java.io.OutputStream;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
+import java.util.Collections;
 import java.util.Date;
+import java.util.List;
 import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -156,6 +169,8 @@
         private final BigPictureStyle mNotificationStyle;
         private final int mImageWidth;
         private final int mImageHeight;
+        private final Handler mHandler;
+        private final ScreenshotNotificationSmartActionsProvider mSmartActionsProvider;
 
         SaveImageInBackgroundTask(Context context, SaveImageInBackgroundData data,
                 NotificationManager nManager) {
@@ -167,6 +182,11 @@
             String imageDate = new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(mImageTime));
             mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, imageDate);
 
+            // Initialize screenshot notification smart actions provider.
+            mHandler = new Handler();
+            mSmartActionsProvider =
+                SystemUIFactory.getInstance().createScreenshotNotificationSmartActionsProvider();
+
             // Create the large notification icon
             mImageWidth = data.image.getWidth();
             mImageHeight = data.image.getHeight();
@@ -242,6 +262,23 @@
             mNotificationStyle.bigLargeIcon((Bitmap) null);
         }
 
+        private int getUserHandleOfForegroundApplication(Context context) {
+            // This logic matches
+            // com.android.systemui.statusbar.phone.PhoneStatusBarPolicy#updateManagedProfile
+            try {
+                return ActivityTaskManager.getService().getLastResumedActivityUserId();
+            } catch (RemoteException e) {
+                Slog.w(TAG, "getUserHandleOfForegroundApplication: ", e);
+                return context.getUserId();
+            }
+        }
+
+        private boolean isManagedProfile(Context context) {
+            UserManager manager = UserManager.get(context);
+            UserInfo info = manager.getUserInfo(getUserHandleOfForegroundApplication(context));
+            return info.isManagedProfile();
+        }
+
         /**
          * Generates a new hardware bitmap with specified values, copying the content from the
          * passed in bitmap.
@@ -268,6 +305,12 @@
 
             Context context = mParams.context;
             Bitmap image = mParams.image;
+            boolean smartActionsEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
+                    SystemUiDeviceConfigFlags.ENABLE_SCREENSHOT_NOTIFICATION_SMART_ACTIONS, true);
+            CompletableFuture<List<Notification.Action>> smartActionsFuture = getSmartActionsFuture(
+                    context, image, mSmartActionsProvider, mHandler, smartActionsEnabled,
+                    isManagedProfile(context));
+
             Resources r = context.getResources();
 
             try {
@@ -378,6 +421,18 @@
                 mParams.imageUri = uri;
                 mParams.image = null;
                 mParams.errorMsgResId = 0;
+
+                if (smartActionsEnabled) {
+                    int timeoutMs = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
+                            SystemUiDeviceConfigFlags
+                                    .SCREENSHOT_NOTIFICATION_SMART_ACTIONS_TIMEOUT_MS,
+                            1000);
+                    List<Notification.Action> smartActions = getSmartActions(smartActionsFuture,
+                            timeoutMs);
+                    for (Notification.Action action : smartActions) {
+                        mNotificationBuilder.addAction(action);
+                    }
+                }
             } catch (Exception e) {
                 // IOException/UnsupportedOperationException may be thrown if external storage is
                 // not mounted
@@ -1039,6 +1094,58 @@
         nManager.notify(SystemMessage.NOTE_GLOBAL_SCREENSHOT, n);
     }
 
+    @VisibleForTesting
+    static CompletableFuture<List<Notification.Action>> getSmartActionsFuture(Context context,
+            Bitmap image, ScreenshotNotificationSmartActionsProvider smartActionsProvider,
+            Handler handler, boolean smartActionsEnabled, boolean isManagedProfile) {
+        if (!smartActionsEnabled) {
+            Slog.i(TAG, "Screenshot Intelligence not enabled, returning empty list.");
+            return CompletableFuture.completedFuture(Collections.emptyList());
+        }
+        if (image.getConfig() != Bitmap.Config.HARDWARE) {
+            Slog.w(TAG, String.format(
+                    "Bitmap expected: Hardware, Bitmap found: %s. Returning empty list.",
+                    image.getConfig()));
+            return CompletableFuture.completedFuture(Collections.emptyList());
+        }
+
+        Slog.d(TAG, "Screenshot from a managed profile: " + isManagedProfile);
+        CompletableFuture<List<Notification.Action>> smartActionsFuture;
+        try {
+            ActivityManager.RunningTaskInfo runningTask =
+                    ActivityManagerWrapper.getInstance().getRunningTask();
+            ComponentName componentName =
+                    (runningTask != null && runningTask.topActivity != null)
+                            ? runningTask.topActivity
+                            : new ComponentName("", "");
+            smartActionsFuture = smartActionsProvider.getActions(image, context,
+                    THREAD_POOL_EXECUTOR,
+                    handler,
+                    componentName,
+                    isManagedProfile);
+        } catch (Throwable e) {
+            smartActionsFuture = CompletableFuture.completedFuture(Collections.emptyList());
+            Slog.e(TAG, "Failed to get future for screenshot notification smart actions.", e);
+        }
+        return smartActionsFuture;
+    }
+
+    @VisibleForTesting
+    static List<Notification.Action> getSmartActions(
+            CompletableFuture<List<Notification.Action>> smartActionsFuture, int timeoutMs) {
+        try {
+            long startTimeMs = SystemClock.uptimeMillis();
+            List<Notification.Action> actions = smartActionsFuture.get(timeoutMs,
+                    TimeUnit.MILLISECONDS);
+            Slog.d(TAG, String.format("Wait time for smart actions: %d ms",
+                    SystemClock.uptimeMillis() - startTimeMs));
+            return actions;
+        } catch (Throwable e) {
+            Slog.e(TAG, "Failed to obtain screenshot notification smart actions.", e);
+            return Collections.emptyList();
+        }
+    }
+
     /**
      * Receiver to proxy the share or edit intent, used to clean up the notification and send
      * appropriate signals to the system (ie. to dismiss the keyguard if necessary).
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java
new file mode 100644
index 0000000..fa23bf7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsProvider.java
@@ -0,0 +1,58 @@
+/*
+ * 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 com.android.systemui.screenshot;
+
+import android.app.Notification;
+import android.content.ComponentName;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.Handler;
+import android.util.Log;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+
+/**
+ * This class can be overridden by a vendor-specific sys UI implementation,
+ * in order to provide smart actions in the screenshot notification.
+ */
+public class ScreenshotNotificationSmartActionsProvider {
+    private static final String TAG = "ScreenshotActions";
+
+    /**
+     * Default implementation that returns an empty list.
+     * This method is overridden in vendor-specific Sys UI implementation.
+     *
+     * @param bitmap           The bitmap of the screenshot. The bitmap config must be {@link
+     *                         HARDWARE}.
+     * @param context          The current app {@link Context}.
+     * @param executor         A {@link Executor} that can be used to execute tasks in parallel.
+     * @param handler          A {@link Handler} to possibly run UI-thread code.
+     * @param componentName    Contains package and activity class names where the screenshot was
+     *                         taken. This is used as an additional signal to generate and rank more
+     *                         relevant actions.
+     * @param isManagedProfile The screenshot was taken for a work profile app.
+     */
+    public CompletableFuture<List<Notification.Action>> getActions(Bitmap bitmap, Context context,
+            Executor executor, Handler handler, ComponentName componentName,
+            boolean isManagedProfile) {
+        Log.d(TAG, "Returning empty smart action list.");
+        return CompletableFuture.completedFuture(Collections.emptyList());
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
index df9791d..a571f01 100644
--- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
@@ -34,13 +34,18 @@
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.stackdivider.DividerView;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /**
  * Dispatches shortcut to System UI components
  */
+@Singleton
 public class ShortcutKeyDispatcher extends SystemUI
         implements ShortcutKeyServiceProxy.Callbacks {
 
     private static final String TAG = "ShortcutKeyDispatcher";
+    private final Divider mDivider;
 
     private ShortcutKeyServiceProxy mShortcutKeyServiceProxy = new ShortcutKeyServiceProxy(this);
     private IWindowManager mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
@@ -53,8 +58,10 @@
     protected final long SC_DOCK_LEFT = META_MASK | KeyEvent.KEYCODE_LEFT_BRACKET;
     protected final long SC_DOCK_RIGHT = META_MASK | KeyEvent.KEYCODE_RIGHT_BRACKET;
 
-    public ShortcutKeyDispatcher(Context context) {
+    @Inject
+    public ShortcutKeyDispatcher(Context context, Divider divider) {
         super(context);
+        mDivider = divider;
     }
 
     /**
@@ -95,7 +102,7 @@
                         : SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT, null, -1);
             } else {
                 // If there is already a docked window, we respond by resizing the docking pane.
-                DividerView dividerView = getComponent(Divider.class).getView();
+                DividerView dividerView = mDivider.getView();
                 DividerSnapAlgorithm snapAlgorithm = dividerView.getSnapAlgorithm();
                 int dividerPosition = dividerView.getCurrentPosition();
                 DividerSnapAlgorithm.SnapTarget currentTarget =
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index c8b2b6a..d12f3ee 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -59,7 +59,6 @@
     public void start() {
         mWindowManager = new DividerWindowManager(mContext);
         update(mContext.getResources().getConfiguration());
-        putComponent(Divider.class, this);
         mDockDividerVisibilityListener = new DockDividerVisibilityListener();
         try {
             WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 681f3ab..2ef1f40 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -107,6 +107,7 @@
     private ColorStateList mTransientTextColorState;
     private ColorStateList mInitialTextColorState;
     private boolean mVisible;
+    private boolean mHideTransientMessageOnScreenOff;
 
     private boolean mPowerPluggedIn;
     private boolean mPowerPluggedInWired;
@@ -295,15 +296,17 @@
      * Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
      */
     public void showTransientIndication(CharSequence transientIndication) {
-        showTransientIndication(transientIndication, mInitialTextColorState);
+        showTransientIndication(transientIndication, mInitialTextColorState,
+                false /* hideOnScreenOff */);
     }
 
     /**
      * Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
      */
-    public void showTransientIndication(CharSequence transientIndication,
-            ColorStateList textColorState) {
+    private void showTransientIndication(CharSequence transientIndication,
+            ColorStateList textColorState, boolean hideOnScreenOff) {
         mTransientIndication = transientIndication;
+        mHideTransientMessageOnScreenOff = hideOnScreenOff && transientIndication != null;
         mTransientTextColorState = textColorState;
         mHandler.removeMessages(MSG_HIDE_TRANSIENT);
         mHandler.removeMessages(MSG_SWIPE_UP_TO_UNLOCK);
@@ -322,6 +325,7 @@
     public void hideTransientIndication() {
         if (mTransientIndication != null) {
             mTransientIndication = null;
+            mHideTransientMessageOnScreenOff = false;
             mHandler.removeMessages(MSG_HIDE_TRANSIENT);
             updateIndication(false);
         }
@@ -544,7 +548,8 @@
             String message = mContext.getString(R.string.keyguard_retry);
             mStatusBarKeyguardViewManager.showBouncerMessage(message, mInitialTextColorState);
         } else if (mKeyguardUpdateMonitor.isScreenOn()) {
-            showTransientIndication(mContext.getString(R.string.keyguard_unlock));
+            showTransientIndication(mContext.getString(R.string.keyguard_unlock),
+                    mInitialTextColorState, true /* hideOnScreenOff */);
             hideTransientIndicationDelayed(BaseKeyguardCallback.HIDE_DELAY_MS);
         }
     }
@@ -554,7 +559,11 @@
             return;
         }
         mDozing = dozing;
-        updateIndication(false);
+        if (mHideTransientMessageOnScreenOff && mDozing) {
+            hideTransientIndication();
+        } else {
+            updateIndication(false);
+        }
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -616,8 +625,7 @@
         @Override
         public void onBiometricHelp(int msgId, String helpString,
                 BiometricSourceType biometricSourceType) {
-            KeyguardUpdateMonitor updateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
-            if (!updateMonitor.isUnlockingWithBiometricAllowed()) {
+            if (!mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed()) {
                 return;
             }
             boolean showSwipeToUnlock =
@@ -625,8 +633,8 @@
             if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
                 mStatusBarKeyguardViewManager.showBouncerMessage(helpString,
                         mInitialTextColorState);
-            } else if (updateMonitor.isScreenOn()) {
-                showTransientIndication(helpString);
+            } else if (mKeyguardUpdateMonitor.isScreenOn()) {
+                showTransientIndication(helpString, mInitialTextColorState, showSwipeToUnlock);
                 if (!showSwipeToUnlock) {
                     hideTransientIndicationDelayed(TRANSIENT_BIOMETRIC_ERROR_TIMEOUT);
                 }
@@ -640,8 +648,7 @@
         @Override
         public void onBiometricError(int msgId, String errString,
                 BiometricSourceType biometricSourceType) {
-            KeyguardUpdateMonitor updateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
-            if (shouldSuppressBiometricError(msgId, biometricSourceType, updateMonitor)) {
+            if (shouldSuppressBiometricError(msgId, biometricSourceType, mKeyguardUpdateMonitor)) {
                 return;
             }
             animatePadlockError();
@@ -651,7 +658,7 @@
                 showSwipeUpToUnlock();
             } else if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
                 mStatusBarKeyguardViewManager.showBouncerMessage(errString, mInitialTextColorState);
-            } else if (updateMonitor.isScreenOn()) {
+            } else if (mKeyguardUpdateMonitor.isScreenOn()) {
                 showTransientIndication(errString);
                 // We want to keep this message around in case the screen was off
                 hideTransientIndicationDelayed(HIDE_DELAY_MS);
@@ -691,13 +698,15 @@
 
         @Override
         public void onTrustAgentErrorMessage(CharSequence message) {
-            showTransientIndication(message, Utils.getColorError(mContext));
+            showTransientIndication(message, Utils.getColorError(mContext),
+                    false /* hideOnScreenOff */);
         }
 
         @Override
         public void onScreenTurnedOn() {
             if (mMessageToShowOnScreenOn != null) {
-                showTransientIndication(mMessageToShowOnScreenOn, Utils.getColorError(mContext));
+                showTransientIndication(mMessageToShowOnScreenOn, Utils.getColorError(mContext),
+                        false /* hideOnScreenOff */);
                 // We want to keep this message around in case the screen was off
                 hideTransientIndicationDelayed(HIDE_DELAY_MS);
                 mMessageToShowOnScreenOn = null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 404087d..13d90ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -261,6 +261,7 @@
             boolean isNew = mNotificationData.get(entry.getKey()) == null;
             if (isNew) {
                 for (NotificationEntryListener listener : mNotificationEntryListeners) {
+                    mNotifLog.log(NotifEvent.INFLATED, entry);
                     listener.onEntryInflated(entry, inflatedFlags);
                 }
                 mNotificationData.add(entry);
@@ -270,6 +271,7 @@
                 }
             } else {
                 for (NotificationEntryListener listener : mNotificationEntryListeners) {
+                    mNotifLog.log(NotifEvent.INFLATED, entry);
                     listener.onEntryReinflated(entry);
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
index 2eefe29..3f7fd1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
@@ -19,7 +19,6 @@
 import static com.android.internal.util.Preconditions.checkNotNull;
 
 import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -34,17 +33,14 @@
 public class NotificationListController {
     private final NotificationEntryManager mEntryManager;
     private final NotificationListContainer mListContainer;
-    private final ForegroundServiceController mForegroundServiceController;
     private final DeviceProvisionedController mDeviceProvisionedController;
 
     public NotificationListController(
             NotificationEntryManager entryManager,
             NotificationListContainer listContainer,
-            ForegroundServiceController foregroundServiceController,
             DeviceProvisionedController deviceProvisionedController) {
         mEntryManager = checkNotNull(entryManager);
         mListContainer = checkNotNull(listContainer);
-        mForegroundServiceController = checkNotNull(foregroundServiceController);
         mDeviceProvisionedController = checkNotNull(deviceProvisionedController);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
index 0ef75165..52fd079 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
@@ -41,8 +41,6 @@
 import com.android.systemui.statusbar.notification.InflationException;
 import com.android.systemui.statusbar.notification.NotificationClicker;
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
-import com.android.systemui.statusbar.notification.logging.NotifEvent;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationContentInflater;
@@ -74,7 +72,6 @@
     private final boolean mAllowLongPress;
     private final KeyguardBypassController mKeyguardBypassController;
     private final StatusBarStateController mStatusBarStateController;
-    private final NotifLog mNotifLog;
 
     private NotificationRemoteInputManager mRemoteInputManager;
     private NotificationPresenter mPresenter;
@@ -88,14 +85,12 @@
 
     public NotificationRowBinderImpl(Context context, boolean allowLongPress,
             KeyguardBypassController keyguardBypassController,
-            StatusBarStateController statusBarStateController,
-            NotifLog notifLog) {
+            StatusBarStateController statusBarStateController) {
         mContext = context;
         mMessagingUtil = new NotificationMessagingUtil(context);
         mAllowLongPress = allowLongPress;
         mKeyguardBypassController = keyguardBypassController;
         mStatusBarStateController = statusBarStateController;
-        mNotifLog = notifLog;
     }
 
     private NotificationRemoteInputManager getRemoteInputManager() {
@@ -149,7 +144,6 @@
                     row -> {
                         bindRow(entry, pmUser, sbn, row, onDismissRunnable);
                         updateNotification(entry, pmUser, sbn, row);
-                        mNotifLog.log(NotifEvent.INFLATED, sbn);
                     });
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 2b9912c..8d50f58 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -142,6 +142,7 @@
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 import com.android.systemui.statusbar.policy.HeadsUpUtil;
 import com.android.systemui.statusbar.policy.ScrollAdapter;
+import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.util.Assert;
 
@@ -344,6 +345,7 @@
     private boolean mForceNoOverlappingRendering;
     private final ArrayList<Pair<ExpandableNotificationRow, Boolean>> mTmpList = new ArrayList<>();
     private FalsingManager mFalsingManager;
+    private final ZenModeController mZenController;
     private boolean mAnimationRunning;
     private ViewTreeObserver.OnPreDrawListener mRunningAnimationUpdater
             = new ViewTreeObserver.OnPreDrawListener() {
@@ -520,7 +522,8 @@
             NotificationLockscreenUserManager notificationLockscreenUserManager,
             NotificationGutsManager notificationGutsManager,
             NotificationSectionsFeatureManager sectionsFeatureManager,
-            PeopleHubSectionFooterViewAdapter peopleHubViewAdapter) {
+            PeopleHubSectionFooterViewAdapter peopleHubViewAdapter,
+            ZenModeController zenController) {
         super(context, attrs, 0, 0);
         Resources res = getResources();
 
@@ -535,6 +538,7 @@
         mHeadsUpManager.setAnimationStateHandler(this::setHeadsUpGoingAwayAnimationsAllowed);
         mKeyguardBypassController = keyguardBypassController;
         mFalsingManager = falsingManager;
+        mZenController = zenController;
 
         int[] buckets = sectionsFeatureManager.getNotificationBuckets();
         mSectionsManager =
@@ -4882,7 +4886,7 @@
         mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled);
 
         int oldTextRes = mEmptyShadeView.getTextResource();
-        int newTextRes = mStatusBar.areNotificationsHidden()
+        int newTextRes = mZenController.areNotificationsHiddenInShade()
                 ? R.string.dnd_suppressing_shade_text : R.string.empty_shade_text;
         if (oldTextRes != newTextRes) {
             mEmptyShadeView.setText(newTextRes);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java
new file mode 100644
index 0000000..93887a6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightsOutNotifController.java
@@ -0,0 +1,179 @@
+/*
+ * 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 com.android.systemui.statusbar.phone;
+
+import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.annotation.Nullable;
+import android.view.View;
+import android.view.WindowInsetsController;
+import android.view.WindowManager;
+import android.view.animation.AccelerateInterpolator;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.statusbar.NotificationVisibility;
+import com.android.internal.view.AppearanceRegion;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.notification.NotificationEntryListener;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Apps can request a low profile mode {@link View.SYSTEM_UI_FLAG_LOW_PROFILE}
+ * where status bar and navigation icons dim. In this mode, a notification dot appears
+ * where the notification icons would appear if they would be shown outside of this mode.
+ *
+ * This controller shows and hides the notification dot in the status bar to indicate
+ * whether there are notifications when the device is in {@link View.SYSTEM_UI_FLAG_LOW_PROFILE}.
+ */
+@Singleton
+public class LightsOutNotifController {
+    private final CommandQueue mCommandQueue;
+    private final NotificationEntryManager mEntryManager;
+    private final WindowManager mWindowManager;
+
+    /** @see android.view.WindowInsetsController#setSystemBarsAppearance(int) */
+    @VisibleForTesting @WindowInsetsController.Appearance int mAppearance;
+
+    private int mDisplayId;
+    private View mLightsOutNotifView;
+
+    @Inject
+    LightsOutNotifController(WindowManager windowManager,
+            NotificationEntryManager entryManager,
+            CommandQueue commandQueue) {
+        mWindowManager = windowManager;
+        mEntryManager = entryManager;
+        mCommandQueue = commandQueue;
+    }
+
+    /**
+     * Sets the notification dot view after it is created in the StatusBar.
+     * This is the view this controller will show and hide depending on whether:
+     * 1. there are active notifications
+     * 2. an app has requested {@link View.SYSTEM_UI_FLAG_LOW_PROFILE}
+     */
+    void setLightsOutNotifView(View lightsOutNotifView) {
+        destroy();
+        mLightsOutNotifView = lightsOutNotifView;
+
+        if (mLightsOutNotifView != null) {
+            mLightsOutNotifView.setVisibility(View.GONE);
+            mLightsOutNotifView.setAlpha(0f);
+            init();
+        }
+    }
+
+    private void destroy() {
+        mEntryManager.removeNotificationEntryListener(mEntryListener);
+        mCommandQueue.removeCallback(mCallback);
+    }
+
+    private void init() {
+        mDisplayId = mWindowManager.getDefaultDisplay().getDisplayId();
+        mEntryManager.addNotificationEntryListener(mEntryListener);
+        mCommandQueue.addCallback(mCallback);
+
+        updateLightsOutView();
+    }
+
+    private boolean hasActiveNotifications() {
+        return !mEntryManager.getNotificationData().getActiveNotifications().isEmpty();
+    }
+
+    @VisibleForTesting
+    void updateLightsOutView() {
+        if (mLightsOutNotifView == null) {
+            return;
+        }
+
+        final boolean showDot = shouldShowDot();
+        if (showDot != isShowingDot()) {
+            if (showDot) {
+                mLightsOutNotifView.setAlpha(0f);
+                mLightsOutNotifView.setVisibility(View.VISIBLE);
+            }
+
+            mLightsOutNotifView.animate()
+                    .alpha(showDot ? 1 : 0)
+                    .setDuration(showDot ? 750 : 250)
+                    .setInterpolator(new AccelerateInterpolator(2.0f))
+                    .setListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator a) {
+                            mLightsOutNotifView.setAlpha(showDot ? 1 : 0);
+                            mLightsOutNotifView.setVisibility(showDot ? View.VISIBLE : View.GONE);
+                        }
+                    })
+                    .start();
+        }
+    }
+
+    @VisibleForTesting
+    boolean isShowingDot() {
+        return mLightsOutNotifView.getVisibility() == View.VISIBLE
+                && mLightsOutNotifView.getAlpha() == 1.0f;
+    }
+
+    @VisibleForTesting
+    boolean shouldShowDot() {
+        return hasActiveNotifications() && areLightsOut();
+    }
+
+    @VisibleForTesting
+    boolean areLightsOut() {
+        return 0 != (mAppearance & APPEARANCE_LOW_PROFILE_BARS);
+    }
+
+    private final CommandQueue.Callbacks mCallback = new CommandQueue.Callbacks() {
+        @Override
+        public void onSystemBarAppearanceChanged(int displayId,
+                @WindowInsetsController.Appearance int appearance,
+                AppearanceRegion[] appearanceRegions,
+                boolean navbarColorManagedByIme) {
+            if (displayId != mDisplayId) {
+                return;
+            }
+            mAppearance = appearance;
+            updateLightsOutView();
+        }
+    };
+
+    private final NotificationEntryListener mEntryListener = new NotificationEntryListener() {
+        // Cares about notifications post-filtering
+        @Override
+        public void onNotificationAdded(NotificationEntry entry) {
+            updateLightsOutView();
+        }
+
+        @Override
+        public void onPostEntryUpdated(NotificationEntry entry) {
+            updateLightsOutView();
+        }
+
+        @Override
+        public void onEntryRemoved(@Nullable NotificationEntry entry,
+                NotificationVisibility visibility, boolean removedByUser) {
+            updateLightsOutView();
+        }
+    };
+}
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 816327f..1c46cf8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -118,6 +118,7 @@
 import java.io.PrintWriter;
 import java.util.List;
 import java.util.Locale;
+import java.util.Optional;
 import java.util.function.Consumer;
 
 import javax.inject.Inject;
@@ -162,8 +163,8 @@
     private int mDisabledFlags1;
     private int mDisabledFlags2;
     private StatusBar mStatusBar;
-    private Recents mRecents;
-    private Divider mDivider;
+    private final Divider mDivider;
+    private final Optional<Recents> mRecentsOptional;
     private WindowManager mWindowManager;
     private final CommandQueue mCommandQueue;
     private long mLastLockToAppLongPress;
@@ -266,7 +267,9 @@
             StatusBarStateController statusBarStateController,
             SysUiState sysUiFlagsContainer,
             BroadcastDispatcher broadcastDispatcher,
-            CommandQueue commandQueue) {
+            CommandQueue commandQueue,
+            Divider divider,
+            Optional<Recents> recentsOptional) {
         mAccessibilityManagerWrapper = accessibilityManagerWrapper;
         mDeviceProvisionedController = deviceProvisionedController;
         mStatusBarStateController = statusBarStateController;
@@ -279,6 +282,8 @@
         mNavBarMode = navigationModeController.addListener(this);
         mBroadcastDispatcher = broadcastDispatcher;
         mCommandQueue = commandQueue;
+        mDivider = divider;
+        mRecentsOptional = recentsOptional;
     }
 
     // ----- Fragment Lifecycle Callbacks -----
@@ -288,8 +293,6 @@
         super.onCreate(savedInstanceState);
         mCommandQueue.observe(getLifecycle(), this);
         mStatusBar = SysUiServiceProvider.getComponent(getContext(), StatusBar.class);
-        mRecents = SysUiServiceProvider.getComponent(getContext(), Recents.class);
-        mDivider = SysUiServiceProvider.getComponent(getContext(), Divider.class);
         mWindowManager = getContext().getSystemService(WindowManager.class);
         mAccessibilityManager = getContext().getSystemService(AccessibilityManager.class);
         mContentResolver = getContext().getContentResolver();
@@ -905,7 +908,7 @@
     }
 
     private boolean onLongPressRecents() {
-        if (mRecents == null || !ActivityTaskManager.supportsMultiWindow(getContext())
+        if (mRecentsOptional.isPresent() || !ActivityTaskManager.supportsMultiWindow(getContext())
                 || !mDivider.getView().getSnapAlgorithm().isSplitScreenFeasible()
                 || ActivityManager.isLowRamDeviceStatic()
                 // If we are connected to the overview service, then disable the recents button
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
index 70cd43a..f359fe7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
@@ -142,12 +142,6 @@
     void onLaunchAnimationCancelled();
 
     /**
-     * When notifications update, give the shade controller a chance to do thing in response to
-     * the new data set
-     */
-    void updateAreThereNotifications();
-
-    /**
      * Callback to notify the shade controller that a {@link ActivatableNotificationView} has become
      * inactive
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index cff2824..910300c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -47,13 +47,10 @@
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
 import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
-import android.app.AppOpsManager;
 import android.app.IWallpaperManager;
 import android.app.KeyguardManager;
 import android.app.Notification;
@@ -117,7 +114,6 @@
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityManager;
-import android.view.animation.AccelerateInterpolator;
 import android.widget.DateTimeView;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -139,7 +135,6 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
 import com.android.systemui.EventLogTags;
-import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.InitController;
 import com.android.systemui.Interpolators;
 import com.android.systemui.Prefs;
@@ -147,7 +142,6 @@
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.bubbles.BubbleController;
@@ -155,9 +149,9 @@
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.doze.DozeHost;
-import com.android.systemui.doze.DozeLog;
 import com.android.systemui.fragments.ExtensionFragmentListener;
 import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.keyguard.KeyguardSliceProvider;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
@@ -216,7 +210,6 @@
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationRowBinderImpl;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
@@ -239,7 +232,6 @@
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.volume.VolumeComponent;
 
 import java.io.FileDescriptor;
@@ -247,6 +239,7 @@
 import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Map;
+import java.util.Optional;
 
 import javax.inject.Named;
 
@@ -255,10 +248,10 @@
 
 public class StatusBar extends SystemUI implements DemoMode,
         ActivityStarter, KeyguardStateController.Callback,
-        OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
+        OnHeadsUpChangedListener, CommandQueue.Callbacks,
         ColorExtractor.OnColorsChangedListener, ConfigurationListener,
         StatusBarStateController.StateListener, ShadeController,
-        ActivityLaunchAnimator.Callback, AppOpsController.Callback {
+        ActivityLaunchAnimator.Callback {
     public static final boolean MULTIUSER_DEBUG = false;
 
     public static final boolean ENABLE_CHILD_NOTIFICATIONS
@@ -377,7 +370,6 @@
 
     private final FeatureFlags mFeatureFlags;
     private final StatusBarIconController mIconController;
-    private final DozeLog mDozeLog;
     private final PulseExpansionHandler mPulseExpansionHandler;
     private final NotificationWakeUpCoordinator mWakeUpCoordinator;
     private final KeyguardBypassController mKeyguardBypassController;
@@ -391,12 +383,14 @@
     private final BroadcastDispatcher mBroadcastDispatcher;
     private final ConfigurationController mConfigurationController;
     private final StatusBarWindowViewController.Builder mStatusBarWindowViewControllerBuilder;
-    private final NotifLog mNotifLog;
     private final DozeParameters mDozeParameters;
     private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
     private final PluginManager mPluginManager;
     private final RemoteInputUriController mRemoteInputUriController;
+    private final Optional<Divider> mDividerOptional;
     private final SuperStatusBarViewFactory mSuperStatusBarViewFactory;
+    private final LightsOutNotifController mLightsOutNotifController;
+    private final DismissCallbackRegistry mDismissCallbackRegistry;
 
     // expanded notifications
     protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -424,10 +418,7 @@
     private NotificationListController mNotificationListController;
     private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
     private final NotificationViewHierarchyManager mViewHierarchyManager;
-    private final ForegroundServiceController mForegroundServiceController;
-    private final AppOpsController mAppOpsController;
     private final KeyguardViewMediator mKeyguardViewMediator;
-    private final ZenModeController mZenController;
     private final NotificationAlertingManager mNotificationAlertingManager;
 
     // for disabling the status bar
@@ -614,25 +605,13 @@
 
     private ActivityIntentHelper mActivityIntentHelper;
 
-    @Override
-    public void onActiveStateChanged(int code, int uid, String packageName, boolean active) {
-        Dependency.get(MAIN_HANDLER).post(() -> {
-            mForegroundServiceController.onAppOpChanged(code, uid, packageName, active);
-        });
-    }
-
-    protected static final int[] APP_OPS = new int[] {AppOpsManager.OP_CAMERA,
-            AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
-            AppOpsManager.OP_RECORD_AUDIO,
-            AppOpsManager.OP_COARSE_LOCATION,
-            AppOpsManager.OP_FINE_LOCATION};
-
     /**
      * Public constructor for StatusBar.
      *
      * StatusBar is considered optional, and therefore can not be marked as @Inject directly.
      * Instead, an @Provide method is included.
      */
+    @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
     public StatusBar(
             Context context,
             FeatureFlags featureFlags,
@@ -640,7 +619,6 @@
             AutoHideController autoHideController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             StatusBarIconController statusBarIconController,
-            DozeLog dozeLog,
             PulseExpansionHandler pulseExpansionHandler,
             NotificationWakeUpCoordinator notificationWakeUpCoordinator,
             KeyguardBypassController keyguardBypassController,
@@ -658,10 +636,7 @@
             NotificationEntryManager notificationEntryManager,
             NotificationInterruptionStateProvider notificationInterruptionStateProvider,
             NotificationViewHierarchyManager notificationViewHierarchyManager,
-            ForegroundServiceController foregroundServiceController,
-            AppOpsController appOpsController,
             KeyguardViewMediator keyguardViewMediator,
-            ZenModeController zenModeController,
             NotificationAlertingManager notificationAlertingManager,
             DisplayMetrics displayMetrics,
             MetricsLogger metricsLogger,
@@ -688,7 +663,6 @@
             ConfigurationController configurationController,
             StatusBarWindowController statusBarWindowController,
             StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder,
-            NotifLog notifLog,
             DozeParameters dozeParameters,
             ScrimController scrimController,
             @Nullable KeyguardLiftController keyguardLiftController,
@@ -700,14 +674,18 @@
             CommandQueue commandQueue,
             PluginManager pluginManager,
             RemoteInputUriController remoteInputUriController,
-            SuperStatusBarViewFactory superStatusBarViewFactory) {
+            Optional<Divider> dividerOptional,
+            LightsOutNotifController lightsOutNotifController,
+            SuperStatusBarViewFactory superStatusBarViewFactory,
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+            ViewMediatorCallback viewMediatorCallback,
+            DismissCallbackRegistry dismissCallbackRegistry) {
         super(context);
         mFeatureFlags = featureFlags;
         mLightBarController = lightBarController;
         mAutoHideController = autoHideController;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mIconController = statusBarIconController;
-        mDozeLog = dozeLog;
         mPulseExpansionHandler = pulseExpansionHandler;
         mWakeUpCoordinator = notificationWakeUpCoordinator;
         mKeyguardBypassController = keyguardBypassController;
@@ -725,10 +703,7 @@
         mEntryManager = notificationEntryManager;
         mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
         mViewHierarchyManager = notificationViewHierarchyManager;
-        mForegroundServiceController = foregroundServiceController;
-        mAppOpsController = appOpsController;
         mKeyguardViewMediator = keyguardViewMediator;
-        mZenController = zenModeController;
         mNotificationAlertingManager = notificationAlertingManager;
         mDisplayMetrics = displayMetrics;
         mMetricsLogger = metricsLogger;
@@ -755,7 +730,6 @@
         mConfigurationController = configurationController;
         mStatusBarWindowController = statusBarWindowController;
         mStatusBarWindowViewControllerBuilder = statusBarWindowViewControllerBuilder;
-        mNotifLog = notifLog;
         mDozeServiceHost = dozeServiceHost;
         mPowerManager = powerManager;
         mDozeParameters = dozeParameters;
@@ -767,7 +741,13 @@
         mCommandQueue = commandQueue;
         mPluginManager = pluginManager;
         mRemoteInputUriController = remoteInputUriController;
+        mDividerOptional = dividerOptional;
+
         mSuperStatusBarViewFactory = superStatusBarViewFactory;
+        mLightsOutNotifController =  lightsOutNotifController;
+        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+        mKeyguardViewMediatorCallback = viewMediatorCallback;
+        mDismissCallbackRegistry = dismissCallbackRegistry;
 
         mBubbleExpandListener =
                 (isExpanding, key) -> {
@@ -922,7 +902,6 @@
         mConfigurationController.addCallback(this);
 
         // set the initial view visibility
-        Dependency.get(InitController.class).addPostInitTask(this::updateAreThereNotifications);
         int disabledFlags1 = result.mDisabledFlags1;
         int disabledFlags2 = result.mDisabledFlags2;
         Dependency.get(InitController.class).addPostInitTask(
@@ -991,7 +970,6 @@
         mNotificationPanel = mStatusBarWindow.findViewById(R.id.notification_panel);
 
         mStackScroller = mStatusBarWindow.findViewById(R.id.notification_stack_scroller);
-        mZenController.addCallback(this);
         NotificationListContainer notifListContainer = (NotificationListContainer) mStackScroller;
         mNotificationLogger.setUpWithContainer(notifListContainer);
 
@@ -1051,8 +1029,10 @@
                             mStatusBarStateController, mKeyguardBypassController,
                             mKeyguardStateController, mWakeUpCoordinator, mCommandQueue);
                     mHeadsUpAppearanceController.readFrom(oldController);
+
+                    mLightsOutNotifController.setLightsOutNotifView(
+                            mStatusBarView.findViewById(R.id.notification_lights_out));
                     mStatusBarWindowViewController.setStatusBarView(mStatusBarView);
-                    updateAreThereNotifications();
                     checkBarModes();
                 }).getFragmentManager()
                 .beginTransaction()
@@ -1249,8 +1229,7 @@
                         mContext,
                         mAllowNotificationLongPress,
                         mKeyguardBypassController,
-                        mStatusBarStateController,
-                        mNotifLog);
+                        mStatusBarStateController);
 
         mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanel,
                 mHeadsUpManager, mStatusBarWindow, mStackScroller, mDozeScrimController,
@@ -1261,10 +1240,8 @@
                 new NotificationListController(
                         mEntryManager,
                         (NotificationListContainer) mStackScroller,
-                        mForegroundServiceController,
                         mDeviceProvisionedController);
 
-        mAppOpsController.addCallback(APP_OPS, this);
         mNotificationShelf.setOnActivatedListener(mPresenter);
         mRemoteInputManager.getController().addCallback(mStatusBarWindowController);
 
@@ -1422,17 +1399,17 @@
     protected void startKeyguard() {
         Trace.beginSection("StatusBar#startKeyguard");
         mBiometricUnlockController = mBiometricUnlockControllerLazy.get();
-        mStatusBarKeyguardViewManager = mKeyguardViewMediator.registerStatusBar(this,
-                getBouncerContainer(), mNotificationPanel, mBiometricUnlockController,
+        mStatusBarKeyguardViewManager.registerStatusBar(
+                /* statusBar= */ this, getBouncerContainer(), mNotificationPanel,
+                mBiometricUnlockController, mDismissCallbackRegistry,
                 mStatusBarWindow.findViewById(R.id.lock_icon_container), mStackScroller,
-                mKeyguardBypassController);
+                mKeyguardBypassController, mFalsingManager);
         mKeyguardIndicationController
                 .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
         mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
         mRemoteInputManager.getController().addCallback(mStatusBarKeyguardViewManager);
         mDynamicPrivacyController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
 
-        mKeyguardViewMediatorCallback = mKeyguardViewMediator.getViewMediatorCallback();
         mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
         mMediaManager.setBiometricUnlockController(mBiometricUnlockController);
         Dependency.get(KeyguardDismissUtil.class).setDismissHandler(this::executeWhenUnlocked);
@@ -1470,8 +1447,8 @@
                     : SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
             return mRecents.splitPrimaryTask(createMode, null, metricsDockAction);
         } else {
-            Divider divider = getComponent(Divider.class);
-            if (divider != null) {
+            if (mDividerOptional.isPresent()) {
+                Divider divider = mDividerOptional.get();
                 if (divider.isMinimized() && !divider.isHomeStackResizable()) {
                     // Undocking from the minimized state is not supported
                     return false;
@@ -1519,10 +1496,6 @@
         mQSPanel.clickTile(tile);
     }
 
-    public boolean areNotificationsHidden() {
-        return mZenController.areNotificationsHiddenInShade();
-    }
-
     /**
      * Request a notification update
      * @param reason why we're requesting a notification update
@@ -1540,38 +1513,6 @@
         }
     }
 
-    public void updateAreThereNotifications() {
-        if (SPEW) {
-            final boolean clearable = hasActiveNotifications() &&
-                    mNotificationPanel.hasActiveClearableNotifications();
-            Log.d(TAG, "updateAreThereNotifications: N=" +
-                    mEntryManager.getNotificationData().getActiveNotifications().size() + " any=" +
-                    hasActiveNotifications() + " clearable=" + clearable);
-        }
-
-        if (mStatusBarView != null) {
-            final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
-            final boolean showDot = hasActiveNotifications() && !areLightsOn();
-            if (showDot != (nlo.getAlpha() == 1.0f)) {
-                if (showDot) {
-                    nlo.setAlpha(0f);
-                    nlo.setVisibility(View.VISIBLE);
-                }
-                nlo.animate()
-                        .alpha(showDot ? 1 : 0)
-                        .setDuration(showDot ? 750 : 250)
-                        .setInterpolator(new AccelerateInterpolator(2.0f))
-                        .setListener(showDot ? null : new AnimatorListenerAdapter() {
-                            @Override
-                            public void onAnimationEnd(Animator _a) {
-                                nlo.setVisibility(View.GONE);
-                            }
-                        })
-                        .start();
-            }
-        }
-    }
-
     private void updateReportRejectedTouchVisibility() {
         if (mReportRejectedTouch == null) {
             return;
@@ -2300,14 +2241,8 @@
             return;
         }
         boolean barModeChanged = false;
-        final int diff = mAppearance ^ appearance;
         if (mAppearance != appearance) {
             mAppearance = appearance;
-
-            // update low profile
-            if ((diff & APPEARANCE_LOW_PROFILE_BARS) != 0) {
-                updateAreThereNotifications();
-            }
             barModeChanged = updateBarMode(barMode(mTransientShown, appearance));
         }
         mLightBarController.onStatusBarAppearanceChanged(appearanceRegions, barModeChanged,
@@ -2488,10 +2423,6 @@
         return mAppImmersive;
     }
 
-    private boolean areLightsOn() {
-        return 0 == (mAppearance & APPEARANCE_LOW_PROFILE_BARS);
-    }
-
     public static String viewInfo(View v) {
         return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
                 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
@@ -2515,10 +2446,6 @@
         pw.print("  mStatusBarMode=");
         pw.println(BarTransitions.modeToString(mStatusBarMode));
         pw.print("  mDozing="); pw.println(mDozing);
-        pw.print("  mZenMode=");
-        pw.println(Settings.Global.zenModeToString(Settings.Global.getInt(
-                mContext.getContentResolver(), Settings.Global.ZEN_MODE,
-                Settings.Global.ZEN_MODE_OFF)));
         pw.print("  mWallpaperSupported= "); pw.println(mWallpaperSupported);
 
         if (mStatusBarView != null) {
@@ -2555,8 +2482,6 @@
         final boolean lightWpTheme = mContext.getThemeResId() == R.style.Theme_SystemUI_Light;
         pw.println("    light wallpaper theme: " + lightWpTheme);
 
-        mDozeLog.dump(pw);
-
         if (mKeyguardIndicationController != null) {
             mKeyguardIndicationController.dump(fd, pw, args);
         }
@@ -3945,14 +3870,14 @@
     @Override
     public void appTransitionCancelled(int displayId) {
         if (displayId == mDisplayId) {
-            getComponent(Divider.class).onAppTransitionFinished();
+            mDividerOptional.ifPresent(Divider::onAppTransitionFinished);
         }
     }
 
     @Override
     public void appTransitionFinished(int displayId) {
         if (displayId == mDisplayId) {
-            getComponent(Divider.class).onAppTransitionFinished();
+            mDividerOptional.ifPresent(Divider::onAppTransitionFinished);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 8683586..31d0362 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -42,7 +42,6 @@
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.settingslib.animation.AppearAnimationUtils;
 import com.android.systemui.DejankUtils;
-import com.android.systemui.Dependency;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
@@ -63,12 +62,16 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 /**
  * Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back
  * via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done,
  * which is in turn, reported to this class by the current
  * {@link com.android.keyguard.KeyguardViewBase}.
  */
+@Singleton
 public class StatusBarKeyguardViewManager implements RemoteInputController.Callback,
         StatusBarStateController.StateListener, ConfigurationController.ConfigurationListener,
         PanelExpansionListener, NavigationModeController.ModeChangedListener {
@@ -167,13 +170,11 @@
 
     // Dismiss action to be launched when we stop dozing or the keyguard is gone.
     private DismissWithActionRequest mPendingWakeupAction;
-    private final KeyguardStateController mKeyguardStateController = Dependency.get(
-            KeyguardStateController.class);
-    private final NotificationMediaManager mMediaManager =
-            Dependency.get(NotificationMediaManager.class);
-    private final SysuiStatusBarStateController mStatusBarStateController =
-            (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class);
+    private final KeyguardStateController mKeyguardStateController;
+    private final NotificationMediaManager mMediaManager;
+    private final SysuiStatusBarStateController mStatusBarStateController;
     private final DockManager mDockManager;
+    private final KeyguardUpdateMonitor mKeyguardUpdateManager;
     private KeyguardBypassController mBypassController;
 
     private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
@@ -189,18 +190,33 @@
         }
     };
 
-    public StatusBarKeyguardViewManager(Context context, ViewMediatorCallback callback,
-            LockPatternUtils lockPatternUtils) {
+    @Inject
+    public StatusBarKeyguardViewManager(
+            Context context,
+            ViewMediatorCallback callback,
+            LockPatternUtils lockPatternUtils,
+            SysuiStatusBarStateController sysuiStatusBarStateController,
+            ConfigurationController configurationController,
+            KeyguardUpdateMonitor keyguardUpdateMonitor,
+            NavigationModeController navigationModeController,
+            DockManager dockManager,
+            StatusBarWindowController statusBarWindowController,
+            KeyguardStateController keyguardStateController,
+            NotificationMediaManager notificationMediaManager) {
         mContext = context;
         mViewMediatorCallback = callback;
         mLockPatternUtils = lockPatternUtils;
-        mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
-        Dependency.get(KeyguardUpdateMonitor.class).registerCallback(mUpdateMonitorCallback);
+        mStatusBarWindowController = statusBarWindowController;
+        mKeyguardStateController = keyguardStateController;
+        mMediaManager = notificationMediaManager;
+        mKeyguardUpdateManager = keyguardUpdateMonitor;
+        mKeyguardUpdateManager.registerCallback(mUpdateMonitorCallback);
+        mStatusBarStateController = sysuiStatusBarStateController;
         mStatusBarStateController.addCallback(this);
-        Dependency.get(ConfigurationController.class).addCallback(this);
+        configurationController.addCallback(this);
         mGesturalNav = QuickStepContract.isGesturalMode(
-                Dependency.get(NavigationModeController.class).addListener(this));
-        mDockManager = Dependency.get(DockManager.class);
+                navigationModeController.addListener(this));
+        mDockManager = dockManager;
         if (mDockManager != null) {
             mDockManager.addListener(mDockEventListener);
             mIsDocked = mDockManager.isDocked();
@@ -409,7 +425,7 @@
             } else {
                 showBouncerOrKeyguard(hideBouncerWhenShowing);
             }
-            Dependency.get(KeyguardUpdateMonitor.class).sendKeyguardReset();
+            mKeyguardUpdateManager.sendKeyguardReset();
             updateStates();
         }
     }
@@ -547,7 +563,7 @@
                 mKeyguardStateController.isOccluded());
         launchPendingWakeupAction();
 
-        if (Dependency.get(KeyguardUpdateMonitor.class).needsSlowUnlockTransition()) {
+        if (mKeyguardUpdateManager.needsSlowUnlockTransition()) {
             fadeoutDuration = KEYGUARD_DISMISS_DURATION_LOCKED;
         }
         long uptimeMillis = SystemClock.uptimeMillis();
@@ -800,12 +816,11 @@
             updateLockIcon();
         }
 
-        KeyguardUpdateMonitor updateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
         if ((showing && !occluded) != (mLastShowing && !mLastOccluded) || mFirstUpdate) {
-            updateMonitor.onKeyguardVisibilityChanged(showing && !occluded);
+            mKeyguardUpdateManager.onKeyguardVisibilityChanged(showing && !occluded);
         }
         if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
-            updateMonitor.sendKeyguardBouncerChanged(bouncerShowing);
+            mKeyguardUpdateManager.sendKeyguardBouncerChanged(bouncerShowing);
         }
 
         mFirstUpdate = false;
@@ -889,8 +904,7 @@
     }
 
     public boolean isGoingToNotificationShade() {
-        return ((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class))
-                .leaveOpenOnKeyguardHide();
+        return mStatusBarStateController.leaveOpenOnKeyguardHide();
     }
 
     public boolean isSecure(int userId) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
index 67f6a0c..9811f96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarModule.java
@@ -26,19 +26,19 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.ForegroundServiceController;
+import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.doze.DozeLog;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.FeatureFlags;
 import com.android.systemui.statusbar.NavigationBarController;
@@ -60,7 +60,6 @@
 import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.logging.NotifLog;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -71,7 +70,8 @@
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
 import com.android.systemui.statusbar.policy.RemoteInputUriController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
+
+import java.util.Optional;
 
 import javax.inject.Named;
 import javax.inject.Singleton;
@@ -97,7 +97,6 @@
             AutoHideController autoHideController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             StatusBarIconController statusBarIconController,
-            DozeLog dozeLog,
             PulseExpansionHandler pulseExpansionHandler,
             NotificationWakeUpCoordinator notificationWakeUpCoordinator,
             KeyguardBypassController keyguardBypassController,
@@ -115,10 +114,7 @@
             NotificationEntryManager notificationEntryManager,
             NotificationInterruptionStateProvider notificationInterruptionStateProvider,
             NotificationViewHierarchyManager notificationViewHierarchyManager,
-            ForegroundServiceController foregroundServiceController,
-            AppOpsController appOpsController,
             KeyguardViewMediator keyguardViewMediator,
-            ZenModeController zenModeController,
             NotificationAlertingManager notificationAlertingManager,
             DisplayMetrics displayMetrics,
             MetricsLogger metricsLogger,
@@ -145,7 +141,6 @@
             ConfigurationController configurationController,
             StatusBarWindowController statusBarWindowController,
             StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder,
-            NotifLog notifLog,
             DozeParameters dozeParameters,
             ScrimController scrimController,
             @Nullable KeyguardLiftController keyguardLiftController,
@@ -157,7 +152,12 @@
             CommandQueue commandQueue,
             PluginManager pluginManager,
             RemoteInputUriController remoteInputUriController,
-            SuperStatusBarViewFactory superStatusBarViewFactory) {
+            Optional<Divider> dividerOptional,
+            LightsOutNotifController lightsOutNotifController,
+            SuperStatusBarViewFactory superStatusBarViewFactory,
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+            ViewMediatorCallback viewMediatorCallback,
+            DismissCallbackRegistry dismissCallbackRegistry) {
         return new StatusBar(
                 context,
                 featureFlags,
@@ -165,7 +165,6 @@
                 autoHideController,
                 keyguardUpdateMonitor,
                 statusBarIconController,
-                dozeLog,
                 pulseExpansionHandler,
                 notificationWakeUpCoordinator,
                 keyguardBypassController,
@@ -183,10 +182,7 @@
                 notificationEntryManager,
                 notificationInterruptionStateProvider,
                 notificationViewHierarchyManager,
-                foregroundServiceController,
-                appOpsController,
                 keyguardViewMediator,
-                zenModeController,
                 notificationAlertingManager,
                 displayMetrics,
                 metricsLogger,
@@ -213,7 +209,6 @@
                 configurationController,
                 statusBarWindowController,
                 statusBarWindowViewControllerBuilder,
-                notifLog,
                 dozeParameters,
                 scrimController,
                 keyguardLiftController,
@@ -225,6 +220,11 @@
                 commandQueue,
                 pluginManager,
                 remoteInputUriController,
-                superStatusBarViewFactory);
+                dividerOptional,
+                lightsOutNotifController,
+                superStatusBarViewFactory,
+                statusBarKeyguardViewManager,
+                viewMediatorCallback,
+                dismissCallbackRegistry);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 02e5ebf..38ff862 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -79,7 +79,8 @@
 
 public class StatusBarNotificationPresenter implements NotificationPresenter,
         ConfigurationController.ConfigurationListener,
-        NotificationRowBinderImpl.BindRowCallback {
+        NotificationRowBinderImpl.BindRowCallback,
+        CommandQueue.Callbacks {
 
     private final LockscreenGestureLogger mLockscreenGestureLogger =
             Dependency.get(LockscreenGestureLogger.class);
@@ -185,17 +186,6 @@
         Dependency.get(InitController.class).addPostInitTask(() -> {
             NotificationEntryListener notificationEntryListener = new NotificationEntryListener() {
                 @Override
-                public void onNotificationAdded(NotificationEntry entry) {
-                    // Recalculate the position of the sliding windows and the titles.
-                    mShadeController.updateAreThereNotifications();
-                }
-
-                @Override
-                public void onPostEntryUpdated(NotificationEntry entry) {
-                    mShadeController.updateAreThereNotifications();
-                }
-
-                @Override
                 public void onEntryRemoved(
                         @Nullable NotificationEntry entry,
                         NotificationVisibility visibility,
@@ -333,7 +323,6 @@
                 }
             }
         }
-        mShadeController.updateAreThereNotifications();
     }
 
     public boolean hasActiveNotifications() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
index 768bd13..bb4387eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
@@ -41,6 +41,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.systemui.appops.AppOpsController;
 import com.android.systemui.statusbar.NotificationEntryBuilder;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -52,6 +53,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -59,12 +62,13 @@
     private ForegroundServiceController mFsc;
     private ForegroundServiceNotificationListener mListener;
     private NotificationEntryListener mEntryListener;
-    private NotificationEntryManager mEntryManager;
+    @Mock private NotificationEntryManager mEntryManager;
+    @Mock private AppOpsController mAppOpsController;
 
     @Before
     public void setUp() throws Exception {
-        mEntryManager = mock(NotificationEntryManager.class);
-        mFsc = new ForegroundServiceController(mEntryManager);
+        MockitoAnnotations.initMocks(this);
+        mFsc = new ForegroundServiceController(mEntryManager, mAppOpsController);
         mListener = new ForegroundServiceNotificationListener(
                 mContext, mFsc, mEntryManager);
         ArgumentCaptor<NotificationEntryListener> entryListenerCaptor =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index c815279..cbfcfdd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -18,14 +18,12 @@
 
 import static android.view.WindowManagerPolicyConstants.OFF_BECAUSE_OF_USER;
 
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.admin.DevicePolicyManager;
-import android.content.Context;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
@@ -34,8 +32,6 @@
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.ViewMediatorCallback;
-import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.classifier.FalsingManagerFake;
@@ -60,8 +56,8 @@
     private @Mock KeyguardUpdateMonitor mUpdateMonitor;
     private @Mock StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private @Mock StatusBarWindowController mStatusBarWindowController;
-    private @Mock SystemUIFactory mSystemUIFactory;
     private @Mock BroadcastDispatcher mBroadcastDispatcher;
+    private @Mock DismissCallbackRegistry mDismissCallbackRegistry;
 
     private FalsingManagerFake mFalsingManager;
 
@@ -76,15 +72,11 @@
                 mStatusBarWindowController);
 
         when(mLockPatternUtils.getDevicePolicyManager()).thenReturn(mDevicePolicyManager);
-        when(mSystemUIFactory.createStatusBarKeyguardViewManager(
-                any(Context.class),
-                any(ViewMediatorCallback.class),
-                any(LockPatternUtils.class))).thenReturn(mStatusBarKeyguardViewManager);
 
         TestableLooper.get(this).runWithLooper(() -> {
             mViewMediator = new KeyguardViewMediator(
                     mContext, mFalsingManager, mLockPatternUtils, mBroadcastDispatcher,
-                    mSystemUIFactory);
+                    () -> mStatusBarKeyguardViewManager, mDismissCallbackRegistry);
         });
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
new file mode 100644
index 0000000..99850e7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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 com.android.systemui.screenshot;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Notification;
+import android.graphics.Bitmap;
+import android.os.Handler;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SystemUIFactory;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+/**
+ * Tests for exception handling and  bitmap configuration in adding smart actions to Screenshot
+ * Notification.
+ */
+public class ScreenshotNotificationSmartActionsTest extends SysuiTestCase {
+    private ScreenshotNotificationSmartActionsProvider mSmartActionsProvider;
+    private Handler mHandler;
+
+    @Before
+    public void setup() {
+        mSmartActionsProvider = mock(
+                ScreenshotNotificationSmartActionsProvider.class);
+        mHandler = mock(Handler.class);
+    }
+
+    // Tests any exception thrown in getting smart actions future does not affect regular
+    // screenshot flow.
+    @Test
+    public void testExceptionHandlingInGetSmartActionsFuture()
+            throws Exception {
+        Bitmap bitmap = mock(Bitmap.class);
+        when(bitmap.getConfig()).thenReturn(Bitmap.Config.HARDWARE);
+        ScreenshotNotificationSmartActionsProvider smartActionsProvider = mock(
+                ScreenshotNotificationSmartActionsProvider.class);
+        when(smartActionsProvider.getActions(any(), any(), any(), any(), any(),
+                eq(false))).thenThrow(
+                RuntimeException.class);
+        CompletableFuture<List<Notification.Action>> smartActionsFuture =
+                GlobalScreenshot.getSmartActionsFuture(mContext, bitmap,
+                        smartActionsProvider, mHandler, true, false);
+        Assert.assertNotNull(smartActionsFuture);
+        List<Notification.Action> smartActions = smartActionsFuture.get(5, TimeUnit.MILLISECONDS);
+        Assert.assertEquals(Collections.emptyList(), smartActions);
+    }
+
+    // Tests any exception thrown in waiting for smart actions future to complete does
+    // not affect regular screenshot flow.
+    @Test
+    public void testExceptionHandlingInGetSmartActions()
+            throws Exception {
+        CompletableFuture<List<Notification.Action>> smartActionsFuture = mock(
+                CompletableFuture.class);
+        int timeoutMs = 1000;
+        when(smartActionsFuture.get(timeoutMs, TimeUnit.MILLISECONDS)).thenThrow(
+                RuntimeException.class);
+        List<Notification.Action> actions = GlobalScreenshot.getSmartActions(
+                smartActionsFuture, timeoutMs);
+        Assert.assertEquals(Collections.emptyList(), actions);
+    }
+
+    // Tests for a non-hardware bitmap, ScreenshotNotificationSmartActionsProvider is never invoked
+    // and a completed future is returned.
+    @Test
+    public void testUnsupportedBitmapConfiguration()
+            throws Exception {
+        Bitmap bitmap = mock(Bitmap.class);
+        when(bitmap.getConfig()).thenReturn(Bitmap.Config.RGB_565);
+        CompletableFuture<List<Notification.Action>> smartActionsFuture =
+                GlobalScreenshot.getSmartActionsFuture(mContext, bitmap,
+                        mSmartActionsProvider, mHandler, true, true);
+        verify(mSmartActionsProvider, never()).getActions(any(), any(), any(), any(), any(),
+                eq(false));
+        Assert.assertNotNull(smartActionsFuture);
+        List<Notification.Action> smartActions = smartActionsFuture.get(5, TimeUnit.MILLISECONDS);
+        Assert.assertEquals(Collections.emptyList(), smartActions);
+    }
+
+    // Tests for a hardware bitmap, ScreenshotNotificationSmartActionsProvider is invoked once.
+    @Test
+    public void testScreenshotNotificationSmartActionsProviderInvokedOnce() {
+        Bitmap bitmap = mock(Bitmap.class);
+        when(bitmap.getConfig()).thenReturn(Bitmap.Config.HARDWARE);
+        GlobalScreenshot.getSmartActionsFuture(mContext, bitmap, mSmartActionsProvider,
+                mHandler, true, true);
+        verify(mSmartActionsProvider, times(1))
+                .getActions(any(), any(), any(), any(), any(), eq(true));
+    }
+
+    // Tests for a hardware bitmap, a completed future is returned.
+    @Test
+    public void testSupportedBitmapConfiguration()
+            throws Exception {
+        Bitmap bitmap = mock(Bitmap.class);
+        when(bitmap.getConfig()).thenReturn(Bitmap.Config.HARDWARE);
+        ScreenshotNotificationSmartActionsProvider actionsProvider =
+                SystemUIFactory.getInstance().createScreenshotNotificationSmartActionsProvider();
+        CompletableFuture<List<Notification.Action>> smartActionsFuture =
+                GlobalScreenshot.getSmartActionsFuture(mContext, bitmap,
+                        actionsProvider,
+                        mHandler, true, true);
+        Assert.assertNotNull(smartActionsFuture);
+        List<Notification.Action> smartActions = smartActionsFuture.get(5, TimeUnit.MILLISECONDS);
+        Assert.assertEquals(smartActions.size(), 0);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index cf6fd4a..d9be8d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -34,8 +34,11 @@
 import android.app.trust.TrustManager;
 import android.content.Context;
 import android.graphics.Color;
+import android.hardware.biometrics.BiometricSourceType;
+import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Looper;
+import android.os.UserManager;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -51,6 +54,7 @@
 import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
 import com.android.systemui.statusbar.phone.LockIcon;
 import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.AccessibilityController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.wakelock.WakeLockFake;
@@ -84,6 +88,10 @@
     private StatusBarStateController mStatusBarStateController;
     @Mock
     private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    @Mock
+    private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    @Mock
+    private UserManager mUserManager;
     private KeyguardIndicationTextView mTextView;
 
     private KeyguardIndicationController mController;
@@ -97,9 +105,13 @@
         mTextView = new KeyguardIndicationTextView(mContext);
 
         mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
+        mContext.addMockSystemService(UserManager.class, mUserManager);
         mContext.addMockSystemService(Context.TRUST_SERVICE, mock(TrustManager.class));
         mContext.addMockSystemService(Context.FINGERPRINT_SERVICE, mock(FingerprintManager.class));
 
+        when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
+        when(mKeyguardUpdateMonitor.isScreenOn()).thenReturn(true);
+        when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
         when(mIndicationArea.findViewById(R.id.keyguard_indication_text)).thenReturn(mTextView);
 
         mWakeLock = new WakeLockFake();
@@ -112,6 +124,7 @@
         mController = new KeyguardIndicationController(mContext, mIndicationArea, mLockIcon,
                 mLockPatternUtils, mWakeLock, mShadeController, mAccessibilityController,
                 mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor);
+        mController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
     }
 
     @Test
@@ -167,6 +180,49 @@
     }
 
     @Test
+    public void transientIndication_visibleWhenDozing_unlessSwipeUp_fromHelp() {
+        createController();
+        String message = "A message";
+
+        mController.setVisible(true);
+        mController.getKeyguardCallback().onBiometricHelp(
+                KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED, message,
+                BiometricSourceType.FACE);
+        assertThat(mTextView.getText()).isEqualTo(message);
+        mController.setDozing(true);
+
+        assertThat(mTextView.getText()).isNotEqualTo(message);
+    }
+
+    @Test
+    public void transientIndication_visibleWhenDozing_unlessSwipeUp_fromError() {
+        createController();
+        String message = mContext.getString(R.string.keyguard_unlock);
+
+        mController.setVisible(true);
+        mController.getKeyguardCallback().onBiometricError(FaceManager.FACE_ERROR_TIMEOUT,
+                "A message", BiometricSourceType.FACE);
+
+        assertThat(mTextView.getText()).isEqualTo(message);
+        mController.setDozing(true);
+
+        assertThat(mTextView.getText()).isNotEqualTo(message);
+    }
+
+    @Test
+    public void transientIndication_swipeUpToRetry() {
+        createController();
+        String message = mContext.getString(R.string.keyguard_retry);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
+
+        mController.setVisible(true);
+        mController.getKeyguardCallback().onBiometricError(FaceManager.FACE_ERROR_TIMEOUT,
+                "A message", BiometricSourceType.FACE);
+
+        verify(mStatusBarKeyguardViewManager).showBouncerMessage(eq(message), any());
+    }
+
+    @Test
     public void lockIcon_click() {
         createController();
 
@@ -190,6 +246,7 @@
     public void updateMonitor_listenerUpdatesIndication() {
         createController();
         String restingIndication = "Resting indication";
+        reset(mKeyguardUpdateMonitor);
 
         mController.setVisible(true);
         assertThat(mTextView.getText()).isEqualTo(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index b2a5109..86ef6e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -258,8 +258,7 @@
         NotificationRowBinderImpl notificationRowBinder =
                 new NotificationRowBinderImpl(mContext, true, /* allowLongPress */
                         mock(KeyguardBypassController.class),
-                        mock(StatusBarStateController.class),
-                        mock(NotifLog.class));
+                        mock(StatusBarStateController.class));
         notificationRowBinder.setUpWithPresenter(
                 mPresenter, mListContainer, mHeadsUpManager, mEntryManager, mBindCallback);
         notificationRowBinder.setNotificationClicker(mock(NotificationClicker.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
index c2d2e31..cc56949 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
@@ -30,7 +30,6 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.NotificationEntryBuilder;
@@ -60,7 +59,6 @@
 
     @Mock private NotificationEntryManager mEntryManager;
     @Mock private NotificationListContainer mListContainer;
-    @Mock private ForegroundServiceController mForegroundServiceController;
     @Mock private DeviceProvisionedController mDeviceProvisionedController;
 
     @Captor private ArgumentCaptor<NotificationEntryListener> mEntryListenerCaptor;
@@ -88,7 +86,6 @@
         mController = new NotificationListController(
                 mEntryManager,
                 mListContainer,
-                mForegroundServiceController,
                 mDeviceProvisionedController);
         mController.bind();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 012ebf72..6f52e4a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -82,6 +82,7 @@
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarTest.TestableNotificationEntryManager;
 import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.util.DeviceConfigProxyFake;
 
 import org.junit.After;
@@ -123,6 +124,7 @@
     @Mock private MetricsLogger mMetricsLogger;
     @Mock private NotificationRoundnessManager mNotificationRoundnessManager;
     @Mock private KeyguardBypassController mKeyguardBypassController;
+    @Mock private ZenModeController mZenModeController;
     private TestableNotificationEntryManager mEntryManager;
     private int mOriginalInterruptionModelSetting;
 
@@ -173,7 +175,8 @@
                 mock(NotificationLockscreenUserManager.class),
                 mock(NotificationGutsManager.class),
                 new NotificationSectionsFeatureManager(new DeviceConfigProxyFake(), mContext),
-                mock(PeopleHubSectionFooterViewAdapter.class));
+                mock(PeopleHubSectionFooterViewAdapter.class),
+                mZenModeController);
         mStackScroller = spy(mStackScrollerInternal);
         mStackScroller.setShelf(notificationShelf);
         mStackScroller.setStatusBar(mBar);
@@ -211,7 +214,7 @@
     @Test
     public void updateEmptyView_dndSuppressing() {
         when(mEmptyShadeView.willBeGone()).thenReturn(true);
-        when(mBar.areNotificationsHidden()).thenReturn(true);
+        when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(true);
 
         mStackScroller.updateEmptyShadeView(true);
 
@@ -222,7 +225,7 @@
     public void updateEmptyView_dndNotSuppressing() {
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
         when(mEmptyShadeView.willBeGone()).thenReturn(true);
-        when(mBar.areNotificationsHidden()).thenReturn(false);
+        when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(false);
 
         mStackScroller.updateEmptyShadeView(true);
 
@@ -233,11 +236,11 @@
     public void updateEmptyView_noNotificationsToDndSuppressing() {
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
         when(mEmptyShadeView.willBeGone()).thenReturn(true);
-        when(mBar.areNotificationsHidden()).thenReturn(false);
+        when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(false);
         mStackScroller.updateEmptyShadeView(true);
         verify(mEmptyShadeView).setText(R.string.empty_shade_text);
 
-        when(mBar.areNotificationsHidden()).thenReturn(true);
+        when(mZenModeController.areNotificationsHiddenInShade()).thenReturn(true);
         mStackScroller.updateEmptyShadeView(true);
         verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java
new file mode 100644
index 0000000..64c1b51
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightsOutNotifControllerTest.java
@@ -0,0 +1,251 @@
+/*
+ * 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 com.android.systemui.statusbar.phone;
+
+import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.Display;
+import android.view.View;
+import android.view.ViewPropertyAnimator;
+import android.view.WindowManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.notification.NotificationEntryListener;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.NotificationData;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class LightsOutNotifControllerTest extends SysuiTestCase {
+    private static final int LIGHTS_ON = 0;
+    private static final int LIGHTS_OUT = APPEARANCE_LOW_PROFILE_BARS;
+
+    @Mock private NotificationEntryManager mEntryManager;
+    @Mock private NotificationData mNotificationData;
+    @Mock private CommandQueue mCommandQueue;
+    @Mock private WindowManager mWindowManager;
+    @Mock private Display mDisplay;
+
+    @Captor private ArgumentCaptor<NotificationEntryListener> mListenerCaptor;
+    @Captor private ArgumentCaptor<CommandQueue.Callbacks> mCallbacksCaptor;
+
+    private View mLightsOutView;
+    private LightsOutNotifController mLightsOutNotifController;
+    private ArrayList<NotificationEntry> mActiveNotifications = new ArrayList<>();
+    private int mDisplayId;
+    private NotificationEntryListener mEntryListener;
+    private CommandQueue.Callbacks mCallbacks;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mDisplayId = mContext.getDisplayId();
+        mLightsOutView = new View(mContext);
+        when(mEntryManager.getNotificationData()).thenReturn(mNotificationData);
+        when(mNotificationData.getActiveNotifications()).thenReturn(mActiveNotifications);
+        when(mWindowManager.getDefaultDisplay()).thenReturn(mDisplay);
+        when(mDisplay.getDisplayId()).thenReturn(mDisplayId);
+
+        mLightsOutNotifController = new LightsOutNotifController(mWindowManager, mEntryManager,
+                mCommandQueue);
+        mLightsOutNotifController.setLightsOutNotifView(mLightsOutView);
+
+        // Capture the entry listener object so we can simulate events in tests below
+        verify(mEntryManager).addNotificationEntryListener(mListenerCaptor.capture());
+        mEntryListener = checkNotNull(mListenerCaptor.getValue());
+
+        // Capture the callback object so we can simulate callback events in tests below
+        verify(mCommandQueue).addCallback(mCallbacksCaptor.capture());
+        mCallbacks = checkNotNull(mCallbacksCaptor.getValue());
+    }
+
+    @Test
+    public void testAreLightsOut_lightsOut() {
+        mCallbacks.onSystemBarAppearanceChanged(
+                mDisplayId /* display id */,
+                LIGHTS_OUT /* appearance */,
+                null /* appearanceRegions */,
+                false /* navbarColorManagedByIme */);
+        assertTrue(mLightsOutNotifController.areLightsOut());
+    }
+
+    @Test
+    public void testAreLightsOut_lightsOn() {
+        mCallbacks.onSystemBarAppearanceChanged(
+                mDisplayId /* display id */,
+                LIGHTS_ON /* appearance */,
+                null /* appearanceRegions */,
+                false /* navbarColorManagedByIme */);
+        assertFalse(mLightsOutNotifController.areLightsOut());
+    }
+
+    @Test
+    public void testIsShowingDot_visible() {
+        mLightsOutView.setVisibility(View.VISIBLE);
+        mLightsOutView.setAlpha(1.0f);
+        assertTrue(mLightsOutNotifController.isShowingDot());
+    }
+
+    @Test
+    public void testIsShowingDot_gone() {
+        mLightsOutView.setVisibility(View.GONE);
+        mLightsOutView.setAlpha(0f);
+        assertFalse(mLightsOutNotifController.isShowingDot());
+    }
+
+    @Test
+    public void testLightsOut_withNotifs_onSystemBarAppearanceChanged() {
+        // GIVEN active visible notifications
+        mActiveNotifications.add(mock(NotificationEntry.class));
+
+        // WHEN lights out
+        mCallbacks.onSystemBarAppearanceChanged(
+                mDisplayId /* display id */,
+                LIGHTS_OUT /* appearance */,
+                null /* appearanceRegions */,
+                false /* navbarColorManagedByIme */);
+
+        // THEN we should show dot
+        assertTrue(mLightsOutNotifController.shouldShowDot());
+        assertIsShowingDot(true);
+    }
+
+    @Test
+    public void testLightsOut_withoutNotifs_onSystemBarAppearanceChanged() {
+        // GIVEN no active visible notifications
+        mActiveNotifications.clear();
+
+        // WHEN lights out
+        mCallbacks.onSystemBarAppearanceChanged(
+                mDisplayId /* display id */,
+                LIGHTS_OUT /* appearance */,
+                null /* appearanceRegions */,
+                false /* navbarColorManagedByIme */);
+
+        // THEN we shouldn't show the dot
+        assertFalse(mLightsOutNotifController.shouldShowDot());
+        assertIsShowingDot(false);
+    }
+
+    @Test
+    public void testLightsOn_afterLightsOut_onSystemBarAppearanceChanged() {
+        // GIVEN active visible notifications
+        mActiveNotifications.add(mock(NotificationEntry.class));
+
+        // WHEN lights on
+        mCallbacks.onSystemBarAppearanceChanged(
+                mDisplayId /* display id */,
+                LIGHTS_ON /* appearance */,
+                null /* appearanceRegions */,
+                false /* navbarColorManagedByIme */);
+
+        // THEN we shouldn't show the dot
+        assertFalse(mLightsOutNotifController.shouldShowDot());
+        assertIsShowingDot(false);
+    }
+
+    @Test
+    public void testEntryAdded() {
+        // GIVEN no visible notifications and lights out
+        mActiveNotifications.clear();
+        mLightsOutNotifController.mAppearance = LIGHTS_OUT;
+        mLightsOutNotifController.updateLightsOutView();
+        assertIsShowingDot(false);
+
+        // WHEN an active notification is added
+        mActiveNotifications.add(mock(NotificationEntry.class));
+        assertTrue(mLightsOutNotifController.shouldShowDot());
+        mEntryListener.onNotificationAdded(mock(NotificationEntry.class));
+
+        // THEN we should see the dot view
+        assertIsShowingDot(true);
+    }
+
+    @Test
+    public void testEntryRemoved() {
+        // GIVEN a visible notification and lights out
+        mActiveNotifications.add(mock(NotificationEntry.class));
+        mLightsOutNotifController.mAppearance = LIGHTS_OUT;
+        mLightsOutNotifController.updateLightsOutView();
+        assertIsShowingDot(true);
+
+        // WHEN all active notifications are removed
+        mActiveNotifications.clear();
+        assertFalse(mLightsOutNotifController.shouldShowDot());
+        mEntryListener.onEntryRemoved(mock(NotificationEntry.class), null, false);
+
+        // THEN we shouldn't see the dot view
+        assertIsShowingDot(false);
+    }
+
+    @Test
+    public void testEntryUpdated() {
+        // GIVEN no visible notifications and lights out
+        mActiveNotifications.clear();
+        mLightsOutNotifController.mAppearance = LIGHTS_OUT;
+        mLightsOutNotifController.updateLightsOutView();
+        assertIsShowingDot(false);
+
+        // WHEN an active notification is added
+        mActiveNotifications.add(mock(NotificationEntry.class));
+        assertTrue(mLightsOutNotifController.shouldShowDot());
+        mEntryListener.onPostEntryUpdated(mock(NotificationEntry.class));
+
+        // THEN we should see the dot view
+        assertIsShowingDot(true);
+    }
+
+    private void assertIsShowingDot(boolean isShowing) {
+        // cancel the animation so we can check the end state
+        final ViewPropertyAnimator animation = mLightsOutView.animate();
+        if (animation != null) {
+            animation.cancel();
+        }
+
+        if (isShowing) {
+            assertTrue(mLightsOutNotifController.isShowingDot());
+        } else {
+            assertFalse(mLightsOutNotifController.isShowingDot());
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
index 1255001..9763675 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
@@ -79,6 +79,8 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.Optional;
+
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
@@ -95,6 +97,10 @@
     private SysUiState mMockSysUiState;
     @Mock
     private BroadcastDispatcher mBroadcastDispatcher;
+    @Mock
+    private Divider mDivider;
+    @Mock
+    private Recents mRecents;
 
     private AccessibilityManagerWrapper mAccessibilityWrapper =
             new AccessibilityManagerWrapper(mContext) {
@@ -152,16 +158,12 @@
 
     private void setupSysuiDependency() {
         mSysuiContext.putComponent(StatusBar.class, mock(StatusBar.class));
-        mSysuiContext.putComponent(Recents.class, mock(Recents.class));
-        mSysuiContext.putComponent(Divider.class, mock(Divider.class));
 
         Display display = new Display(DisplayManagerGlobal.getInstance(), EXTERNAL_DISPLAY_ID,
                 new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS);
         mSysuiTestableContextExternal = (SysuiTestableContext) mSysuiContext.createDisplayContext(
                 display);
         mSysuiTestableContextExternal.putComponent(StatusBar.class, mock(StatusBar.class));
-        mSysuiTestableContextExternal.putComponent(Recents.class, mock(Recents.class));
-        mSysuiTestableContextExternal.putComponent(Divider.class, mock(Divider.class));
 
         injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
         WindowManager windowManager = mock(WindowManager.class);
@@ -251,7 +253,9 @@
                 mock(StatusBarStateController.class),
                 mMockSysUiState,
                 mBroadcastDispatcher,
-                mCommandQueue);
+                mCommandQueue,
+                mDivider,
+                Optional.of(mRecents));
     }
 
     private class HostCallbacksForExternalDisplay extends
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 3e07cff..61e5058 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -41,12 +41,13 @@
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
+import com.android.systemui.dock.DockManager;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import org.junit.Before;
@@ -91,16 +92,21 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mDependency.injectMockDependency(StatusBarWindowController.class);
-        mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
-        mDependency.injectMockDependency(NotificationMediaManager.class);
-        mDependency.injectTestDependency(StatusBarStateController.class, mStatusBarStateController);
-        mDependency.injectTestDependency(KeyguardStateController.class, mKeyguardStateController);
         when(mLockIconContainer.getParent()).thenReturn(mock(ViewGroup.class));
         when(mLockIconContainer.animate()).thenReturn(mock(ViewPropertyAnimator.class,
                 RETURNS_DEEP_STUBS));
-        mStatusBarKeyguardViewManager = new TestableStatusBarKeyguardViewManager(getContext(),
-                mViewMediatorCallback, mLockPatternUtils);
+        mStatusBarKeyguardViewManager = new TestableStatusBarKeyguardViewManager(
+                getContext(),
+                mViewMediatorCallback,
+                mLockPatternUtils,
+                mStatusBarStateController,
+                mock(ConfigurationController.class),
+                mock(KeyguardUpdateMonitor.class),
+                mock(NavigationModeController.class),
+                mock(DockManager.class),
+                mock(StatusBarWindowController.class),
+                mKeyguardStateController,
+                mock(NotificationMediaManager.class));
         mStatusBarKeyguardViewManager.registerStatusBar(mStatusBar, mContainer,
                 mNotificationPanelView, mBiometrucUnlockController, mDismissCallbackRegistry,
                 mLockIconContainer, mNotificationContainer, mBypassController,
@@ -258,8 +264,19 @@
 
         public TestableStatusBarKeyguardViewManager(Context context,
                 ViewMediatorCallback callback,
-                LockPatternUtils lockPatternUtils) {
-            super(context, callback, lockPatternUtils);
+                LockPatternUtils lockPatternUtils,
+                SysuiStatusBarStateController sysuiStatusBarStateController,
+                ConfigurationController configurationController,
+                KeyguardUpdateMonitor keyguardUpdateMonitor,
+                NavigationModeController navigationModeController,
+                DockManager dockManager,
+                StatusBarWindowController statusBarWindowController,
+                KeyguardStateController keyguardStateController,
+                NotificationMediaManager notificationMediaManager) {
+            super(context, callback, lockPatternUtils, sysuiStatusBarStateController,
+                    configurationController, keyguardUpdateMonitor, navigationModeController,
+                    dockManager, statusBarWindowController, keyguardStateController,
+                    notificationMediaManager);
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index ecb2d81..62fd0c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -74,24 +74,23 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.Dependency;
-import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.InitController;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.appops.AppOpsController;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.doze.DozeLog;
+import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.FeatureFlags;
 import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -145,6 +144,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Optional;
 
 import dagger.Lazy;
 
@@ -198,13 +198,10 @@
     @Mock private AssistManager mAssistManager;
     @Mock private NotificationGutsManager mNotificationGutsManager;
     @Mock private NotificationMediaManager mNotificationMediaManager;
-    @Mock private ForegroundServiceController mForegroundServiceController;
-    @Mock private AppOpsController mAppOpsController;
     @Mock private NavigationBarController mNavigationBarController;
     @Mock private BypassHeadsUpNotifier mBypassHeadsUpNotifier;
     @Mock private SysuiColorExtractor mColorExtractor;
     @Mock private ColorExtractor.GradientColors mGradientColors;
-    @Mock private DozeLog mDozeLog;
     @Mock private PulseExpansionHandler mPulseExpansionHandler;
     @Mock private NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
     @Mock private KeyguardBypassController mKeyguardBypassController;
@@ -233,7 +230,11 @@
     @Mock private KeyguardLiftController mKeyguardLiftController;
     @Mock private CommandQueue mCommandQueue;
     @Mock private PluginManager mPluginManager;
+    @Mock private Divider mDivider;
     @Mock private SuperStatusBarViewFactory mSuperStatusBarViewFactory;
+    @Mock private LightsOutNotifController mLightsOutNotifController;
+    @Mock private ViewMediatorCallback mViewMediatorCallback;
+    @Mock private DismissCallbackRegistry mDismissCallbackRegistry;
 
     @Before
     public void setup() throws Exception {
@@ -308,7 +309,6 @@
                 mAutoHideController,
                 mKeyguardUpdateMonitor,
                 mStatusBarIconController,
-                mDozeLog,
                 mPulseExpansionHandler,
                 mNotificationWakeUpCoordinator,
                 mKeyguardBypassController,
@@ -330,10 +330,7 @@
                 entryManager,
                 mNotificationInterruptionStateProvider,
                 mNotificationViewHierarchyManager,
-                mForegroundServiceController,
-                mAppOpsController,
                 mKeyguardViewMediator,
-                mZenModeController,
                 mNotificationAlertingManager,
                 new DisplayMetrics(),
                 mMetricsLogger,
@@ -360,7 +357,6 @@
                 configurationController,
                 mStatusBarWindowController,
                 mStatusBarWindowViewControllerBuilder,
-                mNotifLog,
                 mDozeParameters,
                 mScrimController,
                 mKeyguardLiftController,
@@ -372,7 +368,12 @@
                 mCommandQueue,
                 mPluginManager,
                 mRemoteInputUriController,
-                mSuperStatusBarViewFactory);
+                Optional.of(mDivider),
+                mLightsOutNotifController,
+                mSuperStatusBarViewFactory,
+                mStatusBarKeyguardViewManager,
+                mViewMediatorCallback,
+                mDismissCallbackRegistry);
 
         when(mStatusBarWindowView.findViewById(R.id.lock_icon_container)).thenReturn(
                 mLockIconContainer);
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 067becb..8f1e156 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -335,6 +335,16 @@
             return new ComponentNameSet(setting).contains(component);
         }
 
+        @Override
+        public boolean isDeviceAssociated(String packageName, String macAddress, int userId) {
+            getContext().enforceCallingOrSelfPermission(
+                    android.Manifest.permission.MANAGE_COMPANION_DEVICES, "isDeviceAssociated");
+
+            return CollectionUtils.any(
+                    readAllAssociations(userId, packageName),
+                    a -> Objects.equals(a.deviceAddress, macAddress));
+        }
+
         private void checkCanCallNotificationApi(String callingPackage) throws RemoteException {
             checkCallerIsSystemOr(callingPackage);
             int userId = getCallingUserId();
diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java
index ecea251c..9cdb58d 100644
--- a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java
+++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsManagerService.java
@@ -16,7 +16,6 @@
 
 package com.android.server.contentsuggestions;
 
-import static android.Manifest.permission.BIND_CONTENT_SUGGESTIONS_SERVICE;
 import static android.Manifest.permission.MANAGE_CONTENT_SUGGESTIONS;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 
@@ -96,7 +95,7 @@
 
     private void enforceCaller(int userId, String func) {
         Context ctx = getContext();
-        if (ctx.checkCallingPermission(BIND_CONTENT_SUGGESTIONS_SERVICE) == PERMISSION_GRANTED
+        if (ctx.checkCallingPermission(MANAGE_CONTENT_SUGGESTIONS) == PERMISSION_GRANTED
                 || mServiceNameResolver.isTemporary(userId)
                 || mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid())) {
             return;
diff --git a/services/core/java/com/android/server/AppStateTracker.java b/services/core/java/com/android/server/AppStateTracker.java
index 486cd5f..7d5b176 100644
--- a/services/core/java/com/android/server/AppStateTracker.java
+++ b/services/core/java/com/android/server/AppStateTracker.java
@@ -699,14 +699,16 @@
                 Slog.d(TAG,"onAppIdleStateChanged: " + packageName + " u" + userId
                         + (idle ? " idle" : " active") + " " + bucket);
             }
-            final boolean changed;
-            if (bucket == UsageStatsManager.STANDBY_BUCKET_EXEMPTED) {
-                changed = mExemptedPackages.add(userId, packageName);
-            } else {
-                changed = mExemptedPackages.remove(userId, packageName);
-            }
-            if (changed) {
-                mHandler.notifyExemptChanged();
+            synchronized (mLock) {
+                final boolean changed;
+                if (bucket == UsageStatsManager.STANDBY_BUCKET_EXEMPTED) {
+                    changed = mExemptedPackages.add(userId, packageName);
+                } else {
+                    changed = mExemptedPackages.remove(userId, packageName);
+                }
+                if (changed) {
+                    mHandler.notifyExemptChanged();
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 0ea913f..4361676 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1903,6 +1903,7 @@
         }
 
         // Optimization - if there is no pending user switch, return current id
+        // (no need to acquire lock because mTargetUserId and mCurrentUserId are volatile)
         if (mTargetUserId == UserHandle.USER_NULL) {
             return getUserInfo(mCurrentUserId);
         }
@@ -1919,7 +1920,7 @@
 
     int getCurrentOrTargetUserId() {
         synchronized (mLock) {
-            return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
+            return getCurrentOrTargetUserIdLU();
         }
     }
 
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 2e36a43..7e9a17b 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -47,8 +47,8 @@
 import android.app.AppOpsManager.HistoricalOps;
 import android.app.AppOpsManager.HistoricalOpsRequest;
 import android.app.AppOpsManager.Mode;
-import android.app.AppOpsManager.OpFeatureEntry;
 import android.app.AppOpsManager.OpEntry;
+import android.app.AppOpsManager.OpFeatureEntry;
 import android.app.AppOpsManager.OpFlags;
 import android.app.AppOpsManagerInternal;
 import android.app.AppOpsManagerInternal.CheckOpsDelegate;
@@ -119,6 +119,12 @@
 import com.android.server.LocalServices;
 import com.android.server.LockGuard;
 
+import libcore.util.EmptyArray;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -138,12 +144,6 @@
 import java.util.Map;
 import java.util.Objects;
 
-import libcore.util.EmptyArray;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
 public class AppOpsService extends IAppOpsService.Stub {
     static final String TAG = "AppOps";
     static final boolean DEBUG = false;
@@ -2356,7 +2356,6 @@
     public void noteAsyncOp(String callingPackageName, int uid, String packageName, int opCode,
             String featureId, String message) {
         Preconditions.checkNotNull(message);
-        Preconditions.checkNotNull(packageName);
         verifyAndGetIsPrivileged(uid, packageName);
 
         verifyIncomingUid(uid);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5e76401..5b39fb6 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -8960,6 +8960,7 @@
 
     @VisibleForTesting
     void resetAssistantUserSet(int userId) {
+        checkCallerIsSystemOrShell();
         mAssistants.setUserSet(userId, false);
         handleSavePolicyFile();
     }
@@ -8967,12 +8968,14 @@
     @VisibleForTesting
     @Nullable
     ComponentName getApprovedAssistant(int userId) {
+        checkCallerIsSystemOrShell();
         List<ComponentName> allowedComponents = mAssistants.getAllowedComponents(userId);
         return CollectionUtils.firstOrNull(allowedComponents);
     }
 
     @VisibleForTesting
     protected void simulatePackageSuspendBroadcast(boolean suspend, String pkg) {
+        checkCallerIsSystemOrShell();
         // only use for testing: mimic receive broadcast that package is (un)suspended
         // but does not actually (un)suspend the package
         final Bundle extras = new Bundle();
@@ -8989,6 +8992,7 @@
 
     @VisibleForTesting
     protected void simulatePackageDistractionBroadcast(int flag, String[] pkgs) {
+        checkCallerIsSystemOrShell();
         // only use for testing: mimic receive broadcast that package is (un)distracting
         // but does not actually register that info with packagemanager
         final Bundle extras = new Bundle();
diff --git a/services/core/java/com/android/server/notification/NotificationShellCmd.java b/services/core/java/com/android/server/notification/NotificationShellCmd.java
index 979015d..50f16bc 100644
--- a/services/core/java/com/android/server/notification/NotificationShellCmd.java
+++ b/services/core/java/com/android/server/notification/NotificationShellCmd.java
@@ -32,11 +32,13 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.content.res.Resources;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
+import android.media.IRingtonePlayer;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Process;
@@ -56,6 +58,7 @@
  * Implementation of `cmd notification` in NotificationManagerService.
  */
 public class NotificationShellCmd extends ShellCommand {
+    private static final String TAG = "NotifShellCmd";
     private static final String USAGE = "usage: cmd notification SUBCMD [args]\n\n"
             + "SUBCMDs:\n"
             + "  allow_listener COMPONENT [user_id (current user if not specified)]\n"
@@ -98,18 +101,19 @@
             + "an <intentspec> is (broadcast|service|activity) <args>\n"
             + "  <args> are as described in `am start`";
 
-    public static final int NOTIFICATION_ID = 1138;
-    public static final String NOTIFICATION_PACKAGE = "android";
-    public static final String CHANNEL_ID = "shellcmd";
+    public static final int NOTIFICATION_ID = 2020;
+    public static final String CHANNEL_ID = "shell_cmd";
     public static final String CHANNEL_NAME = "Shell command";
     public static final int CHANNEL_IMP = NotificationManager.IMPORTANCE_DEFAULT;
 
     private final NotificationManagerService mDirectService;
     private final INotificationManager mBinderService;
+    private final PackageManager mPm;
 
     public NotificationShellCmd(NotificationManagerService service) {
         mDirectService = service;
         mBinderService = service.getBinderService();
+        mPm = mDirectService.getContext().getPackageManager();
     }
 
     @Override
@@ -117,6 +121,19 @@
         if (cmd == null) {
             return handleDefaultCommands(cmd);
         }
+        String callingPackage = null;
+        final int callingUid = Binder.getCallingUid();
+        long identity = Binder.clearCallingIdentity();
+        try {
+            String[] packages = mPm.getPackagesForUid(callingUid);
+            if (packages != null && packages.length > 0) {
+                callingPackage = packages[0];
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "failed to get caller pkg", e);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
         final PrintWriter pw = getOutPrintWriter();
         try {
             switch (cmd.replace('-', '_')) {
@@ -139,8 +156,7 @@
                             interruptionFilter = INTERRUPTION_FILTER_ALL;
                     }
                     final int filter = interruptionFilter;
-                    Binder.withCleanCallingIdentity(() -> mBinderService.setInterruptionFilter(
-                            mDirectService.getContext().getPackageName(), filter));
+                    mBinderService.setInterruptionFilter(callingPackage, filter);
                 }
                 break;
                 case "allow_dnd": {
@@ -258,7 +274,7 @@
                 }
                 case "post":
                 case "notify":
-                    doNotify(pw);
+                    doNotify(pw, callingPackage, callingUid);
                     break;
                 default:
                     return handleDefaultCommands(cmd);
@@ -270,27 +286,14 @@
         return 0;
     }
 
-    void ensureChannel() throws RemoteException {
-        final int uid = Process.myUid();
-        final int userid = UserHandle.getCallingUserId();
-        final long token = Binder.clearCallingIdentity();
-        try {
-            if (mBinderService.getNotificationChannelForPackage(NOTIFICATION_PACKAGE,
-                    uid, CHANNEL_ID, false) == null) {
-                final NotificationChannel chan = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME,
-                        CHANNEL_IMP);
-                Slog.v(NotificationManagerService.TAG,
-                        "creating shell channel for user " + userid + " uid " + uid + ": " + chan);
-                mBinderService.createNotificationChannelsForPackage(NOTIFICATION_PACKAGE, uid,
-                        new ParceledListSlice<NotificationChannel>(
-                                Collections.singletonList(chan)));
-                Slog.v(NotificationManagerService.TAG, "created channel: "
-                        + mBinderService.getNotificationChannelForPackage(NOTIFICATION_PACKAGE,
-                                uid, CHANNEL_ID, false));
-            }
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
+    void ensureChannel(String callingPackage, int callingUid) throws RemoteException {
+        final NotificationChannel channel =
+                new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, CHANNEL_IMP);
+        mBinderService.createNotificationChannels(callingPackage,
+                new ParceledListSlice<>(Collections.singletonList(channel)));
+        Slog.v(NotificationManagerService.TAG, "created channel: "
+                + mBinderService.getNotificationChannel(callingPackage,
+                UserHandle.getUserId(callingUid), callingPackage, CHANNEL_ID));
     }
 
     Icon parseIcon(Resources res, String encoded) throws IllegalArgumentException {
@@ -319,7 +322,8 @@
         return null;
     }
 
-    private int doNotify(PrintWriter pw) throws RemoteException, URISyntaxException {
+    private int doNotify(PrintWriter pw, String callingPackage, int callingUid)
+            throws RemoteException, URISyntaxException {
         final Context context = mDirectService.getContext();
         final Resources res = context.getResources();
         final Notification.Builder builder = new Notification.Builder(context, CHANNEL_ID);
@@ -513,26 +517,18 @@
             builder.setSmallIcon(smallIcon);
         }
 
-        ensureChannel();
+        ensureChannel(callingPackage, callingUid);
 
         final Notification n = builder.build();
         pw.println("posting:\n  " + n);
         Slog.v("NotificationManager", "posting: " + n);
 
-        final int userId = UserHandle.getCallingUserId();
-        final long token = Binder.clearCallingIdentity();
-        try {
-            mBinderService.enqueueNotificationWithTag(
-                    NOTIFICATION_PACKAGE, NOTIFICATION_PACKAGE,
-                    tag, NOTIFICATION_ID,
-                    n, userId);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
+        mBinderService.enqueueNotificationWithTag(callingPackage, callingPackage, tag,
+                NOTIFICATION_ID, n, UserHandle.getUserId(callingUid));
 
         if (verbose) {
             NotificationRecord nr = mDirectService.findNotificationLocked(
-                    NOTIFICATION_PACKAGE, tag, NOTIFICATION_ID, userId);
+                    callingPackage, tag, NOTIFICATION_ID, UserHandle.getUserId(callingUid));
             for (int tries = 3; tries-- > 0; ) {
                 if (nr != null) break;
                 try {
@@ -541,7 +537,7 @@
                 } catch (InterruptedException e) {
                 }
                 nr = mDirectService.findNotificationLocked(
-                        NOTIFICATION_PACKAGE, tag, NOTIFICATION_ID, userId);
+                        callingPackage, tag, NOTIFICATION_ID, UserHandle.getUserId(callingUid));
             }
             if (nr == null) {
                 pw.println("warning: couldn't find notification after enqueueing");
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 082b08deb..887dbb3 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -138,6 +138,13 @@
     private boolean mAreChannelsBypassingDnd;
     private boolean mHideSilentStatusBarIcons = DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS;
 
+    private static final String BADGING_FORCED_TRUE = "force_badging_true_for_bug";
+
+    // STOPSHIP (b/142218092) this should be removed before ship
+    static boolean wasBadgingForcedTrue(Context context) {
+        return Settings.Secure.getInt(context.getContentResolver(), BADGING_FORCED_TRUE, 0) != 0;
+    }
+
     public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
             ZenModeHelper zenHelper) {
         mContext = context;
@@ -145,6 +152,14 @@
         mRankingHandler = rankingHandler;
         mPm = pm;
 
+        // STOPSHIP (b/142218092) this should be removed before ship
+        if (!wasBadgingForcedTrue(context)) {
+            Settings.Secure.putInt(mContext.getContentResolver(),
+                    Settings.Secure.NOTIFICATION_BADGING,
+                    DEFAULT_SHOW_BADGE ? 1 : 0);
+            Settings.Secure.putInt(context.getContentResolver(), BADGING_FORCED_TRUE, 1);
+        }
+
         updateBadgingEnabled();
         updateBubblesEnabled();
         syncChannelsBypassingDnd(mContext.getUserId());
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 340720e..15e76fb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5694,11 +5694,9 @@
                     PackageSetting ps = it.next();
                     if (ps.getInstalled(userId)) {
                         res[i++] = ps.name;
-                    } else {
-                        res = ArrayUtils.removeElement(String.class, res, res[i]);
                     }
                 }
-                return res;
+                return ArrayUtils.trimToSize(res, i);
             } else if (obj instanceof PackageSetting) {
                 final PackageSetting ps = (PackageSetting) obj;
                 if (ps.getInstalled(userId)
@@ -22256,8 +22254,9 @@
                 continue;
             }
             final String packageName = ps.pkg.packageName;
-            // Skip over if system app
-            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+            // Skip over if system app or static shared library
+            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0
+                    || !TextUtils.isEmpty(ps.pkg.staticSharedLibName)) {
                 continue;
             }
             if (DEBUG_CLEAN_APKS) {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 3cc6428..dd561e1 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -77,6 +77,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.UserManagerInternal;
 import android.os.storage.StorageManager;
 import android.service.wallpaper.IWallpaperConnection;
 import android.service.wallpaper.IWallpaperEngine;
@@ -2818,12 +2819,19 @@
             return false;   // callingPackage was faked.
         }
 
+        // TODO(b/144048540): DPM needs to take into account the userId, not just the package.
         final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
         if (dpm.isDeviceOwnerApp(callingPackage) || dpm.isProfileOwnerApp(callingPackage)) {
             return true;
         }
-        final UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        return !um.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER);
+        final int callingUserId = UserHandle.getCallingUserId();
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
+            return !umi.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER, callingUserId);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index ff2c671..c506e27 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -189,6 +189,8 @@
         private int reason = APP_TRANSITION_TIMEOUT;
         // TODO(b/132736359) The number may need to consider the visibility change.
         private int numUndrawnActivities = 1;
+        /** Non-null if the application has reported drawn but its window hasn't. */
+        private Runnable pendingFullyDrawn;
         private boolean loggedStartingWindowDrawn;
         private boolean launchTraceActive;
 
@@ -716,6 +718,9 @@
             BackgroundThread.getHandler().post(() -> logAppTransition(
                     currentTransitionDeviceUptime, currentTransitionDelayMs, infoSnapshot));
             BackgroundThread.getHandler().post(() -> logAppDisplayed(infoSnapshot));
+            if (info.pendingFullyDrawn != null) {
+                info.pendingFullyDrawn.run();
+            }
 
             info.launchedActivity.info.launchToken = null;
         }
@@ -839,6 +844,15 @@
         if (info == null) {
             return null;
         }
+        if (info.numUndrawnActivities > 0 && info.pendingFullyDrawn == null) {
+            // There are still undrawn activities, postpone reporting fully drawn until all of its
+            // windows are drawn. So that is closer to an usable state.
+            info.pendingFullyDrawn = () -> {
+                logAppTransitionReportedDrawn(r, restoredFromBundle);
+                info.pendingFullyDrawn = null;
+            };
+            return null;
+        }
 
         // Record the handling of the reportFullyDrawn callback in the trace system. This is not
         // actually used to trace this function, but instead the logical task that this function
@@ -849,9 +863,10 @@
         final LogMaker builder = new LogMaker(APP_TRANSITION_REPORTED_DRAWN);
         builder.setPackageName(r.packageName);
         builder.addTaggedData(FIELD_CLASS_NAME, r.info.name);
-        long currentTimestampNs = SystemClock.elapsedRealtimeNanos();
-        long startupTimeMs =
-            TimeUnit.NANOSECONDS.toMillis(currentTimestampNs - mLastTransitionStartTimeNs);
+        final long currentTimestampNs = SystemClock.elapsedRealtimeNanos();
+        final long startupTimeMs = info.pendingFullyDrawn != null
+                ? info.windowsDrawnDelayMs
+                : TimeUnit.NANOSECONDS.toMillis(currentTimestampNs - mLastTransitionStartTimeNs);
         builder.addTaggedData(APP_TRANSITION_REPORTED_DRAWN_MS, startupTimeMs);
         builder.setType(restoredFromBundle
                 ? TYPE_TRANSITION_REPORTED_DRAWN_WITH_BUNDLE
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index d360041..8aa5e77 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1167,7 +1167,7 @@
     TaskStack getStack() {
         final Task task = getTask();
         if (task != null) {
-            return task.mStack;
+            return task.getTaskStack();
         } else {
             return null;
         }
@@ -1210,8 +1210,8 @@
             if (getDisplayContent() != null) {
                 getDisplayContent().mClosingApps.remove(this);
             }
-        } else if (mLastParent != null && mLastParent.mStack != null) {
-            task.mStack.mExitingActivities.remove(this);
+        } else if (mLastParent != null && mLastParent.getTaskStack() != null) {
+            task.getTaskStack().mExitingActivities.remove(this);
         }
         final TaskStack stack = getStack();
 
@@ -5757,7 +5757,7 @@
                     mWmService.mTaskSnapshotController.createTaskSnapshot(
                             task, 1 /* scaleFraction */);
             if (snapshot != null) {
-                mThumbnail = new AppWindowThumbnail(mWmService.mSurfaceFactory, t, this,
+                mThumbnail = new WindowContainerThumbnail(mWmService.mSurfaceFactory, t, this,
                         snapshot.getGraphicBuffer(), true /* relative */);
             }
         }
@@ -5866,8 +5866,8 @@
             return;
         }
         clearThumbnail();
-        mThumbnail = new AppWindowThumbnail(mWmService.mSurfaceFactory, getPendingTransaction(),
-                this, thumbnailHeader);
+        mThumbnail = new WindowContainerThumbnail(mWmService.mSurfaceFactory,
+                getPendingTransaction(), this, thumbnailHeader);
         mThumbnail.startAnimation(getPendingTransaction(), loadThumbnailAnimation(thumbnailHeader));
     }
 
@@ -5895,7 +5895,7 @@
         if (thumbnail == null) {
             return;
         }
-        mThumbnail = new AppWindowThumbnail(mWmService.mSurfaceFactory,
+        mThumbnail = new WindowContainerThumbnail(mWmService.mSurfaceFactory,
                 getPendingTransaction(), this, thumbnail);
         final Animation animation =
                 getDisplayContent().mAppTransition.createCrossProfileAppsThumbnailAnimationLocked(
@@ -6043,7 +6043,7 @@
     }
 
     @VisibleForTesting
-    AppWindowThumbnail getThumbnail() {
+    WindowContainerThumbnail getThumbnail() {
         return mThumbnail;
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 7df1c15..99659b0 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -149,6 +149,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.os.logging.MetricsLoggerWrapper;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityManagerService;
@@ -789,14 +790,6 @@
                 return;
             }
 
-            if (windowingMode == WINDOWING_MODE_PINNED || currentMode == WINDOWING_MODE_PINNED) {
-                // TODO: Need to remove use of PinnedActivityStack for this to be supported.
-                // NOTE: Need to ASS.scheduleUpdatePictureInPictureModeIfNeeded() in
-                // setWindowModeUnchecked() when this support is added. See TaskRecord.reparent()
-                throw new IllegalArgumentException(
-                        "Changing pinned windowing mode not currently supported");
-            }
-
             if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && splitScreenStack != null) {
                 // We already have a split-screen stack in this display, so just move the tasks over.
                 // TODO: Figure-out how to do all the stuff in
@@ -4915,7 +4908,7 @@
                 // The final orientation of this activity will change after moving to full screen.
                 // Start freezing screen here to prevent showing a temporary full screen window.
                 top.startFreezingScreenLocked(CONFIG_SCREEN_LAYOUT);
-                mService.moveTasksToFullscreenStack(mStackId, true /* onTop */);
+                dismissPip();
                 return;
             }
         }
@@ -4924,6 +4917,34 @@
                 animationDuration, fromFullscreen);
     }
 
+    void dismissPip() {
+        if (!isActivityTypeStandardOrUndefined()) {
+            throw new IllegalArgumentException(
+                    "You can't move tasks from non-standard stacks.");
+        }
+        if (getWindowingMode() != WINDOWING_MODE_PINNED) {
+            throw new IllegalArgumentException(
+                    "Can't exit pinned mode if it's not pinned already.");
+        }
+
+        final ArrayList<TaskRecord> tasks = getAllTasks();
+
+        if (tasks.size() != 1) {
+            throw new RuntimeException("There should be only one task in a pinned stack.");
+        }
+
+        mWindowManager.inSurfaceTransaction(() -> {
+            final TaskRecord task = tasks.get(0);
+            setWindowingMode(WINDOWING_MODE_UNDEFINED);
+
+            getDisplay().positionChildAtTop(this, false /* includingParents */);
+
+            mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, this);
+            MetricsLoggerWrapper.logPictureInPictureFullScreen(mService.mContext,
+                    task.effectiveUid, task.realActivity.flattenToString());
+        });
+    }
+
     /**
      * Get current bounds of this stack, return empty when it is unavailable.
      * @see TaskStack#getAnimationOrCurrentBounds(Rect)
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index f8a7397..5f1c001 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -1499,7 +1499,6 @@
         mService.deferWindowLayout();
         try {
             final int windowingMode = fromStack.getWindowingMode();
-            final boolean inPinnedWindowingMode = windowingMode == WINDOWING_MODE_PINNED;
             final ActivityDisplay toDisplay =
                     mRootActivityContainer.getActivityDisplay(toDisplayId);
 
@@ -1526,7 +1525,8 @@
 
             // If we are moving from the pinned stack, then the animation takes care of updating
             // the picture-in-picture mode.
-            final boolean schedulePictureInPictureModeChange = inPinnedWindowingMode;
+            final boolean schedulePictureInPictureModeChange =
+                    windowingMode == WINDOWING_MODE_PINNED;
             final ArrayList<TaskRecord> tasks = fromStack.getAllTasks();
 
             if (!tasks.isEmpty()) {
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 2c4d893..e2e2b74 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -22,6 +22,7 @@
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
 
+import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
@@ -178,6 +179,13 @@
             options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
         }
         options.setLaunchDisplayId(displayId);
+
+        final ActivityDisplay display =
+                mService.mRootActivityContainer.getActivityDisplay(displayId);
+        // Make sure home stack exist on display.
+        final ActivityStack homeStack =
+                display.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
+
         mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
                 .setOutActivity(tmpOutRecord)
                 .setCallingUid(0)
@@ -185,10 +193,7 @@
                 .setActivityOptions(options.toBundle())
                 .execute();
         mLastHomeActivityStartRecord = tmpOutRecord[0];
-        final ActivityDisplay display =
-                mService.mRootActivityContainer.getActivityDisplay(displayId);
-        final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
-        if (homeStack != null && homeStack.mInResumeTopActivity) {
+        if (homeStack.mInResumeTopActivity) {
             // If we are in resume section already, home activity will be initialized, but not
             // resumed (to avoid recursive resume) and will stay that way until something pokes it
             // again. We need to schedule another resume.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index da7af5f..0dfc8b5 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -3432,7 +3432,7 @@
 
                 if (stack.inFreeformWindowingMode()) {
                     stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
-                } else if (!mSizeCompatFreeform) {
+                } else if (!mSizeCompatFreeform && r.inSizeCompatMode()) {
                     throw new IllegalStateException("Size-compat windows are currently not"
                             + "freeform-enabled");
                 } else if (stack.getParent().inFreeformWindowingMode()) {
@@ -4001,7 +4001,7 @@
                     stack.animateResizePinnedStack(null /* sourceHintBounds */,
                             null /* destBounds */, animationDuration, false /* fromFullscreen */);
                 } else {
-                    mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
+                    stack.dismissPip();
                 }
             }
         } finally {
@@ -4017,11 +4017,6 @@
         }
     }
 
-    /**
-     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
-     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
-     *       activity and clearing the task at the same time.
-     */
     @Override
     // TODO: API should just be about changing windowing modes...
     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index cb9a200..cd7c216 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -1922,11 +1922,13 @@
         if (taskId < 0) {
             return null;
         }
-        ArrayList<Task> tasks = new ArrayList<>();
+        final ArrayList<Task> tasks = new ArrayList<>();
         mDisplayContent.forAllTasks(task -> {
             if (task.mTaskId == taskId) {
                 tasks.add(task);
+                return true;
             }
+            return false;
         });
         return tasks.size() == 1 ? tasks.get(0) : null;
     }
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index dc78922..3eef749 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -48,7 +48,6 @@
 import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
 import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
 import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
-import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
 import static com.android.server.wm.ActivityStackSupervisor.dumpHistoryList;
 import static com.android.server.wm.ActivityStackSupervisor.printThisActivity;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
@@ -358,7 +357,8 @@
             boolean fromHomeKey) {
         // Fallback to top focused display if the displayId is invalid.
         if (displayId == INVALID_DISPLAY) {
-            displayId = getTopDisplayFocusedStack().mDisplayId;
+            final ActivityStack stack = getTopDisplayFocusedStack();
+            displayId = stack != null ? stack.mDisplayId : DEFAULT_DISPLAY;
         }
 
         Intent homeIntent = null;
@@ -964,30 +964,29 @@
         mService.deferWindowLayout();
 
         final ActivityDisplay display = r.getActivityStack().getDisplay();
-        ActivityStack stack = display.getPinnedStack();
-
-        // This will clear the pinned stack by moving an existing task to the full screen stack,
-        // ensuring only one task is present.
-        if (stack != null) {
-            mStackSupervisor.moveTasksToFullscreenStackLocked(stack, !ON_TOP);
-        }
-
-        // Need to make sure the pinned stack exist so we can resize it below...
-        stack = display.getOrCreateStack(WINDOWING_MODE_PINNED, r.getActivityType(), ON_TOP);
 
         try {
             final TaskRecord task = r.getTaskRecord();
-            // Resize the pinned stack to match the current size of the task the activity we are
-            // going to be moving is currently contained in. We do this to have the right starting
-            // animation bounds for the pinned stack to the desired bounds the caller wants.
-            stack.resize(task.getRequestedOverrideBounds(), null /* tempTaskBounds */,
-                    null /* tempTaskInsetBounds */, !PRESERVE_WINDOWS, !DEFER_RESUME);
 
-            if (task.getChildCount() == 1) {
-                // Defer resume until below, and do not schedule PiP changes until we animate below
-                task.reparent(stack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE, DEFER_RESUME,
-                        false /* schedulePictureInPictureModeChange */, reason);
+            final ActivityStack pinnedStack = display.getPinnedStack();
+            // This will change the pinned stack's windowing mode to its original mode, ensuring
+            // we only have one stack that is in pinned mode.
+            if (pinnedStack != null) {
+                pinnedStack.dismissPip();
+            }
+
+            final boolean singleActivity = task.getChildCount() == 1;
+
+            final ActivityStack stack;
+            if (singleActivity) {
+                stack = r.getActivityStack();
             } else {
+                // In the case of multiple activities, we will create a new stack for it and then
+                // move the PIP activity into the stack.
+                // We will then perform a windowing mode change for both scenarios.
+                stack = display.createStack(
+                        r.getActivityStack().getRequestedOverrideWindowingMode(),
+                        r.getActivityType(), ON_TOP);
                 // There are multiple activities in the task and moving the top activity should
                 // reveal/leave the other activities in their original task.
 
@@ -1006,6 +1005,8 @@
                         DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
             }
 
+            stack.setWindowingMode(WINDOWING_MODE_PINNED);
+
             // Reset the state that indicates it can enter PiP while pausing after we've moved it
             // to the pinned stack
             r.supportsEnterPipOnTaskSwitch = false;
@@ -1628,7 +1629,7 @@
         return false;
     }
 
-    <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r,
+    ActivityStack getLaunchStack(@Nullable ActivityRecord r,
             @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop) {
         return getLaunchStack(r, options, candidateTask, onTop, null /* launchParams */,
                 -1 /* no realCallingPid */, -1 /* no realCallingUid */);
@@ -1646,7 +1647,7 @@
      *
      * @return The stack to use for the launch or INVALID_STACK_ID.
      */
-    <T extends ActivityStack> T getLaunchStack(@Nullable ActivityRecord r,
+    ActivityStack getLaunchStack(@Nullable ActivityRecord r,
             @Nullable ActivityOptions options, @Nullable TaskRecord candidateTask, boolean onTop,
             @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid,
             int realCallingUid) {
@@ -1674,7 +1675,7 @@
         }
 
         final int activityType = resolveActivityType(r, options, candidateTask);
-        T stack;
+        ActivityStack stack;
 
         // Next preference for stack goes to the display Id set the candidate display.
         if (launchParams != null && launchParams.mPreferredDisplayId != INVALID_DISPLAY) {
@@ -1690,7 +1691,7 @@
         if (displayId != INVALID_DISPLAY && (canLaunchOnDisplay(r, displayId)
                 || canLaunchOnDisplayFromStartRequest)) {
             if (r != null) {
-                stack = (T) getValidLaunchStackOnDisplay(displayId, r, candidateTask, options,
+                stack = getValidLaunchStackOnDisplay(displayId, r, candidateTask, options,
                         launchParams);
                 if (stack != null) {
                     return stack;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index dce15bc..183ca07 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -58,6 +58,7 @@
 import android.view.SurfaceControl;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ToBooleanFunction;
 
 import java.io.PrintWriter;
 import java.util.function.Consumer;
@@ -67,8 +68,6 @@
 
     final ActivityTaskManagerService mAtmService;
 
-    // TODO: Track parent marks like this in WindowContainer.
-    TaskStack mStack;
     /* Unique identifier for this task. */
     final int mTaskId;
     /* User for which this task was created. */
@@ -128,7 +127,6 @@
         super(atm.mWindowManager);
         mAtmService = atm;
         mTaskId = taskId;
-        mStack = stack;
         mUserId = userId;
         mResizeMode = resizeMode;
         mSupportsPictureInPicture = supportsPictureInPicture;
@@ -139,12 +137,16 @@
         // Tasks have no set orientation value (including SCREEN_ORIENTATION_UNSPECIFIED).
         setOrientation(SCREEN_ORIENTATION_UNSET);
         // TODO(task-merge): Is this really needed?
-        setBounds(getResolvedOverrideBounds());
+        //setBounds(getResolvedOverrideBounds());
     }
 
     @Override
     DisplayContent getDisplayContent() {
-        return mStack != null ? mStack.getDisplayContent() : null;
+        return getTaskStack() != null ? getTaskStack().getDisplayContent() : null;
+    }
+
+    TaskStack getTaskStack() {
+        return (TaskStack) getParent();
     }
 
     int getAdjustedAddPosition(ActivityRecord r, int suggestedPosition) {
@@ -199,7 +201,7 @@
             // No reason to defer removal of a Task that doesn't have any child.
             return false;
         }
-        return hasWindowsAlive() && mStack.isAnimating(TRANSITION | CHILDREN);
+        return hasWindowsAlive() && getTaskStack().isAnimating(TRANSITION | CHILDREN);
     }
 
     @Override
@@ -221,10 +223,10 @@
     // TODO: Consolidate this with TaskRecord.reparent()
     void reparent(TaskStack stack, int position, boolean moveParents, String reason) {
         if (DEBUG_STACK) Slog.i(TAG, "reParentTask: removing taskId=" + mTaskId
-                + " from stack=" + mStack);
+                + " from stack=" + getTaskStack());
         EventLog.writeEvent(WM_TASK_REMOVED, mTaskId, "reParentTask");
 
-        final ActivityStack prevStack = mStack.mActivityStack;
+        final ActivityStack prevStack = getTaskStack().mActivityStack;
         final boolean wasTopFocusedStack =
                 mAtmService.mRootActivityContainer.isTopDisplayFocusedStack(prevStack);
         final ActivityDisplay prevStackDisplay = prevStack.getDisplay();
@@ -236,8 +238,8 @@
             prevStack.moveHomeStackToFrontIfNeeded(wasTopFocusedStack, prevStackDisplay, reason);
         }
 
-        mStack = stack;
-        stack.positionChildAt(position, this, moveParents);
+        // TODO(task-merge): Remove cast.
+        stack.positionChildAt(position, (TaskRecord) this, moveParents);
 
         // If we are moving from the fullscreen stack to the pinned stack then we want to preserve
         // our insets so that there will not be a jump in the area covered by system decorations.
@@ -247,7 +249,8 @@
 
     /** @see ActivityTaskManagerService#positionTaskInStack(int, int, int). */
     void positionAt(int position) {
-        mStack.positionChildAt(position, this, false /* includingParents */);
+        // TODO(task-merge): Remove cast.
+        getTaskStack().positionChildAt(position, (TaskRecord) this, false /* includingParents */);
     }
 
     void setSendingToBottom(boolean toBottom) {
@@ -271,7 +274,8 @@
     @Override
     public int setBounds(Rect bounds) {
         int rotation = Surface.ROTATION_0;
-        final DisplayContent displayContent = mStack != null ? mStack.getDisplayContent() : null;
+        final DisplayContent displayContent = getTaskStack() != null
+                ? getTaskStack().getDisplayContent() : null;
         if (displayContent != null) {
             rotation = displayContent.getDisplayInfo().rotation;
         } else if (bounds == null) {
@@ -462,7 +466,7 @@
 
     /** Bounds of the task to be used for dimming, as well as touch related tests. */
     public void getDimBounds(Rect out) {
-        final DisplayContent displayContent = mStack.getDisplayContent();
+        final DisplayContent displayContent = getTaskStack().getDisplayContent();
         // It doesn't matter if we in particular are part of the resize, since we couldn't have
         // a DimLayer anyway if we weren't visible.
         final boolean dockedResizing = displayContent != null
@@ -479,9 +483,9 @@
             // stack bounds and so we don't even want to use them. Even if the app should not be
             // resized the Dim should keep up with the divider.
             if (dockedResizing) {
-                mStack.getBounds(out);
+                getTaskStack().getBounds(out);
             } else {
-                mStack.getBounds(mTmpRect);
+                getTaskStack().getBounds(mTmpRect);
                 mTmpRect.intersect(getBounds());
                 out.set(mTmpRect);
             }
@@ -494,9 +498,9 @@
     void setDragResizing(boolean dragResizing, int dragResizeMode) {
         if (mDragResizing != dragResizing) {
             // No need to check if the mode is allowed if it's leaving dragResize
-            if (dragResizing && !DragResizeMode.isModeAllowedForStack(mStack, dragResizeMode)) {
+            if (dragResizing && !DragResizeMode.isModeAllowedForStack(getTaskStack(), dragResizeMode)) {
                 throw new IllegalArgumentException("Drag resize mode not allow for stack stackId="
-                        + mStack.mStackId + " dragResizeMode=" + dragResizeMode);
+                        + getTaskStack().mStackId + " dragResizeMode=" + dragResizeMode);
             }
             mDragResizing = dragResizing;
             mDragResizeMode = dragResizeMode;
@@ -586,7 +590,7 @@
      */
     boolean isFloating() {
         return getWindowConfiguration().tasksAreFloating()
-                && !mStack.isAnimatingBoundsToFullscreen() && !mPreserveNonFloatingState;
+                && !getTaskStack().isAnimatingBoundsToFullscreen() && !mPreserveNonFloatingState;
     }
 
     @Override
@@ -718,6 +722,11 @@
         callback.accept(this);
     }
 
+    @Override
+    boolean forAllTasks(ToBooleanFunction<Task> callback) {
+        return callback.apply(this);
+    }
+
     /**
      * @param canAffectSystemUiFlags If false, all windows in this task can not affect SystemUI
      *                               flags. See {@link WindowState#canAffectSystemUiFlags()}.
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 478b1b5..f7b802d 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -30,6 +30,7 @@
 import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
 import android.app.IActivityTaskManager;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -104,6 +105,7 @@
 
     @VisibleForTesting
     Task mTask;
+    WindowState mWindow;
     private boolean mResizing;
     private boolean mPreserveOrientation;
     private boolean mStartOrientationWasLandscape;
@@ -238,8 +240,9 @@
 
     /**
      * @param displayContent The Display that the window being dragged is on.
+     * @param win The window which will be dragged.
      */
-    void register(DisplayContent displayContent) {
+    void register(DisplayContent displayContent, @NonNull WindowState win) {
         final Display display = displayContent.getDisplay();
 
         if (DEBUG_TASK_POSITIONING) {
@@ -309,6 +312,17 @@
         display.getRealSize(mMaxVisibleSize);
 
         mDragEnded = false;
+
+        try {
+            mClientCallback = win.mClient.asBinder();
+            mClientCallback.linkToDeath(this, 0 /* flags */);
+        } catch (RemoteException e) {
+            // The caller has died, so clean up TaskPositioningController.
+            mService.mTaskPositioningController.finishTaskPositioning();
+            return;
+        }
+        mWindow = win;
+        mTask = win.getTask();
     }
 
     void unregister() {
@@ -341,25 +355,19 @@
         ProtoLog.d(WM_DEBUG_ORIENTATION, "Resuming rotation after re-position");
         mDisplayContent.getDisplayRotation().resume();
         mDisplayContent = null;
-        mClientCallback.unlinkToDeath(this, 0 /* flags */);
+        if (mClientCallback != null) {
+            mClientCallback.unlinkToDeath(this, 0 /* flags */);
+        }
+        mWindow = null;
     }
 
-    void startDrag(WindowState win, boolean resize, boolean preserveOrientation, float startX,
-                   float startY) {
+    void startDrag(boolean resize, boolean preserveOrientation, float startX,
+            float startY) {
         if (DEBUG_TASK_POSITIONING) {
-            Slog.d(TAG, "startDrag: win=" + win + ", resize=" + resize
+            Slog.d(TAG, "startDrag: win=" + mWindow + ", resize=" + resize
                     + ", preserveOrientation=" + preserveOrientation + ", {" + startX + ", "
                     + startY + "}");
         }
-        try {
-            mClientCallback = win.mClient.asBinder();
-            mClientCallback.linkToDeath(this, 0 /* flags */);
-        } catch (RemoteException e) {
-            // The caller has died, so clean up TaskPositioningController.
-            mService.mTaskPositioningController.finishTaskPositioning();
-            return;
-        }
-        mTask = win.getTask();
         // Use the bounds of the task which accounts for
         // multiple app windows. Don't use any bounds from win itself as it
         // may not be the same size as the task.
@@ -441,7 +449,7 @@
         }
 
         // This is a moving or scrolling operation.
-        mTask.mStack.getDimBounds(mTmpRect);
+        mTask.getTaskStack().getDimBounds(mTmpRect);
         // If a target window is covered by system bar, there is no way to move it again by touch.
         // So we exclude them from stack bounds. and then it will be shown inside stable area.
         Rect stableBounds = new Rect();
diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java
index e1123fa..c38e63e 100644
--- a/services/core/java/com/android/server/wm/TaskPositioningController.java
+++ b/services/core/java/com/android/server/wm/TaskPositioningController.java
@@ -169,7 +169,7 @@
         mPositioningDisplay = displayContent;
 
         mTaskPositioner = TaskPositioner.create(mService);
-        mTaskPositioner.register(displayContent);
+        mTaskPositioner.register(displayContent, win);
 
         // We need to grab the touch focus so that the touch events during the
         // resizing/scrolling are not sent to the app. 'win' is the main window
@@ -187,7 +187,7 @@
             return false;
         }
 
-        mTaskPositioner.startDrag(win, resize, preserveOrientation, startX, startY);
+        mTaskPositioner.startDrag(resize, preserveOrientation, startX, startY);
         return true;
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 672827f..56f4d32 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -835,8 +835,8 @@
         mNextAffiliateTaskId = nextAffiliate == null ? INVALID_TASK_ID : nextAffiliate.mTaskId;
     }
 
-    <T extends ActivityStack> T getStack() {
-        return (T) mStack;
+    ActivityStack getStack() {
+        return mStack;
     }
 
     // TODO(stack-unify): Can be removed on stack unified.
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 68b76fb..95a908f 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -84,7 +84,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-public class TaskStack extends WindowContainer<Task> implements
+public class TaskStack extends WindowContainer<TaskRecord> implements
         BoundsAnimationTarget, ConfigurationContainerListener {
     /** Minimum size of an adjusted stack bounds relative to original stack bounds. Used to
      * restrict IME adjustment so that a min portion of top stack remains visible.*/
@@ -102,7 +102,6 @@
     private Rect mTmpRect3 = new Rect();
 
     /** For Pinned stack controlling. */
-    private Rect mTmpFromBounds = new Rect();
     private Rect mTmpToBounds = new Rect();
 
     /** Stack bounds adjusted to screen content area (taking into account IM windows, etc.) */
@@ -489,20 +488,18 @@
      * @param position Target position to add the task to.
      * @param showForAllUsers Whether to show the task regardless of the current user.
      */
-    void addChild(Task task, int position, boolean showForAllUsers, boolean moveParents) {
+    void addChild(TaskRecord task, int position, boolean showForAllUsers, boolean moveParents) {
         // Add child task.
-        task.mStack = this;
         addChild(task, null);
 
         // Move child to a proper position, as some restriction for position might apply.
         position = positionChildAt(
                 position, task, moveParents /* includingParents */, showForAllUsers);
-        // TODO(task-merge): Remove cast.
-        mActivityStack.onChildAdded((TaskRecord) task, position);
+        mActivityStack.onChildAdded(task, position);
     }
 
     @Override
-    void addChild(Task task, int position) {
+    void addChild(TaskRecord task, int position) {
         addChild(task, position, task.showForAllUsers(), false /* includingParents */);
     }
 
@@ -520,7 +517,7 @@
         getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
     }
 
-    void positionChildAtTop(Task child, boolean includingParents) {
+    void positionChildAtTop(TaskRecord child, boolean includingParents) {
         if (child == null) {
             // TODO: Fix the call-points that cause this to happen.
             return;
@@ -535,7 +532,7 @@
         displayContent.layoutAndAssignWindowLayersIfNeeded();
     }
 
-    void positionChildAtBottom(Task child, boolean includingParents) {
+    void positionChildAtBottom(TaskRecord child, boolean includingParents) {
         if (child == null) {
             // TODO: Fix the call-points that cause this to happen.
             return;
@@ -550,7 +547,7 @@
     }
 
     @Override
-    void positionChildAt(int position, Task child, boolean includingParents) {
+    void positionChildAt(int position, TaskRecord child, boolean includingParents) {
         positionChildAt(position, child, includingParents, child.showForAllUsers());
     }
 
@@ -559,7 +556,7 @@
      * {@link TaskStack#addChild(Task, int, boolean showForAllUsers, boolean)}, as it can receive
      * showForAllUsers param from {@link ActivityRecord} instead of {@link Task#showForAllUsers()}.
      */
-    int positionChildAt(int position, Task child, boolean includingParents,
+    int positionChildAt(int position, TaskRecord child, boolean includingParents,
             boolean showForAllUsers) {
         final int targetPosition = findPositionForTask(child, position, showForAllUsers);
         super.positionChildAt(targetPosition, child, includingParents);
@@ -666,7 +663,7 @@
      * @param task The Task to delete.
      */
     @Override
-    void removeChild(Task task) {
+    void removeChild(TaskRecord task) {
         if (!mChildren.contains(task)) {
             // Not really in this stack anymore...
             return;
@@ -674,10 +671,8 @@
         if (DEBUG_TASK_MOVEMENT) Slog.d(TAG_WM, "removeChild: task=" + task);
 
         super.removeChild(task);
-        task.mStack = null;
 
-        // TODO(task-merge): Remove cast.
-        mActivityStack.onChildRemoved((TaskRecord) task, mDisplayContent);
+        mActivityStack.onChildRemoved(task, mDisplayContent);
     }
 
     @Override
@@ -963,7 +958,7 @@
         super.switchUser();
         int top = mChildren.size();
         for (int taskNdx = 0; taskNdx < top; ++taskNdx) {
-            Task task = mChildren.get(taskNdx);
+            TaskRecord task = mChildren.get(taskNdx);
             if (mWmService.isCurrentProfileLocked(task.mUserId) || task.showForAllUsers()) {
                 mChildren.remove(taskNdx);
                 mChildren.add(task);
@@ -1576,7 +1571,7 @@
 
             mActivityStack.mService.notifyPinnedStackAnimationEnded();
             if (moveToFullscreen) {
-                mActivityStack.mService.moveTasksToFullscreenStack(mStackId, true /* onTop */);
+                mActivityStack.dismissPip();
             }
         } else {
             // No PiP animation, just run the normal animation-end logic
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index a393ba6..11658f9 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -237,7 +237,7 @@
      * This gets used during some open/close transitions as well as during a change transition
      * where it represents the starting-state snapshot.
      */
-    AppWindowThumbnail mThumbnail;
+    WindowContainerThumbnail mThumbnail;
     final Rect mTransitStartRect = new Rect();
     final Point mTmpPoint = new Point();
     protected final Rect mTmpRect = new Rect();
@@ -1121,6 +1121,21 @@
         }
     }
 
+    /**
+     * For all tasks at or below this container call the callback.
+     *
+     * @param callback Calls the {@link ToBooleanFunction#apply} method for each task found and
+     *                 stops the search if {@link ToBooleanFunction#apply} returns {@code true}.
+     */
+    boolean forAllTasks(ToBooleanFunction<Task> callback) {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            if (mChildren.get(i).forAllTasks(callback)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     WindowState getWindow(Predicate<WindowState> callback) {
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowState w = mChildren.get(i).getWindow(callback);
@@ -1520,8 +1535,8 @@
         try {
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WC#applyAnimation");
             if (okToAnimate()) {
-                Pair<AnimationAdapter, AnimationAdapter> adapters = getAnimationAdapter(lp, transit,
-                        enter, isVoiceInteraction);
+                final Pair<AnimationAdapter, AnimationAdapter> adapters = getAnimationAdapter(lp,
+                        transit, enter, isVoiceInteraction);
                 AnimationAdapter adapter = adapters.first;
                 AnimationAdapter thumbnailAdapter = adapters.second;
                 if (adapter != null) {
@@ -1580,18 +1595,16 @@
             final DisplayInfo displayInfo = getDisplayContent().getDisplayInfo();
             mTmpRect.offsetTo(mTmpPoint.x, mTmpPoint.y);
 
-            AnimationAdapter adapter = new LocalAnimationAdapter(
+            final AnimationAdapter adapter = new LocalAnimationAdapter(
                     new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect, displayInfo,
                             durationScale, true /* isAppAnimation */, false /* isThumbnail */),
                     getSurfaceAnimationRunner());
 
-            AnimationAdapter thumbnailAdapter = null;
-            if (mThumbnail != null) {
-                thumbnailAdapter = new LocalAnimationAdapter(
-                        new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect, displayInfo,
-                                durationScale, true /* isAppAnimation */, true /* isThumbnail */),
-                        getSurfaceAnimationRunner());
-            }
+            final AnimationAdapter thumbnailAdapter = mThumbnail != null
+                    ? new LocalAnimationAdapter(new WindowChangeAnimationSpec(mTransitStartRect,
+                    mTmpRect, displayInfo, durationScale, true /* isAppAnimation */,
+                    true /* isThumbnail */), getSurfaceAnimationRunner())
+                    : null;
             resultAdapters = new Pair<>(adapter, thumbnailAdapter);
             mTransit = transit;
             mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
similarity index 66%
rename from services/core/java/com/android/server/wm/AppWindowThumbnail.java
rename to services/core/java/com/android/server/wm/WindowContainerThumbnail.java
index acd96e9..604eae6 100644
--- a/services/core/java/com/android/server/wm/AppWindowThumbnail.java
+++ b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
@@ -11,7 +11,7 @@
  * 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
+ * limitations under the License.
  */
 
 package com.android.server.wm;
@@ -19,10 +19,10 @@
 import static android.view.SurfaceControl.METADATA_OWNER_UID;
 import static android.view.SurfaceControl.METADATA_WINDOW_TYPE;
 
-import static com.android.server.wm.AppWindowThumbnailProto.HEIGHT;
-import static com.android.server.wm.AppWindowThumbnailProto.SURFACE_ANIMATOR;
-import static com.android.server.wm.AppWindowThumbnailProto.WIDTH;
 import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowContainerThumbnailProto.HEIGHT;
+import static com.android.server.wm.WindowContainerThumbnailProto.SURFACE_ANIMATOR;
+import static com.android.server.wm.WindowContainerThumbnailProto.WIDTH;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
@@ -30,7 +30,7 @@
 import android.graphics.GraphicBuffer;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
-import android.os.Binder;
+import android.os.Process;
 import android.util.proto.ProtoOutputStream;
 import android.view.Surface;
 import android.view.SurfaceControl;
@@ -44,39 +44,40 @@
 import java.util.function.Supplier;
 
 /**
- * Represents a surface that is displayed over an {@link ActivityRecord}
+ * Represents a surface that is displayed over a subclass of {@link WindowContainer}
  */
-class AppWindowThumbnail implements Animatable {
+class WindowContainerThumbnail implements Animatable {
 
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowThumbnail" : TAG_WM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowContainerThumbnail" : TAG_WM;
 
-    private final ActivityRecord mActivityRecord;
+    private final WindowContainer mWindowContainer;
     private SurfaceControl mSurfaceControl;
     private final SurfaceAnimator mSurfaceAnimator;
     private final int mWidth;
     private final int mHeight;
     private final boolean mRelative;
 
-    AppWindowThumbnail(Supplier<Surface> surfaceFactory, Transaction t, ActivityRecord activity,
-            GraphicBuffer thumbnailHeader) {
-        this(surfaceFactory, t, activity, thumbnailHeader, false /* relative */);
+    WindowContainerThumbnail(Supplier<Surface> surfaceFactory, Transaction t,
+            WindowContainer container, GraphicBuffer thumbnailHeader) {
+        this(surfaceFactory, t, container, thumbnailHeader, false /* relative */);
     }
 
     /**
      * @param t Transaction to create the thumbnail in.
-     * @param activity {@link ActivityRecord} to associate this thumbnail with.
+     * @param container The sub-class of {@link WindowContainer} to associate this thumbnail with.
      * @param thumbnailHeader A thumbnail or placeholder for thumbnail to initialize with.
-     * @param relative Whether this thumbnail will be a child of activity (and thus positioned
+     * @param relative Whether this thumbnail will be a child of the container (and thus positioned
      *                 relative to it) or not.
      */
-    AppWindowThumbnail(Supplier<Surface> surfaceFactory, Transaction t, ActivityRecord activity,
-            GraphicBuffer thumbnailHeader, boolean relative) {
-        this(t, activity, thumbnailHeader, relative, surfaceFactory.get(), null);
+    WindowContainerThumbnail(Supplier<Surface> surfaceFactory, Transaction t,
+            WindowContainer container, GraphicBuffer thumbnailHeader, boolean relative) {
+        this(t, container, thumbnailHeader, relative, surfaceFactory.get(), null);
     }
 
-    AppWindowThumbnail(Transaction t, ActivityRecord activity, GraphicBuffer thumbnailHeader,
-            boolean relative, Surface drawSurface, SurfaceAnimator animator) {
-        mActivityRecord = activity;
+    WindowContainerThumbnail(Transaction t, WindowContainer container,
+            GraphicBuffer thumbnailHeader, boolean relative, Surface drawSurface,
+            SurfaceAnimator animator) {
+        mWindowContainer = container;
         mRelative = relative;
         if (animator != null) {
             mSurfaceAnimator = animator;
@@ -84,24 +85,21 @@
             // We can't use a delegating constructor since we need to
             // reference this::onAnimationFinished
             mSurfaceAnimator =
-                new SurfaceAnimator(this, this::onAnimationFinished, activity.mWmService);
+                new SurfaceAnimator(this, this::onAnimationFinished, container.mWmService);
         }
         mWidth = thumbnailHeader.getWidth();
         mHeight = thumbnailHeader.getHeight();
 
         // Create a new surface for the thumbnail
-        WindowState window = mActivityRecord.findMainWindow();
-
         // TODO: This should be attached as a child to the app token, once the thumbnail animations
         // use relative coordinates. Once we start animating task we can also consider attaching
         // this to the task.
-        mSurfaceControl = mActivityRecord.makeSurface()
-                .setName("thumbnail anim: " + mActivityRecord.toString())
+        mSurfaceControl = mWindowContainer.makeSurface()
+                .setName("thumbnail anim: " + mWindowContainer.toString())
                 .setBufferSize(mWidth, mHeight)
                 .setFormat(PixelFormat.TRANSLUCENT)
-                .setMetadata(METADATA_WINDOW_TYPE, mActivityRecord.windowType)
-                .setMetadata(METADATA_OWNER_UID,
-                        window != null ? window.mOwnerUid : Binder.getCallingUid())
+                .setMetadata(METADATA_WINDOW_TYPE, mWindowContainer.getWindowingMode())
+                .setMetadata(METADATA_OWNER_UID, Process.myUid())
                 .build();
 
         ProtoLog.i(WM_SHOW_TRANSACTIONS, "  THUMBNAIL %s: CREATE", mSurfaceControl);
@@ -112,11 +110,11 @@
         drawSurface.release();
         t.show(mSurfaceControl);
 
-        // We parent the thumbnail to the task, and just place it on top of anything else in the
-        // task.
+        // We parent the thumbnail to the container, and just place it on top of anything else in
+        // the container.
         t.setLayer(mSurfaceControl, Integer.MAX_VALUE);
         if (relative) {
-            t.reparent(mSurfaceControl, mActivityRecord.getSurfaceControl());
+            t.reparent(mSurfaceControl, mWindowContainer.getSurfaceControl());
         }
     }
 
@@ -126,12 +124,12 @@
 
     void startAnimation(Transaction t, Animation anim, Point position) {
         anim.restrictDuration(MAX_ANIMATION_DURATION);
-        anim.scaleCurrentDuration(mActivityRecord.mWmService.getTransitionAnimationScaleLocked());
+        anim.scaleCurrentDuration(mWindowContainer.mWmService.getTransitionAnimationScaleLocked());
         mSurfaceAnimator.startAnimation(t, new LocalAnimationAdapter(
                 new WindowAnimationSpec(anim, position,
-                        mActivityRecord.getDisplayContent().mAppTransition.canSkipFirstFrame(),
-                        mActivityRecord.getDisplayContent().getWindowCornerRadius()),
-                mActivityRecord.mWmService.mSurfaceAnimationRunner), false /* hidden */);
+                        mWindowContainer.getDisplayContent().mAppTransition.canSkipFirstFrame(),
+                        mWindowContainer.getDisplayContent().getWindowCornerRadius()),
+                mWindowContainer.mWmService.mSurfaceAnimationRunner), false /* hidden */);
     }
 
     /**
@@ -161,10 +159,11 @@
 
     /**
      * Write to a protocol buffer output stream. Protocol buffer message definition is at {@link
-     * com.android.server.wm.AppWindowThumbnailProto}.
+     * com.android.server.wm.WindowContainerThumbnailProto}.
      *
-     * @param proto Stream to write the AppWindowThumbnail object to.
-     * @param fieldId Field Id of the AppWindowThumbnail as defined in the parent message.
+     * @param proto Stream to write the WindowContainerThumbnailProto object to.
+     * @param fieldId Field Id of the WindowContainerThumbnailProto as defined in the parent
+     *                message.
      * @hide
      */
     void writeToProto(ProtoOutputStream proto, long fieldId) {
@@ -179,19 +178,19 @@
 
     @Override
     public Transaction getPendingTransaction() {
-        return mActivityRecord.getPendingTransaction();
+        return mWindowContainer.getPendingTransaction();
     }
 
     @Override
     public void commitPendingTransaction() {
-        mActivityRecord.commitPendingTransaction();
+        mWindowContainer.commitPendingTransaction();
     }
 
     @Override
     public void onAnimationLeashCreated(Transaction t, SurfaceControl leash) {
         t.setLayer(leash, Integer.MAX_VALUE);
         if (mRelative) {
-            t.reparent(leash, mActivityRecord.getSurfaceControl());
+            t.reparent(leash, mWindowContainer.getSurfaceControl());
         }
     }
 
@@ -205,7 +204,7 @@
 
     @Override
     public Builder makeAnimationLeash() {
-        return mActivityRecord.makeSurface();
+        return mWindowContainer.makeSurface();
     }
 
     @Override
@@ -215,12 +214,12 @@
 
     @Override
     public SurfaceControl getAnimationLeashParent() {
-        return mActivityRecord.getAppAnimationLayer();
+        return mWindowContainer.getAnimationLeashParent();
     }
 
     @Override
     public SurfaceControl getParentSurfaceControl() {
-        return mActivityRecord.getParentSurfaceControl();
+        return mWindowContainer.getParentSurfaceControl();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ab937e0..2c56b11 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4361,7 +4361,7 @@
         final DisplayContent topFocusedDisplay = mRoot.getTopFocusedDisplayContent();
         final ActivityRecord focusedApp = topFocusedDisplay.mFocusedApp;
         return (focusedApp != null && focusedApp.getTask() != null)
-                ? focusedApp.getTask().mStack : null;
+                ? focusedApp.getTask().getTaskStack() : null;
     }
 
     public boolean detectSafeMode() {
@@ -7657,7 +7657,7 @@
             return;
         }
 
-        final TaskStack stack = task.mStack;
+        final TaskStack stack = task.getTaskStack();
         // We ignore home stack since we don't want home stack to move to front when touched.
         // Specifically, in freeform we don't want tapping on home to cause the freeform apps to go
         // behind home. See b/117376413
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 344befa..d196c34 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1283,7 +1283,7 @@
         // notify the client of frame changes in this case. Not only is it a lot of churn, but
         // the frame may not correspond to the surface size or the onscreen area at various
         // phases in the animation, and the client will become sad and confused.
-        if (task != null && task.mStack.isAnimatingBounds()) {
+        if (task != null && task.getTaskStack().isAnimatingBounds()) {
             return;
         }
 
@@ -1423,8 +1423,8 @@
     TaskStack getStack() {
         Task task = getTask();
         if (task != null) {
-            if (task.mStack != null) {
-                return task.mStack;
+            if (task.getTaskStack() != null) {
+                return task.getTaskStack();
             }
         }
         // Some system windows (e.g. "Power off" dialog) don't have a task, but we would still
@@ -1443,7 +1443,7 @@
         bounds.setEmpty();
         mTmpRect.setEmpty();
         if (intersectWithStackBounds) {
-            final TaskStack stack = task.mStack;
+            final TaskStack stack = task.getTaskStack();
             if (stack != null) {
                 stack.getDimBounds(mTmpRect);
             } else {
@@ -1845,8 +1845,8 @@
         final int top = mWindowFrames.mFrame.top;
         final Task task = getTask();
         final boolean adjustedForMinimizedDockOrIme = task != null
-                && (task.mStack.isAdjustedForMinimizedDockedStack()
-                || task.mStack.isAdjustedForIme());
+                && (task.getTaskStack().isAdjustedForMinimizedDockedStack()
+                || task.getTaskStack().isAdjustedForIme());
         if (mToken.okToAnimate()
                 && (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
                 && !isDragResizing() && !adjustedForMinimizedDockOrIme
@@ -1882,7 +1882,7 @@
 
     boolean isObscuringDisplay() {
         Task task = getTask();
-        if (task != null && task.mStack != null && !task.mStack.fillsParent()) {
+        if (task != null && task.getTaskStack() != null && !task.getTaskStack().fillsParent()) {
             return false;
         }
         return isOpaqueDrawn() && fillsDisplay();
@@ -2301,8 +2301,8 @@
 
     void applyAdjustForImeIfNeeded() {
         final Task task = getTask();
-        if (task != null && task.mStack != null && task.mStack.isAdjustedForIme()) {
-            task.mStack.applyAdjustForImeIfNeeded(task);
+        if (task != null && task.getTaskStack() != null && task.getTaskStack().isAdjustedForIme()) {
+            task.getTaskStack().applyAdjustForImeIfNeeded(task);
         }
     }
 
@@ -2633,7 +2633,7 @@
             return false;
         }
 
-        return mActivityRecord.getTask().mStack.shouldIgnoreInput()
+        return mActivityRecord.getTask().getTaskStack().shouldIgnoreInput()
                 || mActivityRecord.hiddenRequested
                 || isAnimatingToRecents();
     }
@@ -3153,7 +3153,7 @@
             return;
         }
 
-        final TaskStack stack = task.mStack;
+        final TaskStack stack = task.getTaskStack();
         if (stack == null) {
             return;
         }
@@ -3167,7 +3167,7 @@
             return;
         }
 
-        final TaskStack stack = task.mStack;
+        final TaskStack stack = task.getTaskStack();
         if (stack == null) {
             return;
         }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index fef3a9d..a853828 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -892,10 +892,10 @@
 
             int posX = 0;
             int posY = 0;
-            task.mStack.getDimBounds(mTmpStackBounds);
+            task.getTaskStack().getDimBounds(mTmpStackBounds);
 
             boolean allowStretching = false;
-            task.mStack.getFinalAnimationSourceHintBounds(mTmpSourceBounds);
+            task.getTaskStack().getFinalAnimationSourceHintBounds(mTmpSourceBounds);
             // If we don't have source bounds, we can attempt to use the content insets
             // in the following scenario:
             //    1. We have content insets.
@@ -905,8 +905,8 @@
             // because of the force-scale until resize state.
             if (mTmpSourceBounds.isEmpty() && (mWin.mLastRelayoutContentInsets.width() > 0
                     || mWin.mLastRelayoutContentInsets.height() > 0)
-                        && !task.mStack.lastAnimatingBoundsWasToFullscreen()) {
-                mTmpSourceBounds.set(task.mStack.mPreAnimationBounds);
+                        && !task.getTaskStack().lastAnimatingBoundsWasToFullscreen()) {
+                mTmpSourceBounds.set(task.getTaskStack().mPreAnimationBounds);
                 mTmpSourceBounds.inset(mWin.mLastRelayoutContentInsets);
                 allowStretching = true;
             }
@@ -920,7 +920,7 @@
             if (!mTmpSourceBounds.isEmpty()) {
                 // Get the final target stack bounds, if we are not animating, this is just the
                 // current stack bounds
-                task.mStack.getFinalAnimationBounds(mTmpAnimatingBounds);
+                task.getTaskStack().getFinalAnimationBounds(mTmpAnimatingBounds);
 
                 // Calculate the current progress and interpolate the difference between the target
                 // and source bounds
@@ -1499,7 +1499,7 @@
      */
     boolean isForceScaled() {
         final Task task = mWin.getTask();
-        if (task != null && task.mStack.isForceScaled()) {
+        if (task != null && task.getTaskStack().isForceScaled()) {
             return true;
         }
         return mForceScaleUntilResize;
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index 8ddb86b..3726228 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -67,7 +67,11 @@
     Return<bool> supportsAmplitudeControl() override {
         int32_t cap = 0;
         if (!mVib->getCapabilities(&cap).isOk()) return false;
-        return (cap & aidl::IVibrator::CAP_AMPLITUDE_CONTROL) > 0;
+        if (mUnderExternalControl) {
+           return (cap & aidl::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0;
+        } else {
+           return (cap & aidl::IVibrator::CAP_AMPLITUDE_CONTROL) > 0;
+        }
     }
 
     Return<V1_0::Status> setAmplitude(uint8_t amplitude) override {
@@ -96,7 +100,11 @@
     }
 
     Return<V1_0::Status> setExternalControl(bool enabled) override {
-        return toHidlStatus(mVib->setExternalControl(enabled));
+        Return<V1_0::Status> status = toHidlStatus(mVib->setExternalControl(enabled));
+        if (status.isOk() && status == V1_0::Status::OK) {
+            mUnderExternalControl = enabled;
+        }
+        return status;
     }
 
     Return<void> perform_1_3(V1_3::Effect effect, V1_0::EffectStrength strength,
@@ -154,21 +162,30 @@
 
         sp<aidl::IVibratorCallback> cb = callback ? new CallbackShim(callback) : nullptr;
         int timeoutMs = 0;
-        V1_0::Status status = toHidlStatus(
+        Return<V1_0::Status> status = toHidlStatus(
             mVib->perform(static_cast<aidl::Effect>(effect),
                           static_cast<aidl::EffectStrength>(strength), cb, &timeoutMs));
-        _hidl_cb(status, timeoutMs);
-        return android::hardware::Status::ok();
+
+        if (status.isOk()) {
+            _hidl_cb(status, timeoutMs);
+            return android::hardware::Status::ok();
+        } else {
+            return android::hardware::details::StatusOf<V1_0::Status, void>(status);
+        }
     }
   private:
     sp<aidl::IVibrator> mVib;
+    bool mUnderExternalControl = false;
 
-    V1_0::Status toHidlStatus(const android::binder::Status& status) {
+    Return<V1_0::Status> toHidlStatus(const android::binder::Status& status) {
         switch(status.exceptionCode()) {
             using android::hardware::Status;
             case Status::EX_NONE: return V1_0::Status::OK;
             case Status::EX_ILLEGAL_ARGUMENT: return V1_0::Status::BAD_VALUE;
             case Status::EX_UNSUPPORTED_OPERATION: return V1_0::Status::UNSUPPORTED_OPERATION;
+            case Status::EX_TRANSACTION_FAILED: {
+                return Status::fromStatusT(status.transactionError());
+            }
         }
         return V1_0::Status::UNKNOWN_ERROR;
     }
@@ -247,8 +264,14 @@
             }
 
             ALOGE("Failed to issue command to vibrator HAL. Retrying.");
+
             // Restoring connection to the HAL.
-            mHal = I::tryGetService();
+            sp<aidl::IVibrator> aidlVib = checkVintfService<aidl::IVibrator>();
+            if (aidlVib) {
+                mHal = new VibratorShim(aidlVib);
+            } else {
+                mHal = I::tryGetService();
+            }
         }
         return ret;
     }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java
index fa90b29..0d44318 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationShellCmdTest.java
@@ -116,8 +116,8 @@
         ArgumentCaptor<Notification> notificationCaptor =
                 ArgumentCaptor.forClass(Notification.class);
         verify(mMockBinderService).enqueueNotificationWithTag(
-                eq(NotificationShellCmd.NOTIFICATION_PACKAGE),
-                eq("android"),
+                eq(getContext().getPackageName()),
+                eq(getContext().getPackageName()),
                 eq(aTag),
                 eq(NotificationShellCmd.NOTIFICATION_ID),
                 notificationCaptor.capture(),
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 7c867b6..44cacd8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -195,9 +195,15 @@
     public void testOnReportFullyDrawn() {
         onActivityLaunched();
 
+        // The activity reports fully drawn before windows drawn, then the fully drawn event will
+        // be pending (see {@link WindowingModeTransitionInfo#pendingFullyDrawn}).
         mActivityMetricsLogger.logAppTransitionReportedDrawn(mTopActivity, false);
+        notifyTransitionStarting();
+        // The pending fully drawn event should send when the actual windows drawn event occurs.
+        notifyWindowsDrawn(mTopActivity);
 
         verifyAsync(mLaunchObserver).onReportFullyDrawn(eqProto(mTopActivity), anyLong());
+        verifyAsync(mLaunchObserver).onActivityLaunchFinished(eqProto(mTopActivity), anyLong());
         verifyNoMoreInteractions(mLaunchObserver);
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
index c5301b8..7b9be3d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
@@ -62,7 +62,7 @@
     public void setUpOnDisplay(DisplayContent dc) {
         mActivity = createTestActivityRecord(dc, WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD);
         mTask = mActivity.getTask();
-        mStack = mTask.mStack;
+        mStack = mTask.getTaskStack();
 
         // Set a remote animator with snapshot disabled. Snapshots don't work in wmtests.
         RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 01489c6..bd137fb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -119,7 +119,7 @@
         waitUntilHandlersIdle();
 
         exitingApp.mIsExiting = true;
-        exitingApp.getTask().mStack.mExitingActivities.add(exitingApp);
+        exitingApp.getTask().getTaskStack().mExitingActivities.add(exitingApp);
 
         assertForAllWindowsOrder(Arrays.asList(
                 mWallpaperWindow,
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 63f70c0..e0e9a58 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -114,16 +114,15 @@
     public void testReplacingTaskInPinnedStack() {
         final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
                 .setStack(mFullscreenStack).build();
-        final TaskRecord firstTask = firstActivity.getTaskRecord();
+        final TaskRecord task = firstActivity.getTaskRecord();
 
-        final ActivityRecord secondActivity = new ActivityBuilder(mService).setCreateTask(true)
+        final ActivityRecord secondActivity = new ActivityBuilder(mService).setTask(task)
                 .setStack(mFullscreenStack).build();
-        final TaskRecord secondTask = secondActivity.getTaskRecord();
 
         mFullscreenStack.moveToFront("testReplacingTaskInPinnedStack");
 
         // Ensure full screen stack has both tasks.
-        ensureStackPlacement(mFullscreenStack, firstTask, secondTask);
+        ensureStackPlacement(mFullscreenStack, firstActivity, secondActivity);
 
         // Move first activity to pinned stack.
         final Rect sourceBounds = new Rect();
@@ -133,8 +132,8 @@
         final ActivityDisplay display = mFullscreenStack.getDisplay();
         ActivityStack pinnedStack = display.getPinnedStack();
         // Ensure a task has moved over.
-        ensureStackPlacement(pinnedStack, firstTask);
-        ensureStackPlacement(mFullscreenStack, secondTask);
+        ensureStackPlacement(pinnedStack, firstActivity);
+        ensureStackPlacement(mFullscreenStack, secondActivity);
 
         // Move second activity to pinned stack.
         mRootActivityContainer.moveActivityToPinnedStack(secondActivity, sourceBounds,
@@ -144,21 +143,27 @@
         pinnedStack = display.getPinnedStack();
         mFullscreenStack = display.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         // Ensure stacks have swapped tasks.
-        ensureStackPlacement(pinnedStack, secondTask);
-        ensureStackPlacement(mFullscreenStack, firstTask);
+        ensureStackPlacement(pinnedStack, secondActivity);
+        ensureStackPlacement(mFullscreenStack, firstActivity);
     }
 
-    private static void ensureStackPlacement(ActivityStack stack, TaskRecord... tasks) {
-        final ArrayList<TaskRecord> stackTasks = stack.getAllTasks();
-        assertEquals("Expecting " + Arrays.deepToString(tasks) + " got " + stackTasks,
-                stackTasks.size(), tasks != null ? tasks.length : 0);
+    private static void ensureStackPlacement(ActivityStack stack, ActivityRecord... activities) {
+        final TaskRecord task = stack.getAllTasks().get(0);
+        final ArrayList<ActivityRecord> stackActivities = new ArrayList<>();
 
-        if (tasks == null) {
+        for (int i = 0; i < task.getChildCount(); i++) {
+            stackActivities.add(task.getChildAt(i));
+        }
+
+        assertEquals("Expecting " + Arrays.deepToString(activities) + " got " + stackActivities,
+                stackActivities.size(), activities != null ? activities.length : 0);
+
+        if (activities == null) {
             return;
         }
 
-        for (TaskRecord task : tasks) {
-            assertTrue(stackTasks.contains(task));
+        for (ActivityRecord activity : activities) {
+            assertTrue(stackActivities.contains(activity));
         }
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
index 012eb52..9275512 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPositionerTests.java
@@ -66,7 +66,6 @@
     private int mMinVisibleWidth;
     private int mMinVisibleHeight;
     private TaskPositioner mPositioner;
-    private WindowState mWindow;
 
     @Before
     public void setUp() {
@@ -81,17 +80,16 @@
         mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, dm);
         removeGlobalMinSizeRestriction();
 
+        WindowState win = createWindow(null, TYPE_BASE_APPLICATION, "window");
         mPositioner = new TaskPositioner(mWm, mWm.mAtmService);
-        mPositioner.register(mDisplayContent);
 
-        mWindow = createWindow(null, TYPE_BASE_APPLICATION, "window");
-        mPositioner.mTask = mWindow.getTask();
-        mWindow.getStack().setWindowingMode(WINDOWING_MODE_FREEFORM);
+        mPositioner.register(mDisplayContent, win);
+
+        win.getStack().setWindowingMode(WINDOWING_MODE_FREEFORM);
     }
 
     @After
     public void tearDown() {
-        mWindow = null;
         mPositioner = null;
     }
 
@@ -122,8 +120,8 @@
         mPositioner.mTask.setBounds(r, true);
 
         // Start a drag resize starting upper left.
-        mPositioner.startDrag(mWindow, true /* resizing */,
-                false /* preserveOrientation */, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
+        mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
+                r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
         assertBoundsEquals(r, mPositioner.getWindowDragBounds());
 
         // Drag to a good landscape size.
@@ -149,8 +147,8 @@
                 mPositioner.getWindowDragBounds());
 
         // Start a drag resize left and see that only the left coord changes..
-        mPositioner.startDrag(mWindow, true /* resizing */,
-                false /* preserveOrientation */, r.left - MOUSE_DELTA_X, midY);
+        mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
+                r.left - MOUSE_DELTA_X, midY);
 
         // Drag to the left.
         mPositioner.resizeDrag(0.0f, midY);
@@ -184,8 +182,8 @@
         mPositioner.mTask.setBounds(r, true);
 
         // Drag upper left.
-        mPositioner.startDrag(mWindow, true /* resizing */,
-                false /* preserveOrientation */, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
+        mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
+                r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
         mPositioner.resizeDrag(0.0f, 0.0f);
         assertNotEquals(r.left, mPositioner.getWindowDragBounds().left);
         assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -193,8 +191,8 @@
         assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
 
         // Drag upper.
-        mPositioner.startDrag(mWindow, true /* resizing */,
-                false /* preserveOrientation */, midX, r.top - MOUSE_DELTA_Y);
+        mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, midX,
+                r.top - MOUSE_DELTA_Y);
         mPositioner.resizeDrag(0.0f, 0.0f);
         assertEquals(r.left, mPositioner.getWindowDragBounds().left);
         assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -202,8 +200,8 @@
         assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
 
         // Drag upper right.
-        mPositioner.startDrag(mWindow, true /* resizing */,
-                false /* preserveOrientation */, r.right + MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
+        mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
+                r.right + MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
         mPositioner.resizeDrag(r.right + 100, 0.0f);
         assertEquals(r.left, mPositioner.getWindowDragBounds().left);
         assertNotEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -211,8 +209,8 @@
         assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
 
         // Drag right.
-        mPositioner.startDrag(mWindow, true /* resizing */,
-                false /* preserveOrientation */, r.right + MOUSE_DELTA_X, midY);
+        mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
+                r.right + MOUSE_DELTA_X, midY);
         mPositioner.resizeDrag(r.right + 100, 0.0f);
         assertEquals(r.left, mPositioner.getWindowDragBounds().left);
         assertNotEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -220,8 +218,7 @@
         assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
 
         // Drag bottom right.
-        mPositioner.startDrag(mWindow, true /* resizing */,
-                false /* preserveOrientation */,
+        mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
                 r.right + MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y);
         mPositioner.resizeDrag(r.right + 100, r.bottom + 100);
         assertEquals(r.left, mPositioner.getWindowDragBounds().left);
@@ -230,8 +227,8 @@
         assertNotEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
 
         // Drag bottom.
-        mPositioner.startDrag(mWindow, true /* resizing */,
-                false /* preserveOrientation */, midX, r.bottom + MOUSE_DELTA_Y);
+        mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */, midX,
+                r.bottom + MOUSE_DELTA_Y);
         mPositioner.resizeDrag(r.right + 100, r.bottom + 100);
         assertEquals(r.left, mPositioner.getWindowDragBounds().left);
         assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -239,8 +236,8 @@
         assertNotEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
 
         // Drag bottom left.
-        mPositioner.startDrag(mWindow, true /* resizing */,
-                false /* preserveOrientation */, r.left - MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y);
+        mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
+                r.left - MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y);
         mPositioner.resizeDrag(0.0f, r.bottom + 100);
         assertNotEquals(r.left, mPositioner.getWindowDragBounds().left);
         assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -248,8 +245,8 @@
         assertNotEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
 
         // Drag left.
-        mPositioner.startDrag(mWindow, true /* resizing */,
-                false /* preserveOrientation */, r.left - MOUSE_DELTA_X, midY);
+        mPositioner.startDrag(true /* resizing */, false /* preserveOrientation */,
+                r.left - MOUSE_DELTA_X, midY);
         mPositioner.resizeDrag(0.0f, r.bottom + 100);
         assertNotEquals(r.left, mPositioner.getWindowDragBounds().left);
         assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -266,8 +263,8 @@
         final Rect r = new Rect(100, 220, 700, 520);
         mPositioner.mTask.setBounds(r, true);
 
-        mPositioner.startDrag(mWindow, true /* resizing */,
-                true /* preserveOrientation */, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
+        mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */,
+                r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
         assertBoundsEquals(r, mPositioner.getWindowDragBounds());
 
         // Drag to a good landscape size.
@@ -305,8 +302,8 @@
         final int midY = (r.top + r.bottom) / 2;
         mPositioner.mTask.setBounds(r, true);
 
-        mPositioner.startDrag(mWindow, true /* resizing */,
-                true /* preserveOrientation */, r.left - MOUSE_DELTA_X, midY);
+        mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */,
+                r.left - MOUSE_DELTA_X, midY);
 
         // Drag to the left.
         mPositioner.resizeDrag(0.0f, midY);
@@ -346,8 +343,8 @@
         final int midX = (r.left + r.right) / 2;
         mPositioner.mTask.setBounds(r, true);
 
-        mPositioner.startDrag(mWindow, true /*resizing*/,
-                true /*preserveOrientation*/, midX, r.top - MOUSE_DELTA_Y);
+        mPositioner.startDrag(true /*resizing*/, true /*preserveOrientation*/, midX,
+                r.top - MOUSE_DELTA_Y);
 
         // Drag to the left (no change).
         mPositioner.resizeDrag(0.0f, r.top);
@@ -382,8 +379,8 @@
         final Rect r = new Rect(330, 100, 630, 600);
         mPositioner.mTask.setBounds(r, true);
 
-        mPositioner.startDrag(mWindow, true /*resizing*/,
-                true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
+        mPositioner.startDrag(true /*resizing*/, true /*preserveOrientation*/,
+                r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
         assertBoundsEquals(r, mPositioner.getWindowDragBounds());
 
         // Drag to a good landscape size.
@@ -416,8 +413,8 @@
         final int midY = (r.top + r.bottom) / 2;
         mPositioner.mTask.setBounds(r, true);
 
-        mPositioner.startDrag(mWindow, true /* resizing */,
-                true /* preserveOrientation */, r.left - MOUSE_DELTA_X, midY);
+        mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */,
+                r.left - MOUSE_DELTA_X, midY);
 
         // Drag to the left.
         mPositioner.resizeDrag(0.0f, midY);
@@ -459,8 +456,8 @@
         final int midX = (r.left + r.right) / 2;
         mPositioner.mTask.setBounds(r, true);
 
-        mPositioner.startDrag(mWindow, true /* resizing */,
-                true /* preserveOrientation */, midX, r.top - MOUSE_DELTA_Y);
+        mPositioner.startDrag(true /* resizing */, true /* preserveOrientation */, midX,
+                r.top - MOUSE_DELTA_Y);
 
         // Drag to the left (no change).
         mPositioner.resizeDrag(0.0f, r.top);
@@ -502,7 +499,7 @@
     public void testFinishingMovingWhenBinderDied() {
         spyOn(mWm.mTaskPositioningController);
 
-        mPositioner.startDrag(mWindow, false, false, 0 /* startX */, 0 /* startY */);
+        mPositioner.startDrag(false, false, 0 /* startX */, 0 /* startY */);
         verify(mWm.mTaskPositioningController, never()).finishTaskPositioning();
         mPositioner.binderDied();
         verify(mWm.mTaskPositioningController).finishTaskPositioning();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
index a66c79c..7897047 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackContainersTests.java
@@ -121,7 +121,7 @@
                 false /* includingParents */);
 
         // Move the task of {@code mDisplayContent} to top.
-        stack.positionChildAt(WindowContainer.POSITION_TOP, task, true /* includingParents */);
+        stack.positionChildAt(WindowContainer.POSITION_TOP, (TaskRecord) task, true /* includingParents */);
         final int indexOfDisplayWithPinnedStack = mWm.mRoot.mChildren.indexOf(mDisplayContent);
 
         assertEquals("The testing DisplayContent should be moved to top with task",
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
index 164d28d..a9d0ea1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
@@ -58,12 +58,12 @@
         final Task task2 = createTaskInStack(stack, 1 /* userId */);
 
         // Current user task should be moved to top.
-        stack.positionChildAt(WindowContainer.POSITION_TOP, task1, false /* includingParents */);
+        stack.positionChildAt(WindowContainer.POSITION_TOP, (TaskRecord) task1, false /* includingParents */);
         assertEquals(stack.mChildren.get(0), task2);
         assertEquals(stack.mChildren.get(1), task1);
 
         // Non-current user won't be moved to top.
-        stack.positionChildAt(WindowContainer.POSITION_TOP, task2, false /* includingParents */);
+        stack.positionChildAt(WindowContainer.POSITION_TOP, (TaskRecord) task2, false /* includingParents */);
         assertEquals(stack.mChildren.get(0), task2);
         assertEquals(stack.mChildren.get(1), task1);
     }
@@ -112,12 +112,12 @@
     public void testStackRemoveImmediately() {
         final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
         final Task task = createTaskInStack(stack, 0 /* userId */);
-        assertEquals(stack, task.mStack);
+        assertEquals(stack, task.getTaskStack());
 
         // Remove stack and check if its child is also removed.
         stack.removeImmediately();
         assertNull(stack.getDisplayContent());
-        assertNull(task.mStack);
+        assertNull(task.getTaskStack());
     }
 
     @Test
@@ -133,7 +133,7 @@
         assertEquals(0, stack.getChildCount());
         assertNull(stack.getDisplayContent());
         assertNull(task.getDisplayContent());
-        assertNull(task.mStack);
+        assertNull(task.getTaskStack());
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java
similarity index 86%
rename from services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java
rename to services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java
index 8520d21..b8de3ca 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerThumbnailTest.java
@@ -37,27 +37,27 @@
  * Test class for {@link TaskSnapshotSurface}.
  *
  * Build/Install/Run:
- *  atest FrameworksServicesTest:AppWindowThumbnailTest
+ *  atest WmTests:WindowContainerThumbnailTest
  *
  */
 @SmallTest
 @Presubmit
 @RunWith(WindowTestRunner.class)
-public class AppWindowThumbnailTest extends WindowTestsBase {
-    private AppWindowThumbnail buildThumbnail() {
+public class WindowContainerThumbnailTest extends WindowTestsBase {
+    private WindowContainerThumbnail buildThumbnail() {
         final GraphicBuffer buffer = GraphicBuffer.create(1, 1, PixelFormat.RGBA_8888,
                 GraphicBuffer.USAGE_SW_READ_RARELY | GraphicBuffer.USAGE_SW_WRITE_NEVER);
         final ActivityRecord mockAr = mock(ActivityRecord.class);
         when(mockAr.getPendingTransaction()).thenReturn(new StubTransaction());
         when(mockAr.makeSurface()).thenReturn(new MockSurfaceControlBuilder());
-        return new AppWindowThumbnail(new StubTransaction(), mockAr,
+        return new WindowContainerThumbnail(new StubTransaction(), mockAr,
                 buffer, false, mock(Surface.class), mock(SurfaceAnimator.class));
     }
 
     @Test
     @FlakyTest(bugId = 131005232)
     public void testDestroy_nullsSurface() {
-        final AppWindowThumbnail t = buildThumbnail();
+        final WindowContainerThumbnail t = buildThumbnail();
         assertNotNull(t.getSurfaceControl());
         t.destroy();
         assertNull(t.getSurfaceControl());
diff --git a/telephony/common/com/google/android/mms/pdu/PduPersister.java b/telephony/common/com/google/android/mms/pdu/PduPersister.java
index 93f3065..95ae409 100755
--- a/telephony/common/com/google/android/mms/pdu/PduPersister.java
+++ b/telephony/common/com/google/android/mms/pdu/PduPersister.java
@@ -1548,6 +1548,7 @@
     public void release() {
         Uri uri = Uri.parse(TEMPORARY_DRM_OBJECT_URI);
         SqliteWrapper.delete(mContext, mContentResolver, uri, null, null);
+        mDrmManagerClient.release();
     }
 
     /**
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index dbada25..a315e6d 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2287,6 +2287,77 @@
             "use_only_rsrp_for_lte_signal_bar_bool";
 
     /**
+     * List of 4 customized 5G SS reference signal received power (SSRSRP) thresholds.
+     *
+     * Reference: 3GPP TS 38.215
+     *
+     * 4 threshold integers must be within the boundaries [-140 dB, -44 dB], and the levels are:
+     *     "NONE: [-140, threshold1]"
+     *     "POOR: (threshold1, threshold2]"
+     *     "MODERATE: (threshold2, threshold3]"
+     *     "GOOD:  (threshold3, threshold4]"
+     *     "EXCELLENT:  (threshold4, -44]"
+     *
+     * This key is considered invalid if the format is violated. If the key is invalid or
+     * not configured, a default value set will apply.
+     */
+    public static final String KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY =
+            "5g_nr_ssrsrp_thresholds_int_array";
+
+    /**
+     * List of 4 customized 5G SS reference signal received quality (SSRSRQ) thresholds.
+     *
+     * Reference: 3GPP TS 38.215
+     *
+     * 4 threshold integers must be within the boundaries [-20 dB, -3 dB], and the levels are:
+     *     "NONE: [-23, threshold1]"
+     *     "POOR: (threshold1, threshold2]"
+     *     "MODERATE: (threshold2, threshold3]"
+     *     "GOOD:  (threshold3, threshold4]"
+     *     "EXCELLENT:  (threshold4, -3]"
+     *
+     * This key is considered invalid if the format is violated. If the key is invalid or
+     * not configured, a default value set will apply.
+     */
+    public static final String KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY =
+            "5g_nr_ssrsrq_thresholds_int_array";
+
+    /**
+     * List of 4 customized 5G SS signal-to-noise and interference ratio (SSSINR) thresholds.
+     *
+     * Reference: 3GPP TS 38.215,
+     *            3GPP TS 38.133 10.1.16.1
+     *
+     * 4 threshold integers must be within the boundaries [-23 dB, 40 dB], and the levels are:
+     *     "NONE: [-23, threshold1]"
+     *     "POOR: (threshold1, threshold2]"
+     *     "MODERATE: (threshold2, threshold3]"
+     *     "GOOD:  (threshold3, threshold4]"
+     *     "EXCELLENT:  (threshold4, 40]"
+     *
+     * This key is considered invalid if the format is violated. If the key is invalid or
+     * not configured, a default value set will apply.
+     */
+    public static final String KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY =
+            "5g_nr_sssinr_thresholds_int_array";
+
+    /**
+     * Bit-field integer to determine whether to use SS reference signal received power (SSRSRP),
+     * SS reference signal received quality (SSRSRQ), or/and SS signal-to-noise and interference
+     * ratio (SSSINR) for the number of 5G NR signal bars. If multiple measures are set bit, the
+     * parameter whose value is smallest is used to indicate the signal bar.
+     *
+     *  SSRSRP = 1 << 0,
+     *  SSRSRQ = 1 << 1,
+     *  SSSINR = 1 << 2,
+     *
+     *  Reference: 3GPP TS 38.215,
+     *             3GPP TS 38.133 10.1.16.1
+     */
+    public static final String KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT =
+            "parameters_use_for_5g_nr_signal_bar_int";
+
+    /**
      * Key identifying if voice call barring notification is required to be shown to the user.
      * @hide
      */
@@ -2840,6 +2911,27 @@
      */
     public static final String KEY_5G_WATCHDOG_TIME_MS_LONG =
             "5g_watchdog_time_long";
+    /**
+     * Controls whether to switch data to primary from opportunistic subscription
+     * if primary is out of service. This control only affects system or 1st party app
+     * initiated data switch, but will not override data switch initiated by privileged carrier apps
+     * This carrier config is used to disable this feature.
+     * @hide
+     */
+    public static final String KEY_SWITCH_DATA_TO_PRIMARY_IF_PRIMARY_IS_OOS_BOOL =
+            "switch_data_to_primary_if_primary_is_oos_bool";
+
+    /**
+     * Controls back off time in milli seconds for switching back to
+     * opportunistic subscription. This time will be added to
+     * {@link CarrierConfigManager#KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_HYSTERESIS_TIME_LONG} to
+     * determine hysteresis time if there is frequent switching
+     * (determined by system app or 1st party app) between primary and opportunistic
+     * subscription.
+     * @hide
+     */
+    public static final String KEY_OPPORTUNISTIC_NETWORK_BACKOFF_TIME_LONG =
+            "opportunistic_network_backoff_time_long";
 
     /**
      * Indicates zero or more emergency number prefix(es), because some carrier requires
@@ -3648,6 +3740,9 @@
         sDefaults.putBoolean(KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL, true);
         /* Default value is 1 hour. */
         sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000);
+        sDefaults.putBoolean(KEY_SWITCH_DATA_TO_PRIMARY_IF_PRIMARY_IS_OOS_BOOL, true);
+        /* Default value is 10 seconds. */
+        sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_BACKOFF_TIME_LONG, 10000);
         sDefaults.putAll(Gps.getDefaults());
         sDefaults.putAll(Wifi.getDefaults());
         sDefaults.putIntArray(KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY,
diff --git a/telephony/java/android/telephony/ImsManager.java b/telephony/java/android/telephony/ImsManager.java
new file mode 100644
index 0000000..02d8be3
--- /dev/null
+++ b/telephony/java/android/telephony/ImsManager.java
@@ -0,0 +1,66 @@
+/*
+ * 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.telephony.ims;
+
+import android.annotation.SystemService;
+import android.content.Context;
+import android.telephony.SubscriptionManager;
+
+/**
+ * Provides access to information about Telephony IMS services on the device.
+ *
+ * @hide
+ */
+@SystemService(Context.TELEPHONY_IMS_SERVICE)
+public class ImsManager {
+
+    private Context mContext;
+
+    public ImsManager(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Create an instance of ImsRcsManager for the subscription id specified.
+     *
+     * @param subscriptionId The ID of the subscription that this ImsRcsManager will use.
+     * @throws IllegalArgumentException if the subscription is invalid.
+     * @return a ImsRcsManager instance with the specific subscription ID.
+     */
+    public ImsRcsManager getImsRcsManager(int subscriptionId) {
+        if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
+            throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
+        }
+
+        return new ImsRcsManager(mContext, subscriptionId);
+    }
+
+    /**
+     * Create an instance of ImsMmTelManager for the subscription id specified.
+     *
+     * @param subscriptionId The ID of the subscription that this ImsMmTelManager will use.
+     * @throws IllegalArgumentException if the subscription is invalid.
+     * @return a ImsMmTelManager instance with the specific subscription ID.
+     */
+    public ImsMmTelManager getImsMmTelManager(int subscriptionId) {
+        if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
+            throw new IllegalArgumentException("Invalid subscription ID: " + subscriptionId);
+        }
+
+        return new ImsMmTelManager(subscriptionId);
+    }
+}
diff --git a/telephony/java/android/telephony/SmsCbLocation.java b/telephony/java/android/telephony/SmsCbLocation.java
index adf7154..d8a4754 100644
--- a/telephony/java/android/telephony/SmsCbLocation.java
+++ b/telephony/java/android/telephony/SmsCbLocation.java
@@ -65,9 +65,8 @@
     /**
      * Construct a location object for the PLMN, LAC, and Cell ID. This class is immutable, so
      * the same object can be reused for multiple broadcasts.
-     * @hide
      */
-    public SmsCbLocation(String plmn, int lac, int cid) {
+    public SmsCbLocation(@NonNull String plmn, int lac, int cid) {
         mPlmn = plmn;
         mLac = lac;
         mCid = cid;
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 3cc6b21..dfcfed7 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -2946,6 +2946,7 @@
      * permission or had carrier privilege permission on the subscription.
      * {@link TelephonyManager#hasCarrierPrivileges()}
      *
+     * @throws IllegalStateException if Telephony service is in bad state.
      * @throws SecurityException if the caller doesn't meet the requirements
      *             outlined above.
      *
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index 6432016..21707b0 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -22,11 +22,15 @@
 import android.annotation.RequiresPermission;
 import android.content.Context;
 import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.telephony.AccessNetworkConstants;
-import android.telephony.SubscriptionManager;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
+import android.telephony.ims.aidl.IImsRcsController;
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.RcsFeature;
+import android.util.Log;
 
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
@@ -35,10 +39,11 @@
  * Manager for interfacing with the framework RCS services, including the User Capability Exchange
  * (UCE) service, as well as managing user settings.
  *
- * Use {@link #createForSubscriptionId(Context, int)} to create an instance of this manager.
+ * Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this manager.
  * @hide
  */
 public class ImsRcsManager implements RegistrationManager {
+    private static final String TAG = "ImsRcsManager";
 
     /**
      * Receives RCS availability status updates from the ImsService.
@@ -112,30 +117,23 @@
     private final int mSubId;
     private final Context mContext;
 
-
     /**
-     * Create an instance of ImsRcsManager for the subscription id specified.
-     *
-     * @param context The context to create this ImsRcsManager instance within.
-     * @param subscriptionId The ID of the subscription that this ImsRcsManager will use.
-     * @see android.telephony.SubscriptionManager#getActiveSubscriptionInfoList()
-     * @throws IllegalArgumentException if the subscription is invalid.
+     * Use {@link ImsManager#getImsRcsManager(int)} to create an instance of this class.
      * @hide
      */
-    public static ImsRcsManager createForSubscriptionId(Context context, int subscriptionId) {
-        if (!SubscriptionManager.isValidSubscriptionId(subscriptionId)) {
-            throw new IllegalArgumentException("Invalid subscription ID");
-        }
-
-        return new ImsRcsManager(context, subscriptionId);
+    public ImsRcsManager(Context context, int subId) {
+        mSubId = subId;
+        mContext = context;
     }
 
     /**
-     * Use {@link #createForSubscriptionId(Context, int)} to create an instance of this class.
+     * @return A {@link RcsUceAdapter} used for User Capability Exchange (UCE) operations for
+     * this subscription.
+     * @hide
      */
-    private ImsRcsManager(Context context, int subId) {
-        mContext = context;
-        mSubId = subId;
+    @NonNull
+    public RcsUceAdapter getUceAdapter() {
+        return new RcsUceAdapter(mSubId);
     }
 
     /**{@inheritDoc}*/
@@ -225,9 +223,22 @@
         if (executor == null) {
             throw new IllegalArgumentException("Must include a non-null Executor.");
         }
+
+        IImsRcsController imsRcsController = getIImsRcsController();
+        if (imsRcsController == null) {
+            Log.e(TAG, "Register availability callback: IImsRcsController is null");
+            throw new ImsException("Can not find remote IMS service",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+
         c.setExecutor(executor);
-        throw new UnsupportedOperationException("registerRcsAvailabilityCallback is not"
-                + "supported.");
+        try {
+            imsRcsController.registerRcsAvailabilityCallback(c.getBinder());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IImsRcsController#registerRcsAvailabilityCallback", e);
+            throw new ImsException("Remote IMS Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
     }
 
     /**
@@ -238,14 +249,31 @@
      * inactive subscription, it will result in a no-op.
      * @param c The RCS {@link AvailabilityCallback} to be removed.
      * @see #registerRcsAvailabilityCallback(Executor, AvailabilityCallback)
+     * @throws ImsException if the IMS service is not available when calling this method
+     * {@link ImsRcsController#unregisterRcsAvailabilityCallback()}.
+     * See {@link ImsException#getCode()} for more information on the error codes.
      */
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public void unregisterRcsAvailabilityCallback(@NonNull AvailabilityCallback c) {
+    public void unregisterRcsAvailabilityCallback(@NonNull AvailabilityCallback c)
+            throws ImsException {
         if (c == null) {
             throw new IllegalArgumentException("Must include a non-null AvailabilityCallback.");
         }
-        throw new UnsupportedOperationException("unregisterRcsAvailabilityCallback is not"
-                + "supported.");
+
+        IImsRcsController imsRcsController = getIImsRcsController();
+        if (imsRcsController == null) {
+            Log.e(TAG, "Unregister availability callback: IImsRcsController is null");
+            throw new ImsException("Can not find remote IMS service",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+
+        try {
+            imsRcsController.unregisterRcsAvailabilityCallback(c.getBinder());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IImsRcsController#unregisterRcsAvailabilityCallback", e);
+            throw new ImsException("Remote IMS Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
     }
 
     /**
@@ -260,10 +288,27 @@
      * rather the subscription is capable of this service over IMS.
      * @see #isAvailable(int)
      * @see android.telephony.CarrierConfigManager#KEY_USE_RCS_PRESENCE_BOOL
+     * @throws ImsException if the IMS service is not available when calling this method
+     * {@link ImsRcsController#isCapable(int, int)}.
+     * See {@link ImsException#getCode()} for more information on the error codes.
      */
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public boolean isCapable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
-        throw new UnsupportedOperationException("isCapable is not supported.");
+    public boolean isCapable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability)
+            throws ImsException {
+        IImsRcsController imsRcsController = getIImsRcsController();
+        if (imsRcsController == null) {
+            Log.e(TAG, "isCapable: IImsRcsController is null");
+            throw new ImsException("Can not find remote IMS service",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+
+        try {
+            return imsRcsController.isCapable(mSubId, capability);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IImsRcsController#isCapable", e);
+            throw new ImsException("Remote IMS Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
     }
 
     /**
@@ -277,18 +322,31 @@
      * false otherwise. If the capability is available, IMS is registered and the service is
      * currently available over IMS.
      * @see #isCapable(int)
+     * @throws ImsException if the IMS service is not available when calling this method
+     * {@link ImsRcsController#isAvailable(int, int)}.
+     * See {@link ImsException#getCode()} for more information on the error codes.
      */
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public boolean isAvailable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
-        throw new UnsupportedOperationException("isAvailable is not supported.");
+    public boolean isAvailable(@RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability)
+            throws ImsException {
+        IImsRcsController imsRcsController = getIImsRcsController();
+        if (imsRcsController == null) {
+            Log.e(TAG, "isAvailable: IImsRcsController is null");
+            throw new ImsException("Can not find remote IMS service",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+
+        try {
+            return imsRcsController.isAvailable(mSubId, capability);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IImsRcsController#isAvailable", e);
+            throw new ImsException("Remote IMS Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
     }
 
-    /**
-     * @return A new {@link RcsUceAdapter} used for User Capability Exchange (UCE) operations for
-     * this subscription.
-     */
-    @NonNull
-    public RcsUceAdapter getUceAdapter() {
-        return new RcsUceAdapter(mSubId);
+    private IImsRcsController getIImsRcsController() {
+        IBinder binder = ServiceManager.getService(Context.TELEPHONY_IMS_SERVICE);
+        return IImsRcsController.Stub.asInterface(binder);
     }
 }
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index a6a7a84..b47bcb9 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -23,6 +23,13 @@
 import android.annotation.RequiresPermission;
 import android.content.Context;
 import android.net.Uri;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.telephony.ims.aidl.IImsRcsController;
+import android.telephony.ims.aidl.IRcsUceControllerCallback;
+import android.util.Log;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -36,6 +43,7 @@
  * @hide
  */
 public class RcsUceAdapter {
+    private static final String TAG = "RcsUceAdapter";
 
     /**
      * An unknown error has caused the request to fail.
@@ -188,7 +196,6 @@
 
     /**
      * Not to be instantiated directly, use
-     * {@link ImsRcsManager#createForSubscriptionId(Context, int)} and
      * {@link ImsRcsManager#getUceAdapter()} to instantiate this manager class.
      */
     RcsUceAdapter(int subId) {
@@ -218,7 +225,45 @@
     public void requestCapabilities(@CallbackExecutor Executor executor,
             @NonNull List<Uri> contactNumbers,
             @NonNull CapabilitiesCallback c) throws ImsException {
-        throw new UnsupportedOperationException("isUceSettingEnabled is not supported.");
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null AvailabilityCallback.");
+        }
+        if (executor == null) {
+            throw new IllegalArgumentException("Must include a non-null Executor.");
+        }
+        if (contactNumbers == null) {
+            throw new IllegalArgumentException("Must include non-null contact number list.");
+        }
+
+        IImsRcsController imsRcsController = getIImsRcsController();
+        if (imsRcsController == null) {
+            Log.e(TAG, "requestCapabilities: IImsRcsController is null");
+            throw new ImsException("Can not find remote IMS service",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+
+        IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() {
+            @Override
+            public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) {
+                Binder.withCleanCallingIdentity(() ->
+                        executor.execute(() ->
+                                c.onCapabilitiesReceived(contactCapabilities)));
+            }
+            @Override
+            public void onError(int errorCode) {
+                Binder.withCleanCallingIdentity(() ->
+                        executor.execute(() ->
+                                c.onError(errorCode)));
+            }
+        };
+
+        try {
+            imsRcsController.requestCapabilities(mSubId, contactNumbers, internalCallback);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IImsRcsController#requestCapabilities", e);
+            throw new ImsException("Remote IMS Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
     }
 
     /**
@@ -233,7 +278,20 @@
      */
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public @PublishState int getUcePublishState() throws ImsException {
-        throw new UnsupportedOperationException("getPublishState is not supported.");
+        IImsRcsController imsRcsController = getIImsRcsController();
+        if (imsRcsController == null) {
+            Log.e(TAG, "getUcePublishState: IImsRcsController is null");
+            throw new ImsException("Can not find remote IMS service",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+
+        try {
+            return imsRcsController.getUcePublishState(mSubId);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IImsRcsController#getUcePublishState", e);
+            throw new ImsException("Remote IMS Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
     }
 
     /**
@@ -252,9 +310,22 @@
      */
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public boolean isUceSettingEnabled() throws ImsException {
-        // TODO: add SubscriptionController column for this property.
-        throw new UnsupportedOperationException("isUceSettingEnabled is not supported.");
+        IImsRcsController imsRcsController = getIImsRcsController();
+        if (imsRcsController == null) {
+            Log.e(TAG, "isUceSettingEnabled: IImsRcsController is null");
+            throw new ImsException("Can not find remote IMS service",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+
+        try {
+            return imsRcsController.isUceSettingEnabled(mSubId);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IImsRcsController#isUceSettingEnabled", e);
+            throw new ImsException("Remote IMS Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
     }
+
     /**
      * Change the user’s setting for whether or not UCE is enabled for the associated subscription.
      * @param isEnabled the user's setting for whether or not they wish for Presence and User
@@ -270,7 +341,24 @@
      */
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public void setUceSettingEnabled(boolean isEnabled) throws ImsException {
-        // TODO: add SubscriptionController column for this property.
-        throw new UnsupportedOperationException("setUceSettingEnabled is not supported.");
+        IImsRcsController imsRcsController = getIImsRcsController();
+        if (imsRcsController == null) {
+            Log.e(TAG, "setUceSettingEnabled: IImsRcsController is null");
+            throw new ImsException("Can not find remote IMS service",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+
+        try {
+            imsRcsController.setUceSettingEnabled(mSubId, isEnabled);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling IImsRcsController#setUceSettingEnabled", e);
+            throw new ImsException("Remote IMS Service is not available",
+                    ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+        }
+    }
+
+    private IImsRcsController getIImsRcsController() {
+        IBinder binder = ServiceManager.getService(Context.TELEPHONY_IMS_SERVICE);
+        return IImsRcsController.Stub.asInterface(binder);
     }
 }
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
new file mode 100644
index 0000000..b379bd0
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IImsRcsController.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.telephony.ims.aidl;
+
+import android.net.Uri;
+import android.telephony.ims.aidl.IImsCapabilityCallback;
+import android.telephony.ims.aidl.IRcsUceControllerCallback;
+
+/**
+ * Interface used to interact with the Telephony IMS.
+ *
+ * {@hide}
+ */
+interface IImsRcsController {
+    void registerRcsAvailabilityCallback(IImsCapabilityCallback c);
+    void unregisterRcsAvailabilityCallback(IImsCapabilityCallback c);
+    boolean isCapable(int subId, int capability);
+    boolean isAvailable(int subId, int capability);
+
+    // ImsUceAdapter specific
+    void requestCapabilities(int subId, in List<Uri> contactNumbers, IRcsUceControllerCallback c);
+    int getUcePublishState(int subId);
+    boolean isUceSettingEnabled(int subId);
+    void setUceSettingEnabled(int subId, boolean isEnabled);
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
new file mode 100644
index 0000000..5975930
--- /dev/null
+++ b/telephony/java/android/telephony/ims/aidl/IRcsUceControllerCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.telephony.ims.aidl;
+
+import android.telephony.ims.RcsContactUceCapability;
+
+/**
+ * Provides interface for RCS UCE when receive a change.
+ *
+ * {@hide}
+ */
+oneway interface IRcsUceControllerCallback {
+    void onCapabilitiesReceived(in List<RcsContactUceCapability> contactCapabilities);
+    void onError(int errorCode);
+}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
index 5766287..5ce42fd 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
@@ -215,7 +215,7 @@
     private static Pair<Integer, List<Geometry>> parseWarningAreaCoordinates(
             byte[] pdu, int wacOffset) {
         // little-endian
-        int wacDataLength = (pdu[wacOffset + 1] << 8) | pdu[wacOffset];
+        int wacDataLength = ((pdu[wacOffset + 1] & 0xff) << 8) | (pdu[wacOffset] & 0xff);
         int offset = wacOffset + 2;
 
         if (offset + wacDataLength > pdu.length) {
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
index 8f36b6e..06be5e2 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
@@ -251,11 +251,11 @@
 
     @Test
     public void testNetworkFailedRollback_Phase3() throws Exception {
-        // Sleep for > health check deadline
+        // Sleep for > health check deadline (120s to trigger rollback + 120s to reboot)
         // The device is expected to reboot during sleeping. This device method will fail and
         // the host will catch the assertion. If reboot doesn't happen, the host will fail the
         // assertion.
-        Thread.sleep(TimeUnit.SECONDS.toMillis(120));
+        Thread.sleep(TimeUnit.SECONDS.toMillis(240));
     }
 
     @Test
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index bfd5dd5..557d498 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -22,6 +22,7 @@
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 
+import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -47,6 +48,11 @@
                     phase));
     }
 
+    @Before
+    public void setUp() throws Exception {
+        getDevice().reboot();
+    }
+
     /**
      * Tests watchdog triggered staged rollbacks involving only apks.
      */
diff --git a/tools/apilint/apilint b/tools/apilint/apilint
deleted file mode 100755
index e42857f..0000000
--- a/tools/apilint/apilint
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-if [ "$1" == "--help" -o "$1" == "-h" ]; then
-echo "Usage: apilint [FILTERS...]"
-echo "  Shows lint from currently open files (as diffed from HEAD), i.e. errors"
-echo "  you will receive if you upload this CL."
-echo
-echo "Usage: apilint --all [FILTERS...]"
-echo "  Shows all lint errors present in the current working directory, regardless"
-echo "  of when they were added."
-echo
-echo "Usage: apilint --level API_LEVEL [FILTERS...]"
-echo "  Shows lint as it stands in API_LEVEL"
-echo
-echo "Usage: apilint --shal SHA [FILTERS...]"
-echo "  Shows lint from locally commited git change SHA."
-echo
-echo "Usage: apilint --unreleased [FILTERS...]"
-echo "  Shows all lint errors in the current working directory directory added since"
-echo "  the last released SDK version."
-echo
-echo "FILTERS"
-echo "  List of class or package names by which to filter the results."
-echo
-exit
-fi
-
-if [ \( -z "$ANDROID_BUILD_TOP" \) \
-           -a \( ! -f frameworks/base/api/current.txt \) \
-           -a \( ! -f frameworks/base/api/system-current.txt \) \
-        ]; then
-    echo "apilint must be run either with ANDROID_BUILD_TOP set or from the" 1>&2
-    echo "root of the android source tree" 1>&2
-    exit 1
-fi
-
-if [ ${ANDROID_BUILD_TOP:0:1} != "/" ]; then
-    echo "ANDROID_BUILD_TOP must be an absolute path, not: $ANDROID_BUILD_TOP" 1>&2
-    exit 1
-fi
-
-if [ -z "$ANDROID_BUILD_TOP" ]; then
-    ANDROID_BUILD_TOP=$(pwd)
-fi
-
-FW_BASE=$ANDROID_BUILD_TOP/frameworks/base
-
-MODE=open
-
-OPTIONS=$(getopt -n apilint -o "" -l "all,sha:,unreleased" -- "$@")
-
-[ $? -eq 0 ] || { 
-    exit 1
-}
-
-eval set -- "$OPTIONS"
-while true; do
-    case "$1" in
-    --all)
-        MODE=all
-        ;;
-    --sha)
-        shift; # The arg is next in position args
-        MODE=sha
-        SHA=$1
-        ;;
-    --unreleased)
-        MODE=unreleased
-        ;;
-    --)
-        shift
-        break
-        ;;
-    esac
-    shift
-done
-FILTERS=
-for var in "$@"
-do
-    FILTERS="$FILTERS --filter $var"
-done
-
-if [ $MODE = "all" ]; then
-    python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
-            --title "SDK" \
-            $FILTERS \
-            $ANDROID_BUILD_TOP/frameworks/base/api/current.txt
-    python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
-            --title "SystemApi" \
-            $FILTERS \
-            --base-current $ANDROID_BUILD_TOP/frameworks/base/api/current.txt \
-            $ANDROID_BUILD_TOP/frameworks/base/api/system-current.txt
-elif [ $MODE = "open" ]; then
-    python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
-            --title "SDK" \
-            $FILTERS \
-            $ANDROID_BUILD_TOP/frameworks/base/api/current.txt \
-            <(cd $FW_BASE ; git show HEAD:api/current.txt)
-    python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
-            --title "SystemApi" \
-            $FILTERS \
-            --base-current $ANDROID_BUILD_TOP/frameworks/base/api/current.txt \
-            --base-previous <(cd $FW_BASE ; git show HEAD:api/current.txt) \
-            $ANDROID_BUILD_TOP/frameworks/base/api/system-current.txt \
-            <(cd $FW_BASE ; git show HEAD:api/system-current.txt)
-elif [ $MODE = "sha" ]; then
-    python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
-            --title "SDK" \
-            $FILTERS \
-            <(cd $FW_BASE ; git show $SHA:api/current.txt) \
-            <(cd $FW_BASE ; git show $SHA^:api/current.txt)
-    python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
-            --title "SystemApi" \
-            $FILTERS \
-            --base-current <(cd $FW_BASE ; git show $SHA:api/current.txt) \
-            --base-previous <(cd $FW_BASE ; git show $SHA^:api/current.txt) \
-            <(cd $FW_BASE ; git show $SHA:api/system-current.txt) \
-            <(cd $FW_BASE ; git show $SHA^:api/system-current.txt)
-elif [ $MODE = "unreleased" ]; then
-    LAST_SDK=$(ls $ANDROID_BUILD_TOP/prebuilts/sdk | grep "^[0-9][0-9]*$" | sort -n | tail -n 1)
-    python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
-            --title "SDK" \
-            $FILTERS \
-            $ANDROID_BUILD_TOP/frameworks/base/api/current.txt \
-            $ANDROID_BUILD_TOP/prebuilts/sdk/$LAST_SDK/public/api/android.txt
-    python2.7 -B $ANDROID_BUILD_TOP/frameworks/base/tools/apilint/apilint.py \
-            --title "SystemApi" \
-            $FILTERS \
-            --base-current $ANDROID_BUILD_TOP/frameworks/base/api/current.txt \
-            --base-previous $ANDROID_BUILD_TOP/prebuilts/sdk/$LAST_SDK/public/api/android.txt \
-            $ANDROID_BUILD_TOP/frameworks/base/api/system-current.txt \
-            $ANDROID_BUILD_TOP/prebuilts/sdk/$LAST_SDK/system/api/android.txt
-fi
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py
deleted file mode 100644
index 912c1ad..0000000
--- a/tools/apilint/apilint.py
+++ /dev/null
@@ -1,2353 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2014 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.
-
-"""
-Enforces common Android public API design patterns.  It ignores lint messages from
-a previous API level, if provided.
-
-Usage: apilint.py current.txt
-Usage: apilint.py current.txt previous.txt
-
-You can also splice in blame details like this:
-$ git blame api/current.txt -t -e > /tmp/currentblame.txt
-$ apilint.py /tmp/currentblame.txt previous.txt --no-color
-"""
-
-import re, sys, collections, traceback, argparse, itertools
-
-
-BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
-
-ALLOW_GOOGLE = False
-USE_COLOR = True
-
-def format(fg=None, bg=None, bright=False, bold=False, dim=False, reset=False):
-    # manually derived from http://en.wikipedia.org/wiki/ANSI_escape_code#Codes
-    if not USE_COLOR: return ""
-    codes = []
-    if reset: codes.append("0")
-    else:
-        if not fg is None: codes.append("3%d" % (fg))
-        if not bg is None:
-            if not bright: codes.append("4%d" % (bg))
-            else: codes.append("10%d" % (bg))
-        if bold: codes.append("1")
-        elif dim: codes.append("2")
-        else: codes.append("22")
-    return "\033[%sm" % (";".join(codes))
-
-
-class Field():
-    def __init__(self, clazz, line, raw, blame, sig_format = 1):
-        self.clazz = clazz
-        self.line = line
-        self.raw = raw.strip(" {;")
-        self.blame = blame
-
-        if sig_format == 2:
-            V2LineParser(raw).parse_into_field(self)
-        elif sig_format == 1:
-            # drop generics for now; may need multiple passes
-            raw = re.sub("<[^<]+?>", "", raw)
-            raw = re.sub("<[^<]+?>", "", raw)
-
-            raw = raw.split()
-            self.split = list(raw)
-
-            for r in ["field", "volatile", "transient", "public", "protected", "static", "final", "deprecated"]:
-                while r in raw: raw.remove(r)
-
-            # ignore annotations for now
-            raw = [ r for r in raw if not r.startswith("@") ]
-
-            self.typ = raw[0]
-            self.name = raw[1].strip(";")
-            if len(raw) >= 4 and raw[2] == "=":
-                self.value = raw[3].strip(';"')
-            else:
-                self.value = None
-            self.annotations = []
-
-        self.ident = "-".join((self.typ, self.name, self.value or ""))
-
-    def __hash__(self):
-        return hash(self.raw)
-
-    def __repr__(self):
-        return self.raw
-
-
-class Argument(object):
-
-    __slots__ = ["type", "annotations", "name", "default"]
-
-    def __init__(self, type):
-        self.type = type
-        self.annotations = []
-        self.name = None
-        self.default = None
-
-
-class Method():
-    def __init__(self, clazz, line, raw, blame, sig_format = 1):
-        self.clazz = clazz
-        self.line = line
-        self.raw = raw.strip(" {;")
-        self.blame = blame
-
-        if sig_format == 2:
-            V2LineParser(raw).parse_into_method(self)
-        elif sig_format == 1:
-            # drop generics for now; may need multiple passes
-            raw = re.sub("<[^<]+?>", "", raw)
-            raw = re.sub("<[^<]+?>", "", raw)
-
-            # handle each clause differently
-            raw_prefix, raw_args, _, raw_throws = re.match(r"(.*?)\((.*?)\)( throws )?(.*?);$", raw).groups()
-
-            # parse prefixes
-            raw = re.split("[\s]+", raw_prefix)
-            for r in ["", ";"]:
-                while r in raw: raw.remove(r)
-            self.split = list(raw)
-
-            for r in ["method", "public", "protected", "static", "final", "deprecated", "abstract", "default", "operator", "synchronized"]:
-                while r in raw: raw.remove(r)
-
-            self.typ = raw[0]
-            self.name = raw[1]
-
-            # parse args
-            self.detailed_args = []
-            for arg in re.split(",\s*", raw_args):
-                arg = re.split("\s", arg)
-                # ignore annotations for now
-                arg = [ a for a in arg if not a.startswith("@") ]
-                if len(arg[0]) > 0:
-                    self.detailed_args.append(Argument(arg[0]))
-
-            # parse throws
-            self.throws = []
-            for throw in re.split(",\s*", raw_throws):
-                self.throws.append(throw)
-
-            self.annotations = []
-        else:
-            raise ValueError("Unknown signature format: " + sig_format)
-
-        self.args = map(lambda a: a.type, self.detailed_args)
-        self.ident = "-".join((self.typ, self.name, "-".join(self.args)))
-
-    def sig_matches(self, typ, name, args):
-        return typ == self.typ and name == self.name and args == self.args
-
-    def __hash__(self):
-        return hash(self.raw)
-
-    def __repr__(self):
-        return self.raw
-
-
-class Class():
-    def __init__(self, pkg, line, raw, blame, sig_format = 1):
-        self.pkg = pkg
-        self.line = line
-        self.raw = raw.strip(" {;")
-        self.blame = blame
-        self.ctors = []
-        self.fields = []
-        self.methods = []
-        self.annotations = []
-
-        if sig_format == 2:
-            V2LineParser(raw).parse_into_class(self)
-        elif sig_format == 1:
-            # drop generics for now; may need multiple passes
-            raw = re.sub("<[^<]+?>", "", raw)
-            raw = re.sub("<[^<]+?>", "", raw)
-
-            raw = raw.split()
-            self.split = list(raw)
-            if "class" in raw:
-                self.fullname = raw[raw.index("class")+1]
-            elif "interface" in raw:
-                self.fullname = raw[raw.index("interface")+1]
-            elif "@interface" in raw:
-                self.fullname = raw[raw.index("@interface")+1]
-            else:
-                raise ValueError("Funky class type %s" % (self.raw))
-
-            if "extends" in raw:
-                self.extends = raw[raw.index("extends")+1]
-            else:
-                self.extends = None
-
-            if "implements" in raw:
-                self.implements = raw[raw.index("implements")+1]
-                self.implements_all = [self.implements]
-            else:
-                self.implements = None
-                self.implements_all = []
-        else:
-            raise ValueError("Unknown signature format: " + sig_format)
-
-        self.fullname = self.pkg.name + "." + self.fullname
-        self.fullname_path = self.fullname.split(".")
-
-        if self.extends is not None:
-            self.extends_path = self.extends.split(".")
-        else:
-            self.extends_path = []
-
-        self.name = self.fullname[self.fullname.rindex(".")+1:]
-
-    def merge_from(self, other):
-        self.ctors.extend(other.ctors)
-        self.fields.extend(other.fields)
-        self.methods.extend(other.methods)
-
-    def __hash__(self):
-        return hash((self.raw, tuple(self.ctors), tuple(self.fields), tuple(self.methods)))
-
-    def __repr__(self):
-        return self.raw
-
-
-class Package():
-    NAME = re.compile("package(?: .*)? ([A-Za-z0-9.]+)")
-
-    def __init__(self, line, raw, blame):
-        self.line = line
-        self.raw = raw.strip(" {;")
-        self.blame = blame
-
-        self.name = Package.NAME.match(raw).group(1)
-        self.name_path = self.name.split(".")
-
-    def __repr__(self):
-        return self.raw
-
-class V2Tokenizer(object):
-    __slots__ = ["raw"]
-
-    SIGNATURE_PREFIX = "// Signature format: "
-    DELIMITER = re.compile(r'\s+|[()@<>;,={}/"!?]|\[\]|\.\.\.')
-    STRING_SPECIAL = re.compile(r'["\\]')
-
-    def __init__(self, raw):
-        self.raw = raw
-
-    def tokenize(self):
-        tokens = []
-        current = 0
-        raw = self.raw
-        length = len(raw)
-
-        while current < length:
-            while current < length:
-                start = current
-                match = V2Tokenizer.DELIMITER.search(raw, start)
-                if match is not None:
-                    match_start = match.start()
-                    if match_start == current:
-                        end = match.end()
-                    else:
-                        end = match_start
-                else:
-                    end = length
-
-                token = raw[start:end]
-                current = end
-
-                if token == "" or token[0] == " ":
-                    continue
-                else:
-                    break
-
-            if token == "@":
-                if raw[start:start+11] == "@interface ":
-                    current = start + 11
-                    tokens.append("@interface")
-                    continue
-            elif token == '/':
-                if raw[start:start+2] == "//":
-                    current = length
-                    continue
-            elif token == '"':
-                current, string_token = self.tokenize_string(raw, length, current)
-                tokens.append(token + string_token)
-                continue
-
-            tokens.append(token)
-
-        return tokens
-
-    def tokenize_string(self, raw, length, current):
-        start = current
-        end = length
-        while start < end:
-            match = V2Tokenizer.STRING_SPECIAL.search(raw, start)
-            if match:
-                if match.group() == '"':
-                    end = match.end()
-                    break
-                elif match.group() == '\\':
-                    # ignore whatever is after the slash
-                    start += 2
-                else:
-                    raise ValueError("Unexpected match: `%s`" % (match.group()))
-            else:
-                raise ValueError("Unexpected EOF tokenizing string: `%s`" % (raw[current - 1:],))
-
-        token = raw[current:end]
-        return end, token
-
-class V2LineParser(object):
-    __slots__ = ["tokenized", "current", "len"]
-
-    FIELD_KINDS = ("field", "property", "enum_constant")
-    MODIFIERS = set("public protected internal private abstract default static final transient volatile synchronized native operator sealed strictfp infix inline suspend vararg".split())
-    JAVA_LANG_TYPES = set("AbstractMethodError AbstractStringBuilder Appendable ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException AssertionError AutoCloseable Boolean BootstrapMethodError Byte Character CharSequence Class ClassCastException ClassCircularityError ClassFormatError ClassLoader ClassNotFoundException Cloneable CloneNotSupportedException Comparable Compiler Deprecated Double Enum EnumConstantNotPresentException Error Exception ExceptionInInitializerError Float FunctionalInterface IllegalAccessError IllegalAccessException IllegalArgumentException IllegalMonitorStateException IllegalStateException IllegalThreadStateException IncompatibleClassChangeError IndexOutOfBoundsException InheritableThreadLocal InstantiationError InstantiationException Integer InternalError InterruptedException Iterable LinkageError Long Math NegativeArraySizeException NoClassDefFoundError NoSuchFieldError NoSuchFieldException NoSuchMethodError NoSuchMethodException NullPointerException Number NumberFormatException Object OutOfMemoryError Override Package package-info.java Process ProcessBuilder ProcessEnvironment ProcessImpl Readable ReflectiveOperationException Runnable Runtime RuntimeException RuntimePermission SafeVarargs SecurityException SecurityManager Short StackOverflowError StackTraceElement StrictMath String StringBuffer StringBuilder StringIndexOutOfBoundsException SuppressWarnings System Thread ThreadDeath ThreadGroup ThreadLocal Throwable TypeNotPresentException UNIXProcess UnknownError UnsatisfiedLinkError UnsupportedClassVersionError UnsupportedOperationException VerifyError VirtualMachineError Void".split())
-
-    def __init__(self, raw):
-        self.tokenized = V2Tokenizer(raw).tokenize()
-        self.current = 0
-        self.len = len(self.tokenized)
-
-    def parse_into_method(self, method):
-        method.split = []
-        kind = self.parse_one_of("ctor", "method")
-        method.split.append(kind)
-        method.annotations = self.parse_annotations()
-        method.split.extend(self.parse_modifiers())
-        self.parse_matching_paren("<", ">")
-        if "@Deprecated" in method.annotations:
-            method.split.append("deprecated")
-        if kind == "ctor":
-            method.typ = "ctor"
-        else:
-            method.typ = self.parse_type()
-            method.split.append(method.typ)
-        method.name = self.parse_name()
-        method.split.append(method.name)
-        self.parse_token("(")
-        method.detailed_args = self.parse_args()
-        self.parse_token(")")
-        method.throws = self.parse_throws()
-        if "@interface" in method.clazz.split:
-            self.parse_annotation_default()
-        self.parse_token(";")
-        self.parse_eof()
-
-    def parse_into_class(self, clazz):
-        clazz.split = []
-        clazz.annotations = self.parse_annotations()
-        if "@Deprecated" in clazz.annotations:
-            clazz.split.append("deprecated")
-        clazz.split.extend(self.parse_modifiers())
-        kind = self.parse_one_of("class", "interface", "@interface", "enum")
-        if kind == "enum":
-            # enums are implicitly final
-            clazz.split.append("final")
-        clazz.split.append(kind)
-        clazz.fullname = self.parse_name()
-        self.parse_matching_paren("<", ">")
-        extends = self.parse_extends()
-        clazz.extends = extends[0] if extends else None
-        clazz.implements_all = self.parse_implements()
-        # The checks assume that interfaces are always found in implements, which isn't true for
-        # subinterfaces.
-        if not clazz.implements_all and "interface" in clazz.split:
-            clazz.implements_all = [clazz.extends]
-        clazz.implements = clazz.implements_all[0] if clazz.implements_all else None
-        self.parse_token("{")
-        self.parse_eof()
-
-    def parse_into_field(self, field):
-        kind = self.parse_one_of(*V2LineParser.FIELD_KINDS)
-        field.split = [kind]
-        field.annotations = self.parse_annotations()
-        if "@Deprecated" in field.annotations:
-            field.split.append("deprecated")
-        field.split.extend(self.parse_modifiers())
-        field.typ = self.parse_type()
-        field.split.append(field.typ)
-        field.name = self.parse_name()
-        field.split.append(field.name)
-        if self.parse_if("="):
-            field.value = self.parse_value_stripped()
-        else:
-            field.value = None
-
-        self.parse_token(";")
-        self.parse_eof()
-
-    def lookahead(self):
-        return self.tokenized[self.current]
-
-    def parse_one_of(self, *options):
-        found = self.lookahead()
-        if found not in options:
-            raise ValueError("Parsing failed, expected one of `%s` but found `%s` in %s" % (options, found, repr(self.tokenized)))
-        return self.parse_token()
-
-    def parse_token(self, tok = None):
-        found = self.lookahead()
-        if tok is not None and found != tok:
-            raise ValueError("Parsing failed, expected `%s` but found `%s` in %s" % (tok, found, repr(self.tokenized)))
-        self.current += 1
-        return found
-
-    def eof(self):
-        return self.current == self.len
-
-    def parse_eof(self):
-        if not self.eof():
-            raise ValueError("Parsing failed, expected EOF, but %s has not been parsed in %s" % (self.tokenized[self.current:], self.tokenized))
-
-    def parse_if(self, tok):
-        if not self.eof() and self.lookahead() == tok:
-            self.parse_token()
-            return True
-        return False
-
-    def parse_annotations(self):
-        ret = []
-        while self.lookahead() == "@":
-            ret.append(self.parse_annotation())
-        return ret
-
-    def parse_annotation(self):
-        ret = self.parse_token("@") + self.parse_token()
-        self.parse_matching_paren("(", ")")
-        return ret
-
-    def parse_matching_paren(self, open, close):
-        start = self.current
-        if not self.parse_if(open):
-            return
-        length = len(self.tokenized)
-        count = 1
-        while count > 0:
-            if self.current == length:
-                raise ValueError("Unexpected EOF looking for closing paren: `%s`" % (self.tokenized[start:],))
-            t = self.parse_token()
-            if t == open:
-                count += 1
-            elif t == close:
-                count -= 1
-        return self.tokenized[start:self.current]
-
-    def parse_modifiers(self):
-        ret = []
-        while self.lookahead() in V2LineParser.MODIFIERS:
-            ret.append(self.parse_token())
-        return ret
-
-    def parse_kotlin_nullability(self):
-        t = self.lookahead()
-        if t == "?" or t == "!":
-            return self.parse_token()
-        return None
-
-    def parse_type(self):
-        self.parse_annotations()
-        type = self.parse_token()
-        if type[-1] == '.':
-            self.parse_annotations()
-            type += self.parse_token()
-        if type in V2LineParser.JAVA_LANG_TYPES:
-            type = "java.lang." + type
-        self.parse_matching_paren("<", ">")
-        while True:
-            t = self.lookahead()
-            if t == "@":
-                self.parse_annotation()
-            elif t == "[]":
-                type += self.parse_token()
-            elif self.parse_kotlin_nullability() is not None:
-                pass  # discard nullability for now
-            else:
-                break
-        return type
-
-    def parse_arg_type(self):
-        type = self.parse_type()
-        if self.parse_if("..."):
-            type += "..."
-        self.parse_kotlin_nullability() # discard nullability for now
-        return type
-
-    def parse_name(self):
-        return self.parse_token()
-
-    def parse_args(self):
-        args = []
-        if self.lookahead() == ")":
-            return args
-
-        while True:
-            args.append(self.parse_arg())
-            if self.lookahead() == ")":
-                return args
-            self.parse_token(",")
-
-    def parse_arg(self):
-        self.parse_if("vararg")  # kotlin vararg
-        annotations = self.parse_annotations()
-        arg = Argument(self.parse_arg_type())
-        arg.annotations = annotations
-        l = self.lookahead()
-        if l != "," and l != ")":
-            if self.lookahead() != '=':
-                arg.name = self.parse_token()  # kotlin argument name
-            if self.parse_if('='): # kotlin default value
-                arg.default = self.parse_expression()
-        return arg
-
-    def parse_expression(self):
-        while not self.lookahead() in [')', ',', ';']:
-            (self.parse_matching_paren('(', ')') or
-            self.parse_matching_paren('{', '}') or
-            self.parse_token())
-
-    def parse_throws(self):
-        ret = []
-        if self.parse_if("throws"):
-            ret.append(self.parse_type())
-            while self.parse_if(","):
-                ret.append(self.parse_type())
-        return ret
-
-    def parse_extends(self):
-        if self.parse_if("extends"):
-            return self.parse_space_delimited_type_list()
-        return []
-
-    def parse_implements(self):
-        if self.parse_if("implements"):
-            return self.parse_space_delimited_type_list()
-        return []
-
-    def parse_space_delimited_type_list(self, terminals = ["implements", "{"]):
-        types = []
-        while True:
-            types.append(self.parse_type())
-            if self.lookahead() in terminals:
-                return types
-
-    def parse_annotation_default(self):
-        if self.parse_if("default"):
-            self.parse_expression()
-
-    def parse_value(self):
-        if self.lookahead() == "{":
-            return " ".join(self.parse_matching_paren("{", "}"))
-        elif self.lookahead() == "(":
-            return " ".join(self.parse_matching_paren("(", ")"))
-        else:
-            return self.parse_token()
-
-    def parse_value_stripped(self):
-        value = self.parse_value()
-        if value[0] == '"':
-            return value[1:-1]
-        return value
-
-
-def _parse_stream(f, clazz_cb=None, base_f=None, out_classes_with_base=None,
-                  in_classes_with_base=[]):
-    api = {}
-    in_classes_with_base = _retry_iterator(in_classes_with_base)
-
-    if base_f:
-        base_classes = _retry_iterator(_parse_stream_to_generator(base_f))
-    else:
-        base_classes = []
-
-    def handle_class(clazz):
-        if clazz_cb:
-            clazz_cb(clazz)
-        else: # In callback mode, don't keep track of the full API
-            api[clazz.fullname] = clazz
-
-    def handle_missed_classes_with_base(clazz):
-        for c in _yield_until_matching_class(in_classes_with_base, clazz):
-            base_class = _skip_to_matching_class(base_classes, c)
-            if base_class:
-                handle_class(base_class)
-
-    for clazz in _parse_stream_to_generator(f):
-        # Before looking at clazz, let's see if there's some classes that were not present, but
-        # may have an entry in the base stream.
-        handle_missed_classes_with_base(clazz)
-
-        base_class = _skip_to_matching_class(base_classes, clazz)
-        if base_class:
-            clazz.merge_from(base_class)
-            if out_classes_with_base is not None:
-                out_classes_with_base.append(clazz)
-        handle_class(clazz)
-
-    handle_missed_classes_with_base(None)
-
-    return api
-
-def _parse_stream_to_generator(f):
-    line = 0
-    pkg = None
-    clazz = None
-    blame = None
-    sig_format = 1
-
-    re_blame = re.compile(r"^(\^?[a-z0-9]{7,}) \(<([^>]+)>.+?\) (.+?)$")
-
-    field_prefixes = map(lambda kind: "    %s" % (kind,), V2LineParser.FIELD_KINDS)
-    def startsWithFieldPrefix(raw):
-        for prefix in field_prefixes:
-            if raw.startswith(prefix):
-                return True
-        return False
-
-    for raw in f:
-        line += 1
-        raw = raw.rstrip()
-        match = re_blame.match(raw)
-        if match is not None:
-            blame = match.groups()[0:2]
-            if blame[0].startswith("^"):  # Outside of blame range
-              blame = None
-            raw = match.groups()[2]
-        else:
-            blame = None
-
-        if line == 1 and V2Tokenizer.SIGNATURE_PREFIX in raw:
-            sig_format_string = raw[len(V2Tokenizer.SIGNATURE_PREFIX):]
-            if sig_format_string in ["2.0", "3.0"]:
-                sig_format = 2
-            else:
-                raise ValueError("Unknown format: %s" % (sig_format_string,))
-        elif raw.startswith("package"):
-            pkg = Package(line, raw, blame)
-        elif raw.startswith("  ") and raw.endswith("{"):
-            clazz = Class(pkg, line, raw, blame, sig_format=sig_format)
-        elif raw.startswith("    ctor"):
-            clazz.ctors.append(Method(clazz, line, raw, blame, sig_format=sig_format))
-        elif raw.startswith("    method"):
-            clazz.methods.append(Method(clazz, line, raw, blame, sig_format=sig_format))
-        elif startsWithFieldPrefix(raw):
-            clazz.fields.append(Field(clazz, line, raw, blame, sig_format=sig_format))
-        elif raw.startswith("  }") and clazz:
-            yield clazz
-
-def _retry_iterator(it):
-    """Wraps an iterator, such that calling send(True) on it will redeliver the same element"""
-    for e in it:
-        while True:
-            retry = yield e
-            if not retry:
-                break
-            # send() was called, asking us to redeliver clazz on next(). Still need to yield
-            # a dummy value to the send() first though.
-            if (yield "Returning clazz on next()"):
-                raise TypeError("send() must be followed by next(), not send()")
-
-def _skip_to_matching_class(classes, needle):
-    """Takes a classes iterator and consumes entries until it returns the class we're looking for
-
-    This relies on classes being sorted by package and class name."""
-
-    for clazz in classes:
-        if clazz.pkg.name < needle.pkg.name:
-            # We haven't reached the right package yet
-            continue
-        if clazz.pkg.name == needle.pkg.name and clazz.fullname < needle.fullname:
-            # We're in the right package, but not the right class yet
-            continue
-        if clazz.fullname == needle.fullname:
-            return clazz
-        # We ran past the right class. Send it back into the generator, then report failure.
-        classes.send(clazz)
-        return None
-
-def _yield_until_matching_class(classes, needle):
-    """Takes a class iterator and yields entries it until it reaches the class we're looking for.
-
-    This relies on classes being sorted by package and class name."""
-
-    for clazz in classes:
-        if needle is None:
-            yield clazz
-        elif clazz.pkg.name < needle.pkg.name:
-            # We haven't reached the right package yet
-            yield clazz
-        elif clazz.pkg.name == needle.pkg.name and clazz.fullname < needle.fullname:
-            # We're in the right package, but not the right class yet
-            yield clazz
-        elif clazz.fullname == needle.fullname:
-            # Class found, abort.
-            return
-        else:
-            # We ran past the right class. Send it back into the iterator, then abort.
-            classes.send(clazz)
-            return
-
-class Failure():
-    def __init__(self, sig, clazz, detail, error, rule, msg):
-        self.clazz = clazz
-        self.sig = sig
-        self.error = error
-        self.rule = rule
-        self.msg = msg
-
-        if error:
-            self.head = "Error %s" % (rule) if rule else "Error"
-            dump = "%s%s:%s %s" % (format(fg=RED, bg=BLACK, bold=True), self.head, format(reset=True), msg)
-        else:
-            self.head = "Warning %s" % (rule) if rule else "Warning"
-            dump = "%s%s:%s %s" % (format(fg=YELLOW, bg=BLACK, bold=True), self.head, format(reset=True), msg)
-
-        self.line = clazz.line
-        blame = clazz.blame
-        if detail is not None:
-            dump += "\n    in " + repr(detail)
-            self.line = detail.line
-            blame = detail.blame
-        dump += "\n    in " + repr(clazz)
-        dump += "\n    in " + repr(clazz.pkg)
-        dump += "\n    at line " + repr(self.line)
-        if blame is not None:
-            dump += "\n    last modified by %s in %s" % (blame[1], blame[0])
-
-        self.dump = dump
-
-    def __repr__(self):
-        return self.dump
-
-
-failures = {}
-
-def _fail(clazz, detail, error, rule, msg):
-    """Records an API failure to be processed later."""
-    global failures
-
-    sig = "%s-%s-%s" % (clazz.fullname, detail.ident if detail else None, msg)
-    sig = sig.replace(" deprecated ", " ")
-
-    failures[sig] = Failure(sig, clazz, detail, error, rule, msg)
-
-
-def warn(clazz, detail, rule, msg):
-    _fail(clazz, detail, False, rule, msg)
-
-def error(clazz, detail, rule, msg):
-    _fail(clazz, detail, True, rule, msg)
-
-
-noticed = {}
-
-def notice(clazz):
-    global noticed
-
-    noticed[clazz.fullname] = hash(clazz)
-
-
-verifiers = {}
-
-def verifier(f):
-    verifiers[f.__name__] = f
-    return f
-
-
-@verifier
-def verify_constants(clazz):
-    """All static final constants must be FOO_NAME style."""
-    if re.match("android\.R\.[a-z]+", clazz.fullname): return
-    if clazz.fullname.startswith("android.os.Build"): return
-    if clazz.fullname == "android.system.OsConstants": return
-
-    req = ["java.lang.String","byte","short","int","long","float","double","boolean","char"]
-    for f in clazz.fields:
-        if "static" in f.split and "final" in f.split:
-            if re.match("[A-Z0-9_]+", f.name) is None:
-                error(clazz, f, "C2", "Constant field names must be FOO_NAME")
-            if f.typ != "java.lang.String":
-                if f.name.startswith("MIN_") or f.name.startswith("MAX_"):
-                    warn(clazz, f, "C8", "If min/max could change in future, make them dynamic methods")
-            if f.typ in req and f.value is None:
-                error(clazz, f, None, "All constants must be defined at compile time")
-
-@verifier
-def verify_enums(clazz):
-    """Enums are bad, mmkay?"""
-    if clazz.extends == "java.lang.Enum" or "enum" in clazz.split:
-        error(clazz, None, "F5", "Enums are not allowed")
-
-@verifier
-def verify_class_names(clazz):
-    """Try catching malformed class names like myMtp or MTPUser."""
-    if clazz.fullname.startswith("android.opengl"): return
-    if clazz.fullname.startswith("android.renderscript"): return
-    if re.match("android\.R\.[a-z]+", clazz.fullname): return
-
-    if re.search("[A-Z]{2,}", clazz.name) is not None:
-        warn(clazz, None, "S1", "Class names with acronyms should be Mtp not MTP")
-    if re.match("[^A-Z]", clazz.name):
-        error(clazz, None, "S1", "Class must start with uppercase char")
-    if clazz.name.endswith("Impl"):
-        error(clazz, None, None, "Don't expose your implementation details")
-
-
-@verifier
-def verify_method_names(clazz):
-    """Try catching malformed method names, like Foo() or getMTU()."""
-    if clazz.fullname.startswith("android.opengl"): return
-    if clazz.fullname.startswith("android.renderscript"): return
-    if clazz.fullname == "android.system.OsConstants": return
-
-    for m in clazz.methods:
-        if re.search("[A-Z]{2,}", m.name) is not None:
-            warn(clazz, m, "S1", "Method names with acronyms should be getMtu() instead of getMTU()")
-        if re.match("[^a-z]", m.name):
-            error(clazz, m, "S1", "Method name must start with lowercase char")
-
-
-@verifier
-def verify_callbacks(clazz):
-    """Verify Callback classes.
-    All methods must follow onFoo() naming style."""
-    if clazz.fullname == "android.speech.tts.SynthesisCallback": return
-
-    if clazz.name.endswith("Callbacks"):
-        error(clazz, None, "L1", "Callback class names should be singular")
-    if clazz.name.endswith("Observer"):
-        warn(clazz, None, "L1", "Class should be named FooCallback")
-
-    if clazz.name.endswith("Callback"):
-        for m in clazz.methods:
-            if not re.match("on[A-Z][a-z]*", m.name):
-                error(clazz, m, "L1", "Callback method names must be onFoo() style")
-
-
-@verifier
-def verify_listeners(clazz):
-    """Verify Listener classes.
-    All Listener classes must be interface.
-    All methods must follow onFoo() naming style.
-    If only a single method, it must match class name:
-        interface OnFooListener { void onFoo() }"""
-
-    if clazz.name.endswith("Listener"):
-        if "abstract" in clazz.split and "class" in clazz.split:
-            error(clazz, None, "L1", "Listeners should be an interface, or otherwise renamed Callback")
-
-        for m in clazz.methods:
-            if not re.match("on[A-Z][a-z]*", m.name):
-                error(clazz, m, "L1", "Listener method names must be onFoo() style")
-
-        if len(clazz.methods) == 1 and clazz.name.startswith("On"):
-            m = clazz.methods[0]
-            if (m.name + "Listener").lower() != clazz.name.lower():
-                error(clazz, m, "L1", "Single listener method name must match class name")
-
-
-@verifier
-def verify_actions(clazz):
-    """Verify intent actions.
-    All action names must be named ACTION_FOO.
-    All action values must be scoped by package and match name:
-        package android.foo {
-            String ACTION_BAR = "android.foo.action.BAR";
-        }"""
-    for f in clazz.fields:
-        if f.value is None: continue
-        if f.name.startswith("EXTRA_"): continue
-        if f.name == "SERVICE_INTERFACE" or f.name == "PROVIDER_INTERFACE": continue
-        if "INTERACTION" in f.name: continue
-
-        if "static" in f.split and "final" in f.split and f.typ == "java.lang.String":
-            if "_ACTION" in f.name or "ACTION_" in f.name or ".action." in f.value.lower():
-                if not f.name.startswith("ACTION_"):
-                    error(clazz, f, "C3", "Intent action constant name must be ACTION_FOO")
-                else:
-                    if clazz.fullname == "android.content.Intent":
-                        prefix = "android.intent.action"
-                    elif clazz.fullname == "android.provider.Settings":
-                        prefix = "android.settings"
-                    elif clazz.fullname == "android.app.admin.DevicePolicyManager" or clazz.fullname == "android.app.admin.DeviceAdminReceiver":
-                        prefix = "android.app.action"
-                    else:
-                        prefix = clazz.pkg.name + ".action"
-                    expected = prefix + "." + f.name[7:]
-                    if f.value != expected:
-                        error(clazz, f, "C4", "Inconsistent action value; expected '%s'" % (expected))
-
-
-@verifier
-def verify_extras(clazz):
-    """Verify intent extras.
-    All extra names must be named EXTRA_FOO.
-    All extra values must be scoped by package and match name:
-        package android.foo {
-            String EXTRA_BAR = "android.foo.extra.BAR";
-        }"""
-    if clazz.fullname == "android.app.Notification": return
-    if clazz.fullname == "android.appwidget.AppWidgetManager": return
-
-    for f in clazz.fields:
-        if f.value is None: continue
-        if f.name.startswith("ACTION_"): continue
-
-        if "static" in f.split and "final" in f.split and f.typ == "java.lang.String":
-            if "_EXTRA" in f.name or "EXTRA_" in f.name or ".extra" in f.value.lower():
-                if not f.name.startswith("EXTRA_"):
-                    error(clazz, f, "C3", "Intent extra must be EXTRA_FOO")
-                else:
-                    if clazz.pkg.name == "android.content" and clazz.name == "Intent":
-                        prefix = "android.intent.extra"
-                    elif clazz.pkg.name == "android.app.admin":
-                        prefix = "android.app.extra"
-                    else:
-                        prefix = clazz.pkg.name + ".extra"
-                    expected = prefix + "." + f.name[6:]
-                    if f.value != expected:
-                        error(clazz, f, "C4", "Inconsistent extra value; expected '%s'" % (expected))
-
-
-@verifier
-def verify_equals(clazz):
-    """Verify that equals() and hashCode() must be overridden together."""
-    eq = False
-    hc = False
-    for m in clazz.methods:
-        if "static" in m.split: continue
-        if m.sig_matches("boolean", "equals", ["java.lang.Object"]): eq = True
-        if m.sig_matches("int", "hashCode", []): hc = True
-    if eq != hc:
-        error(clazz, None, "M8", "Must override both equals and hashCode; missing one")
-
-
-@verifier
-def verify_parcelable(clazz):
-    """Verify that Parcelable objects aren't hiding required bits."""
-    if clazz.implements == "android.os.Parcelable":
-        creator = [ i for i in clazz.fields if i.name == "CREATOR" ]
-        write = [ i for i in clazz.methods if i.name == "writeToParcel" ]
-        describe = [ i for i in clazz.methods if i.name == "describeContents" ]
-
-        if len(creator) == 0 or len(write) == 0 or len(describe) == 0:
-            error(clazz, None, "FW3", "Parcelable requires CREATOR, writeToParcel, and describeContents; missing one")
-
-        if "final" not in clazz.split:
-            error(clazz, None, "FW8", "Parcelable classes must be final")
-
-        for c in clazz.ctors:
-            if c.args == ["android.os.Parcel"]:
-                error(clazz, c, "FW3", "Parcelable inflation is exposed through CREATOR, not raw constructors")
-
-
-@verifier
-def verify_protected(clazz):
-    """Verify that no protected methods or fields are allowed."""
-    for m in clazz.methods:
-        if m.name == "finalize": continue
-        if "protected" in m.split:
-            error(clazz, m, "M7", "Protected methods not allowed; must be public")
-    for f in clazz.fields:
-        if "protected" in f.split:
-            error(clazz, f, "M7", "Protected fields not allowed; must be public")
-
-
-@verifier
-def verify_fields(clazz):
-    """Verify that all exposed fields are final.
-    Exposed fields must follow myName style.
-    Catch internal mFoo objects being exposed."""
-
-    IGNORE_BARE_FIELDS = [
-        "android.app.ActivityManager.RecentTaskInfo",
-        "android.app.Notification",
-        "android.content.pm.ActivityInfo",
-        "android.content.pm.ApplicationInfo",
-        "android.content.pm.ComponentInfo",
-        "android.content.pm.ResolveInfo",
-        "android.content.pm.FeatureGroupInfo",
-        "android.content.pm.InstrumentationInfo",
-        "android.content.pm.PackageInfo",
-        "android.content.pm.PackageItemInfo",
-        "android.content.res.Configuration",
-        "android.graphics.BitmapFactory.Options",
-        "android.os.Message",
-        "android.system.StructPollfd",
-    ]
-
-    for f in clazz.fields:
-        if not "final" in f.split:
-            if clazz.fullname in IGNORE_BARE_FIELDS:
-                pass
-            elif clazz.fullname.endswith("LayoutParams"):
-                pass
-            elif clazz.fullname.startswith("android.util.Mutable"):
-                pass
-            else:
-                error(clazz, f, "F2", "Bare fields must be marked final, or add accessors if mutable")
-
-        if "static" not in f.split and "property" not in f.split:
-            if not re.match("[a-z]([a-zA-Z]+)?", f.name):
-                error(clazz, f, "S1", "Non-static fields must be named using myField style")
-
-        if re.match("[ms][A-Z]", f.name):
-            error(clazz, f, "F1", "Internal objects must not be exposed")
-
-        if re.match("[A-Z_]+", f.name):
-            if "static" not in f.split or "final" not in f.split:
-                error(clazz, f, "C2", "Constants must be marked static final")
-
-
-@verifier
-def verify_register(clazz):
-    """Verify parity of registration methods.
-    Callback objects use register/unregister methods.
-    Listener objects use add/remove methods."""
-    methods = [ m.name for m in clazz.methods ]
-    for m in clazz.methods:
-        if "Callback" in m.raw:
-            if m.name.startswith("register"):
-                other = "unregister" + m.name[8:]
-                if other not in methods:
-                    error(clazz, m, "L2", "Missing unregister method")
-            if m.name.startswith("unregister"):
-                other = "register" + m.name[10:]
-                if other not in methods:
-                    error(clazz, m, "L2", "Missing register method")
-
-            if m.name.startswith("add") or m.name.startswith("remove"):
-                error(clazz, m, "L3", "Callback methods should be named register/unregister")
-
-        if "Listener" in m.raw:
-            if m.name.startswith("add"):
-                other = "remove" + m.name[3:]
-                if other not in methods:
-                    error(clazz, m, "L2", "Missing remove method")
-            if m.name.startswith("remove") and not m.name.startswith("removeAll"):
-                other = "add" + m.name[6:]
-                if other not in methods:
-                    error(clazz, m, "L2", "Missing add method")
-
-            if m.name.startswith("register") or m.name.startswith("unregister"):
-                error(clazz, m, "L3", "Listener methods should be named add/remove")
-
-
-@verifier
-def verify_sync(clazz):
-    """Verify synchronized methods aren't exposed."""
-    for m in clazz.methods:
-        if "synchronized" in m.split:
-            error(clazz, m, "M5", "Internal locks must not be exposed")
-
-
-@verifier
-def verify_intent_builder(clazz):
-    """Verify that Intent builders are createFooIntent() style."""
-    if clazz.name == "Intent": return
-
-    for m in clazz.methods:
-        if m.typ == "android.content.Intent":
-            if m.name.startswith("create") and m.name.endswith("Intent"):
-                pass
-            else:
-                warn(clazz, m, "FW1", "Methods creating an Intent should be named createFooIntent()")
-
-
-@verifier
-def verify_helper_classes(clazz):
-    """Verify that helper classes are named consistently with what they extend.
-    All developer extendable methods should be named onFoo()."""
-    test_methods = False
-    if clazz.extends == "android.app.Service":
-        test_methods = True
-        if not clazz.name.endswith("Service"):
-            error(clazz, None, "CL4", "Inconsistent class name; should be FooService")
-
-        found = False
-        for f in clazz.fields:
-            if f.name == "SERVICE_INTERFACE":
-                found = True
-                if f.value != clazz.fullname:
-                    error(clazz, f, "C4", "Inconsistent interface constant; expected '%s'" % (clazz.fullname))
-
-    if clazz.extends == "android.content.ContentProvider":
-        test_methods = True
-        if not clazz.name.endswith("Provider"):
-            error(clazz, None, "CL4", "Inconsistent class name; should be FooProvider")
-
-        found = False
-        for f in clazz.fields:
-            if f.name == "PROVIDER_INTERFACE":
-                found = True
-                if f.value != clazz.fullname:
-                    error(clazz, f, "C4", "Inconsistent interface constant; expected '%s'" % (clazz.fullname))
-
-    if clazz.extends == "android.content.BroadcastReceiver":
-        test_methods = True
-        if not clazz.name.endswith("Receiver"):
-            error(clazz, None, "CL4", "Inconsistent class name; should be FooReceiver")
-
-    if clazz.extends == "android.app.Activity":
-        test_methods = True
-        if not clazz.name.endswith("Activity"):
-            error(clazz, None, "CL4", "Inconsistent class name; should be FooActivity")
-
-    if test_methods:
-        for m in clazz.methods:
-            if "final" in m.split: continue
-            if not re.match("on[A-Z]", m.name):
-                if "abstract" in m.split:
-                    warn(clazz, m, None, "Methods implemented by developers should be named onFoo()")
-                else:
-                    warn(clazz, m, None, "If implemented by developer, should be named onFoo(); otherwise consider marking final")
-
-
-@verifier
-def verify_builder(clazz):
-    """Verify builder classes.
-    Methods should return the builder to enable chaining."""
-    if clazz.extends: return
-    if not clazz.name.endswith("Builder"): return
-
-    if clazz.name != "Builder":
-        warn(clazz, None, None, "Builder should be defined as inner class")
-
-    has_build = False
-    for m in clazz.methods:
-        if m.name == "build":
-            has_build = True
-            continue
-
-        if m.name.startswith("get"): continue
-        if m.name.startswith("clear"): continue
-
-        if m.name.startswith("with"):
-            warn(clazz, m, None, "Builder methods names should use setFoo() style")
-
-        if m.name.startswith("set"):
-            if not m.typ.endswith(clazz.fullname):
-                warn(clazz, m, "M4", "Methods must return the builder object")
-
-    if not has_build:
-        warn(clazz, None, None, "Missing build() method")
-
-    if "final" not in clazz.split:
-        error(clazz, None, None, "Builder should be final")
-
-
-@verifier
-def verify_aidl(clazz):
-    """Catch people exposing raw AIDL."""
-    if clazz.extends == "android.os.Binder" or clazz.implements == "android.os.IInterface":
-        error(clazz, None, None, "Raw AIDL interfaces must not be exposed")
-
-
-@verifier
-def verify_internal(clazz):
-    """Catch people exposing internal classes."""
-    if clazz.pkg.name.startswith("com.android"):
-        error(clazz, None, None, "Internal classes must not be exposed")
-
-def layering_build_ranking(ranking_list):
-    r = {}
-    for rank, ps in enumerate(ranking_list):
-        if not isinstance(ps, list):
-            ps = [ps]
-        for p in ps:
-            rs = r
-            for n in p.split('.'):
-                if n not in rs:
-                    rs[n] = {}
-                rs = rs[n]
-            rs['-rank'] = rank
-    return r
-
-LAYERING_PACKAGE_RANKING = layering_build_ranking([
-    ["android.service","android.accessibilityservice","android.inputmethodservice","android.printservice","android.appwidget","android.webkit","android.preference","android.gesture","android.print"],
-    "android.app",
-    "android.widget",
-    "android.view",
-    "android.animation",
-    "android.provider",
-    ["android.content","android.graphics.drawable"],
-    "android.database",
-    "android.text",
-    "android.graphics",
-    "android.os",
-    "android.util"
-])
-
-@verifier
-def verify_layering(clazz):
-    """Catch package layering violations.
-    For example, something in android.os depending on android.app."""
-
-    def rank(p):
-        r = None
-        l = LAYERING_PACKAGE_RANKING
-        for n in p.split('.'):
-            if n in l:
-                l = l[n]
-                if '-rank' in l:
-                    r = l['-rank']
-            else:
-                break
-        return r
-
-    cr = rank(clazz.pkg.name)
-    if cr is None: return
-
-    for f in clazz.fields:
-        ir = rank(f.typ)
-        if ir is not None and ir < cr:
-            warn(clazz, f, "FW6", "Field type violates package layering")
-
-    for m in itertools.chain(clazz.methods, clazz.ctors):
-        ir = rank(m.typ)
-        if ir is not None and ir < cr:
-            warn(clazz, m, "FW6", "Method return type violates package layering")
-        for arg in m.args:
-            ir = rank(arg)
-            if ir is not None and ir < cr:
-                warn(clazz, m, "FW6", "Method argument type violates package layering")
-
-
-@verifier
-def verify_boolean(clazz):
-    """Verifies that boolean accessors are named correctly.
-    For example, hasFoo() and setHasFoo()."""
-
-    def is_get(m): return len(m.args) == 0 and m.typ == "boolean"
-    def is_set(m): return len(m.args) == 1 and m.args[0] == "boolean"
-
-    gets = [ m for m in clazz.methods if is_get(m) ]
-    sets = [ m for m in clazz.methods if is_set(m) ]
-
-    def error_if_exists(methods, trigger, expected, actual):
-        for m in methods:
-            if m.name == actual:
-                error(clazz, m, "M6", "Symmetric method for %s must be named %s" % (trigger, expected))
-
-    for m in clazz.methods:
-        if is_get(m):
-            if re.match("is[A-Z]", m.name):
-                target = m.name[2:]
-                expected = "setIs" + target
-                error_if_exists(sets, m.name, expected, "setHas" + target)
-            elif re.match("has[A-Z]", m.name):
-                target = m.name[3:]
-                expected = "setHas" + target
-                error_if_exists(sets, m.name, expected, "setIs" + target)
-                error_if_exists(sets, m.name, expected, "set" + target)
-            elif re.match("get[A-Z]", m.name):
-                target = m.name[3:]
-                expected = "set" + target
-                error_if_exists(sets, m.name, expected, "setIs" + target)
-                error_if_exists(sets, m.name, expected, "setHas" + target)
-
-        if is_set(m):
-            if re.match("set[A-Z]", m.name):
-                target = m.name[3:]
-                expected = "get" + target
-                error_if_exists(sets, m.name, expected, "is" + target)
-                error_if_exists(sets, m.name, expected, "has" + target)
-
-
-@verifier
-def verify_collections(clazz):
-    """Verifies that collection types are interfaces."""
-    if clazz.fullname == "android.os.Bundle": return
-    if clazz.fullname == "android.os.Parcel": return
-
-    bad = ["java.util.Vector", "java.util.LinkedList", "java.util.ArrayList", "java.util.Stack",
-           "java.util.HashMap", "java.util.HashSet", "android.util.ArraySet", "android.util.ArrayMap"]
-    for m in clazz.methods:
-        if m.typ in bad:
-            error(clazz, m, "CL2", "Return type is concrete collection; must be higher-level interface")
-        for arg in m.args:
-            if arg in bad:
-                error(clazz, m, "CL2", "Argument is concrete collection; must be higher-level interface")
-
-
-@verifier
-def verify_uris(clazz):
-    bad = ["java.net.URL", "java.net.URI", "android.net.URL"]
-
-    for f in clazz.fields:
-        if f.typ in bad:
-            error(clazz, f, None, "Field must be android.net.Uri instead of " + f.typ)
-
-    for m in clazz.methods + clazz.ctors:
-        if m.typ in bad:
-            error(clazz, m, None, "Must return android.net.Uri instead of " + m.typ)
-        for arg in m.args:
-            if arg in bad:
-                error(clazz, m, None, "Argument must take android.net.Uri instead of " + arg)
-
-
-@verifier
-def verify_flags(clazz):
-    """Verifies that flags are non-overlapping."""
-    known = collections.defaultdict(int)
-    for f in clazz.fields:
-        if "FLAG_" in f.name:
-            try:
-                val = int(f.value)
-            except:
-                continue
-
-            scope = f.name[0:f.name.index("FLAG_")]
-            if val & known[scope]:
-                warn(clazz, f, "C1", "Found overlapping flag constant value")
-            known[scope] |= val
-
-
-@verifier
-def verify_exception(clazz):
-    """Verifies that methods don't throw generic exceptions."""
-    for m in clazz.methods:
-        for t in m.throws:
-            if t in ["java.lang.Exception", "java.lang.Throwable", "java.lang.Error"]:
-                error(clazz, m, "S1", "Methods must not throw generic exceptions")
-
-            if t in ["android.os.RemoteException"]:
-                if clazz.fullname == "android.content.ContentProviderClient": continue
-                if clazz.fullname == "android.os.Binder": continue
-                if clazz.fullname == "android.os.IBinder": continue
-
-                error(clazz, m, "FW9", "Methods calling into system server should rethrow RemoteException as RuntimeException")
-
-            if len(m.args) == 0 and t in ["java.lang.IllegalArgumentException", "java.lang.NullPointerException"]:
-                warn(clazz, m, "S1", "Methods taking no arguments should throw IllegalStateException")
-
-
-GOOGLE_IGNORECASE = re.compile("google", re.IGNORECASE)
-
-# Not marked as @verifier, because it is only conditionally applied.
-def verify_google(clazz):
-    """Verifies that APIs never reference Google."""
-
-    if GOOGLE_IGNORECASE.search(clazz.raw) is not None:
-        error(clazz, None, None, "Must never reference Google")
-
-    for test in clazz.ctors, clazz.fields, clazz.methods:
-        for t in test:
-            if GOOGLE_IGNORECASE.search(t.raw) is not None:
-                error(clazz, t, None, "Must never reference Google")
-
-
-@verifier
-def verify_bitset(clazz):
-    """Verifies that we avoid using heavy BitSet."""
-
-    for f in clazz.fields:
-        if f.typ == "java.util.BitSet":
-            error(clazz, f, None, "Field type must not be heavy BitSet")
-
-    for m in clazz.methods:
-        if m.typ == "java.util.BitSet":
-            error(clazz, m, None, "Return type must not be heavy BitSet")
-        for arg in m.args:
-            if arg == "java.util.BitSet":
-                error(clazz, m, None, "Argument type must not be heavy BitSet")
-
-
-@verifier
-def verify_manager(clazz):
-    """Verifies that FooManager is only obtained from Context."""
-
-    if not clazz.name.endswith("Manager"): return
-
-    for c in clazz.ctors:
-        error(clazz, c, None, "Managers must always be obtained from Context; no direct constructors")
-
-    for m in clazz.methods:
-        if m.typ == clazz.fullname:
-            error(clazz, m, None, "Managers must always be obtained from Context")
-
-
-@verifier
-def verify_boxed(clazz):
-    """Verifies that methods avoid boxed primitives."""
-
-    boxed = ["java.lang.Number","java.lang.Byte","java.lang.Double","java.lang.Float","java.lang.Integer","java.lang.Long","java.lang.Short"]
-
-    for c in clazz.ctors:
-        for arg in c.args:
-            if arg in boxed:
-                error(clazz, c, "M11", "Must avoid boxed primitives")
-
-    for f in clazz.fields:
-        if f.typ in boxed:
-            error(clazz, f, "M11", "Must avoid boxed primitives")
-
-    for m in clazz.methods:
-        if m.typ in boxed:
-            error(clazz, m, "M11", "Must avoid boxed primitives")
-        for arg in m.args:
-            if arg in boxed:
-                error(clazz, m, "M11", "Must avoid boxed primitives")
-
-
-@verifier
-def verify_static_utils(clazz):
-    """Verifies that helper classes can't be constructed."""
-    if clazz.fullname.startswith("android.opengl"): return
-    if clazz.fullname.startswith("android.R"): return
-
-    # Only care about classes with default constructors
-    if len(clazz.ctors) == 1 and len(clazz.ctors[0].args) == 0:
-        test = []
-        test.extend(clazz.fields)
-        test.extend(clazz.methods)
-
-        if len(test) == 0: return
-        for t in test:
-            if "static" not in t.split:
-                return
-
-        error(clazz, None, None, "Fully-static utility classes must not have constructor")
-
-
-# @verifier  # Disabled for now
-def verify_overload_args(clazz):
-    """Verifies that method overloads add new arguments at the end."""
-    if clazz.fullname.startswith("android.opengl"): return
-
-    overloads = collections.defaultdict(list)
-    for m in clazz.methods:
-        if "deprecated" in m.split: continue
-        overloads[m.name].append(m)
-
-    for name, methods in overloads.items():
-        if len(methods) <= 1: continue
-
-        # Look for arguments common across all overloads
-        def cluster(args):
-            count = collections.defaultdict(int)
-            res = set()
-            for i in range(len(args)):
-                a = args[i]
-                res.add("%s#%d" % (a, count[a]))
-                count[a] += 1
-            return res
-
-        common_args = cluster(methods[0].args)
-        for m in methods:
-            common_args = common_args & cluster(m.args)
-
-        if len(common_args) == 0: continue
-
-        # Require that all common arguments are present at start of signature
-        locked_sig = None
-        for m in methods:
-            sig = m.args[0:len(common_args)]
-            if not common_args.issubset(cluster(sig)):
-                warn(clazz, m, "M2", "Expected common arguments [%s] at beginning of overloaded method" % (", ".join(common_args)))
-            elif not locked_sig:
-                locked_sig = sig
-            elif locked_sig != sig:
-                error(clazz, m, "M2", "Expected consistent argument ordering between overloads: %s..." % (", ".join(locked_sig)))
-
-
-@verifier
-def verify_callback_handlers(clazz):
-    """Verifies that methods adding listener/callback have overload
-    for specifying delivery thread."""
-
-    # Ignore UI packages which assume main thread
-    skip = [
-        "animation",
-        "view",
-        "graphics",
-        "transition",
-        "widget",
-        "webkit",
-    ]
-    for s in skip:
-        if s in clazz.pkg.name_path: return
-        if s in clazz.extends_path: return
-
-    # Ignore UI classes which assume main thread
-    if "app" in clazz.pkg.name_path or "app" in clazz.extends_path:
-        for s in ["ActionBar","Dialog","Application","Activity","Fragment","Loader"]:
-            if s in clazz.fullname: return
-    if "content" in clazz.pkg.name_path or "content" in clazz.extends_path:
-        for s in ["Loader"]:
-            if s in clazz.fullname: return
-
-    found = {}
-    by_name = collections.defaultdict(list)
-    examine = clazz.ctors + clazz.methods
-    for m in examine:
-        if m.name.startswith("unregister"): continue
-        if m.name.startswith("remove"): continue
-        if re.match("on[A-Z]+", m.name): continue
-
-        by_name[m.name].append(m)
-
-        for a in m.args:
-            if a.endswith("Listener") or a.endswith("Callback") or a.endswith("Callbacks"):
-                found[m.name] = m
-
-    for f in found.values():
-        takes_handler = False
-        takes_exec = False
-        for m in by_name[f.name]:
-            if "android.os.Handler" in m.args:
-                takes_handler = True
-            if "java.util.concurrent.Executor" in m.args:
-                takes_exec = True
-        if not takes_exec:
-            warn(clazz, f, "L1", "Registration methods should have overload that accepts delivery Executor")
-
-
-@verifier
-def verify_context_first(clazz):
-    """Verifies that methods accepting a Context keep it the first argument."""
-    examine = clazz.ctors + clazz.methods
-    for m in examine:
-        if len(m.args) > 1 and m.args[0] != "android.content.Context":
-            if "android.content.Context" in m.args[1:]:
-                error(clazz, m, "M3", "Context is distinct, so it must be the first argument")
-        if len(m.args) > 1 and m.args[0] != "android.content.ContentResolver":
-            if "android.content.ContentResolver" in m.args[1:]:
-                error(clazz, m, "M3", "ContentResolver is distinct, so it must be the first argument")
-
-
-@verifier
-def verify_listener_last(clazz):
-    """Verifies that methods accepting a Listener or Callback keep them as last arguments."""
-    examine = clazz.ctors + clazz.methods
-    for m in examine:
-        if "Listener" in m.name or "Callback" in m.name: continue
-        found = False
-        for a in m.args:
-            if a.endswith("Callback") or a.endswith("Callbacks") or a.endswith("Listener"):
-                found = True
-            elif found:
-                warn(clazz, m, "M3", "Listeners should always be at end of argument list")
-
-
-@verifier
-def verify_resource_names(clazz):
-    """Verifies that resource names have consistent case."""
-    if not re.match("android\.R\.[a-z]+", clazz.fullname): return
-
-    # Resources defined by files are foo_bar_baz
-    if clazz.name in ["anim","animator","color","dimen","drawable","interpolator","layout","transition","menu","mipmap","string","plurals","raw","xml"]:
-        for f in clazz.fields:
-            if re.match("config_[a-z][a-zA-Z1-9]*$", f.name): continue
-            if f.name.startswith("config_"):
-                error(clazz, f, None, "Expected config name to be config_fooBarBaz style")
-
-            if re.match("[a-z1-9_]+$", f.name): continue
-            error(clazz, f, None, "Expected resource name in this class to be foo_bar_baz style")
-
-    # Resources defined inside files are fooBarBaz
-    if clazz.name in ["array","attr","id","bool","fraction","integer"]:
-        for f in clazz.fields:
-            if re.match("config_[a-z][a-zA-Z1-9]*$", f.name): continue
-            if re.match("layout_[a-z][a-zA-Z1-9]*$", f.name): continue
-            if re.match("state_[a-z_]*$", f.name): continue
-
-            if re.match("[a-z][a-zA-Z1-9]*$", f.name): continue
-            error(clazz, f, "C7", "Expected resource name in this class to be fooBarBaz style")
-
-    # Styles are FooBar_Baz
-    if clazz.name in ["style"]:
-        for f in clazz.fields:
-            if re.match("[A-Z][A-Za-z1-9]+(_[A-Z][A-Za-z1-9]+?)*$", f.name): continue
-            error(clazz, f, "C7", "Expected resource name in this class to be FooBar_Baz style")
-
-
-@verifier
-def verify_files(clazz):
-    """Verifies that methods accepting File also accept streams."""
-
-    has_file = set()
-    has_stream = set()
-
-    test = []
-    test.extend(clazz.ctors)
-    test.extend(clazz.methods)
-
-    for m in test:
-        if "java.io.File" in m.args:
-            has_file.add(m)
-        if "java.io.FileDescriptor" in m.args or "android.os.ParcelFileDescriptor" in m.args or "java.io.InputStream" in m.args or "java.io.OutputStream" in m.args:
-            has_stream.add(m.name)
-
-    for m in has_file:
-        if m.name not in has_stream:
-            warn(clazz, m, "M10", "Methods accepting File should also accept FileDescriptor or streams")
-
-
-@verifier
-def verify_manager_list(clazz):
-    """Verifies that managers return List<? extends Parcelable> instead of arrays."""
-
-    if not clazz.name.endswith("Manager"): return
-
-    for m in clazz.methods:
-        if m.typ.startswith("android.") and m.typ.endswith("[]"):
-            warn(clazz, m, None, "Methods should return List<? extends Parcelable> instead of Parcelable[] to support ParceledListSlice under the hood")
-
-
-@verifier
-def verify_abstract_inner(clazz):
-    """Verifies that abstract inner classes are static."""
-
-    if re.match(".+?\.[A-Z][^\.]+\.[A-Z]", clazz.fullname):
-        if "abstract" in clazz.split and "static" not in clazz.split:
-            warn(clazz, None, None, "Abstract inner classes should be static to improve testability")
-
-
-@verifier
-def verify_runtime_exceptions(clazz):
-    """Verifies that runtime exceptions aren't listed in throws."""
-
-    banned = [
-        "java.lang.NullPointerException",
-        "java.lang.ClassCastException",
-        "java.lang.IndexOutOfBoundsException",
-        "java.lang.reflect.UndeclaredThrowableException",
-        "java.lang.reflect.MalformedParametersException",
-        "java.lang.reflect.MalformedParameterizedTypeException",
-        "java.lang.invoke.WrongMethodTypeException",
-        "java.lang.EnumConstantNotPresentException",
-        "java.lang.IllegalMonitorStateException",
-        "java.lang.SecurityException",
-        "java.lang.UnsupportedOperationException",
-        "java.lang.annotation.AnnotationTypeMismatchException",
-        "java.lang.annotation.IncompleteAnnotationException",
-        "java.lang.TypeNotPresentException",
-        "java.lang.IllegalStateException",
-        "java.lang.ArithmeticException",
-        "java.lang.IllegalArgumentException",
-        "java.lang.ArrayStoreException",
-        "java.lang.NegativeArraySizeException",
-        "java.util.MissingResourceException",
-        "java.util.EmptyStackException",
-        "java.util.concurrent.CompletionException",
-        "java.util.concurrent.RejectedExecutionException",
-        "java.util.IllformedLocaleException",
-        "java.util.ConcurrentModificationException",
-        "java.util.NoSuchElementException",
-        "java.io.UncheckedIOException",
-        "java.time.DateTimeException",
-        "java.security.ProviderException",
-        "java.nio.BufferUnderflowException",
-        "java.nio.BufferOverflowException",
-    ]
-
-    examine = clazz.ctors + clazz.methods
-    for m in examine:
-        for t in m.throws:
-            if t in banned:
-                error(clazz, m, None, "Methods must not mention RuntimeException subclasses in throws clauses")
-
-
-@verifier
-def verify_error(clazz):
-    """Verifies that we always use Exception instead of Error."""
-    if not clazz.extends: return
-    if clazz.extends.endswith("Error"):
-        error(clazz, None, None, "Trouble must be reported through an Exception, not Error")
-    if clazz.extends.endswith("Exception") and not clazz.name.endswith("Exception"):
-        error(clazz, None, None, "Exceptions must be named FooException")
-
-
-@verifier
-def verify_units(clazz):
-    """Verifies that we use consistent naming for units."""
-
-    # If we find K, recommend replacing with V
-    bad = {
-        "Ns": "Nanos",
-        "Ms": "Millis or Micros",
-        "Sec": "Seconds", "Secs": "Seconds",
-        "Hr": "Hours", "Hrs": "Hours",
-        "Mo": "Months", "Mos": "Months",
-        "Yr": "Years", "Yrs": "Years",
-        "Byte": "Bytes", "Space": "Bytes",
-    }
-
-    for m in clazz.methods:
-        if m.typ not in ["short","int","long"]: continue
-        for k, v in bad.iteritems():
-            if m.name.endswith(k):
-                error(clazz, m, None, "Expected method name units to be " + v)
-        if m.name.endswith("Nanos") or m.name.endswith("Micros"):
-            warn(clazz, m, None, "Returned time values are strongly encouraged to be in milliseconds unless you need the extra precision")
-        if m.name.endswith("Seconds"):
-            error(clazz, m, None, "Returned time values must be in milliseconds")
-
-    for m in clazz.methods:
-        typ = m.typ
-        if typ == "void":
-            if len(m.args) != 1: continue
-            typ = m.args[0]
-
-        if m.name.endswith("Fraction") and typ != "float":
-            error(clazz, m, None, "Fractions must use floats")
-        if m.name.endswith("Percentage") and typ != "int":
-            error(clazz, m, None, "Percentage must use ints")
-
-
-@verifier
-def verify_closable(clazz):
-    """Verifies that classes are AutoClosable."""
-    if "java.lang.AutoCloseable" in clazz.implements_all: return
-    if "java.io.Closeable" in clazz.implements_all: return
-
-    for m in clazz.methods:
-        if len(m.args) > 0: continue
-        if m.name in ["close","release","destroy","finish","finalize","disconnect","shutdown","stop","free","quit"]:
-            warn(clazz, m, None, "Classes that release resources should implement AutoClosable and CloseGuard")
-            return
-
-
-@verifier
-def verify_member_name_not_kotlin_keyword(clazz):
-    """Prevent method names which are keywords in Kotlin."""
-
-    # https://kotlinlang.org/docs/reference/keyword-reference.html#hard-keywords
-    # This list does not include Java keywords as those are already impossible to use.
-    keywords = [
-        'as',
-        'fun',
-        'in',
-        'is',
-        'object',
-        'typealias',
-        'val',
-        'var',
-        'when',
-    ]
-
-    for m in clazz.methods:
-        if m.name in keywords:
-            error(clazz, m, None, "Method name must not be a Kotlin keyword")
-    for f in clazz.fields:
-        if f.name in keywords:
-            error(clazz, f, None, "Field name must not be a Kotlin keyword")
-
-
-@verifier
-def verify_method_name_not_kotlin_operator(clazz):
-    """Warn about method names which become operators in Kotlin."""
-
-    binary = set()
-
-    def unique_binary_op(m, op):
-        if op in binary:
-            error(clazz, m, None, "Only one of '{0}' and '{0}Assign' methods should be present for Kotlin".format(op))
-        binary.add(op)
-
-    for m in clazz.methods:
-        if 'static' in m.split or 'operator' in m.split:
-            continue
-
-        # https://kotlinlang.org/docs/reference/operator-overloading.html#unary-prefix-operators
-        if m.name in ['unaryPlus', 'unaryMinus', 'not'] and len(m.args) == 0:
-            warn(clazz, m, None, "Method can be invoked as a unary operator from Kotlin")
-
-        # https://kotlinlang.org/docs/reference/operator-overloading.html#increments-and-decrements
-        if m.name in ['inc', 'dec'] and len(m.args) == 0 and m.typ != 'void':
-            # This only applies if the return type is the same or a subtype of the enclosing class, but we have no
-            # practical way of checking that relationship here.
-            warn(clazz, m, None, "Method can be invoked as a pre/postfix inc/decrement operator from Kotlin")
-
-        # https://kotlinlang.org/docs/reference/operator-overloading.html#arithmetic
-        if m.name in ['plus', 'minus', 'times', 'div', 'rem', 'mod', 'rangeTo'] and len(m.args) == 1:
-            warn(clazz, m, None, "Method can be invoked as a binary operator from Kotlin")
-            unique_binary_op(m, m.name)
-
-        # https://kotlinlang.org/docs/reference/operator-overloading.html#in
-        if m.name == 'contains' and len(m.args) == 1 and m.typ == 'boolean':
-            warn(clazz, m, None, "Method can be invoked as a 'in' operator from Kotlin")
-
-        # https://kotlinlang.org/docs/reference/operator-overloading.html#indexed
-        if (m.name == 'get' and len(m.args) > 0) or (m.name == 'set' and len(m.args) > 1):
-            warn(clazz, m, None, "Method can be invoked with an indexing operator from Kotlin")
-
-        # https://kotlinlang.org/docs/reference/operator-overloading.html#invoke
-        if m.name == 'invoke':
-            warn(clazz, m, None, "Method can be invoked with function call syntax from Kotlin")
-
-        # https://kotlinlang.org/docs/reference/operator-overloading.html#assignments
-        if m.name in ['plusAssign', 'minusAssign', 'timesAssign', 'divAssign', 'remAssign', 'modAssign'] \
-                and len(m.args) == 1 \
-                and m.typ == 'void':
-            warn(clazz, m, None, "Method can be invoked as a compound assignment operator from Kotlin")
-            unique_binary_op(m, m.name[:-6])  # Remove 'Assign' suffix
-
-
-@verifier
-def verify_collections_over_arrays(clazz):
-    """Warn that [] should be Collections."""
-
-    if "@interface" in clazz.split:
-        return
-
-    safe = ["java.lang.String[]","byte[]","short[]","int[]","long[]","float[]","double[]","boolean[]","char[]"]
-    for m in clazz.methods:
-        if m.typ.endswith("[]") and m.typ not in safe:
-            warn(clazz, m, None, "Method should return Collection<> (or subclass) instead of raw array")
-        for arg in m.args:
-            if arg.endswith("[]") and arg not in safe:
-                warn(clazz, m, None, "Method argument should be Collection<> (or subclass) instead of raw array")
-
-
-@verifier
-def verify_user_handle(clazz):
-    """Methods taking UserHandle should be ForUser or AsUser."""
-    if clazz.name.endswith("Listener") or clazz.name.endswith("Callback") or clazz.name.endswith("Callbacks"): return
-    if clazz.fullname == "android.app.admin.DeviceAdminReceiver": return
-    if clazz.fullname == "android.content.pm.LauncherApps": return
-    if clazz.fullname == "android.os.UserHandle": return
-    if clazz.fullname == "android.os.UserManager": return
-
-    for m in clazz.methods:
-        if re.match("on[A-Z]+", m.name): continue
-
-        has_arg = "android.os.UserHandle" in m.args
-        has_name = m.name.endswith("AsUser") or m.name.endswith("ForUser")
-
-        if clazz.fullname.endswith("Manager") and has_arg:
-            warn(clazz, m, None, "When a method overload is needed to target a specific "
-                 "UserHandle, callers should be directed to use "
-                 "Context.createPackageContextAsUser() and re-obtain the relevant "
-                 "Manager, and no new API should be added")
-        elif has_arg and not has_name:
-            warn(clazz, m, None, "Method taking UserHandle should be named 'doFooAsUser' "
-                 "or 'queryFooForUser'")
-
-
-@verifier
-def verify_params(clazz):
-    """Parameter classes should be 'Params'."""
-    if clazz.name.endswith("Params"): return
-    if clazz.fullname == "android.app.ActivityOptions": return
-    if clazz.fullname == "android.app.BroadcastOptions": return
-    if clazz.fullname == "android.os.Bundle": return
-    if clazz.fullname == "android.os.BaseBundle": return
-    if clazz.fullname == "android.os.PersistableBundle": return
-
-    bad = ["Param","Parameter","Parameters","Args","Arg","Argument","Arguments","Options","Bundle"]
-    for b in bad:
-        if clazz.name.endswith(b):
-            error(clazz, None, None, "Classes holding a set of parameters should be called 'FooParams'")
-
-
-@verifier
-def verify_services(clazz):
-    """Service name should be FOO_BAR_SERVICE = 'foo_bar'."""
-    if clazz.fullname != "android.content.Context": return
-
-    for f in clazz.fields:
-        if f.typ != "java.lang.String": continue
-        found = re.match(r"([A-Z_]+)_SERVICE", f.name)
-        if found:
-            expected = found.group(1).lower()
-            if f.value != expected:
-                error(clazz, f, "C4", "Inconsistent service value; expected '%s'" % (expected))
-
-
-@verifier
-def verify_tense(clazz):
-    """Verify tenses of method names."""
-    if clazz.fullname.startswith("android.opengl"): return
-
-    for m in clazz.methods:
-        if m.name.endswith("Enable"):
-            warn(clazz, m, None, "Unexpected tense; probably meant 'enabled'")
-
-
-@verifier
-def verify_icu(clazz):
-    """Verifies that richer ICU replacements are used."""
-    better = {
-        "java.util.TimeZone": "android.icu.util.TimeZone",
-        "java.util.Calendar": "android.icu.util.Calendar",
-        "java.util.Locale": "android.icu.util.ULocale",
-        "java.util.ResourceBundle": "android.icu.util.UResourceBundle",
-        "java.util.SimpleTimeZone": "android.icu.util.SimpleTimeZone",
-        "java.util.StringTokenizer": "android.icu.util.StringTokenizer",
-        "java.util.GregorianCalendar": "android.icu.util.GregorianCalendar",
-        "java.lang.Character": "android.icu.lang.UCharacter",
-        "java.text.BreakIterator": "android.icu.text.BreakIterator",
-        "java.text.Collator": "android.icu.text.Collator",
-        "java.text.DecimalFormatSymbols": "android.icu.text.DecimalFormatSymbols",
-        "java.text.NumberFormat": "android.icu.text.NumberFormat",
-        "java.text.DateFormatSymbols": "android.icu.text.DateFormatSymbols",
-        "java.text.DateFormat": "android.icu.text.DateFormat",
-        "java.text.SimpleDateFormat": "android.icu.text.SimpleDateFormat",
-        "java.text.MessageFormat": "android.icu.text.MessageFormat",
-        "java.text.DecimalFormat": "android.icu.text.DecimalFormat",
-    }
-
-    for m in clazz.ctors + clazz.methods:
-        types = []
-        types.extend(m.typ)
-        types.extend(m.args)
-        for arg in types:
-            if arg in better:
-                warn(clazz, m, None, "Type %s should be replaced with richer ICU type %s" % (arg, better[arg]))
-
-
-@verifier
-def verify_clone(clazz):
-    """Verify that clone() isn't implemented; see EJ page 61."""
-    for m in clazz.methods:
-        if m.name == "clone":
-            error(clazz, m, None, "Provide an explicit copy constructor instead of implementing clone()")
-
-
-@verifier
-def verify_pfd(clazz):
-    """Verify that android APIs use PFD over FD."""
-    if clazz.fullname == "android.os.FileUtils" or clazz.fullname == "android.system.Os":
-        return
-
-    examine = clazz.ctors + clazz.methods
-    for m in examine:
-        if m.typ == "java.io.FileDescriptor":
-            error(clazz, m, "FW11", "Must use ParcelFileDescriptor")
-        if m.typ == "int":
-            if "Fd" in m.name or "FD" in m.name or "FileDescriptor" in m.name:
-                error(clazz, m, "FW11", "Must use ParcelFileDescriptor")
-        for arg in m.args:
-            if arg == "java.io.FileDescriptor":
-                error(clazz, m, "FW11", "Must use ParcelFileDescriptor")
-
-    for f in clazz.fields:
-        if f.typ == "java.io.FileDescriptor":
-            error(clazz, f, "FW11", "Must use ParcelFileDescriptor")
-
-
-@verifier
-def verify_numbers(clazz):
-    """Discourage small numbers types like short and byte."""
-
-    discouraged = ["short","byte"]
-
-    for c in clazz.ctors:
-        for arg in c.args:
-            if arg in discouraged:
-                warn(clazz, c, "FW12", "Should avoid odd sized primitives; use int instead")
-
-    for f in clazz.fields:
-        if f.typ in discouraged:
-            warn(clazz, f, "FW12", "Should avoid odd sized primitives; use int instead")
-
-    for m in clazz.methods:
-        if m.typ in discouraged:
-            warn(clazz, m, "FW12", "Should avoid odd sized primitives; use int instead")
-        for arg in m.args:
-            if arg in discouraged:
-                warn(clazz, m, "FW12", "Should avoid odd sized primitives; use int instead")
-
-
-PRIMITIVES = {"void", "int", "float", "boolean", "short", "char", "byte", "long", "double"}
-
-@verifier
-def verify_nullability(clazz):
-    """Catches missing nullability annotations"""
-
-    for f in clazz.fields:
-        if "enum_constant" in f.split:
-            continue  # Enum constants are never null
-        if f.value is not None and 'final' in f.split:
-            continue  # Nullability of constants can be inferred.
-        if f.typ not in PRIMITIVES and not has_nullability(f.annotations):
-            error(clazz, f, "M12", "Field must be marked either @NonNull or @Nullable")
-
-    for c in clazz.ctors:
-        verify_nullability_args(clazz, c)
-
-    for m in clazz.methods:
-        if m.name == "writeToParcel" or m.name == "onReceive" or m.name == "onBind":
-            continue  # Parcelable.writeToParcel(), BroadcastReceiver.onReceive(), and Service.onBind() are not yet annotated
-
-        if (m.name == "equals" and m.args == ["java.lang.Object"] or
-                m.name == "toString" and m.args == []):
-            continue  # Nullability of equals and toString is implicit.
-
-        if m.typ not in PRIMITIVES and not has_nullability(m.annotations):
-            error(clazz, m, "M12", "Return value must be marked either @NonNull or @Nullable")
-        verify_nullability_args(clazz, m)
-
-def verify_nullability_args(clazz, m):
-    for i, arg in enumerate(m.detailed_args):
-        if arg.type not in PRIMITIVES and not has_nullability(arg.annotations):
-            error(clazz, m, "M12", "Argument %d must be marked either @NonNull or @Nullable" % (i+1,))
-
-def has_nullability(annotations):
-    return "@NonNull" in annotations or "@Nullable" in annotations
-
-
-@verifier
-def verify_intdef(clazz):
-    """intdefs must be @hide, because the constant names cannot be stored in
-       the stubs (only the values are, which is not useful)"""
-    if "@interface" not in clazz.split:
-        return
-    if "@IntDef" in clazz.annotations or "@LongDef" in clazz.annotations:
-        error(clazz, None, None, "@IntDef and @LongDef annotations must be @hide")
-
-
-@verifier
-def verify_singleton(clazz):
-    """Catch singleton objects with constructors."""
-
-    singleton = False
-    for m in clazz.methods:
-        if m.name.startswith("get") and m.name.endswith("Instance") and " static " in m.raw:
-            singleton = True
-
-    if singleton:
-        for c in clazz.ctors:
-            error(clazz, c, None, "Singleton classes should use getInstance() methods")
-
-
-
-def is_interesting(clazz):
-    """Test if given class is interesting from an Android PoV."""
-
-    if clazz.pkg.name.startswith("java"): return False
-    if clazz.pkg.name.startswith("junit"): return False
-    if clazz.pkg.name.startswith("org.apache"): return False
-    if clazz.pkg.name.startswith("org.xml"): return False
-    if clazz.pkg.name.startswith("org.json"): return False
-    if clazz.pkg.name.startswith("org.w3c"): return False
-    if clazz.pkg.name.startswith("android.icu."): return False
-    return True
-
-
-def examine_clazz(clazz):
-    """Find all style issues in the given class."""
-
-    notice(clazz)
-
-    if not is_interesting(clazz): return
-
-    for v in verifiers.itervalues():
-        v(clazz)
-
-    if not ALLOW_GOOGLE: verify_google(clazz)
-
-
-def examine_stream(stream, base_stream=None, in_classes_with_base=[], out_classes_with_base=None):
-    """Find all style issues in the given API stream."""
-    global failures, noticed
-    failures = {}
-    noticed = {}
-    _parse_stream(stream, examine_clazz, base_f=base_stream,
-                  in_classes_with_base=in_classes_with_base,
-                  out_classes_with_base=out_classes_with_base)
-    return (failures, noticed)
-
-
-def examine_api(api):
-    """Find all style issues in the given parsed API."""
-    global failures
-    failures = {}
-    for key in sorted(api.keys()):
-        examine_clazz(api[key])
-    return failures
-
-
-def verify_compat(cur, prev):
-    """Find any incompatible API changes between two levels."""
-    global failures
-
-    def class_exists(api, test):
-        return test.fullname in api
-
-    def ctor_exists(api, clazz, test):
-        for m in clazz.ctors:
-            if m.ident == test.ident: return True
-        return False
-
-    def all_methods(api, clazz):
-        methods = list(clazz.methods)
-        if clazz.extends is not None:
-            methods.extend(all_methods(api, api[clazz.extends]))
-        return methods
-
-    def method_exists(api, clazz, test):
-        methods = all_methods(api, clazz)
-        for m in methods:
-            if m.ident == test.ident: return True
-        return False
-
-    def field_exists(api, clazz, test):
-        for f in clazz.fields:
-            if f.ident == test.ident: return True
-        return False
-
-    failures = {}
-    for key in sorted(prev.keys()):
-        prev_clazz = prev[key]
-
-        if not class_exists(cur, prev_clazz):
-            error(prev_clazz, None, None, "Class removed or incompatible change")
-            continue
-
-        cur_clazz = cur[key]
-
-        for test in prev_clazz.ctors:
-            if not ctor_exists(cur, cur_clazz, test):
-                error(prev_clazz, prev_ctor, None, "Constructor removed or incompatible change")
-
-        methods = all_methods(prev, prev_clazz)
-        for test in methods:
-            if not method_exists(cur, cur_clazz, test):
-                error(prev_clazz, test, None, "Method removed or incompatible change")
-
-        for test in prev_clazz.fields:
-            if not field_exists(cur, cur_clazz, test):
-                error(prev_clazz, test, None, "Field removed or incompatible change")
-
-    return failures
-
-
-def match_filter(filters, fullname):
-    for f in filters:
-        if fullname == f:
-            return True
-        if fullname.startswith(f + '.'):
-            return True
-    return False
-
-
-def show_deprecations_at_birth(cur, prev):
-    """Show API deprecations at birth."""
-    global failures
-
-    # Remove all existing things so we're left with new
-    for prev_clazz in prev.values():
-        if prev_clazz.fullname not in cur:
-            # The class was removed this release; we can safely ignore it.
-            continue
-
-        cur_clazz = cur[prev_clazz.fullname]
-        if not is_interesting(cur_clazz): continue
-
-        sigs = { i.ident: i for i in prev_clazz.ctors }
-        cur_clazz.ctors = [ i for i in cur_clazz.ctors if i.ident not in sigs ]
-        sigs = { i.ident: i for i in prev_clazz.methods }
-        cur_clazz.methods = [ i for i in cur_clazz.methods if i.ident not in sigs ]
-        sigs = { i.ident: i for i in prev_clazz.fields }
-        cur_clazz.fields = [ i for i in cur_clazz.fields if i.ident not in sigs ]
-
-        # Forget about class entirely when nothing new
-        if len(cur_clazz.ctors) == 0 and len(cur_clazz.methods) == 0 and len(cur_clazz.fields) == 0:
-            del cur[prev_clazz.fullname]
-
-    for clazz in cur.values():
-        if not is_interesting(clazz): continue
-
-        if "deprecated" in clazz.split and not clazz.fullname in prev:
-            error(clazz, None, None, "Found API deprecation at birth")
-
-        for i in clazz.ctors + clazz.methods + clazz.fields:
-            if "deprecated" in i.split:
-                error(clazz, i, None, "Found API deprecation at birth")
-
-    print "%s Deprecated at birth %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True),
-                                            format(reset=True)))
-    for f in sorted(failures):
-        print failures[f]
-        print
-
-
-def show_stats(cur, prev):
-    """Show API stats."""
-
-    stats = collections.defaultdict(int)
-    for cur_clazz in cur.values():
-        if not is_interesting(cur_clazz): continue
-
-        if cur_clazz.fullname not in prev:
-            stats['new_classes'] += 1
-            stats['new_ctors'] += len(cur_clazz.ctors)
-            stats['new_methods'] += len(cur_clazz.methods)
-            stats['new_fields'] += len(cur_clazz.fields)
-        else:
-            prev_clazz = prev[cur_clazz.fullname]
-
-            sigs = { i.ident: i for i in prev_clazz.ctors }
-            ctors = len([ i for i in cur_clazz.ctors if i.ident not in sigs ])
-            sigs = { i.ident: i for i in prev_clazz.methods }
-            methods = len([ i for i in cur_clazz.methods if i.ident not in sigs ])
-            sigs = { i.ident: i for i in prev_clazz.fields }
-            fields = len([ i for i in cur_clazz.fields if i.ident not in sigs ])
-
-            if ctors + methods + fields > 0:
-                stats['extend_classes'] += 1
-                stats['extend_ctors'] += ctors
-                stats['extend_methods'] += methods
-                stats['extend_fields'] += fields
-
-    print "#", "".join([ k.ljust(20) for k in sorted(stats.keys()) ])
-    print " ", "".join([ str(stats[k]).ljust(20) for k in sorted(stats.keys()) ])
-
-
-def main():
-    parser = argparse.ArgumentParser(description="Enforces common Android public API design \
-            patterns. It ignores lint messages from a previous API level, if provided.")
-    parser.add_argument("--base-current", nargs='?', type=argparse.FileType('r'), default=None,
-            help="The base current.txt to use when examining system-current.txt or"
-                 " test-current.txt")
-    parser.add_argument("--base-previous", nargs='?', type=argparse.FileType('r'), default=None,
-            help="The base previous.txt to use when examining system-previous.txt or"
-                 " test-previous.txt")
-    parser.add_argument("--no-color", action='store_const', const=True,
-            help="Disable terminal colors")
-    parser.add_argument("--color", action='store_const', const=True,
-            help="Use terminal colors")
-    parser.add_argument("--allow-google", action='store_const', const=True,
-            help="Allow references to Google")
-    parser.add_argument("--show-noticed", action='store_const', const=True,
-            help="Show API changes noticed")
-    parser.add_argument("--show-deprecations-at-birth", action='store_const', const=True,
-            help="Show API deprecations at birth")
-    parser.add_argument("--show-stats", action='store_const', const=True,
-            help="Show API stats")
-    parser.add_argument("--title", action='store', default=None,
-            help="Title to put in for display purposes")
-    parser.add_argument("--filter", action="append",
-            help="If provided, only show lint for the given packages or classes.")
-    parser.add_argument("current.txt", type=argparse.FileType('r'), help="current.txt")
-    parser.add_argument("previous.txt", nargs='?', type=argparse.FileType('r'), default=None,
-            help="previous.txt")
-    args = vars(parser.parse_args())
-
-    if args['no_color']:
-        USE_COLOR = False
-    elif args['color']:
-        USE_COLOR = True
-    else:
-        USE_COLOR = sys.stdout.isatty()
-
-    if args['allow_google']:
-        ALLOW_GOOGLE = True
-
-    current_file = args['current.txt']
-    base_current_file = args['base_current']
-    previous_file = args['previous.txt']
-    base_previous_file = args['base_previous']
-    filters = args['filter']
-    if not filters:
-        filters = []
-    title = args['title']
-    if not title:
-        title = current_file.name
-
-    if args['show_deprecations_at_birth']:
-        with current_file as f:
-            cur = _parse_stream(f)
-        with previous_file as f:
-            prev = _parse_stream(f)
-        show_deprecations_at_birth(cur, prev)
-        sys.exit()
-
-    if args['show_stats']:
-        with current_file as f:
-            cur = _parse_stream(f)
-        with previous_file as f:
-            prev = _parse_stream(f)
-        show_stats(cur, prev)
-        sys.exit()
-
-    classes_with_base = []
-
-    with current_file as f:
-        if base_current_file:
-            with base_current_file as base_f:
-                cur_fail, cur_noticed = examine_stream(f, base_f,
-                                                       out_classes_with_base=classes_with_base)
-        else:
-            cur_fail, cur_noticed = examine_stream(f, out_classes_with_base=classes_with_base)
-
-    if not previous_file is None:
-        with previous_file as f:
-            if base_previous_file:
-                with base_previous_file as base_f:
-                    prev_fail, prev_noticed = examine_stream(f, base_f,
-                                                             in_classes_with_base=classes_with_base)
-            else:
-                prev_fail, prev_noticed = examine_stream(f, in_classes_with_base=classes_with_base)
-
-        # ignore errors from previous API level
-        for p in prev_fail:
-            if p in cur_fail:
-                del cur_fail[p]
-
-        # ignore classes unchanged from previous API level
-        for k, v in prev_noticed.iteritems():
-            if k in cur_noticed and v == cur_noticed[k]:
-                del cur_noticed[k]
-
-        """
-        # NOTE: disabled because of memory pressure
-        # look for compatibility issues
-        compat_fail = verify_compat(cur, prev)
-
-        print "%s API compatibility issues %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True), format(reset=True)))
-        for f in sorted(compat_fail):
-            print compat_fail[f]
-            print
-        """
-
-    # ignore everything but the given filters, if provided
-    if filters:
-        cur_fail = dict([(key, failure) for key, failure in cur_fail.iteritems()
-                if match_filter(filters, failure.clazz.fullname)])
-
-    if args['show_noticed'] and len(cur_noticed) != 0:
-        print "%s API changes noticed %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True), format(reset=True)))
-        for f in sorted(cur_noticed.keys()):
-            print f
-        print
-
-    if len(cur_fail) != 0:
-        print "%s API style issues: %s %s" % ((format(fg=WHITE, bg=BLUE, bold=True),
-                    title, format(reset=True)))
-        for f in filters:
-            print "%s   filter: %s %s" % ((format(fg=WHITE, bg=BLUE, bold=True),
-                        f, format(reset=True)))
-        print
-        for f in sorted(cur_fail):
-            print cur_fail[f]
-            print
-        print "%d errors" % len(cur_fail)
-        sys.exit(77)
-
-if __name__ == "__main__":
-    try:
-        main()
-    except KeyboardInterrupt:
-        sys.exit(1)
diff --git a/tools/apilint/apilint_sha.sh b/tools/apilint/apilint_sha.sh
deleted file mode 100755
index 2a45b10..0000000
--- a/tools/apilint/apilint_sha.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-if git show --name-only --pretty=format: $1 | grep api/ > /dev/null; then
-    python tools/apilint/apilint.py <(git show $1:api/current.txt) <(git show $1^:api/current.txt)
-fi
diff --git a/tools/apilint/apilint_sha_system.sh b/tools/apilint/apilint_sha_system.sh
deleted file mode 100755
index 8538a3d..0000000
--- a/tools/apilint/apilint_sha_system.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-if git show --name-only --pretty=format: $1 | grep api/ > /dev/null; then
-  python tools/apilint/apilint.py \
-    --base-current <(git show $1:api/current.txt) \
-    --base-previous <(git show $1^:api/current.txt) \
-    <(git show $1:api/system-current.txt) \
-    <(git show $1^:api/system-current.txt)
-fi
diff --git a/tools/apilint/apilint_stats.sh b/tools/apilint/apilint_stats.sh
deleted file mode 100755
index 052d9a5..0000000
--- a/tools/apilint/apilint_stats.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-API=28
-while [ $API -gt 14 ]; do
-    echo "# Changes in API $((API))"
-    python tools/apilint/apilint.py --show-stats ../../prebuilts/sdk/$((API))/public/api/android.txt ../../prebuilts/sdk/$((API-1))/public/api/android.txt
-    let API=API-1
-done
diff --git a/tools/apilint/apilint_test.py b/tools/apilint/apilint_test.py
deleted file mode 100644
index 811cb9a..0000000
--- a/tools/apilint/apilint_test.py
+++ /dev/null
@@ -1,414 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-import unittest
-
-import apilint
-
-def cls(pkg, name):
-    return apilint.Class(apilint.Package(999, "package %s {" % pkg, None), 999,
-                  "public final class %s {" % name, None)
-
-_ri = apilint._retry_iterator
-
-c1 = cls("android.app", "ActivityManager")
-c2 = cls("android.app", "Notification")
-c3 = cls("android.app", "Notification.Action")
-c4 = cls("android.graphics", "Bitmap")
-
-class UtilTests(unittest.TestCase):
-    def test_retry_iterator(self):
-        it = apilint._retry_iterator([1, 2, 3, 4])
-        self.assertEqual(it.next(), 1)
-        self.assertEqual(it.next(), 2)
-        self.assertEqual(it.next(), 3)
-        it.send("retry")
-        self.assertEqual(it.next(), 3)
-        self.assertEqual(it.next(), 4)
-        with self.assertRaises(StopIteration):
-            it.next()
-
-    def test_retry_iterator_one(self):
-        it = apilint._retry_iterator([1])
-        self.assertEqual(it.next(), 1)
-        it.send("retry")
-        self.assertEqual(it.next(), 1)
-        with self.assertRaises(StopIteration):
-            it.next()
-
-    def test_retry_iterator_one(self):
-        it = apilint._retry_iterator([1])
-        self.assertEqual(it.next(), 1)
-        it.send("retry")
-        self.assertEqual(it.next(), 1)
-        with self.assertRaises(StopIteration):
-            it.next()
-
-    def test_skip_to_matching_class_found(self):
-        it = _ri([c1, c2, c3, c4])
-        self.assertEquals(apilint._skip_to_matching_class(it, c3),
-                          c3)
-        self.assertEqual(it.next(), c4)
-
-    def test_skip_to_matching_class_not_found(self):
-        it = _ri([c1, c2, c3, c4])
-        self.assertEquals(apilint._skip_to_matching_class(it, cls("android.content", "ContentProvider")),
-                          None)
-        self.assertEqual(it.next(), c4)
-
-    def test_yield_until_matching_class_found(self):
-        it = _ri([c1, c2, c3, c4])
-        self.assertEquals(list(apilint._yield_until_matching_class(it, c3)),
-                          [c1, c2])
-        self.assertEqual(it.next(), c4)
-
-    def test_yield_until_matching_class_not_found(self):
-        it = _ri([c1, c2, c3, c4])
-        self.assertEquals(list(apilint._yield_until_matching_class(it, cls("android.content", "ContentProvider"))),
-                          [c1, c2, c3])
-        self.assertEqual(it.next(), c4)
-
-    def test_yield_until_matching_class_None(self):
-        it = _ri([c1, c2, c3, c4])
-        self.assertEquals(list(apilint._yield_until_matching_class(it, None)),
-                          [c1, c2, c3, c4])
-
-
-faulty_current_txt = """
-// Signature format: 2.0
-package android.app {
-  public final class Activity {
-  }
-
-  public final class WallpaperColors implements android.os.Parcelable {
-    ctor public WallpaperColors(@NonNull android.os.Parcel);
-    method public int describeContents();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR;
-  }
-}
-""".strip().split('\n')
-
-ok_current_txt = """
-// Signature format: 2.0
-package android.app {
-  public final class Activity {
-  }
-
-  public final class WallpaperColors implements android.os.Parcelable {
-    ctor public WallpaperColors();
-    method public int describeContents();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR;
-  }
-}
-""".strip().split('\n')
-
-system_current_txt = """
-// Signature format: 2.0
-package android.app {
-  public final class WallpaperColors implements android.os.Parcelable {
-    method public int getSomething();
-  }
-}
-""".strip().split('\n')
-
-
-
-class BaseFileTests(unittest.TestCase):
-    def test_base_file_avoids_errors(self):
-        failures, _ = apilint.examine_stream(system_current_txt, ok_current_txt)
-        self.assertEquals(failures, {})
-
-    def test_class_with_base_finds_same_errors(self):
-        failures_with_classes_with_base, _ = apilint.examine_stream("", faulty_current_txt,
-                                                                    in_classes_with_base=[cls("android.app", "WallpaperColors")])
-        failures_with_system_txt, _ = apilint.examine_stream(system_current_txt, faulty_current_txt)
-
-        self.assertEquals(failures_with_classes_with_base.keys(), failures_with_system_txt.keys())
-
-    def test_classes_with_base_is_emited(self):
-        classes_with_base = []
-        _, _ = apilint.examine_stream(system_current_txt, faulty_current_txt,
-                                      out_classes_with_base=classes_with_base)
-        self.assertEquals(map(lambda x: x.fullname, classes_with_base), ["android.app.WallpaperColors"])
-
-class ParseV2Stream(unittest.TestCase):
-    def test_field_kinds(self):
-        api = apilint._parse_stream("""
-// Signature format: 2.0
-package android {
-  public enum SomeEnum {
-    enum_constant public static final android.SomeEnum ENUM_CONST;
-    field public static final int FIELD_CONST;
-    property public final int someProperty;
-    ctor public SomeEnum();
-    method public Object? getObject();
-  }
-}
-        """.strip().split('\n'))
-
-        self.assertEquals(api['android.SomeEnum'].fields[0].split[0], 'enum_constant')
-        self.assertEquals(api['android.SomeEnum'].fields[1].split[0], 'field')
-        self.assertEquals(api['android.SomeEnum'].fields[2].split[0], 'property')
-        self.assertEquals(api['android.SomeEnum'].ctors[0].split[0], 'ctor')
-        self.assertEquals(api['android.SomeEnum'].methods[0].split[0], 'method')
-
-class ParseV3Stream(unittest.TestCase):
-    def test_field_kinds(self):
-        api = apilint._parse_stream("""
-// Signature format: 3.0
-package a {
-
-  public final class ContextKt {
-    method public static inline <reified T> T! getSystemService(android.content.Context);
-    method public static inline void withStyledAttributes(android.content.Context, android.util.AttributeSet? set = null, int[] attrs, @AttrRes int defStyleAttr = 0, @StyleRes int defStyleRes = 0, kotlin.jvm.functions.Function1<? super android.content.res.TypedArray,kotlin.Unit> block);
-  }
-}
-        """.strip().split('\n'))
-        self.assertEquals(api['a.ContextKt'].methods[0].name, 'getSystemService')
-        self.assertEquals(api['a.ContextKt'].methods[0].split[:4], ['method', 'public', 'static', 'inline'])
-        self.assertEquals(api['a.ContextKt'].methods[1].name, 'withStyledAttributes')
-        self.assertEquals(api['a.ContextKt'].methods[1].split[:4], ['method', 'public', 'static', 'inline'])
-
-class V2TokenizerTests(unittest.TestCase):
-    def _test(self, raw, expected):
-        self.assertEquals(apilint.V2Tokenizer(raw).tokenize(), expected)
-
-    def test_simple(self):
-        self._test("  method public some.Type someName(some.Argument arg, int arg);",
-                   ['method', 'public', 'some.Type', 'someName', '(', 'some.Argument',
-                    'arg', ',', 'int', 'arg', ')', ';'])
-        self._test("class Some.Class extends SomeOther {",
-                   ['class', 'Some.Class', 'extends', 'SomeOther', '{'])
-
-    def test_varargs(self):
-        self._test("name(String...)",
-                   ['name', '(', 'String', '...', ')'])
-
-    def test_kotlin(self):
-        self._test("String? name(String!...)",
-                   ['String', '?', 'name', '(', 'String', '!',  '...', ')'])
-
-    def test_annotation(self):
-        self._test("method @Nullable public void name();",
-                   ['method', '@', 'Nullable', 'public', 'void', 'name', '(', ')', ';'])
-
-    def test_annotation_args(self):
-        self._test("@Some(val=1, other=2) class Class {",
-                   ['@', 'Some', '(', 'val', '=', '1', ',', 'other', '=', '2', ')',
-                    'class', 'Class', '{'])
-    def test_comment(self):
-        self._test("some //comment", ['some'])
-
-    def test_strings(self):
-        self._test(r'"" "foo" "\"" "\\"', ['""', '"foo"', r'"\""', r'"\\"'])
-
-    def test_at_interface(self):
-        self._test("public @interface Annotation {",
-                   ['public', '@interface', 'Annotation', '{'])
-
-    def test_array_type(self):
-        self._test("int[][]", ['int', '[]', '[]'])
-
-    def test_generics(self):
-        self._test("<>foobar<A extends Object>",
-                   ['<', '>', 'foobar', '<', 'A', 'extends', 'Object', '>'])
-
-class V2ParserTests(unittest.TestCase):
-    def _cls(self, raw):
-        pkg = apilint.Package(999, "package pkg {", None)
-        return apilint.Class(pkg, 1, raw, '', sig_format=2)
-
-    def _method(self, raw, cls=None):
-        if not cls:
-            cls = self._cls("class Class {")
-        return apilint.Method(cls, 1, raw, '', sig_format=2)
-
-    def _field(self, raw):
-        cls = self._cls("class Class {")
-        return apilint.Field(cls, 1, raw, '', sig_format=2)
-
-    def test_parse_package(self):
-        pkg = apilint.Package(999, "package wifi.p2p {", None)
-        self.assertEquals("wifi.p2p", pkg.name)
-
-    def test_class(self):
-        cls = self._cls("@Deprecated @IntRange(from=1, to=2) public static abstract class Some.Name extends Super<Class> implements Interface<Class> {")
-        self.assertTrue('deprecated' in cls.split)
-        self.assertTrue('static' in cls.split)
-        self.assertTrue('abstract' in cls.split)
-        self.assertTrue('class' in cls.split)
-        self.assertEquals('Super', cls.extends)
-        self.assertEquals('Interface', cls.implements)
-        self.assertEquals('pkg.Some.Name', cls.fullname)
-
-    def test_enum(self):
-        cls = self._cls("public enum Some.Name {")
-        self._field("enum_constant public static final android.ValueType COLOR;")
-
-    def test_interface(self):
-        cls = self._cls("@Deprecated @IntRange(from=1, to=2) public interface Some.Name extends Interface<Class> {")
-        self.assertTrue('deprecated' in cls.split)
-        self.assertTrue('interface' in cls.split)
-        self.assertEquals('Interface', cls.extends)
-        self.assertEquals('Interface', cls.implements)
-        self.assertEquals('pkg.Some.Name', cls.fullname)
-
-    def test_at_interface(self):
-        cls = self._cls("@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.LOCAL_VARIABLE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface SuppressLint {")
-        self.assertTrue('@interface' in cls.split)
-        self.assertEquals('pkg.SuppressLint', cls.fullname)
-
-    def test_parse_method(self):
-        m = self._method("method @Deprecated public static native <T> Class<T>[][] name("
-                         + "Class<T[]>[][], Class<T[][][]>[][]...) throws Exception, T;")
-        self.assertTrue('static' in m.split)
-        self.assertTrue('public' in m.split)
-        self.assertTrue('method' in m.split)
-        self.assertTrue('native' in m.split)
-        self.assertTrue('deprecated' in m.split)
-        self.assertEquals('java.lang.Class[][]', m.typ)
-        self.assertEquals('name', m.name)
-        self.assertEquals(['java.lang.Class[][]', 'java.lang.Class[][]...'], m.args)
-        self.assertEquals(['java.lang.Exception', 'T'], m.throws)
-
-    def test_ctor(self):
-        m = self._method("ctor @Deprecated <T> ClassName();")
-        self.assertTrue('ctor' in m.split)
-        self.assertTrue('deprecated' in m.split)
-        self.assertEquals('ctor', m.typ)
-        self.assertEquals('ClassName', m.name)
-
-    def test_parse_annotation_method(self):
-        cls = self._cls("@interface Annotation {")
-        self._method('method abstract String category() default "";', cls=cls)
-        self._method('method abstract boolean deepExport() default false;', cls=cls)
-        self._method('method abstract ViewDebug.FlagToString[] flagMapping() default {};', cls=cls)
-        self._method('method abstract ViewDebug.FlagToString[] flagMapping() default (double)java.lang.Float.NEGATIVE_INFINITY;', cls=cls)
-
-    def test_parse_string_field(self):
-        f = self._field('field @Deprecated public final String SOME_NAME = "value";')
-        self.assertTrue('field' in f.split)
-        self.assertTrue('deprecated' in f.split)
-        self.assertTrue('final' in f.split)
-        self.assertEquals('java.lang.String', f.typ)
-        self.assertEquals('SOME_NAME', f.name)
-        self.assertEquals('value', f.value)
-
-    def test_parse_field(self):
-        f = self._field('field public Object SOME_NAME;')
-        self.assertTrue('field' in f.split)
-        self.assertEquals('java.lang.Object', f.typ)
-        self.assertEquals('SOME_NAME', f.name)
-        self.assertEquals(None, f.value)
-
-    def test_parse_int_field(self):
-        f = self._field('field public int NAME = 123;')
-        self.assertTrue('field' in f.split)
-        self.assertEquals('int', f.typ)
-        self.assertEquals('NAME', f.name)
-        self.assertEquals('123', f.value)
-
-    def test_parse_quotient_field(self):
-        f = self._field('field public int NAME = (0.0/0.0);')
-        self.assertTrue('field' in f.split)
-        self.assertEquals('int', f.typ)
-        self.assertEquals('NAME', f.name)
-        self.assertEquals('( 0.0 / 0.0 )', f.value)
-
-    def test_kotlin_types(self):
-        self._field('field public List<Integer[]?[]!>?[]![]? NAME;')
-        self._method("method <T?> Class<T!>?[]![][]? name(Type!, Type argname,"
-                         + "Class<T?>[][]?[]!...!) throws Exception, T;")
-        self._method("method <T> T name(T a = 1, T b = A(1), Lambda f = { false }, N? n = null, "
-                         + """double c = (1/0), float d = 1.0f, String s = "heyo", char c = 'a');""")
-
-    def test_kotlin_operator(self):
-        self._method('method public operator void unaryPlus(androidx.navigation.NavDestination);')
-        self._method('method public static operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, @IdRes int id);')
-        self._method('method public static operator <T> T get(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<T> clazz);')
-
-    def test_kotlin_property(self):
-        self._field('property public VM value;')
-        self._field('property public final String? action;')
-
-    def test_kotlin_varargs(self):
-        self._method('method public void error(int p = "42", Integer int2 = "null", int p1 = "42", vararg String args);')
-
-    def test_kotlin_default_values(self):
-        self._method('method public void foo(String! = null, String! = "Hello World", int = 42);')
-        self._method('method void method(String, String firstArg = "hello", int secondArg = "42", String thirdArg = "world");')
-        self._method('method void method(String, String firstArg = "hello", int secondArg = "42");')
-        self._method('method void method(String, String firstArg = "hello");')
-        self._method('method void edit(android.Type, boolean commit = false, Function1<? super Editor,kotlin.Unit> action);')
-        self._method('method <K, V> LruCache<K,V> lruCache(int maxSize, Function2<? super K,? super V,java.lang.Integer> sizeOf = { _, _ -> 1 }, Function1<? extends V> create = { (V)null }, Function4<kotlin.Unit> onEntryRemoved = { _, _, _, _ ->  });')
-        self._method('method android.Bitmap? drawToBitmap(android.View, android.Config config = android.graphics.Bitmap.Config.ARGB_8888);')
-        self._method('method void emptyLambda(Function0<kotlin.Unit> sizeOf = {});')
-        self._method('method void method1(int p = 42, Integer? int2 = null, int p1 = 42, String str = "hello world", java.lang.String... args);')
-        self._method('method void method2(int p, int int2 = (2 * int) * some.other.pkg.Constants.Misc.SIZE);')
-        self._method('method void method3(String str, int p, int int2 = double(int) + str.length);')
-        self._method('method void print(test.pkg.Foo foo = test.pkg.Foo());')
-
-    def test_type_use_annotation(self):
-        self._method('method public static int codePointAt(char @NonNull [], int);')
-        self._method('method @NonNull public java.util.Set<java.util.Map.@NonNull Entry<K,V>> entrySet();')
-
-        m = self._method('method @NonNull public java.lang.annotation.@NonNull Annotation @NonNull [] getAnnotations();')
-        self.assertEquals('java.lang.annotation.Annotation[]', m.typ)
-
-        m = self._method('method @NonNull public abstract java.lang.annotation.@NonNull Annotation @NonNull [] @NonNull [] getParameterAnnotations();')
-        self.assertEquals('java.lang.annotation.Annotation[][]', m.typ)
-
-        m = self._method('method @NonNull public @NonNull String @NonNull [] split(@NonNull String, int);')
-        self.assertEquals('java.lang.String[]', m.typ)
-
-class PackageTests(unittest.TestCase):
-    def _package(self, raw):
-        return apilint.Package(123, raw, "blame")
-
-    def test_regular_package(self):
-        p = self._package("package an.pref.int {")
-        self.assertEquals('an.pref.int', p.name)
-
-    def test_annotation_package(self):
-        p = self._package("package @RestrictTo(a.b.C) an.pref.int {")
-        self.assertEquals('an.pref.int', p.name)
-
-    def test_multi_annotation_package(self):
-        p = self._package("package @Rt(a.b.L_G_P) @RestrictTo(a.b.C) an.pref.int {")
-        self.assertEquals('an.pref.int', p.name)
-
-class FilterTests(unittest.TestCase):
-    def test_filter_match_prefix(self):
-        self.assertTrue(apilint.match_filter(["a"], "a.B"))
-        self.assertTrue(apilint.match_filter(["a.B"], "a.B.C"))
-
-    def test_filter_dont_match_prefix(self):
-        self.assertFalse(apilint.match_filter(["c"], "a.B"))
-        self.assertFalse(apilint.match_filter(["a."], "a.B"))
-        self.assertFalse(apilint.match_filter(["a.B."], "a.B.C"))
-
-    def test_filter_match_exact(self):
-        self.assertTrue(apilint.match_filter(["a.B"], "a.B"))
-
-    def test_filter_dont_match_exact(self):
-        self.assertFalse(apilint.match_filter([""], "a.B"))
-        self.assertFalse(apilint.match_filter(["a.C"], "a.B"))
-        self.assertFalse(apilint.match_filter(["a.C"], "a.B"))
-        
-if __name__ == "__main__":
-    unittest.main()
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index aa895a6..ed1a2f9 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -549,6 +549,7 @@
         /**
          * Extension IDs
          */
+        public static final int EID_EXT_HE_CAPABILITIES = 35;
         public static final int EID_EXT_HE_OPERATION = 36;
 
         @UnsupportedAppUsage
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 8108fef..b5c3d6f5 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -2220,6 +2220,10 @@
     public static final long WIFI_FEATURE_DPP              = 0x80000000L; // DPP (Easy-Connect)
     /** @hide */
     public static final long WIFI_FEATURE_P2P_RAND_MAC    = 0x100000000L; // Random P2P MAC
+    /** @hide */
+    public static final long WIFI_FEATURE_CONNECTED_RAND_MAC    = 0x200000000L; // Random STA MAC
+    /** @hide */
+    public static final long WIFI_FEATURE_AP_RAND_MAC    = 0x400000000L; // Random AP MAC
 
     private long getSupportedFeatures() {
         try {
@@ -2345,6 +2349,24 @@
     }
 
     /**
+     * @return true if this device supports connected MAC randomization.
+     * @hide
+     */
+    @SystemApi
+    public boolean isConnectedMacRandomizationSupported() {
+        return isFeatureSupported(WIFI_FEATURE_CONNECTED_RAND_MAC);
+    }
+
+    /**
+     * @return true if this device supports connected MAC randomization.
+     * @hide
+     */
+    @SystemApi
+    public boolean isApMacRandomizationSupported() {
+        return isFeatureSupported(WIFI_FEATURE_AP_RAND_MAC);
+    }
+
+    /**
      * Return the record of {@link WifiActivityEnergyInfo} object that
      * has the activity and energy info. This can be used to ascertain what
      * the controller has been up to, since the last sample.
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 67993e1..0a99326 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -138,7 +138,8 @@
     public List<Integer> getAvailableChannels(@WifiBand int band) {
         try {
             Bundle bundle = mService.getAvailableChannels(band, mContext.getOpPackageName());
-            return bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA);
+            List<Integer> channels = bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA);
+            return channels == null ? new ArrayList<>() : channels;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/wifi/java/android/net/wifi/rtt/ResponderConfig.java b/wifi/java/android/net/wifi/rtt/ResponderConfig.java
index 64dfc34..be4eecc 100644
--- a/wifi/java/android/net/wifi/rtt/ResponderConfig.java
+++ b/wifi/java/android/net/wifi/rtt/ResponderConfig.java
@@ -16,6 +16,8 @@
 
 package android.net.wifi.rtt;
 
+import static android.net.wifi.ScanResult.InformationElement.EID_EXTENSION_PRESENT;
+import static android.net.wifi.ScanResult.InformationElement.EID_EXT_HE_CAPABILITIES;
 import static android.net.wifi.ScanResult.InformationElement.EID_HT_CAPABILITIES;
 import static android.net.wifi.ScanResult.InformationElement.EID_VHT_CAPABILITIES;
 
@@ -106,7 +108,7 @@
     public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4;
 
     /** @hide */
-    @IntDef({PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT})
+    @IntDef({PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT, PREAMBLE_HE})
     @Retention(RetentionPolicy.SOURCE)
     public @interface PreambleType {
     }
@@ -126,6 +128,10 @@
      */
     public static final int PREAMBLE_VHT = 2;
 
+    /**
+     * Preamble type: HE.
+     */
+    public static final int PREAMBLE_HE = 3;
 
     /**
      * The MAC address of the Responder. Will be null if a Wi-Fi Aware peer identifier (the
@@ -307,14 +313,21 @@
         if (scanResult.informationElements != null && scanResult.informationElements.length != 0) {
             boolean htCapabilitiesPresent = false;
             boolean vhtCapabilitiesPresent = false;
+            boolean heCapabilitiesPresent = false;
+
             for (ScanResult.InformationElement ie : scanResult.informationElements) {
                 if (ie.id == EID_HT_CAPABILITIES) {
                     htCapabilitiesPresent = true;
                 } else if (ie.id == EID_VHT_CAPABILITIES) {
                     vhtCapabilitiesPresent = true;
+                } else if (ie.id == EID_EXTENSION_PRESENT && ie.idExt == EID_EXT_HE_CAPABILITIES) {
+                    heCapabilitiesPresent = true;
                 }
             }
-            if (vhtCapabilitiesPresent) {
+
+            if (heCapabilitiesPresent) {
+                preamble = PREAMBLE_HE;
+            } else if (vhtCapabilitiesPresent) {
                 preamble = PREAMBLE_VHT;
             } else if (htCapabilitiesPresent) {
                 preamble = PREAMBLE_HT;