diff options
11 files changed, 182 insertions, 56 deletions
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java index c5d97b718ff0..74b913645ad4 100644 --- a/core/java/android/service/notification/StatusBarNotification.java +++ b/core/java/android/service/notification/StatusBarNotification.java @@ -35,6 +35,7 @@ import android.os.Parcelable; import android.os.UserHandle; import android.text.TextUtils; +import com.android.internal.logging.InstanceId; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -68,6 +69,8 @@ public class StatusBarNotification implements Parcelable { private final UserHandle user; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final long postTime; + // A small per-notification ID, used for statsd logging. + private InstanceId mInstanceId; // Not final, see setInstanceId() private Context mContext; // used for inflation & icon expansion @@ -131,8 +134,9 @@ public class StatusBarNotification implements Parcelable { this.postTime = in.readLong(); if (in.readInt() != 0) { this.overrideGroupKey = in.readString(); - } else { - this.overrideGroupKey = null; + } + if (in.readInt() != 0) { + this.mInstanceId = InstanceId.CREATOR.createFromParcel(in); } this.key = key(); this.groupKey = groupKey(); @@ -196,7 +200,6 @@ public class StatusBarNotification implements Parcelable { out.writeInt(this.initialPid); this.notification.writeToParcel(out, flags); user.writeToParcel(out, flags); - out.writeLong(this.postTime); if (this.overrideGroupKey != null) { out.writeInt(1); @@ -204,6 +207,12 @@ public class StatusBarNotification implements Parcelable { } else { out.writeInt(0); } + if (this.mInstanceId != null) { + out.writeInt(1); + mInstanceId.writeToParcel(out, flags); + } else { + out.writeInt(0); + } } public int describeContents() { @@ -390,6 +399,20 @@ public class StatusBarNotification implements Parcelable { /** * @hide */ + public InstanceId getInstanceId() { + return mInstanceId; + } + + /** + * @hide + */ + public void setInstanceId(InstanceId instanceId) { + mInstanceId = instanceId; + } + + /** + * @hide + */ @UnsupportedAppUsage public Context getPackageContext(Context context) { if (mContext == null) { diff --git a/core/java/com/android/internal/logging/InstanceId.java b/core/java/com/android/internal/logging/InstanceId.java index 85dbac3f59bb..85643fcffa2f 100644 --- a/core/java/com/android/internal/logging/InstanceId.java +++ b/core/java/com/android/internal/logging/InstanceId.java @@ -16,20 +16,33 @@ package com.android.internal.logging; +import static java.lang.Math.max; +import static java.lang.Math.min; + import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; import com.android.internal.annotations.VisibleForTesting; /** * An opaque identifier used to disambiguate which logs refer to a particular instance of some * UI element. Useful when there might be multiple instances simultaneously active. - * Obtain from InstanceIdSequence. + * Obtain from InstanceIdSequence. Clipped to range [0, INSTANCE_ID_MAX]. */ -public class InstanceId { - private int mId; - protected InstanceId(int id) { - mId = id; +public final class InstanceId implements Parcelable { + // At most 20 bits: ~1m possibilities, ~0.5% probability of collision in 100 values + static final int INSTANCE_ID_MAX = 1 << 20; + + private final int mId; + InstanceId(int id) { + mId = min(max(0, id), INSTANCE_ID_MAX); + } + + private InstanceId(Parcel in) { + this(in.readInt()); } + @VisibleForTesting public int getId() { return mId; @@ -47,4 +60,28 @@ public class InstanceId { } return mId == ((InstanceId) obj).mId; } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mId); + } + + public static final Parcelable.Creator<InstanceId> CREATOR = + new Parcelable.Creator<InstanceId>() { + @Override + public InstanceId createFromParcel(Parcel in) { + return new InstanceId(in); + } + + @Override + public InstanceId[] newArray(int size) { + return new InstanceId[size]; + } + }; + } diff --git a/core/java/com/android/internal/logging/InstanceIdSequence.java b/core/java/com/android/internal/logging/InstanceIdSequence.java index 2e78ed8c5185..aa507e538944 100644 --- a/core/java/com/android/internal/logging/InstanceIdSequence.java +++ b/core/java/com/android/internal/logging/InstanceIdSequence.java @@ -19,6 +19,8 @@ package com.android.internal.logging; import static java.lang.Math.max; import static java.lang.Math.min; +import com.android.internal.annotations.VisibleForTesting; + import java.security.SecureRandom; import java.util.Random; @@ -28,8 +30,6 @@ import java.util.Random; * first use; try to give it a long lifetime. Safe for concurrent use. */ public class InstanceIdSequence { - // At most 20 bits: ~1m possibilities, ~0.5% probability of collision in 100 values - private static final int INSTANCE_ID_MAX = 1 << 20; protected final int mInstanceIdMax; private final Random mRandom = new SecureRandom(); @@ -39,7 +39,7 @@ public class InstanceIdSequence { * an all-zero sequence. */ public InstanceIdSequence(int instanceIdMax) { - mInstanceIdMax = min(max(0, instanceIdMax), INSTANCE_ID_MAX); + mInstanceIdMax = min(max(0, instanceIdMax), InstanceId.INSTANCE_ID_MAX); } /** @@ -47,6 +47,16 @@ public class InstanceIdSequence { * @return new InstanceId */ public InstanceId newInstanceId() { - return new InstanceId(mRandom.nextInt(mInstanceIdMax)); + return newInstanceIdInternal(mRandom.nextInt(mInstanceIdMax)); + } + + /** + * Factory function for instance IDs, used for testing. + * @param id + * @return new InstanceId(id) + */ + @VisibleForTesting + protected InstanceId newInstanceIdInternal(int id) { + return new InstanceId(id); } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 7f107d58abae..7104790d0a7c 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -231,6 +231,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.compat.IPlatformCompat; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; +import com.android.internal.logging.InstanceIdSequence; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -380,6 +381,8 @@ public class NotificationManagerService extends SystemService { private static final String SCHEME_TIMEOUT = "timeout"; private static final String EXTRA_KEY = "key"; + private static final int NOTIFICATION_INSTANCE_ID_MAX = (1 << 13); + /** * Apps that post custom toasts in the background will have those blocked. Apps can * still post toasts created with @@ -519,6 +522,7 @@ public class NotificationManagerService extends SystemService { private final SavePolicyFileRunnable mSavePolicyFile = new SavePolicyFileRunnable(); private NotificationRecordLogger mNotificationRecordLogger; + private InstanceIdSequence mNotificationInstanceIdSequence; private static class Archive { final int mBufferSize; @@ -1718,18 +1722,22 @@ public class NotificationManagerService extends SystemService { } public NotificationManagerService(Context context) { - this(context, new NotificationRecordLoggerImpl()); + this(context, + new NotificationRecordLoggerImpl(), + new InstanceIdSequence(NOTIFICATION_INSTANCE_ID_MAX)); } @VisibleForTesting public NotificationManagerService(Context context, - NotificationRecordLogger notificationRecordLogger) { + NotificationRecordLogger notificationRecordLogger, + InstanceIdSequence notificationInstanceIdSequence) { super(context); mNotificationRecordLogger = notificationRecordLogger; + mNotificationInstanceIdSequence = notificationInstanceIdSequence; Notification.processWhitelistToken = WHITELIST_TOKEN; } - // TODO - replace these methods with a single VisibleForTesting constructor + // TODO - replace these methods with new fields in the VisibleForTesting constructor @VisibleForTesting void setAudioManager(AudioManager audioMananger) { mAudioManager = audioMananger; @@ -6291,6 +6299,14 @@ public class NotificationManagerService extends SystemService { NotificationRecord old = mNotificationsByKey.get(key); final StatusBarNotification n = r.sbn; final Notification notification = n.getNotification(); + + // Make sure the SBN has an instance ID for statsd logging. + if (old == null || old.sbn.getInstanceId() == null) { + n.setInstanceId(mNotificationInstanceIdSequence.newInstanceId()); + } else { + n.setInstanceId(old.sbn.getInstanceId()); + } + int index = indexOfNotificationLocked(n.getKey()); if (index < 0) { mNotificationList.add(r); diff --git a/services/core/java/com/android/server/notification/NotificationRecordLogger.java b/services/core/java/com/android/server/notification/NotificationRecordLogger.java index 03929e883852..9bbc39249e2e 100644 --- a/services/core/java/com/android/server/notification/NotificationRecordLogger.java +++ b/services/core/java/com/android/server/notification/NotificationRecordLogger.java @@ -138,5 +138,9 @@ public interface NotificationRecordLogger { String assistant = r.getAdjustmentIssuer(); return (assistant == null) ? 0 : assistant.hashCode(); } + + int getInstanceId() { + return (r.sbn.getInstanceId() == null ? 0 : r.sbn.getInstanceId().getId()); + } } } diff --git a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java index d637ad5e368b..00b4c2b060ac 100644 --- a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java +++ b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java @@ -35,7 +35,7 @@ public class NotificationRecordLoggerImpl implements NotificationRecordLogger { /* int32 event_id = 1 */ p.getUiEvent().getId(), /* int32 uid = 2 */ r.getUid(), /* string package_name = 3 */ r.sbn.getPackageName(), - /* int32 instance_id = 4 */ 0, // TODO generate and fill instance ids + /* int32 instance_id = 4 */ p.getInstanceId(), /* int32 notification_id = 5 */ r.sbn.getId(), /* string notification_tag = 6 */ r.sbn.getTag(), /* string channel_id = 7 */ r.sbn.getChannelIdLogTag(), diff --git a/core/java/com/android/internal/logging/testing/InstanceIdSequenceFake.java b/services/tests/uiservicestests/src/com/android/internal/logging/InstanceIdSequenceFake.java index 0fd40b9ceb06..1629ef00b65a 100644 --- a/core/java/com/android/internal/logging/testing/InstanceIdSequenceFake.java +++ b/services/tests/uiservicestests/src/com/android/internal/logging/InstanceIdSequenceFake.java @@ -14,12 +14,7 @@ * limitations under the License. */ -package com.android.internal.logging.testing; - -import android.annotation.SuppressLint; - -import com.android.internal.logging.InstanceId; -import com.android.internal.logging.InstanceIdSequence; +package com.android.internal.logging; /** * A fake implementation of InstanceIdSequence that returns 0, 1, 2, ... @@ -30,27 +25,15 @@ public class InstanceIdSequenceFake extends InstanceIdSequence { super(instanceIdMax); } - /** - * Extend InstanceId to add a constructor we can call, strictly for testing purposes. - * Public so that tests can check whether the InstanceIds they see are fake. - */ - public static class InstanceIdFake extends InstanceId { - @SuppressLint("VisibleForTests") // This is test infrastructure, which ought to count - InstanceIdFake(int id) { - super(id); - } - } - private int mNextId = 0; @Override public InstanceId newInstanceId() { synchronized (this) { - ++mNextId; if (mNextId >= mInstanceIdMax) { mNextId = 0; } - return new InstanceIdFake(mNextId); + return newInstanceIdInternal(mNextId++); } } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java index 651ad40a4781..f029bc80480a 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java @@ -72,6 +72,8 @@ import android.view.accessibility.IAccessibilityManagerClient; import androidx.test.runner.AndroidJUnit4; +import com.android.internal.logging.InstanceIdSequence; +import com.android.internal.logging.InstanceIdSequenceFake; import com.android.internal.util.IntPair; import com.android.server.UiServiceTestCase; import com.android.server.lights.LogicalLight; @@ -99,6 +101,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { @Mock IAccessibilityManager mAccessibilityService; NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake(); + private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake( + 1 << 30); private NotificationManagerService mService; private String mPkg = "com.android.server.notification"; @@ -149,7 +153,8 @@ public class BuzzBeepBlinkTest extends UiServiceTestCase { verify(mAccessibilityService).addClient(any(IAccessibilityManagerClient.class), anyInt()); assertTrue(accessibilityManager.isEnabled()); - mService = spy(new NotificationManagerService(getContext(), mNotificationRecordLogger)); + mService = spy(new NotificationManagerService(getContext(), mNotificationRecordLogger, + mNotificationInstanceIdSequence)); mService.setAudioManager(mAudioManager); mService.setVibrator(mVibrator); mService.setSystemReady(true); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 768b4721a1ee..2cf5eaefcc58 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -148,6 +148,8 @@ import androidx.test.InstrumentationRegistry; import com.android.internal.R; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; +import com.android.internal.logging.InstanceIdSequence; +import com.android.internal.logging.InstanceIdSequenceFake; import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.util.FastXmlSerializer; import com.android.server.LocalServices; @@ -257,7 +259,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Mock NotificationHistoryManager mHistoryManager; NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake(); - + private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake( + 1 << 30); // Use a Testable subclass so we can simulate calls from the system without failing. private static class TestableNotificationManagerService extends NotificationManagerService { @@ -267,8 +270,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Nullable NotificationAssistantAccessGrantedCallback mNotificationAssistantAccessGrantedCallback; - TestableNotificationManagerService(Context context, NotificationRecordLogger logger) { - super(context, logger); + TestableNotificationManagerService(Context context, NotificationRecordLogger logger, + InstanceIdSequence notificationInstanceIdSequence) { + super(context, logger, notificationInstanceIdSequence); } @Override @@ -355,7 +359,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any()); - mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger); + mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, + mNotificationInstanceIdSequence); // Use this testable looper. mTestableLooper = TestableLooper.get(this); @@ -1135,6 +1140,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals(PKG, call.r.sbn.getPackageName()); assertEquals(0, call.r.sbn.getId()); assertEquals(tag, call.r.sbn.getTag()); + assertNotNull(call.r.sbn.getInstanceId()); + assertEquals(0, call.r.sbn.getInstanceId().getId()); } @Test @@ -1151,14 +1158,19 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, update, 0); waitForIdle(); assertEquals(2, mNotificationRecordLogger.getCalls().size()); + assertTrue(mNotificationRecordLogger.get(0).shouldLog()); assertEquals( NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED, mNotificationRecordLogger.get(0).getUiEvent()); + assertEquals(0, mNotificationRecordLogger.get(0).r.sbn.getInstanceId().getId()); + + assertTrue(mNotificationRecordLogger.get(1).shouldLog()); assertEquals( NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_UPDATED, mNotificationRecordLogger.get(1).getUiEvent()); - assertTrue(mNotificationRecordLogger.get(1).shouldLog()); + // Instance ID doesn't change on update of an active notification + assertEquals(0, mNotificationRecordLogger.get(1).r.sbn.getInstanceId().getId()); } @Test @@ -1175,6 +1187,34 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } @Test + public void testEnqueueNotificationWithTag_LogsAgainAfterCancel() throws Exception { + final String tag = "testEnqueueNotificationWithTag_LogsAgainAfterCancel"; + Notification notification = new Notification.Builder(mContext, + mTestNotificationChannel.getId()) + .setSmallIcon(android.R.drawable.sym_def_app_icon).build(); + mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, notification, 0); + waitForIdle(); + mBinderService.cancelNotificationWithTag(PKG, PKG, tag, 0, 0); + waitForIdle(); + mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, notification, 0); + waitForIdle(); + assertEquals(2, mNotificationRecordLogger.getCalls().size()); + + assertTrue(mNotificationRecordLogger.get(0).shouldLog()); + assertEquals( + NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED, + mNotificationRecordLogger.get(0).getUiEvent()); + assertEquals(0, mNotificationRecordLogger.get(0).r.sbn.getInstanceId().getId()); + + assertTrue(mNotificationRecordLogger.get(1).shouldLog()); + assertEquals( + NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED, + mNotificationRecordLogger.get(1).getUiEvent()); + // New instance ID because notification was canceled before re-post + assertEquals(1, mNotificationRecordLogger.get(1).r.sbn.getInstanceId().getId()); + } + + @Test public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception { mBinderService.enqueueNotificationWithTag(PKG, PKG, "testCancelNotificationImmediatelyAfterEnqueue", 0, @@ -2309,7 +2349,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test public void testHasCompanionDevice_noService() { - mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger); + mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, + mNotificationInstanceIdSequence); assertFalse(mService.hasCompanionDevice(mListener)); } @@ -4679,8 +4720,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } // cross user, with permission, no problem - TestablePermissions perms = mContext.getTestablePermissions(); - perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED); + enableInteractAcrossUsers(); mBinderService.canNotifyAsPackage("src", "target", mContext.getUserId() + 1); } @@ -4698,8 +4738,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } // cross user, with permission, no problem - TestablePermissions perms = mContext.getTestablePermissions(); - perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED); + enableInteractAcrossUsers(); mBinderService.getNotificationChannels("src", "target", mContext.getUserId() + 1); } @@ -5317,8 +5356,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } // cross user, with permission, no problem - TestablePermissions perms = mContext.getTestablePermissions(); - perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED); + enableInteractAcrossUsers(); mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(), mUid + UserHandle.PER_USER_RANGE); } @@ -5334,12 +5372,16 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { } // cross user, with permission, no problem - TestablePermissions perms = mContext.getTestablePermissions(); - perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED); + enableInteractAcrossUsers(); mBinderService.areBubblesAllowedForPackage(mContext.getPackageName(), mUid + UserHandle.PER_USER_RANGE); } + private void enableInteractAcrossUsers() { + TestablePermissions perms = mContext.getTestablePermissions(); + perms.setPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, PERMISSION_GRANTED); + } + @Test public void testNotificationBubbleChanged_false() throws Exception { // Bubbles are allowed! diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java index 11972fd6a8dc..5c1487f0fdf6 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java @@ -23,7 +23,7 @@ import java.util.List; * Fake implementation of NotificationRecordLogger, for testing. */ class NotificationRecordLoggerFake implements NotificationRecordLogger { - class CallRecord extends NotificationRecordPair { + static class CallRecord extends NotificationRecordPair { public int position, buzzBeepBlink; CallRecord(NotificationRecord r, NotificationRecord old, int position, int buzzBeepBlink) { @@ -35,7 +35,7 @@ class NotificationRecordLoggerFake implements NotificationRecordLogger { return shouldLog(buzzBeepBlink); } } - List<CallRecord> mCalls = new ArrayList<CallRecord>(); + private List<CallRecord> mCalls = new ArrayList<CallRecord>(); List<CallRecord> getCalls() { return mCalls; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java index e18c8919b645..64a980484539 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java @@ -54,6 +54,8 @@ import android.util.ArraySet; import android.util.AtomicFile; import android.util.Pair; +import com.android.internal.logging.InstanceIdSequence; +import com.android.internal.logging.InstanceIdSequenceFake; import com.android.server.LocalServices; import com.android.server.UiServiceTestCase; import com.android.server.lights.LightsManager; @@ -92,12 +94,15 @@ public class RoleObserverTest extends UiServiceTestCase { @Mock private RoleManager mRoleManager; NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake(); - + private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake( + 1 << 30); private List<UserInfo> mUsers; private static class TestableNotificationManagerService extends NotificationManagerService { - TestableNotificationManagerService(Context context, NotificationRecordLogger logger) { - super(context, logger); + TestableNotificationManagerService(Context context, + NotificationRecordLogger logger, + InstanceIdSequence notificationInstanceIdSequence) { + super(context, logger, notificationInstanceIdSequence); } @Override @@ -120,7 +125,8 @@ public class RoleObserverTest extends UiServiceTestCase { mUsers.add(new UserInfo(10, "second", 0)); when(mUm.getUsers()).thenReturn(mUsers); - mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger); + mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger, + mNotificationInstanceIdSequence); mRoleObserver = mService.new RoleObserver(mRoleManager, mPm, mExecutor); try { |