diff options
| author | 2020-04-09 16:08:47 +0000 | |
|---|---|---|
| committer | 2020-04-09 16:08:47 +0000 | |
| commit | 2214685d42d297eb7f8f73f07bfe15fb1ebab9fc (patch) | |
| tree | 51942bff919df56e4898322e7330a92b1b862d01 | |
| parent | 8ecd6a377b1a2f3cecda831bc6b403608c8a0e11 (diff) | |
| parent | ccf5c5eff7769d94f3c5342e5bcec4919a4e1401 (diff) | |
Merge "Track NotificationEntry creation time" into rvc-dev
9 files changed, 83 insertions, 27 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java index 362014f51e36..e17d4e69093a 100644 --- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java +++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceLifetimeExtender.java @@ -25,6 +25,7 @@ import android.util.ArraySet; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.statusbar.NotificationLifetimeExtender; 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 @@ -39,8 +40,10 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx private NotificationSafeToRemoveCallback mNotificationSafeToRemoveCallback; private ArraySet<NotificationEntry> mManagedEntries = new ArraySet<>(); private Handler mHandler = new Handler(Looper.getMainLooper()); + private final SystemClock mSystemClock; - public ForegroundServiceLifetimeExtender() { + public ForegroundServiceLifetimeExtender(SystemClock systemClock) { + mSystemClock = systemClock; } @Override @@ -55,8 +58,8 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx return false; } - long currentTime = System.currentTimeMillis(); - return currentTime - entry.getSbn().getPostTime() < MIN_FGS_TIME_MS; + long currentTime = mSystemClock.uptimeMillis(); + return currentTime - entry.getCreationTime() < MIN_FGS_TIME_MS; } @Override @@ -84,7 +87,7 @@ public class ForegroundServiceLifetimeExtender implements NotificationLifetimeEx } }; long delayAmt = MIN_FGS_TIME_MS - - (System.currentTimeMillis() - entry.getSbn().getPostTime()); + - (mSystemClock.uptimeMillis() - entry.getCreationTime()); mHandler.postDelayed(r, delayAmt); } } diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java index f01fa811c529..ef1f4e0afede 100644 --- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java +++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceNotificationListener.java @@ -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.NotificationEntry; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener; +import com.android.systemui.util.time.SystemClock; import javax.inject.Inject; import javax.inject.Singleton; @@ -49,7 +50,8 @@ public class ForegroundServiceNotificationListener { public ForegroundServiceNotificationListener(Context context, ForegroundServiceController foregroundServiceController, NotificationEntryManager notificationEntryManager, - NotifPipeline notifPipeline) { + NotifPipeline notifPipeline, + SystemClock systemClock) { mContext = context; mForegroundServiceController = foregroundServiceController; @@ -76,7 +78,8 @@ public class ForegroundServiceNotificationListener { removeNotification(entry.getSbn()); } }); - mEntryManager.addNotificationLifetimeExtender(new ForegroundServiceLifetimeExtender()); + mEntryManager.addNotificationLifetimeExtender( + new ForegroundServiceLifetimeExtender(systemClock)); notifPipeline.addCollectionListener(new NotifCollectionListener() { @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java index 295adae9c9ee..9324b14bf211 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java @@ -24,6 +24,7 @@ import static com.android.systemui.statusbar.notification.row.NotificationRowCon import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Notification; +import android.os.SystemClock; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.RankingMap; @@ -555,8 +556,8 @@ public class NotificationEntryManager implements NotificationEntry entry = new NotificationEntry( notification, ranking, - mFgsFeatureController.isForegroundServiceDismissalEnabled()); - mAllNotifications.add(entry); + mFgsFeatureController.isForegroundServiceDismissalEnabled(), + SystemClock.uptimeMillis()); mLeakDetector.trackInstance(entry); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java index 9c2cac71925e..365862bef871 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java @@ -47,6 +47,7 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.Notification; import android.os.RemoteException; +import android.os.SystemClock; import android.os.UserHandle; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.Ranking; @@ -387,7 +388,7 @@ public class NotifCollection implements Dumpable { if (entry == null) { // A new notification! - entry = new NotificationEntry(sbn, ranking); + entry = new NotificationEntry(sbn, ranking, SystemClock.uptimeMillis()); mNotificationSet.put(sbn.getKey(), entry); mLogger.logNotifPosted(sbn.getKey()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java index c1ba26d034ed..68ec34e90760 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java @@ -35,6 +35,7 @@ import static com.android.systemui.statusbar.notification.stack.NotificationSect import static java.util.Objects.requireNonNull; +import android.annotation.CurrentTimeMillisLong; import android.app.Notification; import android.app.Notification.MessagingStyle.Message; import android.app.NotificationChannel; @@ -93,6 +94,7 @@ public final class NotificationEntry extends ListEntry { private final String mKey; private StatusBarNotification mSbn; private Ranking mRanking; + private long mCreationTime; /* * Bookkeeping members @@ -171,21 +173,29 @@ public final class NotificationEntry extends ListEntry { private boolean mAllowFgsDismissal; 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( @NonNull StatusBarNotification sbn, - @NonNull Ranking ranking) { - this(sbn, ranking, false); + @NonNull Ranking ranking, + long creationTime) { + this(sbn, ranking, false, creationTime); } public NotificationEntry( @NonNull StatusBarNotification sbn, @NonNull Ranking ranking, - boolean allowFgsDismissal + boolean allowFgsDismissal, + long creationTime ) { super(requireNonNull(Objects.requireNonNull(sbn).getKey())); requireNonNull(ranking); + mCreationTime = creationTime; mKey = sbn.getKey(); setSbn(sbn); setRanking(ranking); @@ -238,6 +248,21 @@ public final class NotificationEntry extends ListEntry { } /** + * 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. * TODO: Make this package-private */ diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java index 69e933e95562..45f9437efc15 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java @@ -52,6 +52,7 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotifPipeline; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; +import com.android.systemui.util.time.FakeSystemClock; import junit.framework.Assert; @@ -69,6 +70,7 @@ public class ForegroundServiceControllerTest extends SysuiTestCase { private ForegroundServiceController mFsc; private ForegroundServiceNotificationListener mListener; private NotificationEntryListener mEntryListener; + private final FakeSystemClock mClock = new FakeSystemClock(); @Mock private NotificationEntryManager mEntryManager; @Mock private AppOpsController mAppOpsController; @Mock private Handler mMainHandler; @@ -80,9 +82,10 @@ public class ForegroundServiceControllerTest extends SysuiTestCase { allowTestableLooperAsMainThread(); MockitoAnnotations.initMocks(this); - mFsc = new ForegroundServiceController(mEntryManager, mAppOpsController, mMainHandler); + mFsc = new ForegroundServiceController( + mEntryManager, mAppOpsController, mMainHandler); mListener = new ForegroundServiceNotificationListener( - mContext, mFsc, mEntryManager, mNotifPipeline); + mContext, mFsc, mEntryManager, mNotifPipeline, mClock); ArgumentCaptor<NotificationEntryListener> entryListenerCaptor = ArgumentCaptor.forClass(NotificationEntryListener.class); verify(mEntryManager).addNotificationEntryListener( diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceNotificationListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceNotificationListenerTest.java index 46a473bd6543..bca8deeafd34 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceNotificationListenerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceNotificationListenerTest.java @@ -17,7 +17,6 @@ package com.android.systemui; import static com.android.systemui.ForegroundServiceLifetimeExtender.MIN_FGS_TIME_MS; -import static com.android.systemui.statusbar.NotificationEntryHelper.modifySbn; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -29,6 +28,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder; +import com.android.systemui.util.time.FakeSystemClock; import org.junit.Before; import org.junit.Test; @@ -37,12 +37,15 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) @SmallTest public class ForegroundServiceNotificationListenerTest extends SysuiTestCase { - private ForegroundServiceLifetimeExtender mExtender = new ForegroundServiceLifetimeExtender(); + private ForegroundServiceLifetimeExtender mExtender; private NotificationEntry mEntry; private Notification mNotif; + private final FakeSystemClock mClock = new FakeSystemClock(); @Before public void setup() { + mExtender = new ForegroundServiceLifetimeExtender(mClock); + mNotif = new Notification.Builder(mContext, "") .setSmallIcon(R.drawable.ic_person) .setContentTitle("Title") @@ -50,6 +53,7 @@ public class ForegroundServiceNotificationListenerTest extends SysuiTestCase { .build(); mEntry = new NotificationEntryBuilder() + .setCreationTime(mClock.uptimeMillis()) .setNotification(mNotif) .build(); } @@ -62,27 +66,26 @@ public class ForegroundServiceNotificationListenerTest extends SysuiTestCase { // Extend the lifetime of a FGS notification iff it has not been visible // for the minimum time mNotif.flags |= Notification.FLAG_FOREGROUND_SERVICE; - modifySbn(mEntry) - .setPostTime(System.currentTimeMillis()) - .build(); + + // No time has elapsed, keep showing assertTrue(mExtender.shouldExtendLifetime(mEntry)); } @Test public void testShouldExtendLifetime_shouldNot_foreground() { mNotif.flags |= Notification.FLAG_FOREGROUND_SERVICE; - modifySbn(mEntry) - .setPostTime(System.currentTimeMillis() - MIN_FGS_TIME_MS - 1) - .build(); + + // Entry was created at mClock.uptimeMillis(), advance it MIN_FGS_TIME_MS + 1 + mClock.advanceTime(MIN_FGS_TIME_MS + 1); assertFalse(mExtender.shouldExtendLifetime(mEntry)); } @Test public void testShouldExtendLifetime_shouldNot_notForeground() { mNotif.flags = 0; - modifySbn(mEntry) - .setPostTime(System.currentTimeMillis() - MIN_FGS_TIME_MS - 1) - .build(); + + // Entry was created at mClock.uptimeMillis(), advance it MIN_FGS_TIME_MS + 1 + mClock.advanceTime(MIN_FGS_TIME_MS + 1); assertFalse(mExtender.shouldExtendLifetime(mEntry)); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java index 43cf83f380f1..81f9546ba885 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java @@ -29,6 +29,7 @@ import android.service.notification.StatusBarNotification; import com.android.internal.logging.InstanceId; import com.android.systemui.statusbar.RankingBuilder; import com.android.systemui.statusbar.SbnBuilder; +import com.android.systemui.util.time.FakeSystemClock; import java.util.ArrayList; @@ -44,16 +45,22 @@ import java.util.ArrayList; public class NotificationEntryBuilder { private final SbnBuilder mSbnBuilder = new SbnBuilder(); private final RankingBuilder mRankingBuilder = new RankingBuilder(); + private final FakeSystemClock mClock = new FakeSystemClock(); private StatusBarNotification mSbn = null; /* ListEntry properties */ private GroupEntry mParent; private int mSection = -1; + /* If set, use this creation time instead of mClock.uptimeMillis */ + private long mCreationTime = -1; + public NotificationEntry build() { StatusBarNotification sbn = mSbn != null ? mSbn : mSbnBuilder.build(); mRankingBuilder.setKey(sbn.getKey()); - final NotificationEntry entry = new NotificationEntry(sbn, mRankingBuilder.build()); + long creationTime = mCreationTime != -1 ? mCreationTime : mClock.uptimeMillis(); + final NotificationEntry entry = new NotificationEntry( + sbn, mRankingBuilder.build(), mClock.uptimeMillis()); /* ListEntry properties */ entry.setParent(mParent); @@ -86,6 +93,14 @@ public class NotificationEntryBuilder { return this; } + /** + * Set the creation time + */ + public NotificationEntryBuilder setCreationTime(long creationTime) { + mCreationTime = creationTime; + return this; + } + /* Delegated to SbnBuilder */ public NotificationEntryBuilder setPkg(String pkg) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java index 5b0b66849027..1a022ec7c87d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java @@ -52,6 +52,7 @@ import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.statusbar.RankingBuilder; import com.android.systemui.statusbar.SbnBuilder; +import com.android.systemui.util.time.FakeSystemClock; import org.junit.Before; import org.junit.Test; @@ -71,6 +72,7 @@ public class NotificationEntryTest extends SysuiTestCase { private int mId; private NotificationEntry mEntry; + private final FakeSystemClock mClock = new FakeSystemClock(); @Before public void setup() { @@ -187,7 +189,7 @@ public class NotificationEntryTest extends SysuiTestCase { .build(); NotificationEntry entry = - new NotificationEntry(sbn, ranking); + new NotificationEntry(sbn, ranking, mClock.uptimeMillis()); assertEquals(systemGeneratedSmartActions, entry.getSmartActions()); assertEquals(NOTIFICATION_CHANNEL, entry.getChannel()); |