diff options
8 files changed, 258 insertions, 47 deletions
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index e053ed58a82b..0ff2e0386121 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -214,6 +214,32 @@ public abstract class NotificationListenerService extends Service { public static final int REASON_TIMEOUT = 19; /** + * @hide + */ + @IntDef(prefix = "REASON_", value = { + REASON_CLICK, + REASON_CANCEL, + REASON_CANCEL_ALL, + REASON_ERROR, + REASON_PACKAGE_CHANGED, + REASON_USER_STOPPED, + REASON_PACKAGE_BANNED, + REASON_APP_CANCEL, + REASON_APP_CANCEL_ALL, + REASON_LISTENER_CANCEL, + REASON_LISTENER_CANCEL_ALL, + REASON_GROUP_SUMMARY_CANCELED, + REASON_GROUP_OPTIMIZATION, + REASON_PACKAGE_SUSPENDED, + REASON_PROFILE_TURNED_OFF, + REASON_UNAUTOBUNDLED, + REASON_CHANNEL_BANNED, + REASON_SNOOZED, + REASON_TIMEOUT + }) + public @interface NotificationCancelReason{}; + + /** * The full trim of the StatusBarNotification including all its features. * * @hide diff --git a/core/java/com/android/internal/logging/UiEventLogger.java b/core/java/com/android/internal/logging/UiEventLogger.java index 48d2bc2ae58d..67ffd4d93404 100644 --- a/core/java/com/android/internal/logging/UiEventLogger.java +++ b/core/java/com/android/internal/logging/UiEventLogger.java @@ -56,8 +56,8 @@ public interface UiEventLogger { * @param event an enum implementing UiEventEnum interface. * @param uid the uid of the relevant app, if known (0 otherwise). * @param packageName the package name of the relevant app, if known (null otherwise). - * @param instance An identifier obtained from an InstanceIdSequence. + * @param instance An identifier obtained from an InstanceIdSequence. If null, reduces to log(). */ void logWithInstanceId(@NonNull UiEventEnum event, int uid, @Nullable String packageName, - @NonNull InstanceId instance); + @Nullable InstanceId instance); } diff --git a/core/java/com/android/internal/logging/UiEventLoggerImpl.java b/core/java/com/android/internal/logging/UiEventLoggerImpl.java index 785b2edf2e1b..4d171ec8a3a8 100644 --- a/core/java/com/android/internal/logging/UiEventLoggerImpl.java +++ b/core/java/com/android/internal/logging/UiEventLoggerImpl.java @@ -41,9 +41,11 @@ public class UiEventLoggerImpl implements UiEventLogger { public void logWithInstanceId(UiEventEnum event, int uid, String packageName, InstanceId instance) { final int eventID = event.getId(); - if (eventID > 0) { + if ((eventID > 0) && (instance != null)) { FrameworkStatsLog.write(FrameworkStatsLog.UI_EVENT_REPORTED, eventID, uid, packageName, instance.getId()); + } else { + log(event, uid, packageName); } } } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index b52289e36b50..cadfea7e12aa 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -7428,13 +7428,15 @@ public class NotificationManagerService extends SystemService { } @GuardedBy("mNotificationLock") - private void cancelNotificationLocked(NotificationRecord r, boolean sendDelete, int reason, + private void cancelNotificationLocked(NotificationRecord r, boolean sendDelete, + @NotificationListenerService.NotificationCancelReason int reason, boolean wasPosted, String listenerName) { cancelNotificationLocked(r, sendDelete, reason, -1, -1, wasPosted, listenerName); } @GuardedBy("mNotificationLock") - private void cancelNotificationLocked(NotificationRecord r, boolean sendDelete, int reason, + private void cancelNotificationLocked(NotificationRecord r, boolean sendDelete, + @NotificationListenerService.NotificationCancelReason int reason, int rank, int count, boolean wasPosted, String listenerName) { final String canceledKey = r.getKey(); @@ -7552,6 +7554,10 @@ public class NotificationManagerService extends SystemService { EventLogTags.writeNotificationCanceled(canceledKey, reason, r.getLifespanMs(now), r.getFreshnessMs(now), r.getExposureMs(now), rank, count, listenerName); + if (wasPosted) { + mNotificationRecordLogger.logNotificationCancelled(r, reason, + r.getStats().getDismissalSurface()); + } } @VisibleForTesting diff --git a/services/core/java/com/android/server/notification/NotificationRecordLogger.java b/services/core/java/com/android/server/notification/NotificationRecordLogger.java index 8d8511f030f0..fc2d9e775149 100644 --- a/services/core/java/com/android/server/notification/NotificationRecordLogger.java +++ b/services/core/java/com/android/server/notification/NotificationRecordLogger.java @@ -16,10 +16,16 @@ package com.android.server.notification; +import static android.service.notification.NotificationListenerService.REASON_CANCEL; +import static android.service.notification.NotificationListenerService.REASON_CLICK; +import static android.service.notification.NotificationListenerService.REASON_TIMEOUT; + import android.annotation.Nullable; import android.app.Notification; import android.app.Person; import android.os.Bundle; +import android.service.notification.NotificationListenerService; +import android.service.notification.NotificationStats; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; @@ -44,22 +50,144 @@ public interface NotificationRecordLogger { int position, int buzzBeepBlink); /** + * Logs a notification cancel / dismiss event using UiEventReported (event ids from the + * NotificationCancelledEvents enum). + * @param r The NotificationRecord. If null, no action is taken. + * @param reason The reason the notification was canceled. + * @param dismissalSurface The surface the notification was dismissed from. + */ + void logNotificationCancelled(@Nullable NotificationRecord r, + @NotificationListenerService.NotificationCancelReason int reason, + @NotificationStats.DismissalSurface int dismissalSurface); + + /** * The UiEvent enums that this class can log. */ - enum NotificationReportedEvents implements UiEventLogger.UiEventEnum { - INVALID(0), + enum NotificationReportedEvent implements UiEventLogger.UiEventEnum { @UiEvent(doc = "New notification enqueued to post") NOTIFICATION_POSTED(162), - @UiEvent(doc = "Notification substantially updated") + @UiEvent(doc = "Notification substantially updated, or alerted again.") NOTIFICATION_UPDATED(163); private final int mId; - NotificationReportedEvents(int id) { + NotificationReportedEvent(int id) { + mId = id; + } + @Override public int getId() { + return mId; + } + + public static NotificationReportedEvent fromRecordPair(NotificationRecordPair p) { + return (p.old != null) ? NotificationReportedEvent.NOTIFICATION_UPDATED : + NotificationReportedEvent.NOTIFICATION_POSTED; + } + } + + enum NotificationCancelledEvent implements UiEventLogger.UiEventEnum { + INVALID(0), + @UiEvent(doc = "Notification was canceled due to a notification click.") + NOTIFICATION_CANCEL_CLICK(164), + @UiEvent(doc = "Notification was canceled due to a user dismissal, surface not specified.") + NOTIFICATION_CANCEL_USER_OTHER(165), + @UiEvent(doc = "Notification was canceled due to a user dismiss-all (from the notification" + + " shade).") + NOTIFICATION_CANCEL_USER_CANCEL_ALL(166), + @UiEvent(doc = "Notification was canceled due to an inflation error.") + NOTIFICATION_CANCEL_ERROR(167), + @UiEvent(doc = "Notification was canceled by the package manager modifying the package.") + NOTIFICATION_CANCEL_PACKAGE_CHANGED(168), + @UiEvent(doc = "Notification was canceled by the owning user context being stopped.") + NOTIFICATION_CANCEL_USER_STOPPED(169), + @UiEvent(doc = "Notification was canceled by the user banning the package.") + NOTIFICATION_CANCEL_PACKAGE_BANNED(170), + @UiEvent(doc = "Notification was canceled by the app canceling this specific notification.") + NOTIFICATION_CANCEL_APP_CANCEL(171), + @UiEvent(doc = "Notification was canceled by the app cancelling all its notifications.") + NOTIFICATION_CANCEL_APP_CANCEL_ALL(172), + @UiEvent(doc = "Notification was canceled by a listener reporting a user dismissal.") + NOTIFICATION_CANCEL_LISTENER_CANCEL(173), + @UiEvent(doc = "Notification was canceled by a listener reporting a user dismiss all.") + NOTIFICATION_CANCEL_LISTENER_CANCEL_ALL(174), + @UiEvent(doc = "Notification was canceled because it was a member of a canceled group.") + NOTIFICATION_CANCEL_GROUP_SUMMARY_CANCELED(175), + @UiEvent(doc = "Notification was canceled because it was an invisible member of a group.") + NOTIFICATION_CANCEL_GROUP_OPTIMIZATION(176), + @UiEvent(doc = "Notification was canceled by the device administrator suspending the " + + "package.") + NOTIFICATION_CANCEL_PACKAGE_SUSPENDED(177), + @UiEvent(doc = "Notification was canceled by the owning managed profile being turned off.") + NOTIFICATION_CANCEL_PROFILE_TURNED_OFF(178), + @UiEvent(doc = "Autobundled summary notification was canceled because its group was " + + "unbundled") + NOTIFICATION_CANCEL_UNAUTOBUNDLED(179), + @UiEvent(doc = "Notification was canceled by the user banning the channel.") + NOTIFICATION_CANCEL_CHANNEL_BANNED(180), + @UiEvent(doc = "Notification was snoozed.") + NOTIFICATION_CANCEL_SNOOZED(181), + @UiEvent(doc = "Notification was canceled due to timeout") + NOTIFICATION_CANCEL_TIMEOUT(182), + // Values 183-189 reserved for future system dismissal reasons + @UiEvent(doc = "Notification was canceled due to user dismissal of a peeking notification.") + NOTIFICATION_CANCEL_USER_PEEK(190), + @UiEvent(doc = "Notification was canceled due to user dismissal from the always-on display") + NOTIFICATION_CANCEL_USER_AOD(191), + @UiEvent(doc = "Notification was canceled due to user dismissal from the notification" + + " shade.") + NOTIFICATION_CANCEL_USER_SHADE(192), + @UiEvent(doc = "Notification was canceled due to user dismissal from the lockscreen") + NOTIFICATION_CANCEL_USER_LOCKSCREEN(193); + + private final int mId; + NotificationCancelledEvent(int id) { mId = id; } @Override public int getId() { return mId; } + public static NotificationCancelledEvent fromCancelReason( + @NotificationListenerService.NotificationCancelReason int reason, + @NotificationStats.DismissalSurface int surface) { + // Shouldn't be possible to get a non-dismissed notification here. + if (surface == NotificationStats.DISMISSAL_NOT_DISMISSED) { + if (NotificationManagerService.DBG) { + throw new IllegalArgumentException("Unexpected surface " + surface); + } + return INVALID; + } + // Most cancel reasons do not have a meaningful surface. Reason codes map directly + // to NotificationCancelledEvent codes. + if (surface == NotificationStats.DISMISSAL_OTHER) { + if ((REASON_CLICK <= reason) && (reason <= REASON_TIMEOUT)) { + return NotificationCancelledEvent.values()[reason]; + } + if (NotificationManagerService.DBG) { + throw new IllegalArgumentException("Unexpected cancel reason " + reason); + } + return INVALID; + } + // User cancels have a meaningful surface, which we differentiate by. See b/149038335 + // for caveats. + if (reason != REASON_CANCEL) { + if (NotificationManagerService.DBG) { + throw new IllegalArgumentException("Unexpected cancel with surface " + reason); + } + return INVALID; + } + switch (surface) { + case NotificationStats.DISMISSAL_PEEK: + return NOTIFICATION_CANCEL_USER_PEEK; + case NotificationStats.DISMISSAL_AOD: + return NOTIFICATION_CANCEL_USER_AOD; + case NotificationStats.DISMISSAL_SHADE: + return NOTIFICATION_CANCEL_USER_SHADE; + default: + if (NotificationManagerService.DBG) { + throw new IllegalArgumentException("Unexpected surface for user-dismiss " + + reason); + } + return INVALID; + } + } } /** @@ -88,7 +216,8 @@ public interface NotificationRecordLogger { return true; } - return !(Objects.equals(r.getSbn().getChannelIdLogTag(), old.getSbn().getChannelIdLogTag()) + return !(Objects.equals(r.getSbn().getChannelIdLogTag(), + old.getSbn().getChannelIdLogTag()) && Objects.equals(r.getSbn().getGroupLogTag(), old.getSbn().getGroupLogTag()) && (r.getSbn().getNotification().isGroupSummary() == old.getSbn().getNotification().isGroupSummary()) @@ -97,11 +226,6 @@ public interface NotificationRecordLogger { && (r.getImportance() == old.getImportance())); } - NotificationReportedEvents getUiEvent() { - return (old != null) ? NotificationReportedEvents.NOTIFICATION_UPDATED : - NotificationReportedEvents.NOTIFICATION_POSTED; - } - /** * @return hash code for the notification style class, or 0 if none exists. */ diff --git a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java index 4974c3001b9b..015d280535e6 100644 --- a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java +++ b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java @@ -16,6 +16,8 @@ package com.android.server.notification; +import com.android.internal.logging.UiEventLogger; +import com.android.internal.logging.UiEventLoggerImpl; import com.android.internal.util.FrameworkStatsLog; /** @@ -24,6 +26,8 @@ import com.android.internal.util.FrameworkStatsLog; */ public class NotificationRecordLoggerImpl implements NotificationRecordLogger { + UiEventLogger mUiEventLogger = new UiEventLoggerImpl(); + @Override public void logNotificationReported(NotificationRecord r, NotificationRecord old, int position, int buzzBeepBlink) { @@ -32,7 +36,7 @@ public class NotificationRecordLoggerImpl implements NotificationRecordLogger { return; } FrameworkStatsLog.write(FrameworkStatsLog.NOTIFICATION_REPORTED, - /* int32 event_id = 1 */ p.getUiEvent().getId(), + /* int32 event_id = 1 */ NotificationReportedEvent.fromRecordPair(p).getId(), /* int32 uid = 2 */ r.getUid(), /* string package_name = 3 */ r.getSbn().getPackageName(), /* int32 instance_id = 4 */ p.getInstanceId(), @@ -61,9 +65,10 @@ public class NotificationRecordLoggerImpl implements NotificationRecordLogger { ); } - - - - - + @Override + public void logNotificationCancelled(NotificationRecord r, int reason, int dismissalSurface) { + mUiEventLogger.logWithInstanceId( + NotificationCancelledEvent.fromCancelReason(reason, dismissalSurface), + r.getUid(), r.getSbn().getPackageName(), r.getSbn().getInstanceId()); + } } 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 e0ee3ce3aa57..990222e0ffa9 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -32,7 +32,6 @@ import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS; import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS; -import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT; @@ -50,6 +49,8 @@ import static android.os.Build.VERSION_CODES.P; import static android.os.UserHandle.USER_SYSTEM; import static android.service.notification.Adjustment.KEY_IMPORTANCE; import static android.service.notification.Adjustment.KEY_USER_SENTIMENT; +import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL; +import static android.service.notification.NotificationListenerService.REASON_CANCEL; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL; @@ -1144,7 +1145,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { waitForIdle(); assertEquals(1, mNotificationRecordLogger.getCalls().size()); NotificationRecordLoggerFake.CallRecord call = mNotificationRecordLogger.get(0); - assertTrue(call.shouldLog()); + assertTrue(call.shouldLog); + assertEquals(NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED, + call.event); assertNotNull(call.r); assertNull(call.old); assertEquals(0, call.position); @@ -1153,7 +1156,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals(0, call.r.getSbn().getId()); assertEquals(tag, call.r.getSbn().getTag()); assertNotNull(call.r.getSbn().getInstanceId()); - assertEquals(0, call.r.getSbn().getInstanceId().getId()); + assertEquals(0, call.getInstanceId()); // Fake instance IDs are assigned in order } @Test @@ -1171,18 +1174,18 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { waitForIdle(); assertEquals(2, mNotificationRecordLogger.getCalls().size()); - assertTrue(mNotificationRecordLogger.get(0).shouldLog()); + assertTrue(mNotificationRecordLogger.get(0).shouldLog); assertEquals( - NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED, - mNotificationRecordLogger.get(0).getUiEvent()); - assertEquals(0, mNotificationRecordLogger.get(0).r.getSbn().getInstanceId().getId()); + NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED, + mNotificationRecordLogger.get(0).event); + assertEquals(0, mNotificationRecordLogger.get(0).getInstanceId()); - assertTrue(mNotificationRecordLogger.get(1).shouldLog()); + assertTrue(mNotificationRecordLogger.get(1).shouldLog); assertEquals( - NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_UPDATED, - mNotificationRecordLogger.get(1).getUiEvent()); + NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_UPDATED, + mNotificationRecordLogger.get(1).event); // Instance ID doesn't change on update of an active notification - assertEquals(0, mNotificationRecordLogger.get(1).r.getSbn().getInstanceId().getId()); + assertEquals(0, mNotificationRecordLogger.get(1).getInstanceId()); } @Test @@ -1194,8 +1197,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { generateNotificationRecord(null).getNotification(), 0); waitForIdle(); assertEquals(2, mNotificationRecordLogger.getCalls().size()); - assertTrue(mNotificationRecordLogger.get(0).shouldLog()); - assertFalse(mNotificationRecordLogger.get(1).shouldLog()); + assertTrue(mNotificationRecordLogger.get(0).shouldLog); + assertFalse(mNotificationRecordLogger.get(1).shouldLog); } @Test @@ -1210,20 +1213,37 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { waitForIdle(); mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, notification, 0); waitForIdle(); - assertEquals(2, mNotificationRecordLogger.getCalls().size()); + assertEquals(3, mNotificationRecordLogger.getCalls().size()); + + assertEquals( + NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED, + mNotificationRecordLogger.get(0).event); + assertTrue(mNotificationRecordLogger.get(0).shouldLog); + assertEquals(0, mNotificationRecordLogger.get(0).getInstanceId()); - assertTrue(mNotificationRecordLogger.get(0).shouldLog()); + assertEquals(REASON_APP_CANCEL, mNotificationRecordLogger.get(1).reason); assertEquals( - NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED, - mNotificationRecordLogger.get(0).getUiEvent()); - assertEquals(0, mNotificationRecordLogger.get(0).r.getSbn().getInstanceId().getId()); + NotificationRecordLogger.NotificationCancelledEvent.NOTIFICATION_CANCEL_APP_CANCEL, + mNotificationRecordLogger.get(1).event); + assertTrue(mNotificationRecordLogger.get(1).shouldLog); + assertEquals(0, mNotificationRecordLogger.get(1).getInstanceId()); - assertTrue(mNotificationRecordLogger.get(1).shouldLog()); assertEquals( - NotificationRecordLogger.NotificationReportedEvents.NOTIFICATION_POSTED, - mNotificationRecordLogger.get(1).getUiEvent()); + NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED, + mNotificationRecordLogger.get(2).event); + assertTrue(mNotificationRecordLogger.get(2).shouldLog); // New instance ID because notification was canceled before re-post - assertEquals(1, mNotificationRecordLogger.get(1).r.getSbn().getInstanceId().getId()); + assertEquals(1, mNotificationRecordLogger.get(2).getInstanceId()); + } + + @Test + public void testCancelNonexistentNotification() throws Exception { + mBinderService.cancelNotificationWithTag(PKG, PKG, + "testCancelNonexistentNotification", 0, 0); + waitForIdle(); + // The notification record logger doesn't even get called when a nonexistent notification + // is cancelled, because that happens very frequently and is not interesting. + assertEquals(0, mNotificationRecordLogger.getCalls().size()); } @Test @@ -3365,6 +3385,17 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { waitForIdle(); assertEquals(NotificationStats.DISMISSAL_AOD, r.getStats().getDismissalSurface()); + + // Using mService.addNotification() does not generate a NotificationRecordLogger log, + // so we only get the cancel notification. + assertEquals(1, mNotificationRecordLogger.getCalls().size()); + + assertEquals(REASON_CANCEL, mNotificationRecordLogger.get(0).reason); + assertEquals( + NotificationRecordLogger.NotificationCancelledEvent.NOTIFICATION_CANCEL_USER_AOD, + mNotificationRecordLogger.get(0).event); + assertTrue(mNotificationRecordLogger.get(0).shouldLog); + assertEquals(0, mNotificationRecordLogger.get(0).getInstanceId()); } @Test 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 5c1487f0fdf6..b120dbee03c5 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordLoggerFake.java @@ -16,6 +16,8 @@ package com.android.server.notification; +import com.android.internal.logging.UiEventLogger; + import java.util.ArrayList; import java.util.List; @@ -24,18 +26,27 @@ import java.util.List; */ class NotificationRecordLoggerFake implements NotificationRecordLogger { static class CallRecord extends NotificationRecordPair { - public int position, buzzBeepBlink; + static final int INVALID = -1; + public int position = INVALID, buzzBeepBlink = INVALID, reason = INVALID; + public boolean shouldLog; + public UiEventLogger.UiEventEnum event; CallRecord(NotificationRecord r, NotificationRecord old, int position, int buzzBeepBlink) { super(r, old); + this.position = position; this.buzzBeepBlink = buzzBeepBlink; + shouldLog = shouldLog(buzzBeepBlink); + event = NotificationReportedEvent.fromRecordPair(this); } - boolean shouldLog() { - return shouldLog(buzzBeepBlink); + CallRecord(NotificationRecord r, int reason, int dismissalSurface) { + super(r, null); + this.reason = reason; + shouldLog = true; + event = NotificationCancelledEvent.fromCancelReason(reason, dismissalSurface); } } - private List<CallRecord> mCalls = new ArrayList<CallRecord>(); + private List<CallRecord> mCalls = new ArrayList<>(); List<CallRecord> getCalls() { return mCalls; @@ -50,4 +61,10 @@ class NotificationRecordLoggerFake implements NotificationRecordLogger { int position, int buzzBeepBlink) { mCalls.add(new CallRecord(r, old, position, buzzBeepBlink)); } + + @Override + public void logNotificationCancelled(NotificationRecord r, int reason, int dismissalSurface) { + mCalls.add(new CallRecord(r, reason, dismissalSurface)); + } + } |