diff options
| author | 2021-03-22 02:08:10 +0000 | |
|---|---|---|
| committer | 2021-03-22 02:08:10 +0000 | |
| commit | b7eee43f5055363cae65c60a57bee16f6bf48a51 (patch) | |
| tree | fdedd30b87922b9b79a75e6cddd66fa2d040dec0 | |
| parent | f505c5d215d8e8511b4034362ac6de99ee66a299 (diff) | |
| parent | 972df6e950752bbe54430ca2c221ea4a22133a3d (diff) | |
Merge "Provide more specific notification cancelation reasons" into sc-dev
7 files changed, 49 insertions, 27 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index e31d31d75820..7e2edd6af0b6 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -38321,6 +38321,8 @@ package android.service.notification { field public static final int REASON_CANCEL = 2; // 0x2 field public static final int REASON_CANCEL_ALL = 3; // 0x3 field public static final int REASON_CHANNEL_BANNED = 17; // 0x11 + field public static final int REASON_CHANNEL_REMOVED = 20; // 0x14 + field public static final int REASON_CLEAR_DATA = 21; // 0x15 field public static final int REASON_CLICK = 1; // 0x1 field public static final int REASON_ERROR = 4; // 0x4 field public static final int REASON_GROUP_OPTIMIZATION = 13; // 0xd diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index bf5f24d17f8a..09c3b2effcb0 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -251,6 +251,10 @@ public abstract class NotificationListenerService extends Service { public static final int REASON_SNOOZED = 18; /** Notification was canceled due to timeout */ public static final int REASON_TIMEOUT = 19; + /** Notification was canceled due to the backing channel being deleted */ + public static final int REASON_CHANNEL_REMOVED = 20; + /** Notification was canceled due to the app's storage being cleared */ + public static final int REASON_CLEAR_DATA = 21; /** * @hide diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java index 78c1a95a891d..3238f1fb3a6f 100644 --- a/services/core/java/com/android/server/notification/ConditionProviders.java +++ b/services/core/java/com/android/server/notification/ConditionProviders.java @@ -25,6 +25,7 @@ import android.content.pm.ServiceInfo; import android.net.Uri; import android.os.IBinder; import android.os.IInterface; +import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; @@ -41,8 +42,6 @@ import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.server.notification.NotificationManagerService.DumpFilter; -import org.xmlpull.v1.XmlSerializer; - import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; @@ -78,8 +77,8 @@ public class ConditionProviders extends ManagedServices { public void addSystemProvider(SystemConditionProviderService service) { mSystemConditionProviders.add(service); service.attachBase(mContext); - registerSystemService( - service.asInterface(), service.getComponent(), UserHandle.USER_SYSTEM); + registerSystemService(service.asInterface(), service.getComponent(), UserHandle.USER_SYSTEM, + Process.SYSTEM_UID); } public Iterable<SystemConditionProviderService> getSystemProviders() { diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index bbdcac28fb02..3007515edee8 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -317,9 +317,9 @@ abstract public class ManagedServices { private ManagedServiceInfo newServiceInfo(IInterface service, ComponentName component, int userId, boolean isSystem, ServiceConnection connection, - int targetSdkVersion) { + int targetSdkVersion, int uid) { return new ManagedServiceInfo(service, component, userId, isSystem, connection, - targetSdkVersion); + targetSdkVersion, uid); } public void onBootPhaseAppsCanStart() {} @@ -974,10 +974,11 @@ abstract public class ManagedServices { unregisterServiceImpl(service, userid); } - public void registerSystemService(IInterface service, ComponentName component, int userid) { + public void registerSystemService(IInterface service, ComponentName component, int userid, + int uid) { checkNotNull(service); ManagedServiceInfo info = registerServiceImpl( - service, component, userid, Build.VERSION_CODES.CUR_DEVELOPMENT); + service, component, userid, Build.VERSION_CODES.CUR_DEVELOPMENT, uid); if (info != null) { onServiceAdded(info); } @@ -1441,6 +1442,7 @@ abstract public class ManagedServices { } final int targetSdkVersion = appInfo != null ? appInfo.targetSdkVersion : Build.VERSION_CODES.BASE; + final int uid = appInfo != null ? appInfo.uid : -1; try { Slog.v(TAG, "binding: " + intent); @@ -1457,7 +1459,7 @@ abstract public class ManagedServices { try { mService = asInterface(binder); info = newServiceInfo(mService, name, - userid, isSystem, this, targetSdkVersion); + userid, isSystem, this, targetSdkVersion, uid); binder.linkToDeath(info, 0); added = mServices.add(info); } catch (RemoteException e) { @@ -1576,9 +1578,9 @@ abstract public class ManagedServices { } private ManagedServiceInfo registerServiceImpl(final IInterface service, - final ComponentName component, final int userid, int targetSdk) { + final ComponentName component, final int userid, int targetSdk, int uid) { ManagedServiceInfo info = newServiceInfo(service, component, userid, - true /*isSystem*/, null /*connection*/, targetSdk); + true /*isSystem*/, null /*connection*/, targetSdk, uid); return registerServiceImpl(info); } @@ -1624,15 +1626,18 @@ abstract public class ManagedServices { public ServiceConnection connection; public int targetSdkVersion; public Pair<ComponentName, Integer> mKey; + public int uid; public ManagedServiceInfo(IInterface service, ComponentName component, - int userid, boolean isSystem, ServiceConnection connection, int targetSdkVersion) { + int userid, boolean isSystem, ServiceConnection connection, int targetSdkVersion, + int uid) { this.service = service; this.component = component; this.userid = userid; this.isSystem = isSystem; this.connection = connection; this.targetSdkVersion = targetSdkVersion; + this.uid = uid; mKey = Pair.create(component, userid); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index eb4f9d305a27..68fc14c13143 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -60,7 +60,6 @@ import static android.content.pm.PackageManager.MATCH_ALL; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static android.media.AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY; import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; @@ -85,6 +84,8 @@ import static android.service.notification.NotificationListenerService.REASON_AP import static android.service.notification.NotificationListenerService.REASON_CANCEL; import static android.service.notification.NotificationListenerService.REASON_CANCEL_ALL; import static android.service.notification.NotificationListenerService.REASON_CHANNEL_BANNED; +import static android.service.notification.NotificationListenerService.REASON_CHANNEL_REMOVED; +import static android.service.notification.NotificationListenerService.REASON_CLEAR_DATA; import static android.service.notification.NotificationListenerService.REASON_CLICK; import static android.service.notification.NotificationListenerService.REASON_ERROR; import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED; @@ -456,6 +457,13 @@ public class NotificationManagerService extends SystemService { private static final long NOTIFICATION_TRAMPOLINE_BLOCK = 167676448L; /** + * Whether a notification listeners can understand new, more specific, cancellation reasons. + */ + @ChangeId + @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) + private static final long NOTIFICATION_CANCELLATION_REASONS = 175319604L; + + /** * Rate limit showing toasts, on a per package basis. * * It limits the number of {@link android.widget.Toast#show()} calls to prevent overburdening @@ -3599,7 +3607,7 @@ public class NotificationManagerService extends SystemService { } enforceDeletingChannelHasNoFgService(pkg, callingUser, channelId); cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channelId, 0, 0, true, - callingUser, REASON_CHANNEL_BANNED, null); + callingUser, REASON_CHANNEL_REMOVED, null); mPreferencesHelper.deleteNotificationChannel(pkg, callingUid, channelId); mListeners.notifyNotificationChannelChanged(pkg, UserHandle.getUserHandleForUid(callingUid), @@ -3623,7 +3631,7 @@ public class NotificationManagerService extends SystemService { final String channelId = nc.getId(); mAmi.stopForegroundServicesForChannel(pkg, appUserId, channelId); cancelAllNotificationsInt(MY_UID, MY_PID, pkg, nc.getId(), 0, 0, true, - appUserId, REASON_CHANNEL_BANNED, null); + appUserId, REASON_CHANNEL_REMOVED, null); mPreferencesHelper.deleteNotificationChannel(pkg, uid, channelId); mListeners.notifyNotificationChannelChanged(pkg, UserHandle.getUserHandleForUid(uid), @@ -3672,7 +3680,7 @@ public class NotificationManagerService extends SystemService { final NotificationChannel deletedChannel = deletedChannels.get(i); cancelAllNotificationsInt(MY_UID, MY_PID, pkg, deletedChannel.getId(), 0, 0, true, - userId, REASON_CHANNEL_BANNED, + userId, REASON_CHANNEL_REMOVED, null); mListeners.notifyNotificationChannelChanged(pkg, UserHandle.getUserHandleForUid(callingUid), @@ -3852,7 +3860,7 @@ public class NotificationManagerService extends SystemService { // Cancel posted notifications final int userId = UserHandle.getUserId(uid); cancelAllNotificationsInt(MY_UID, MY_PID, packageName, null, 0, 0, true, - UserHandle.getUserId(Binder.getCallingUid()), REASON_CHANNEL_BANNED, null); + UserHandle.getUserId(Binder.getCallingUid()), REASON_CLEAR_DATA, null); // Zen packagesChanged |= @@ -4128,7 +4136,7 @@ public class NotificationManagerService extends SystemService { public void registerListener(final INotificationListener listener, final ComponentName component, final int userid) { enforceSystemOrSystemUI("INotificationManager.registerListener"); - mListeners.registerSystemService(listener, component, userid); + mListeners.registerSystemService(listener, component, userid, Binder.getCallingUid()); } /** @@ -6075,7 +6083,7 @@ public class NotificationManagerService extends SystemService { mPreferencesHelper.deleteConversations(pkg, uid, shortcuts); for (String channelId : deletedChannelIds) { cancelAllNotificationsInt(MY_UID, MY_PID, pkg, channelId, 0, 0, true, - UserHandle.getUserId(uid), REASON_CHANNEL_BANNED, + UserHandle.getUserId(uid), REASON_CHANNEL_REMOVED, null); } handleSavePolicyFile(); @@ -10324,6 +10332,10 @@ public class NotificationManagerService extends SystemService { final INotificationListener listener = (INotificationListener) info.service; StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn); try { + if (!CompatChanges.isChangeEnabled(NOTIFICATION_CANCELLATION_REASONS, info.uid) + && (reason == REASON_CHANNEL_REMOVED || reason == REASON_CLEAR_DATA)) { + reason = REASON_CHANNEL_BANNED; + } listener.onNotificationRemoved(sbnHolder, rankingUpdate, stats, reason); } catch (RemoteException ex) { Slog.e(TAG, "unable to notify listener (removed): " + info, ex); 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 07475e955785..be6e80143221 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java @@ -1111,7 +1111,7 @@ public class ManagedServicesTest extends UiServiceTestCase { when(service.asBinder()).thenReturn(mock(IBinder.class)); ManagedServices services = new TestManagedServices(getContext(), mLock, mUserProfiles, mIpm, APPROVAL_BY_PACKAGE); - services.registerSystemService(service, null, 10); + services.registerSystemService(service, null, 10, 1000); ManagedServices.ManagedServiceInfo info = services.checkServiceTokenLocked(service); info.isSystem = true; @@ -1163,10 +1163,10 @@ public class ManagedServicesTest extends UiServiceTestCase { ManagedServices.ManagedServiceInfo service0 = service.new ManagedServiceInfo( iInterface, ComponentName.unflattenFromString("a/a"), 0, false, - mock(ServiceConnection.class), 26); + mock(ServiceConnection.class), 26, 34); ManagedServices.ManagedServiceInfo service10 = service.new ManagedServiceInfo( iInterface, ComponentName.unflattenFromString("b/b"), 10, false, - mock(ServiceConnection.class), 26); + mock(ServiceConnection.class), 26, 345); Set<ManagedServices.ManagedServiceInfo> removableBoundServices = new ArraySet<>(); removableBoundServices.add(service0); removableBoundServices.add(service10); @@ -1199,13 +1199,13 @@ public class ManagedServicesTest extends UiServiceTestCase { ManagedServices.ManagedServiceInfo service0 = service.new ManagedServiceInfo( iInterface, ComponentName.unflattenFromString("a/a"), 0, false, - mock(ServiceConnection.class), 26); + mock(ServiceConnection.class), 26, 345); ManagedServices.ManagedServiceInfo service0a = service.new ManagedServiceInfo( iInterface, ComponentName.unflattenFromString("c/c"), 0, false, - mock(ServiceConnection.class), 26); + mock(ServiceConnection.class), 26, 3456); ManagedServices.ManagedServiceInfo service10 = service.new ManagedServiceInfo( iInterface, ComponentName.unflattenFromString("b/b"), 10, false, - mock(ServiceConnection.class), 26); + mock(ServiceConnection.class), 26, 34567); Set<ManagedServices.ManagedServiceInfo> removableBoundServices = new ArraySet<>(); removableBoundServices.add(service0); removableBoundServices.add(service0a); 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 ec3a1af062f7..e37b82fe7ac0 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -469,7 +469,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mListeners.getNotificationListenerFilter(any())).thenReturn(mNlf); mListener = mListeners.new ManagedServiceInfo( null, new ComponentName(PKG, "test_class"), - UserHandle.getUserId(mUid), true, null, 0); + UserHandle.getUserId(mUid), true, null, 0, 123); ComponentName defaultComponent = ComponentName.unflattenFromString("config/device"); ArraySet<ComponentName> components = new ArraySet<>(); components.add(defaultComponent); @@ -2869,7 +2869,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { snoozeNotificationRunnable.run(); ManagedServices.ManagedServiceInfo listener = mListeners.new ManagedServiceInfo( - null, new ComponentName(PKG, "test_class"), mUid, true, null, 0); + null, new ComponentName(PKG, "test_class"), mUid, true, null, 0, 234); listener.isSystem = true; when(mListeners.checkServiceTokenLocked(any())).thenReturn(listener); |