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());
}
}