Merge "Track NotificationEntry creation time" into rvc-dev am: 2214685d42 am: 5a0f5e7195

Change-Id: I029511369d959c2dac59769c108dbbe29920fc13
This commit is contained in:
Evan Laird
2020-04-09 16:28:38 +00:00
committed by Automerger Merge Worker
9 changed files with 83 additions and 27 deletions

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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());

View File

@@ -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

View File

@@ -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(

View File

@@ -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));
}
}

View File

@@ -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) {

View File

@@ -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());