Loading packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java +39 −6 Original line number Diff line number Diff line Loading @@ -21,10 +21,13 @@ import android.util.ArraySet; import android.util.SparseArray; import com.android.internal.messages.nano.SystemMessageProto; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import javax.inject.Inject; import javax.inject.Singleton; /** * Tracks state of foreground services and notifications related to foreground services per user. */ Loading @@ -33,9 +36,11 @@ public class ForegroundServiceController { private final SparseArray<ForegroundServicesUserState> mUserServices = new SparseArray<>(); private final Object mMutex = new Object(); private final NotificationEntryManager mEntryManager; @Inject public ForegroundServiceController() { public ForegroundServiceController(NotificationEntryManager entryManager) { mEntryManager = entryManager; } /** Loading Loading @@ -90,11 +95,18 @@ public class ForegroundServiceController { } /** * Records active app ops. App Ops are stored in FSC in addition to NotificationData in * case they change before we have a notification to tag. * Records active app ops and updates the app op for the pending or visible notifications * with the given parameters. * App Ops are stored in FSC in addition to NotificationEntry in case they change before we * have a notification to tag. * @param appOpCode code for appOp to add/remove * @param uid of user the notification is sent to * @param packageName package that created the notification * @param active whether the appOpCode is active or not */ public void onAppOpChanged(int code, int uid, String packageName, boolean active) { public void onAppOpChanged(int appOpCode, int uid, String packageName, boolean active) { int userId = UserHandle.getUserId(uid); // Record active app ops synchronized (mMutex) { ForegroundServicesUserState userServices = mUserServices.get(userId); if (userServices == null) { Loading @@ -102,9 +114,30 @@ public class ForegroundServiceController { mUserServices.put(userId, userServices); } if (active) { userServices.addOp(packageName, code); userServices.addOp(packageName, appOpCode); } else { userServices.removeOp(packageName, code); userServices.removeOp(packageName, appOpCode); } } // Update appOp if there's an associated pending or visible notification: final String foregroundKey = getStandardLayoutKey(userId, packageName); if (foregroundKey != null) { final NotificationEntry entry = mEntryManager.getPendingOrCurrentNotif(foregroundKey); if (entry != null && uid == entry.getSbn().getUid() && packageName.equals(entry.getSbn().getPackageName())) { boolean changed; synchronized (entry.mActiveAppOps) { if (active) { changed = entry.mActiveAppOps.add(appOpCode); } else { changed = entry.mActiveAppOps.remove(appOpCode); } } if (changed) { mEntryManager.updateNotifications("appOpChanged pkg=" + packageName); } } } } Loading packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java +28 −11 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.app.NotificationManager; import android.content.Context; import android.os.Bundle; import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.Log; import com.android.internal.statusbar.NotificationVisibility; Loading @@ -40,6 +41,7 @@ public class ForegroundServiceNotificationListener { private final Context mContext; private final ForegroundServiceController mForegroundServiceController; private final NotificationEntryManager mEntryManager; @Inject public ForegroundServiceNotificationListener(Context context, Loading @@ -47,15 +49,16 @@ public class ForegroundServiceNotificationListener { NotificationEntryManager notificationEntryManager) { mContext = context; mForegroundServiceController = foregroundServiceController; notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() { mEntryManager = notificationEntryManager; mEntryManager.addNotificationEntryListener(new NotificationEntryListener() { @Override public void onPendingEntryAdded(NotificationEntry entry) { addNotification(entry.getSbn(), entry.getImportance()); addNotification(entry, entry.getImportance()); } @Override public void onPostEntryUpdated(NotificationEntry entry) { updateNotification(entry.getSbn(), entry.getImportance()); public void onPreEntryUpdated(NotificationEntry entry) { updateNotification(entry, entry.getImportance()); } @Override Loading @@ -67,15 +70,14 @@ public class ForegroundServiceNotificationListener { } }); notificationEntryManager.addNotificationLifetimeExtender( new ForegroundServiceLifetimeExtender()); mEntryManager.addNotificationLifetimeExtender(new ForegroundServiceLifetimeExtender()); } /** * @param sbn notification that was just posted * @param entry notification that was just posted */ private void addNotification(StatusBarNotification sbn, int importance) { updateNotification(sbn, importance); private void addNotification(NotificationEntry entry, int importance) { updateNotification(entry, importance); } /** Loading Loading @@ -113,9 +115,10 @@ public class ForegroundServiceNotificationListener { } /** * @param sbn notification that was just changed in some way * @param entry notification that was just changed in some way */ private void updateNotification(StatusBarNotification sbn, int newImportance) { private void updateNotification(NotificationEntry entry, int newImportance) { final StatusBarNotification sbn = entry.getSbn(); mForegroundServiceController.updateUserState( sbn.getUserId(), userState -> { Loading Loading @@ -143,8 +146,22 @@ public class ForegroundServiceNotificationListener { } } } tagForeground(entry); return true; }, true /* create if not found */); } private void tagForeground(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(); entry.mActiveAppOps.addAll(activeOps); } } } } packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java +2 −9 Original line number Diff line number Diff line Loading @@ -20,12 +20,12 @@ import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.StatusBarNotification; import androidx.annotation.NonNull; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag; import androidx.annotation.NonNull; /** * Listener interface for changes sent by NotificationEntryManager. */ Loading @@ -37,13 +37,6 @@ public interface NotificationEntryListener { default void onPendingEntryAdded(NotificationEntry entry) { } // TODO: Combine this with onPreEntryUpdated into "onBeforeEntryFiltered" or similar /** * Called when a new entry is created but before it has been filtered or displayed to the user. */ default void onBeforeNotificationAdded(NotificationEntry entry) { } /** * Called when a new entry is created. */ Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +12 −3 Original line number Diff line number Diff line Loading @@ -262,9 +262,6 @@ public class NotificationEntryManager implements listener.onEntryInflated(entry, inflatedFlags); } mNotificationData.add(entry); for (NotificationEntryListener listener : mNotificationEntryListeners) { listener.onBeforeNotificationAdded(entry); } updateNotifications("onAsyncInflationFinished"); for (NotificationEntryListener listener : mNotificationEntryListeners) { listener.onNotificationAdded(entry); Loading Loading @@ -563,6 +560,18 @@ public class NotificationEntryManager implements return mPendingNotifications.values(); } /** * Gets the pending or visible notification entry with the given key. Returns null if * notification doesn't exist. */ public NotificationEntry getPendingOrCurrentNotif(String key) { if (mPendingNotifications.containsKey(key)) { return mPendingNotifications.get(key); } else { return mNotificationData.get(key); } } private void extendLifetime(NotificationEntry entry, NotificationLifetimeExtender extender) { NotificationLifetimeExtender activeExtender = mRetainedNotifications.get(entry); if (activeExtender != null && activeExtender != extender) { Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java +0 −34 Original line number Diff line number Diff line Loading @@ -18,10 +18,6 @@ package com.android.systemui.statusbar.notification; import static com.android.internal.util.Preconditions.checkNotNull; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.util.ArraySet; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.ForegroundServiceController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; Loading Loading @@ -70,11 +66,6 @@ public class NotificationListController { boolean removedByUser) { mListContainer.cleanUpViewStateForEntry(entry); } @Override public void onBeforeNotificationAdded(NotificationEntry entry) { tagForeground(entry.getSbn()); } }; private final DeviceProvisionedListener mDeviceProvisionedListener = Loading @@ -84,29 +75,4 @@ public class NotificationListController { mEntryManager.updateNotifications("device provisioned changed"); } }; // TODO: This method is horrifically inefficient private void tagForeground(StatusBarNotification notification) { ArraySet<Integer> activeOps = mForegroundServiceController.getAppOps( notification.getUserId(), notification.getPackageName()); if (activeOps != null) { int len = activeOps.size(); for (int i = 0; i < len; i++) { updateNotificationsForAppOp(activeOps.valueAt(i), notification.getUid(), notification.getPackageName(), true); } } } /** When an app op changes, propagate that change to notifications. */ public void updateNotificationsForAppOp(int appOp, int uid, String pkg, boolean showIcon) { String foregroundKey = mForegroundServiceController.getStandardLayoutKey(UserHandle.getUserId(uid), pkg); if (foregroundKey != null) { mEntryManager .getNotificationData().updateAppOp(appOp, uid, pkg, foregroundKey, showIcon); mEntryManager.updateNotifications("app opp changed pkg=" + pkg); } } } Loading
packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java +39 −6 Original line number Diff line number Diff line Loading @@ -21,10 +21,13 @@ import android.util.ArraySet; import android.util.SparseArray; import com.android.internal.messages.nano.SystemMessageProto; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import javax.inject.Inject; import javax.inject.Singleton; /** * Tracks state of foreground services and notifications related to foreground services per user. */ Loading @@ -33,9 +36,11 @@ public class ForegroundServiceController { private final SparseArray<ForegroundServicesUserState> mUserServices = new SparseArray<>(); private final Object mMutex = new Object(); private final NotificationEntryManager mEntryManager; @Inject public ForegroundServiceController() { public ForegroundServiceController(NotificationEntryManager entryManager) { mEntryManager = entryManager; } /** Loading Loading @@ -90,11 +95,18 @@ public class ForegroundServiceController { } /** * Records active app ops. App Ops are stored in FSC in addition to NotificationData in * case they change before we have a notification to tag. * Records active app ops and updates the app op for the pending or visible notifications * with the given parameters. * App Ops are stored in FSC in addition to NotificationEntry in case they change before we * have a notification to tag. * @param appOpCode code for appOp to add/remove * @param uid of user the notification is sent to * @param packageName package that created the notification * @param active whether the appOpCode is active or not */ public void onAppOpChanged(int code, int uid, String packageName, boolean active) { public void onAppOpChanged(int appOpCode, int uid, String packageName, boolean active) { int userId = UserHandle.getUserId(uid); // Record active app ops synchronized (mMutex) { ForegroundServicesUserState userServices = mUserServices.get(userId); if (userServices == null) { Loading @@ -102,9 +114,30 @@ public class ForegroundServiceController { mUserServices.put(userId, userServices); } if (active) { userServices.addOp(packageName, code); userServices.addOp(packageName, appOpCode); } else { userServices.removeOp(packageName, code); userServices.removeOp(packageName, appOpCode); } } // Update appOp if there's an associated pending or visible notification: final String foregroundKey = getStandardLayoutKey(userId, packageName); if (foregroundKey != null) { final NotificationEntry entry = mEntryManager.getPendingOrCurrentNotif(foregroundKey); if (entry != null && uid == entry.getSbn().getUid() && packageName.equals(entry.getSbn().getPackageName())) { boolean changed; synchronized (entry.mActiveAppOps) { if (active) { changed = entry.mActiveAppOps.add(appOpCode); } else { changed = entry.mActiveAppOps.remove(appOpCode); } } if (changed) { mEntryManager.updateNotifications("appOpChanged pkg=" + packageName); } } } } Loading
packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java +28 −11 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.app.NotificationManager; import android.content.Context; import android.os.Bundle; import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.Log; import com.android.internal.statusbar.NotificationVisibility; Loading @@ -40,6 +41,7 @@ public class ForegroundServiceNotificationListener { private final Context mContext; private final ForegroundServiceController mForegroundServiceController; private final NotificationEntryManager mEntryManager; @Inject public ForegroundServiceNotificationListener(Context context, Loading @@ -47,15 +49,16 @@ public class ForegroundServiceNotificationListener { NotificationEntryManager notificationEntryManager) { mContext = context; mForegroundServiceController = foregroundServiceController; notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() { mEntryManager = notificationEntryManager; mEntryManager.addNotificationEntryListener(new NotificationEntryListener() { @Override public void onPendingEntryAdded(NotificationEntry entry) { addNotification(entry.getSbn(), entry.getImportance()); addNotification(entry, entry.getImportance()); } @Override public void onPostEntryUpdated(NotificationEntry entry) { updateNotification(entry.getSbn(), entry.getImportance()); public void onPreEntryUpdated(NotificationEntry entry) { updateNotification(entry, entry.getImportance()); } @Override Loading @@ -67,15 +70,14 @@ public class ForegroundServiceNotificationListener { } }); notificationEntryManager.addNotificationLifetimeExtender( new ForegroundServiceLifetimeExtender()); mEntryManager.addNotificationLifetimeExtender(new ForegroundServiceLifetimeExtender()); } /** * @param sbn notification that was just posted * @param entry notification that was just posted */ private void addNotification(StatusBarNotification sbn, int importance) { updateNotification(sbn, importance); private void addNotification(NotificationEntry entry, int importance) { updateNotification(entry, importance); } /** Loading Loading @@ -113,9 +115,10 @@ public class ForegroundServiceNotificationListener { } /** * @param sbn notification that was just changed in some way * @param entry notification that was just changed in some way */ private void updateNotification(StatusBarNotification sbn, int newImportance) { private void updateNotification(NotificationEntry entry, int newImportance) { final StatusBarNotification sbn = entry.getSbn(); mForegroundServiceController.updateUserState( sbn.getUserId(), userState -> { Loading Loading @@ -143,8 +146,22 @@ public class ForegroundServiceNotificationListener { } } } tagForeground(entry); return true; }, true /* create if not found */); } private void tagForeground(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(); entry.mActiveAppOps.addAll(activeOps); } } } }
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java +2 −9 Original line number Diff line number Diff line Loading @@ -20,12 +20,12 @@ import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.StatusBarNotification; import androidx.annotation.NonNull; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag; import androidx.annotation.NonNull; /** * Listener interface for changes sent by NotificationEntryManager. */ Loading @@ -37,13 +37,6 @@ public interface NotificationEntryListener { default void onPendingEntryAdded(NotificationEntry entry) { } // TODO: Combine this with onPreEntryUpdated into "onBeforeEntryFiltered" or similar /** * Called when a new entry is created but before it has been filtered or displayed to the user. */ default void onBeforeNotificationAdded(NotificationEntry entry) { } /** * Called when a new entry is created. */ Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +12 −3 Original line number Diff line number Diff line Loading @@ -262,9 +262,6 @@ public class NotificationEntryManager implements listener.onEntryInflated(entry, inflatedFlags); } mNotificationData.add(entry); for (NotificationEntryListener listener : mNotificationEntryListeners) { listener.onBeforeNotificationAdded(entry); } updateNotifications("onAsyncInflationFinished"); for (NotificationEntryListener listener : mNotificationEntryListeners) { listener.onNotificationAdded(entry); Loading Loading @@ -563,6 +560,18 @@ public class NotificationEntryManager implements return mPendingNotifications.values(); } /** * Gets the pending or visible notification entry with the given key. Returns null if * notification doesn't exist. */ public NotificationEntry getPendingOrCurrentNotif(String key) { if (mPendingNotifications.containsKey(key)) { return mPendingNotifications.get(key); } else { return mNotificationData.get(key); } } private void extendLifetime(NotificationEntry entry, NotificationLifetimeExtender extender) { NotificationLifetimeExtender activeExtender = mRetainedNotifications.get(entry); if (activeExtender != null && activeExtender != extender) { Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java +0 −34 Original line number Diff line number Diff line Loading @@ -18,10 +18,6 @@ package com.android.systemui.statusbar.notification; import static com.android.internal.util.Preconditions.checkNotNull; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.util.ArraySet; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.ForegroundServiceController; import com.android.systemui.statusbar.notification.collection.NotificationEntry; Loading Loading @@ -70,11 +66,6 @@ public class NotificationListController { boolean removedByUser) { mListContainer.cleanUpViewStateForEntry(entry); } @Override public void onBeforeNotificationAdded(NotificationEntry entry) { tagForeground(entry.getSbn()); } }; private final DeviceProvisionedListener mDeviceProvisionedListener = Loading @@ -84,29 +75,4 @@ public class NotificationListController { mEntryManager.updateNotifications("device provisioned changed"); } }; // TODO: This method is horrifically inefficient private void tagForeground(StatusBarNotification notification) { ArraySet<Integer> activeOps = mForegroundServiceController.getAppOps( notification.getUserId(), notification.getPackageName()); if (activeOps != null) { int len = activeOps.size(); for (int i = 0; i < len; i++) { updateNotificationsForAppOp(activeOps.valueAt(i), notification.getUid(), notification.getPackageName(), true); } } } /** When an app op changes, propagate that change to notifications. */ public void updateNotificationsForAppOp(int appOp, int uid, String pkg, boolean showIcon) { String foregroundKey = mForegroundServiceController.getStandardLayoutKey(UserHandle.getUserId(uid), pkg); if (foregroundKey != null) { mEntryManager .getNotificationData().updateAppOp(appOp, uid, pkg, foregroundKey, showIcon); mEntryManager.updateNotifications("app opp changed pkg=" + pkg); } } }