summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifEvent.java153
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifLog.java117
2 files changed, 270 insertions, 0 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifEvent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifEvent.java
new file mode 100644
index 000000000000..2396d28bd46d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifEvent.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.logging;
+
+import android.annotation.IntDef;
+import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.StatusBarNotification;
+
+import com.android.systemui.log.RichEvent;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * An event related to notifications. {@link NotifLog} stores and prints these events for debugging
+ * and triaging purposes.
+ */
+public class NotifEvent extends RichEvent {
+ public static final int TOTAL_EVENT_TYPES = 8;
+ private StatusBarNotification mSbn;
+ private Ranking mRanking;
+
+ /**
+ * Creates a NotifEvent with an event type that matches with an index in the array
+ * getSupportedEvents() and {@link EventType}.
+ *
+ * The status bar notification and ranking objects are stored as shallow copies of the current
+ * state of the event when this event occurred.
+ */
+ public NotifEvent(int logLevel, int type, String reason, StatusBarNotification sbn,
+ Ranking ranking) {
+ super(logLevel, type, reason);
+ mSbn = sbn.clone();
+ mRanking = new Ranking();
+ mRanking.populate(ranking);
+ mMessage += getExtraInfo();
+ }
+
+ private String getExtraInfo() {
+ StringBuilder extraInfo = new StringBuilder();
+
+ if (mSbn != null) {
+ extraInfo.append(" Sbn=");
+ extraInfo.append(mSbn);
+ }
+
+ if (mRanking != null) {
+ extraInfo.append(" Ranking=");
+ extraInfo.append(mRanking);
+ }
+
+ return extraInfo.toString();
+ }
+
+ /**
+ * Event labels for NotifEvents
+ * Index corresponds to the {@link EventType}
+ */
+ @Override
+ public String[] getEventLabels() {
+ final String[] events = new String[]{
+ "NotifAdded",
+ "NotifRemoved",
+ "NotifUpdated",
+ "HeadsUpStarted",
+ "HeadsUpEnded",
+ "Filter",
+ "Sort",
+ "NotifVisibilityChanged",
+ };
+
+ if (events.length != TOTAL_EVENT_TYPES) {
+ throw new IllegalStateException("NotifEvents events.length should match "
+ + TOTAL_EVENT_TYPES
+ + " events.length=" + events.length
+ + " TOTAL_EVENT_LENGTH=" + TOTAL_EVENT_TYPES);
+ }
+ return events;
+ }
+
+ /**
+ * @return a copy of the status bar notification that changed with this event
+ */
+ public StatusBarNotification getSbn() {
+ return mSbn;
+ }
+
+ /**
+ * Builds a NotifEvent.
+ */
+ public static class NotifEventBuilder extends RichEvent.Builder<NotifEventBuilder> {
+ private StatusBarNotification mSbn;
+ private Ranking mRanking;
+
+ @Override
+ public NotifEventBuilder getBuilder() {
+ return this;
+ }
+
+ /**
+ * Stores the status bar notification object. A shallow copy is stored in the NotifEvent's
+ * constructor.
+ */
+ public NotifEventBuilder setSbn(StatusBarNotification sbn) {
+ mSbn = sbn;
+ return this;
+ }
+
+ /**
+ * Stores the ranking object. A shallow copy is stored in the NotifEvent's
+ * constructor.
+ */
+ public NotifEventBuilder setRanking(Ranking ranking) {
+ mRanking = ranking;
+ return this;
+ }
+
+ @Override
+ public RichEvent build() {
+ return new NotifEvent(mLogLevel, mType, mReason, mSbn, mRanking);
+ }
+ }
+
+ @IntDef({NOTIF_ADDED, NOTIF_REMOVED, NOTIF_UPDATED, HEADS_UP_STARTED, HEADS_UP_ENDED, FILTER,
+ SORT, NOTIF_VISIBILITY_CHANGED})
+ /**
+ * Types of NotifEvents
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface EventType {}
+ public static final int NOTIF_ADDED = 0;
+ public static final int NOTIF_REMOVED = 1;
+ public static final int NOTIF_UPDATED = 2;
+ public static final int HEADS_UP_STARTED = 3;
+ public static final int HEADS_UP_ENDED = 4;
+ public static final int FILTER = 5;
+ public static final int SORT = 6;
+ public static final int NOTIF_VISIBILITY_CHANGED = 7;
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifLog.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifLog.java
new file mode 100644
index 000000000000..d42cd82f9784
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotifLog.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.logging;
+
+import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.StatusBarNotification;
+
+import com.android.systemui.DumpController;
+import com.android.systemui.log.SysuiLog;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Logs systemui notification events for debugging and triaging purposes. Logs are dumped in
+ * bugreports or on demand:
+ * adb shell dumpsys activity service com.android.systemui/.SystemUIService \
+ * dependency DumpController NotifLog
+ */
+@Singleton
+public class NotifLog extends SysuiLog {
+ private static final String TAG = "NotifLog";
+ private static final int MAX_DOZE_DEBUG_LOGS = 400;
+ private static final int MAX_DOZE_LOGS = 50;
+
+ @Inject
+ public NotifLog(DumpController dumpController) {
+ super(dumpController, TAG, MAX_DOZE_DEBUG_LOGS, MAX_DOZE_LOGS);
+ }
+
+ /**
+ * Logs a {@link NotifEvent} with a notification, ranking and message
+ * @return true if successfully logged, else false
+ */
+ public boolean log(@NotifEvent.EventType int eventType, StatusBarNotification sbn,
+ Ranking ranking, String msg) {
+ return log(new NotifEvent.NotifEventBuilder()
+ .setType(eventType)
+ .setSbn(sbn)
+ .setRanking(ranking)
+ .setReason(msg)
+ .build());
+ }
+
+ /**
+ * Logs a {@link NotifEvent}
+ * @return true if successfully logged, else false
+ */
+ public boolean log(@NotifEvent.EventType int eventType) {
+ return log(eventType, null, null, null);
+ }
+
+ /**
+ * Logs a {@link NotifEvent} with a message
+ * @return true if successfully logged, else false
+ */
+ public boolean log(@NotifEvent.EventType int eventType, String msg) {
+ return log(eventType, null, null, msg);
+ }
+
+ /**
+ * Logs a {@link NotifEvent} with a notification
+ * @return true if successfully logged, else false
+ */
+ public boolean log(@NotifEvent.EventType int eventType, StatusBarNotification sbn) {
+ return log(eventType, sbn, null, "");
+ }
+
+ /**
+ * Logs a {@link NotifEvent} with a ranking
+ * @return true if successfully logged, else false
+ */
+ public boolean log(@NotifEvent.EventType int eventType, Ranking ranking) {
+ return log(eventType, null, ranking, "");
+ }
+
+ /**
+ * Logs a {@link NotifEvent} with a notification and ranking
+ * @return true if successfully logged, else false
+ */
+ public boolean log(@NotifEvent.EventType int eventType, StatusBarNotification sbn,
+ Ranking ranking) {
+ return log(eventType, sbn, ranking, "");
+ }
+
+ /**
+ * Logs a {@link NotifEvent} with a notification entry
+ * @return true if successfully logged, else false
+ */
+ public boolean log(@NotifEvent.EventType int eventType, NotificationEntry entry) {
+ return log(eventType, entry.sbn(), entry.ranking(), "");
+ }
+
+ /**
+ * Logs a {@link NotifEvent} with a notification entry
+ * @return true if successfully logged, else false
+ */
+ public boolean log(@NotifEvent.EventType int eventType, NotificationEntry entry,
+ String msg) {
+ return log(eventType, entry.sbn(), entry.ranking(), msg);
+ }
+}