• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 package com.android.launcher3.logging;
17 
18 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
19 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_CLOSE_DOWN;
20 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_OPEN_UP;
21 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE;
22 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_GESTURE;
23 
24 import android.content.Context;
25 
26 import androidx.annotation.Nullable;
27 
28 import com.android.launcher3.R;
29 import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
30 import com.android.launcher3.logger.LauncherAtom.FromState;
31 import com.android.launcher3.logger.LauncherAtom.ToState;
32 import com.android.launcher3.model.data.ItemInfo;
33 import com.android.launcher3.userevent.LauncherLogProto;
34 import com.android.launcher3.util.ResourceBasedOverride;
35 
36 import java.util.List;
37 
38 /**
39  * Handles the user event logging in R+.
40  *
41  * <pre>
42  * All of the event ids are defined here.
43  * Most of the methods are dummy methods for Launcher3
44  * Actual call happens only for Launcher variant that implements QuickStep.
45  * </pre>
46  */
47 public class StatsLogManager implements ResourceBasedOverride {
48 
49     public static final int LAUNCHER_STATE_UNSPECIFIED = 0;
50     public static final int LAUNCHER_STATE_BACKGROUND = 1;
51     public static final int LAUNCHER_STATE_HOME = 2;
52     public static final int LAUNCHER_STATE_OVERVIEW = 3;
53     public static final int LAUNCHER_STATE_ALLAPPS = 4;
54     public static final int LAUNCHER_STATE_UNCHANGED = 5;
55 
56     /**
57      * Returns proper launcher state enum for {@link StatsLogManager}(to be removed during
58      * UserEventDispatcher cleanup)
59      */
containerTypeToAtomState(int containerType)60     public static int containerTypeToAtomState(int containerType) {
61         switch (containerType) {
62             case LauncherLogProto.ContainerType.ALLAPPS_VALUE:
63                 return LAUNCHER_STATE_ALLAPPS;
64             case LauncherLogProto.ContainerType.OVERVIEW_VALUE:
65                 return LAUNCHER_STATE_OVERVIEW;
66             case LauncherLogProto.ContainerType.WORKSPACE_VALUE:
67                 return LAUNCHER_STATE_HOME;
68             case LauncherLogProto.ContainerType.APP_VALUE:
69                 return LAUNCHER_STATE_BACKGROUND;
70         }
71         return LAUNCHER_STATE_UNSPECIFIED;
72     }
73 
74     /**
75      * Returns event enum based on the two {@link ContainerType} transition information when swipe
76      * gesture happens(to be removed during UserEventDispatcher cleanup).
77      */
getLauncherAtomEvent(int startContainerType, int targetContainerType, EventEnum fallbackEvent)78     public static EventEnum getLauncherAtomEvent(int startContainerType,
79             int targetContainerType, EventEnum fallbackEvent) {
80         if (startContainerType == LauncherLogProto.ContainerType.WORKSPACE.getNumber()
81                 && targetContainerType == LauncherLogProto.ContainerType.WORKSPACE.getNumber()) {
82             return LAUNCHER_HOME_GESTURE;
83         } else if (startContainerType != LauncherLogProto.ContainerType.TASKSWITCHER.getNumber()
84                 && targetContainerType == LauncherLogProto.ContainerType.TASKSWITCHER.getNumber()) {
85             return LAUNCHER_OVERVIEW_GESTURE;
86         } else if (startContainerType != LauncherLogProto.ContainerType.ALLAPPS.getNumber()
87                 && targetContainerType == LauncherLogProto.ContainerType.ALLAPPS.getNumber()) {
88             return LAUNCHER_ALLAPPS_OPEN_UP;
89         } else if (startContainerType == LauncherLogProto.ContainerType.ALLAPPS.getNumber()
90                 && targetContainerType != LauncherLogProto.ContainerType.ALLAPPS.getNumber()) {
91             return LAUNCHER_ALLAPPS_CLOSE_DOWN;
92         }
93         return fallbackEvent; // TODO fix
94     }
95 
96     public interface EventEnum {
getId()97         int getId();
98     }
99 
100     public enum LauncherEvent implements EventEnum {
101         /* Used to prevent double logging. */
102         IGNORE(-1),
103 
104         @UiEvent(doc = "App launched from workspace, hotseat or folder in launcher")
105         LAUNCHER_APP_LAUNCH_TAP(338),
106 
107         @UiEvent(doc = "Task launched from overview using TAP")
108         LAUNCHER_TASK_LAUNCH_TAP(339),
109 
110         @UiEvent(doc = "User tapped on notification inside popup context menu.")
111         LAUNCHER_NOTIFICATION_LAUNCH_TAP(516),
112 
113         @UiEvent(doc = "Task launched from overview using SWIPE DOWN")
114         LAUNCHER_TASK_LAUNCH_SWIPE_DOWN(340),
115 
116         @UiEvent(doc = "TASK dismissed from overview using SWIPE UP")
117         LAUNCHER_TASK_DISMISS_SWIPE_UP(341),
118 
119         @UiEvent(doc = "User dragged a launcher item")
120         LAUNCHER_ITEM_DRAG_STARTED(383),
121 
122         @UiEvent(doc = "A dragged launcher item is successfully dropped")
123         LAUNCHER_ITEM_DROP_COMPLETED(385),
124 
125         @UiEvent(doc = "A dragged launcher item is successfully dropped on another item "
126                 + "resulting in a new folder creation")
127         LAUNCHER_ITEM_DROP_FOLDER_CREATED(386),
128 
129         @UiEvent(doc = "Folder's label is automatically assigned.")
130         LAUNCHER_FOLDER_AUTO_LABELED(591),
131 
132         @UiEvent(doc = "Could not auto-label a folder because primary suggestion is null or empty.")
133         LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_PRIMARY(592),
134 
135         @UiEvent(doc = "Could not auto-label a folder because no suggestions exist.")
136         LAUNCHER_FOLDER_AUTO_LABELING_SKIPPED_EMPTY_SUGGESTIONS(593),
137 
138         @UiEvent(doc = "User manually updated the folder label.")
139         LAUNCHER_FOLDER_LABEL_UPDATED(460),
140 
141         @UiEvent(doc = "User long pressed on the workspace empty space.")
142         LAUNCHER_WORKSPACE_LONGPRESS(461),
143 
144         @UiEvent(doc = "User tapped or long pressed on a wallpaper icon inside launcher settings.")
145         LAUNCHER_WALLPAPER_BUTTON_TAP_OR_LONGPRESS(462),
146 
147         @UiEvent(doc = "User tapped or long pressed on settings icon inside launcher settings.")
148         LAUNCHER_SETTINGS_BUTTON_TAP_OR_LONGPRESS(463),
149 
150         @UiEvent(doc = "User tapped or long pressed on widget tray icon inside launcher settings.")
151         LAUNCHER_WIDGETSTRAY_BUTTON_TAP_OR_LONGPRESS(464),
152 
153         @UiEvent(doc = "A dragged item is dropped on 'Remove' button in the target bar")
154         LAUNCHER_ITEM_DROPPED_ON_REMOVE(465),
155 
156         @UiEvent(doc = "A dragged item is dropped on 'Cancel' button in the target bar")
157         LAUNCHER_ITEM_DROPPED_ON_CANCEL(466),
158 
159         @UiEvent(doc = "A predicted item is dragged and dropped on 'Don't suggest app'"
160                 + " button in the target bar")
161         LAUNCHER_ITEM_DROPPED_ON_DONT_SUGGEST(467),
162 
163         @UiEvent(doc = "A dragged item is dropped on 'Uninstall' button in target bar")
164         LAUNCHER_ITEM_DROPPED_ON_UNINSTALL(468),
165 
166         @UiEvent(doc = "User completed uninstalling the package after dropping on "
167                 + "the icon onto 'Uninstall' button in the target bar")
168         LAUNCHER_ITEM_UNINSTALL_COMPLETED(469),
169 
170         @UiEvent(doc = "User cancelled uninstalling the package after dropping on "
171                 + "the icon onto 'Uninstall' button in the target bar")
172         LAUNCHER_ITEM_UNINSTALL_CANCELLED(470),
173 
174         @UiEvent(doc = "User tapped or long pressed on the task icon(aka package icon) "
175                 + "from overview to open task menu.")
176         LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS(517),
177 
178         @UiEvent(doc = "User opened package specific widgets list by tapping on widgets system "
179                 + "shortcut inside popup context menu.")
180         LAUNCHER_SYSTEM_SHORTCUT_WIDGETS_TAP(514),
181 
182         @UiEvent(doc = "User tapped on app info system shortcut.")
183         LAUNCHER_SYSTEM_SHORTCUT_APP_INFO_TAP(515),
184 
185         @UiEvent(doc = "User tapped on split screen icon on a task menu.")
186         LAUNCHER_SYSTEM_SHORTCUT_SPLIT_SCREEN_TAP(518),
187 
188         @UiEvent(doc = "User tapped on free form icon on a task menu.")
189         LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP(519),
190 
191         @UiEvent(doc = "User tapped on pause app system shortcut.")
192         LAUNCHER_SYSTEM_SHORTCUT_PAUSE_TAP(521),
193 
194         @UiEvent(doc = "User tapped on pin system shortcut.")
195         LAUNCHER_SYSTEM_SHORTCUT_PIN_TAP(522),
196 
197         @UiEvent(doc = "User is shown All Apps education view.")
198         LAUNCHER_ALL_APPS_EDU_SHOWN(523),
199 
200         @UiEvent(doc = "User opened a folder.")
201         LAUNCHER_FOLDER_OPEN(551),
202 
203         @UiEvent(doc = "Hotseat education half sheet seen")
204         LAUNCHER_HOTSEAT_EDU_SEEN(479),
205 
206         @UiEvent(doc = "Hotseat migration accepted")
207         LAUNCHER_HOTSEAT_EDU_ACCEPT(480),
208 
209         @UiEvent(doc = "Hotseat migration denied")
210         LAUNCHER_HOTSEAT_EDU_DENY(481),
211 
212         @UiEvent(doc = "Hotseat education tip shown")
213         LAUNCHER_HOTSEAT_EDU_ONLY_TIP(482),
214 
215         /**
216          * @deprecated LauncherUiChanged.rank field is repurposed to store all apps rank, so no
217          * separate event is required.
218          */
219         @Deprecated
220         @UiEvent(doc = "App launch ranking logged for all apps predictions")
221         LAUNCHER_ALL_APPS_RANKED(552),
222 
223         @UiEvent(doc = "App launch ranking logged for hotseat predictions)")
224         LAUNCHER_HOTSEAT_RANKED(553),
225         @UiEvent(doc = "Launcher is now in background. e.g., Screen off event")
226         LAUNCHER_ONSTOP(562),
227 
228         @UiEvent(doc = "Launcher is now in foreground. e.g., Screen on event, back button")
229         LAUNCHER_ONRESUME(563),
230 
231         @UiEvent(doc = "User swipes or fling in LEFT direction on workspace.")
232         LAUNCHER_SWIPELEFT(564),
233 
234         @UiEvent(doc = "User swipes or fling in RIGHT direction on workspace.")
235         LAUNCHER_SWIPERIGHT(565),
236 
237         @UiEvent(doc = "User swipes or fling in UP direction in unknown way.")
238         LAUNCHER_UNKNOWN_SWIPEUP(566),
239 
240         @UiEvent(doc = "User swipes or fling in DOWN direction in unknown way.")
241         LAUNCHER_UNKNOWN_SWIPEDOWN(567),
242 
243         @UiEvent(doc = "User swipes or fling in UP direction to open apps drawer.")
244         LAUNCHER_ALLAPPS_OPEN_UP(568),
245 
246         @UiEvent(doc = "User swipes or fling in DOWN direction to close apps drawer.")
247         LAUNCHER_ALLAPPS_CLOSE_DOWN(569),
248 
249         @UiEvent(doc = "User swipes or fling in UP direction and hold from the bottom bazel area")
250         LAUNCHER_OVERVIEW_GESTURE(570),
251 
252         @UiEvent(doc = "User swipes or fling in LEFT direction on the bottom bazel area.")
253         LAUNCHER_QUICKSWITCH_LEFT(571),
254 
255         @UiEvent(doc = "User swipes or fling in RIGHT direction on the bottom bazel area.")
256         LAUNCHER_QUICKSWITCH_RIGHT(572),
257 
258         @UiEvent(doc = "User swipes or fling in DOWN direction on the bottom bazel area.")
259         LAUNCHER_SWIPEDOWN_NAVBAR(573),
260 
261         @UiEvent(doc = "User swipes or fling in UP direction from bottom bazel area.")
262         LAUNCHER_HOME_GESTURE(574),
263 
264         @UiEvent(doc = "User's workspace layout information is snapshot in the background.")
265         LAUNCHER_WORKSPACE_SNAPSHOT(579),
266 
267         @UiEvent(doc = "User tapped on the screenshot button on overview)")
268         LAUNCHER_OVERVIEW_ACTIONS_SCREENSHOT(580),
269 
270         @UiEvent(doc = "User tapped on the select button on overview)")
271         LAUNCHER_OVERVIEW_ACTIONS_SELECT(581),
272 
273         @UiEvent(doc = "User tapped on the share button on overview")
274         LAUNCHER_OVERVIEW_ACTIONS_SHARE(582),
275 
276         @UiEvent(doc = "User tapped on the close button in select mode")
277         LAUNCHER_SELECT_MODE_CLOSE(583),
278 
279         @UiEvent(doc = "User tapped on the highlight items in select mode")
280         LAUNCHER_SELECT_MODE_ITEM(584),
281 
282         @UiEvent(doc = "Notification dot on app icon enabled.")
283         LAUNCHER_NOTIFICATION_DOT_ENABLED(611),
284 
285         @UiEvent(doc = "Notification dot on app icon disabled.")
286         LAUNCHER_NOTIFICATION_DOT_DISABLED(612),
287 
288         @UiEvent(doc = "For new apps, add app icons to home screen enabled.")
289         LAUNCHER_ADD_NEW_APPS_TO_HOME_SCREEN_ENABLED(613),
290 
291         @UiEvent(doc = "For new apps, add app icons to home screen disabled.")
292         LAUNCHER_ADD_NEW_APPS_TO_HOME_SCREEN_DISABLED(614),
293 
294         @UiEvent(doc = "Home screen rotation is enabled when phone is rotated.")
295         LAUNCHER_HOME_SCREEN_ROTATION_ENABLED(615),
296 
297         @UiEvent(doc = "Home screen rotation is disabled when phone is rotated.")
298         LAUNCHER_HOME_SCREEN_ROTATION_DISABLED(616),
299 
300         @UiEvent(doc = "Suggestions in all apps list enabled.")
301         LAUNCHER_ALL_APPS_SUGGESTIONS_ENABLED(619),
302 
303         @UiEvent(doc = "Suggestions in all apps list disabled.")
304         LAUNCHER_ALL_APPS_SUGGESTIONS_DISABLED(620),
305 
306         @UiEvent(doc = "Suggestions on home screen is enabled.")
307         LAUNCHER_HOME_SCREEN_SUGGESTIONS_ENABLED(621),
308 
309         @UiEvent(doc = "Suggestions on home screen is disabled.")
310         LAUNCHER_HOME_SCREEN_SUGGESTIONS_DISABLED(622),
311 
312         @UiEvent(doc = "System navigation is 3 button mode.")
313         LAUNCHER_NAVIGATION_MODE_3_BUTTON(623),
314 
315         @UiEvent(doc = "System navigation mode is 2 button mode.")
316         LAUNCHER_NAVIGATION_MODE_2_BUTTON(624),
317 
318         @UiEvent(doc = "System navigation mode is 0 button mode/gesture navigation mode .")
319         LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON(625),
320 
321         @UiEvent(doc = "User tapped on image content in Overview Select mode.")
322         LAUNCHER_SELECT_MODE_IMAGE(627),
323 
324         @UiEvent(doc = "User swiped down on workspace (triggering noti shade to open).")
325         LAUNCHER_SWIPE_DOWN_WORKSPACE_NOTISHADE_OPEN(651);
326         // ADD MORE
327 
328         private final int mId;
329 
LauncherEvent(int id)330         LauncherEvent(int id) {
331             mId = id;
332         }
333 
getId()334         public int getId() {
335             return mId;
336         }
337     }
338 
339     /**
340      * Launcher specific ranking related events.
341      */
342     public enum LauncherRankingEvent implements EventEnum {
343 
344         UNKNOWN(0);
345         // ADD MORE
346 
347         private final int mId;
348 
LauncherRankingEvent(int id)349         LauncherRankingEvent(int id) {
350             mId = id;
351         }
352 
getId()353         public int getId() {
354             return mId;
355         }
356     }
357 
358     /**
359      * Helps to construct and write the log message.
360      */
361     public interface StatsLogger {
362 
363         /**
364          * Sets log fields from provided {@link ItemInfo}.
365          */
withItemInfo(ItemInfo itemInfo)366         default StatsLogger withItemInfo(ItemInfo itemInfo) {
367             return this;
368         }
369 
370 
371         /**
372          * Sets {@link InstanceId} of log message.
373          */
withInstanceId(InstanceId instanceId)374         default StatsLogger withInstanceId(InstanceId instanceId) {
375             return this;
376         }
377 
378         /**
379          * Sets rank field of log message.
380          */
withRank(int rank)381         default StatsLogger withRank(int rank) {
382             return this;
383         }
384 
385         /**
386          * Sets source launcher state field of log message.
387          */
withSrcState(int srcState)388         default StatsLogger withSrcState(int srcState) {
389             return this;
390         }
391 
392         /**
393          * Sets destination launcher state field of log message.
394          */
withDstState(int dstState)395         default StatsLogger withDstState(int dstState) {
396             return this;
397         }
398 
399         /**
400          * Sets FromState field of log message.
401          */
withFromState(FromState fromState)402         default StatsLogger withFromState(FromState fromState) {
403             return this;
404         }
405 
406         /**
407          * Sets ToState field of log message.
408          */
withToState(ToState toState)409         default StatsLogger withToState(ToState toState) {
410             return this;
411         }
412 
413         /**
414          * Sets editText field of log message.
415          */
withEditText(String editText)416         default StatsLogger withEditText(String editText) {
417             return this;
418         }
419 
420         /**
421          * Sets the final value for container related fields of log message.
422          *
423          * By default container related fields are derived from {@link ItemInfo}, this method would
424          * override those values.
425          */
withContainerInfo(ContainerInfo containerInfo)426         default StatsLogger withContainerInfo(ContainerInfo containerInfo) {
427             return this;
428         }
429 
430         /**
431          * Builds the final message and logs it as {@link EventEnum}.
432          */
log(EventEnum event)433         default void log(EventEnum event) {
434         }
435     }
436 
437     /**
438      * Returns new logger object.
439      */
logger()440     public StatsLogger logger() {
441         return new StatsLogger() {
442         };
443     }
444 
445     /**
446      * Creates a new instance of {@link StatsLogManager} based on provided context.
447      */
newInstance(Context context)448     public static StatsLogManager newInstance(Context context) {
449         StatsLogManager mgr = Overrides.getObject(StatsLogManager.class,
450                 context.getApplicationContext(), R.string.stats_log_manager_class);
451         return mgr;
452     }
453 
454     /**
455      * Log an event with ranked-choice information along with package. Does nothing if event.getId()
456      * <= 0.
457      *
458      * @param rankingEvent an enum implementing EventEnum interface.
459      * @param instanceId An identifier obtained from an InstanceIdSequence.
460      * @param packageName the package name of the relevant app, if known (null otherwise).
461      * @param position the position picked.
462      */
log(EventEnum rankingEvent, InstanceId instanceId, @Nullable String packageName, int position)463     public void log(EventEnum rankingEvent, InstanceId instanceId, @Nullable String packageName,
464             int position) {
465     }
466 
467     /**
468      * Logs impression of the current workspace with additional launcher events.
469      */
logSnapshot(List<EventEnum> additionalEvents)470     public void logSnapshot(List<EventEnum> additionalEvents) {
471     }
472 }
473