Loading packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java +28 −24 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.util.Assert; import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; Loading Loading @@ -62,7 +64,7 @@ public class ForegroundServiceController { /** * @return true if this user has services missing notifications and therefore needs a * disclosure notification. * disclosure notification for running a foreground service. */ public boolean isDisclosureNeededForUser(int userId) { synchronized (mMutex) { Loading @@ -74,26 +76,26 @@ public class ForegroundServiceController { /** * @return true if this user/pkg has a missing or custom layout notification and therefore needs * a disclosure notification for system alert windows. * a disclosure notification showing the user which appsOps the app is using. */ public boolean isSystemAlertWarningNeeded(int userId, String pkg) { synchronized (mMutex) { final ForegroundServicesUserState services = mUserServices.get(userId); if (services == null) return false; return services.getStandardLayoutKey(pkg) == null; return services.getStandardLayoutKeys(pkg) == null; } } /** * Returns the key of the foreground service from this package using the standard template, * if one exists. * Returns the keys for notifications from this package using the standard template, * if they exist. */ @Nullable public String getStandardLayoutKey(int userId, String pkg) { public ArraySet<String> getStandardLayoutKeys(int userId, String pkg) { synchronized (mMutex) { final ForegroundServicesUserState services = mUserServices.get(userId); if (services == null) return null; return services.getStandardLayoutKey(pkg); return services.getStandardLayoutKeys(pkg); } } Loading Loading @@ -140,20 +142,23 @@ public class ForegroundServiceController { } // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by // ForegroundCoordinator // Update appOp if there's an associated pending or visible notification: final String foregroundKey = getStandardLayoutKey(userId, packageName); if (foregroundKey != null) { final NotificationEntry entry = mEntryManager.getPendingOrActiveNotif(foregroundKey); // AppOpsCoordinator // Update appOps if there are associated pending or visible notifications final Set<String> notificationKeys = getStandardLayoutKeys(userId, packageName); if (notificationKeys != null) { boolean changed = false; for (String key : notificationKeys) { final NotificationEntry entry = mEntryManager.getPendingOrActiveNotif(key); if (entry != null && uid == entry.getSbn().getUid() && packageName.equals(entry.getSbn().getPackageName())) { boolean changed; synchronized (entry.mActiveAppOps) { if (active) { changed = entry.mActiveAppOps.add(appOpCode); changed |= entry.mActiveAppOps.add(appOpCode); } else { changed = entry.mActiveAppOps.remove(appOpCode); changed |= entry.mActiveAppOps.remove(appOpCode); } } } } if (changed) { Loading @@ -161,7 +166,6 @@ public class ForegroundServiceController { } } } } /** * Looks up the {@link ForegroundServicesUserState} for the given {@code userId}, then performs Loading packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java +13 −13 Original line number Diff line number Diff line Loading @@ -163,6 +163,7 @@ public class ForegroundServiceNotificationListener { userState.addImportantNotification(sbn.getPackageName(), sbn.getKey()); } } final Notification.Builder builder = Notification.Builder.recoverBuilder( mContext, sbn.getNotification()); Loading @@ -171,23 +172,22 @@ public class ForegroundServiceNotificationListener { sbn.getPackageName(), sbn.getKey()); } } } tagForeground(entry); tagAppOps(entry); return true; }, true /* create if not found */); } // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by // ForegroundCoordinator private void tagForeground(NotificationEntry entry) { // AppOpsCoordinator private void tagAppOps(NotificationEntry entry) { final StatusBarNotification sbn = entry.getSbn(); ArraySet<Integer> activeOps = mForegroundServiceController.getAppOps( sbn.getUserId(), sbn.getPackageName()); if (activeOps != null) { synchronized (entry.mActiveAppOps) { entry.mActiveAppOps.clear(); if (activeOps != null) { entry.mActiveAppOps.addAll(activeOps); } } Loading packages/SystemUI/src/com/android/systemui/ForegroundServicesUserState.java +14 −4 Original line number Diff line number Diff line Loading @@ -30,9 +30,11 @@ public class ForegroundServicesUserState { private String[] mRunning = null; private long mServiceStartTime = 0; // package -> sufficiently important posted notification keys // package -> sufficiently important posted notification keys that signal an app is // running a foreground service private ArrayMap<String, ArraySet<String>> mImportantNotifications = new ArrayMap<>(1); // package -> standard layout posted notification keys // package -> standard layout posted notification keys that can display appOps private ArrayMap<String, ArraySet<String>> mStandardLayoutNotifications = new ArrayMap<>(1); // package -> app ops Loading Loading @@ -110,6 +112,11 @@ public class ForegroundServicesUserState { return found; } /** * System disclosures for foreground services are required if an app has a foreground service * running AND the app hasn't posted its own notification signalling it is running a * foreground service */ public boolean isDisclosureNeeded() { if (mRunning != null && System.currentTimeMillis() - mServiceStartTime Loading @@ -129,12 +136,15 @@ public class ForegroundServicesUserState { return mAppOps.get(pkg); } public String getStandardLayoutKey(String pkg) { /** * Gets the notifications with standard layouts associated with this package */ public ArraySet<String> getStandardLayoutKeys(String pkg) { final ArraySet<String> set = mStandardLayoutNotifications.get(pkg); if (set == null || set.size() == 0) { return null; } return set.valueAt(0); return set; } @Override Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinator.java→packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java +33 −28 Original line number Diff line number Diff line Loading @@ -39,8 +39,8 @@ import javax.inject.Inject; import javax.inject.Singleton; /** * Handles ForegroundService interactions with notifications. * Tags notifications with appOps. * Handles ForegroundService and AppOp interactions with notifications. * Tags notifications with appOps * Lifetime extends notifications associated with an ongoing ForegroundService. * Filters out notifications that represent foreground services that are no longer running * Loading @@ -48,12 +48,10 @@ import javax.inject.Singleton; * frameworks/base/packages/SystemUI/src/com/android/systemui/ForegroundServiceController * frameworks/base/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener * frameworks/base/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender * * TODO: AppOps stuff should be spun off into its own coordinator */ @Singleton public class ForegroundCoordinator implements Coordinator { private static final String TAG = "ForegroundCoordinator"; public class AppOpsCoordinator implements Coordinator { private static final String TAG = "AppOpsCoordinator"; private final ForegroundServiceController mForegroundServiceController; private final AppOpsController mAppOpsController; Loading @@ -62,7 +60,7 @@ public class ForegroundCoordinator implements Coordinator { private NotifPipeline mNotifPipeline; @Inject public ForegroundCoordinator( public AppOpsCoordinator( ForegroundServiceController foregroundServiceController, AppOpsController appOpsController, @Main DelayableExecutor mainExecutor) { Loading @@ -89,18 +87,22 @@ public class ForegroundCoordinator implements Coordinator { } /** * Filters out notifications that represent foreground services that are no longer running. * Filters out notifications that represent foreground services that are no longer running or * that already have an app notification with the appOps tagged to */ private final NotifFilter mNotifFilter = new NotifFilter(TAG) { @Override public boolean shouldFilterOut(NotificationEntry entry, long now) { StatusBarNotification sbn = entry.getSbn(); // Filters out system-posted disclosure notifications when unneeded if (mForegroundServiceController.isDisclosureNotification(sbn) && !mForegroundServiceController.isDisclosureNeededForUser( sbn.getUser().getIdentifier())) { return true; } // Filters out system alert notifications when unneeded if (mForegroundServiceController.isSystemAlertNotification(sbn)) { final String[] apps = sbn.getNotification().extras.getStringArray( Notification.EXTRA_FOREGROUND_APPS); Loading Loading @@ -179,23 +181,24 @@ public class ForegroundCoordinator implements Coordinator { private NotifCollectionListener mNotifCollectionListener = new NotifCollectionListener() { @Override public void onEntryAdded(NotificationEntry entry) { tagForeground(entry); tagAppOps(entry); } @Override public void onEntryUpdated(NotificationEntry entry) { tagForeground(entry); tagAppOps(entry); } private void tagForeground(NotificationEntry entry) { private void tagAppOps(NotificationEntry entry) { final StatusBarNotification sbn = entry.getSbn(); // note: requires that the ForegroundServiceController is updating their appOps first ArraySet<Integer> activeOps = mForegroundServiceController.getAppOps( sbn.getUser().getIdentifier(), sbn.getPackageName()); if (activeOps != null) { entry.mActiveAppOps.clear(); if (activeOps != null) { entry.mActiveAppOps.addAll(activeOps); } } Loading @@ -218,26 +221,28 @@ public class ForegroundCoordinator implements Coordinator { int userId = UserHandle.getUserId(uid); // Update appOp if there's an associated posted notification: final String foregroundKey = mForegroundServiceController.getStandardLayoutKey(userId, packageName); if (foregroundKey != null) { final NotificationEntry entry = findNotificationEntryWithKey(foregroundKey); // Update appOps of the app's posted notifications with standard layouts final ArraySet<String> notifKeys = mForegroundServiceController.getStandardLayoutKeys(userId, packageName); if (notifKeys != null) { boolean changed = false; for (int i = 0; i < notifKeys.size(); i++) { final NotificationEntry entry = findNotificationEntryWithKey(notifKeys.valueAt(i)); if (entry != null && uid == entry.getSbn().getUid() && packageName.equals(entry.getSbn().getPackageName())) { boolean changed; if (active) { changed = entry.mActiveAppOps.add(code); changed |= entry.mActiveAppOps.add(code); } else { changed = entry.mActiveAppOps.remove(code); changed |= entry.mActiveAppOps.remove(code); } } } if (changed) { mNotifFilter.invalidateList(); } } } } private NotificationEntry findNotificationEntryWithKey(String key) { for (NotificationEntry entry : mNotifPipeline.getAllNotifs()) { Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java +2 −2 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ public class NotifCoordinators implements Dumpable { HideNotifsForOtherUsersCoordinator hideNotifsForOtherUsersCoordinator, KeyguardCoordinator keyguardCoordinator, RankingCoordinator rankingCoordinator, ForegroundCoordinator foregroundCoordinator, AppOpsCoordinator appOpsCoordinator, DeviceProvisionedCoordinator deviceProvisionedCoordinator, BubbleCoordinator bubbleCoordinator, HeadsUpCoordinator headsUpCoordinator, Loading @@ -64,7 +64,7 @@ public class NotifCoordinators implements Dumpable { mCoordinators.add(hideNotifsForOtherUsersCoordinator); mCoordinators.add(keyguardCoordinator); mCoordinators.add(rankingCoordinator); mCoordinators.add(foregroundCoordinator); mCoordinators.add(appOpsCoordinator); mCoordinators.add(deviceProvisionedCoordinator); mCoordinators.add(bubbleCoordinator); if (featureFlags.isNewNotifPipelineRenderingEnabled()) { Loading Loading
packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java +28 −24 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.util.Assert; import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; Loading Loading @@ -62,7 +64,7 @@ public class ForegroundServiceController { /** * @return true if this user has services missing notifications and therefore needs a * disclosure notification. * disclosure notification for running a foreground service. */ public boolean isDisclosureNeededForUser(int userId) { synchronized (mMutex) { Loading @@ -74,26 +76,26 @@ public class ForegroundServiceController { /** * @return true if this user/pkg has a missing or custom layout notification and therefore needs * a disclosure notification for system alert windows. * a disclosure notification showing the user which appsOps the app is using. */ public boolean isSystemAlertWarningNeeded(int userId, String pkg) { synchronized (mMutex) { final ForegroundServicesUserState services = mUserServices.get(userId); if (services == null) return false; return services.getStandardLayoutKey(pkg) == null; return services.getStandardLayoutKeys(pkg) == null; } } /** * Returns the key of the foreground service from this package using the standard template, * if one exists. * Returns the keys for notifications from this package using the standard template, * if they exist. */ @Nullable public String getStandardLayoutKey(int userId, String pkg) { public ArraySet<String> getStandardLayoutKeys(int userId, String pkg) { synchronized (mMutex) { final ForegroundServicesUserState services = mUserServices.get(userId); if (services == null) return null; return services.getStandardLayoutKey(pkg); return services.getStandardLayoutKeys(pkg); } } Loading Loading @@ -140,20 +142,23 @@ public class ForegroundServiceController { } // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by // ForegroundCoordinator // Update appOp if there's an associated pending or visible notification: final String foregroundKey = getStandardLayoutKey(userId, packageName); if (foregroundKey != null) { final NotificationEntry entry = mEntryManager.getPendingOrActiveNotif(foregroundKey); // AppOpsCoordinator // Update appOps if there are associated pending or visible notifications final Set<String> notificationKeys = getStandardLayoutKeys(userId, packageName); if (notificationKeys != null) { boolean changed = false; for (String key : notificationKeys) { final NotificationEntry entry = mEntryManager.getPendingOrActiveNotif(key); if (entry != null && uid == entry.getSbn().getUid() && packageName.equals(entry.getSbn().getPackageName())) { boolean changed; synchronized (entry.mActiveAppOps) { if (active) { changed = entry.mActiveAppOps.add(appOpCode); changed |= entry.mActiveAppOps.add(appOpCode); } else { changed = entry.mActiveAppOps.remove(appOpCode); changed |= entry.mActiveAppOps.remove(appOpCode); } } } } if (changed) { Loading @@ -161,7 +166,6 @@ public class ForegroundServiceController { } } } } /** * Looks up the {@link ForegroundServicesUserState} for the given {@code userId}, then performs Loading
packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java +13 −13 Original line number Diff line number Diff line Loading @@ -163,6 +163,7 @@ public class ForegroundServiceNotificationListener { userState.addImportantNotification(sbn.getPackageName(), sbn.getKey()); } } final Notification.Builder builder = Notification.Builder.recoverBuilder( mContext, sbn.getNotification()); Loading @@ -171,23 +172,22 @@ public class ForegroundServiceNotificationListener { sbn.getPackageName(), sbn.getKey()); } } } tagForeground(entry); tagAppOps(entry); return true; }, true /* create if not found */); } // TODO: (b/145659174) remove when moving to NewNotifPipeline. Replaced by // ForegroundCoordinator private void tagForeground(NotificationEntry entry) { // AppOpsCoordinator private void tagAppOps(NotificationEntry entry) { final StatusBarNotification sbn = entry.getSbn(); ArraySet<Integer> activeOps = mForegroundServiceController.getAppOps( sbn.getUserId(), sbn.getPackageName()); if (activeOps != null) { synchronized (entry.mActiveAppOps) { entry.mActiveAppOps.clear(); if (activeOps != null) { entry.mActiveAppOps.addAll(activeOps); } } Loading
packages/SystemUI/src/com/android/systemui/ForegroundServicesUserState.java +14 −4 Original line number Diff line number Diff line Loading @@ -30,9 +30,11 @@ public class ForegroundServicesUserState { private String[] mRunning = null; private long mServiceStartTime = 0; // package -> sufficiently important posted notification keys // package -> sufficiently important posted notification keys that signal an app is // running a foreground service private ArrayMap<String, ArraySet<String>> mImportantNotifications = new ArrayMap<>(1); // package -> standard layout posted notification keys // package -> standard layout posted notification keys that can display appOps private ArrayMap<String, ArraySet<String>> mStandardLayoutNotifications = new ArrayMap<>(1); // package -> app ops Loading Loading @@ -110,6 +112,11 @@ public class ForegroundServicesUserState { return found; } /** * System disclosures for foreground services are required if an app has a foreground service * running AND the app hasn't posted its own notification signalling it is running a * foreground service */ public boolean isDisclosureNeeded() { if (mRunning != null && System.currentTimeMillis() - mServiceStartTime Loading @@ -129,12 +136,15 @@ public class ForegroundServicesUserState { return mAppOps.get(pkg); } public String getStandardLayoutKey(String pkg) { /** * Gets the notifications with standard layouts associated with this package */ public ArraySet<String> getStandardLayoutKeys(String pkg) { final ArraySet<String> set = mStandardLayoutNotifications.get(pkg); if (set == null || set.size() == 0) { return null; } return set.valueAt(0); return set; } @Override Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinator.java→packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/AppOpsCoordinator.java +33 −28 Original line number Diff line number Diff line Loading @@ -39,8 +39,8 @@ import javax.inject.Inject; import javax.inject.Singleton; /** * Handles ForegroundService interactions with notifications. * Tags notifications with appOps. * Handles ForegroundService and AppOp interactions with notifications. * Tags notifications with appOps * Lifetime extends notifications associated with an ongoing ForegroundService. * Filters out notifications that represent foreground services that are no longer running * Loading @@ -48,12 +48,10 @@ import javax.inject.Singleton; * frameworks/base/packages/SystemUI/src/com/android/systemui/ForegroundServiceController * frameworks/base/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener * frameworks/base/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender * * TODO: AppOps stuff should be spun off into its own coordinator */ @Singleton public class ForegroundCoordinator implements Coordinator { private static final String TAG = "ForegroundCoordinator"; public class AppOpsCoordinator implements Coordinator { private static final String TAG = "AppOpsCoordinator"; private final ForegroundServiceController mForegroundServiceController; private final AppOpsController mAppOpsController; Loading @@ -62,7 +60,7 @@ public class ForegroundCoordinator implements Coordinator { private NotifPipeline mNotifPipeline; @Inject public ForegroundCoordinator( public AppOpsCoordinator( ForegroundServiceController foregroundServiceController, AppOpsController appOpsController, @Main DelayableExecutor mainExecutor) { Loading @@ -89,18 +87,22 @@ public class ForegroundCoordinator implements Coordinator { } /** * Filters out notifications that represent foreground services that are no longer running. * Filters out notifications that represent foreground services that are no longer running or * that already have an app notification with the appOps tagged to */ private final NotifFilter mNotifFilter = new NotifFilter(TAG) { @Override public boolean shouldFilterOut(NotificationEntry entry, long now) { StatusBarNotification sbn = entry.getSbn(); // Filters out system-posted disclosure notifications when unneeded if (mForegroundServiceController.isDisclosureNotification(sbn) && !mForegroundServiceController.isDisclosureNeededForUser( sbn.getUser().getIdentifier())) { return true; } // Filters out system alert notifications when unneeded if (mForegroundServiceController.isSystemAlertNotification(sbn)) { final String[] apps = sbn.getNotification().extras.getStringArray( Notification.EXTRA_FOREGROUND_APPS); Loading Loading @@ -179,23 +181,24 @@ public class ForegroundCoordinator implements Coordinator { private NotifCollectionListener mNotifCollectionListener = new NotifCollectionListener() { @Override public void onEntryAdded(NotificationEntry entry) { tagForeground(entry); tagAppOps(entry); } @Override public void onEntryUpdated(NotificationEntry entry) { tagForeground(entry); tagAppOps(entry); } private void tagForeground(NotificationEntry entry) { private void tagAppOps(NotificationEntry entry) { final StatusBarNotification sbn = entry.getSbn(); // note: requires that the ForegroundServiceController is updating their appOps first ArraySet<Integer> activeOps = mForegroundServiceController.getAppOps( sbn.getUser().getIdentifier(), sbn.getPackageName()); if (activeOps != null) { entry.mActiveAppOps.clear(); if (activeOps != null) { entry.mActiveAppOps.addAll(activeOps); } } Loading @@ -218,26 +221,28 @@ public class ForegroundCoordinator implements Coordinator { int userId = UserHandle.getUserId(uid); // Update appOp if there's an associated posted notification: final String foregroundKey = mForegroundServiceController.getStandardLayoutKey(userId, packageName); if (foregroundKey != null) { final NotificationEntry entry = findNotificationEntryWithKey(foregroundKey); // Update appOps of the app's posted notifications with standard layouts final ArraySet<String> notifKeys = mForegroundServiceController.getStandardLayoutKeys(userId, packageName); if (notifKeys != null) { boolean changed = false; for (int i = 0; i < notifKeys.size(); i++) { final NotificationEntry entry = findNotificationEntryWithKey(notifKeys.valueAt(i)); if (entry != null && uid == entry.getSbn().getUid() && packageName.equals(entry.getSbn().getPackageName())) { boolean changed; if (active) { changed = entry.mActiveAppOps.add(code); changed |= entry.mActiveAppOps.add(code); } else { changed = entry.mActiveAppOps.remove(code); changed |= entry.mActiveAppOps.remove(code); } } } if (changed) { mNotifFilter.invalidateList(); } } } } private NotificationEntry findNotificationEntryWithKey(String key) { for (NotificationEntry entry : mNotifPipeline.getAllNotifs()) { Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java +2 −2 Original line number Diff line number Diff line Loading @@ -52,7 +52,7 @@ public class NotifCoordinators implements Dumpable { HideNotifsForOtherUsersCoordinator hideNotifsForOtherUsersCoordinator, KeyguardCoordinator keyguardCoordinator, RankingCoordinator rankingCoordinator, ForegroundCoordinator foregroundCoordinator, AppOpsCoordinator appOpsCoordinator, DeviceProvisionedCoordinator deviceProvisionedCoordinator, BubbleCoordinator bubbleCoordinator, HeadsUpCoordinator headsUpCoordinator, Loading @@ -64,7 +64,7 @@ public class NotifCoordinators implements Dumpable { mCoordinators.add(hideNotifsForOtherUsersCoordinator); mCoordinators.add(keyguardCoordinator); mCoordinators.add(rankingCoordinator); mCoordinators.add(foregroundCoordinator); mCoordinators.add(appOpsCoordinator); mCoordinators.add(deviceProvisionedCoordinator); mCoordinators.add(bubbleCoordinator); if (featureFlags.isNewNotifPipelineRenderingEnabled()) { Loading