diff options
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); + } +} |