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.NotificationSectionsManagerKt.BUCKET_ALERTING;
20 import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_FOREGROUND_SERVICE;
21 import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_HEADS_UP;
22 import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_MEDIA_CONTROLS;
23 import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_PEOPLE;
24 import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.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     enum NotificationPanelEvent implements UiEventLogger.UiEventEnum {
49         @UiEvent(doc = "Notification panel shown from status bar.")
50         NOTIFICATION_PANEL_OPEN_STATUS_BAR(200),
51         @UiEvent(doc = "Notification panel shown from lockscreen.")
52         NOTIFICATION_PANEL_OPEN_LOCKSCREEN(201);
53 
54         private final int mId;
NotificationPanelEvent(int id)55         NotificationPanelEvent(int id) {
56             mId = id;
57         }
getId()58         @Override public int getId() {
59             return mId;
60         }
61 
fromLockscreen(boolean isLockscreen)62         public static NotificationPanelEvent fromLockscreen(boolean isLockscreen) {
63             return isLockscreen ? NOTIFICATION_PANEL_OPEN_LOCKSCREEN :
64                     NOTIFICATION_PANEL_OPEN_STATUS_BAR;
65         }
66     }
67 
68     /**
69      * Composes a NotificationsList proto from the list of visible notifications.
70      * @param visibleNotifications as provided by NotificationEntryManager.getVisibleNotifications()
71      * @return NotificationList proto suitable for SysUiStatsLog.write(NOTIFICATION_PANEL_REPORTED)
72      */
toNotificationProto( @ullable List<NotificationEntry> visibleNotifications)73     static Notifications.NotificationList toNotificationProto(
74             @Nullable List<NotificationEntry> visibleNotifications) {
75         Notifications.NotificationList notificationList = new Notifications.NotificationList();
76         if (visibleNotifications == null) {
77             return notificationList;
78         }
79         final Notifications.Notification[] proto_array =
80                 new Notifications.Notification[visibleNotifications.size()];
81         int i = 0;
82         for (NotificationEntry ne : visibleNotifications) {
83             final StatusBarNotification n = ne.getSbn();
84             if (n != null) {
85                 final Notifications.Notification proto = new Notifications.Notification();
86                 proto.uid = n.getUid();
87                 proto.packageName = n.getPackageName();
88                 if (n.getInstanceId() != null) {
89                     proto.instanceId = n.getInstanceId().getId();
90                 }
91                 // TODO set np.groupInstanceId
92                 if (n.getNotification() != null) {
93                     proto.isGroupSummary = n.getNotification().isGroupSummary();
94                 }
95                 proto.section = toNotificationSection(ne.getBucket());
96                 proto_array[i] = proto;
97             }
98             ++i;
99         }
100         notificationList.notifications = proto_array;
101         return notificationList;
102     }
103 
104     /**
105      * Maps PriorityBucket enum to Notification.SECTION constant. The two lists should generally
106      * use matching names, but the values may differ, because PriorityBucket order changes from
107      * time to time, while logs need to have stable meanings.
108      * @param bucket PriorityBucket constant
109      * @return Notification.SECTION constant
110      */
toNotificationSection(@riorityBucket int bucket)111     static int toNotificationSection(@PriorityBucket int bucket) {
112         switch(bucket) {
113             case BUCKET_MEDIA_CONTROLS : return Notifications.Notification.SECTION_MEDIA_CONTROLS;
114             case BUCKET_HEADS_UP: return Notifications.Notification.SECTION_HEADS_UP;
115             case BUCKET_FOREGROUND_SERVICE:
116                 return Notifications.Notification.SECTION_FOREGROUND_SERVICE;
117             case BUCKET_PEOPLE: return Notifications.Notification.SECTION_PEOPLE;
118             case BUCKET_ALERTING: return Notifications.Notification.SECTION_ALERTING;
119             case BUCKET_SILENT: return Notifications.Notification.SECTION_SILENT;
120         }
121         return Notifications.Notification.SECTION_UNKNOWN;
122     }
123 
124 }
125