Merge "Ensure that we stop app switches when finishing the recents animation" into qt-dev
diff --git a/api/test-current.txt b/api/test-current.txt
index ee6fb51..1a912a1c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1917,6 +1917,10 @@
     method public boolean hasSingleFileDescriptor();
   }
 
+  public final class Parcel {
+    method public int readExceptionCode();
+  }
+
   public class ParcelFileDescriptor implements java.io.Closeable android.os.Parcelable {
     method public static java.io.File getFile(java.io.FileDescriptor) throws java.io.IOException;
   }
@@ -1986,6 +1990,7 @@
   public class SystemProperties {
     method @NonNull public static String get(@NonNull String);
     method @NonNull public static String get(@NonNull String, @Nullable String);
+    method public static boolean getBoolean(@NonNull String, boolean);
   }
 
   public final class UserHandle implements android.os.Parcelable {
@@ -2140,6 +2145,36 @@
 
 }
 
+package android.os.image {
+
+  public class DynamicSystemClient {
+    ctor public DynamicSystemClient(@NonNull android.content.Context);
+    method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void bind();
+    method public void setOnStatusChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener);
+    method public void setOnStatusChangedListener(@NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener);
+    method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void start(@NonNull android.net.Uri, long);
+    method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void start(@NonNull android.net.Uri, long, long);
+    method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void unbind();
+    field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6
+    field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4
+    field public static final int CAUSE_ERROR_IO = 3; // 0x3
+    field public static final int CAUSE_ERROR_IPC = 5; // 0x5
+    field public static final int CAUSE_INSTALL_CANCELLED = 2; // 0x2
+    field public static final int CAUSE_INSTALL_COMPLETED = 1; // 0x1
+    field public static final int CAUSE_NOT_SPECIFIED = 0; // 0x0
+    field public static final int STATUS_IN_PROGRESS = 2; // 0x2
+    field public static final int STATUS_IN_USE = 4; // 0x4
+    field public static final int STATUS_NOT_STARTED = 1; // 0x1
+    field public static final int STATUS_READY = 3; // 0x3
+    field public static final int STATUS_UNKNOWN = 0; // 0x0
+  }
+
+  public static interface DynamicSystemClient.OnStatusChangedListener {
+    method public void onStatusChanged(int, int, long, @Nullable Throwable);
+  }
+
+}
+
 package android.os.storage {
 
   public class StorageManager {
@@ -2946,6 +2981,21 @@
     method public E valueAtUnchecked(int);
   }
 
+  public class FeatureFlagUtils {
+    ctor public FeatureFlagUtils();
+    method public static java.util.Map<java.lang.String,java.lang.String> getAllFeatureFlags();
+    method public static boolean isEnabled(android.content.Context, String);
+    method public static void setEnabled(android.content.Context, String, boolean);
+    field public static final String DYNAMIC_SYSTEM = "settings_dynamic_system";
+    field public static final String FFLAG_OVERRIDE_PREFIX = "sys.fflag.override.";
+    field public static final String FFLAG_PREFIX = "sys.fflag.";
+    field public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
+    field public static final String PERSIST_PREFIX = "persist.sys.fflag.override.";
+    field public static final String PIXEL_WALLPAPER_CATEGORY_SWITCH = "settings_pixel_wallpaper_category_switch";
+    field public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
+    field public static final String SEAMLESS_TRANSFER = "settings_seamless_transfer";
+  }
+
   public class TimeUtils {
     method public static String formatDuration(long);
   }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index b09eada..cb939f0 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -807,7 +807,7 @@
      *
      * @hide
      */
-    public static final int INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS = 0x00000200;
+    public static final int INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS = 0x00400000;
 
     /** {@hide} */
     public static final int INSTALL_FORCE_VOLUME_UUID = 0x00000200;
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index 41be38a..58aacc2 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -153,14 +153,21 @@
     public static final int CLONE_REMOVE_RES_NAMES = 1 << 3;
 
     /** @hide */
+    public static final int CLONE_REMOVE_PERSON = 1 << 4;
+
+    /** @hide */
     public static final int CLONE_REMOVE_FOR_CREATOR = CLONE_REMOVE_ICON | CLONE_REMOVE_RES_NAMES;
 
     /** @hide */
     public static final int CLONE_REMOVE_FOR_LAUNCHER = CLONE_REMOVE_ICON | CLONE_REMOVE_INTENT
-            | CLONE_REMOVE_RES_NAMES;
+            | CLONE_REMOVE_RES_NAMES | CLONE_REMOVE_PERSON;
 
     /** @hide */
     public static final int CLONE_REMOVE_FOR_LAUNCHER_APPROVAL = CLONE_REMOVE_INTENT
+            | CLONE_REMOVE_RES_NAMES | CLONE_REMOVE_PERSON;
+
+    /** @hide */
+    public static final int CLONE_REMOVE_FOR_APP_PREDICTION = CLONE_REMOVE_ICON
             | CLONE_REMOVE_RES_NAMES;
 
     /** @hide */
@@ -169,8 +176,11 @@
             CLONE_REMOVE_INTENT,
             CLONE_REMOVE_NON_KEY_INFO,
             CLONE_REMOVE_RES_NAMES,
+            CLONE_REMOVE_PERSON,
             CLONE_REMOVE_FOR_CREATOR,
-            CLONE_REMOVE_FOR_LAUNCHER
+            CLONE_REMOVE_FOR_LAUNCHER,
+            CLONE_REMOVE_FOR_LAUNCHER_APPROVAL,
+            CLONE_REMOVE_FOR_APP_PREDICTION
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface CloneFlags {}
@@ -548,7 +558,9 @@
             mDisabledMessage = source.mDisabledMessage;
             mDisabledMessageResId = source.mDisabledMessageResId;
             mCategories = cloneCategories(source.mCategories);
-            mPersons = clonePersons(source.mPersons);
+            if ((cloneFlags & CLONE_REMOVE_PERSON) == 0) {
+                mPersons = clonePersons(source.mPersons);
+            }
             if ((cloneFlags & CLONE_REMOVE_INTENT) == 0) {
                 mIntents = cloneIntents(source.mIntents);
                 mIntentPersistableExtrases =
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index de963c9..fe2e948 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -2001,6 +2002,7 @@
      * @hide
      */
     @UnsupportedAppUsage
+    @TestApi
     public final int readExceptionCode() {
         int code = readInt();
         if (code == EX_HAS_REPLY_HEADER) {
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index edfdda8bb..4538410 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -174,6 +174,7 @@
      * @hide
      */
     @SystemApi
+    @TestApi
     public static boolean getBoolean(@NonNull String key, boolean def) {
         if (TRACK_KEY_ACCESS) onKeyAccess(key);
         return native_get_boolean(key, def);
diff --git a/core/java/android/os/image/DynamicSystemClient.java b/core/java/android/os/image/DynamicSystemClient.java
index f1f24fb..921f0f2 100644
--- a/core/java/android/os/image/DynamicSystemClient.java
+++ b/core/java/android/os/image/DynamicSystemClient.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -67,6 +68,7 @@
  * @hide
  */
 @SystemApi
+@TestApi
 public class DynamicSystemClient {
     /** @hide */
     @IntDef(prefix = { "STATUS_" }, value = {
@@ -283,6 +285,7 @@
      * @hide
      */
     @SystemApi
+    @TestApi
     public DynamicSystemClient(@NonNull Context context) {
         mContext = context;
         mConnection = new DynSystemServiceConnection();
@@ -314,8 +317,11 @@
      * Bind to {@code DynamicSystem} installation service. Binding to the installation service
      * allows it to send status updates to {@link #OnStatusChangedListener}. It is recommanded
      * to bind before calling {@link #start} and get status updates.
+     * @hide
      */
     @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM)
+    @SystemApi
+    @TestApi
     public void bind() {
         if (!featureFlagEnabled()) {
             Slog.w(TAG, FeatureFlagUtils.DYNAMIC_SYSTEM + " not enabled; bind() aborted.");
@@ -334,8 +340,11 @@
     /**
      * Unbind from {@code DynamicSystem} installation service. Unbinding from the installation
      * service stops it from sending following status updates.
+     * @hide
      */
     @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM)
+    @SystemApi
+    @TestApi
     public void unbind() {
         if (!mBound) {
             return;
@@ -367,8 +376,11 @@
      *
      * @param systemUrl a network Uri, a file Uri or a content Uri pointing to a system image file.
      * @param systemSize size of system image.
+     * @hide
      */
     @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM)
+    @SystemApi
+    @TestApi
     public void start(@NonNull Uri systemUrl, @BytesLong long systemSize) {
         start(systemUrl, systemSize, DEFAULT_USERDATA_SIZE);
     }
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index c42dc81..324e02c 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -16,6 +16,7 @@
 
 package android.util;
 
+import android.annotation.TestApi;
 import android.content.Context;
 import android.os.SystemProperties;
 import android.provider.Settings;
@@ -29,6 +30,7 @@
  *
  * @hide
  */
+@TestApi
 public class FeatureFlagUtils {
 
     public static final String FFLAG_PREFIX = "sys.fflag.";
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index a88c51a..fca97fe 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -185,7 +185,7 @@
     private static final int SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20;
 
     private static final int QUERY_TARGET_SERVICE_LIMIT = 5;
-    private static final int WATCHDOG_TIMEOUT_MILLIS = 3000;
+    private static final int WATCHDOG_TIMEOUT_MILLIS = 5000;
 
     private static final int DEFAULT_SALT_EXPIRATION_DAYS = 7;
     private int mMaxHashSaltDays = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
@@ -252,6 +252,123 @@
     // Sorted list of DisplayResolveInfos for the alphabetical app section.
     private List<ResolverActivity.DisplayResolveInfo> mSortedList = new ArrayList<>();
 
+    private ContentPreviewCoordinator mPreviewCoord;
+
+    private class ContentPreviewCoordinator {
+        private static final int IMAGE_LOAD_TIMEOUT_MILLIS = 300;
+        private static final int IMAGE_FADE_IN_MILLIS = 150;
+        private static final int IMAGE_LOAD_TIMEOUT = 1;
+        private static final int IMAGE_LOAD_INTO_VIEW = 2;
+
+        private final View mParentView;
+        private boolean mHideParentOnFail;
+        private boolean mAtLeastOneLoaded = false;
+
+        class LoadUriTask {
+            public final Uri mUri;
+            public final int mImageResourceId;
+            public final int mExtraCount;
+            public final Bitmap mBmp;
+
+            LoadUriTask(int imageResourceId, Uri uri, int extraCount, Bitmap bmp) {
+                this.mImageResourceId = imageResourceId;
+                this.mUri = uri;
+                this.mExtraCount = extraCount;
+                this.mBmp = bmp;
+            }
+        }
+
+        // If at least one image loads within the timeout period, allow other
+        // loads to continue. Otherwise terminate and optionally hide
+        // the parent area
+        private final Handler mHandler = new Handler() {
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case IMAGE_LOAD_TIMEOUT:
+                        maybeHideContentPreview();
+                        break;
+
+                    case IMAGE_LOAD_INTO_VIEW:
+                        if (isFinishing()) break;
+
+                        LoadUriTask task = (LoadUriTask) msg.obj;
+                        RoundedRectImageView imageView = mParentView.findViewById(
+                                task.mImageResourceId);
+                        if (task.mBmp == null) {
+                            imageView.setVisibility(View.GONE);
+                            maybeHideContentPreview();
+                            return;
+                        }
+
+                        mAtLeastOneLoaded = true;
+                        imageView.setVisibility(View.VISIBLE);
+                        imageView.setAlpha(0.0f);
+                        imageView.setImageBitmap(task.mBmp);
+
+                        ValueAnimator fadeAnim = ObjectAnimator.ofFloat(imageView, "alpha", 0.0f,
+                                1.0f);
+                        fadeAnim.setInterpolator(new DecelerateInterpolator(1.0f));
+                        fadeAnim.setDuration(IMAGE_FADE_IN_MILLIS);
+                        fadeAnim.start();
+
+                        if (task.mExtraCount > 0) {
+                            imageView.setExtraImageCount(task.mExtraCount);
+                        }
+                }
+            }
+        };
+
+        ContentPreviewCoordinator(View parentView, boolean hideParentOnFail) {
+            super();
+
+            this.mParentView = parentView;
+            this.mHideParentOnFail = hideParentOnFail;
+        }
+
+        private void loadUriIntoView(final int imageResourceId, final Uri uri,
+                final int extraImages) {
+            mHandler.sendEmptyMessageDelayed(IMAGE_LOAD_TIMEOUT, IMAGE_LOAD_TIMEOUT_MILLIS);
+
+            AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
+                final Bitmap bmp = loadThumbnail(uri, new Size(200, 200));
+                final Message msg = Message.obtain();
+                msg.what = IMAGE_LOAD_INTO_VIEW;
+                msg.obj = new LoadUriTask(imageResourceId, uri, extraImages, bmp);
+                mHandler.sendMessage(msg);
+            });
+        }
+
+        private void cancelLoads() {
+            mHandler.removeMessages(IMAGE_LOAD_INTO_VIEW);
+            mHandler.removeMessages(IMAGE_LOAD_TIMEOUT);
+        }
+
+        private void maybeHideContentPreview() {
+            if (!mAtLeastOneLoaded && mHideParentOnFail) {
+                Log.i(TAG, "Hiding image preview area. Timed out waiting for preview to load"
+                        + " within " + IMAGE_LOAD_TIMEOUT_MILLIS + "ms.");
+                collapseParentView();
+                if (mChooserRowAdapter != null) {
+                    mChooserRowAdapter.hideContentPreview();
+                }
+                mHideParentOnFail = false;
+            }
+        }
+
+        private void collapseParentView() {
+            // This will effectively hide the content preview row by forcing the height
+            // to zero. It is faster than forcing a relayout of the listview
+            final View v = mParentView;
+            int widthSpec = MeasureSpec.makeMeasureSpec(v.getWidth(), MeasureSpec.EXACTLY);
+            int heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY);
+            v.measure(widthSpec, heightSpec);
+            v.getLayoutParams().height = 0;
+            v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getTop());
+            v.invalidate();
+        }
+    }
+
     private final Handler mChooserHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
@@ -621,14 +738,15 @@
     private ViewGroup displayContentPreview(@ContentPreviewType int previewType,
             Intent targetIntent, LayoutInflater layoutInflater, ViewGroup convertView,
             ViewGroup parent) {
+        if (convertView != null) return convertView;
+
         switch (previewType) {
             case CONTENT_PREVIEW_TEXT:
-                return displayTextContentPreview(targetIntent, layoutInflater, convertView, parent);
+                return displayTextContentPreview(targetIntent, layoutInflater, parent);
             case CONTENT_PREVIEW_IMAGE:
-                return displayImageContentPreview(targetIntent, layoutInflater, convertView,
-                        parent);
+                return displayImageContentPreview(targetIntent, layoutInflater, parent);
             case CONTENT_PREVIEW_FILE:
-                return displayFileContentPreview(targetIntent, layoutInflater, convertView, parent);
+                return displayFileContentPreview(targetIntent, layoutInflater, parent);
             default:
                 Log.e(TAG, "Unexpected content preview type: " + previewType);
         }
@@ -637,10 +755,9 @@
     }
 
     private ViewGroup displayTextContentPreview(Intent targetIntent, LayoutInflater layoutInflater,
-            ViewGroup convertView, ViewGroup parent) {
-        ViewGroup contentPreviewLayout =
-                convertView != null ? convertView : (ViewGroup) layoutInflater.inflate(
-                        R.layout.chooser_grid_preview_text, parent, false);
+            ViewGroup parent) {
+        ViewGroup contentPreviewLayout = (ViewGroup) layoutInflater.inflate(
+                R.layout.chooser_grid_preview_text, parent, false);
 
         contentPreviewLayout.findViewById(R.id.copy_button).setOnClickListener(
                 this::onCopyButtonClicked);
@@ -677,12 +794,8 @@
             if (previewThumbnail == null) {
                 previewThumbnailView.setVisibility(View.GONE);
             } else {
-                Bitmap bmp = loadThumbnail(previewThumbnail, new Size(100, 100));
-                if (bmp == null) {
-                    previewThumbnailView.setVisibility(View.GONE);
-                } else {
-                    previewThumbnailView.setImageBitmap(bmp);
-                }
+                mPreviewCoord = new ContentPreviewCoordinator(contentPreviewLayout, false);
+                mPreviewCoord.loadUriIntoView(R.id.content_preview_thumbnail, previewThumbnail, 0);
             }
         }
 
@@ -690,15 +803,15 @@
     }
 
     private ViewGroup displayImageContentPreview(Intent targetIntent, LayoutInflater layoutInflater,
-            ViewGroup convertView, ViewGroup parent) {
-        ViewGroup contentPreviewLayout =
-                convertView != null ? convertView : (ViewGroup) layoutInflater.inflate(
-                        R.layout.chooser_grid_preview_image, parent, false);
+            ViewGroup parent) {
+        ViewGroup contentPreviewLayout = (ViewGroup) layoutInflater.inflate(
+                R.layout.chooser_grid_preview_image, parent, false);
+        mPreviewCoord = new ContentPreviewCoordinator(contentPreviewLayout, true);
 
         String action = targetIntent.getAction();
         if (Intent.ACTION_SEND.equals(action)) {
             Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM);
-            loadUriIntoView(R.id.content_preview_image_1_large, uri, contentPreviewLayout);
+            mPreviewCoord.loadUriIntoView(R.id.content_preview_image_1_large, uri, 0);
         } else {
             ContentResolver resolver = getContentResolver();
 
@@ -717,21 +830,16 @@
                 return contentPreviewLayout;
             }
 
-            loadUriIntoView(R.id.content_preview_image_1_large, imageUris.get(0),
-                    contentPreviewLayout);
+            mPreviewCoord.loadUriIntoView(R.id.content_preview_image_1_large, imageUris.get(0), 0);
 
             if (imageUris.size() == 2) {
-                loadUriIntoView(R.id.content_preview_image_2_large, imageUris.get(1),
-                        contentPreviewLayout);
+                mPreviewCoord.loadUriIntoView(R.id.content_preview_image_2_large,
+                        imageUris.get(1), 0);
             } else if (imageUris.size() > 2) {
-                loadUriIntoView(R.id.content_preview_image_2_small, imageUris.get(1),
-                        contentPreviewLayout);
-                RoundedRectImageView imageView = loadUriIntoView(
-                        R.id.content_preview_image_3_small, imageUris.get(2), contentPreviewLayout);
-
-                if (imageUris.size() > 3) {
-                    imageView.setExtraImageCount(imageUris.size() - 3);
-                }
+                mPreviewCoord.loadUriIntoView(R.id.content_preview_image_2_small,
+                        imageUris.get(1), 0);
+                mPreviewCoord.loadUriIntoView(R.id.content_preview_image_3_small,
+                        imageUris.get(2), imageUris.size() - 3);
             }
         }
 
@@ -803,11 +911,10 @@
     }
 
     private ViewGroup displayFileContentPreview(Intent targetIntent, LayoutInflater layoutInflater,
-            ViewGroup convertView, ViewGroup parent) {
+            ViewGroup parent) {
 
-        ViewGroup contentPreviewLayout =
-                convertView != null ? convertView : (ViewGroup) layoutInflater.inflate(
-                        R.layout.chooser_grid_preview_file, parent, false);
+        ViewGroup contentPreviewLayout = (ViewGroup) layoutInflater.inflate(
+                R.layout.chooser_grid_preview_file, parent, false);
 
         // TODO(b/120417119): Disable file copy until after moving to sysui,
         // due to permissions issues
@@ -839,6 +946,10 @@
                         R.id.content_preview_filename);
                 fileNameView.setText(fileName);
 
+                View thumbnailView = contentPreviewLayout.findViewById(
+                        R.id.content_preview_file_thumbnail);
+                thumbnailView.setVisibility(View.GONE);
+
                 ImageView fileIconView = contentPreviewLayout.findViewById(
                         R.id.content_preview_file_icon);
                 fileIconView.setVisibility(View.VISIBLE);
@@ -849,32 +960,25 @@
         return contentPreviewLayout;
     }
 
-    private void loadFileUriIntoView(Uri uri, View parent) {
+    private void loadFileUriIntoView(final Uri uri, final View parent) {
         FileInfo fileInfo = extractFileInfo(uri, getContentResolver());
 
         TextView fileNameView = parent.findViewById(R.id.content_preview_filename);
         fileNameView.setText(fileInfo.name);
 
         if (fileInfo.hasThumbnail) {
-            loadUriIntoView(R.id.content_preview_file_thumbnail, uri, parent);
+            mPreviewCoord = new ContentPreviewCoordinator(parent, false);
+            mPreviewCoord.loadUriIntoView(R.id.content_preview_file_thumbnail, uri, 0);
         } else {
+            View thumbnailView = parent.findViewById(R.id.content_preview_file_thumbnail);
+            thumbnailView.setVisibility(View.GONE);
+
             ImageView fileIconView = parent.findViewById(R.id.content_preview_file_icon);
             fileIconView.setVisibility(View.VISIBLE);
             fileIconView.setImageResource(R.drawable.chooser_file_generic);
         }
     }
 
-    private RoundedRectImageView loadUriIntoView(int imageResourceId, Uri uri, View parent) {
-        RoundedRectImageView imageView = parent.findViewById(imageResourceId);
-        Bitmap bmp = loadThumbnail(uri, new Size(200, 200));
-        if (bmp != null) {
-            imageView.setVisibility(View.VISIBLE);
-            imageView.setImageBitmap(bmp);
-        }
-
-        return imageView;
-    }
-
     @VisibleForTesting
     protected boolean isImageType(String mimeType) {
         return mimeType != null && mimeType.startsWith("image/");
@@ -944,6 +1048,9 @@
         mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT);
         mChooserHandler.removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT);
         mChooserHandler.removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED);
+
+        if (mPreviewCoord != null) mPreviewCoord.cancelLoads();
+
         if (mAppPredictor != null) {
             mAppPredictor.unregisterPredictionUpdates(mAppPredictorCallback);
             mAppPredictor.destroy();
@@ -2036,9 +2143,12 @@
         }
 
         int availableWidth = right - left - v.getPaddingLeft() - v.getPaddingRight();
-        if (mChooserRowAdapter.calculateChooserTargetWidth(availableWidth)
+        if (mChooserRowAdapter.consumeLayoutRequest()
+                || mChooserRowAdapter.calculateChooserTargetWidth(availableWidth)
                 || mAdapterView.getAdapter() == null) {
-            mAdapterView.setAdapter(mChooserRowAdapter);
+            if (mAdapterView.getAdapter() == null) {
+                mAdapterView.setAdapter(mChooserRowAdapter);
+            }
 
             getMainThreadHandler().post(() -> {
                 if (mResolverDrawerLayout == null || mChooserRowAdapter == null) {
@@ -2589,6 +2699,9 @@
         private int mChooserTargetWidth = 0;
         private boolean mShowAzLabelIfPoss;
 
+        private boolean mHideContentPreview = false;
+        private boolean mLayoutRequested = false;
+
         private static final int VIEW_TYPE_DIRECT_SHARE = 0;
         private static final int VIEW_TYPE_NORMAL = 1;
         private static final int VIEW_TYPE_CONTENT_PREVIEW = 2;
@@ -2651,6 +2764,18 @@
             return maxTargets;
         }
 
+        public void hideContentPreview() {
+            mHideContentPreview = true;
+            mLayoutRequested = true;
+            notifyDataSetChanged();
+        }
+
+        public boolean consumeLayoutRequest() {
+            boolean oldValue = mLayoutRequested;
+            mLayoutRequested = false;
+            return oldValue;
+        }
+
         @Override
         public boolean areAllItemsEnabled() {
             return false;
@@ -2684,7 +2809,8 @@
                 return 0;
             }
 
-            if (mChooserListAdapter == null || mChooserListAdapter.getCount() == 0) {
+            if (mHideContentPreview || mChooserListAdapter == null
+                    || mChooserListAdapter.getCount() == 0) {
                 return 0;
             }
 
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index f9f28da..daa6347 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -1301,18 +1301,6 @@
     lpTrack->setParameters(param.toString());
 }
 
-static void android_media_AudioTrack_set_eos(JNIEnv *env,  jobject thiz) {
-    sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
-    if (lpTrack == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException",
-                          "AudioTrack not initialized");
-        return;
-    }
-    AudioParameter param = AudioParameter();
-    param.addInt(String8("EOS"), 1);
-    lpTrack->setParameters(param.toString());
-}
-
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 static const JNINativeMethod gMethods[] = {
@@ -1389,7 +1377,6 @@
     {"native_setPresentation", "(II)I", (void *)android_media_AudioTrack_setPresentation},
     {"native_getPortId", "()I", (void *)android_media_AudioTrack_get_port_id},
     {"native_set_delay_padding", "(II)V", (void *)android_media_AudioTrack_set_delay_padding},
-    {"native_set_eos",        "()V",    (void *)android_media_AudioTrack_set_eos},
 };
 
 
diff --git a/core/res/res/layout/chooser_grid_preview_file.xml b/core/res/res/layout/chooser_grid_preview_file.xml
index 27c6041..f7d60c9 100644
--- a/core/res/res/layout/chooser_grid_preview_file.xml
+++ b/core/res/res/layout/chooser_grid_preview_file.xml
@@ -44,8 +44,7 @@
           android:adjustViewBounds="true"
           android:layout_gravity="center_vertical"
           android:gravity="center"
-          android:scaleType="centerCrop"
-          android:visibility="gone"/>
+          android:scaleType="centerCrop"/>
     <ImageView
         android:id="@+id/content_preview_file_icon"
         android:layout_width="36dp"
diff --git a/core/res/res/layout/chooser_grid_preview_image.xml b/core/res/res/layout/chooser_grid_preview_image.xml
index ad31e0d..79a0de4 100644
--- a/core/res/res/layout/chooser_grid_preview_image.xml
+++ b/core/res/res/layout/chooser_grid_preview_image.xml
@@ -33,7 +33,6 @@
 
     <view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
           android:id="@+id/content_preview_image_1_large"
-          android:visibility="gone"
           android:layout_width="120dp"
           android:layout_height="140dp"
           android:layout_alignParentTop="true"
diff --git a/packages/SystemUI/res/values-mcc310-mnc030/config.xml b/core/res/res/values-mcc310-mnc030/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc310-mnc030/config.xml
rename to core/res/res/values-mcc310-mnc030/config.xml
diff --git a/packages/SystemUI/res/values-mcc310-mnc070/config.xml b/core/res/res/values-mcc310-mnc070/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc310-mnc070/config.xml
rename to core/res/res/values-mcc310-mnc070/config.xml
diff --git a/packages/SystemUI/res/values-mcc310-mnc170/config.xml b/core/res/res/values-mcc310-mnc170/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc310-mnc170/config.xml
rename to core/res/res/values-mcc310-mnc170/config.xml
diff --git a/packages/SystemUI/res/values-mcc310-mnc280/config.xml b/core/res/res/values-mcc310-mnc280/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc310-mnc280/config.xml
rename to core/res/res/values-mcc310-mnc280/config.xml
diff --git a/packages/SystemUI/res/values-mcc310-mnc380/config.xml b/core/res/res/values-mcc310-mnc380/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc310-mnc380/config.xml
rename to core/res/res/values-mcc310-mnc380/config.xml
diff --git a/core/res/res/values-mcc310-mnc410/config.xml b/core/res/res/values-mcc310-mnc410/config.xml
index 00ab712..3fb3f0f 100644
--- a/core/res/res/values-mcc310-mnc410/config.xml
+++ b/core/res/res/values-mcc310-mnc410/config.xml
@@ -48,4 +48,8 @@
         <item>"#8"</item>
         <item>"#9"</item>
     </string-array>
+
+    <!-- Enable 5 bar signal strength icon -->
+    <bool name="config_inflateSignalStrength">true</bool>
+
 </resources>
diff --git a/packages/SystemUI/res/values-mcc310-mnc560/config.xml b/core/res/res/values-mcc310-mnc560/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc310-mnc560/config.xml
rename to core/res/res/values-mcc310-mnc560/config.xml
diff --git a/packages/SystemUI/res/values-mcc310-mnc950/config.xml b/core/res/res/values-mcc310-mnc950/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc310-mnc950/config.xml
rename to core/res/res/values-mcc310-mnc950/config.xml
diff --git a/packages/SystemUI/res/values-mcc311-mnc180/config.xml b/core/res/res/values-mcc311-mnc180/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc311-mnc180/config.xml
rename to core/res/res/values-mcc311-mnc180/config.xml
diff --git a/core/res/res/values-mcc311-mnc480/config.xml b/core/res/res/values-mcc311-mnc480/config.xml
index db2f8d0..336e30e 100755
--- a/core/res/res/values-mcc311-mnc480/config.xml
+++ b/core/res/res/values-mcc311-mnc480/config.xml
@@ -40,4 +40,7 @@
 
     <bool name="config_use_sim_language_file">true</bool>
 
+    <!-- Enable 5 bar signal strength icon -->
+    <bool name="config_inflateSignalStrength">true</bool>
+
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2de5397..fb58569 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4121,4 +4121,9 @@
     even after user setup is complete. The defined component should be used for supervision purposes
     only. The component must be part of a system app. -->
     <string name="config_defaultSupervisionProfileOwnerComponent" translatable="false"></string>
+
+    <!-- Whether to artificially interpret all signal strengths as
+         one bar higher than they actually are -->
+    <bool name="config_inflateSignalStrength">false</bool>
+
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6cdb3d6..3d2d969 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3797,4 +3797,5 @@
   <java-symbol type="style" name="Animation.DeviceDefault.Activity.Resolver" />
   
   <java-symbol type="string" name="config_defaultSupervisionProfileOwnerComponent" />
+  <java-symbol type="bool" name="config_inflateSignalStrength" />
 </resources>
diff --git a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
index dbb79bc..e030478 100644
--- a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
+++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
@@ -162,15 +162,15 @@
             }
 
             if ((opResult.output != null) && (opResult.output.length > 0)) {
-                if (inputLength > 0) {
+                if (inputLength + mBufferedLength > 0) {
                     // More output might be produced in this loop -- buffer the current output
                     if (bufferedOutput == null) {
                         bufferedOutput = new ByteArrayOutputStream();
-                        try {
-                            bufferedOutput.write(opResult.output);
-                        } catch (IOException e) {
-                            throw new ProviderException("Failed to buffer output", e);
-                        }
+                    }
+                    try {
+                        bufferedOutput.write(opResult.output);
+                    } catch (IOException e) {
+                        throw new ProviderException("Failed to buffer output", e);
                     }
                 } else {
                     // No more output will be produced in this loop
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index d9d614f..e29e569 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -101,6 +101,20 @@
     public static final int PLAYSTATE_PAUSED  = 2;  // matches SL_PLAYSTATE_PAUSED
     /** indicates AudioTrack state is playing */
     public static final int PLAYSTATE_PLAYING = 3;  // matches SL_PLAYSTATE_PLAYING
+    /**
+      * @hide
+      * indicates AudioTrack state is stopping waiting for NATIVE_EVENT_STREAM_END to
+      * transition to PLAYSTATE_STOPPED.
+      * Only valid for offload mode.
+      */
+    private static final int PLAYSTATE_STOPPING = 4;
+    /**
+      * @hide
+      * indicates AudioTrack state is paused from stopping state. Will transition to
+      * PLAYSTATE_STOPPING if play() is called.
+      * Only valid for offload mode.
+      */
+    private static final int PLAYSTATE_PAUSED_STOPPING = 5;
 
     // keep these values in sync with android_media_AudioTrack.cpp
     /**
@@ -303,6 +317,14 @@
      * One of PLAYSTATE_STOPPED, PLAYSTATE_PAUSED, or PLAYSTATE_PLAYING.
      */
     private int mPlayState = PLAYSTATE_STOPPED;
+
+    /**
+     * Indicates that we are expecting an end of stream callback following a call
+     * to setOffloadEndOfStream() in a gapless track transition context. The native track
+     * will be restarted automatically.
+     */
+    private boolean mOffloadEosPending = false;
+
     /**
      * Lock to ensure mPlayState updates reflect the actual state of the object.
      */
@@ -1073,6 +1095,10 @@
      * Declares that the last write() operation on this track provided the last buffer of this
      * stream.
      * After the end of stream, previously set padding and delay values are ignored.
+     * Can only be called only if the AudioTrack is opened in offload mode
+     * {@see Builder#setOffloadedPlayback(boolean)}.
+     * Can only be called only if the AudioTrack is in state {@link #PLAYSTATE_PLAYING}
+     * {@see #getPlaystate()}.
      * Use this method in the same thread as any write() operation.
      */
     public void setOffloadEndOfStream() {
@@ -1082,7 +1108,20 @@
         if (mState == STATE_UNINITIALIZED) {
             throw new IllegalStateException("Uninitialized track");
         }
-        native_set_eos();
+        if (mPlayState != PLAYSTATE_PLAYING) {
+            throw new IllegalStateException("EOS not supported if not playing");
+        }
+        synchronized (mStreamEventCbLock) {
+            if (mStreamEventCbInfoList.size() == 0) {
+                throw new IllegalStateException("EOS not supported without StreamEventCallback");
+            }
+        }
+
+        synchronized (mPlayStateLock) {
+            native_stop();
+            mOffloadEosPending = true;
+            mPlayState = PLAYSTATE_STOPPING;
+        }
     }
 
     /**
@@ -1366,7 +1405,11 @@
         }
         baseRelease();
         native_release();
-        mState = STATE_UNINITIALIZED;
+        synchronized (mPlayStateLock) {
+            mState = STATE_UNINITIALIZED;
+            mPlayState = PLAYSTATE_STOPPED;
+            mPlayStateLock.notify();
+        }
     }
 
     @Override
@@ -1525,7 +1568,14 @@
      */
     public int getPlayState() {
         synchronized (mPlayStateLock) {
-            return mPlayState;
+            switch (mPlayState) {
+                case PLAYSTATE_STOPPING:
+                    return PLAYSTATE_PLAYING;
+                case PLAYSTATE_PAUSED_STOPPING:
+                    return PLAYSTATE_PAUSED;
+                default:
+                    return mPlayState;
+            }
         }
     }
 
@@ -2260,7 +2310,12 @@
         synchronized(mPlayStateLock) {
             baseStart();
             native_start();
-            mPlayState = PLAYSTATE_PLAYING;
+            if (mPlayState == PLAYSTATE_PAUSED_STOPPING) {
+                mPlayState = PLAYSTATE_STOPPING;
+            } else {
+                mPlayState = PLAYSTATE_PLAYING;
+                mOffloadEosPending = false;
+            }
         }
     }
 
@@ -2282,9 +2337,15 @@
         synchronized(mPlayStateLock) {
             native_stop();
             baseStop();
-            mPlayState = PLAYSTATE_STOPPED;
-            mAvSyncHeader = null;
-            mAvSyncBytesRemaining = 0;
+            if (mOffloaded && mPlayState != PLAYSTATE_PAUSED_STOPPING) {
+                mPlayState = PLAYSTATE_STOPPING;
+            } else {
+                mPlayState = PLAYSTATE_STOPPED;
+                mOffloadEosPending = false;
+                mAvSyncHeader = null;
+                mAvSyncBytesRemaining = 0;
+                mPlayStateLock.notify();
+            }
         }
     }
 
@@ -2305,7 +2366,11 @@
         synchronized(mPlayStateLock) {
             native_pause();
             basePause();
-            mPlayState = PLAYSTATE_PAUSED;
+            if (mPlayState == PLAYSTATE_STOPPING) {
+                mPlayState = PLAYSTATE_PAUSED_STOPPING;
+            } else {
+                mPlayState = PLAYSTATE_PAUSED;
+            }
         }
     }
 
@@ -2434,6 +2499,9 @@
             return ERROR_BAD_VALUE;
         }
 
+        if (!blockUntilOffloadDrain(writeMode)) {
+            return 0;
+        }
 
         final int ret = native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat,
                 writeMode == WRITE_BLOCKING);
@@ -2544,6 +2612,10 @@
             return ERROR_BAD_VALUE;
         }
 
+        if (!blockUntilOffloadDrain(writeMode)) {
+            return 0;
+        }
+
         final int ret = native_write_short(audioData, offsetInShorts, sizeInShorts, mAudioFormat,
                 writeMode == WRITE_BLOCKING);
 
@@ -2632,6 +2704,10 @@
             return ERROR_BAD_VALUE;
         }
 
+        if (!blockUntilOffloadDrain(writeMode)) {
+            return 0;
+        }
+
         final int ret = native_write_float(audioData, offsetInFloats, sizeInFloats, mAudioFormat,
                 writeMode == WRITE_BLOCKING);
 
@@ -2706,6 +2782,10 @@
             return ERROR_BAD_VALUE;
         }
 
+        if (!blockUntilOffloadDrain(writeMode)) {
+            return 0;
+        }
+
         int ret = 0;
         if (audioData.isDirect()) {
             ret = native_write_native_bytes(audioData,
@@ -2790,6 +2870,10 @@
             return ERROR_BAD_VALUE;
         }
 
+        if (!blockUntilOffloadDrain(writeMode)) {
+            return 0;
+        }
+
         // create timestamp header if none exists
         if (mAvSyncHeader == null) {
             mAvSyncHeader = ByteBuffer.allocate(mOffset);
@@ -2859,6 +2943,25 @@
         return native_reload_static();
     }
 
+    /**
+     * When an AudioTrack in offload mode is in STOPPING play state, wait until event STREAM_END is
+     * received if blocking write or return with 0 frames written if non blocking mode.
+     */
+    private boolean blockUntilOffloadDrain(int writeMode) {
+        synchronized (mPlayStateLock) {
+            while (mPlayState == PLAYSTATE_STOPPING || mPlayState == PLAYSTATE_PAUSED_STOPPING) {
+                if (writeMode == WRITE_NON_BLOCKING) {
+                    return false;
+                }
+                try {
+                    mPlayStateLock.wait();
+                } catch (InterruptedException e) {
+                }
+            }
+            return true;
+        }
+    }
+
     //--------------------------------------------------------------------------
     // Audio effects management
     //--------------------
@@ -3293,6 +3396,22 @@
         public void handleMessage(Message msg) {
             final LinkedList<StreamEventCbInfo> cbInfoList;
             synchronized (mStreamEventCbLock) {
+                if (msg.what == NATIVE_EVENT_STREAM_END) {
+                    synchronized (mPlayStateLock) {
+                        if (mPlayState == PLAYSTATE_STOPPING) {
+                            if (mOffloadEosPending) {
+                                native_start();
+                                mPlayState = PLAYSTATE_PLAYING;
+                            } else {
+                                mAvSyncHeader = null;
+                                mAvSyncBytesRemaining = 0;
+                                mPlayState = PLAYSTATE_STOPPED;
+                            }
+                            mOffloadEosPending = false;
+                            mPlayStateLock.notify();
+                        }
+                    }
+                }
                 if (mStreamEventCbInfoList.size() == 0) {
                     return;
                 }
@@ -3560,7 +3679,6 @@
     private native int native_getPortId();
 
     private native void native_set_delay_padding(int delayInFrames, int paddingInFrames);
-    private native void native_set_eos();
 
     //---------------------------------------------------------
     // Utility methods
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 4c72f48..0e91839 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -578,6 +578,8 @@
     <string name="wifi_display_certification">Wireless display certification</string>
     <!-- Setting Checkbox title whether to enable WiFi Verbose Logging. [CHAR LIMIT=40] -->
     <string name="wifi_verbose_logging">Enable Wi\u2011Fi Verbose Logging</string>
+    <!-- Setting Checkbox title whether to disable WiFi Scan Throttling. [CHAR LIMIT=40] -->
+    <string name="wifi_scan_throttling">Wi\u2011Fi scan throttling</string>
     <!-- Setting Checkbox title whether to always keep mobile data active. [CHAR LIMIT=80] -->
     <string name="mobile_data_always_on">Mobile data always active</string>
     <!-- Setting Checkbox title whether to enable hardware acceleration for tethering. [CHAR LIMIT=80] -->
@@ -633,6 +635,8 @@
     <string name="wifi_display_certification_summary">Show options for wireless display certification</string>
     <!-- Setting Checkbox summary whether to enable Wifi verbose Logging [CHAR LIMIT=80] -->
     <string name="wifi_verbose_logging_summary">Increase Wi\u2011Fi logging level, show per SSID RSSI in Wi\u2011Fi Picker</string>
+    <!-- Setting Checkbox summary whether to disable Wifi scan throttling [CHAR LIMIT=NONE] -->
+    <string name="wifi_scan_throttling_summary">Reduces battery drain &amp; improves network performance</string>
     <!-- Label indicating network has been manually marked as metered -->
     <string name="wifi_metered_label">Metered</string>
     <!-- Label indicating network has been manually marked as unmetered -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java b/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java
new file mode 100644
index 0000000..246f2ce
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.net;
+
+import android.content.Context;
+import android.telephony.SubscriptionManager;
+
+/**
+ * Utilities for dealing with signal strength.
+ */
+public class SignalStrengthUtil {
+    /**
+     * @return whether we should artificially inflate the signal strength and number of levels by 1
+     * bar for the subscription with the given id
+     */
+    public static boolean shouldInflateSignalStrength(Context context, int subscriptionId) {
+        return SubscriptionManager.getResourcesForSubId(context, subscriptionId)
+                .getBoolean(com.android.internal.R.bool.config_inflateSignalStrength);
+    }
+}
diff --git a/packages/SystemUI/res/drawable/ic_volume_media.xml b/packages/SystemUI/res/drawable/ic_volume_media.xml
index c8fa3fb..99be7b6 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media.xml
@@ -22,6 +22,6 @@
 
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M12,3l0.01,10.55c-0.59,-0.34 -1.27,-0.55 -2,-0.55C7.79,13 6,14.79 6,17c0,2.21 1.79,4 4.01,4S14,19.21 14,17V7h4V3H12zM10.01,19c-1.1,0 -2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2C12.01,18.1 11.11,19 10.01,19z"/>
+        android:pathData="M12 3l0.01 10.55c-0.59-0.34-1.27-0.55-2-0.55C7.79 13 6 14.79 6 17s1.79 4 4.01 4S14 19.21 14 17V7h4V3h-6z" />
 
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_media_mute.xml b/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
index 45b5b87..3a495963 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
@@ -22,9 +22,6 @@
 
     <path
         android:fillColor="#FFFFFFFF"
-        android:pathData="M21.19,21.19L14,14l-2,-2l-9.2,-9.2L1.39,4.22l8.79,8.79c-0.06,0 -0.12,-0.01 -0.18,-0.01C7.79,13 6,14.79 6,17c0,2.21 1.79,4 4.01,4S14,19.21 14,17v-0.17l5.78,5.78L21.19,21.19zM10.01,19c-1.1,0 -2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2C12.01,18.1 11.11,19 10.01,19z"/>
-    <path
-        android:fillColor="#FFffffff"
-        android:pathData="M14,11.17l0,-4.17l4,0l0,-4l-6,0l0,6.17z"/>
+        android:pathData="M21.19 21.19L14 14l-2-2-9.2-9.2-1.41 1.42 8.79 8.79c-0.06 0-0.12-0.01-0.18-0.01-2.21 0-4 1.79-4 4s1.79 4 4.01 4S14 19.21 14 17v-0.17l5.78 5.78 1.41-1.42zM14 11.17V7h4V3h-6v6.17z" />
 
 </vector>
diff --git a/packages/SystemUI/res/values-mcc310-mnc410/config.xml b/packages/SystemUI/res/values-mcc310-mnc410/config.xml
deleted file mode 100644
index 26b9192..0000000
--- a/packages/SystemUI/res/values-mcc310-mnc410/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2019, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- These resources are around just to allow their values to be customized
-     for different hardware and product builds. -->
-<resources>
-    <!-- Enable 5 bar signal strength icon -->
-    <bool name="config_inflateSignalStrength">true</bool>
-</resources>
-
diff --git a/packages/SystemUI/res/values-mcc311-mnc480/config.xml b/packages/SystemUI/res/values-mcc311-mnc480/config.xml
deleted file mode 100644
index 7dadae7..0000000
--- a/packages/SystemUI/res/values-mcc311-mnc480/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2017, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- These resources are around just to allow their values to be customized
-     for different hardware and product builds. -->
-<resources>
-    <!-- Enable 5 bar signal strength icon -->
-    <bool name="config_inflateSignalStrength">true</bool>
-</resources>
-
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 27431f7..19e7b73 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -417,10 +417,6 @@
          it has been expanded to reveal its children. -->
     <bool name="config_showGroupNotificationBgWhenExpanded">false</bool>
 
-    <!-- Whether to artificially interpret all signal strengths as
-         one bar higher than they actually are -->
-    <bool name="config_inflateSignalStrength">false</bool>
-
     <!-- Should we vibrate on an icon animation of the shelf. This should only be active if the
      vibrator is capable of subtle vibrations -->
     <bool name="config_vibrateOnIconAnimation">false</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1987494..c04d28a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -38,7 +38,6 @@
     <dimen name="navigation_handle_sample_horizontal_margin">10dp</dimen>
     <dimen name="navigation_home_handle_width">72dp</dimen>
 
-
     <!-- Size of the nav bar edge panels, should be greater to the
          edge sensitivity + the drag threshold -->
     <dimen name="navigation_edge_panel_width">70dp</dimen>
@@ -57,6 +56,9 @@
     <!-- Luminance change threshold that allows applying new value if difference was exceeded -->
     <item name="navigation_luminance_change_threshold" type="dimen" format="float">0.05</item>
 
+    <dimen name="floating_rotation_button_diameter">40dp</dimen>
+    <dimen name="floating_rotation_button_margin">4dp</dimen>
+
     <!-- Height of notification icons in the status bar -->
     <dimen name="status_bar_icon_size">@*android:dimen/status_bar_icon_size</dimen>
 
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 4ec79a6..392183b 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.bubbles;
 
+import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
@@ -40,8 +41,6 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
-import android.app.ActivityTaskManager;
-import android.app.IActivityTaskManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -53,6 +52,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.provider.Settings;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
 import android.service.notification.ZenModeConfig;
 import android.util.Log;
@@ -138,7 +138,6 @@
 
     private final Context mContext;
     private final NotificationEntryManager mNotificationEntryManager;
-    private final IActivityTaskManager mActivityTaskManager;
     private final BubbleTaskStackListener mTaskStackListener;
     private BubbleStateChangeListener mStateChangeListener;
     private BubbleExpandListener mExpandListener;
@@ -250,7 +249,6 @@
         mStatusBarStateListener = new StatusBarStateListener();
         Dependency.get(StatusBarStateController.class).addCallback(mStatusBarStateListener);
 
-        mActivityTaskManager = ActivityTaskManager.getService();
         mTaskStackListener = new BubbleTaskStackListener();
         ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
 
@@ -509,6 +507,12 @@
                 updateBubble(entry);
             }
         }
+
+        @Override
+        public void onNotificationRankingUpdated(RankingMap rankingMap) {
+            // Forward to BubbleData to block any bubbles which should no longer be shown
+            mBubbleData.notificationRankingUpdated(rankingMap);
+        }
     };
 
     @SuppressWarnings("FieldCanBeLocal")
@@ -547,8 +551,11 @@
                     mNotificationEntryManager.performRemoveNotification(bubble.entry.notification,
                             UNDEFINED_DISMISS_REASON);
                 } else {
-                    // The notification is still in the shade but we've removed the bubble so
-                    // lets make sure NoMan knows it's not a bubble anymore
+                    // Update the flag for SysUI
+                    bubble.entry.notification.getNotification().flags &= ~FLAG_BUBBLE;
+
+                    // Make sure NoMan knows it's not a bubble anymore so anyone querying it will
+                    // get right result back
                     try {
                         mBarService.onNotificationBubbleChanged(bubble.getKey(),
                                 false /* isBubble */);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
index 6ab973e..5575b35 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
@@ -22,6 +22,8 @@
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.Context;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.util.Log;
 import android.util.Pair;
 
@@ -114,6 +116,8 @@
     // State tracked during an operation -- keeps track of what listener events to dispatch.
     private Update mStateChange;
 
+    private NotificationListenerService.Ranking mTmpRanking;
+
     private TimeSource mTimeSource = System::currentTimeMillis;
 
     @Nullable
@@ -193,6 +197,31 @@
         dispatchPendingChanges();
     }
 
+    /**
+     * Called when NotificationListener has received adjusted notification rank and reapplied
+     * filtering and sorting. This is used to dismiss any bubbles which should no longer be shown
+     * due to changes in permissions on the notification channel or the global setting.
+     *
+     * @param rankingMap the updated ranking map from NotificationListenerService
+     */
+    public void notificationRankingUpdated(RankingMap rankingMap) {
+        if (mTmpRanking == null) {
+            mTmpRanking = new NotificationListenerService.Ranking();
+        }
+
+        String[] orderedKeys = rankingMap.getOrderedKeys();
+        for (int i = 0; i < orderedKeys.length; i++) {
+            String key = orderedKeys[i];
+            if (hasBubbleWithKey(key)) {
+                rankingMap.getRanking(key, mTmpRanking);
+                if (!mTmpRanking.canBubble()) {
+                    doRemove(key, BubbleController.DISMISS_BLOCKED);
+                }
+            }
+        }
+        dispatchPendingChanges();
+    }
+
     private void doAdd(Bubble bubble) {
         if (DEBUG) {
             Log.d(TAG, "doAdd: " + bubble);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 6de0fb5..c63389a 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -732,7 +732,6 @@
         }
     }
 
-
     /**
      * Changes the currently selected bubble. If the stack is already expanded, the newly selected
      * bubble will be shown immediately. This does not change the expanded state or change the
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index 9d5871e..c375574 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -169,6 +169,5 @@
     public interface NotificationSettingsListener {
 
         default void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) { }
-
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
index a5a6d87..1aa6bc9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
@@ -16,6 +16,8 @@
 package com.android.systemui.statusbar.notification;
 
 import android.annotation.Nullable;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
 
 import com.android.internal.statusbar.NotificationVisibility;
@@ -98,4 +100,14 @@
             @Nullable NotificationVisibility visibility,
             boolean removedByUser) {
     }
+
+    /**
+     * Called whenever notification ranking changes, in response to
+     * {@link NotificationListenerService#onNotificationRankingUpdate}. This is called after
+     * NotificationData has processed the update and notifications have been re-sorted and filtered.
+     *
+     * @param rankingMap provides access to ranking information on currently active notifications
+     */
+    default void onNotificationRankingUpdated(RankingMap rankingMap) {
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 3ac5768..e8388ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -483,6 +483,10 @@
         }
 
         updateNotifications();
+
+        for (NotificationEntryListener listener : mNotificationEntryListeners) {
+            listener.onNotificationRankingUpdated(rankingMap);
+        }
     }
 
     private void updateRankingOfPendingNotifications(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index c65e90e..35cc960 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -65,7 +65,7 @@
     private val mDozeParameters: DozeParameters;
     var willWakeUp = false
         set(value) {
-            if (value && mDozeAmount != 0.0f) {
+            if (!value || mDozeAmount != 0.0f) {
                 field = value
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
index 215aa77..6286d4d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.phone;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.PixelFormat;
 import android.view.ContextThemeWrapper;
 import android.view.Gravity;
@@ -35,6 +36,8 @@
     private final Context mContext;
     private final WindowManager mWindowManager;
     private final KeyButtonView mKeyButtonView;
+    private final int mDiameter;
+    private final int mMargin;
     private KeyButtonDrawable mKeyButtonDrawable;
     private boolean mIsShowing;
     private boolean mCanShow = true;
@@ -46,6 +49,11 @@
         mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
         mKeyButtonView = (KeyButtonView) LayoutInflater.from(mContext).inflate(
                 R.layout.rotate_suggestion, null);
+        mKeyButtonView.setVisibility(View.VISIBLE);
+
+        Resources resources = mContext.getResources();
+        mDiameter = resources.getDimensionPixelSize(R.dimen.floating_rotation_button_diameter);
+        mMargin = resources.getDimensionPixelSize(R.dimen.floating_rotation_button_margin);
     }
 
     @Override
@@ -66,11 +74,8 @@
         mIsShowing = true;
         int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
-        float density = mContext.getResources().getDisplayMetrics().density;
-        int diameter = (int) density * 48;
-        int margin = (int) density * 4;
-        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(diameter, diameter,
-                margin, margin, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, flags,
+        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(mDiameter, mDiameter,
+                mMargin, mMargin, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, flags,
                 PixelFormat.TRANSLUCENT);
         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
         lp.setTitle("FloatingRotationButton");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index c08390f..2afe485 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -38,6 +38,7 @@
 import com.android.internal.telephony.cdma.EriInfo;
 import com.android.settingslib.Utils;
 import com.android.settingslib.graph.SignalDrawable;
+import com.android.settingslib.net.SignalStrengthUtil;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.NetworkController.IconState;
 import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
@@ -248,9 +249,8 @@
     }
 
     private void updateInflateSignalStrength() {
-        mInflateSignalStrengths = SubscriptionManager.getResourcesForSubId(mContext,
-               mSubscriptionInfo.getSubscriptionId())
-               .getBoolean(R.bool.config_inflateSignalStrength);
+        mInflateSignalStrengths = SignalStrengthUtil.shouldInflateSignalStrength(mContext,
+                mSubscriptionInfo.getSubscriptionId());
     }
 
     private int getNumLevels() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index b8a14ef..b2972fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -1140,7 +1140,8 @@
                     res.getBoolean(com.android.internal.R.bool.config_alwaysUseCdmaRssi);
             config.hspaDataDistinguishable =
                     res.getBoolean(R.bool.config_hspa_data_distinguishable);
-            config.inflateSignalStrengths = res.getBoolean(R.bool.config_inflateSignalStrength);
+            config.inflateSignalStrengths = res.getBoolean(
+                    com.android.internal.R.bool.config_inflateSignalStrength);
 
             CarrierConfigManager configMgr = (CarrierConfigManager)
                     context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 4d593c1..72f3a62 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -402,6 +402,7 @@
         verify(mRow).setEntry(eq(mEntry));
         assertEquals(1, mEntry.systemGeneratedSmartActions.size());
         assertEquals("action", mEntry.systemGeneratedSmartActions.get(0).title);
+        verify(mEntryListener).onNotificationRankingUpdated(mRankingMap);
     }
 
     @Test
diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
index bdbff3d..4b48ef9 100644
--- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java
+++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
@@ -661,12 +661,6 @@
         return mTestUserKeyFile == null ? getAdbFile(ADB_KEYS_FILE) : mTestUserKeyFile;
     }
 
-    private void createKeyFile(File keyFile) throws IOException {
-        keyFile.createNewFile();
-        FileUtils.setPermissions(keyFile.toString(),
-                FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP, -1, -1);
-    }
-
     private void writeKey(String key) {
         try {
             File keyFile = getUserKeyFile();
@@ -675,14 +669,13 @@
                 return;
             }
 
-            if (!keyFile.exists()) {
-                createKeyFile(keyFile);
-            }
-
             FileOutputStream fo = new FileOutputStream(keyFile, true);
             fo.write(key.getBytes());
             fo.write('\n');
             fo.close();
+
+            FileUtils.setPermissions(keyFile.toString(),
+                    FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP, -1, -1);
         } catch (IOException ex) {
             Slog.e(TAG, "Error writing key:" + ex);
         }
@@ -698,10 +691,6 @@
                 return;
             }
 
-            if (!keyFile.exists()) {
-                createKeyFile(keyFile);
-            }
-
             atomicKeyFile = new AtomicFile(keyFile);
             fo = atomicKeyFile.startWrite();
             for (String key : keys) {
@@ -709,6 +698,9 @@
                 fo.write('\n');
             }
             atomicKeyFile.finishWrite(fo);
+
+            FileUtils.setPermissions(keyFile.toString(),
+                    FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP, -1, -1);
         } catch (IOException ex) {
             Slog.e(TAG, "Error writing keys: " + ex);
             if (atomicKeyFile != null) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 1160e33..c4eb661 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1036,19 +1036,12 @@
                     final StatusBarNotification n = r.sbn;
                     final int callingUid = n.getUid();
                     final String pkg = n.getPackageName();
-                    final boolean wasBubble = r.getNotification().isBubbleNotification();
                     if (isBubble && isNotificationAppropriateToBubble(r, pkg, callingUid,
                             null /* oldEntry */)) {
                         r.getNotification().flags |= FLAG_BUBBLE;
                     } else {
                         r.getNotification().flags &= ~FLAG_BUBBLE;
                     }
-                    if (wasBubble != r.getNotification().isBubbleNotification()) {
-                        // Add the "alert only once" flag so that the notification won't HUN
-                        // unnecessarily just because the bubble flag was changed.
-                        r.getNotification().flags |= FLAG_ONLY_ALERT_ONCE;
-                        mListeners.notifyPostedLocked(r, r);
-                    }
                 }
             }
         }
@@ -2643,18 +2636,25 @@
                 ParceledListSlice channelsList) {
             List<NotificationChannel> channels = channelsList.getList();
             final int channelsSize = channels.size();
+            boolean needsPolicyFileChange = false;
             for (int i = 0; i < channelsSize; i++) {
                 final NotificationChannel channel = channels.get(i);
                 Preconditions.checkNotNull(channel, "channel in list is null");
-                mPreferencesHelper.createNotificationChannel(pkg, uid, channel,
-                        true /* fromTargetApp */, mConditionProviders.isPackageOrComponentAllowed(
+                needsPolicyFileChange = mPreferencesHelper.createNotificationChannel(pkg, uid,
+                        channel, true /* fromTargetApp */,
+                        mConditionProviders.isPackageOrComponentAllowed(
                                 pkg, UserHandle.getUserId(uid)));
-                mListeners.notifyNotificationChannelChanged(pkg,
-                        UserHandle.getUserHandleForUid(uid),
-                        mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(), false),
-                        NOTIFICATION_CHANNEL_OR_GROUP_ADDED);
+                if (needsPolicyFileChange) {
+                    mListeners.notifyNotificationChannelChanged(pkg,
+                            UserHandle.getUserHandleForUid(uid),
+                            mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(),
+                                    false),
+                            NOTIFICATION_CHANNEL_OR_GROUP_ADDED);
+                }
             }
-            handleSavePolicyFile();
+            if (needsPolicyFileChange) {
+                handleSavePolicyFile();
+            }
         }
 
         @Override
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 5956c65..1c0ac16 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -615,12 +615,13 @@
     }
 
     @Override
-    public void createNotificationChannel(String pkg, int uid, NotificationChannel channel,
+    public boolean createNotificationChannel(String pkg, int uid, NotificationChannel channel,
             boolean fromTargetApp, boolean hasDndAccess) {
         Preconditions.checkNotNull(pkg);
         Preconditions.checkNotNull(channel);
         Preconditions.checkNotNull(channel.getId());
         Preconditions.checkArgument(!TextUtils.isEmpty(channel.getName()));
+        boolean needsPolicyFileChange = false;
         synchronized (mPackagePreferences) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
             if (r == null) {
@@ -637,17 +638,28 @@
             if (existing != null && fromTargetApp) {
                 if (existing.isDeleted()) {
                     existing.setDeleted(false);
+                    needsPolicyFileChange = true;
 
                     // log a resurrected channel as if it's new again
                     MetricsLogger.action(getChannelLog(channel, pkg).setType(
                             com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_OPEN));
                 }
 
-                existing.setName(channel.getName().toString());
-                existing.setDescription(channel.getDescription());
-                existing.setBlockableSystem(channel.isBlockableSystem());
-                if (existing.getGroup() == null) {
+                if (!Objects.equals(channel.getName().toString(), existing.getName().toString())) {
+                    existing.setName(channel.getName().toString());
+                    needsPolicyFileChange = true;
+                }
+                if (!Objects.equals(channel.getDescription(), existing.getDescription())) {
+                    existing.setDescription(channel.getDescription());
+                    needsPolicyFileChange = true;
+                }
+                if (channel.isBlockableSystem() != existing.isBlockableSystem()) {
+                    existing.setBlockableSystem(channel.isBlockableSystem());
+                    needsPolicyFileChange = true;
+                }
+                if (channel.getGroup() != null && existing.getGroup() == null) {
                     existing.setGroup(channel.getGroup());
+                    needsPolicyFileChange = true;
                 }
 
                 // Apps are allowed to downgrade channel importance if the user has not changed any
@@ -656,23 +668,30 @@
                 if (existing.getUserLockedFields() == 0 &&
                         channel.getImportance() < existing.getImportance()) {
                     existing.setImportance(channel.getImportance());
+                    needsPolicyFileChange = true;
                 }
 
                 // system apps and dnd access apps can bypass dnd if the user hasn't changed any
                 // fields on the channel yet
                 if (existing.getUserLockedFields() == 0 && hasDndAccess) {
                     boolean bypassDnd = channel.canBypassDnd();
-                    existing.setBypassDnd(bypassDnd);
+                    if (bypassDnd != existing.canBypassDnd()) {
+                        existing.setBypassDnd(bypassDnd);
+                        needsPolicyFileChange = true;
 
-                    if (bypassDnd != mAreChannelsBypassingDnd
-                            || previousExistingImportance != existing.getImportance()) {
-                        updateChannelsBypassingDnd(mContext.getUserId());
+                        if (bypassDnd != mAreChannelsBypassingDnd
+                                || previousExistingImportance != existing.getImportance()) {
+                            updateChannelsBypassingDnd(mContext.getUserId());
+                        }
                     }
                 }
 
                 updateConfig();
-                return;
+                return needsPolicyFileChange;
             }
+
+            needsPolicyFileChange = true;
+
             if (channel.getImportance() < IMPORTANCE_NONE
                     || channel.getImportance() > NotificationManager.IMPORTANCE_MAX) {
                 throw new IllegalArgumentException("Invalid importance level");
@@ -708,6 +727,8 @@
             MetricsLogger.action(getChannelLog(channel, pkg).setType(
                     com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_OPEN));
         }
+
+        return needsPolicyFileChange;
     }
 
     void clearLockedFieldsLocked(NotificationChannel channel) {
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 72502acd..5de00e4 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -39,7 +39,7 @@
             boolean fromTargetApp);
     ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
             int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty);
-    void createNotificationChannel(String pkg, int uid, NotificationChannel channel,
+    boolean createNotificationChannel(String pkg, int uid, NotificationChannel channel,
             boolean fromTargetApp, boolean hasDndAccess);
     void updateNotificationChannel(String pkg, int uid, NotificationChannel channel, boolean fromUser);
     NotificationChannel getNotificationChannel(String pkg, int uid, String channelId, boolean includeDeleted);
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index eec4b70..d6e87aa 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -674,9 +674,10 @@
             return new ArrayList<>();
         }
 
-        // Get the list of all dynamic shortcuts in this package
+        // Get the list of all dynamic shortcuts in this package.
         final ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
-        findAll(shortcuts, ShortcutInfo::isDynamicVisible, ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
+        findAll(shortcuts, ShortcutInfo::isDynamicVisible,
+                ShortcutInfo.CLONE_REMOVE_FOR_APP_PREDICTION);
 
         final List<ShortcutManager.ShareShortcutInfo> result = new ArrayList<>();
         for (int i = 0; i < shortcuts.size(); i++) {
diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
index e65eae0..54369ca 100644
--- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java
+++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
@@ -16,21 +16,17 @@
 
 package com.android.server.telecom;
 
+import android.app.role.RoleManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
-import android.provider.Settings;
 import android.telecom.DefaultDialerManager;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
@@ -221,19 +217,10 @@
     private void registerDefaultAppNotifier() {
         final DefaultPermissionGrantPolicy permissionPolicy = getDefaultPermissionGrantPolicy();
         // Notify the package manager on default app changes
-        final Uri defaultDialerAppUri = Settings.Secure.getUriFor(
-                Settings.Secure.DIALER_DEFAULT_APPLICATION);
-        ContentObserver contentObserver = new ContentObserver(
-                new Handler(Looper.getMainLooper())) {
-            @Override
-            public void onChange(boolean selfChange, Uri uri, int userId) {
-                if (defaultDialerAppUri.equals(uri)) {
-                    updateSimCallManagerPermissions(permissionPolicy, userId);
-                }
-            }
-        };
-        mContext.getContentResolver().registerContentObserver(defaultDialerAppUri,
-                false, contentObserver, UserHandle.USER_ALL);
+        final RoleManager roleManager = mContext.getSystemService(RoleManager.class);
+        roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(),
+                (roleName, user) -> updateSimCallManagerPermissions(permissionPolicy,
+                        user.getIdentifier()), UserHandle.ALL);
     }
 
 
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 3a39053..a2eb40b 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -518,8 +518,11 @@
                     agentInfo = mActiveAgents.valueAt(index);
                 }
 
-                boolean directUnlock = resolveInfo.serviceInfo.directBootAware
-                    && agentInfo.settings.canUnlockProfile;
+                boolean directUnlock = false;
+                if (agentInfo.settings != null) {
+                    directUnlock = resolveInfo.serviceInfo.directBootAware
+                        && agentInfo.settings.canUnlockProfile;
+                }
 
                 if (directUnlock) {
                     if (DEBUG) Slog.d(TAG, "refreshAgentList: trustagent " + name
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index fa1bcac..fd3678d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -423,9 +423,7 @@
         assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
         assertEquals(null, si.getIntent());
         assertEquals(123, si.getRank());
-        assertEquals("person", si.getPersons()[0].getName());
-        assertEquals("personKey", si.getPersons()[0].getKey());
-        assertEquals("personUri", si.getPersons()[0].getUri());
+        assertEquals(null, si.getPersons());
         assertEquals(1, si.getExtras().getInt("k"));
 
         assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
@@ -455,6 +453,30 @@
 
         assertEquals(456, si.getIconResourceId());
         assertEquals(null, si.getIconResName());
+
+        si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_APP_PREDICTION);
+
+        assertEquals(mClientContext.getPackageName(), si.getPackage());
+        assertEquals("id", si.getId());
+        assertEquals(new ComponentName("a", "b"), si.getActivity());
+        assertEquals(null, si.getIcon());
+        assertEquals("title", si.getTitle());
+        assertEquals("text", si.getText());
+        assertEquals("dismes", si.getDisabledMessage());
+        assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+        assertEquals("action", si.getIntent().getAction());
+        assertEquals("val", si.getIntent().getStringExtra("key"));
+        assertEquals(123, si.getRank());
+        assertEquals("person", si.getPersons()[0].getName());
+        assertEquals("personKey", si.getPersons()[0].getKey());
+        assertEquals("personUri", si.getPersons()[0].getUri());
+        assertEquals(1, si.getExtras().getInt("k"));
+
+        assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
+        assertEquals(null, si.getBitmapPath());
+
+        assertEquals(456, si.getIconResourceId());
+        assertEquals(null, si.getIconResName());
     }
 
     public void testShortcutInfoClone_resId() {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 87f221a..e75a30b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -22,7 +22,6 @@
 import static android.app.Notification.CATEGORY_CALL;
 import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
-import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
 import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
@@ -1660,11 +1659,14 @@
         when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
                 eq(channel2.getId()), anyBoolean()))
                 .thenReturn(channel2);
+        when(mPreferencesHelper.createNotificationChannel(eq(PKG), anyInt(),
+                eq(channel2), anyBoolean(), anyBoolean()))
+                .thenReturn(true);
 
         reset(mListeners);
         mBinderService.createNotificationChannels(PKG,
                 new ParceledListSlice(Arrays.asList(mTestNotificationChannel, channel2)));
-        verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
+        verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
         verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
@@ -4963,13 +4965,10 @@
         mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), false);
         waitForIdle();
 
-        // Make sure we are not a bubble / reported as such to listeners
-        ArgumentCaptor<NotificationRecord> captor =
-                ArgumentCaptor.forClass(NotificationRecord.class);
-        verify(mListeners, times(1)).notifyPostedLocked(captor.capture(), any());
-
-        assertEquals((captor.getValue().getNotification().flags & FLAG_BUBBLE), 0);
-        assertTrue((captor.getValue().getNotification().flags & FLAG_ONLY_ALERT_ONCE) != 0);
+        // Make sure we are not a bubble
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        assertEquals(1, notifsAfter.length);
+        assertEquals((notifsAfter[0].getNotification().flags & FLAG_BUBBLE), 0);
     }
 
     @Test
@@ -5000,13 +4999,10 @@
         mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), true);
         waitForIdle();
 
-        // Make sure we are a bubble / reported as such to listeners
-        ArgumentCaptor<NotificationRecord> captor =
-                ArgumentCaptor.forClass(NotificationRecord.class);
-        verify(mListeners, times(1)).notifyPostedLocked(captor.capture(), any());
-
-        assertTrue((captor.getValue().getNotification().flags & FLAG_BUBBLE) != 0);
-        assertTrue((captor.getValue().getNotification().flags & FLAG_ONLY_ALERT_ONCE) != 0);
+        // Make sure we are a bubble
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        assertEquals(1, notifsAfter.length);
+        assertTrue((notifsAfter[0].getNotification().flags & FLAG_BUBBLE) != 0);
     }
 
     @Test
@@ -5037,7 +5033,6 @@
         StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
         assertEquals(1, notifsAfter.length);
         assertEquals((notifsAfter[0].getNotification().flags & FLAG_BUBBLE), 0);
-        verify(mListeners, times(0)).notifyPostedLocked(any(), any());
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index a0660c4..8f8b746 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -262,13 +262,13 @@
         int uid0 = 1001;
         setUpPackageWithUid(package0, uid0);
         NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(package0, uid0, channel0, true, false);
+        assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
 
         String package10 = "test.package.user10";
         int uid10 = 1001001;
         setUpPackageWithUid(package10, uid10);
         NotificationChannel channel10 = new NotificationChannel("id10", "name10", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(package10, uid10, channel10, true, false);
+        assertTrue(mHelper.createNotificationChannel(package10, uid10, channel10, true, false));
 
         ByteArrayOutputStream baos = writeXmlAndPurge(package10, uid10, true, 10);
 
@@ -293,7 +293,7 @@
         int uid0 = 1001;
         setUpPackageWithUid(package0, uid0);
         NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(package0, uid0, channel0, true, false);
+        assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
 
         ByteArrayOutputStream baos = writeXmlAndPurge(package0, uid0, true, 0);
 
@@ -334,8 +334,8 @@
 
         mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
         mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false));
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false));
 
         mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
         mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
@@ -716,8 +716,8 @@
     public void testCreateChannel_blocked() throws Exception {
         mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_NONE);
 
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
-                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
+                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false));
     }
 
     @Test
@@ -746,10 +746,10 @@
         } catch (IllegalArgumentException e) {
             // yay
         }
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
-                new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
-                new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false);
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
+                new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false));
+        assertFalse(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
+                new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false));
     }
 
 
@@ -763,7 +763,7 @@
         channel.setBypassDnd(true);
         channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
 
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false);
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false));
 
         // same id, try to update all fields
         final NotificationChannel channel2 =
@@ -776,7 +776,8 @@
         mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true);
 
         // all fields should be changed
-        assertEquals(channel2, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false));
+        assertEquals(channel2,
+                mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false));
 
         verify(mHandler, times(1)).requestSort();
     }
@@ -894,7 +895,7 @@
         }
         channel.lockFields(lockMask);
 
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
 
         NotificationChannel savedChannel =
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
@@ -1469,13 +1470,18 @@
                 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setVibrationPattern(vibration);
 
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
 
         NotificationChannel newChannel = new NotificationChannel(
                 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
         newChannel.setVibrationPattern(new long[]{100});
+        newChannel.setAllowBubbles(!channel.canBubble());
+        newChannel.setLightColor(Color.BLUE);
+        newChannel.setSound(Uri.EMPTY, null);
+        newChannel.setShowBadge(!channel.canShowBadge());
 
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel, true, false);
+        assertFalse(mHelper.createNotificationChannel(
+                PKG_N_MR1, UID_N_MR1, newChannel, true, false));
 
         // Old settings not overridden
         compareChannels(channel,
@@ -1588,16 +1594,17 @@
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
 
-        mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
-                UID_N_MR1});
+        assertTrue(mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1},
+                new int[]{UID_N_MR1}));
 
-        assertEquals(0, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, true).getList().size());
+        assertEquals(0, mHelper.getNotificationChannels(
+                PKG_N_MR1, UID_N_MR1, true).getList().size());
 
         // Not deleted
         mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
 
-        mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
-                UID_N_MR1});
+        assertFalse(mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM,
+                new String[]{PKG_N_MR1}, new int[]{UID_N_MR1}));
         assertEquals(2, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
     }
 
@@ -1825,13 +1832,13 @@
     @Test
     public void testCreateChannel_updateName() {
         NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false);
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
         NotificationChannel actual =
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
         assertEquals("hello", actual.getName());
 
         nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false);
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
 
         actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
         assertEquals("goodbye", actual.getName());
@@ -1845,14 +1852,14 @@
         NotificationChannelGroup group = new NotificationChannelGroup("group", "");
         mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
         NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false);
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
         NotificationChannel actual =
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
         assertNull(actual.getGroup());
 
         nc = new NotificationChannel("id", "hello", IMPORTANCE_HIGH);
         nc.setGroup(group.getId());
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false);
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
 
         actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
         assertNotNull(actual.getGroup());
@@ -2109,7 +2116,7 @@
 
         NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
         update.setBypassDnd(true);
-        mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false);
+        assertFalse(mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false));
 
         assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
                 .canBypassDnd());
@@ -2122,7 +2129,7 @@
 
         NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
         update.setBypassDnd(true);
-        mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true, true);
+        assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true, true));
 
         assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
     }
diff --git a/services/usb/java/com/android/server/usb/UsbSerialReader.java b/services/usb/java/com/android/server/usb/UsbSerialReader.java
index 32fc796..8ca77f0 100644
--- a/services/usb/java/com/android/server/usb/UsbSerialReader.java
+++ b/services/usb/java/com/android/server/usb/UsbSerialReader.java
@@ -85,22 +85,22 @@
                     throw new RemoteException("package " + packageName + " cannot be found");
                 }
                 packageTargetSdkVersion = pkg.applicationInfo.targetSdkVersion;
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
 
-            if (packageTargetSdkVersion >= Build.VERSION_CODES.Q) {
-                if (mContext.checkPermission(android.Manifest.permission.MANAGE_USB, pid, uid)
-                        == PackageManager.PERMISSION_DENIED) {
-                    UsbUserSettingsManager settings = mSettingsManager.getSettingsForUser(
-                            UserHandle.getUserId(uid));
+                if (packageTargetSdkVersion >= Build.VERSION_CODES.Q) {
+                    if (mContext.checkPermission(android.Manifest.permission.MANAGE_USB, pid, uid)
+                            == PackageManager.PERMISSION_DENIED) {
+                        UsbUserSettingsManager settings = mSettingsManager.getSettingsForUser(
+                                UserHandle.getUserId(uid));
 
-                    if (mDevice instanceof UsbDevice) {
-                        settings.checkPermission((UsbDevice) mDevice, packageName, uid);
-                    } else {
-                        settings.checkPermission((UsbAccessory) mDevice, uid);
+                        if (mDevice instanceof UsbDevice) {
+                            settings.checkPermission((UsbDevice) mDevice, packageName, uid);
+                        } else {
+                            settings.checkPermission((UsbAccessory) mDevice, uid);
+                        }
                     }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
 
diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java
index 7b51457..511adf6 100644
--- a/telephony/java/android/telephony/emergency/EmergencyNumber.java
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java
@@ -299,7 +299,7 @@
      * Get the dialing number of the emergency number.
      *
      * The character in the number string is only the dial pad
-     * character('0'-'9', '*', or '#'). For example: 911.
+     * character('0'-'9', '*', '+', or '#'). For example: 911.
      *
      * @return the dialing number.
      */