diff --git a/core/proto/android/service/notification.proto b/core/proto/android/service/notification.proto index bc257e04440d4..819460e089574 100644 --- a/core/proto/android/service/notification.proto +++ b/core/proto/android/service/notification.proto @@ -23,6 +23,8 @@ option java_outer_classname = "NotificationServiceProto"; message NotificationServiceDumpProto { repeated NotificationRecordProto records = 1; + + ZenModeProto zen = 2; } message NotificationRecordProto { @@ -42,4 +44,21 @@ enum State { ENQUEUED = 0; POSTED = 1; + + SNOOZED = 2; +} + +message ZenModeProto { + ZenMode zen_mode = 1; + repeated string enabled_active_conditions = 2; + int32 suppressed_effects = 3; + repeated string suppressors = 4; + string policy = 5; +} + +enum ZenMode { + ZEN_MODE_OFF = 0; + ZEN_MODE_IMPORTANT_INTERRUPTIONS = 1; + ZEN_MODE_NO_INTERRUPTIONS = 2; + ZEN_MODE_ALARMS = 3; } \ No newline at end of file diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 653e80af83b2f..245bf9ed31be1 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -41,6 +41,9 @@ message MetricsEvent { // The view or control was dismissed. TYPE_DISMISS = 5; + + // The view or control was updated. + TYPE_UPDATE = 6; } // Known visual elements: views or controls. @@ -3397,6 +3400,16 @@ message MetricsEvent { // ACTION: A tile in Settings information architecture is clicked ACTION_SETTINGS_TILE_CLICK = 830; + // OPEN: Notification unsnoozed. CLOSE: Notification snoozed. UPDATE: snoozed notification + // updated + // CATEGORY: NOTIFICATION + // OS: O + NOTIFICATION_SNOOZED = 831; + + // Tagged data for NOTIFICATION_SNOOZED. TRUE: snoozed until context, FALSE: snoozed for time. + // OS: O + NOTIFICATION_SNOOZED_CRITERIA = 832; + // ---- End O Constants, all O constants go above this line ---- // Add new aosp constants above this line. diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 771ae9a2a7435..67acdafb74f86 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -121,6 +121,7 @@ import android.service.notification.NotificationServiceProto; import android.service.notification.SnoozeCriterion; import android.service.notification.StatusBarNotification; import android.service.notification.ZenModeConfig; +import android.service.notification.ZenModeProto; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.text.TextUtils; @@ -140,6 +141,7 @@ import android.widget.Toast; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.util.FastXmlSerializer; @@ -2812,8 +2814,26 @@ public class NotificationManagerService extends SystemService { proto.write(NotificationRecordProto.STATE, NotificationServiceProto.ENQUEUED); } } + List snoozed = mSnoozeHelper.getSnoozed(); + N = snoozed.size(); + if (N > 0) { + for (int i = 0; i < N; i++) { + final NotificationRecord nr = snoozed.get(i); + if (filter.filtered && !filter.matches(nr.sbn)) continue; + nr.dump(proto, filter.redact); + proto.write(NotificationRecordProto.STATE, NotificationServiceProto.SNOOZED); + } + } proto.end(records); } + + long zenLog = proto.start(NotificationServiceDumpProto.ZEN); + mZenModeHelper.dump(proto); + for (ComponentName suppressor : mEffectsSuppressors) { + proto.write(ZenModeProto.SUPPRESSORS, suppressor.toString()); + } + proto.end(zenLog); + proto.flush(); } @@ -2899,23 +2919,11 @@ public class NotificationManagerService extends SystemService { } pw.println(" "); } + + mSnoozeHelper.dump(pw, filter); } } - if (!zenOnly) { - pw.println("\n Usage Stats:"); - mUsageStats.dump(pw, " ", filter); - } - - if (!filter.filtered || zenOnly) { - pw.println("\n Zen Mode:"); - pw.print(" mInterruptionFilter="); pw.println(mInterruptionFilter); - mZenModeHelper.dump(pw, " "); - - pw.println("\n Zen Log:"); - ZenLog.dump(pw, " "); - } - if (!zenOnly) { pw.println("\n Ranking Config:"); mRankingHelper.dump(pw, " ", filter); @@ -2945,8 +2953,13 @@ public class NotificationManagerService extends SystemService { mNotificationAssistants.dump(pw, filter); } - if (!zenOnly) { - mSnoozeHelper.dump(pw, filter); + if (!filter.filtered || zenOnly) { + pw.println("\n Zen Mode:"); + pw.print(" mInterruptionFilter="); pw.println(mInterruptionFilter); + mZenModeHelper.dump(pw, " "); + + pw.println("\n Zen Log:"); + ZenLog.dump(pw, " "); } pw.println("\n Policy access:"); @@ -2964,6 +2977,11 @@ public class NotificationManagerService extends SystemService { r.dump(pw, " ", getContext(), filter.redact); } } + + if (!zenOnly) { + pw.println("\n Usage Stats:"); + mUsageStats.dump(pw, " ", filter); + } } } @@ -3131,7 +3149,9 @@ public class NotificationManagerService extends SystemService { // snoozed apps if (mSnoozeHelper.isSnoozed(userId, pkg, r.getKey())) { - // TODO: log to event log + MetricsLogger.action(r.getLogMaker() + .setType(MetricsProto.MetricsEvent.TYPE_UPDATE) + .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED)); if (DBG) { Slog.d(TAG, "Ignored enqueue for snoozed notification " + r.getKey()); } @@ -4155,7 +4175,7 @@ public class NotificationManagerService extends SystemService { if (until < System.currentTimeMillis() && snoozeCriterionId == null) { return; } - // TODO: write to event log + if (DBG) { Slog.d(TAG, String.format("snooze event(%s, %d, %s, %s)", key, until, snoozeCriterionId, listenerName)); @@ -4167,6 +4187,11 @@ public class NotificationManagerService extends SystemService { synchronized (mNotificationLock) { final NotificationRecord r = findNotificationByKeyLocked(key); if (r != null) { + MetricsLogger.action(r.getLogMaker() + .setCategory(MetricsEvent.NOTIFICATION_SNOOZED) + .setType(MetricsEvent.TYPE_CLOSE) + .addTaggedData(MetricsEvent.NOTIFICATION_SNOOZED_CRITERIA, + snoozeCriterionId == null ? false : true)); cancelNotificationLocked(r, false, REASON_SNOOZED); updateLightsLocked(); if (snoozeCriterionId != null) { @@ -4185,7 +4210,6 @@ public class NotificationManagerService extends SystemService { void unsnoozeNotificationInt(String key, ManagedServiceInfo listener) { String listenerName = listener == null ? null : listener.component.toShortString(); - // TODO: write to event log if (DBG) { Slog.d(TAG, String.format("unsnooze event(%s, %s)", key, listenerName)); } diff --git a/services/core/java/com/android/server/notification/SnoozeHelper.java b/services/core/java/com/android/server/notification/SnoozeHelper.java index f2aff1102b0bb..0cd8cea881ab7 100644 --- a/services/core/java/com/android/server/notification/SnoozeHelper.java +++ b/services/core/java/com/android/server/notification/SnoozeHelper.java @@ -16,11 +16,14 @@ package com.android.server.notification; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.nano.MetricsProto; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import android.annotation.NonNull; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; @@ -99,7 +102,7 @@ public class SnoozeHelper { return Collections.EMPTY_LIST; } - protected List getSnoozed() { + protected @NonNull List getSnoozed() { List snoozedForUser = new ArrayList<>(); int[] userIds = mUserProfiles.getCurrentProfileIds(); final int N = userIds.length; @@ -270,6 +273,9 @@ public class SnoozeHelper { final NotificationRecord record = pkgRecords.remove(key); if (record != null) { + MetricsLogger.action(record.getLogMaker() + .setCategory(MetricsProto.MetricsEvent.NOTIFICATION_SNOOZED) + .setType(MetricsProto.MetricsEvent.TYPE_OPEN)); mCallback.repost(userId, record); } } diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 66fb9766749a3..75190f3e3e898 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -50,14 +50,18 @@ import android.os.Process; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings.Global; +import android.service.notification.Condition; import android.service.notification.ConditionProviderService; +import android.service.notification.NotificationServiceDumpProto; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.EventInfo; import android.service.notification.ZenModeConfig.ScheduleInfo; import android.service.notification.ZenModeConfig.ZenRule; +import android.service.notification.ZenModeProto; import android.util.AndroidRuntimeException; import android.util.Log; import android.util.SparseArray; +import android.util.proto.ProtoOutputStream; import com.android.internal.R; import com.android.internal.logging.MetricsLogger; @@ -488,6 +492,24 @@ public class ZenModeHelper { } } + void dump(ProtoOutputStream proto) { + + proto.write(ZenModeProto.ZEN_MODE, mZenMode); + synchronized (mConfig) { + if (mConfig.manualRule != null) { + proto.write(ZenModeProto.ENABLED_ACTIVE_CONDITIONS, mConfig.manualRule.toString()); + } + for (ZenRule rule : mConfig.automaticRules.values()) { + if (rule.enabled && rule.condition.state == Condition.STATE_TRUE + && !rule.snoozing) { + proto.write(ZenModeProto.ENABLED_ACTIVE_CONDITIONS, rule.toString()); + } + } + proto.write(ZenModeProto.POLICY, mConfig.toNotificationPolicy().toString()); + proto.write(ZenModeProto.SUPPRESSED_EFFECTS, mSuppressedEffects); + } + } + public void dump(PrintWriter pw, String prefix) { pw.print(prefix); pw.print("mZenMode="); pw.println(Global.zenModeToString(mZenMode));