From 0642113b7c2f8316205b8d899299f47c92d82bc5 Mon Sep 17 00:00:00 2001 From: Eugene Susla Date: Tue, 6 Oct 2020 13:29:06 -0700 Subject: Expose get/set notification listeners as a @SystemAPI We need to grant/revoke notification listener privileges from PermissionController maniline module. This exposes a @SystemApi API to do so Bug: 165951651 Test: atest NotificationManagerTest Change-Id: I81502756e9c7f11ce0347f5f3c006a1539f91b37 --- api/system-current.txt | 3 +++ api/test-current.txt | 3 +++ core/java/android/app/NotificationManager.java | 31 ++++++++++++++++++++-- core/res/AndroidManifest.xml | 6 +++++ non-updatable-api/system-current.txt | 3 +++ packages/Shell/AndroidManifest.xml | 3 +++ .../notification/NotificationManagerService.java | 12 +++++++-- 7 files changed, 57 insertions(+), 4 deletions(-) diff --git a/api/system-current.txt b/api/system-current.txt index 1404f7e1c554..5fa0f93c4371 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -122,6 +122,7 @@ package android { field public static final String MANAGE_FACTORY_RESET_PROTECTION = "android.permission.MANAGE_FACTORY_RESET_PROTECTION"; field public static final String MANAGE_IPSEC_TUNNELS = "android.permission.MANAGE_IPSEC_TUNNELS"; field public static final String MANAGE_MUSIC_RECOGNITION = "android.permission.MANAGE_MUSIC_RECOGNITION"; + field public static final String MANAGE_NOTIFICATION_LISTENERS = "android.permission.MANAGE_NOTIFICATION_LISTENERS"; field public static final String MANAGE_ONE_TIME_PERMISSION_SESSIONS = "android.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS"; field public static final String MANAGE_ROLE_HOLDERS = "android.permission.MANAGE_ROLE_HOLDERS"; field public static final String MANAGE_ROLLBACKS = "android.permission.MANAGE_ROLLBACKS"; @@ -674,8 +675,10 @@ package android.app { public class NotificationManager { method @NonNull public java.util.List getAllowedAssistantAdjustments(); method @Nullable public android.content.ComponentName getAllowedNotificationAssistant(); + method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS) public java.util.List getEnabledNotificationListeners(); method public boolean isNotificationAssistantAccessGranted(@NonNull android.content.ComponentName); method public void setNotificationAssistantAccessGranted(@Nullable android.content.ComponentName, boolean); + method @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS) public void setNotificationListenerAccessGranted(@NonNull android.content.ComponentName, boolean); field @RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE) public static final String ACTION_CLOSE_NOTIFICATION_HANDLER_PANEL = "android.app.action.CLOSE_NOTIFICATION_HANDLER_PANEL"; field @RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE) public static final String ACTION_OPEN_NOTIFICATION_HANDLER_PANEL = "android.app.action.OPEN_NOTIFICATION_HANDLER_PANEL"; field @RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE) public static final String ACTION_TOGGLE_NOTIFICATION_HANDLER_PANEL = "android.app.action.TOGGLE_NOTIFICATION_HANDLER_PANEL"; diff --git a/api/test-current.txt b/api/test-current.txt index 76663378caf1..98ca66525174 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -14,6 +14,7 @@ package android { field public static final String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES"; field public static final String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS"; field public static final String MANAGE_CRATES = "android.permission.MANAGE_CRATES"; + field public static final String MANAGE_NOTIFICATION_LISTENERS = "android.permission.MANAGE_NOTIFICATION_LISTENERS"; field public static final String MANAGE_ROLLBACKS = "android.permission.MANAGE_ROLLBACKS"; field public static final String NETWORK_SETTINGS = "android.permission.NETWORK_SETTINGS"; field public static final String NETWORK_STACK = "android.permission.NETWORK_STACK"; @@ -487,9 +488,11 @@ package android.app { method @NonNull public java.util.List getAllowedAssistantAdjustments(); method @Nullable public android.content.ComponentName getAllowedNotificationAssistant(); method public android.content.ComponentName getEffectsSuppressor(); + method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS) public java.util.List getEnabledNotificationListeners(); method public boolean isNotificationAssistantAccessGranted(@NonNull android.content.ComponentName); method public boolean matchesCallFilter(android.os.Bundle); method public void setNotificationAssistantAccessGranted(@Nullable android.content.ComponentName, boolean); + method @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS) public void setNotificationListenerAccessGranted(@NonNull android.content.ComponentName, boolean); method public void updateNotificationChannel(@NonNull String, int, @NonNull android.app.NotificationChannel); } diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index fe8936654aa4..d442f5f321ec 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -1567,8 +1567,20 @@ public class NotificationManager { } } - /** @hide */ - public void setNotificationListenerAccessGranted(ComponentName listener, boolean granted) { + /** + * Grants/revokes Notification Listener access to the given component for current user. + * To grant access for a particular user, obtain this service by using the {@link Context} + * provided by {@link Context#createPackageContextAsUser} + * + * @param listener Name of component to grant/revoke access + * @param granted Grant/revoke access + * @hide + */ + @SystemApi + @TestApi + @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS) + public void setNotificationListenerAccessGranted( + @NonNull ComponentName listener, boolean granted) { INotificationManager service = getService(); try { service.setNotificationListenerAccessGranted(listener, granted); @@ -1610,6 +1622,21 @@ public class NotificationManager { } } + /** + * Gets the list of enabled notification listener components for current user. + * To query for a particular user, obtain this service by using the {@link Context} + * provided by {@link Context#createPackageContextAsUser} + * + * @return the list of {@link ComponentName}s of the notification listeners + * @hide + */ + @SystemApi + @TestApi + @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS) + public @NonNull List getEnabledNotificationListeners() { + return getEnabledNotificationListeners(mContext.getUserId()); + } + /** @hide */ public List getEnabledNotificationListeners(int userId) { INotificationManager service = getService(); diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index e2f4f2f9294b..f2af514c08ba 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -4518,6 +4518,12 @@ + + + + getAllowedAssistantAdjustments(); method @Nullable public android.content.ComponentName getAllowedNotificationAssistant(); + method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS) public java.util.List getEnabledNotificationListeners(); method public boolean isNotificationAssistantAccessGranted(@NonNull android.content.ComponentName); method public void setNotificationAssistantAccessGranted(@Nullable android.content.ComponentName, boolean); + method @RequiresPermission(android.Manifest.permission.MANAGE_NOTIFICATION_LISTENERS) public void setNotificationListenerAccessGranted(@NonNull android.content.ComponentName, boolean); field @RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE) public static final String ACTION_CLOSE_NOTIFICATION_HANDLER_PANEL = "android.app.action.CLOSE_NOTIFICATION_HANDLER_PANEL"; field @RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE) public static final String ACTION_OPEN_NOTIFICATION_HANDLER_PANEL = "android.app.action.OPEN_NOTIFICATION_HANDLER_PANEL"; field @RequiresPermission(android.Manifest.permission.STATUS_BAR_SERVICE) public static final String ACTION_TOGGLE_NOTIFICATION_HANDLER_PANEL = "android.app.action.TOGGLE_NOTIFICATION_HANDLER_PANEL"; diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index bba29dba0827..5f018a0322a3 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -335,6 +335,9 @@ + + + getEnabledNotificationListeners(int userId) { - checkCallerIsSystem(); + checkNotificationListenerAccess(); return mListeners.getAllowedComponents(userId); } @@ -4835,7 +4835,7 @@ public class NotificationManagerService extends SystemService { public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId, boolean granted) { Objects.requireNonNull(listener); - checkCallerIsSystemOrShell(); + checkNotificationListenerAccess(); final long identity = Binder.clearCallingIdentity(); try { if (mAllowedManagedServicePackages.test( @@ -5108,6 +5108,14 @@ public class NotificationManagerService extends SystemService { } }; + protected void checkNotificationListenerAccess() { + if (!isCallerSystemOrPhone()) { + getContext().enforceCallingPermission( + permission.MANAGE_NOTIFICATION_LISTENERS, + "Caller must hold " + permission.MANAGE_NOTIFICATION_LISTENERS); + } + } + @VisibleForTesting protected void setNotificationAssistantAccessGrantedForUserInternal( ComponentName assistant, int baseUserId, boolean granted) { -- cgit v1.2.3-59-g8ed1b