diff options
author | 2019-03-07 00:59:56 +0000 | |
---|---|---|
committer | 2019-03-07 00:59:56 +0000 | |
commit | a3e9952ee5434e3df1b8e5adb7f45a64ae62857a (patch) | |
tree | a38ca15ec48a9ffcbeb73814c87901a99be0d747 | |
parent | 021dccc37ff6290791b5c3373845b51f97d05c97 (diff) | |
parent | d0ceefa9893217334c29794e39bd68d3bbfb7cbf (diff) |
Merge "API changes for NAS"
16 files changed, 204 insertions, 90 deletions
diff --git a/api/current.txt b/api/current.txt index 7da2cd08183b..0f3cb1b552f4 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5812,7 +5812,6 @@ package android.app { method public java.util.List<android.app.NotificationChannel> getNotificationChannels(); method @Nullable public String getNotificationDelegate(); method public android.app.NotificationManager.Policy getNotificationPolicy(); - method public boolean isNotificationAssistantAccessGranted(@NonNull android.content.ComponentName); method public boolean isNotificationListenerAccessGranted(android.content.ComponentName); method public boolean isNotificationPolicyAccessGranted(); method public void notify(int, android.app.Notification); @@ -41602,23 +41601,6 @@ package android.service.media { package android.service.notification { - public final class Adjustment implements android.os.Parcelable { - ctor public Adjustment(@NonNull String, @NonNull String, @NonNull android.os.Bundle, @NonNull CharSequence, @NonNull android.os.UserHandle); - method public int describeContents(); - method @NonNull public CharSequence getExplanation(); - method @NonNull public String getKey(); - method @NonNull public String getPackage(); - method @NonNull public android.os.Bundle getSignals(); - method @NonNull public android.os.UserHandle getUserHandle(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR; - field public static final String KEY_CONTEXTUAL_ACTIONS = "key_contextual_actions"; - field public static final String KEY_IMPORTANCE = "key_importance"; - field public static final String KEY_SNOOZE_CRITERIA = "key_snooze_criteria"; - field public static final String KEY_TEXT_REPLIES = "key_text_replies"; - field public static final String KEY_USER_SENTIMENT = "key_user_sentiment"; - } - public final class Condition implements android.os.Parcelable { ctor public Condition(android.net.Uri, String, int); ctor public Condition(android.net.Uri, String, String, String, int, int, int); @@ -41665,26 +41647,6 @@ package android.service.notification { field @Deprecated public static final String SERVICE_INTERFACE = "android.service.notification.ConditionProviderService"; } - public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService { - ctor public NotificationAssistantService(); - method public final void adjustNotification(@NonNull android.service.notification.Adjustment); - method public final void adjustNotifications(@NonNull java.util.List<android.service.notification.Adjustment>); - method public void onActionInvoked(@NonNull String, @NonNull android.app.Notification.Action, int); - method @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent); - method public void onNotificationDirectReplied(@NonNull String); - method public abstract android.service.notification.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification); - method @Nullable public android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification, @NonNull android.app.NotificationChannel); - method public void onNotificationExpansionChanged(@NonNull String, boolean, boolean); - method public void onNotificationRemoved(@NonNull android.service.notification.StatusBarNotification, @NonNull android.service.notification.NotificationListenerService.RankingMap, @NonNull android.service.notification.NotificationStats, int); - method public abstract void onNotificationSnoozedUntilContext(android.service.notification.StatusBarNotification, String); - method public void onNotificationsSeen(@NonNull java.util.List<java.lang.String>); - method public void onSuggestedReplySent(@NonNull String, @NonNull CharSequence, int); - method public final void unsnoozeNotification(String); - field public static final String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService"; - field public static final int SOURCE_FROM_APP = 0; // 0x0 - field public static final int SOURCE_FROM_ASSISTANT = 1; // 0x1 - } - public abstract class NotificationListenerService extends android.app.Service { ctor public NotificationListenerService(); method public final void cancelAllNotifications(); @@ -41787,37 +41749,6 @@ package android.service.notification { field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.NotificationListenerService.RankingMap> CREATOR; } - public final class NotificationStats implements android.os.Parcelable { - ctor public NotificationStats(); - method public int describeContents(); - method public int getDismissalSentiment(); - method public int getDismissalSurface(); - method public boolean hasDirectReplied(); - method public boolean hasExpanded(); - method public boolean hasInteracted(); - method public boolean hasSeen(); - method public boolean hasSnoozed(); - method public boolean hasViewedSettings(); - method public void setDirectReplied(); - method public void setDismissalSentiment(int); - method public void setDismissalSurface(int); - method public void setExpanded(); - method public void setSeen(); - method public void setSnoozed(); - method public void setViewedSettings(); - method public void writeToParcel(android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.NotificationStats> CREATOR; - field public static final int DISMISSAL_AOD = 2; // 0x2 - field public static final int DISMISSAL_NOT_DISMISSED = -1; // 0xffffffff - field public static final int DISMISSAL_OTHER = 0; // 0x0 - field public static final int DISMISSAL_PEEK = 1; // 0x1 - field public static final int DISMISSAL_SHADE = 3; // 0x3 - field public static final int DISMISS_SENTIMENT_NEGATIVE = 0; // 0x0 - field public static final int DISMISS_SENTIMENT_NEUTRAL = 1; // 0x1 - field public static final int DISMISS_SENTIMENT_POSITIVE = 2; // 0x2 - field public static final int DISMISS_SENTIMENT_UNKNOWN = -1000; // 0xfffffc18 - } - public class StatusBarNotification implements android.os.Parcelable { ctor @Deprecated public StatusBarNotification(String, String, int, String, int, int, int, android.app.Notification, android.os.UserHandle, long); ctor public StatusBarNotification(android.os.Parcel); diff --git a/api/system-current.txt b/api/system-current.txt index 951926d2437d..2ed385fb83d0 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -161,6 +161,7 @@ package android { field public static final String REMOTE_DISPLAY_PROVIDER = "android.permission.REMOTE_DISPLAY_PROVIDER"; field public static final String REMOVE_DRM_CERTIFICATES = "android.permission.REMOVE_DRM_CERTIFICATES"; field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS"; + field public static final String REQUEST_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE"; field public static final String RESET_PASSWORD = "android.permission.RESET_PASSWORD"; field public static final String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS"; field public static final String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT"; @@ -547,6 +548,7 @@ package android.app { public class NotificationManager { method @Nullable public android.content.ComponentName getAllowedNotificationAssistant(); method @Nullable public android.content.ComponentName getAllowedNotificationAssistantForUser(android.os.UserHandle); + method public boolean isNotificationAssistantAccessGranted(@NonNull android.content.ComponentName); method public void setNotificationAssistantAccessGranted(android.content.ComponentName, boolean); method public void setNotificationAssistantAccessGrantedForUser(android.content.ComponentName, android.os.UserHandle, boolean); } @@ -6621,13 +6623,78 @@ package android.service.notification { public final class Adjustment implements android.os.Parcelable { ctor public Adjustment(String, String, android.os.Bundle, CharSequence, int); + ctor public Adjustment(@NonNull String, @NonNull String, @NonNull android.os.Bundle, @NonNull CharSequence, @NonNull android.os.UserHandle); ctor protected Adjustment(android.os.Parcel); + method public int describeContents(); + method @NonNull public CharSequence getExplanation(); + method @NonNull public String getKey(); + method @NonNull public String getPackage(); + method @NonNull public android.os.Bundle getSignals(); method public int getUser(); + method @NonNull public android.os.UserHandle getUserHandle(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR; + field public static final String KEY_CONTEXTUAL_ACTIONS = "key_contextual_actions"; + field public static final String KEY_IMPORTANCE = "key_importance"; field public static final String KEY_PEOPLE = "key_people"; + field public static final String KEY_SNOOZE_CRITERIA = "key_snooze_criteria"; + field public static final String KEY_TEXT_REPLIES = "key_text_replies"; + field public static final String KEY_USER_SENTIMENT = "key_user_sentiment"; + } + + public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService { + ctor public NotificationAssistantService(); + method public final void adjustNotification(@NonNull android.service.notification.Adjustment); + method public final void adjustNotifications(@NonNull java.util.List<android.service.notification.Adjustment>); + method public void onActionInvoked(@NonNull String, @NonNull android.app.Notification.Action, int); + method @NonNull public final android.os.IBinder onBind(@Nullable android.content.Intent); + method public void onNotificationDirectReplied(@NonNull String); + method @Nullable public abstract android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification); + method @Nullable public android.service.notification.Adjustment onNotificationEnqueued(@NonNull android.service.notification.StatusBarNotification, @NonNull android.app.NotificationChannel); + method public void onNotificationExpansionChanged(@NonNull String, boolean, boolean); + method public abstract void onNotificationSnoozedUntilContext(@NonNull android.service.notification.StatusBarNotification, @NonNull String); + method public void onNotificationsSeen(@NonNull java.util.List<java.lang.String>); + method public void onSuggestedReplySent(@NonNull String, @NonNull CharSequence, int); + method public final void unsnoozeNotification(@NonNull String); + field public static final String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService"; + field public static final int SOURCE_FROM_APP = 0; // 0x0 + field public static final int SOURCE_FROM_ASSISTANT = 1; // 0x1 + } + + public abstract class NotificationListenerService extends android.app.Service { + method public void onNotificationRemoved(@NonNull android.service.notification.StatusBarNotification, @NonNull android.service.notification.NotificationListenerService.RankingMap, @NonNull android.service.notification.NotificationStats, int); } public final class NotificationStats implements android.os.Parcelable { + ctor public NotificationStats(); ctor protected NotificationStats(android.os.Parcel); + method public int describeContents(); + method public int getDismissalSentiment(); + method public int getDismissalSurface(); + method public boolean hasDirectReplied(); + method public boolean hasExpanded(); + method public boolean hasInteracted(); + method public boolean hasSeen(); + method public boolean hasSnoozed(); + method public boolean hasViewedSettings(); + method public void setDirectReplied(); + method public void setDismissalSentiment(int); + method public void setDismissalSurface(int); + method public void setExpanded(); + method public void setSeen(); + method public void setSnoozed(); + method public void setViewedSettings(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.NotificationStats> CREATOR; + field public static final int DISMISSAL_AOD = 2; // 0x2 + field public static final int DISMISSAL_NOT_DISMISSED = -1; // 0xffffffff + field public static final int DISMISSAL_OTHER = 0; // 0x0 + field public static final int DISMISSAL_PEEK = 1; // 0x1 + field public static final int DISMISSAL_SHADE = 3; // 0x3 + field public static final int DISMISS_SENTIMENT_NEGATIVE = 0; // 0x0 + field public static final int DISMISS_SENTIMENT_NEUTRAL = 1; // 0x1 + field public static final int DISMISS_SENTIMENT_POSITIVE = 2; // 0x2 + field public static final int DISMISS_SENTIMENT_UNKNOWN = -1000; // 0xfffffc18 } public final class SnoozeCriterion implements android.os.Parcelable { diff --git a/api/test-current.txt b/api/test-current.txt index 659696ae0b97..bc011574e8fb 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -2333,7 +2333,38 @@ package android.service.notification { } public abstract class NotificationListenerService extends android.app.Service { - method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap, android.service.notification.NotificationStats, int); + method public void onNotificationRemoved(@NonNull android.service.notification.StatusBarNotification, @NonNull android.service.notification.NotificationListenerService.RankingMap, @NonNull android.service.notification.NotificationStats, int); + } + + public final class NotificationStats implements android.os.Parcelable { + ctor public NotificationStats(); + method public int describeContents(); + method public int getDismissalSentiment(); + method public int getDismissalSurface(); + method public boolean hasDirectReplied(); + method public boolean hasExpanded(); + method public boolean hasInteracted(); + method public boolean hasSeen(); + method public boolean hasSnoozed(); + method public boolean hasViewedSettings(); + method public void setDirectReplied(); + method public void setDismissalSentiment(int); + method public void setDismissalSurface(int); + method public void setExpanded(); + method public void setSeen(); + method public void setSnoozed(); + method public void setViewedSettings(); + method public void writeToParcel(android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.NotificationStats> CREATOR; + field public static final int DISMISSAL_AOD = 2; // 0x2 + field public static final int DISMISSAL_NOT_DISMISSED = -1; // 0xffffffff + field public static final int DISMISSAL_OTHER = 0; // 0x0 + field public static final int DISMISSAL_PEEK = 1; // 0x1 + field public static final int DISMISSAL_SHADE = 3; // 0x3 + field public static final int DISMISS_SENTIMENT_NEGATIVE = 0; // 0x0 + field public static final int DISMISS_SENTIMENT_NEUTRAL = 1; // 0x1 + field public static final int DISMISS_SENTIMENT_POSITIVE = 2; // 0x2 + field public static final int DISMISS_SENTIMENT_UNKNOWN = -1000; // 0xfffffc18 } public final class SnoozeCriterion implements android.os.Parcelable { diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 6ad6e3842de4..edf86f9501d8 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -1168,7 +1168,9 @@ public class NotificationManager { * matches the system intent action * TODO: STOPSHIP: Add correct intent * {@link android.provider.Settings#ACTION_MANAGE_DEFAULT_APPS_SETTINGS}. + * @hide */ + @SystemApi public boolean isNotificationAssistantAccessGranted(@NonNull ComponentName assistant) { INotificationManager service = getService(); try { diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java index af0dfd2c26e5..1cdb62fe8934 100644 --- a/core/java/android/service/notification/Adjustment.java +++ b/core/java/android/service/notification/Adjustment.java @@ -32,7 +32,10 @@ import android.os.UserHandle; * realizes on the notification rankings. * * Notifications affected by the Adjustment will be re-ranked if necessary. + * + * @hide */ +@SystemApi public final class Adjustment implements Parcelable { private final String mPackage; private final String mKey; diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java index ceb21e7d418a..87bdfe052324 100644 --- a/core/java/android/service/notification/NotificationAssistantService.java +++ b/core/java/android/service/notification/NotificationAssistantService.java @@ -22,6 +22,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; +import android.annotation.SystemApi; import android.app.Notification; import android.app.NotificationChannel; import android.app.admin.DevicePolicyManager; @@ -60,7 +61,9 @@ import java.util.List; * <p> * All callbacks are called on the main thread. * </p> + * @hide */ +@SystemApi public abstract class NotificationAssistantService extends NotificationListenerService { private static final String TAG = "NotificationAssistants"; @@ -112,8 +115,8 @@ public abstract class NotificationAssistantService extends NotificationListenerS * @param sbn the notification to snooze * @param snoozeCriterionId the {@link SnoozeCriterion#getId()} representing a device context. */ - abstract public void onNotificationSnoozedUntilContext(StatusBarNotification sbn, - String snoozeCriterionId); + abstract public void onNotificationSnoozedUntilContext(@NonNull StatusBarNotification sbn, + @NonNull String snoozeCriterionId); /** * A notification was posted by an app. Called before post. @@ -124,7 +127,7 @@ public abstract class NotificationAssistantService extends NotificationListenerS * @param sbn the new notification * @return an adjustment or null to take no action, within 100ms. */ - abstract public Adjustment onNotificationEnqueued(StatusBarNotification sbn); + abstract public @Nullable Adjustment onNotificationEnqueued(@NonNull StatusBarNotification sbn); /** * A notification was posted by an app. Called before post. @@ -255,7 +258,7 @@ public abstract class NotificationAssistantService extends NotificationListenerS * notification. * @param key The key of the notification to snooze */ - public final void unsnoozeNotification(String key) { + public final void unsnoozeNotification(@NonNull String key) { if (!isBound()) return; try { getNotificationInterface().unsnoozeNotificationFromAssistant(mWrapper, key); diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 767a3f7fda34..23607ebe78fe 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -425,8 +425,9 @@ public abstract class NotificationListenerService extends Service { * @hide */ @TestApi - public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap, - NotificationStats stats, int reason) { + @SystemApi + public void onNotificationRemoved(@NonNull StatusBarNotification sbn, + @NonNull RankingMap rankingMap, @NonNull NotificationStats stats, int reason) { onNotificationRemoved(sbn, rankingMap, reason); } diff --git a/core/java/android/service/notification/NotificationStats.java b/core/java/android/service/notification/NotificationStats.java index 5a54a439bbf4..2b4c24cbb069 100644 --- a/core/java/android/service/notification/NotificationStats.java +++ b/core/java/android/service/notification/NotificationStats.java @@ -17,6 +17,7 @@ package android.service.notification; import android.annotation.IntDef; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.app.RemoteInput; import android.os.Parcel; import android.os.Parcelable; @@ -24,6 +25,12 @@ import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +/** + * Information about how the user has interacted with a given notification. + * @hide + */ +@TestApi +@SystemApi public final class NotificationStats implements Parcelable { private boolean mSeen; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 4c4393d4fd61..9aaa14f9b821 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -3966,6 +3966,13 @@ <permission android:name="android.permission.UPDATE_LOCK" android:protectionLevel="signature|privileged" /> + <!-- @SystemApi Allows an application the opportunity to become a + {@link android.service.notification.NotificationAssistantService}. + User permission is still required before access is granted. + @hide --> + <permission android:name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" + android:protectionLevel="signature|privileged" /> + <!-- @SystemApi @TestApi Allows an application to read the current set of notifications, including any metadata and intents attached. @hide --> diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index f19e44c2f8a0..fcd5d566f250 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -23,6 +23,7 @@ applications that come with the platform <privapp-permissions package="android.ext.services"> <permission name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" /> <permission name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE" /> + <permission name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" /> </privapp-permissions> <privapp-permissions package="com.android.apps.tag"> diff --git a/packages/ExtServices/AndroidManifest.xml b/packages/ExtServices/AndroidManifest.xml index fe6581b37330..48c72ba2c995 100644 --- a/packages/ExtServices/AndroidManifest.xml +++ b/packages/ExtServices/AndroidManifest.xml @@ -25,6 +25,7 @@ <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" /> <uses-permission android:name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE" /> + <uses-permission android:name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" /> <application android:label="@string/app_name" android:defaultToDeviceProtectedStorage="true" diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java index 41f2cc5a0c83..64477a52a9d9 100644 --- a/services/core/java/com/android/server/notification/ConditionProviders.java +++ b/services/core/java/com/android/server/notification/ConditionProviders.java @@ -192,6 +192,11 @@ public class ConditionProviders extends ManagedServices { return true; } + @Override + protected String getRequiredPermission() { + return null; + } + public ManagedServiceInfo checkServiceToken(IConditionProvider provider) { synchronized(mMutex) { return checkServiceTokenLocked(provider); diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index 8480830b7698..7a87a572ab0f 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -64,6 +64,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.XmlUtils; +import com.android.internal.util.function.TriPredicate; import com.android.server.notification.NotificationManagerService.DumpFilter; import org.xmlpull.v1.XmlPullParser; @@ -360,7 +361,7 @@ abstract public class ManagedServices { public void readXml( XmlPullParser parser, - Predicate<String> allowedManagedServicePackages, + TriPredicate<String, Integer, String> allowedManagedServicePackages, boolean forRestore, int userId) throws XmlPullParserException, IOException { @@ -383,8 +384,8 @@ abstract public class ManagedServices { final boolean isPrimary = XmlUtils.readBooleanAttribute(parser, ATT_IS_PRIMARY, true); readExtraAttributes(tag, parser, resolvedUserId); - if (allowedManagedServicePackages == null || - allowedManagedServicePackages.test(getPackageName(approved))) { + if (allowedManagedServicePackages == null || allowedManagedServicePackages.test( + getPackageName(approved), resolvedUserId, getRequiredPermission())) { if (mUm.getUserInfo(resolvedUserId) != null) { addApprovedList(approved, resolvedUserId, isPrimary); } @@ -402,6 +403,8 @@ abstract public class ManagedServices { protected void readExtraAttributes(String tag, XmlPullParser parser, int userId) throws IOException {} + protected abstract String getRequiredPermission(); + private void loadAllowedComponentsFromSettings() { for (UserInfo user : mUm.getUsers()) { final ContentResolver cr = mContext.getContentResolver(); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 22f0b9db85b2..9281bf86d984 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -205,6 +205,7 @@ import com.android.internal.util.DumpUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.Preconditions; import com.android.internal.util.XmlUtils; +import com.android.internal.util.function.TriPredicate; import com.android.server.DeviceIdleController; import com.android.server.EventLogTags; import com.android.server.IoThread; @@ -432,7 +433,7 @@ public class NotificationManagerService extends SystemService { private boolean mIsAutomotive; private MetricsLogger mMetricsLogger; - private Predicate<String> mAllowedManagedServicePackages; + private TriPredicate<String, Integer, String> mAllowedManagedServicePackages; private static class Archive { final int mBufferSize; @@ -3614,7 +3615,8 @@ public class NotificationManagerService extends SystemService { checkCallerIsSystemOrShell(); final long identity = Binder.clearCallingIdentity(); try { - if (mAllowedManagedServicePackages.test(pkg)) { + if (mAllowedManagedServicePackages.test( + pkg, userId, mConditionProviders.getRequiredPermission())) { mConditionProviders.setPackageOrComponentEnabled( pkg, userId, true, granted); @@ -3771,7 +3773,8 @@ public class NotificationManagerService extends SystemService { checkCallerIsSystemOrShell(); final long identity = Binder.clearCallingIdentity(); try { - if (mAllowedManagedServicePackages.test(listener.getPackageName())) { + if (mAllowedManagedServicePackages.test( + listener.getPackageName(), userId, mListeners.getRequiredPermission())) { mConditionProviders.setPackageOrComponentEnabled(listener.flattenToString(), userId, false, granted); mListeners.setPackageOrComponentEnabled(listener.flattenToString(), @@ -4022,7 +4025,8 @@ public class NotificationManagerService extends SystemService { } return; } - if (mAllowedManagedServicePackages.test(assistant.getPackageName())) { + if (mAllowedManagedServicePackages.test(assistant.getPackageName(), userId, + mAssistants.getRequiredPermission())) { mConditionProviders.setPackageOrComponentEnabled(assistant.flattenToString(), userId, false, granted); mAssistants.setPackageOrComponentEnabled(assistant.flattenToString(), @@ -7084,7 +7088,7 @@ public class NotificationManagerService extends SystemService { } @VisibleForTesting - boolean canUseManagedServices(String pkg) { + boolean canUseManagedServices(String pkg, Integer userId, String requiredPermission) { boolean canUseManagedServices = !mActivityManager.isLowRamDevice() || mPackageManagerClient.hasSystemFeature(PackageManager.FEATURE_WATCH); @@ -7095,6 +7099,17 @@ public class NotificationManagerService extends SystemService { } } + if (requiredPermission != null) { + try { + if (mPackageManager.checkPermission(requiredPermission, pkg, userId) + != PackageManager.PERMISSION_GRANTED) { + canUseManagedServices = false; + } + } catch (RemoteException e) { + Log.e(TAG, "can't talk to pm", e); + } + } + return canUseManagedServices; } @@ -7179,6 +7194,12 @@ public class NotificationManagerService extends SystemService { rebindServices(true, user); } + @Override + protected String getRequiredPermission() { + // only signature/privileged apps can be bound + return android.Manifest.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE; + } + protected void onNotificationsSeenLocked(ArrayList<NotificationRecord> records) { // There should be only one, but it's a list, so while we enforce // singularity elsewhere, we keep it general here, to avoid surprises. @@ -7486,6 +7507,11 @@ public class NotificationManagerService extends SystemService { mLightTrimListeners.remove(removed); } + @Override + protected String getRequiredPermission() { + return null; + } + @GuardedBy("mNotificationLock") public void setOnNotificationPostedTrimLocked(ManagedServiceInfo info, int trim) { if (trim == TRIM_LIGHT) { diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java index 7a530dfe306f..43fe674c5d78 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java @@ -1228,5 +1228,10 @@ public class ManagedServicesTest extends UiServiceTestCase { protected void onServiceAdded(ManagedServiceInfo info) { } + + @Override + protected String getRequiredPermission() { + return null; + } } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 5df19410d55b..7df52b2ae06a 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -3660,7 +3660,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(new String[] {"a", "b", "c"}); when(mContext.getResources()).thenReturn(mResources); - assertEquals(false, mService.canUseManagedServices(null)); + assertEquals(false, mService.canUseManagedServices(null, 0, null)); } @Test @@ -3671,7 +3671,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(new String[] {"a", "b", "c"}); when(mContext.getResources()).thenReturn(mResources); - assertEquals(true, mService.canUseManagedServices("b")); + assertEquals(true, mService.canUseManagedServices("b", 0, null)); } @Test @@ -3682,7 +3682,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(new String[] {"a", "b", "c"}); when(mContext.getResources()).thenReturn(mResources); - assertEquals(false, mService.canUseManagedServices("d")); + assertEquals(false, mService.canUseManagedServices("d", 0, null)); } @Test @@ -3693,7 +3693,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(new String[] {"a", "b", "c"}); when(mContext.getResources()).thenReturn(mResources); - assertEquals(true, mService.canUseManagedServices("d")); + assertEquals(true, mService.canUseManagedServices("d", 0, null)); } @Test @@ -3704,7 +3704,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(new String[] {"a", "b", "c"}); when(mContext.getResources()).thenReturn(mResources); - assertEquals(true, mService.canUseManagedServices("d")); + assertEquals(true, mService.canUseManagedServices("d", 0 , null)); } @Test @@ -3715,7 +3715,28 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { .thenReturn(new String[] {"a", "b", "c"}); when(mContext.getResources()).thenReturn(mResources); - assertEquals(true, mService.canUseManagedServices("d")); + assertEquals(true, mService.canUseManagedServices("d", 0, null)); + } + + @Test + public void testCanUseManagedServices_hasPermission() throws Exception { + when(mPackageManager.checkPermission("perm", "pkg", 0)) + .thenReturn(PackageManager.PERMISSION_GRANTED); + + assertEquals(true, mService.canUseManagedServices("pkg", 0, "perm")); + } + + @Test + public void testCanUseManagedServices_noPermission() throws Exception { + when(mPackageManager.checkPermission("perm", "pkg", 0)) + .thenReturn(PackageManager.PERMISSION_DENIED); + + assertEquals(false, mService.canUseManagedServices("pkg", 0, "perm")); + } + + @Test + public void testCanUseManagedServices_permDoesNotMatter() { + assertEquals(true, mService.canUseManagedServices("pkg", 0, null)); } @Test |