Merge "Remove stopship for IdmapManager vendor sdk" into qt-dev
diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java
index 7a85dcb..0b1a845 100644
--- a/core/java/android/net/DnsResolver.java
+++ b/core/java/android/net/DnsResolver.java
@@ -34,6 +34,7 @@
 import android.annotation.Nullable;
 import android.os.CancellationSignal;
 import android.os.Looper;
+import android.os.MessageQueue;
 import android.system.ErrnoException;
 import android.util.Log;
 
@@ -466,10 +467,20 @@
     private void registerFDListener(@NonNull Executor executor,
             @NonNull FileDescriptor queryfd, @NonNull Callback<? super byte[]> answerCallback,
             @Nullable CancellationSignal cancellationSignal, @NonNull Object lock) {
-        Looper.getMainLooper().getQueue().addOnFileDescriptorEventListener(
+        final MessageQueue mainThreadMessageQueue = Looper.getMainLooper().getQueue();
+        mainThreadMessageQueue.addOnFileDescriptorEventListener(
                 queryfd,
                 FD_EVENTS,
                 (fd, events) -> {
+                    // b/134310704
+                    // Unregister fd event listener before resNetworkResult is called to prevent
+                    // race condition caused by fd reused.
+                    // For example when querying v4 and v6, it's possible that the first query ends
+                    // and the fd is closed before the second request starts, which might return
+                    // the same fd for the second request. By that time, the looper must have
+                    // unregistered the fd, otherwise another event listener can't be registered.
+                    mainThreadMessageQueue.removeOnFileDescriptorEventListener(fd);
+
                     executor.execute(() -> {
                         DnsResponse resp = null;
                         ErrnoException exception = null;
@@ -490,7 +501,11 @@
                         }
                         answerCallback.onAnswer(resp.answerbuf, resp.rcode);
                     });
-                    // Unregister this fd listener
+
+                    // The file descriptor has already been unregistered, so it does not really
+                    // matter what is returned here. In spirit 0 (meaning "unregister this FD")
+                    // is still the closest to what the looper needs to do. When returning 0,
+                    // Looper knows to ignore the fd if it has already been unregistered.
                     return 0;
                 });
     }
diff --git a/core/java/android/os/ExternalVibration.java b/core/java/android/os/ExternalVibration.java
index b93bef8..37ca868 100644
--- a/core/java/android/os/ExternalVibration.java
+++ b/core/java/android/os/ExternalVibration.java
@@ -114,6 +114,24 @@
         return true;
     }
 
+    /**
+     * Links a recipient to death against this external vibration token
+     */
+    public void linkToDeath(IBinder.DeathRecipient recipient) {
+        try {
+            mToken.linkToDeath(recipient, 0);
+        } catch (RemoteException e) {
+            return;
+        }
+    }
+
+    /**
+     * Unlinks a recipient to death against this external vibration token
+     */
+    public void unlinkToDeath(IBinder.DeathRecipient recipient) {
+        mToken.unlinkToDeath(recipient, 0);
+    }
+
     @Override
     public boolean equals(Object o) {
         if (o == null || !(o instanceof ExternalVibration)) {
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index e50ab6c..74c89d6 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -511,7 +511,6 @@
      * @param appDataDir null-ok the data directory of the app.
      * @param invokeWith null-ok the command to invoke with.
      * @param packageName null-ok the name of the package this process belongs to.
-     * @param useSystemGraphicsDriver whether the process uses system graphics driver.
      *
      * @param zygoteArgs Additional arguments to supply to the zygote process.
      * @return An object that describes the result of the attempt to start the process.
@@ -531,13 +530,11 @@
                                            @Nullable String appDataDir,
                                            @Nullable String invokeWith,
                                            @Nullable String packageName,
-                                           boolean useSystemGraphicsDriver,
                                            @Nullable String[] zygoteArgs) {
         return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, packageName,
-                    /*useUsapPool=*/ true,
-                    useSystemGraphicsDriver, zygoteArgs);
+                    /*useUsapPool=*/ true, zygoteArgs);
     }
 
     /** @hide */
@@ -553,13 +550,11 @@
                                                   @Nullable String appDataDir,
                                                   @Nullable String invokeWith,
                                                   @Nullable String packageName,
-                                                  boolean useSystemGraphicsDriver,
                                                   @Nullable String[] zygoteArgs) {
         return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, packageName,
-                    /*useUsapPool=*/ false,
-                    useSystemGraphicsDriver, zygoteArgs);
+                    /*useUsapPool=*/ false, zygoteArgs);
     }
 
     /**
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index d42478e5..9bcdcee 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -307,7 +307,6 @@
      * @param invokeWith null-ok the command to invoke with.
      * @param packageName null-ok the name of the package this process belongs to.
      * @param zygoteArgs Additional arguments to supply to the zygote process.
-     * @param useSystemGraphicsDriver whether the process uses system graphics driver.
      *
      * @return An object that describes the result of the attempt to start the process.
      * @throws RuntimeException on fatal start failure
@@ -324,7 +323,6 @@
                                                   @Nullable String invokeWith,
                                                   @Nullable String packageName,
                                                   boolean useUsapPool,
-                                                  boolean useSystemGraphicsDriver,
                                                   @Nullable String[] zygoteArgs) {
         // TODO (chriswailes): Is there a better place to check this value?
         if (fetchUsapPoolEnabledPropWithMinInterval()) {
@@ -335,7 +333,7 @@
             return startViaZygote(processClass, niceName, uid, gid, gids,
                     runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                     abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
-                    packageName, useUsapPool, useSystemGraphicsDriver, zygoteArgs);
+                    packageName, useUsapPool, zygoteArgs);
         } catch (ZygoteStartFailedEx ex) {
             Log.e(LOG_TAG,
                     "Starting VM process through Zygote failed");
@@ -554,7 +552,6 @@
                                                       boolean startChildZygote,
                                                       @Nullable String packageName,
                                                       boolean useUsapPool,
-                                                      boolean useSystemGraphicsDriver,
                                                       @Nullable String[] extraArgs)
                                                       throws ZygoteStartFailedEx {
         ArrayList<String> argsForZygote = new ArrayList<>();
@@ -636,7 +633,7 @@
             // The USAP pool can not be used if the application will not use the systems graphics
             // driver.  If that driver is requested use the Zygote application start path.
             return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
-                                              useUsapPool && useSystemGraphicsDriver,
+                                              useUsapPool,
                                               argsForZygote);
         }
     }
@@ -1147,8 +1144,7 @@
                     gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo,
                     abi, instructionSet, null /* appDataDir */, null /* invokeWith */,
                     true /* startChildZygote */, null /* packageName */,
-                    false /* useUsapPool */, false /*useSystemGraphicsDriver*/,
-                    extraArgs);
+                    false /* useUsapPool */, extraArgs);
         } catch (ZygoteStartFailedEx ex) {
             throw new RuntimeException("Starting child-zygote through Zygote failed", ex);
         }
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 9a11104..19dbc6a 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -48,6 +48,8 @@
 
 /**
  * Device level configuration parameters which can be tuned by a separate configuration service.
+ * Namespaces that end in "_native" such as {@link #NAMESPACE_NETD_NATIVE} are intended to be used
+ * by native code and should be pushed to system properties to make them accessible.
  *
  * @hide
  */
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index e02fd9f..b44c9d5 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -1199,20 +1199,25 @@
         }
     }
 
-    /** Convert new-style Icons to legacy representations for pre-M clients. */
-    private void createLegacyIconExtras(Notification n) {
-        Icon smallIcon = n.getSmallIcon();
-        Icon largeIcon = n.getLargeIcon();
-        if (smallIcon != null && smallIcon.getType() == Icon.TYPE_RESOURCE) {
-            n.extras.putInt(Notification.EXTRA_SMALL_ICON, smallIcon.getResId());
-            n.icon = smallIcon.getResId();
-        }
-        if (largeIcon != null) {
-            Drawable d = largeIcon.loadDrawable(getContext());
-            if (d != null && d instanceof BitmapDrawable) {
-                final Bitmap largeIconBits = ((BitmapDrawable) d).getBitmap();
-                n.extras.putParcelable(Notification.EXTRA_LARGE_ICON, largeIconBits);
-                n.largeIcon = largeIconBits;
+    /**
+     * Convert new-style Icons to legacy representations for pre-M clients.
+     * @hide
+     */
+    public final void createLegacyIconExtras(Notification n) {
+        if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.M) {
+            Icon smallIcon = n.getSmallIcon();
+            Icon largeIcon = n.getLargeIcon();
+            if (smallIcon != null && smallIcon.getType() == Icon.TYPE_RESOURCE) {
+                n.extras.putInt(Notification.EXTRA_SMALL_ICON, smallIcon.getResId());
+                n.icon = smallIcon.getResId();
+            }
+            if (largeIcon != null) {
+                Drawable d = largeIcon.loadDrawable(getContext());
+                if (d != null && d instanceof BitmapDrawable) {
+                    final Bitmap largeIconBits = ((BitmapDrawable) d).getBitmap();
+                    n.extras.putParcelable(Notification.EXTRA_LARGE_ICON, largeIconBits);
+                    n.largeIcon = largeIconBits;
+                }
             }
         }
     }
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 4cb552d..85e9e49 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2553,34 +2553,42 @@
         final boolean isItemEnabled;
         final ViewGroup.LayoutParams lp = view.getLayoutParams();
         if (lp instanceof AbsListView.LayoutParams) {
-            isItemEnabled = ((AbsListView.LayoutParams) lp).isEnabled;
+            isItemEnabled = ((AbsListView.LayoutParams) lp).isEnabled && isEnabled();
         } else {
             isItemEnabled = false;
         }
 
-        if (!isEnabled() || !isItemEnabled) {
-            info.setEnabled(false);
-            return;
-        }
+        info.setEnabled(isItemEnabled);
 
         if (position == getSelectedItemPosition()) {
             info.setSelected(true);
-            info.addAction(AccessibilityAction.ACTION_CLEAR_SELECTION);
-        } else {
-            info.addAction(AccessibilityAction.ACTION_SELECT);
+            addAccessibilityActionIfEnabled(info, isItemEnabled,
+                    AccessibilityAction.ACTION_CLEAR_SELECTION);
+        } else  {
+            addAccessibilityActionIfEnabled(info, isItemEnabled,
+                    AccessibilityAction.ACTION_SELECT);
         }
 
         if (isItemClickable(view)) {
-            info.addAction(AccessibilityAction.ACTION_CLICK);
+            addAccessibilityActionIfEnabled(info, isItemEnabled, AccessibilityAction.ACTION_CLICK);
             info.setClickable(true);
         }
 
         if (isLongClickable()) {
-            info.addAction(AccessibilityAction.ACTION_LONG_CLICK);
+            addAccessibilityActionIfEnabled(info, isItemEnabled,
+                    AccessibilityAction.ACTION_LONG_CLICK);
             info.setLongClickable(true);
         }
     }
 
+
+    private void addAccessibilityActionIfEnabled(AccessibilityNodeInfo info, boolean enabled,
+            AccessibilityAction action) {
+        if (enabled) {
+            info.addAction(action);
+        }
+    }
+
     private boolean isItemClickable(View view) {
         return !view.hasExplicitFocusable();
     }
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 18c6abb..50bb688 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -38,6 +38,11 @@
 import android.view.inspector.InspectableProperty;
 
 import com.android.internal.R;
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 
 /**
@@ -91,6 +96,10 @@
     @UnsupportedAppUsage
     private boolean mIsDragging;
 
+    private List<Rect> mUserGestureExclusionRects = Collections.emptyList();
+    private final List<Rect> mGestureExclusionRects = new ArrayList<>();
+    private final Rect mThumbRect = new Rect();
+
     public AbsSeekBar(Context context) {
         super(context);
     }
@@ -735,6 +744,27 @@
 
         // Canvas will be translated, so 0,0 is where we start drawing
         thumb.setBounds(left, top, right, bottom);
+        updateGestureExclusionRects();
+    }
+
+    @Override
+    public void setSystemGestureExclusionRects(@NonNull List<Rect> rects) {
+        Preconditions.checkNotNull(rects, "rects must not be null");
+        mUserGestureExclusionRects = rects;
+        updateGestureExclusionRects();
+    }
+
+    private void updateGestureExclusionRects() {
+        final Drawable thumb = mThumb;
+        if (thumb == null) {
+            super.setSystemGestureExclusionRects(mUserGestureExclusionRects);
+            return;
+        }
+        mGestureExclusionRects.clear();
+        thumb.copyBounds(mThumbRect);
+        mGestureExclusionRects.add(mThumbRect);
+        mGestureExclusionRects.addAll(mUserGestureExclusionRects);
+        super.setSystemGestureExclusionRects(mGestureExclusionRects);
     }
 
     /**
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index c9ef038..cac75cfd 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -134,6 +134,7 @@
 import java.text.BreakIterator;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
@@ -5097,6 +5098,12 @@
         void onHandleMoved() {}
 
         public void onDetached() {}
+
+        @Override
+        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+            super.onSizeChanged(w, h, oldw, oldh);
+            setSystemGestureExclusionRects(Collections.singletonList(new Rect(0, 0, w, h)));
+        }
     }
 
     private class InsertionHandleView extends HandleView {
diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java
index d9fd3b5..b27c11b 100644
--- a/core/java/com/android/internal/colorextraction/ColorExtractor.java
+++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java
@@ -53,11 +53,13 @@
     protected WallpaperColors mLockColors;
 
     public ColorExtractor(Context context) {
-        this(context, new Tonal(context), true /* immediately */);
+        this(context, new Tonal(context), true /* immediately */,
+                context.getSystemService(WallpaperManager.class));
     }
 
     @VisibleForTesting
-    public ColorExtractor(Context context, ExtractionType extractionType, boolean immediately) {
+    public ColorExtractor(Context context, ExtractionType extractionType, boolean immediately,
+            WallpaperManager wallpaperManager) {
         mContext = context;
         mExtractionType = extractionType;
 
@@ -72,7 +74,6 @@
 
         mOnColorsChangedListeners = new ArrayList<>();
 
-        WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class);
         if (wallpaperManager == null) {
             Log.w(TAG, "Can't listen to color changes!");
         } else {
@@ -110,7 +111,7 @@
         }
     }
 
-    private void extractWallpaperColors() {
+    protected void extractWallpaperColors() {
         GradientColors[] systemColors = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
         GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK);
         extractInto(mSystemColors,
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index ee81868..2ba9cf1 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -512,9 +512,6 @@
         Credentials peerCredentials = null;
         ZygoteArguments args = null;
 
-        // Load resources
-        ZygoteInit.nativePreloadGraphicsDriver();
-
         while (true) {
             try {
                 sessionSocket = usapPoolSocket.accept();
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 585a279..723f161 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -262,8 +262,10 @@
     private final int mResizeShadowSize;
     private final Paint mVerticalResizeShadowPaint = new Paint();
     private final Paint mHorizontalResizeShadowPaint = new Paint();
+    private final Paint mLegacyNavigationBarBackgroundPaint = new Paint();
     private Insets mBackgroundInsets = Insets.NONE;
     private Insets mLastBackgroundInsets = Insets.NONE;
+    private boolean mDrawLegacyNavigationBarBackground;
 
     DecorView(Context context, int featureId, PhoneWindow window,
             WindowManager.LayoutParams params) {
@@ -292,6 +294,8 @@
         mResizeShadowSize = context.getResources().getDimensionPixelSize(
                 R.dimen.resize_shadow_size);
         initResizingPaints();
+
+        mLegacyNavigationBarBackgroundPaint.setColor(Color.BLACK);
     }
 
     void setBackgroundFallback(@Nullable Drawable fallbackDrawable) {
@@ -1004,6 +1008,10 @@
     public void onWindowSystemUiVisibilityChanged(int visible) {
         updateColorViews(null /* insets */, true /* animate */);
         updateDecorCaptionStatus(getResources().getConfiguration());
+
+        if (mStatusGuard != null && mStatusGuard.getVisibility() == VISIBLE) {
+            updateStatusGuardColor();
+        }
     }
 
     @Override
@@ -1139,6 +1147,8 @@
                     navBarToRightEdge || navBarToLeftEdge, navBarToLeftEdge,
                     0 /* sideInset */, animate && !disallowAnimate,
                     mForceWindowDrawsBarBackgrounds);
+            mDrawLegacyNavigationBarBackground = mNavigationColorViewState.visible
+                    && (mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0;
 
             boolean statusBarNeedsRightInset = navBarToRightEdge
                     && mNavigationColorViewState.present;
@@ -1462,28 +1472,45 @@
                     }
                     final Rect rect = mTempRect;
 
-                    // If the parent doesn't consume the insets, manually
-                    // apply the default system window insets.
-                    mWindow.mContentParent.computeSystemWindowInsets(insets, rect);
-                    final int newMargin = rect.top == 0 ? insets.getSystemWindowInsetTop() : 0;
-                    if (mlp.topMargin != newMargin) {
-                        mlpChanged = true;
-                        mlp.topMargin = insets.getSystemWindowInsetTop();
+                    // Apply the insets that have not been applied by the contentParent yet.
+                    WindowInsets innerInsets =
+                            mWindow.mContentParent.computeSystemWindowInsets(insets, rect);
+                    int newTopMargin = innerInsets.getSystemWindowInsetTop();
+                    int newLeftMargin = innerInsets.getSystemWindowInsetLeft();
+                    int newRightMargin = innerInsets.getSystemWindowInsetRight();
 
-                        if (mStatusGuard == null) {
-                            mStatusGuard = new View(mContext);
-                            mStatusGuard.setBackgroundColor(mContext.getColor(
-                                    R.color.decor_view_status_guard));
-                            addView(mStatusGuard, indexOfChild(mStatusColorViewState.view),
-                                    new LayoutParams(LayoutParams.MATCH_PARENT,
-                                            mlp.topMargin, Gravity.START | Gravity.TOP));
-                        } else {
-                            final LayoutParams lp = (LayoutParams)
-                                    mStatusGuard.getLayoutParams();
-                            if (lp.height != mlp.topMargin) {
-                                lp.height = mlp.topMargin;
-                                mStatusGuard.setLayoutParams(lp);
-                            }
+                    // Must use root window insets for the guard, because the color views consume
+                    // the navigation bar inset if the window does not request LAYOUT_HIDE_NAV - but
+                    // the status guard is attached at the root.
+                    WindowInsets rootInsets = getRootWindowInsets();
+                    int newGuardLeftMargin = rootInsets.getSystemWindowInsetLeft();
+                    int newGuardRightMargin = rootInsets.getSystemWindowInsetRight();
+
+                    if (mlp.topMargin != newTopMargin || mlp.leftMargin != newLeftMargin
+                            || mlp.rightMargin != newRightMargin) {
+                        mlpChanged = true;
+                        mlp.topMargin = newTopMargin;
+                        mlp.leftMargin = newLeftMargin;
+                        mlp.rightMargin = newRightMargin;
+                    }
+
+                    if (newTopMargin > 0 && mStatusGuard == null) {
+                        mStatusGuard = new View(mContext);
+                        mStatusGuard.setVisibility(GONE);
+                        final LayoutParams lp = new LayoutParams(MATCH_PARENT,
+                                mlp.topMargin, Gravity.LEFT | Gravity.TOP);
+                        lp.leftMargin = newGuardLeftMargin;
+                        lp.rightMargin = newGuardRightMargin;
+                        addView(mStatusGuard, indexOfChild(mStatusColorViewState.view), lp);
+                    } else if (mStatusGuard != null) {
+                        final LayoutParams lp = (LayoutParams)
+                                mStatusGuard.getLayoutParams();
+                        if (lp.height != mlp.topMargin || lp.leftMargin != newGuardLeftMargin
+                                || lp.rightMargin != newGuardRightMargin) {
+                            lp.height = mlp.topMargin;
+                            lp.leftMargin = newGuardLeftMargin;
+                            lp.rightMargin = newGuardRightMargin;
+                            mStatusGuard.setLayoutParams(lp);
                         }
                     }
 
@@ -1491,6 +1518,11 @@
                     // always show the status guard above it if we have one.
                     showStatusGuard = mStatusGuard != null;
 
+                    if (showStatusGuard && mStatusGuard.getVisibility() != VISIBLE) {
+                        // If it wasn't previously shown, the color may be stale
+                        updateStatusGuardColor();
+                    }
+
                     // We only need to consume the insets if the action
                     // mode is overlaid on the app content (e.g. it's
                     // sitting in a FrameLayout, see
@@ -1502,7 +1534,7 @@
                     }
                 } else {
                     // reset top margin
-                    if (mlp.topMargin != 0) {
+                    if (mlp.topMargin != 0 || mlp.leftMargin != 0 || mlp.rightMargin != 0) {
                         mlpChanged = true;
                         mlp.topMargin = 0;
                     }
@@ -1513,11 +1545,19 @@
             }
         }
         if (mStatusGuard != null) {
-            mStatusGuard.setVisibility(showStatusGuard ? View.VISIBLE : View.GONE);
+            mStatusGuard.setVisibility(showStatusGuard ? VISIBLE : GONE);
         }
         return insets;
     }
 
+    private void updateStatusGuardColor() {
+        boolean lightStatusBar =
+                (getWindowSystemUiVisibility() & SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0;
+        mStatusGuard.setBackgroundColor(lightStatusBar
+                ? mContext.getColor(R.color.decor_view_status_guard_light)
+                : mContext.getColor(R.color.decor_view_status_guard));
+    }
+
     /**
      * Overrides the view outline when the activity enters picture-in-picture to ensure that it has
      * an opaque shadow even if the window background is completely transparent. This only applies
@@ -2276,6 +2316,7 @@
     @Override
     public void onPostDraw(RecordingCanvas canvas) {
         drawResizingShadowIfNeeded(canvas);
+        drawLegacyNavigationBarBackground(canvas);
     }
 
     private void initResizingPaints() {
@@ -2308,6 +2349,18 @@
         canvas.restore();
     }
 
+    private void drawLegacyNavigationBarBackground(RecordingCanvas canvas) {
+        if (!mDrawLegacyNavigationBarBackground) {
+            return;
+        }
+        View v = mNavigationColorViewState.view;
+        if (v == null) {
+            return;
+        }
+        canvas.drawRect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom(),
+                mLegacyNavigationBarBackgroundPaint);
+    }
+
     /** Release the renderer thread which is usually done when the user stops resizing. */
     private void releaseThreadedRenderer() {
         if (mResizingBackgroundDrawable != null && mLastBackgroundDrawableCb != null) {
@@ -2594,6 +2647,7 @@
                                         }
                                         lastActionModeView.killMode();
                                         mFadeAnim = null;
+                                        requestApplyInsets();
                                     }
                                 }
 
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index fc2b7f6..686a919 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -2242,6 +2242,12 @@
     return AudioSystem::setAllowedCapturePolicy(uid, flags);
 }
 
+static jint
+android_media_AudioSystem_setRttEnabled(JNIEnv *env, jobject thiz, jboolean enabled)
+{
+    return (jint) check_AudioSystem_Command(AudioSystem::setRttEnabled(enabled));
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gMethods[] = {
@@ -2319,6 +2325,7 @@
     {"getHwOffloadEncodingFormatsSupportedForA2DP", "(Ljava/util/ArrayList;)I",
                     (void*)android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP},
     {"setAllowedCapturePolicy", "(II)I", (void *)android_media_AudioSystem_setAllowedCapturePolicy},
+    {"setRttEnabled",       "(Z)I",     (void *)android_media_AudioSystem_setRttEnabled},
 };
 
 static const JNINativeMethod gEventHandlerMethods[] = {
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index 842679e..14dbabb 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -713,16 +713,20 @@
                                      O_CREAT | O_WRONLY | O_NOFOLLOW | O_CLOEXEC | O_APPEND,
                                      0666));
     if (fd < 0) {
-        fprintf(stderr, "Can't open %s: %s\n", fileNameChars.c_str(), strerror(errno));
+        PLOG(ERROR) << "Can't open " << fileNameChars.c_str();
         return false;
     }
 
-    return (dump_backtrace_to_file_timeout(pid, dumpType, timeoutSecs, fd) == 0);
+    int res = dump_backtrace_to_file_timeout(pid, dumpType, timeoutSecs, fd);
+    if (fdatasync(fd.get()) != 0) {
+        PLOG(ERROR) << "Failed flushing trace.";
+    }
+    return res == 0;
 }
 
 static jboolean android_os_Debug_dumpJavaBacktraceToFileTimeout(JNIEnv* env, jobject clazz,
         jint pid, jstring fileName, jint timeoutSecs) {
-    const bool ret =  dumpTraces(env, pid, fileName, timeoutSecs, kDebuggerdJavaBacktrace);
+    const bool ret = dumpTraces(env, pid, fileName, timeoutSecs, kDebuggerdJavaBacktrace);
     return ret ? JNI_TRUE : JNI_FALSE;
 }
 
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 3b28265..1dcd389 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -79,6 +79,7 @@
 
     <drawable name="input_method_fullscreen_background">#fff9f9f9</drawable>
     <color name="decor_view_status_guard">#ff000000</color>
+    <color name="decor_view_status_guard_light">#ffffffff</color>
 
     <!-- For date picker widget -->
     <drawable name="selected_day_background">#ff0092f4</drawable>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 641f223..9d75654 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1962,6 +1962,7 @@
   <java-symbol type="bool" name="show_ongoing_ime_switcher" />
   <java-symbol type="color" name="config_defaultNotificationColor" />
   <java-symbol type="color" name="decor_view_status_guard" />
+  <java-symbol type="color" name="decor_view_status_guard_light" />
   <java-symbol type="drawable" name="ic_notification_ime_default" />
   <java-symbol type="drawable" name="ic_menu_refresh" />
   <java-symbol type="drawable" name="ic_settings" />
@@ -3803,7 +3804,9 @@
   <java-symbol type="string" name="chooser_all_apps_button_label" />
   <java-symbol type="anim" name="resolver_launch_anim" />
   <java-symbol type="style" name="Animation.DeviceDefault.Activity.Resolver" />
-  
+
+  <java-symbol type="color" name="decor_view_status_guard_light" />
+
   <java-symbol type="string" name="config_defaultSupervisionProfileOwnerComponent" />
   <java-symbol type="bool" name="config_inflateSignalStrength" />
 </resources>
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index fde0e64..53bc65d 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -24,7 +24,6 @@
 import android.content.pm.PackageManager;
 import android.media.audiofx.AudioEffect;
 import android.media.audiopolicy.AudioMix;
-import android.os.Build;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -981,6 +980,8 @@
     public static native boolean getMasterMono();
     /** @hide enables or disables the master mono mode. */
     public static native int setMasterMono(boolean mono);
+    /** @hide enables or disables the RTT mode. */
+    public static native int setRttEnabled(boolean enabled);
 
     /** @hide returns master balance value in range -1.f -> 1.f, where 0.f is dead center. */
     @TestApi
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 8373761..16b0125 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -63,6 +63,7 @@
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.classifier.FalsingManagerFactory;
 import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.car.CarQSFragment;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -127,6 +128,7 @@
     private SwitchToGuestTimer mSwitchToGuestTimer;
     private NotificationDataManager mNotificationDataManager;
     private NotificationClickHandlerFactory mNotificationClickHandlerFactory;
+    private ScreenLifecycle mScreenLifecycle;
 
     // The container for the notifications.
     private CarNotificationView mNotificationView;
@@ -230,6 +232,9 @@
         mPowerManagerHelper.connectToCarService();
 
         mSwitchToGuestTimer = new SwitchToGuestTimer(mContext);
+
+        mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
+        mScreenLifecycle.addObserver(mScreenObserver);
     }
 
     /**
@@ -315,7 +320,6 @@
     public void showKeyguard() {
         super.showKeyguard();
         updateNavBarForKeyguardContent();
-        dismissKeyguardWhenUserSwitcherNotDisplayed();
     }
 
     /**
@@ -978,6 +982,13 @@
         }
     }
 
+    final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
+        @Override
+        public void onScreenTurnedOn() {
+            dismissKeyguardWhenUserSwitcherNotDisplayed();
+        }
+    };
+
     // We automatically dismiss keyguard unless user switcher is being shown on the keyguard.
     private void dismissKeyguardWhenUserSwitcherNotDisplayed() {
         if (mFullscreenUserSwitcher == null) {
@@ -1000,6 +1011,10 @@
      * Dismisses the keyguard and shows bouncer if authentication is necessary.
      */
     public void dismissKeyguard() {
+        // Don't dismiss keyguard when the screen is off.
+        if (mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_OFF) {
+            return;
+        }
         executeRunnableDismissingKeyguard(null/* runnable */, null /* cancelAction */,
                 true /* dismissShade */, true /* afterKeyguardGone */, true /* deferred */);
     }
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
index 93f24f7..4f85eea 100755
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
@@ -130,18 +130,15 @@
             } else {
                 PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
                         PackageInstaller.SessionParams.MODE_FULL_INSTALL);
-                params.installFlags = PackageManager.INSTALL_FULL_APP;
-                params.referrerUri = getIntent().getParcelableExtra(Intent.EXTRA_REFERRER);
-                params.originatingUri = getIntent()
-                        .getParcelableExtra(Intent.EXTRA_ORIGINATING_URI);
-                params.originatingUid = getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID,
-                        UID_UNKNOWN);
-                params.installerPackageName =
-                        getIntent().getStringExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME);
-                params.installReason = PackageManager.INSTALL_REASON_USER;
-
-                // Whitelist all restricted permissions.
-                params.setWhitelistedRestrictedPermissions(null /*permissions*/);
+                params.setInstallAsInstantApp(false);
+                params.setReferrerUri(getIntent().getParcelableExtra(Intent.EXTRA_REFERRER));
+                params.setOriginatingUri(getIntent()
+                        .getParcelableExtra(Intent.EXTRA_ORIGINATING_URI));
+                params.setOriginatingUid(getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID,
+                        UID_UNKNOWN));
+                params.setInstallerPackageName(getIntent().getStringExtra(
+                        Intent.EXTRA_INSTALLER_PACKAGE_NAME));
+                params.setInstallReason(PackageManager.INSTALL_REASON_USER);
 
                 File file = new File(mPackageURI.getPath());
                 try {
diff --git a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/RecentsActivity.java
index 79c691c..a7ccc3a 100644
--- a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/RecentsActivity.java
@@ -323,7 +323,7 @@
         mColorExtractor = Dependency.get(SysuiColorExtractor.class);
         mColorExtractor.addOnColorsChangedListener(this);
         mUsingDarkText = mColorExtractor.getColors(ColorExtractor.TYPE_DARK,
-                WallpaperManager.FLAG_SYSTEM, true).supportsDarkText();
+                WallpaperManager.FLAG_SYSTEM).supportsDarkText();
         setTheme(mUsingDarkText ? R.style.RecentsTheme_Wallpaper_Light
                 : R.style.RecentsTheme_Wallpaper);
 
@@ -394,8 +394,6 @@
     @Override
     public void onColorsChanged(ColorExtractor colorExtractor, int which) {
         if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
-            // Recents doesn't care about the wallpaper being visible or not, it always
-            // wants to scrim with wallpaper colors
             ColorExtractor.GradientColors colors = mColorExtractor.getNeutralColors();
             boolean darkText = colors.supportsDarkText();
             if (darkText != mUsingDarkText) {
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 9a04222..67c4458 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -111,7 +111,7 @@
         <item name="android:colorBackground">@*android:color/background_material_dark</item>
     </style>
 
-    <style name="TextAppearance.Keyguard" parent="Theme.SystemUI">
+    <style name="TextAppearance.Keyguard">
         <item name="android:textSize">@dimen/widget_title_font_size</item>
         <item name="android:gravity">center</item>
         <item name="android:ellipsize">end</item>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index 6b07ed8..a2abb4b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -64,6 +64,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.Future;
 import java.util.function.Consumer;
 
 public class ActivityManagerWrapper {
@@ -380,8 +381,8 @@
     /**
      * Requests that the system close any open system windows (including other SystemUI).
      */
-    public void closeSystemWindows(final String reason) {
-        mBackgroundExecutor.submit(new Runnable() {
+    public Future<?> closeSystemWindows(final String reason) {
+        return mBackgroundExecutor.submit(new Runnable() {
             @Override
             public void run() {
                 try {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 0bb9e744..7ec1bda 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -374,7 +374,7 @@
 
     private void updateColors() {
         ColorExtractor.GradientColors colors = mSysuiColorExtractor.getColors(
-                WallpaperManager.FLAG_LOCK, true);
+                WallpaperManager.FLAG_LOCK);
         mSupportsDarkText = colors.supportsDarkText();
         mColorPalette = colors.getColorPalette();
         if (mClockPlugin != null) {
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
index f468eca..558ac4b 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
@@ -130,7 +130,7 @@
         setDarkAmount(1f);
         setTextColor(Color.WHITE);
         ColorExtractor.GradientColors colors = mColorExtractor.getColors(
-                WallpaperManager.FLAG_LOCK, true);
+                WallpaperManager.FLAG_LOCK);
         setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
         onTimeTick();
 
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
index 61a6952..bdf9dc4 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
@@ -130,7 +130,7 @@
         setDarkAmount(1f);
         setTextColor(Color.WHITE);
         ColorExtractor.GradientColors colors = mColorExtractor.getColors(
-                WallpaperManager.FLAG_LOCK, true);
+                WallpaperManager.FLAG_LOCK);
         setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
         onTimeTick();
 
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
index ce1f09c..98679ade 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/DefaultClockController.java
@@ -124,7 +124,7 @@
         setDarkAmount(1f);
         setTextColor(Color.WHITE);
         ColorExtractor.GradientColors colors = mColorExtractor.getColors(
-                WallpaperManager.FLAG_LOCK, true);
+                WallpaperManager.FLAG_LOCK);
         setColorPalette(colors.supportsDarkText(), colors.getColorPalette());
         onTimeTick();
 
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 7d36469..eff7054 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -64,6 +64,7 @@
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
+import android.view.animation.AccelerateInterpolator;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 import android.widget.FrameLayout;
@@ -231,7 +232,10 @@
             anim.start();
         } else {
             view.animate().cancel();
-            view.animate().setDuration(400).alpha(0f);
+            view.animate()
+                    .setInterpolator(new AccelerateInterpolator(1.5f))
+                    .setDuration(250)
+                    .alpha(0f);
         }
 
     }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
index b7479985..002d4f3 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java
@@ -243,12 +243,12 @@
             return;
         }
 
-        mHandlesShowing = false;
-        mHandlesLastHiddenAt = SystemClock.elapsedRealtime();
         ScreenDecorations screenDecorations = mScreenDecorationsSupplier.get();
         if (screenDecorations == null) {
             Log.w(TAG, "Couldn't hide handles, ScreenDecorations unavailable");
         } else {
+            mHandlesShowing = false;
+            mHandlesLastHiddenAt = SystemClock.elapsedRealtime();
             screenDecorations.setAssistHintVisible(false);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
index 835ffc9..6f56a53 100644
--- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
@@ -16,18 +16,11 @@
 
 package com.android.systemui.colorextraction;
 
-import android.annotation.ColorInt;
 import android.app.WallpaperColors;
 import android.app.WallpaperManager;
 import android.content.Context;
-import android.os.Handler;
-import android.os.RemoteException;
+import android.graphics.Color;
 import android.os.UserHandle;
-import android.util.Log;
-import android.view.Display;
-import android.view.IWallpaperVisibilityListener;
-import android.view.IWindowManager;
-import android.view.WindowManagerGlobal;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.colorextraction.ColorExtractor;
@@ -52,46 +45,28 @@
         ConfigurationController.ConfigurationListener {
     private static final String TAG = "SysuiColorExtractor";
     private final Tonal mTonal;
-    private boolean mWallpaperVisible;
-    private boolean mHasBackdrop;
-    // Colors to return when the wallpaper isn't visible
-    private final GradientColors mWpHiddenColors;
+    private boolean mHasMediaArtwork;
+    private final GradientColors mNeutralColorsLock;
+    private final GradientColors mBackdropColors;
 
     @Inject
     public SysuiColorExtractor(Context context, ConfigurationController configurationController) {
-        this(context, new Tonal(context), configurationController, true);
+        this(context, new Tonal(context), configurationController,
+                context.getSystemService(WallpaperManager.class), false /* immediately */);
     }
 
     @VisibleForTesting
     public SysuiColorExtractor(Context context, ExtractionType type,
-            ConfigurationController configurationController, boolean registerVisibility) {
-        super(context, type, false /* immediately */);
+            ConfigurationController configurationController,
+            WallpaperManager wallpaperManager, boolean immediately) {
+        super(context, type, immediately, wallpaperManager);
         mTonal = type instanceof Tonal ? (Tonal) type : new Tonal(context);
-        mWpHiddenColors = new GradientColors();
+        mNeutralColorsLock = new GradientColors();
         configurationController.addCallback(this);
 
-        WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
-        updateDefaultGradients(systemColors);
+        mBackdropColors = new GradientColors();
+        mBackdropColors.setMainColor(Color.BLACK);
 
-        if (registerVisibility) {
-            try {
-                IWindowManager windowManagerService = WindowManagerGlobal.getWindowManagerService();
-                Handler handler = Handler.getMain();
-                boolean visible = windowManagerService.registerWallpaperVisibilityListener(
-                        new IWallpaperVisibilityListener.Stub() {
-                            @Override
-                            public void onWallpaperVisibilityChanged(boolean newVisibility,
-                                    int displayId) throws RemoteException {
-                                handler.post(() -> setWallpaperVisible(newVisibility));
-                            }
-                        }, Display.DEFAULT_DISPLAY);
-                setWallpaperVisible(visible);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Can't listen to wallpaper visibility changes", e);
-            }
-        }
-
-        WallpaperManager wallpaperManager = context.getSystemService(WallpaperManager.class);
         if (wallpaperManager != null) {
             // Listen to all users instead of only the current one.
             wallpaperManager.removeOnColorsChangedListener(this);
@@ -100,8 +75,14 @@
         }
     }
 
-    private void updateDefaultGradients(WallpaperColors colors) {
-        mTonal.applyFallback(colors, mWpHiddenColors);
+    @Override
+    protected void extractWallpaperColors() {
+        super.extractWallpaperColors();
+        // mTonal is final but this method will be invoked by the base class during its ctor.
+        if (mTonal == null) {
+            return;
+        }
+        mTonal.applyFallback(mLockColors == null ? mSystemColors : mLockColors, mNeutralColorsLock);
     }
 
     @Override
@@ -110,27 +91,28 @@
             // Colors do not belong to current user, ignoring.
             return;
         }
-
-        super.onColorsChanged(colors, which);
-
-        if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
-            @ColorInt int oldColor = mWpHiddenColors.getMainColor();
-            updateDefaultGradients(colors);
-            if (oldColor != mWpHiddenColors.getMainColor()) {
-                triggerColorsChanged(WallpaperManager.FLAG_SYSTEM);
-            }
+        if ((which & WallpaperManager.FLAG_LOCK) != 0) {
+            mTonal.applyFallback(colors, mNeutralColorsLock);
         }
+        super.onColorsChanged(colors, which);
     }
 
     @Override
     public void onUiModeChanged() {
-        WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
-        updateDefaultGradients(systemColors);
-        triggerColorsChanged(WallpaperManager.FLAG_SYSTEM);
+        extractWallpaperColors();
+        triggerColorsChanged(WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK);
+    }
+
+    @Override
+    public GradientColors getColors(int which, int type) {
+        if (mHasMediaArtwork && (which & WallpaperManager.FLAG_LOCK) != 0) {
+            return mBackdropColors;
+        }
+        return super.getColors(which, type);
     }
 
     /**
-     * Colors the should be using for scrims.
+     * Colors that should be using for scrims.
      *
      * They will be:
      * - A light gray if the wallpaper is light
@@ -138,81 +120,12 @@
      * - Black otherwise
      */
     public GradientColors getNeutralColors() {
-        return mWpHiddenColors;
+        return mHasMediaArtwork ? mBackdropColors : mNeutralColorsLock;
     }
 
-    /**
-     * Get TYPE_NORMAL colors when wallpaper is visible, or fallback otherwise.
-     *
-     * @param which FLAG_LOCK or FLAG_SYSTEM
-     * @return colors
-     */
-    @Override
-    public GradientColors getColors(int which) {
-        return getColors(which, TYPE_DARK);
-    }
-
-    /**
-     * Wallpaper colors when the wallpaper is visible, fallback otherwise.
-     *
-     * @param which FLAG_LOCK or FLAG_SYSTEM
-     * @param type TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK
-     * @return colors
-     */
-    @Override
-    public GradientColors getColors(int which, int type) {
-        return getColors(which, type, false /* ignoreVisibility */);
-    }
-
-    /**
-     * Get TYPE_NORMAL colors, possibly ignoring wallpaper visibility.
-     *
-     * @param which FLAG_LOCK or FLAG_SYSTEM
-     * @param ignoreWallpaperVisibility whether you want fallback colors or not if the wallpaper
-     *                                  isn't visible
-     * @return
-     */
-    public GradientColors getColors(int which, boolean ignoreWallpaperVisibility) {
-        return getColors(which, TYPE_NORMAL, ignoreWallpaperVisibility);
-    }
-
-    /**
-     *
-     * @param which FLAG_LOCK or FLAG_SYSTEM
-     * @param type TYPE_NORMAL, TYPE_DARK or TYPE_EXTRA_DARK
-     * @param ignoreWallpaperVisibility true if true wallpaper colors should be returning
-     *                                  if it's visible or not
-     * @return colors
-     */
-    public GradientColors getColors(int which, int type, boolean ignoreWallpaperVisibility) {
-        // mWallpaperVisible only handles the "system wallpaper" and will be always set to false
-        // if we have different lock and system wallpapers.
-        if (which == WallpaperManager.FLAG_SYSTEM) {
-            if (mWallpaperVisible || ignoreWallpaperVisibility) {
-                return super.getColors(which, type);
-            } else {
-                return mWpHiddenColors;
-            }
-        } else {
-            if (mHasBackdrop) {
-                return mWpHiddenColors;
-            } else {
-                return super.getColors(which, type);
-            }
-        }
-    }
-
-    @VisibleForTesting
-    void setWallpaperVisible(boolean visible) {
-        if (mWallpaperVisible != visible) {
-            mWallpaperVisible = visible;
-            triggerColorsChanged(WallpaperManager.FLAG_SYSTEM);
-        }
-    }
-
-    public void setHasBackdrop(boolean hasBackdrop) {
-        if (mHasBackdrop != hasBackdrop) {
-            mHasBackdrop = hasBackdrop;
+    public void setHasMediaArtwork(boolean hasBackdrop) {
+        if (mHasMediaArtwork != hasBackdrop) {
+            mHasMediaArtwork = hasBackdrop;
             triggerColorsChanged(WallpaperManager.FLAG_LOCK);
         }
     }
@@ -230,7 +143,8 @@
         pw.println("  Gradients:");
         pw.println("    system: " + Arrays.toString(system));
         pw.println("    lock: " + Arrays.toString(lock));
-        pw.println("  Default scrim: " + mWpHiddenColors);
+        pw.println("  Neutral colors: " + mNeutralColorsLock);
+        pw.println("  Has media backdrop: " + mHasMediaArtwork);
 
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 831d074..5f52486 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -70,11 +70,12 @@
     private final Consumer<Boolean> mProxCallback;
     private final Callback mCallback;
     @VisibleForTesting
-    protected final TriggerSensor[] mSensors;
+    protected TriggerSensor[] mSensors;
 
     private final Handler mHandler = new Handler();
     private final ProxSensor mProxSensor;
     private long mDebounceFrom;
+    private boolean mSettingRegistered;
 
     public DozeSensors(Context context, AlarmManager alarmManager, SensorManager sensorManager,
             DozeParameters dozeParameters, AmbientDisplayConfiguration config, WakeLock wakeLock,
@@ -172,13 +173,8 @@
     public void setListening(boolean listen) {
         for (TriggerSensor s : mSensors) {
             s.setListening(listen);
-            if (listen) {
-                s.registerSettingsObserver(mSettingsObserver);
-            }
         }
-        if (!listen) {
-            mResolver.unregisterContentObserver(mSettingsObserver);
-        }
+        registerSettingsObserverIfNeeded(listen);
     }
 
     /** Set the listening state of only the sensors that require the touchscreen. */
@@ -240,6 +236,17 @@
         return mProxSensor.mCurrentlyFar;
     }
 
+    private void registerSettingsObserverIfNeeded(boolean register) {
+        if (!register) {
+            mResolver.unregisterContentObserver(mSettingsObserver);
+        } else if (!mSettingRegistered) {
+            for (TriggerSensor s : mSensors) {
+                s.registerSettingsObserver(mSettingsObserver);
+            }
+        }
+        mSettingRegistered = register;
+    }
+
     private class ProxSensor implements SensorEventListener {
 
         boolean mRequested;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 341461b..11ca94f 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -92,6 +92,11 @@
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+
 
 /**
  * POD used in the AsyncTask which saves an image in the background.
@@ -446,6 +451,8 @@
     static final String EXTRA_CANCEL_NOTIFICATION = "android:screenshot_cancel_notification";
     static final String EXTRA_DISALLOW_ENTER_PIP = "android:screenshot_disallow_enter_pip";
 
+    private static final String TAG = "GlobalScreenshot";
+
     private static final int SCREENSHOT_FLASH_TO_PEAK_DURATION = 130;
     private static final int SCREENSHOT_DROP_IN_DURATION = 430;
     private static final int SCREENSHOT_DROP_OUT_DELAY = 500;
@@ -902,11 +909,19 @@
      * appropriate signals to the system (ie. to dismiss the keyguard if necessary).
      */
     public static class ActionProxyReceiver extends BroadcastReceiver {
+        static final int CLOSE_WINDOWS_TIMEOUT_MILLIS = 3000;
+
         @Override
         public void onReceive(Context context, final Intent intent) {
             Runnable startActivityRunnable = () -> {
-                ActivityManagerWrapper.getInstance().closeSystemWindows(
-                        SYSTEM_DIALOG_REASON_SCREENSHOT);
+                try {
+                    ActivityManagerWrapper.getInstance().closeSystemWindows(
+                            SYSTEM_DIALOG_REASON_SCREENSHOT).get(
+                            CLOSE_WINDOWS_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+                } catch (TimeoutException | InterruptedException | ExecutionException e) {
+                    Slog.e(TAG, "Unable to share screenshot", e);
+                    return;
+                }
 
                 Intent actionIntent = intent.getParcelableExtra(EXTRA_ACTION_INTENT);
                 if (intent.getBooleanExtra(EXTRA_CANCEL_NOTIFICATION, false)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 75ef185..6c36ab9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -488,6 +488,7 @@
         if (bmp != null) {
             artworkDrawable = new BitmapDrawable(mBackdropBack.getResources(), bmp);
         }
+        boolean hasMediaArtwork = artworkDrawable != null;
         boolean allowWhenShade = false;
         if (ENABLE_LOCKSCREEN_WALLPAPER && artworkDrawable == null) {
             Bitmap lockWallpaper =
@@ -506,7 +507,7 @@
         boolean hideBecauseOccluded = shadeController != null && shadeController.isOccluded();
 
         final boolean hasArtwork = artworkDrawable != null;
-        mColorExtractor.setHasBackdrop(hasArtwork);
+        mColorExtractor.setHasMediaArtwork(hasMediaArtwork);
         if (mScrimController != null) {
             mScrimController.setHasBackdrop(hasArtwork);
         }
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 d219ac9..c214431 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
@@ -20,7 +20,7 @@
 import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
 import static com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.ANCHOR_SCROLLING;
 import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE;
-import static com.android.systemui.statusbar.phone.NotificationIconAreaController.LOW_PRIORITY;
+import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY;
 import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -187,7 +187,7 @@
     private int mCurrentStackHeight = Integer.MAX_VALUE;
     private final Paint mBackgroundPaint = new Paint();
     private final boolean mShouldDrawNotificationBackground;
-    private boolean mLowPriorityBeforeSpeedBump;
+    private boolean mHighPriorityBeforeSpeedBump;
     private final boolean mAllowLongPress;
     private boolean mDismissRtl;
 
@@ -584,12 +584,12 @@
 
         TunerService tunerService = Dependency.get(TunerService.class);
         tunerService.addTunable((key, newValue) -> {
-            if (key.equals(LOW_PRIORITY)) {
-                mLowPriorityBeforeSpeedBump = "1".equals(newValue);
+            if (key.equals(HIGH_PRIORITY)) {
+                mHighPriorityBeforeSpeedBump = "1".equals(newValue);
             } else if (key.equals(Settings.Secure.NOTIFICATION_DISMISS_RTL)) {
                 updateDismissRtlSetting("1".equals(newValue));
             }
-        }, LOW_PRIORITY, Settings.Secure.NOTIFICATION_DISMISS_RTL);
+        }, HIGH_PRIORITY, Settings.Secure.NOTIFICATION_DISMISS_RTL);
 
         mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
             @Override
@@ -654,15 +654,7 @@
     @Override
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void onThemeChanged() {
-        int which;
-        if (mStatusBarState == StatusBarState.KEYGUARD
-                || mStatusBarState == StatusBarState.SHADE_LOCKED) {
-            which = WallpaperManager.FLAG_LOCK;
-        } else {
-            which = WallpaperManager.FLAG_SYSTEM;
-        }
-        final boolean useDarkText = mColorExtractor.getColors(which,
-                true /* ignoreVisibility */).supportsDarkText();
+        final boolean useDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
         updateDecorViews(useDarkText);
 
         updateFooter();
@@ -868,8 +860,8 @@
         int backgroundRectTop = top;
         int lastSectionBottom =
                 mSections[0].getCurrentBounds().bottom + animationYOffset;
-        int previousLeft = left;
-        int previousRight = right;
+        int currentLeft = left;
+        int currentRight = right;
         boolean first = true;
         for (NotificationSection section : mSections) {
             if (section.getFirstVisibleChild() == null) {
@@ -882,23 +874,23 @@
             // as separate roundrects, as the rounded corners right next to each other look
             // bad.
             if (sectionTop - lastSectionBottom > DISTANCE_BETWEEN_ADJACENT_SECTIONS_PX
-                    || (previousLeft != ownLeft && !first)) {
-                canvas.drawRoundRect(ownLeft,
+                    || ((currentLeft != ownLeft || currentRight != ownRight) && !first)) {
+                canvas.drawRoundRect(currentLeft,
                         backgroundRectTop,
-                        ownRight,
+                        currentRight,
                         lastSectionBottom,
                         mCornerRadius, mCornerRadius, mBackgroundPaint);
                 backgroundRectTop = sectionTop;
             }
-            previousLeft = ownLeft;
-            previousRight = ownRight;
+            currentLeft = ownLeft;
+            currentRight = ownRight;
             lastSectionBottom =
                     section.getCurrentBounds().bottom + animationYOffset;
             first = false;
         }
-        canvas.drawRoundRect(previousLeft,
+        canvas.drawRoundRect(currentLeft,
                 backgroundRectTop,
-                previousRight,
+                currentRight,
                 lastSectionBottom,
                 mCornerRadius, mCornerRadius, mBackgroundPaint);
     }
@@ -5765,10 +5757,10 @@
             ExpandableNotificationRow row = (ExpandableNotificationRow) view;
             currentIndex++;
             boolean beforeSpeedBump;
-            if (mLowPriorityBeforeSpeedBump) {
-                beforeSpeedBump = !row.getEntry().ambient;
-            } else {
+            if (mHighPriorityBeforeSpeedBump) {
                 beforeSpeedBump = row.getEntry().isHighPriority();
+            } else {
+                beforeSpeedBump = !row.getEntry().ambient;
             }
             if (beforeSpeedBump) {
                 speedBumpIndex = currentIndex;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 501e597..98505cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -41,7 +41,7 @@
 public class NotificationIconAreaController implements DarkReceiver,
         StatusBarStateController.StateListener {
 
-    public static final String LOW_PRIORITY = "low_priority";
+    public static final String HIGH_PRIORITY = "high_priority";
 
     private final ContrastColorUtil mContrastColorUtil;
     private final NotificationEntryManager mEntryManager;
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 5fff054..80fbda0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -3222,8 +3222,7 @@
 
         // Lock wallpaper defines the color of the majority of the views, hence we'll use it
         // to set our default theme.
-        final boolean lockDarkText = mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, true
-                /* ignoreVisibility */).supportsDarkText();
+        final boolean lockDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
         final int themeResId = lockDarkText ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI;
         if (mContext.getThemeResId() != themeResId) {
             mContext.setTheme(themeResId);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index 891bb35..c73ed60 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -25,7 +25,6 @@
 
 import android.app.ActivityManager;
 import android.app.IActivityManager;
-import android.app.WallpaperManager;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.res.Resources;
@@ -556,17 +555,7 @@
             return;
         }
 
-        StatusBarStateController state = Dependency.get(StatusBarStateController.class);
-        int which;
-        if (state.getState() == StatusBarState.KEYGUARD
-                || state.getState() == StatusBarState.SHADE_LOCKED) {
-            which = WallpaperManager.FLAG_LOCK;
-        } else {
-            which = WallpaperManager.FLAG_SYSTEM;
-        }
-        final boolean useDarkText = mColorExtractor.getColors(which,
-                true /* ignoreVisibility */).supportsDarkText();
-
+        final boolean useDarkText = mColorExtractor.getNeutralColors().supportsDarkText();
         // Make sure we have the correct navbar/statusbar colors.
         setKeyguardDark(useDarkText);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
index 9c2c822..41747f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
@@ -40,6 +40,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
 /**
@@ -57,6 +58,8 @@
             ColorExtractor.TYPE_DARK,
             ColorExtractor.TYPE_EXTRA_DARK};
 
+    @Mock
+    private WallpaperManager mWallpaperManager;
     private ColorExtractor.GradientColors mColors;
     private SysuiColorExtractor mColorExtractor;
 
@@ -72,32 +75,15 @@
                     outGradientColorsNormal.set(mColors);
                     outGradientColorsDark.set(mColors);
                     outGradientColorsExtraDark.set(mColors);
-                }, mock(ConfigurationController.class), false);
+                }, mock(ConfigurationController.class), mWallpaperManager, true /* immediately */);
     }
 
     @Test
-    public void getColors_usesGreyIfWallpaperNotVisible() {
-        simulateEvent(mColorExtractor);
-        mColorExtractor.setWallpaperVisible(false);
-
-        ColorExtractor.GradientColors fallbackColors = mColorExtractor.getNeutralColors();
-
-        for (int type : sTypes) {
-            assertEquals("Not using fallback!",
-                    mColorExtractor.getColors(WallpaperManager.FLAG_SYSTEM, type), fallbackColors);
-            assertNotEquals("Wallpaper visibility event should not affect lock wallpaper.",
-                    mColorExtractor.getColors(WallpaperManager.FLAG_LOCK, type), fallbackColors);
-        }
-    }
-
-    @Test
-    public void getColors_doesntUseFallbackIfVisible() {
+    public void getColors() {
         mColors.setMainColor(Color.RED);
         mColors.setSecondaryColor(Color.RED);
 
         simulateEvent(mColorExtractor);
-        mColorExtractor.setWallpaperVisible(true);
-
         for (int which : sWhich) {
             for (int type : sTypes) {
                 assertEquals("Not using extracted colors!",
@@ -109,8 +95,7 @@
     @Test
     public void getColors_fallbackWhenMediaIsVisible() {
         simulateEvent(mColorExtractor);
-        mColorExtractor.setWallpaperVisible(true);
-        mColorExtractor.setHasBackdrop(true);
+        mColorExtractor.setHasMediaArtwork(true);
 
         ColorExtractor.GradientColors fallbackColors = mColorExtractor.getNeutralColors();
 
@@ -127,7 +112,7 @@
         Tonal tonal = mock(Tonal.class);
         ConfigurationController configurationController = mock(ConfigurationController.class);
         SysuiColorExtractor sysuiColorExtractor = new SysuiColorExtractor(getContext(),
-                tonal, configurationController, false /* registerVisibility */);
+                tonal, configurationController, mWallpaperManager, true /* immediately */);
         verify(configurationController).addCallback(eq(sysuiColorExtractor));
 
         reset(tonal);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
index 4467faf..3304291 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
@@ -27,10 +27,12 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.AlarmManager;
+import android.database.ContentObserver;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -39,6 +41,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.doze.DozeSensors.TriggerSensor;
 import com.android.systemui.plugins.SensorManagerPlugin;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.AsyncSensorManager;
@@ -73,6 +76,8 @@
     private Consumer<Boolean> mProxCallback;
     @Mock
     private AlwaysOnDisplayPolicy mAlwaysOnDisplayPolicy;
+    @Mock
+    private TriggerSensor mMockTriggerSensor;
     private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener;
     private TestableLooper mTestableLooper;
     private DozeSensors mDozeSensors;
@@ -107,6 +112,25 @@
                 anyBoolean(), anyFloat(), anyFloat(), eq(null));
     }
 
+    @Test
+    public void testSetListening_firstTrue_registerSettingsObserver() {
+        mDozeSensors.mSensors = new TriggerSensor[] {mMockTriggerSensor};
+
+        mDozeSensors.setListening(true);
+
+        verify(mMockTriggerSensor).registerSettingsObserver(any(ContentObserver.class));
+    }
+
+    @Test
+    public void testSetListening_twiceTrue_onlyRegisterSettingsObserverOnce() {
+        mDozeSensors.mSensors = new TriggerSensor[] {mMockTriggerSensor};
+        mDozeSensors.setListening(true);
+
+        mDozeSensors.setListening(true);
+
+        verify(mMockTriggerSensor, times(1)).registerSettingsObserver(any(ContentObserver.class));
+    }
+
     private class TestableDozeSensors extends DozeSensors {
 
         TestableDozeSensors() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
index 025296d..06ff047 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
@@ -101,7 +101,7 @@
         mNotificationInflater.setUsesIncreasedHeadsUpHeight(true);
         Notification.Builder builder = spy(mBuilder);
         mNotificationInflater.inflateNotificationViews(
-                false /* inflateSynchronously */,
+                true /* inflateSynchronously */,
                 FLAG_CONTENT_VIEW_ALL,
                 builder,
                 mContext);
@@ -113,7 +113,7 @@
         mNotificationInflater.setUsesIncreasedHeight(true);
         Notification.Builder builder = spy(mBuilder);
         mNotificationInflater.inflateNotificationViews(
-                false /* inflateSynchronously */,
+                true /* inflateSynchronously */,
                 FLAG_CONTENT_VIEW_ALL,
                 builder,
                 mContext);
@@ -161,6 +161,7 @@
     @Test
     public void testRemovedNotInflated() throws Exception {
         mRow.setRemoved();
+        mNotificationInflater.setInflateSynchronously(true);
         mNotificationInflater.inflateNotificationViews();
         Assert.assertNull(mRow.getEntry().getRunningTask());
     }
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 56265d0..d425982 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
@@ -70,6 +70,7 @@
 import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationIconAreaController;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
@@ -110,6 +111,7 @@
     @Mock private NotificationData mNotificationData;
     @Mock private NotificationRemoteInputManager mRemoteInputManager;
     @Mock private RemoteInputController mRemoteInputController;
+    @Mock private NotificationIconAreaController mNotificationIconAreaController;
     @Mock private MetricsLogger mMetricsLogger;
     @Mock private NotificationRoundnessManager mNotificationRoundnessManager;
     private TestableNotificationEntryManager mEntryManager;
@@ -162,6 +164,7 @@
         mStackScroller.setHeadsUpManager(mHeadsUpManager);
         mStackScroller.setGroupManager(mGroupManager);
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
+        mStackScroller.setIconAreaController(mNotificationIconAreaController);
 
         // Stub out functionality that isn't necessary to test.
         doNothing().when(mBar)
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
index 1232201..ac1f022 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
@@ -25,6 +25,6 @@
     <dimen name="navigation_bar_width">16dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_frame_height">48dp</dimen>
-        <!-- The height of the bottom navigation gesture area. -->
+    <!-- The height of the bottom navigation gesture area. -->
     <dimen name="navigation_bar_gesture_height">32dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml
index c8f994c..d5991f3 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/config.xml
@@ -37,6 +37,15 @@
      {@link Window#setEnsuringNavigationBarContrastWhenTransparent}. -->
     <bool name="config_navBarNeedsScrim">false</bool>
 
+    <!-- Controls the opacity of the navigation bar depending on the visibility of the
+     various workspace stacks.
+     0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
+     1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
+         opaque.
+     2 - Nav bar is never forced opaque.
+     -->
+    <integer name="config_navBarOpacityMode">2</integer>
+
     <!-- Controls whether seamless rotation should be allowed even though the navbar can move
          (which normally prevents seamless rotation). -->
     <bool name="config_allowSeamlessRotationDespiteNavBarMoving">true</bool>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/dimens.xml
index 987d203..ac1f022 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/dimens.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayExtraWideBack/res/values/dimens.xml
@@ -25,4 +25,6 @@
     <dimen name="navigation_bar_width">16dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_frame_height">48dp</dimen>
+    <!-- The height of the bottom navigation gesture area. -->
+    <dimen name="navigation_bar_gesture_height">32dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml
index 693110a..ff507ee 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/config.xml
@@ -37,6 +37,15 @@
      {@link Window#setEnsuringNavigationBarContrastWhenTransparent}. -->
     <bool name="config_navBarNeedsScrim">false</bool>
 
+    <!-- Controls the opacity of the navigation bar depending on the visibility of the
+     various workspace stacks.
+     0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
+     1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
+         opaque.
+     2 - Nav bar is never forced opaque.
+     -->
+    <integer name="config_navBarOpacityMode">2</integer>
+
     <!-- Controls whether seamless rotation should be allowed even though the navbar can move
          (which normally prevents seamless rotation). -->
     <bool name="config_allowSeamlessRotationDespiteNavBarMoving">true</bool>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/dimens.xml
index 987d203..ac1f022 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/dimens.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayNarrowBack/res/values/dimens.xml
@@ -25,4 +25,6 @@
     <dimen name="navigation_bar_width">16dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_frame_height">48dp</dimen>
+    <!-- The height of the bottom navigation gesture area. -->
+    <dimen name="navigation_bar_gesture_height">32dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml
index 5cd6ce3..378756a 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/config.xml
@@ -37,6 +37,15 @@
      {@link Window#setEnsuringNavigationBarContrastWhenTransparent}. -->
     <bool name="config_navBarNeedsScrim">false</bool>
 
+    <!-- Controls the opacity of the navigation bar depending on the visibility of the
+     various workspace stacks.
+     0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
+     1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
+         opaque.
+     2 - Nav bar is never forced opaque.
+     -->
+    <integer name="config_navBarOpacityMode">2</integer>
+
     <!-- Controls whether seamless rotation should be allowed even though the navbar can move
          (which normally prevents seamless rotation). -->
     <bool name="config_allowSeamlessRotationDespiteNavBarMoving">true</bool>
diff --git a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/dimens.xml
index 987d203..ac1f022 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/dimens.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlayWideBack/res/values/dimens.xml
@@ -25,4 +25,6 @@
     <dimen name="navigation_bar_width">16dp</dimen>
     <!-- Height of the bottom navigation / system bar. -->
     <dimen name="navigation_bar_frame_height">48dp</dimen>
+    <!-- The height of the bottom navigation gesture area. -->
+    <dimen name="navigation_bar_gesture_height">32dp</dimen>
 </resources>
\ No newline at end of file
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 0d19a67..6eb9f0c 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -620,7 +620,6 @@
                 linkVibration(vib);
                 long ident = Binder.clearCallingIdentity();
                 try {
-
                     doCancelVibrateLocked();
                     startVibrationLocked(vib);
                     addToPreviousVibrationsLocked(vib);
@@ -1437,6 +1436,8 @@
     }
 
     final class ExternalVibratorService extends IExternalVibratorService.Stub {
+        ExternalVibrationDeathRecipient mCurrentExternalDeathRecipient;
+
         @Override
         public int onExternalVibrationStart(ExternalVibration vib) {
             if (!mSupportsExternalControl) {
@@ -1470,6 +1471,8 @@
                     // Note that this doesn't support multiple concurrent external controls, as we
                     // would need to mute the old one still if it came from a different controller.
                     mCurrentExternalVibration = vib;
+                    mCurrentExternalDeathRecipient = new ExternalVibrationDeathRecipient();
+                    mCurrentExternalVibration.linkToDeath(mCurrentExternalDeathRecipient);
                     if (mPreviousExternalVibrations.size() > mPreviousVibrationsLimit) {
                         mPreviousExternalVibrations.removeFirst();
                     }
@@ -1514,6 +1517,8 @@
         public void onExternalVibrationStop(ExternalVibration vib) {
             synchronized (mLock) {
                 if (vib.equals(mCurrentExternalVibration)) {
+                    mCurrentExternalVibration.unlinkToDeath(mCurrentExternalDeathRecipient);
+                    mCurrentExternalDeathRecipient = null;
                     mCurrentExternalVibration = null;
                     setVibratorUnderExternalControl(false);
                     if (DEBUG) {
@@ -1522,6 +1527,14 @@
                 }
             }
         }
+
+        private class ExternalVibrationDeathRecipient implements IBinder.DeathRecipient {
+            public void binderDied() {
+                synchronized (mLock) {
+                    onExternalVibrationStop(mCurrentExternalVibration);
+                }
+            }
+        }
     }
 
     private final class VibratorShellCommand extends ShellCommand {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c5fc5c8..f14a3fd 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -547,6 +547,7 @@
     private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
 
     private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
+    private static final int JAVA_DUMP_MINIMUM_SIZE = 100; // 100 bytes.
 
     OomAdjuster mOomAdjuster;
     final LowMemDetector mLowMemDetector;
@@ -3805,9 +3806,28 @@
      */
     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
         final long timeStart = SystemClock.elapsedRealtime();
-        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
-            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
-                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
+        boolean javaSuccess = Debug.dumpJavaBacktraceToFileTimeout(pid, fileName,
+                (int) (timeoutMs / 1000));
+        if (javaSuccess) {
+            // Check that something is in the file, actually. Try-catch should not be necessary,
+            // but better safe than sorry.
+            try {
+                long size = new File(fileName).length();
+                if (size < JAVA_DUMP_MINIMUM_SIZE) {
+                    Slog.w(TAG, "Successfully created Java ANR file is empty!");
+                    javaSuccess = false;
+                }
+            } catch (Exception e) {
+                Slog.w(TAG, "Unable to get ANR file size", e);
+                javaSuccess = false;
+            }
+        }
+        if (!javaSuccess) {
+            Slog.w(TAG, "Dumping Java threads failed, initiating native stack dump.");
+            if (!Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
+                    (NATIVE_DUMP_TIMEOUT_MS / 1000))) {
+                Slog.w(TAG, "Native stack dump failed!");
+            }
         }
 
         return SystemClock.elapsedRealtime() - timeStart;
@@ -5375,34 +5395,13 @@
 
     @Override
     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
-        if (!(sender instanceof PendingIntentRecord)) {
-            return;
-        }
-        boolean isCancelled;
-        synchronized(this) {
-            PendingIntentRecord pendingIntent = (PendingIntentRecord) sender;
-            isCancelled = pendingIntent.canceled;
-            if (!isCancelled) {
-                pendingIntent.registerCancelListenerLocked(receiver);
-            }
-        }
-        if (isCancelled) {
-            try {
-                receiver.send(Activity.RESULT_CANCELED, null);
-            } catch (RemoteException e) {
-            }
-        }
+        mPendingIntentController.registerIntentSenderCancelListener(sender, receiver);
     }
 
     @Override
     public void unregisterIntentSenderCancelListener(IIntentSender sender,
             IResultReceiver receiver) {
-        if (!(sender instanceof PendingIntentRecord)) {
-            return;
-        }
-        synchronized(this) {
-            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
-        }
+        mPendingIntentController.unregisterIntentSenderCancelListener(sender, receiver);
     }
 
     @Override
@@ -17679,13 +17678,8 @@
         @Override
         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
                 long duration) {
-            if (!(target instanceof PendingIntentRecord)) {
-                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
-                return;
-            }
-            synchronized (ActivityManagerService.this) {
-                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
-            }
+            mPendingIntentController.setPendingIntentWhitelistDuration(target, whitelistToken,
+                    duration);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/am/PendingIntentController.java b/services/core/java/com/android/server/am/PendingIntentController.java
index a5d4738..d75591c 100644
--- a/services/core/java/com/android/server/am/PendingIntentController.java
+++ b/services/core/java/com/android/server/am/PendingIntentController.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
+
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
@@ -39,6 +40,7 @@
 import android.os.UserHandle;
 import android.util.ArrayMap;
 import android.util.Slog;
+
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
@@ -242,6 +244,47 @@
         }
     }
 
+    void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
+        if (!(sender instanceof PendingIntentRecord)) {
+            return;
+        }
+        boolean isCancelled;
+        synchronized (mLock) {
+            PendingIntentRecord pendingIntent = (PendingIntentRecord) sender;
+            isCancelled = pendingIntent.canceled;
+            if (!isCancelled) {
+                pendingIntent.registerCancelListenerLocked(receiver);
+            }
+        }
+        if (isCancelled) {
+            try {
+                receiver.send(Activity.RESULT_CANCELED, null);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    void unregisterIntentSenderCancelListener(IIntentSender sender,
+            IResultReceiver receiver) {
+        if (!(sender instanceof PendingIntentRecord)) {
+            return;
+        }
+        synchronized (mLock) {
+            ((PendingIntentRecord) sender).unregisterCancelListenerLocked(receiver);
+        }
+    }
+
+    void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
+            long duration) {
+        if (!(target instanceof PendingIntentRecord)) {
+            Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
+            return;
+        }
+        synchronized (mLock) {
+            ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
+        }
+    }
+
     private void makeIntentSenderCanceled(PendingIntentRecord rec) {
         rec.canceled = true;
         final RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 943fe75..d64a2c2 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -63,7 +63,6 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.GraphicsEnvironment;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -705,16 +704,6 @@
         return prefix + "+" + Integer.toString(diff);
     }
 
-    private static boolean shouldUseSystemGraphicsDriver(Context context, Bundle coreSettings,
-            ApplicationInfo applicationInfo) {
-        final boolean shouldUseGameDriver =
-                GraphicsEnvironment.shouldUseGameDriver(context, coreSettings, applicationInfo);
-        final boolean shouldUseAngle =
-                GraphicsEnvironment.shouldUseAngle(context, coreSettings,
-                    applicationInfo.packageName);
-        return !shouldUseGameDriver && !shouldUseAngle;
-    }
-
     public static String makeOomAdjString(int setAdj, boolean compact) {
         if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
             return buildOomTag("cch", "cch", "   ", setAdj,
@@ -1811,8 +1800,6 @@
             String seInfo, String requiredAbi, String instructionSet, String invokeWith,
             long startTime) {
         try {
-            final boolean useSystemGraphicsDriver = shouldUseSystemGraphicsDriver(mService.mContext,
-                    mService.mCoreSettingsObserver.getCoreSettingsLocked(), app.info);
             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                     app.processName);
             checkSlow(startTime, "startProcess: asking zygote to start proc");
@@ -1822,7 +1809,6 @@
                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                         app.info.dataDir, null, app.info.packageName,
-                        useSystemGraphicsDriver,
                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
             } else if (hostingRecord.usesAppZygote()) {
                 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
@@ -1831,14 +1817,13 @@
                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                         app.info.dataDir, null, app.info.packageName,
-                        /*useUsapPool=*/ false, useSystemGraphicsDriver,
+                        /*useUsapPool=*/ false,
                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
             } else {
                 startResult = Process.start(entryPoint,
                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                         app.info.dataDir, invokeWith, app.info.packageName,
-                        useSystemGraphicsDriver,
                         new String[] {PROC_START_SEQ_IDENT + app.startSeq});
             }
             checkSlow(startTime, "startProcess: returned from zygote!");
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index e43c548..5ae5113 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1016,6 +1016,7 @@
             sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
             sendEnabledSurroundFormats(mContentResolver, true);
             updateAssistantUId(true);
+            updateRttEanbled(mContentResolver);
         }
         synchronized (mAccessibilityServiceUidsLock) {
             AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
@@ -1480,6 +1481,12 @@
         }
     }
 
+    private void updateRttEanbled(ContentResolver cr) {
+        final boolean rttEnabled = Settings.Secure.getIntForUser(cr,
+                    Settings.Secure.RTT_CALLING_MODE, 0, UserHandle.USER_CURRENT) != 0;
+        AudioSystem.setRttEnabled(rttEnabled);
+    }
+
     private void readPersistedSettings() {
         final ContentResolver cr = mContentResolver;
 
@@ -1524,6 +1531,7 @@
             sendEncodedSurroundMode(cr, "readPersistedSettings");
             sendEnabledSurroundFormats(cr, true);
             updateAssistantUId(true);
+            updateRttEanbled(cr);
         }
 
         mMuteAffectedStreams = System.getIntForUser(cr,
@@ -5502,6 +5510,8 @@
 
             mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
                     Settings.Secure.VOICE_INTERACTION_SERVICE), false, this);
+            mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.RTT_CALLING_MODE), false, this);
         }
 
         @Override
@@ -5525,6 +5535,7 @@
                 updateEncodedSurroundOutput();
                 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged);
                 updateAssistantUId(false);
+                updateRttEanbled(mContentResolver);
             }
         }
 
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index 7689bd2..65dac8b 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -247,10 +247,20 @@
             mVerb = VERB_BINDING;
             scheduleOpTimeOutLocked();
             final Intent intent = new Intent().setComponent(job.getServiceComponent());
-            boolean binding = mContext.bindServiceAsUser(intent, this,
-                    Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
-                    | Context.BIND_NOT_VISIBLE | Context.BIND_ADJUST_BELOW_PERCEPTIBLE,
-                    new UserHandle(job.getUserId()));
+            boolean binding = false;
+            try {
+                binding = mContext.bindServiceAsUser(intent, this,
+                        Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
+                        | Context.BIND_NOT_VISIBLE | Context.BIND_ADJUST_BELOW_PERCEPTIBLE,
+                        new UserHandle(job.getUserId()));
+            } catch (SecurityException e) {
+                // Some permission policy, for example INTERACT_ACROSS_USERS and
+                // android:singleUser, can result in a SecurityException being thrown from
+                // bindServiceAsUser().  If this happens, catch it and fail gracefully.
+                Slog.w(TAG, "Job service " + job.getServiceComponent().getShortClassName()
+                        + " cannot be executed: " + e.getMessage());
+                binding = false;
+            }
             if (!binding) {
                 if (DEBUG) {
                     Slog.d(TAG, job.getServiceComponent().getShortClassName() + " unavailable.");
diff --git a/services/core/java/com/android/server/location/GnssVisibilityControl.java b/services/core/java/com/android/server/location/GnssVisibilityControl.java
index 65bd5c6..3ee9419 100644
--- a/services/core/java/com/android/server/location/GnssVisibilityControl.java
+++ b/services/core/java/com/android/server/location/GnssVisibilityControl.java
@@ -78,7 +78,6 @@
     private final Handler mHandler;
     private final Context mContext;
     private final GpsNetInitiatedHandler mNiHandler;
-    private final Notification mEmergencyLocationUserNotification;
 
     private boolean mIsGpsEnabled;
 
@@ -107,7 +106,6 @@
         mNiHandler = niHandler;
         mAppOps = mContext.getSystemService(AppOpsManager.class);
         mPackageManager = mContext.getPackageManager();
-        mEmergencyLocationUserNotification = createEmergencyLocationUserNotification(mContext);
 
         // Complete initialization as the first event to run in mHandler thread. After that,
         // all object state read/update events run in the mHandler thread.
@@ -632,13 +630,15 @@
         }
 
         notificationManager.notifyAsUser(/* tag= */ null, /* notificationId= */ 0,
-                mEmergencyLocationUserNotification, UserHandle.ALL);
+                createEmergencyLocationUserNotification(mContext), UserHandle.ALL);
     }
 
     private static Notification createEmergencyLocationUserNotification(Context context) {
-        String firstLineText = context.getString(R.string.gpsNotifTitle);
-        String secondLineText =  context.getString(R.string.global_action_emergency);
-        String accessibilityServicesText = firstLineText + " (" + secondLineText + ")";
+        // NOTE: Do not reuse the returned notification object as it will not reflect
+        //       changes to notification text when the system language is changed.
+        final String firstLineText = context.getString(R.string.gpsNotifTitle);
+        final String secondLineText =  context.getString(R.string.global_action_emergency);
+        final String accessibilityServicesText = firstLineText + " (" + secondLineText + ")";
         return new Notification.Builder(context, SystemNotificationChannels.NETWORK_ALERTS)
                 .setSmallIcon(com.android.internal.R.drawable.stat_sys_gps_on)
                 .setWhen(0)
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 1d01a84..6882afb 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -19,6 +19,7 @@
 import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.MODE_DEFAULT;
 import static android.app.AppOpsManager.MODE_ERRORED;
+import static android.app.AppOpsManager.MODE_FOREGROUND;
 import static android.app.AppOpsManager.MODE_IGNORED;
 import static android.app.AppOpsManager.OP_NONE;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
@@ -290,7 +291,7 @@
          *
          * Currently, only used by the restricted permissions logic.
          *
-         * @see #syncRestrictedOps
+         * @see #syncPackages
          */
         private final @NonNull ArrayList<OpToRestrict> mOpsToDefault = new ArrayList<>();
 
@@ -299,16 +300,14 @@
          *
          * Currently, only used by the restricted permissions logic.
          *
-         * @see #syncRestrictedOps
+         * @see #syncPackages
          */
         private final @NonNull ArrayList<OpToUnrestrict> mOpsToAllowIfDefault = new ArrayList<>();
 
         /**
          * All ops that need to be flipped to allow.
          *
-         * Currently, only used by the restricted permissions logic.
-         *
-         * @see #syncRestrictedOps
+         * @see #syncPackages
          */
         private final @NonNull ArrayList<OpToUnrestrict> mOpsToAllow = new ArrayList<>();
 
@@ -317,16 +316,25 @@
          *
          * Currently, only used by the restricted permissions logic.
          *
-         * @see #syncRestrictedOps
+         * @see #syncPackages
          */
         private final @NonNull ArrayList<OpToUnrestrict> mOpsToIgnoreIfDefault = new ArrayList<>();
 
         /**
-         * All foreground permissions
+         * All ops that need to be flipped to ignore.
          *
-         * @see #syncOpsOfFgPermissions()
+         * @see #syncPackages
          */
-        private final @NonNull ArrayList<FgPermission> mFgPermOps = new ArrayList<>();
+        private final @NonNull ArrayList<OpToUnrestrict> mOpsToIgnore = new ArrayList<>();
+
+        /**
+         * All ops that need to be flipped to foreground.
+         *
+         * Currently, only used by the foreground/background permissions logic.
+         *
+         * @see #syncPackages
+         */
+        private final @NonNull ArrayList<OpToUnrestrict> mOpsToForeground = new ArrayList<>();
 
         PermissionToOpSynchroniser(@NonNull Context context) {
             mContext = context;
@@ -335,11 +343,11 @@
         }
 
         /**
-         * Set app ops that belong to restricted permissions.
+         * Set app ops that were added in {@link #addPackage}.
          *
          * <p>This processes ops previously added by {@link #addOpIfRestricted}
          */
-        private void syncRestrictedOps() {
+        private void syncPackages() {
             final int allowCount = mOpsToAllow.size();
             for (int i = 0; i < allowCount; i++) {
                 final OpToUnrestrict op = mOpsToAllow.get(i);
@@ -350,6 +358,16 @@
                 final OpToUnrestrict op = mOpsToAllowIfDefault.get(i);
                 setUidModeAllowedIfDefault(op.code, op.uid, op.packageName);
             }
+            final int foregroundCount = mOpsToForeground.size();
+            for (int i = 0; i < foregroundCount; i++) {
+                final OpToUnrestrict op = mOpsToForeground.get(i);
+                setUidModeForeground(op.code, op.uid);
+            }
+            final int ignoreCount = mOpsToIgnore.size();
+            for (int i = 0; i < ignoreCount; i++) {
+                final OpToUnrestrict op = mOpsToIgnore.get(i);
+                setUidModeIgnored(op.code, op.uid);
+            }
             final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
             for (int i = 0; i < ignoreIfDefaultCount; i++) {
                 final OpToUnrestrict op = mOpsToIgnoreIfDefault.get(i);
@@ -363,46 +381,8 @@
         }
 
         /**
-         * Set app ops that belong to restricted permissions.
-         *
-         * <p>This processed ops previously added by {@link #addOpIfRestricted}
-         */
-        private void syncOpsOfFgPermissions() {
-            int numFgPermOps = mFgPermOps.size();
-            for (int i = 0; i < numFgPermOps; i++) {
-                FgPermission perm = mFgPermOps.get(i);
-
-                if (mPackageManager.checkPermission(perm.fgPermissionName, perm.packageName)
-                        == PackageManager.PERMISSION_GRANTED) {
-                    if (mPackageManager.checkPermission(perm.bgPermissionName, perm.packageName)
-                            == PackageManager.PERMISSION_GRANTED) {
-                        mAppOpsManager.setUidMode(
-                                AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
-                                AppOpsManager.MODE_ALLOWED);
-                    } else {
-                        mAppOpsManager.setUidMode(
-                                AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
-                                AppOpsManager.MODE_FOREGROUND);
-                    }
-                } else {
-                    mAppOpsManager.setUidMode(
-                            AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid,
-                            AppOpsManager.MODE_IGNORED);
-                }
-            }
-        }
-
-        /**
-         * Synchronize all previously {@link #addPackage added} packages.
-         */
-        void syncPackages() {
-            syncRestrictedOps();
-            syncOpsOfFgPermissions();
-        }
-
-        /**
          * Add op that belong to a restricted permission for later processing in
-         * {@link #syncRestrictedOps}.
+         * {@link #syncPackages()}.
          *
          * <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
          *
@@ -424,19 +404,29 @@
                     mContext.getUser()) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
 
             if (permissionInfo.isHardRestricted()) {
-                if (applyRestriction) {
-                    mOpsToDefault.add(new OpToRestrict(uid, opCode));
-                } else {
-                    mOpsToAllowIfDefault.add(new OpToUnrestrict(uid, pkg.packageName, opCode));
+                if (opCode != OP_NONE) {
+                    if (applyRestriction) {
+                        mOpsToDefault.add(new OpToRestrict(uid, opCode));
+                    } else {
+                        mOpsToAllowIfDefault.add(new OpToUnrestrict(uid, pkg.packageName, opCode));
+                    }
                 }
             } else if (permissionInfo.isSoftRestricted()) {
                 final SoftRestrictedPermissionPolicy policy =
                         SoftRestrictedPermissionPolicy.forPermission(mContext, pkg.applicationInfo,
                                 permission);
 
-                final int op = policy.getAppOp();
+                if (opCode != OP_NONE) {
+                    if (policy.canBeGranted()) {
+                        mOpsToAllowIfDefault.add(new OpToUnrestrict(uid, pkg.packageName, opCode));
+                    } else {
+                        mOpsToDefault.add(new OpToRestrict(uid, opCode));
+                    }
+                }
+
+                final int op = policy.resolveAppOp();
                 if (op != OP_NONE) {
-                    switch (policy.getAppOpMode()) {
+                    switch (policy.getDesiredOpMode()) {
                         case MODE_DEFAULT:
                             mOpsToDefault.add(new OpToRestrict(uid, op));
                             break;
@@ -444,16 +434,22 @@
                             if (policy.shouldSetAppOpIfNotDefault()) {
                                 mOpsToAllow.add(new OpToUnrestrict(uid, pkg.packageName, op));
                             } else {
-                                mOpsToAllowIfDefault.add(new OpToUnrestrict(uid, pkg.packageName,
-                                        op));
+                                mOpsToAllowIfDefault.add(
+                                        new OpToUnrestrict(uid, pkg.packageName,
+                                                op));
                             }
                             break;
+                        case MODE_FOREGROUND:
+                            Slog.wtf(LOG_TAG,
+                                    "Setting appop to foreground is not implemented");
+                            break;
                         case MODE_IGNORED:
                             if (policy.shouldSetAppOpIfNotDefault()) {
-                                Slog.wtf(LOG_TAG, "Always ignoring appops is not implemented");
+                                mOpsToIgnore.add(new OpToUnrestrict(uid, pkg.packageName, op));
                             } else {
-                                mOpsToIgnoreIfDefault.add(new OpToUnrestrict(uid, pkg.packageName,
-                                        op));
+                                mOpsToIgnoreIfDefault.add(
+                                        new OpToUnrestrict(uid, pkg.packageName,
+                                                op));
                             }
                             break;
                         case MODE_ERRORED:
@@ -463,19 +459,59 @@
             }
         }
 
+        /**
+         * Add op that belong to a foreground permission for later processing in
+         * {@link #syncPackages()}.
+         *
+         * <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
+         *
+         * @param permissionInfo The permission that is currently looked at
+         * @param pkg The package looked at
+         */
         private void addOpIfFgPermissions(@NonNull PermissionInfo permissionInfo,
                 @NonNull PackageInfo pkg) {
-            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
-                // Pre-M apps do not store their fg/bg state in the permissions
+            final String bgPermissionName = permissionInfo.backgroundPermission;
+
+            if (bgPermissionName == null) {
                 return;
             }
 
-            if (permissionInfo.backgroundPermission == null) {
-                return;
-            }
+            final String permission = permissionInfo.name;
+            final int opCode = AppOpsManager.permissionToOpCode(permission);
+            final String pkgName = pkg.packageName;
+            final int uid = pkg.applicationInfo.uid;
 
-            mFgPermOps.add(new FgPermission(pkg.applicationInfo.uid, pkg.packageName,
-                    permissionInfo.name, permissionInfo.backgroundPermission));
+            if (mPackageManager.checkPermission(permission, pkgName)
+                    == PackageManager.PERMISSION_GRANTED) {
+                boolean isBgHardRestricted = false;
+                try {
+                    final PermissionInfo bgPermInfo = mPackageManager.getPermissionInfo(
+                            bgPermissionName, 0);
+
+                    if (bgPermInfo.isSoftRestricted()) {
+                        Slog.wtf(LOG_TAG, "Support for soft restricted background permissions not "
+                                + "implemented");
+                    }
+
+                    isBgHardRestricted =
+                            bgPermInfo.isHardRestricted() && (mPackageManager.getPermissionFlags(
+                                    bgPermissionName, pkgName, UserHandle.getUserHandleForUid(uid))
+                                    & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
+                } catch (NameNotFoundException e) {
+                    Slog.w(LOG_TAG, "Cannot read permission state of " + bgPermissionName, e);
+                }
+
+                final boolean isBgPermGranted = mPackageManager.checkPermission(bgPermissionName,
+                        pkgName) == PackageManager.PERMISSION_GRANTED;
+
+                if (!isBgHardRestricted && isBgPermGranted) {
+                    mOpsToAllow.add(new OpToUnrestrict(uid, pkgName, opCode));
+                } else {
+                    mOpsToForeground.add(new OpToUnrestrict(uid, pkgName, opCode));
+                }
+            } else {
+                mOpsToIgnore.add(new OpToUnrestrict(uid, pkgName, opCode));
+            }
         }
 
         /**
@@ -525,14 +561,33 @@
             mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_ALLOWED);
         }
 
+        private void setUidModeForeground(int opCode, int uid) {
+            mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_FOREGROUND);
+        }
+
         private void setUidModeIgnoredIfDefault(int opCode, int uid, @NonNull String packageName) {
             setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_IGNORED, packageName);
         }
 
+        private void setUidModeIgnored(int opCode, int uid) {
+            mAppOpsManager.setUidMode(opCode, uid, MODE_IGNORED);
+        }
+
         private void setUidModeIfDefault(int opCode, int uid, int mode,
                 @NonNull String packageName) {
-            final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
-                    .opToPublicName(opCode), uid, packageName);
+            final int currentMode;
+            try {
+                currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
+                        .opToPublicName(opCode), uid, packageName);
+            } catch (SecurityException e) {
+                // This might happen if the app was uninstalled in between the add and sync step.
+                // In this case the package name cannot be resolved inside appops service and hence
+                // the uid does not match.
+                Slog.w(LOG_TAG, "Cannot set mode of uid=" + uid + " op=" + opCode + " to " + mode,
+                        e);
+                return;
+            }
+
             if (currentMode == MODE_DEFAULT) {
                 mAppOpsManager.setUidMode(opCode, uid, mode);
             }
@@ -563,21 +618,6 @@
                 this.code = code;
             }
         }
-
-        private class FgPermission {
-            final int uid;
-            final @NonNull String packageName;
-            final @NonNull String fgPermissionName;
-            final @NonNull String bgPermissionName;
-
-            private FgPermission(int uid, @NonNull String packageName,
-                    @NonNull String fgPermissionName, @NonNull String bgPermissionName) {
-                this.uid = uid;
-                this.packageName = packageName;
-                this.fgPermissionName = fgPermissionName;
-                this.bgPermissionName = bgPermissionName;
-            }
-        }
     }
 
     private class Internal extends PermissionPolicyInternal {
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
index e19b708..d447617 100644
--- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -33,7 +33,6 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.os.Build;
-import android.util.Log;
 
 /**
  * The behavior of soft restricted permissions is different for each permission. This class collects
@@ -43,8 +42,6 @@
  * {@link com.android.packageinstaller.permission.utils.SoftRestrictedPermissionPolicy}
  */
 public abstract class SoftRestrictedPermissionPolicy {
-    private static final String LOG_TAG = SoftRestrictedPermissionPolicy.class.getSimpleName();
-
     private static final int FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT =
             FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT
                     | FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT
@@ -53,12 +50,12 @@
     private static final SoftRestrictedPermissionPolicy DUMMY_POLICY =
             new SoftRestrictedPermissionPolicy() {
                 @Override
-                public int getAppOp() {
+                public int resolveAppOp() {
                     return OP_NONE;
                 }
 
                 @Override
-                public int getAppOpMode() {
+                public int getDesiredOpMode() {
                     return MODE_DEFAULT;
                 }
 
@@ -100,12 +97,12 @@
 
                 return new SoftRestrictedPermissionPolicy() {
                     @Override
-                    public int getAppOp() {
+                    public int resolveAppOp() {
                         return OP_LEGACY_STORAGE;
                     }
 
                     @Override
-                    public int getAppOpMode() {
+                    public int getDesiredOpMode() {
                         if (applyRestriction) {
                             return MODE_DEFAULT;
                         } else if (hasRequestedLegacyExternalStorage) {
@@ -119,7 +116,7 @@
                     public boolean shouldSetAppOpIfNotDefault() {
                         // Do not switch from allowed -> ignored as this would mean to retroactively
                         // turn on isolated storage. This will make the app loose all its files.
-                        return getAppOpMode() != MODE_IGNORED;
+                        return getDesiredOpMode() != MODE_IGNORED;
                     }
 
                     @Override
@@ -127,10 +124,6 @@
                         if (isWhiteListed || targetSDK >= Build.VERSION_CODES.Q) {
                             return true;
                         } else {
-                            Log.w(LOG_TAG, permission + " for " + appInfo.packageName
-                                    + " is not whitelisted and targetSDK " + targetSDK + "<"
-                                    + Build.VERSION_CODES.Q);
-
                             return false;
                         }
                     }
@@ -145,16 +138,16 @@
      * @return An app op to be changed based on the state of the permission or
      * {@link AppOpsManager#OP_NONE} if not app-op should be set.
      */
-    public abstract int getAppOp();
+    public abstract int resolveAppOp();
 
     /**
-     * @return The mode the {@link #getAppOp() app op} should be in.
+     * @return The mode the {@link #resolveAppOp() app op} should be in.
      */
-    public abstract @AppOpsManager.Mode int getAppOpMode();
+    public abstract @AppOpsManager.Mode int getDesiredOpMode();
 
     /**
-     * @return If the {@link #getAppOp() app op} should be set even if the app-op is currently not
-     * {@link AppOpsManager#MODE_DEFAULT}.
+     * @return If the {@link #resolveAppOp() app op} should be set even if the app-op is currently
+     * not {@link AppOpsManager#MODE_DEFAULT}.
      */
     public abstract boolean shouldSetAppOpIfNotDefault();
 
diff --git a/services/core/java/com/android/server/policy/TEST_MAPPING b/services/core/java/com/android/server/policy/TEST_MAPPING
index 02b0e21..c7f8c07 100644
--- a/services/core/java/com/android/server/policy/TEST_MAPPING
+++ b/services/core/java/com/android/server/policy/TEST_MAPPING
@@ -35,6 +35,14 @@
           "include-filter": "android.permission2.cts.RestrictedPermissionsTest"
         }
       ]
+    },
+    {
+      "name": "CtsPermissionTestCases",
+      "options": [
+        {
+          "include-filter": "android.permission.cts.SplitPermissionTest"
+        }
+      ]
     }
   ],
   "postsubmit": [
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 5c55c2e..0a88eef 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1419,6 +1419,13 @@
                     stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
                             null /* intentResultData */, "startActivity", true /* oomAdj */);
                 }
+
+                // Stack should also be detached from display and be removed if it's empty.
+                if (startedActivityStack != null && startedActivityStack.isAttached()
+                        && startedActivityStack.numActivities() == 0
+                        && !startedActivityStack.isActivityTypeHome()) {
+                    startedActivityStack.remove();
+                }
             }
             mService.mWindowManager.continueSurfaceLayout();
         }
@@ -2289,15 +2296,17 @@
     }
 
     private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
+        if (mRestrictedBgActivity && (mReuseTask == null || !mReuseTask.containsAppUid(mCallingUid))
+                && handleBackgroundActivityAbort(mStartActivity)) {
+            return START_ABORTED;
+        }
+
         mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
 
         // Do no move the target stack to front yet, as we might bail if
         // isLockTaskModeViolation fails below.
 
         if (mReuseTask == null) {
-            if (mRestrictedBgActivity && handleBackgroundActivityAbort(mStartActivity)) {
-                return START_ABORTED;
-            }
             final TaskRecord task = mTargetStack.createTaskRecord(
                     mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId),
                     mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
@@ -2310,11 +2319,6 @@
             if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
                     + " in new task " + mStartActivity.getTaskRecord());
         } else {
-            if (mRestrictedBgActivity && !mReuseTask.containsAppUid(mCallingUid)) {
-                if (handleBackgroundActivityAbort(mStartActivity)) {
-                    return START_ABORTED;
-                }
-            }
             addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
         }
 
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 4a9a3f7..60cfe14 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -540,6 +540,14 @@
                 // If the app was already visible, don't reset the waitingToShow state.
                 if (isHidden()) {
                     waitingToShow = true;
+
+                    // Let's reset the draw state in order to prevent the starting window to be
+                    // immediately dismissed when the app still has the surface.
+                    forAllWindows(w -> {
+                            if (w.mAttrs.type != TYPE_APPLICATION_STARTING) {
+                                w.mWinAnimator.resetDrawState();
+                            }
+                        },  true /* traverseTopToBottom */);
                 }
             }
 
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index de9d769..c6c9e1b 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1548,7 +1548,8 @@
      */
     boolean isInteresting() {
         return mAppToken != null && !mAppDied
-                && (!mAppToken.isFreezingScreen() || !mAppFreezing);
+                && (!mAppToken.isFreezingScreen() || !mAppFreezing)
+                && mViewVisibility == View.VISIBLE;
     }
 
     /**
diff --git a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl b/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl
index 1e688d0..30893b2 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface IIpMemoryStore {
   oneway void storeNetworkAttributes(String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnStatusListener listener);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl b/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl
index cf02c26..535ae2c 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface IIpMemoryStoreCallbacks {
   oneway void onIpMemoryStoreFetched(in android.net.IIpMemoryStore ipMemoryStore);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl
index 291dbef..6d2dc0c 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 parcelable Blob {
   byte[] data;
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
index 52f40d4..48c1fb8 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnBlobRetrievedListener {
   oneway void onBlobRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in String name, in android.net.ipmemorystore.Blob data);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
index 7853514..aebc724 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnL2KeyResponseListener {
   oneway void onL2KeyResponse(in android.net.ipmemorystore.StatusParcelable status, in String l2Key);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
index 3dd2ae6..b66db5a 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnNetworkAttributesRetrievedListener {
   oneway void onNetworkAttributesRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
index 46d4ecb..e9f2db4 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnSameL3NetworkResponseListener {
   oneway void onSameL3NetworkResponse(in android.net.ipmemorystore.StatusParcelable status, in android.net.ipmemorystore.SameL3NetworkResponseParcelable response);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl
index 54e654b..49172ce 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 interface IOnStatusListener {
   oneway void onComplete(in android.net.ipmemorystore.StatusParcelable status);
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
index 9531ea3..188db20 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 parcelable NetworkAttributesParcelable {
   byte[] assignedV4Address;
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
index 414272b..7a2ed48 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 parcelable SameL3NetworkResponseParcelable {
   String l2Key1;
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl
index 92c6779..d9b0678 100644
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl
+++ b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ipmemorystore;
 parcelable StatusParcelable {
   int resultCode;
diff --git a/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl b/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl
index 31891de..07ff321 100644
--- a/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable DhcpResultsParcelable {
   android.net.StaticIpConfiguration baseConfiguration;
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl b/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl
index 029968b..8aa68bd 100644
--- a/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl
+++ b/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface INetworkMonitor {
   oneway void start();
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl
index ee9871d..ea93729 100644
--- a/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl
+++ b/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface INetworkMonitorCallbacks {
   oneway void onNetworkMonitorCreated(in android.net.INetworkMonitor networkMonitor);
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl b/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl
index 7da11e4..e3a83d1 100644
--- a/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl
+++ b/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface INetworkStackConnector {
   oneway void makeDhcpServer(in String ifName, in android.net.dhcp.DhcpServingParamsParcel params, in android.net.dhcp.IDhcpServerCallbacks cb);
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl b/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl
index f6ca6f7..3112a08 100644
--- a/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl
+++ b/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 interface INetworkStackStatusCallback {
   oneway void onStatusAvailable(int statusCode);
diff --git a/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl b/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl
index c80a787..f846b26 100644
--- a/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable InitialConfigurationParcelable {
   android.net.LinkAddress[] ipAddresses;
diff --git a/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl
index 65de883..de75940 100644
--- a/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable NattKeepalivePacketDataParcelable {
   byte[] srcAddress;
diff --git a/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl b/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl
index 2de790b..cf0fbce9 100644
--- a/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl
+++ b/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable PrivateDnsConfigParcel {
   String hostname;
diff --git a/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl b/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl
index 3a6c304..c0f2d4d 100644
--- a/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable ProvisioningConfigurationParcelable {
   boolean enableIPv4;
diff --git a/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl
index e121c06..5926794 100644
--- a/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl
+++ b/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net;
 parcelable TcpKeepalivePacketDataParcelable {
   byte[] srcAddress;
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl
index 67193ae..7ab156f 100644
--- a/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl
+++ b/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.dhcp;
 parcelable DhcpServingParamsParcel {
   int serverAddr;
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl
index 9143158..d281ecf 100644
--- a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl
+++ b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.dhcp;
 interface IDhcpServer {
   oneway void start(in android.net.INetworkStackStatusCallback cb);
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl
index dcc4489..98be0ab 100644
--- a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl
+++ b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.dhcp;
 interface IDhcpServerCallbacks {
   oneway void onDhcpServerCreated(int statusCode, in android.net.dhcp.IDhcpServer server);
diff --git a/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl b/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl
index 176a5ce..85c8676 100644
--- a/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl
+++ b/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ip;
 interface IIpClient {
   oneway void completedPreDhcpAction();
diff --git a/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl
index d6bc808..7fe39ed 100644
--- a/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl
+++ b/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl
@@ -1,3 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
+// try to edit this file. It looks like you are doing that because you have
+// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
+// function from an interface or a field from a parcelable and it broke the
+// build. That breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
 package android.net.ip;
 interface IIpClientCallbacks {
   oneway void onIpClientCreated(in android.net.ip.IIpClient ipClient);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index bee3b2b..397d215 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.notification;
 
+import static android.app.Notification.EXTRA_SMALL_ICON;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE;
@@ -24,6 +25,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.mock;
@@ -33,8 +35,13 @@
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.PendingIntent;
+import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
 import android.os.Binder;
+import android.os.Build;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.service.notification.NotificationListenerService;
@@ -44,20 +51,34 @@
 import android.service.notification.SnoozeCriterion;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import androidx.test.runner.AndroidJUnit4;
-
 import com.android.server.UiServiceTestCase;
 
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import androidx.test.runner.AndroidJUnit4;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class NotificationListenerServiceTest extends UiServiceTestCase {
 
+    int targetSdk = 0;
+
+    @Before
+    public void setUp() {
+        targetSdk = mContext.getApplicationInfo().targetSdkVersion;
+    }
+
+    @After
+    public void tearDown() {
+        mContext.getApplicationInfo().targetSdkVersion = targetSdk;
+    }
+
     @Test
     public void testGetActiveNotifications_notNull() throws Exception {
         TestListenerService service = new TestListenerService();
@@ -109,17 +130,6 @@
         assertEquals(nru, nru1);
     }
 
-    private void detailedAssertEquals(RankingMap a, RankingMap b) {
-        Ranking arank = new Ranking();
-        Ranking brank = new Ranking();
-        assertArrayEquals(a.getOrderedKeys(), b.getOrderedKeys());
-        for (String key : a.getOrderedKeys()) {
-            a.getRanking(key, arank);
-            b.getRanking(key, brank);
-            detailedAssertEquals("ranking for key <" + key + ">", arank, brank);
-        }
-    }
-
     // Tests parceling of RankingMap and RankingMap.equals
     @Test
     public void testRankingMap_parcel() {
@@ -133,28 +143,6 @@
         assertEquals(rmap, rmap1);
     }
 
-    private void detailedAssertEquals(String comment, Ranking a, Ranking b) {
-        assertEquals(comment, a.getKey(), b.getKey());
-        assertEquals(comment, a.getRank(), b.getRank());
-        assertEquals(comment, a.matchesInterruptionFilter(), b.matchesInterruptionFilter());
-        assertEquals(comment, a.getVisibilityOverride(), b.getVisibilityOverride());
-        assertEquals(comment, a.getSuppressedVisualEffects(), b.getSuppressedVisualEffects());
-        assertEquals(comment, a.getImportance(), b.getImportance());
-        assertEquals(comment, a.getImportanceExplanation(), b.getImportanceExplanation());
-        assertEquals(comment, a.getOverrideGroupKey(), b.getOverrideGroupKey());
-        assertEquals(comment, a.getChannel(), b.getChannel());
-        assertEquals(comment, a.getAdditionalPeople(), b.getAdditionalPeople());
-        assertEquals(comment, a.getSnoozeCriteria(), b.getSnoozeCriteria());
-        assertEquals(comment, a.canShowBadge(), b.canShowBadge());
-        assertEquals(comment, a.getUserSentiment(), b.getUserSentiment());
-        assertEquals(comment, a.isSuspended(), b.isSuspended());
-        assertEquals(comment, a.getLastAudiblyAlertedMillis(), b.getLastAudiblyAlertedMillis());
-        assertEquals(comment, a.isNoisy(), b.isNoisy());
-        assertEquals(comment, a.getSmartReplies(), b.getSmartReplies());
-        assertEquals(comment, a.canBubble(), b.canBubble());
-        assertActionsEqual(a.getSmartActions(), b.getSmartActions());
-    }
-
     // Tests parceling of Ranking and Ranking.equals
     @Test
     public void testRanking_parcel() {
@@ -167,10 +155,6 @@
         assertEquals(ranking, ranking1);
     }
 
-    private void detailedAssertEquals(NotificationRankingUpdate a, NotificationRankingUpdate b) {
-        assertEquals(a.getRankingMap(), b.getRankingMap());
-    }
-
     // Tests NotificationRankingUpdate.equals(), and by extension, RankingMap and Ranking.
     @Test
     public void testRankingUpdate_equals() {
@@ -203,6 +187,49 @@
         assertNotEquals(nru, nru2);
     }
 
+    @Test
+    public void testLegacyIcons_preM() {
+        TestListenerService service = new TestListenerService();
+        service.attachBaseContext(mContext);
+        service.targetSdk = Build.VERSION_CODES.LOLLIPOP_MR1;
+
+        Bitmap largeIcon = Bitmap.createBitmap(100, 200, Bitmap.Config.RGB_565);
+
+        Notification n = new Notification.Builder(mContext, "channel")
+                .setSmallIcon(android.R.drawable.star_on)
+                .setLargeIcon(Icon.createWithBitmap(largeIcon))
+                .setContentTitle("test")
+                .build();
+
+        service.createLegacyIconExtras(n);
+
+        assertEquals(android.R.drawable.star_on, n.extras.getInt(EXTRA_SMALL_ICON));
+        assertEquals(android.R.drawable.star_on, n.icon);
+        assertNotNull(n.largeIcon);
+        assertNotNull(n.extras.getParcelable(Notification.EXTRA_LARGE_ICON));
+    }
+
+    @Test
+    public void testLegacyIcons_mPlus() {
+        TestListenerService service = new TestListenerService();
+        service.attachBaseContext(mContext);
+        service.targetSdk = Build.VERSION_CODES.M;
+
+        Bitmap largeIcon = Bitmap.createBitmap(100, 200, Bitmap.Config.RGB_565);
+
+        Notification n = new Notification.Builder(mContext, "channel")
+                .setSmallIcon(android.R.drawable.star_on)
+                .setLargeIcon(Icon.createWithBitmap(largeIcon))
+                .setContentTitle("test")
+                .build();
+
+        service.createLegacyIconExtras(n);
+
+        assertEquals(0, n.extras.getInt(EXTRA_SMALL_ICON));
+        assertNull(n.largeIcon);
+    }
+
+
     // Test data
 
     private String[] mKeys = new String[] { "key", "key1", "key2", "key3", "key4"};
@@ -346,8 +373,46 @@
         }
     }
 
+    private void detailedAssertEquals(NotificationRankingUpdate a, NotificationRankingUpdate b) {
+        assertEquals(a.getRankingMap(), b.getRankingMap());
+    }
+
+    private void detailedAssertEquals(String comment, Ranking a, Ranking b) {
+        assertEquals(comment, a.getKey(), b.getKey());
+        assertEquals(comment, a.getRank(), b.getRank());
+        assertEquals(comment, a.matchesInterruptionFilter(), b.matchesInterruptionFilter());
+        assertEquals(comment, a.getVisibilityOverride(), b.getVisibilityOverride());
+        assertEquals(comment, a.getSuppressedVisualEffects(), b.getSuppressedVisualEffects());
+        assertEquals(comment, a.getImportance(), b.getImportance());
+        assertEquals(comment, a.getImportanceExplanation(), b.getImportanceExplanation());
+        assertEquals(comment, a.getOverrideGroupKey(), b.getOverrideGroupKey());
+        assertEquals(comment, a.getChannel(), b.getChannel());
+        assertEquals(comment, a.getAdditionalPeople(), b.getAdditionalPeople());
+        assertEquals(comment, a.getSnoozeCriteria(), b.getSnoozeCriteria());
+        assertEquals(comment, a.canShowBadge(), b.canShowBadge());
+        assertEquals(comment, a.getUserSentiment(), b.getUserSentiment());
+        assertEquals(comment, a.isSuspended(), b.isSuspended());
+        assertEquals(comment, a.getLastAudiblyAlertedMillis(), b.getLastAudiblyAlertedMillis());
+        assertEquals(comment, a.isNoisy(), b.isNoisy());
+        assertEquals(comment, a.getSmartReplies(), b.getSmartReplies());
+        assertEquals(comment, a.canBubble(), b.canBubble());
+        assertActionsEqual(a.getSmartActions(), b.getSmartActions());
+    }
+
+    private void detailedAssertEquals(RankingMap a, RankingMap b) {
+        Ranking arank = new Ranking();
+        Ranking brank = new Ranking();
+        assertArrayEquals(a.getOrderedKeys(), b.getOrderedKeys());
+        for (String key : a.getOrderedKeys()) {
+            a.getRanking(key, arank);
+            b.getRanking(key, brank);
+            detailedAssertEquals("ranking for key <" + key + ">", arank, brank);
+        }
+    }
+
     public static class TestListenerService extends NotificationListenerService {
         private final IBinder binder = new LocalBinder();
+        public int targetSdk = 0;
 
         public TestListenerService() {
             mWrapper = mock(NotificationListenerWrapper.class);
@@ -369,5 +434,19 @@
                 return TestListenerService.this;
             }
         }
+
+        @Override
+        protected void attachBaseContext(Context base) {
+            super.attachBaseContext(base);
+        }
+
+        @Override
+        public ApplicationInfo getApplicationInfo() {
+            ApplicationInfo info = super.getApplicationInfo();
+            if (targetSdk != 0) {
+                info.targetSdkVersion = targetSdk;
+            }
+            return info;
+        }
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index 53b0add..4986a6d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -585,7 +585,10 @@
         }
 
         void tearDown() {
-            mHandlerThread.quitSafely();
+            // Make sure there are no running messages and then quit the thread so the next test
+            // won't be affected.
+            mHandlerThread.getThreadHandler().runWithScissors(mHandlerThread::quit,
+                    0 /* timeout */);
         }
     }
 
@@ -630,7 +633,8 @@
             mWindowManager = prepareMockWindowManager();
             mKeyguardController = mock(KeyguardController.class);
 
-            // Do not schedule idle timeouts
+            // Do not schedule idle that may touch methods outside the scope of the test.
+            doNothing().when(this).scheduleIdleLocked();
             doNothing().when(this).scheduleIdleTimeoutLocked(any());
             // unit test version does not handle launch wake lock
             doNothing().when(this).acquireLaunchWakelock();
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 5d39a2c..518da74 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -16,6 +16,8 @@
 
 package android.telephony;
 
+import static android.telephony.TelephonyManager.NETWORK_TYPE_BITMASK_UNKNOWN;
+
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -1605,6 +1607,12 @@
         }
     }
 
+    /** @hide */
+    public static int networkTypeToAccessNetworkType(@TelephonyManager.NetworkType
+            int networkType) {
+        return rilRadioTechnologyToAccessNetworkType(networkTypeToRilRadioTechnology(networkType));
+    }
+
     /**
      * Get current data network type.
      *
@@ -1730,6 +1738,36 @@
         return false;
     }
 
+    /**
+     *
+     * Returns whether the bearerBitmask includes a networkType that matches the accessNetworkType.
+     *
+     * The NetworkType refers to NetworkType in TelephonyManager. For example
+     * {@link TelephonyManager#NETWORK_TYPE_GPRS}.
+     *
+     * The accessNetworkType refers to {@link AccessNetworkType}.
+     *
+     * @hide
+     * */
+    public static boolean networkBitmaskHasAccessNetworkType(
+            @TelephonyManager.NetworkTypeBitMask int networkBitmask, int accessNetworkType) {
+        if (networkBitmask == NETWORK_TYPE_BITMASK_UNKNOWN) return true;
+        if (accessNetworkType == AccessNetworkType.UNKNOWN) return false;
+
+        int networkType = 1;
+        while (networkBitmask != 0) {
+            if ((networkBitmask & 1) != 0) {
+                if (networkTypeToAccessNetworkType(networkType) == accessNetworkType) {
+                    return true;
+                }
+            }
+            networkBitmask = networkBitmask >> 1;
+            networkType++;
+        }
+
+        return false;
+    }
+
     /** @hide */
     public static int getBitmaskForTech(int radioTech) {
         if (radioTech >= 1) {
diff --git a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
index 17fa931..45ddc3e 100644
--- a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
+++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
@@ -39,6 +39,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 /**
  * Tests color extraction generation.
@@ -48,16 +50,19 @@
 public class ColorExtractorTest {
 
     Context mContext;
+    @Mock
+    WallpaperManager mWallpaperManager;
 
     @Before
     public void setup() {
+        MockitoAnnotations.initMocks(this);
         mContext = InstrumentationRegistry.getContext();
     }
 
     @Test
     public void ColorExtractor_extractWhenInitialized() {
         ExtractionType type = mock(Tonal.class);
-        new ColorExtractor(mContext, type, true);
+        new ColorExtractor(mContext, type, true, mWallpaperManager);
         // 1 for lock and 1 for system
         verify(type, times(2))
                 .extractInto(any(), any(), any(), any());
@@ -84,7 +89,7 @@
                     outGradientColorsDark.set(colorsExpectedDark);
                     outGradientColorsExtraDark.set(colorsExpectedExtraDark);
                 };
-        ColorExtractor extractor = new ColorExtractor(mContext, type, true);
+        ColorExtractor extractor = new ColorExtractor(mContext, type, true, mWallpaperManager);
 
         GradientColors colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM,
                 ColorExtractor.TYPE_NORMAL);
@@ -99,7 +104,8 @@
     public void addOnColorsChangedListener_invokesListener() {
         ColorExtractor.OnColorsChangedListener mockedListeners =
                 mock(ColorExtractor.OnColorsChangedListener.class);
-        ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext), true);
+        ColorExtractor extractor = new ColorExtractor(mContext, new Tonal(mContext), true,
+                mWallpaperManager);
         extractor.addOnColorsChangedListener(mockedListeners);
 
         extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.RED), null, null),