1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.statusbar.notification.logging;
18 
19 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_ALERTING;
20 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_FOREGROUND_SERVICE;
21 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_HEADS_UP;
22 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_MEDIA_CONTROLS;
23 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_PEOPLE;
24 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT;
25 
26 import android.annotation.Nullable;
27 import android.service.notification.StatusBarNotification;
28 
29 import com.android.internal.logging.UiEvent;
30 import com.android.internal.logging.UiEventLogger;
31 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
32 import com.android.systemui.statusbar.notification.logging.nano.Notifications;
33 import com.android.systemui.statusbar.notification.stack.PriorityBucket;
34 
35 import java.util.List;
36 /**
37  * Statsd logging for notification panel.
38  */
39 public interface NotificationPanelLogger {
40 
41     /**
42      * Log a NOTIFICATION_PANEL_REPORTED statsd event.
43      * @param visibleNotifications as provided by NotificationEntryManager.getVisibleNotifications()
44      */
logPanelShown(boolean isLockscreen, @Nullable List<NotificationEntry> visibleNotifications)45     void logPanelShown(boolean isLockscreen,
46             @Nullable List<NotificationEntry> visibleNotifications);
47 
48     /**
49      * Log a NOTIFICATION_PANEL_REPORTED statsd event, with
50      * {@link NotificationPanelEvent#NOTIFICATION_DRAG} as the eventID.
51      *
52      * @param draggedNotification the notification that is being dragged
53      */
logNotificationDrag(NotificationEntry draggedNotification)54     void logNotificationDrag(NotificationEntry draggedNotification);
55 
56     enum NotificationPanelEvent implements UiEventLogger.UiEventEnum {
57         @UiEvent(doc = "Notification panel shown from status bar.")
58         NOTIFICATION_PANEL_OPEN_STATUS_BAR(200),
59         @UiEvent(doc = "Notification panel shown from lockscreen.")
60         NOTIFICATION_PANEL_OPEN_LOCKSCREEN(201),
61         @UiEvent(doc = "Notification was dragged")
62         NOTIFICATION_DRAG(1226);
63 
64         private final int mId;
NotificationPanelEvent(int id)65         NotificationPanelEvent(int id) {
66             mId = id;
67         }
getId()68         @Override public int getId() {
69             return mId;
70         }
71 
fromLockscreen(boolean isLockscreen)72         public static NotificationPanelEvent fromLockscreen(boolean isLockscreen) {
73             return isLockscreen ? NOTIFICATION_PANEL_OPEN_LOCKSCREEN :
74                     NOTIFICATION_PANEL_OPEN_STATUS_BAR;
75         }
76     }
77 
78     /**
79      * Composes a NotificationsList proto from the list of visible notifications.
80      * @param visibleNotifications as provided by NotificationEntryManager.getVisibleNotifications()
81      * @return NotificationList proto suitable for SysUiStatsLog.write(NOTIFICATION_PANEL_REPORTED)
82      */
toNotificationProto( @ullable List<NotificationEntry> visibleNotifications)83     static Notifications.NotificationList toNotificationProto(
84             @Nullable List<NotificationEntry> visibleNotifications) {
85         Notifications.NotificationList notificationList = new Notifications.NotificationList();
86         if (visibleNotifications == null) {
87             return notificationList;
88         }
89         final Notifications.Notification[] proto_array =
90                 new Notifications.Notification[visibleNotifications.size()];
91         int i = 0;
92         for (NotificationEntry ne : visibleNotifications) {
93             final StatusBarNotification n = ne.getSbn();
94             if (n != null) {
95                 final Notifications.Notification proto = new Notifications.Notification();
96                 proto.uid = n.getUid();
97                 proto.packageName = n.getPackageName();
98                 if (n.getInstanceId() != null) {
99                     proto.instanceId = n.getInstanceId().getId();
100                 }
101                 // TODO set np.groupInstanceId
102                 if (n.getNotification() != null) {
103                     proto.isGroupSummary = n.getNotification().isGroupSummary();
104                 }
105                 proto.section = toNotificationSection(ne.getBucket());
106                 proto_array[i] = proto;
107             }
108             ++i;
109         }
110         notificationList.notifications = proto_array;
111         return notificationList;
112     }
113 
114     /**
115      * Maps PriorityBucket enum to Notification.SECTION constant. The two lists should generally
116      * use matching names, but the values may differ, because PriorityBucket order changes from
117      * time to time, while logs need to have stable meanings.
118      * @param bucket PriorityBucket constant
119      * @return Notification.SECTION constant
120      */
toNotificationSection(@riorityBucket int bucket)121     static int toNotificationSection(@PriorityBucket int bucket) {
122         switch(bucket) {
123             case BUCKET_MEDIA_CONTROLS : return Notifications.Notification.SECTION_MEDIA_CONTROLS;
124             case BUCKET_HEADS_UP: return Notifications.Notification.SECTION_HEADS_UP;
125             case BUCKET_FOREGROUND_SERVICE:
126                 return Notifications.Notification.SECTION_FOREGROUND_SERVICE;
127             case BUCKET_PEOPLE: return Notifications.Notification.SECTION_PEOPLE;
128             case BUCKET_ALERTING: return Notifications.Notification.SECTION_ALERTING;
129             case BUCKET_SILENT: return Notifications.Notification.SECTION_SILENT;
130         }
131         return Notifications.Notification.SECTION_UNKNOWN;
132     }
133 
134 }
135