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.internal.app;
18 
19 import android.content.Intent;
20 import android.provider.MediaStore;
21 
22 import com.android.internal.logging.InstanceId;
23 import com.android.internal.logging.UiEvent;
24 import com.android.internal.logging.UiEventLogger;
25 import com.android.internal.util.FrameworkStatsLog;
26 
27 /**
28  * Interface for writing Sharesheet atoms to statsd log.
29  * @hide
30  */
31 public interface ChooserActivityLogger {
32     /** Logs a UiEventReported event for the system sharesheet completing initial start-up. */
logShareStarted(int eventId, String packageName, String mimeType, int appProvidedDirect, int appProvidedApp, boolean isWorkprofile, int previewType, String intent)33     void logShareStarted(int eventId, String packageName, String mimeType, int appProvidedDirect,
34             int appProvidedApp, boolean isWorkprofile, int previewType, String intent);
35 
36     /** Logs a UiEventReported event for the system sharesheet when the user selects a target. */
logShareTargetSelected(int targetType, String packageName, int positionPicked, boolean isPinned)37     void logShareTargetSelected(int targetType, String packageName, int positionPicked,
38             boolean isPinned);
39 
40     /** Logs a UiEventReported event for the system sharesheet being triggered by the user. */
logSharesheetTriggered()41     default void logSharesheetTriggered() {
42         log(SharesheetStandardEvent.SHARESHEET_TRIGGERED, getInstanceId());
43     }
44 
45     /** Logs a UiEventReported event for the system sharesheet completing loading app targets. */
logSharesheetAppLoadComplete()46     default void logSharesheetAppLoadComplete() {
47         log(SharesheetStandardEvent.SHARESHEET_APP_LOAD_COMPLETE, getInstanceId());
48     }
49 
50     /**
51      * Logs a UiEventReported event for the system sharesheet completing loading service targets.
52      */
logSharesheetDirectLoadComplete()53     default void logSharesheetDirectLoadComplete() {
54         log(SharesheetStandardEvent.SHARESHEET_DIRECT_LOAD_COMPLETE, getInstanceId());
55     }
56 
57     /**
58      * Logs a UiEventReported event for the system sharesheet timing out loading service targets.
59      */
logSharesheetDirectLoadTimeout()60     default void logSharesheetDirectLoadTimeout() {
61         log(SharesheetStandardEvent.SHARESHEET_DIRECT_LOAD_TIMEOUT, getInstanceId());
62     }
63 
64     /**
65      * Logs a UiEventReported event for the system sharesheet switching
66      * between work and main profile.
67      */
logShareheetProfileChanged()68     default void logShareheetProfileChanged() {
69         log(SharesheetStandardEvent.SHARESHEET_PROFILE_CHANGED, getInstanceId());
70     }
71 
72     /** Logs a UiEventReported event for the system sharesheet getting expanded or collapsed. */
logSharesheetExpansionChanged(boolean isCollapsed)73     default void logSharesheetExpansionChanged(boolean isCollapsed) {
74         log(isCollapsed ? SharesheetStandardEvent.SHARESHEET_COLLAPSED :
75                 SharesheetStandardEvent.SHARESHEET_EXPANDED, getInstanceId());
76     }
77 
78     /**
79      * Logs a UiEventReported event for the system sharesheet app share ranking timing out.
80      */
logSharesheetAppShareRankingTimeout()81     default void logSharesheetAppShareRankingTimeout() {
82         log(SharesheetStandardEvent.SHARESHEET_APP_SHARE_RANKING_TIMEOUT, getInstanceId());
83     }
84 
85     /**
86      * Logs a UiEventReported event for the system sharesheet when direct share row is empty.
87      */
logSharesheetEmptyDirectShareRow()88     default void logSharesheetEmptyDirectShareRow() {
89         log(SharesheetStandardEvent.SHARESHEET_EMPTY_DIRECT_SHARE_ROW, getInstanceId());
90     }
91 
92     /**
93      * Logs a UiEventReported event for a given share activity
94      * @param event
95      * @param instanceId
96      */
log(UiEventLogger.UiEventEnum event, InstanceId instanceId)97     void log(UiEventLogger.UiEventEnum event, InstanceId instanceId);
98 
99     /**
100      *
101      * @return
102      */
getInstanceId()103     InstanceId getInstanceId();
104 
105     /**
106      * The UiEvent enums that this class can log.
107      */
108     enum SharesheetStartedEvent implements UiEventLogger.UiEventEnum {
109         @UiEvent(doc = "Basic system Sharesheet has started and is visible.")
110         SHARE_STARTED(228);
111 
112         private final int mId;
SharesheetStartedEvent(int id)113         SharesheetStartedEvent(int id) {
114             mId = id;
115         }
116         @Override
getId()117         public int getId() {
118             return mId;
119         }
120     }
121 
122     /**
123      * The UiEvent enums that this class can log.
124      */
125     enum SharesheetTargetSelectedEvent implements UiEventLogger.UiEventEnum {
126         INVALID(0),
127         @UiEvent(doc = "User selected a service target.")
128         SHARESHEET_SERVICE_TARGET_SELECTED(232),
129         @UiEvent(doc = "User selected an app target.")
130         SHARESHEET_APP_TARGET_SELECTED(233),
131         @UiEvent(doc = "User selected a standard target.")
132         SHARESHEET_STANDARD_TARGET_SELECTED(234),
133         @UiEvent(doc = "User selected the copy target.")
134         SHARESHEET_COPY_TARGET_SELECTED(235),
135         @UiEvent(doc = "User selected the nearby target.")
136         SHARESHEET_NEARBY_TARGET_SELECTED(626),
137         @UiEvent(doc = "User selected the edit target.")
138         SHARESHEET_EDIT_TARGET_SELECTED(669);
139 
140         private final int mId;
SharesheetTargetSelectedEvent(int id)141         SharesheetTargetSelectedEvent(int id) {
142             mId = id;
143         }
getId()144         @Override public int getId() {
145             return mId;
146         }
147 
fromTargetType(int targetType)148         public static SharesheetTargetSelectedEvent fromTargetType(int targetType) {
149             switch(targetType) {
150                 case ChooserActivity.SELECTION_TYPE_SERVICE:
151                     return SHARESHEET_SERVICE_TARGET_SELECTED;
152                 case ChooserActivity.SELECTION_TYPE_APP:
153                     return SHARESHEET_APP_TARGET_SELECTED;
154                 case ChooserActivity.SELECTION_TYPE_STANDARD:
155                     return SHARESHEET_STANDARD_TARGET_SELECTED;
156                 case ChooserActivity.SELECTION_TYPE_COPY:
157                     return SHARESHEET_COPY_TARGET_SELECTED;
158                 case ChooserActivity.SELECTION_TYPE_NEARBY:
159                     return SHARESHEET_NEARBY_TARGET_SELECTED;
160                 case ChooserActivity.SELECTION_TYPE_EDIT:
161                     return SHARESHEET_EDIT_TARGET_SELECTED;
162                 default:
163                     return INVALID;
164             }
165         }
166     }
167 
168     /**
169      * The UiEvent enums that this class can log.
170      */
171     enum SharesheetStandardEvent implements UiEventLogger.UiEventEnum {
172         INVALID(0),
173         @UiEvent(doc = "User clicked share.")
174         SHARESHEET_TRIGGERED(227),
175         @UiEvent(doc = "User changed from work to personal profile or vice versa.")
176         SHARESHEET_PROFILE_CHANGED(229),
177         @UiEvent(doc = "User expanded target list.")
178         SHARESHEET_EXPANDED(230),
179         @UiEvent(doc = "User collapsed target list.")
180         SHARESHEET_COLLAPSED(231),
181         @UiEvent(doc = "Sharesheet app targets is fully populated.")
182         SHARESHEET_APP_LOAD_COMPLETE(322),
183         @UiEvent(doc = "Sharesheet direct targets is fully populated.")
184         SHARESHEET_DIRECT_LOAD_COMPLETE(323),
185         @UiEvent(doc = "Sharesheet direct targets timed out.")
186         SHARESHEET_DIRECT_LOAD_TIMEOUT(324),
187         @UiEvent(doc = "Sharesheet app share ranking timed out.")
188         SHARESHEET_APP_SHARE_RANKING_TIMEOUT(831),
189         @UiEvent(doc = "Sharesheet empty direct share row.")
190         SHARESHEET_EMPTY_DIRECT_SHARE_ROW(828);
191 
192         private final int mId;
SharesheetStandardEvent(int id)193         SharesheetStandardEvent(int id) {
194             mId = id;
195         }
getId()196         @Override public int getId() {
197             return mId;
198         }
199     }
200 
201     /**
202      * Returns the enum used in sharesheet started atom to indicate what preview type was used.
203      */
typeFromPreviewInt(int previewType)204     default int typeFromPreviewInt(int previewType) {
205         switch(previewType) {
206             case ChooserActivity.CONTENT_PREVIEW_IMAGE:
207                 return FrameworkStatsLog.SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_IMAGE;
208             case ChooserActivity.CONTENT_PREVIEW_FILE:
209                 return FrameworkStatsLog.SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_FILE;
210             case ChooserActivity.CONTENT_PREVIEW_TEXT:
211             default:
212                 return FrameworkStatsLog
213                         .SHARESHEET_STARTED__PREVIEW_TYPE__CONTENT_PREVIEW_TYPE_UNKNOWN;
214         }
215     }
216 
217     /**
218      * Returns the enum used in sharesheet started atom to indicate what intent triggers the
219      * ChooserActivity.
220      */
typeFromIntentString(String intent)221     default int typeFromIntentString(String intent) {
222         if (intent == null) {
223             return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_DEFAULT;
224         }
225         switch (intent) {
226             case Intent.ACTION_VIEW:
227                 return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_VIEW;
228             case Intent.ACTION_EDIT:
229                 return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_EDIT;
230             case Intent.ACTION_SEND:
231                 return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_SEND;
232             case Intent.ACTION_SENDTO:
233                 return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_SENDTO;
234             case Intent.ACTION_SEND_MULTIPLE:
235                 return FrameworkStatsLog
236                         .SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_SEND_MULTIPLE;
237             case MediaStore.ACTION_IMAGE_CAPTURE:
238                 return FrameworkStatsLog
239                         .SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_IMAGE_CAPTURE;
240             case Intent.ACTION_MAIN:
241                 return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_ACTION_MAIN;
242             default:
243                 return FrameworkStatsLog.SHARESHEET_STARTED__INTENT_TYPE__INTENT_DEFAULT;
244         }
245     }
246 }
247