Loading packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java +7 −4 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.util.ArraySet; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.util.time.SystemClock; /** /** * Extends the lifetime of foreground notification services such that they show for at least * Extends the lifetime of foreground notification services such that they show for at least Loading @@ -39,8 +40,10 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx private NotificationSafeToRemoveCallback mNotificationSafeToRemoveCallback; private NotificationSafeToRemoveCallback mNotificationSafeToRemoveCallback; private ArraySet<NotificationEntry> mManagedEntries = new ArraySet<>(); private ArraySet<NotificationEntry> mManagedEntries = new ArraySet<>(); private Handler mHandler = new Handler(Looper.getMainLooper()); private Handler mHandler = new Handler(Looper.getMainLooper()); private final SystemClock mSystemClock; public ForegroundServiceLifetimeExtender() { public ForegroundServiceLifetimeExtender(SystemClock systemClock) { mSystemClock = systemClock; } } @Override @Override Loading @@ -55,8 +58,8 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx return false; return false; } } long currentTime = System.currentTimeMillis(); long currentTime = mSystemClock.uptimeMillis(); return currentTime - entry.getSbn().getPostTime() < MIN_FGS_TIME_MS; return currentTime - entry.getCreationTime() < MIN_FGS_TIME_MS; } } @Override @Override Loading Loading @@ -84,7 +87,7 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx } } }; }; long delayAmt = MIN_FGS_TIME_MS long delayAmt = MIN_FGS_TIME_MS - (System.currentTimeMillis() - entry.getSbn().getPostTime()); - (mSystemClock.uptimeMillis() - entry.getCreationTime()); mHandler.postDelayed(r, delayAmt); mHandler.postDelayed(r, delayAmt); } } } } Loading packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java +5 −2 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.util.time.SystemClock; import javax.inject.Inject; import javax.inject.Inject; import javax.inject.Singleton; import javax.inject.Singleton; Loading @@ -49,7 +50,8 @@ public class ForegroundServiceNotificationListener { public ForegroundServiceNotificationListener(Context context, public ForegroundServiceNotificationListener(Context context, ForegroundServiceController foregroundServiceController, ForegroundServiceController foregroundServiceController, NotificationEntryManager notificationEntryManager, NotificationEntryManager notificationEntryManager, NotifPipeline notifPipeline) { NotifPipeline notifPipeline, SystemClock systemClock) { mContext = context; mContext = context; mForegroundServiceController = foregroundServiceController; mForegroundServiceController = foregroundServiceController; Loading @@ -76,7 +78,8 @@ public class ForegroundServiceNotificationListener { removeNotification(entry.getSbn()); removeNotification(entry.getSbn()); } } }); }); mEntryManager.addNotificationLifetimeExtender(new ForegroundServiceLifetimeExtender()); mEntryManager.addNotificationLifetimeExtender( new ForegroundServiceLifetimeExtender(systemClock)); notifPipeline.addCollectionListener(new NotifCollectionListener() { notifPipeline.addCollectionListener(new NotifCollectionListener() { @Override @Override Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static com.android.systemui.statusbar.notification.row.NotificationRowCon import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.Notification; import android.app.Notification; import android.os.SystemClock; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.NotificationListenerService.RankingMap; Loading Loading @@ -555,8 +556,8 @@ public class NotificationEntryManager implements NotificationEntry entry = new NotificationEntry( NotificationEntry entry = new NotificationEntry( notification, notification, ranking, ranking, mFgsFeatureController.isForegroundServiceDismissalEnabled()); mFgsFeatureController.isForegroundServiceDismissalEnabled(), mAllNotifications.add(entry); SystemClock.uptimeMillis()); mLeakDetector.trackInstance(entry); mLeakDetector.trackInstance(entry); Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.annotation.UserIdInt; import android.app.Notification; import android.app.Notification; import android.os.RemoteException; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserHandle; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.Ranking; Loading Loading @@ -387,7 +388,7 @@ public class NotifCollection implements Dumpable { if (entry == null) { if (entry == null) { // A new notification! // A new notification! entry = new NotificationEntry(sbn, ranking); entry = new NotificationEntry(sbn, ranking, SystemClock.uptimeMillis()); mNotificationSet.put(sbn.getKey(), entry); mNotificationSet.put(sbn.getKey(), entry); mLogger.logNotifPosted(sbn.getKey()); mLogger.logNotifPosted(sbn.getKey()); Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +28 −3 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ import static com.android.systemui.statusbar.notification.stack.NotificationSect import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull; import android.annotation.CurrentTimeMillisLong; import android.app.Notification; import android.app.Notification; import android.app.Notification.MessagingStyle.Message; import android.app.Notification.MessagingStyle.Message; import android.app.NotificationChannel; import android.app.NotificationChannel; Loading Loading @@ -93,6 +94,7 @@ public final class NotificationEntry extends ListEntry { private final String mKey; private final String mKey; private StatusBarNotification mSbn; private StatusBarNotification mSbn; private Ranking mRanking; private Ranking mRanking; private long mCreationTime; /* /* * Bookkeeping members * Bookkeeping members Loading Loading @@ -171,21 +173,29 @@ public final class NotificationEntry extends ListEntry { private boolean mAllowFgsDismissal; private boolean mAllowFgsDismissal; private int mBucket = BUCKET_ALERTING; private int mBucket = BUCKET_ALERTING; /** * @param sbn the StatusBarNotification from system server * @param ranking also from system server * @param creationTime SystemClock.uptimeMillis of when we were created */ public NotificationEntry( public NotificationEntry( @NonNull StatusBarNotification sbn, @NonNull StatusBarNotification sbn, @NonNull Ranking ranking) { @NonNull Ranking ranking, this(sbn, ranking, false); long creationTime) { this(sbn, ranking, false, creationTime); } } public NotificationEntry( public NotificationEntry( @NonNull StatusBarNotification sbn, @NonNull StatusBarNotification sbn, @NonNull Ranking ranking, @NonNull Ranking ranking, boolean allowFgsDismissal boolean allowFgsDismissal, long creationTime ) { ) { super(requireNonNull(Objects.requireNonNull(sbn).getKey())); super(requireNonNull(Objects.requireNonNull(sbn).getKey())); requireNonNull(ranking); requireNonNull(ranking); mCreationTime = creationTime; mKey = sbn.getKey(); mKey = sbn.getKey(); setSbn(sbn); setSbn(sbn); setRanking(ranking); setRanking(ranking); Loading Loading @@ -237,6 +247,21 @@ public final class NotificationEntry extends ListEntry { return mRanking; return mRanking; } } /** * A timestamp of SystemClock.uptimeMillis() of when this entry was first created, regardless * of any changes to the data presented. It is set once on creation and will never change, and * allows us to know exactly how long this notification has been alive for in our listener * service. It is entirely unrelated to the information inside of the notification. * * This is different to Notification#when because it persists throughout updates, whereas * system server treats every single call to notify() as a new notification and we handle * updates to NotificationEntry locally. */ @CurrentTimeMillisLong public long getCreationTime() { return mCreationTime; } /** /** * Should only be called by NotificationEntryManager and friends. * Should only be called by NotificationEntryManager and friends. * TODO: Make this package-private * TODO: Make this package-private Loading Loading
packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java +7 −4 Original line number Original line Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.util.ArraySet; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.util.time.SystemClock; /** /** * Extends the lifetime of foreground notification services such that they show for at least * Extends the lifetime of foreground notification services such that they show for at least Loading @@ -39,8 +40,10 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx private NotificationSafeToRemoveCallback mNotificationSafeToRemoveCallback; private NotificationSafeToRemoveCallback mNotificationSafeToRemoveCallback; private ArraySet<NotificationEntry> mManagedEntries = new ArraySet<>(); private ArraySet<NotificationEntry> mManagedEntries = new ArraySet<>(); private Handler mHandler = new Handler(Looper.getMainLooper()); private Handler mHandler = new Handler(Looper.getMainLooper()); private final SystemClock mSystemClock; public ForegroundServiceLifetimeExtender() { public ForegroundServiceLifetimeExtender(SystemClock systemClock) { mSystemClock = systemClock; } } @Override @Override Loading @@ -55,8 +58,8 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx return false; return false; } } long currentTime = System.currentTimeMillis(); long currentTime = mSystemClock.uptimeMillis(); return currentTime - entry.getSbn().getPostTime() < MIN_FGS_TIME_MS; return currentTime - entry.getCreationTime() < MIN_FGS_TIME_MS; } } @Override @Override Loading Loading @@ -84,7 +87,7 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx } } }; }; long delayAmt = MIN_FGS_TIME_MS long delayAmt = MIN_FGS_TIME_MS - (System.currentTimeMillis() - entry.getSbn().getPostTime()); - (mSystemClock.uptimeMillis() - entry.getCreationTime()); mHandler.postDelayed(r, delayAmt); mHandler.postDelayed(r, delayAmt); } } } } Loading
packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java +5 −2 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,7 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; import com.android.systemui.util.time.SystemClock; import javax.inject.Inject; import javax.inject.Inject; import javax.inject.Singleton; import javax.inject.Singleton; Loading @@ -49,7 +50,8 @@ public class ForegroundServiceNotificationListener { public ForegroundServiceNotificationListener(Context context, public ForegroundServiceNotificationListener(Context context, ForegroundServiceController foregroundServiceController, ForegroundServiceController foregroundServiceController, NotificationEntryManager notificationEntryManager, NotificationEntryManager notificationEntryManager, NotifPipeline notifPipeline) { NotifPipeline notifPipeline, SystemClock systemClock) { mContext = context; mContext = context; mForegroundServiceController = foregroundServiceController; mForegroundServiceController = foregroundServiceController; Loading @@ -76,7 +78,8 @@ public class ForegroundServiceNotificationListener { removeNotification(entry.getSbn()); removeNotification(entry.getSbn()); } } }); }); mEntryManager.addNotificationLifetimeExtender(new ForegroundServiceLifetimeExtender()); mEntryManager.addNotificationLifetimeExtender( new ForegroundServiceLifetimeExtender(systemClock)); notifPipeline.addCollectionListener(new NotifCollectionListener() { notifPipeline.addCollectionListener(new NotifCollectionListener() { @Override @Override Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static com.android.systemui.statusbar.notification.row.NotificationRowCon import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.Notification; import android.app.Notification; import android.os.SystemClock; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.NotificationListenerService.RankingMap; Loading Loading @@ -555,8 +556,8 @@ public class NotificationEntryManager implements NotificationEntry entry = new NotificationEntry( NotificationEntry entry = new NotificationEntry( notification, notification, ranking, ranking, mFgsFeatureController.isForegroundServiceDismissalEnabled()); mFgsFeatureController.isForegroundServiceDismissalEnabled(), mAllNotifications.add(entry); SystemClock.uptimeMillis()); mLeakDetector.trackInstance(entry); mLeakDetector.trackInstance(entry); Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -47,6 +47,7 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.annotation.UserIdInt; import android.app.Notification; import android.app.Notification; import android.os.RemoteException; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserHandle; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.Ranking; Loading Loading @@ -387,7 +388,7 @@ public class NotifCollection implements Dumpable { if (entry == null) { if (entry == null) { // A new notification! // A new notification! entry = new NotificationEntry(sbn, ranking); entry = new NotificationEntry(sbn, ranking, SystemClock.uptimeMillis()); mNotificationSet.put(sbn.getKey(), entry); mNotificationSet.put(sbn.getKey(), entry); mLogger.logNotifPosted(sbn.getKey()); mLogger.logNotifPosted(sbn.getKey()); Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +28 −3 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ import static com.android.systemui.statusbar.notification.stack.NotificationSect import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull; import android.annotation.CurrentTimeMillisLong; import android.app.Notification; import android.app.Notification; import android.app.Notification.MessagingStyle.Message; import android.app.Notification.MessagingStyle.Message; import android.app.NotificationChannel; import android.app.NotificationChannel; Loading Loading @@ -93,6 +94,7 @@ public final class NotificationEntry extends ListEntry { private final String mKey; private final String mKey; private StatusBarNotification mSbn; private StatusBarNotification mSbn; private Ranking mRanking; private Ranking mRanking; private long mCreationTime; /* /* * Bookkeeping members * Bookkeeping members Loading Loading @@ -171,21 +173,29 @@ public final class NotificationEntry extends ListEntry { private boolean mAllowFgsDismissal; private boolean mAllowFgsDismissal; private int mBucket = BUCKET_ALERTING; private int mBucket = BUCKET_ALERTING; /** * @param sbn the StatusBarNotification from system server * @param ranking also from system server * @param creationTime SystemClock.uptimeMillis of when we were created */ public NotificationEntry( public NotificationEntry( @NonNull StatusBarNotification sbn, @NonNull StatusBarNotification sbn, @NonNull Ranking ranking) { @NonNull Ranking ranking, this(sbn, ranking, false); long creationTime) { this(sbn, ranking, false, creationTime); } } public NotificationEntry( public NotificationEntry( @NonNull StatusBarNotification sbn, @NonNull StatusBarNotification sbn, @NonNull Ranking ranking, @NonNull Ranking ranking, boolean allowFgsDismissal boolean allowFgsDismissal, long creationTime ) { ) { super(requireNonNull(Objects.requireNonNull(sbn).getKey())); super(requireNonNull(Objects.requireNonNull(sbn).getKey())); requireNonNull(ranking); requireNonNull(ranking); mCreationTime = creationTime; mKey = sbn.getKey(); mKey = sbn.getKey(); setSbn(sbn); setSbn(sbn); setRanking(ranking); setRanking(ranking); Loading Loading @@ -237,6 +247,21 @@ public final class NotificationEntry extends ListEntry { return mRanking; return mRanking; } } /** * A timestamp of SystemClock.uptimeMillis() of when this entry was first created, regardless * of any changes to the data presented. It is set once on creation and will never change, and * allows us to know exactly how long this notification has been alive for in our listener * service. It is entirely unrelated to the information inside of the notification. * * This is different to Notification#when because it persists throughout updates, whereas * system server treats every single call to notify() as a new notification and we handle * updates to NotificationEntry locally. */ @CurrentTimeMillisLong public long getCreationTime() { return mCreationTime; } /** /** * Should only be called by NotificationEntryManager and friends. * Should only be called by NotificationEntryManager and friends. * TODO: Make this package-private * TODO: Make this package-private Loading