Merge "Save KeyChainSnapshots to disk" into pi-dev
diff --git a/Android.mk b/Android.mk
index e219661..d7d9c90 100644
--- a/Android.mk
+++ b/Android.mk
@@ -252,6 +252,11 @@
 		-federate SupportLib https://developer.android.com \
 		-federationapi SupportLib prebuilts/sdk/current/support-api.txt
 
+# Federate AndroidX references against local API file.
+framework_docs_LOCAL_DROIDDOC_OPTIONS += \
+		-federate AndroidX https://developer.android.com \
+		-federationapi AndroidX prebuilts/sdk/current/androidx-api.txt
+
 # ====  Public API diff ===========================
 include $(CLEAR_VARS)
 
diff --git a/api/current.txt b/api/current.txt
index af042fb..670f6ca 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6115,8 +6115,12 @@
     method public android.view.WindowAnimationFrameStats getWindowAnimationFrameStats();
     method public android.view.WindowContentFrameStats getWindowContentFrameStats(int);
     method public java.util.List<android.view.accessibility.AccessibilityWindowInfo> getWindows();
+    method public void grantRuntimePermission(java.lang.String, java.lang.String);
+    method public void grantRuntimePermissionAsUser(java.lang.String, java.lang.String, android.os.UserHandle);
     method public boolean injectInputEvent(android.view.InputEvent, boolean);
     method public boolean performGlobalAction(int);
+    method public void revokeRuntimePermission(java.lang.String, java.lang.String);
+    method public void revokeRuntimePermissionAsUser(java.lang.String, java.lang.String, android.os.UserHandle);
     method public void setOnAccessibilityEventListener(android.app.UiAutomation.OnAccessibilityEventListener);
     method public boolean setRotation(int);
     method public void setRunAsMonkey(boolean);
@@ -6501,7 +6505,7 @@
     method public boolean installExistingPackage(android.content.ComponentName, java.lang.String);
     method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String);
     method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean);
-    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, boolean, boolean);
+    method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate[], java.lang.String, int);
     method public boolean isActivePasswordSufficient();
     method public boolean isAdminActive(android.content.ComponentName);
     method public boolean isAffiliatedUser();
@@ -6685,6 +6689,8 @@
     field public static final int ID_TYPE_IMEI = 4; // 0x4
     field public static final int ID_TYPE_MEID = 8; // 0x8
     field public static final int ID_TYPE_SERIAL = 2; // 0x2
+    field public static final int INSTALLKEY_REQUEST_CREDENTIALS_ACCESS = 1; // 0x1
+    field public static final int INSTALLKEY_SET_USER_SELECTABLE = 2; // 0x2
     field public static final int KEYGUARD_DISABLE_BIOMETRICS = 416; // 0x1a0
     field public static final int KEYGUARD_DISABLE_FACE = 128; // 0x80
     field public static final int KEYGUARD_DISABLE_FEATURES_ALL = 2147483647; // 0x7fffffff
diff --git a/api/test-current.txt b/api/test-current.txt
index d323725..b520dfb 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1,8 +1,10 @@
 package android {
 
   public static final class Manifest.permission {
+    field public static final java.lang.String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING";
     field public static final java.lang.String BRIGHTNESS_SLIDER_USAGE = "android.permission.BRIGHTNESS_SLIDER_USAGE";
     field public static final java.lang.String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS";
+    field public static final java.lang.String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS";
   }
 
 }
@@ -127,8 +129,8 @@
   public final class UiAutomation {
     method public void destroy();
     method public android.os.ParcelFileDescriptor[] executeShellCommandRw(java.lang.String);
-    method public boolean grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
-    method public boolean revokeRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
+    method public deprecated boolean grantRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
+    method public deprecated boolean revokeRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
   }
 
   public class UiModeManager {
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 0ded515..70e3fad 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -1,4 +1,5 @@
 Landroid/accounts/AccountManager;->mContext:Landroid/content/Context;
+Landroid/accounts/IAccountAuthenticatorResponse$Stub;-><init>()V
 Landroid/accounts/IAccountManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountManager;
 Landroid/accounts/IAccountManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/animation/LayoutTransition;->cancel()V
@@ -236,6 +237,7 @@
 Landroid/app/IActivityManager;->getTaskForActivity(Landroid/os/IBinder;Z)I
 Landroid/app/IActivityManager;->moveTaskToFront(IILandroid/os/Bundle;)V
 Landroid/app/IActivityManager;->publishContentProviders(Landroid/app/IApplicationThread;Ljava/util/List;)V
+Landroid/app/IActivityManager;->requestBugReport(I)V
 Landroid/app/IActivityManager;->resumeAppSwitches()V
 Landroid/app/IActivityManager;->setRequestedOrientation(Landroid/os/IBinder;I)V
 Landroid/app/IActivityManager;->setTaskResizeable(II)V
@@ -948,6 +950,7 @@
 Landroid/media/IAudioService;->setStreamVolume(IIILjava/lang/String;)V
 Landroid/media/IAudioService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IAudioService;
 Landroid/media/IAudioService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/media/IRemoteDisplayCallback;->onStateChanged(Landroid/media/RemoteDisplayState;)V
 Landroid/media/IVolumeController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IVolumeController;
 Landroid/media/JetPlayer;->mNativePlayerInJavaObj:J
 Landroid/media/JetPlayer;->postEventFromNative(Ljava/lang/Object;III)V
@@ -1000,6 +1003,8 @@
 Landroid/media/RemoteDisplay;->notifyDisplayConnected(Landroid/view/Surface;IIII)V
 Landroid/media/RemoteDisplay;->notifyDisplayDisconnected()V
 Landroid/media/RemoteDisplay;->notifyDisplayError(I)V
+Landroid/media/RemoteDisplayState;->displays:Ljava/util/ArrayList;
+Landroid/media/RemoteDisplayState;-><init>()V
 Landroid/media/RingtoneManager;->getRingtone(Landroid/content/Context;Landroid/net/Uri;I)Landroid/media/Ringtone;
 Landroid/media/session/MediaSessionLegacyHelper;->getHelper(Landroid/content/Context;)Landroid/media/session/MediaSessionLegacyHelper;
 Landroid/media/session/MediaSession;->mCallback:Landroid/media/session/MediaSession$CallbackMessageHandler;
@@ -1011,6 +1016,11 @@
 Landroid/media/soundtrigger/SoundTriggerManager;->stopRecognition(Ljava/util/UUID;)I
 Landroid/media/soundtrigger/SoundTriggerManager;->unloadSoundModel(Ljava/util/UUID;)I
 Landroid/media/SubtitleController;->mHandler:Landroid/os/Handler;
+Landroid/media/SubtitleTrack$RenderingWidget;->draw(Landroid/graphics/Canvas;)V
+Landroid/media/SubtitleTrack$RenderingWidget;->onAttachedToWindow()V
+Landroid/media/SubtitleTrack$RenderingWidget;->onDetachedFromWindow()V
+Landroid/media/SubtitleTrack$RenderingWidget;->setOnChangedListener(Landroid/media/SubtitleTrack$RenderingWidget$OnChangedListener;)V
+Landroid/media/SubtitleTrack$RenderingWidget;->setSize(II)V
 Landroid/media/ThumbnailUtils;->createImageThumbnail(Ljava/lang/String;I)Landroid/graphics/Bitmap;
 Landroid/media/ToneGenerator;->mNativeContext:J
 Landroid/media/VolumeShaper$Configuration;-><init>(IIIDI[F[F)V
@@ -1116,6 +1126,8 @@
 Landroid/net/wifi/p2p/WifiP2pManager;->requestPersistentGroupInfo(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Landroid/net/wifi/p2p/WifiP2pManager$PersistentGroupInfoListener;)V
 Landroid/net/wifi/p2p/WifiP2pManager;->setDeviceName(Landroid/net/wifi/p2p/WifiP2pManager$Channel;Ljava/lang/String;Landroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V
 Landroid/net/wifi/p2p/WifiP2pManager;->setWifiP2pChannels(Landroid/net/wifi/p2p/WifiP2pManager$Channel;IILandroid/net/wifi/p2p/WifiP2pManager$ActionListener;)V
+Landroid/net/wifi/p2p/WifiP2pManager$Channel;->mAsyncChannel:Lcom/android/internal/util/AsyncChannel;
+Landroid/net/wifi/p2p/WifiP2pManager$Channel;->putListener(Ljava/lang/Object;)I
 Landroid/net/wifi/ScanResult;->anqpDomainId:I
 Landroid/net/wifi/ScanResult;->anqpLines:Ljava/util/List;
 Landroid/net/wifi/ScanResult;->distanceCm:I
@@ -1966,6 +1978,7 @@
 Landroid/util/Rational;->mNumerator:I
 Landroid/util/Singleton;->mInstance:Ljava/lang/Object;
 Landroid/util/Slog;->d(Ljava/lang/String;Ljava/lang/String;)I
+Landroid/util/Slog;->w(Ljava/lang/String;Ljava/lang/String;)I
 Landroid/util/SparseIntArray;->mKeys:[I
 Landroid/util/SparseIntArray;->mSize:I
 Landroid/util/SparseIntArray;->mValues:[I
@@ -2285,6 +2298,7 @@
 Landroid/webkit/IWebViewUpdateService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/webkit/WebResourceResponse;->mImmutable:Z
 Landroid/webkit/WebSyncManager;->mHandler:Landroid/os/Handler;
+Landroid/webkit/WebViewClient;->onUnhandledInputEvent(Landroid/webkit/WebView;Landroid/view/InputEvent;)V
 Landroid/webkit/WebView;->debugDump()V
 Landroid/webkit/WebView;->disablePlatformNotifications()V
 Landroid/webkit/WebView;->emulateShiftHeld()V
@@ -2714,11 +2728,15 @@
 Lcom/android/internal/R$styleable;->CheckBoxPreference_summaryOn:I
 Lcom/android/internal/R$styleable;->CompoundButton_button:I
 Lcom/android/internal/R$styleable;->CompoundButton:[I
+Lcom/android/internal/R$styleable;->DialogPreference_dialogTitle:I
+Lcom/android/internal/R$styleable;->DialogPreference:[I
 Lcom/android/internal/R$styleable;->EdgeEffect_colorEdgeEffect:I
 Lcom/android/internal/R$styleable;->EdgeEffect:[I
 Lcom/android/internal/R$styleable;->IconMenuView:[I
 Lcom/android/internal/R$styleable;->ImageView:[I
 Lcom/android/internal/R$styleable;->ImageView_src:I
+Lcom/android/internal/R$styleable;->ListPreference_entries:I
+Lcom/android/internal/R$styleable;->ListPreference:[I
 Lcom/android/internal/R$styleable;->Preference_defaultValue:I
 Lcom/android/internal/R$styleable;->Preference_dependency:I
 Lcom/android/internal/R$styleable;->Preference_enabled:I
@@ -2784,6 +2802,7 @@
 Lcom/android/internal/telephony/ITelephony$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Lcom/android/internal/telephony/ITelephony$Stub;->TRANSACTION_getDeviceId:I
 Lcom/android/internal/textservice/ITextServicesManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Lcom/android/internal/util/AsyncChannel;->sendMessage(III)V
 Lcom/android/internal/util/FastPrintWriter;-><init>(Ljava/io/OutputStream;)V
 Lcom/android/internal/util/XmlUtils;->readMapXml(Ljava/io/InputStream;)Ljava/util/HashMap;
 Lcom/android/internal/view/IInputMethodManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodManager;
@@ -2960,6 +2979,7 @@
 Ljava/lang/Runtime;->nativeLoad(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/String;
 Ljava/lang/Short;->value:S
 Ljava/lang/String;-><init>(II[C)V
+Ljava/lang/System;->arraycopy([II[III)V
 Ljava/lang/System;-><init>()V
 Ljava/lang/Thread;->daemon:Z
 Ljava/lang/Thread;->dispatchUncaughtException(Ljava/lang/Throwable;)V
@@ -3071,5 +3091,7 @@
 Lorg/apache/http/conn/ssl/SSLSocketFactory;-><init>(Ljavax/net/ssl/SSLSocketFactory;)V
 Lorg/apache/http/conn/ssl/SSLSocketFactory;-><init>()V
 Lorg/json/JSONArray;->values:Ljava/util/List;
+Lorg/json/JSONObject;->append(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
+Lorg/json/JSONObject;->keySet()Ljava/util/Set;
 Lorg/json/JSONObject;->writeTo(Lorg/json/JSONStringer;)V
 Lsun/misc/Unsafe;->theUnsafe:Lsun/misc/Unsafe;
diff --git a/config/hiddenapi-vendor-list.txt b/config/hiddenapi-vendor-list.txt
index 6b52850..61ae6e7 100644
--- a/config/hiddenapi-vendor-list.txt
+++ b/config/hiddenapi-vendor-list.txt
@@ -32,7 +32,6 @@
 Landroid/app/IActivityManager;->getTaskSnapshot(IZ)Landroid/app/ActivityManager$TaskSnapshot;
 Landroid/app/IActivityManager;->registerTaskStackListener(Landroid/app/ITaskStackListener;)V
 Landroid/app/IActivityManager;->removeTask(I)Z
-Landroid/app/IActivityManager;->requestBugReport(I)V
 Landroid/app/IActivityManager;->startActivityAsUser(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;I)I
 Landroid/app/IActivityManager;->startActivityFromRecents(ILandroid/os/Bundle;)I
 Landroid/app/IActivityManager;->startActivity(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;)I
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 8f01685..bd4933a 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -24,7 +24,6 @@
 import android.annotation.NonNull;
 import android.annotation.TestApi;
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -47,6 +46,7 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityWindowInfo;
 import android.view.accessibility.IAccessibilityInteractionConnection;
+
 import libcore.io.IoUtils;
 
 import java.io.IOException;
@@ -876,15 +876,35 @@
     }
 
     /**
+     * Grants a runtime permission to a package.
+     * @param packageName The package to which to grant.
+     * @param permission The permission to grant.
+     * @throws SecurityException if unable to grant the permission.
+     */
+    public void grantRuntimePermission(String packageName, String permission) {
+        grantRuntimePermissionAsUser(packageName, permission, android.os.Process.myUserHandle());
+    }
+
+    /**
+     * @deprecated replaced by
+     *             {@link #grantRuntimePermissionAsUser(String, String, UserHandle)}.
+     * @hide
+     */
+    @Deprecated
+    @TestApi
+    public boolean grantRuntimePermission(String packageName, String permission,
+            UserHandle userHandle) {
+        grantRuntimePermissionAsUser(packageName, permission, userHandle);
+        return true;
+    }
+
+    /**
      * Grants a runtime permission to a package for a user.
      * @param packageName The package to which to grant.
      * @param permission The permission to grant.
-     * @return Whether granting succeeded.
-     *
-     * @hide
+     * @throws SecurityException if unable to grant the permission.
      */
-    @TestApi
-    public boolean grantRuntimePermission(String packageName, String permission,
+    public void grantRuntimePermissionAsUser(String packageName, String permission,
             UserHandle userHandle) {
         synchronized (mLock) {
             throwIfNotConnectedLocked();
@@ -896,25 +916,42 @@
             // Calling out without a lock held.
             mUiAutomationConnection.grantRuntimePermission(packageName,
                     permission, userHandle.getIdentifier());
-            // TODO: The package manager API should return boolean.
-            return true;
-        } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error granting runtime permission", re);
+        } catch (Exception e) {
+            throw new SecurityException("Error granting runtime permission", e);
         }
-        return false;
     }
 
     /**
-     * Revokes a runtime permission from a package for a user.
-     * @param packageName The package from which to revoke.
-     * @param permission The permission to revoke.
-     * @return Whether revoking succeeded.
-     *
+     * Revokes a runtime permission from a package.
+     * @param packageName The package to which to grant.
+     * @param permission The permission to grant.
+     * @throws SecurityException if unable to revoke the permission.
+     */
+    public void revokeRuntimePermission(String packageName, String permission) {
+        revokeRuntimePermissionAsUser(packageName, permission, android.os.Process.myUserHandle());
+    }
+
+    /**
+     * @deprecated replaced by
+     *             {@link #revokeRuntimePermissionAsUser(String, String, UserHandle)}.
      * @hide
      */
+    @Deprecated
     @TestApi
     public boolean revokeRuntimePermission(String packageName, String permission,
             UserHandle userHandle) {
+        revokeRuntimePermissionAsUser(packageName, permission, userHandle);
+        return true;
+    }
+
+    /**
+     * Revokes a runtime permission from a package.
+     * @param packageName The package to which to grant.
+     * @param permission The permission to grant.
+     * @throws SecurityException if unable to revoke the permission.
+     */
+    public void revokeRuntimePermissionAsUser(String packageName, String permission,
+            UserHandle userHandle) {
         synchronized (mLock) {
             throwIfNotConnectedLocked();
         }
@@ -925,12 +962,9 @@
             // Calling out without a lock held.
             mUiAutomationConnection.revokeRuntimePermission(packageName,
                     permission, userHandle.getIdentifier());
-            // TODO: The package manager API should return boolean.
-            return true;
-        } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error revoking runtime permission", re);
+        } catch (Exception e) {
+            throw new SecurityException("Error granting runtime permission", e);
         }
-        return false;
     }
 
     /**
@@ -949,6 +983,7 @@
         synchronized (mLock) {
             throwIfNotConnectedLocked();
         }
+        warnIfBetterCommand(command);
 
         ParcelFileDescriptor source = null;
         ParcelFileDescriptor sink = null;
@@ -991,6 +1026,7 @@
         synchronized (mLock) {
             throwIfNotConnectedLocked();
         }
+        warnIfBetterCommand(command);
 
         ParcelFileDescriptor source_read = null;
         ParcelFileDescriptor sink_read = null;
@@ -1056,6 +1092,16 @@
         }
     }
 
+    private void warnIfBetterCommand(String cmd) {
+        if (cmd.startsWith("pm grant ")) {
+            Log.w(LOG_TAG, "UiAutomation.grantRuntimePermission() "
+                    + "is more robust and should be used instead of 'pm grant'");
+        } else if (cmd.startsWith("pm revoke ")) {
+            Log.w(LOG_TAG, "UiAutomation.revokeRuntimePermission() "
+                    + "is more robust and should be used instead of 'pm revoke'");
+        }
+    }
+
     private class IAccessibilityServiceClientImpl extends IAccessibilityServiceClientWrapper {
 
         public IAccessibilityServiceClientImpl(Looper looper) {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 5c55e4f..1534a15 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -124,6 +124,7 @@
 @SystemService(Context.DEVICE_POLICY_SERVICE)
 @RequiresFeature(PackageManager.FEATURE_DEVICE_ADMIN)
 public class DevicePolicyManager {
+
     private static String TAG = "DevicePolicyManager";
 
     private final Context mContext;
@@ -1751,6 +1752,25 @@
     public static final int ID_TYPE_MEID = 8;
 
     /**
+     * Specifies that the calling app should be granted access to the installed credentials
+     * immediately. Otherwise, access to the credentials will be gated by user approval.
+     * For use with {@link #installKeyPair(ComponentName, PrivateKey, Certificate[], String, int)}
+     *
+     * @see #installKeyPair(ComponentName, PrivateKey, Certificate[], String, int)
+     */
+    public static final int INSTALLKEY_REQUEST_CREDENTIALS_ACCESS = 1;
+
+    /**
+     * Specifies that a user can select the key via the Certificate Selection prompt.
+     * If this flag is not set when calling {@link #installKeyPair}, the key can only be granted
+     * access by implementing {@link android.app.admin.DeviceAdminReceiver#onChoosePrivateKeyAlias}.
+     * For use with {@link #installKeyPair(ComponentName, PrivateKey, Certificate[], String, int)}
+     *
+     * @see #installKeyPair(ComponentName, PrivateKey, Certificate[], String, int)
+     */
+    public static final int INSTALLKEY_SET_USER_SELECTABLE = 2;
+
+    /**
      * Broadcast action: sent when the profile owner is set, changed or cleared.
      *
      * This broadcast is sent only to the user managed by the new profile owner.
@@ -4126,7 +4146,11 @@
      */
     public boolean installKeyPair(@Nullable ComponentName admin, @NonNull PrivateKey privKey,
             @NonNull Certificate[] certs, @NonNull String alias, boolean requestAccess) {
-        return installKeyPair(admin, privKey, certs, alias, requestAccess, true);
+        int flags = INSTALLKEY_SET_USER_SELECTABLE;
+        if (requestAccess) {
+            flags |= INSTALLKEY_REQUEST_CREDENTIALS_ACCESS;
+        }
+        return installKeyPair(admin, privKey, certs, alias, flags);
     }
 
     /**
@@ -4150,13 +4174,9 @@
      *        {@link android.security.KeyChain#getCertificateChain}.
      * @param alias The private key alias under which to install the certificate. If a certificate
      *        with that alias already exists, it will be overwritten.
-     * @param requestAccess {@code true} to request that the calling app be granted access to the
-     *        credentials immediately. Otherwise, access to the credentials will be gated by user
-     *        approval.
-     * @param isUserSelectable {@code true} to indicate that a user can select this key via the
-     *        Certificate Selection prompt, false to indicate that this key can only be granted
-     *        access by implementing
-     *        {@link android.app.admin.DeviceAdminReceiver#onChoosePrivateKeyAlias}.
+     * @param flags Flags to request that the calling app be granted access to the credentials
+     *        and set the key to be user-selectable. See {@link #INSTALLKEY_SET_USER_SELECTABLE} and
+     *        {@link #INSTALLKEY_REQUEST_CREDENTIALS_ACCESS}.
      * @return {@code true} if the keys were installed, {@code false} otherwise.
      * @throws SecurityException if {@code admin} is not {@code null} and not a device or profile
      *         owner.
@@ -4165,9 +4185,12 @@
      * @see #DELEGATION_CERT_INSTALL
      */
     public boolean installKeyPair(@Nullable ComponentName admin, @NonNull PrivateKey privKey,
-            @NonNull Certificate[] certs, @NonNull String alias, boolean requestAccess,
-            boolean isUserSelectable) {
+            @NonNull Certificate[] certs, @NonNull String alias, int flags) {
         throwIfParentInstance("installKeyPair");
+        boolean requestAccess = (flags & INSTALLKEY_REQUEST_CREDENTIALS_ACCESS)
+                == INSTALLKEY_REQUEST_CREDENTIALS_ACCESS;
+        boolean isUserSelectable = (flags & INSTALLKEY_SET_USER_SELECTABLE)
+                == INSTALLKEY_SET_USER_SELECTABLE;
         try {
             final byte[] pemCert = Credentials.convertToPem(certs[0]);
             byte[] pemChain = null;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 48d394a..cb375d5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2016,11 +2016,11 @@
     <permission android:name="android.permission.REMOVE_TASKS"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi @hide Allows an application to create/manage/remove stacks -->
+    <!-- @SystemApi @TestApi @hide Allows an application to create/manage/remove stacks -->
     <permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"
         android:protectionLevel="signature|privileged|development" />
 
-    <!-- @SystemApi @hide Allows an application to embed other activities -->
+    <!-- @SystemApi @TestApi @hide Allows an application to embed other activities -->
     <permission android:name="android.permission.ACTIVITY_EMBEDDING"
                 android:protectionLevel="signature|privileged|development" />
 
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 7ffca173..d527465 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -323,10 +323,10 @@
 
         if (notif != null) {
             mNotificationManager.notifyAsUser(vol.getId(), SystemMessage.NOTE_STORAGE_PUBLIC,
-                    notif, UserHandle.ALL);
+                    notif, UserHandle.of(vol.getMountUserId()));
         } else {
             mNotificationManager.cancelAsUser(vol.getId(), SystemMessage.NOTE_STORAGE_PUBLIC,
-                    UserHandle.ALL);
+                    UserHandle.of(vol.getMountUserId()));
         }
     }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 8941b49..de112f9 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -853,11 +853,7 @@
             if (mSecurityPolicy.findA11yWindowInfoById(windowId) == null) {
                 return null;
             }
-            IBinder token = mGlobalWindowTokens.get(windowId);
-            if (token != null) {
-                return token;
-            }
-            return getCurrentUserStateLocked().mWindowTokens.get(windowId);
+            return findWindowTokenLocked(windowId);
         }
     }
 
@@ -2527,6 +2523,14 @@
         getInteractionBridge().clearAccessibilityFocusNotLocked(windowId);
     }
 
+    private IBinder findWindowTokenLocked(int windowId) {
+        IBinder token = mGlobalWindowTokens.get(windowId);
+        if (token != null) {
+            return token;
+        }
+        return getCurrentUserStateLocked().mWindowTokens.get(windowId);
+    }
+
     private int findWindowIdLocked(IBinder token) {
         final int globalIndex = mGlobalWindowTokens.indexOfValue(token);
         if (globalIndex >= 0) {
@@ -2986,7 +2990,7 @@
                 // the accessibility layer reports which are windows
                 // that a sighted user can touch.
                 default: {
-                    return isRetrievalAllowingWindow(event.getWindowId());
+                    return isRetrievalAllowingWindowLocked(event.getWindowId());
                 }
             }
         }
@@ -3438,7 +3442,8 @@
 
         public boolean canGetAccessibilityNodeInfoLocked(
                 AbstractAccessibilityServiceConnection service, int windowId) {
-            return canRetrieveWindowContentLocked(service) && isRetrievalAllowingWindow(windowId);
+            return canRetrieveWindowContentLocked(service)
+                    && isRetrievalAllowingWindowLocked(windowId);
         }
 
         public boolean canRetrieveWindowsLocked(AbstractAccessibilityServiceConnection service) {
@@ -3523,17 +3528,40 @@
                     || userId == UserHandle.USER_CURRENT_OR_SELF);
         }
 
-        private boolean isRetrievalAllowingWindow(int windowId) {
+        private boolean isRetrievalAllowingWindowLocked(int windowId) {
             // The system gets to interact with any window it wants.
             if (Binder.getCallingUid() == Process.SYSTEM_UID) {
                 return true;
             }
+            if (Binder.getCallingUid() == Process.SHELL_UID) {
+                if (!isShellAllowedToRetrieveWindowLocked(windowId)) {
+                    return false;
+                }
+            }
             if (windowId == mActiveWindowId) {
                 return true;
             }
             return findA11yWindowInfoById(windowId) != null;
         }
 
+        private boolean isShellAllowedToRetrieveWindowLocked(int windowId) {
+            long token = Binder.clearCallingIdentity();
+            try {
+                IBinder windowToken = findWindowTokenLocked(windowId);
+                if (windowToken == null) {
+                    return false;
+                }
+                int userId = mWindowManagerService.getWindowOwnerUserId(windowToken);
+                if (userId == UserHandle.USER_NULL) {
+                    return false;
+                }
+                return !mUserManager.hasUserRestriction(
+                        UserManager.DISALLOW_DEBUGGING_FEATURES, UserHandle.of(userId));
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
         public AccessibilityWindowInfo findA11yWindowInfoById(int windowId) {
             return mA11yWindowInfoById.get(windowId);
         }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index d4ecd8b..3253f2e 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -19,7 +19,6 @@
 import static android.Manifest.permission.MANAGE_AUTO_FILL;
 import static android.content.Context.AUTOFILL_MANAGER_SERVICE;
 
-import static com.android.server.autofill.Helper.bundleToString;
 import static com.android.server.autofill.Helper.sDebug;
 import static com.android.server.autofill.Helper.sFullScreenMode;
 import static com.android.server.autofill.Helper.sPartitionMaxCount;
@@ -193,8 +192,7 @@
                 if (disabledBefore == disabledNow) {
                     // Nothing changed, do nothing.
                     if (sDebug) {
-                        Slog.d(TAG, "Autofill restriction did not change for user " + userId + ": "
-                                + bundleToString(newRestrictions));
+                        Slog.d(TAG, "Autofill restriction did not change for user " + userId);
                         return;
                     }
                 }
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index a202aaf..78526f5 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -79,28 +79,6 @@
         throw new UnsupportedOperationException("contains static members only");
     }
 
-    static void append(StringBuilder builder, Bundle bundle) {
-        if (bundle == null || !sVerbose) {
-            builder.append("null");
-            return;
-        }
-        final Set<String> keySet = bundle.keySet();
-        builder.append("[Bundle with ").append(keySet.size()).append(" extras:");
-        for (String key : keySet) {
-            final Object value = bundle.get(key);
-            builder.append(' ').append(key).append('=');
-            builder.append((value instanceof Object[])
-                    ? Arrays.toString((Objects[]) value) : value);
-        }
-        builder.append(']');
-    }
-
-    static String bundleToString(Bundle bundle) {
-        final StringBuilder builder = new StringBuilder();
-        append(builder, bundle);
-        return builder.toString();
-    }
-
     @Nullable
     static AutofillId[] toArray(@Nullable ArraySet<AutofillId> set) {
         if (set == null) return null;
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 706fb1a..706a6ab 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -2502,8 +2502,10 @@
         }
 
         pw.print(prefix); pw.print("mHasCallback: "); pw.println(mHasCallback);
-        pw.print(prefix); pw.print("mClientState: "); pw.println(
-                Helper.bundleToString(mClientState));
+        if (mClientState != null) {
+            pw.print(prefix); pw.println("mClientState: "); pw.print(mClientState.getSize()); pw
+                .println(" items");
+        }
         pw.print(prefix); pw.print("mCompatMode: "); pw.println(mCompatMode);
         pw.print(prefix); pw.print("mUrlBar: ");
         if (mUrlBar == null) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 210857e..31b0461 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2149,7 +2149,8 @@
                 final NotificationChannel channel = channels.get(i);
                 Preconditions.checkNotNull(channel, "channel in list is null");
                 mRankingHelper.createNotificationChannel(pkg, uid, channel,
-                        true /* fromTargetApp */);
+                        true /* fromTargetApp */, mConditionProviders.isPackageOrComponentAllowed(
+                                pkg, UserHandle.getUserId(uid)));
                 mListeners.notifyNotificationChannelChanged(pkg,
                         UserHandle.getUserHandleForUid(uid),
                         mRankingHelper.getNotificationChannel(pkg, uid, channel.getId(), false),
@@ -4691,11 +4692,12 @@
 
     private boolean playSound(final NotificationRecord record, Uri soundUri) {
         boolean looping = (record.getNotification().flags & Notification.FLAG_INSISTENT) != 0;
-        // do not play notifications if there is a user of exclusive audio focus
-        // or the device is in vibrate mode
-        if (!mAudioManager.isAudioFocusExclusive() && (mAudioManager.getRingerModeInternal()
-                != AudioManager.RINGER_MODE_VIBRATE || mAudioManager.getStreamVolume(
-                AudioAttributes.toLegacyStreamType(record.getAudioAttributes())) != 0)) {
+        // play notifications if there is no user of exclusive audio focus
+        // and the stream volume is not 0 (non-zero volume implies not silenced by SILENT or
+        //   VIBRATE ringer mode)
+        if (!mAudioManager.isAudioFocusExclusive()
+                && (mAudioManager.getStreamVolume(
+                        AudioAttributes.toLegacyStreamType(record.getAudioAttributes())) != 0)) {
             final long identity = Binder.clearCallingIdentity();
             try {
                 final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index b1b0bf2..af64683 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -38,7 +38,7 @@
     ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
             int uid, boolean includeDeleted, boolean includeNonGrouped);
     void createNotificationChannel(String pkg, int uid, NotificationChannel channel,
-            boolean fromTargetApp);
+            boolean fromTargetApp, boolean hasDndAccess);
     void updateNotificationChannel(String pkg, int uid, NotificationChannel channel, boolean fromUser);
     NotificationChannel getNotificationChannel(String pkg, int uid, String channelId, boolean includeDeleted);
     void deleteNotificationChannel(String pkg, int uid, String channelId);
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index f163113..98d5c9a 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -569,7 +569,7 @@
 
     @Override
     public void createNotificationChannel(String pkg, int uid, NotificationChannel channel,
-            boolean fromTargetApp) {
+            boolean fromTargetApp, boolean hasDndAccess) {
         Preconditions.checkNotNull(pkg);
         Preconditions.checkNotNull(channel);
         Preconditions.checkNotNull(channel.getId());
@@ -610,8 +610,9 @@
                 existing.setImportance(channel.getImportance());
             }
 
-            // system apps can bypass dnd if the user hasn't changed any fields on the channel yet
-            if (existing.getUserLockedFields() == 0 & isSystemApp) {
+            // 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 && (isSystemApp || hasDndAccess)) {
                 existing.setBypassDnd(channel.canBypassDnd());
             }
 
@@ -624,7 +625,7 @@
         }
 
         // Reset fields that apps aren't allowed to set.
-        if (fromTargetApp && !isSystemApp) {
+        if (fromTargetApp && !(isSystemApp || hasDndAccess)) {
             channel.setBypassDnd(r.priority == Notification.PRIORITY_MAX);
         }
         if (fromTargetApp) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 6bceda5..6686b80 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -419,4 +419,10 @@
      * @see android.view.IWindowManager#lockNow
      */
     public abstract void lockNow();
+
+    /**
+     * Return the user that owns the given window, {@link android.os.UserHandle#USER_NULL} if
+     * the window token is not found.
+     */
+    public abstract int getWindowOwnerUserId(IBinder windowToken);
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0b5c006..c8b4f88 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7351,6 +7351,17 @@
         public void lockNow() {
             WindowManagerService.this.lockNow(null);
         }
+
+        @Override
+        public int getWindowOwnerUserId(IBinder token) {
+            synchronized (mWindowMap) {
+                WindowState window = mWindowMap.get(token);
+                if (window != null) {
+                    return UserHandle.getUserId(window.mOwnerUid);
+                }
+                return UserHandle.USER_NULL;
+            }
+        }
     }
 
     void registerAppFreezeListener(AppFreezeListener listener) {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
index 09d88fd..0815876 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -367,8 +367,8 @@
 
         mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
         mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
-        mHelper.createNotificationChannel(PKG, UID, channel1, true);
-        mHelper.createNotificationChannel(PKG, UID, channel2, false);
+        mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
+        mHelper.createNotificationChannel(PKG, UID, channel2, false, false);
 
         mHelper.setShowBadge(PKG, UID, true);
 
@@ -427,10 +427,10 @@
 
         mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
         mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
-        mHelper.createNotificationChannel(PKG, UID, channel1, true);
-        mHelper.createNotificationChannel(PKG, UID, channel2, false);
-        mHelper.createNotificationChannel(PKG, UID, channel3, false);
-        mHelper.createNotificationChannel(UPDATED_PKG, UID2, getChannel(), true);
+        mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
+        mHelper.createNotificationChannel(PKG, UID, channel2, false, false);
+        mHelper.createNotificationChannel(PKG, UID, channel3, false, false);
+        mHelper.createNotificationChannel(UPDATED_PKG, UID2, getChannel(), true, false);
 
         mHelper.setShowBadge(PKG, UID, true);
 
@@ -481,7 +481,7 @@
         NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_LOW);
         channel.setSound(SOUND_URI, mAudioAttributes);
-        mHelper.createNotificationChannel(PKG, UID, channel, true);
+        mHelper.createNotificationChannel(PKG, UID, channel, true, false);
 
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
 
@@ -507,7 +507,7 @@
         NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_LOW);
         channel.setSound(SOUND_URI, mAudioAttributes);
-        mHelper.createNotificationChannel(PKG, UID, channel, true);
+        mHelper.createNotificationChannel(PKG, UID, channel, true, false);
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
 
         loadStreamXml(baos, true);
@@ -528,7 +528,7 @@
         NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_LOW);
         channel.setSound(SOUND_URI, mAudioAttributes);
-        mHelper.createNotificationChannel(PKG, UID, channel, true);
+        mHelper.createNotificationChannel(PKG, UID, channel, true, false);
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
 
         loadStreamXml(baos, true);
@@ -569,7 +569,7 @@
         NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_LOW);
         channel.setSound(null, mAudioAttributes);
-        mHelper.createNotificationChannel(PKG, UID, channel, true);
+        mHelper.createNotificationChannel(PKG, UID, channel, true, false);
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, true, channel.getId());
 
         loadStreamXml(baos, true);
@@ -593,9 +593,9 @@
 
         mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
         mHelper.createNotificationChannelGroup(PKG, UID, ncg2, true);
-        mHelper.createNotificationChannel(PKG, UID, channel1, true);
-        mHelper.createNotificationChannel(PKG, UID, channel2, false);
-        mHelper.createNotificationChannel(PKG, UID, channel3, true);
+        mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
+        mHelper.createNotificationChannel(PKG, UID, channel2, false, false);
+        mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
 
         mHelper.deleteNotificationChannel(PKG, UID, channel1.getId());
         mHelper.deleteNotificationChannelGroup(PKG, UID, ncg.getId());
@@ -701,7 +701,7 @@
     @Test
     public void testDeletesDefaultChannelAfterChannelIsCreated() throws Exception {
         mHelper.createNotificationChannel(PKG, UID,
-                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true);
+                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
                 NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
 
@@ -721,7 +721,7 @@
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
                 NotificationChannel.DEFAULT_CHANNEL_ID, "bananas");
         mHelper.createNotificationChannel(PKG, UID,
-                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true);
+                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
 
         loadStreamXml(baos, false);
 
@@ -734,36 +734,39 @@
         mHelper.setImportance(PKG, UID, IMPORTANCE_NONE);
 
         mHelper.createNotificationChannel(PKG, UID,
-                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true);
+                new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
     }
 
     @Test
     public void testCreateChannel_badImportance() throws Exception {
         try {
             mHelper.createNotificationChannel(PKG, UID,
-                    new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE - 1), true);
+                    new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE - 1),
+                    true, false);
             fail("Was allowed to create a channel with invalid importance");
         } catch (IllegalArgumentException e) {
             // yay
         }
         try {
             mHelper.createNotificationChannel(PKG, UID,
-                    new NotificationChannel("bananas", "bananas", IMPORTANCE_UNSPECIFIED), true);
+                    new NotificationChannel("bananas", "bananas", IMPORTANCE_UNSPECIFIED),
+                    true, false);
             fail("Was allowed to create a channel with invalid importance");
         } catch (IllegalArgumentException e) {
             // yay
         }
         try {
             mHelper.createNotificationChannel(PKG, UID,
-                    new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1), true);
+                    new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX + 1),
+                    true, false);
             fail("Was allowed to create a channel with invalid importance");
         } catch (IllegalArgumentException e) {
             // yay
         }
         mHelper.createNotificationChannel(PKG, UID,
-                new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true);
+                new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false);
         mHelper.createNotificationChannel(PKG, UID,
-                new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true);
+                new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false);
     }
 
 
@@ -777,7 +780,7 @@
         channel.setBypassDnd(true);
         channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
 
-        mHelper.createNotificationChannel(PKG, UID, channel, false);
+        mHelper.createNotificationChannel(PKG, UID, channel, false, false);
 
         // same id, try to update all fields
         final NotificationChannel channel2 =
@@ -824,7 +827,7 @@
     public void testUpdate_postUpgrade_noUpdateAppFields() throws Exception {
         final NotificationChannel channel = new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
 
-        mHelper.createNotificationChannel(PKG, UID, channel, false);
+        mHelper.createNotificationChannel(PKG, UID, channel, false, false);
         assertTrue(mHelper.canShowBadge(PKG, UID));
         assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG, UID));
         assertEquals(NotificationManager.VISIBILITY_NO_OVERRIDE,
@@ -865,7 +868,7 @@
         }
         channel.lockFields(lockMask);
 
-        mHelper.createNotificationChannel(PKG, UID, channel, true);
+        mHelper.createNotificationChannel(PKG, UID, channel, true, false);
 
         NotificationChannel savedChannel =
                 mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
@@ -894,7 +897,7 @@
         }
         channel.lockFields(lockMask);
 
-        mHelper.createNotificationChannel(PKG, UID, channel, true);
+        mHelper.createNotificationChannel(PKG, UID, channel, true, false);
 
         NotificationChannel savedChannel =
                 mHelper.getNotificationChannel(PKG, UID, channel.getId(), false);
@@ -920,7 +923,7 @@
 
     @Test
     public void testLockFields_soundAndVibration() throws Exception {
-        mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
+        mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
 
         final NotificationChannel update1 = getChannel();
         update1.setSound(new Uri.Builder().scheme("test").build(),
@@ -944,7 +947,7 @@
 
     @Test
     public void testLockFields_vibrationAndLights() throws Exception {
-        mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
+        mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
 
         final NotificationChannel update1 = getChannel();
         update1.setVibrationPattern(new long[]{7945, 46 ,246});
@@ -964,7 +967,7 @@
 
     @Test
     public void testLockFields_lightsAndImportance() throws Exception {
-        mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
+        mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
 
         final NotificationChannel update1 = getChannel();
         update1.setLightColor(Color.GREEN);
@@ -984,7 +987,7 @@
 
     @Test
     public void testLockFields_visibilityAndDndAndBadge() throws Exception {
-        mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
+        mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
         assertEquals(0,
                 mHelper.getNotificationChannel(PKG, UID, getChannel().getId(), false)
                         .getUserLockedFields());
@@ -1029,7 +1032,7 @@
         channel.enableVibration(true);
         channel.setVibrationPattern(new long[]{100, 67, 145, 156});
 
-        mHelper.createNotificationChannel(PKG, UID, channel, true);
+        mHelper.createNotificationChannel(PKG, UID, channel, true, false);
         mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
 
         // Does not return deleted channel
@@ -1058,8 +1061,8 @@
         NotificationChannel channel2 =
                 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
         channelMap.put(channel2.getId(), channel2);
-        mHelper.createNotificationChannel(PKG, UID, channel, true);
-        mHelper.createNotificationChannel(PKG, UID, channel2, true);
+        mHelper.createNotificationChannel(PKG, UID, channel, true, false);
+        mHelper.createNotificationChannel(PKG, UID, channel2, true, false);
 
         mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
 
@@ -1091,9 +1094,9 @@
                 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
         NotificationChannel channel3 =
                 new NotificationChannel("id4", "a", NotificationManager.IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG, UID, channel, true);
-        mHelper.createNotificationChannel(PKG, UID, channel2, true);
-        mHelper.createNotificationChannel(PKG, UID, channel3, true);
+        mHelper.createNotificationChannel(PKG, UID, channel, true, false);
+        mHelper.createNotificationChannel(PKG, UID, channel2, true, false);
+        mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
 
         mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
         mHelper.deleteNotificationChannel(PKG, UID, channel3.getId());
@@ -1109,14 +1112,14 @@
                 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setVibrationPattern(vibration);
 
-        mHelper.createNotificationChannel(PKG, UID, channel, true);
+        mHelper.createNotificationChannel(PKG, UID, channel, true, false);
         mHelper.deleteNotificationChannel(PKG, UID, channel.getId());
 
         NotificationChannel newChannel = new NotificationChannel(
                 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
         newChannel.setVibrationPattern(new long[]{100});
 
-        mHelper.createNotificationChannel(PKG, UID, newChannel, true);
+        mHelper.createNotificationChannel(PKG, UID, newChannel, true, false);
 
         // No long deleted, using old settings
         compareChannels(channel,
@@ -1128,7 +1131,7 @@
         assertTrue(mHelper.onlyHasDefaultChannel(PKG, UID));
         assertFalse(mHelper.onlyHasDefaultChannel(UPDATED_PKG, UID2));
 
-        mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
+        mHelper.createNotificationChannel(PKG, UID, getChannel(), true, false);
         assertFalse(mHelper.onlyHasDefaultChannel(PKG, UID));
     }
 
@@ -1136,7 +1139,7 @@
     public void testCreateChannel_defaultChannelId() throws Exception {
         try {
             mHelper.createNotificationChannel(PKG, UID, new NotificationChannel(
-                    NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true);
+                    NotificationChannel.DEFAULT_CHANNEL_ID, "ha", IMPORTANCE_HIGH), true, false);
             fail("Allowed to create default channel");
         } catch (IllegalArgumentException e) {
             // pass
@@ -1150,13 +1153,13 @@
                 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
         channel.setVibrationPattern(vibration);
 
-        mHelper.createNotificationChannel(PKG, UID, channel, true);
+        mHelper.createNotificationChannel(PKG, UID, channel, true, false);
 
         NotificationChannel newChannel = new NotificationChannel(
                 channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
         newChannel.setVibrationPattern(new long[]{100});
 
-        mHelper.createNotificationChannel(PKG, UID, newChannel, true);
+        mHelper.createNotificationChannel(PKG, UID, newChannel, true, false);
 
         // Old settings not overridden
         compareChannels(channel,
@@ -1169,7 +1172,7 @@
         final NotificationChannel channel = new NotificationChannel("id2", "name2",
                  NotificationManager.IMPORTANCE_DEFAULT);
         channel.setSound(sound, mAudioAttributes);
-        mHelper.createNotificationChannel(PKG, UID, channel, true);
+        mHelper.createNotificationChannel(PKG, UID, channel, true, false);
         assertEquals(sound, mHelper.getNotificationChannel(
                 PKG, UID, channel.getId(), false).getSound());
     }
@@ -1181,8 +1184,8 @@
         NotificationChannel channel2 =
                 new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
 
-        mHelper.createNotificationChannel(PKG, UID, channel1, true);
-        mHelper.createNotificationChannel(PKG, UID, channel2, false);
+        mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
+        mHelper.createNotificationChannel(PKG, UID, channel2, false, false);
 
         mHelper.permanentlyDeleteNotificationChannels(PKG, UID);
 
@@ -1205,9 +1208,9 @@
 
         mHelper.createNotificationChannelGroup(PKG, UID, notDeleted, true);
         mHelper.createNotificationChannelGroup(PKG, UID, deleted, true);
-        mHelper.createNotificationChannel(PKG, UID, nonGroupedNonDeletedChannel, true);
-        mHelper.createNotificationChannel(PKG, UID, groupedAndDeleted, true);
-        mHelper.createNotificationChannel(PKG, UID, groupedButNotDeleted, true);
+        mHelper.createNotificationChannel(PKG, UID, nonGroupedNonDeletedChannel, true, false);
+        mHelper.createNotificationChannel(PKG, UID, groupedAndDeleted, true, false);
+        mHelper.createNotificationChannel(PKG, UID, groupedButNotDeleted, true, false);
 
         mHelper.deleteNotificationChannelGroup(PKG, UID, deleted.getId());
 
@@ -1264,14 +1267,14 @@
         // Deleted
         NotificationChannel channel1 =
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG, UID, channel1, true);
+        mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
 
         mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
 
         assertEquals(0, mHelper.getNotificationChannels(PKG, UID, true).getList().size());
 
         // Not deleted
-        mHelper.createNotificationChannel(PKG, UID, channel1, true);
+        mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
 
         mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
         assertEquals(2, mHelper.getNotificationChannels(PKG, UID, false).getList().size());
@@ -1302,7 +1305,7 @@
     @Test
     public void testOnPackageChange_downgradeTargetSdk() throws Exception {
         // create channel as api 26
-        mHelper.createNotificationChannel(UPDATED_PKG, UID2, getChannel(), true);
+        mHelper.createNotificationChannel(UPDATED_PKG, UID2, getChannel(), true, false);
 
         // install new app version targeting 25
         final ApplicationInfo legacy = new ApplicationInfo();
@@ -1338,7 +1341,7 @@
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         channel1.setGroup("garbage");
         try {
-            mHelper.createNotificationChannel(PKG, UID, channel1, true);
+            mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
             fail("Created a channel with a bad group");
         } catch (IllegalArgumentException e) {
         }
@@ -1351,7 +1354,7 @@
         NotificationChannel channel1 =
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         channel1.setGroup(ncg.getId());
-        mHelper.createNotificationChannel(PKG, UID, channel1, true);
+        mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
 
         assertEquals(ncg.getId(),
                 mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false).getGroup());
@@ -1369,20 +1372,20 @@
         NotificationChannel channel1 =
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         channel1.setGroup(ncg.getId());
-        mHelper.createNotificationChannel(PKG, UID, channel1, true);
+        mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
         NotificationChannel channel1a =
                 new NotificationChannel("id1a", "name1", NotificationManager.IMPORTANCE_HIGH);
         channel1a.setGroup(ncg.getId());
-        mHelper.createNotificationChannel(PKG, UID, channel1a, true);
+        mHelper.createNotificationChannel(PKG, UID, channel1a, true, false);
 
         NotificationChannel channel2 =
                 new NotificationChannel("id2", "name1", NotificationManager.IMPORTANCE_HIGH);
         channel2.setGroup(ncg2.getId());
-        mHelper.createNotificationChannel(PKG, UID, channel2, true);
+        mHelper.createNotificationChannel(PKG, UID, channel2, true, false);
 
         NotificationChannel channel3 =
                 new NotificationChannel("id3", "name1", NotificationManager.IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG, UID, channel3, true);
+        mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
 
         List<NotificationChannelGroup> actual =
                 mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
@@ -1416,7 +1419,7 @@
         NotificationChannel channel1 =
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         channel1.setGroup(ncg.getId());
-        mHelper.createNotificationChannel(PKG, UID, channel1, true);
+        mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
         mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
 
         channel1.setImportance(IMPORTANCE_LOW);
@@ -1436,12 +1439,12 @@
     @Test
     public void testCreateChannel_updateName() throws Exception {
         NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG, UID, nc, true);
+        mHelper.createNotificationChannel(PKG, UID, nc, true, false);
         NotificationChannel actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
         assertEquals("hello", actual.getName());
 
         nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
-        mHelper.createNotificationChannel(PKG, UID, nc, true);
+        mHelper.createNotificationChannel(PKG, UID, nc, true, false);
 
         actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
         assertEquals("goodbye", actual.getName());
@@ -1455,13 +1458,13 @@
         NotificationChannelGroup group = new NotificationChannelGroup("group", "");
         mHelper.createNotificationChannelGroup(PKG, UID, group, true);
         NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
-        mHelper.createNotificationChannel(PKG, UID, nc, true);
+        mHelper.createNotificationChannel(PKG, UID, nc, true, false);
         NotificationChannel actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
         assertNull(actual.getGroup());
 
         nc = new NotificationChannel("id", "hello", IMPORTANCE_HIGH);
         nc.setGroup(group.getId());
-        mHelper.createNotificationChannel(PKG, UID, nc, true);
+        mHelper.createNotificationChannel(PKG, UID, nc, true, false);
 
         actual = mHelper.getNotificationChannel(PKG, UID, "id", false);
         assertNotNull(actual.getGroup());
@@ -1486,7 +1489,7 @@
             int numChannels = ThreadLocalRandom.current().nextInt(1, 10);
             for (int j = 0; j < numChannels; j++) {
                 mHelper.createNotificationChannel(pkgName, UID,
-                        new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true);
+                        new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true, false);
             }
             expectedChannels.put(pkgName, numChannels);
         }
@@ -1621,10 +1624,10 @@
         c.setGroup(group.getId());
         NotificationChannel d = new NotificationChannel("d", "d", IMPORTANCE_DEFAULT);
 
-        mHelper.createNotificationChannel(PKG, UID, a, true);
-        mHelper.createNotificationChannel(PKG, UID, b, true);
-        mHelper.createNotificationChannel(PKG, UID, c, true);
-        mHelper.createNotificationChannel(PKG, UID, d, true);
+        mHelper.createNotificationChannel(PKG, UID, a, true, false);
+        mHelper.createNotificationChannel(PKG, UID, b, true, false);
+        mHelper.createNotificationChannel(PKG, UID, c, true, false);
+        mHelper.createNotificationChannel(PKG, UID, d, true, false);
         mHelper.deleteNotificationChannel(PKG, UID, c.getId());
 
         NotificationChannelGroup retrieved = mHelper.getNotificationChannelGroupWithChannels(
@@ -1641,22 +1644,31 @@
 
     @Test
     public void testAndroidPkgCanBypassDnd_creation() {
-
         NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
         test.setBypassDnd(true);
 
-        mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true);
+        mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
 
         assertTrue(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
                 .canBypassDnd());
     }
 
     @Test
+    public void testDndPkgCanBypassDnd_creation() {
+        NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
+        test.setBypassDnd(true);
+
+        mHelper.createNotificationChannel(PKG, UID, test, true, true);
+
+        assertTrue(mHelper.getNotificationChannel(PKG, UID, "A", false).canBypassDnd());
+    }
+
+    @Test
     public void testNormalPkgCannotBypassDnd_creation() {
         NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
         test.setBypassDnd(true);
 
-        mHelper.createNotificationChannel(PKG, 1000, test, true);
+        mHelper.createNotificationChannel(PKG, 1000, test, true, false);
 
         assertFalse(mHelper.getNotificationChannel(PKG, 1000, "A", false).canBypassDnd());
     }
@@ -1664,11 +1676,11 @@
     @Test
     public void testAndroidPkgCanBypassDnd_update() throws Exception {
         NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true);
+        mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, test, true, false);
 
         NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
         update.setBypassDnd(true);
-        mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true);
+        mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false);
 
         assertTrue(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
                 .canBypassDnd());
@@ -1678,12 +1690,24 @@
     }
 
     @Test
-    public void testNormalPkgCannotBypassDnd_update() {
+    public void testDndPkgCanBypassDnd_update() throws Exception {
         NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
-        mHelper.createNotificationChannel(PKG, 1000, test, true);
+        mHelper.createNotificationChannel(PKG, UID, test, true, true);
+
         NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
         update.setBypassDnd(true);
-        mHelper.createNotificationChannel(PKG, 1000, update, true);
+        mHelper.createNotificationChannel(PKG, UID, update, true, true);
+
+        assertTrue(mHelper.getNotificationChannel(PKG, UID, "A", false).canBypassDnd());
+    }
+
+    @Test
+    public void testNormalPkgCannotBypassDnd_update() {
+        NotificationChannel test = new NotificationChannel("A", "a", IMPORTANCE_LOW);
+        mHelper.createNotificationChannel(PKG, 1000, test, true, false);
+        NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
+        update.setBypassDnd(true);
+        mHelper.createNotificationChannel(PKG, 1000, update, true, false);
         assertFalse(mHelper.getNotificationChannel(PKG, 1000, "A", false).canBypassDnd());
     }
 }