Merge "Track NotificationEntry creation time" into rvc-dev am: 2214685d42 am: 5a0f5e7195
Change-Id: I029511369d959c2dac59769c108dbbe29920fc13
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
@@ -237,6 +247,21 @@ public final class NotificationEntry extends ListEntry {
|
||||
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.
|
||||
* TODO: Make this package-private
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user