• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.wm.shell.desktopmode
18 
19 import android.app.ActivityManager.RunningTaskInfo
20 import android.util.Size
21 import android.view.InputDevice.SOURCE_MOUSE
22 import android.view.InputDevice.SOURCE_TOUCHSCREEN
23 import android.view.MotionEvent
24 import android.view.MotionEvent.TOOL_TYPE_FINGER
25 import android.view.MotionEvent.TOOL_TYPE_MOUSE
26 import android.view.MotionEvent.TOOL_TYPE_STYLUS
27 import android.window.DesktopModeFlags
28 import com.android.internal.annotations.VisibleForTesting
29 import com.android.internal.protolog.ProtoLog
30 import com.android.internal.util.FrameworkStatsLog
31 import com.android.wm.shell.EventLogTags
32 import com.android.wm.shell.common.DisplayController
33 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
34 import java.security.SecureRandom
35 import java.util.Random
36 import java.util.concurrent.atomic.AtomicInteger
37 
38 /** Event logger for logging desktop mode session events */
39 class DesktopModeEventLogger {
40     private val random: Random = SecureRandom()
41 
42     /** The session id for the current desktop mode session */
43     @VisibleForTesting val currentSessionId: AtomicInteger = AtomicInteger(NO_SESSION_ID)
44 
generateSessionIdnull45     private fun generateSessionId() = 1 + random.nextInt(1 shl 20)
46 
47     /** Logs enter into desktop mode with [enterReason] */
48     fun logSessionEnter(enterReason: EnterReason) {
49         val sessionId = generateSessionId()
50         val previousSessionId = currentSessionId.getAndSet(sessionId)
51         if (previousSessionId != NO_SESSION_ID) {
52             ProtoLog.w(
53                 WM_SHELL_DESKTOP_MODE,
54                 "DesktopModeLogger: Existing desktop mode session id: %s found on desktop " +
55                     "mode enter",
56                 previousSessionId,
57             )
58         }
59 
60         ProtoLog.v(
61             WM_SHELL_DESKTOP_MODE,
62             "DesktopModeLogger: Logging session enter, session: %s reason: %s",
63             sessionId,
64             enterReason.name,
65         )
66         FrameworkStatsLog.write(
67             DESKTOP_MODE_ATOM_ID,
68             /* event */ FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EVENT__ENTER,
69             /* enterReason */ enterReason.reason,
70             /* exitReason */ 0,
71             /* session_id */ sessionId,
72         )
73         EventLogTags.writeWmShellEnterDesktopMode(enterReason.reason, sessionId)
74     }
75 
76     /** Logs exit from desktop mode session with [exitReason] */
logSessionExitnull77     fun logSessionExit(exitReason: ExitReason) {
78         val sessionId = currentSessionId.getAndSet(NO_SESSION_ID)
79         if (sessionId == NO_SESSION_ID) {
80             ProtoLog.w(
81                 WM_SHELL_DESKTOP_MODE,
82                 "DesktopModeLogger: No session id found for logging exit from desktop mode",
83             )
84             return
85         }
86 
87         ProtoLog.v(
88             WM_SHELL_DESKTOP_MODE,
89             "DesktopModeLogger: Logging session exit, session: %s reason: %s",
90             sessionId,
91             exitReason.name,
92         )
93         FrameworkStatsLog.write(
94             DESKTOP_MODE_ATOM_ID,
95             /* event */ FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EVENT__EXIT,
96             /* enterReason */ 0,
97             /* exitReason */ exitReason.reason,
98             /* session_id */ sessionId,
99         )
100         EventLogTags.writeWmShellExitDesktopMode(exitReason.reason, sessionId)
101     }
102 
103     /** Logs that a task with [taskUpdate] was added in a desktop mode session */
logTaskAddednull104     fun logTaskAdded(taskUpdate: TaskUpdate) {
105         val sessionId = currentSessionId.get()
106         if (sessionId == NO_SESSION_ID) {
107             ProtoLog.w(
108                 WM_SHELL_DESKTOP_MODE,
109                 "DesktopModeLogger: No session id found for logging task added",
110             )
111             return
112         }
113 
114         ProtoLog.v(
115             WM_SHELL_DESKTOP_MODE,
116             "DesktopModeLogger: Logging task added, session: %s taskId: %s",
117             sessionId,
118             taskUpdate.instanceId,
119         )
120         logTaskUpdate(
121             FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__TASK_EVENT__TASK_ADDED,
122             sessionId,
123             taskUpdate,
124         )
125     }
126 
127     /** Logs that a task with [taskUpdate] was removed from a desktop mode session */
logTaskRemovednull128     fun logTaskRemoved(taskUpdate: TaskUpdate) {
129         val sessionId = currentSessionId.get()
130         if (sessionId == NO_SESSION_ID) {
131             ProtoLog.w(
132                 WM_SHELL_DESKTOP_MODE,
133                 "DesktopModeLogger: No session id found for logging task removed",
134             )
135             return
136         }
137 
138         ProtoLog.v(
139             WM_SHELL_DESKTOP_MODE,
140             "DesktopModeLogger: Logging task remove, session: %s taskId: %s",
141             sessionId,
142             taskUpdate.instanceId,
143         )
144         logTaskUpdate(
145             FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__TASK_EVENT__TASK_REMOVED,
146             sessionId,
147             taskUpdate,
148         )
149     }
150 
151     /** Logs that a task with [taskUpdate] had it's info changed in a desktop mode session */
logTaskInfoChangednull152     fun logTaskInfoChanged(taskUpdate: TaskUpdate) {
153         val sessionId = currentSessionId.get()
154         if (sessionId == NO_SESSION_ID) {
155             ProtoLog.w(
156                 WM_SHELL_DESKTOP_MODE,
157                 "DesktopModeLogger: No session id found for logging task info changed",
158             )
159             return
160         }
161 
162         ProtoLog.v(
163             WM_SHELL_DESKTOP_MODE,
164             "DesktopModeLogger: Logging task info changed, session: %s taskId: %s",
165             sessionId,
166             taskUpdate.instanceId,
167         )
168         logTaskUpdate(
169             FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__TASK_EVENT__TASK_INFO_CHANGED,
170             sessionId,
171             taskUpdate,
172         )
173     }
174 
175     /**
176      * Logs that a task resize event is starting with [taskSizeUpdate] within a Desktop mode
177      * session.
178      */
logTaskResizingStartednull179     fun logTaskResizingStarted(
180         resizeTrigger: ResizeTrigger,
181         inputMethod: InputMethod,
182         taskInfo: RunningTaskInfo,
183         taskWidth: Int? = null,
184         taskHeight: Int? = null,
185         displayController: DisplayController? = null,
186         displayLayoutSize: Size? = null,
187     ) {
188         if (!DesktopModeFlags.ENABLE_RESIZING_METRICS.isTrue) return
189 
190         val sessionId = currentSessionId.get()
191         if (sessionId == NO_SESSION_ID) {
192             ProtoLog.w(
193                 WM_SHELL_DESKTOP_MODE,
194                 "DesktopModeLogger: No session id found for logging start of task resizing",
195             )
196             return
197         }
198 
199         val taskSizeUpdate =
200             createTaskSizeUpdate(
201                 resizeTrigger,
202                 inputMethod,
203                 taskInfo,
204                 taskWidth,
205                 taskHeight,
206                 displayController = displayController,
207                 displayLayoutSize = displayLayoutSize,
208             )
209 
210         ProtoLog.v(
211             WM_SHELL_DESKTOP_MODE,
212             "DesktopModeLogger: Logging task resize is starting, session: %s, taskSizeUpdate: %s",
213             sessionId,
214             taskSizeUpdate,
215         )
216         logTaskSizeUpdated(
217             FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZING_STAGE__START_RESIZING_STAGE,
218             sessionId,
219             taskSizeUpdate,
220         )
221     }
222 
223     /**
224      * Logs that a task resize event is ending with [taskSizeUpdate] within a Desktop mode session.
225      */
logTaskResizingEndednull226     fun logTaskResizingEnded(
227         resizeTrigger: ResizeTrigger,
228         inputMethod: InputMethod,
229         taskInfo: RunningTaskInfo,
230         taskWidth: Int? = null,
231         taskHeight: Int? = null,
232         displayController: DisplayController? = null,
233         displayLayoutSize: Size? = null,
234     ) {
235         if (!DesktopModeFlags.ENABLE_RESIZING_METRICS.isTrue) return
236 
237         val sessionId = currentSessionId.get()
238         if (sessionId == NO_SESSION_ID) {
239             ProtoLog.w(
240                 WM_SHELL_DESKTOP_MODE,
241                 "DesktopModeLogger: No session id found for logging end of task resizing",
242             )
243             return
244         }
245 
246         val taskSizeUpdate =
247             createTaskSizeUpdate(
248                 resizeTrigger,
249                 inputMethod,
250                 taskInfo,
251                 taskWidth,
252                 taskHeight,
253                 displayController,
254                 displayLayoutSize,
255             )
256 
257         ProtoLog.v(
258             WM_SHELL_DESKTOP_MODE,
259             "DesktopModeLogger: Logging task resize is ending, session: %s, taskSizeUpdate: %s",
260             sessionId,
261             taskSizeUpdate,
262         )
263 
264         logTaskSizeUpdated(
265             FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZING_STAGE__END_RESIZING_STAGE,
266             sessionId,
267             taskSizeUpdate,
268         )
269     }
270 
createTaskSizeUpdatenull271     private fun createTaskSizeUpdate(
272         resizeTrigger: ResizeTrigger,
273         inputMethod: InputMethod,
274         taskInfo: RunningTaskInfo,
275         taskWidth: Int? = null,
276         taskHeight: Int? = null,
277         displayController: DisplayController? = null,
278         displayLayoutSize: Size? = null,
279     ): TaskSizeUpdate {
280         val taskBounds = taskInfo.configuration.windowConfiguration.bounds
281 
282         val height = taskHeight ?: taskBounds.height()
283         val width = taskWidth ?: taskBounds.width()
284 
285         val displaySize =
286             when {
287                 displayLayoutSize != null -> displayLayoutSize.height * displayLayoutSize.width
288                 displayController != null ->
289                     displayController.getDisplayLayout(taskInfo.displayId)?.let {
290                         it.height() * it.width()
291                     }
292                 else -> null
293             }
294 
295         return TaskSizeUpdate(
296             resizeTrigger,
297             inputMethod,
298             taskInfo.taskId,
299             taskInfo.effectiveUid,
300             height,
301             width,
302             displaySize,
303         )
304     }
305 
logTaskInfoStateInitnull306     fun logTaskInfoStateInit() {
307         logTaskUpdate(
308             FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__TASK_EVENT__TASK_INIT_STATSD,
309             sessionId = 0,
310             TaskUpdate(
311                 visibleTaskCount = 0,
312                 instanceId = 0,
313                 uid = 0,
314                 taskHeight = 0,
315                 taskWidth = 0,
316                 taskX = 0,
317                 taskY = 0,
318             ),
319         )
320     }
321 
logTaskUpdatenull322     private fun logTaskUpdate(taskEvent: Int, sessionId: Int, taskUpdate: TaskUpdate) {
323         FrameworkStatsLog.write(
324             DESKTOP_MODE_TASK_UPDATE_ATOM_ID,
325             /* task_event */
326             taskEvent,
327             /* instance_id */
328             taskUpdate.instanceId,
329             /* uid */
330             taskUpdate.uid,
331             /* task_height */
332             taskUpdate.taskHeight,
333             /* task_width */
334             taskUpdate.taskWidth,
335             /* task_x */
336             taskUpdate.taskX,
337             /* task_y */
338             taskUpdate.taskY,
339             /* session_id */
340             sessionId,
341             taskUpdate.minimizeReason?.reason ?: UNSET_MINIMIZE_REASON,
342             taskUpdate.unminimizeReason?.reason ?: UNSET_UNMINIMIZE_REASON,
343             /* visible_task_count */
344             taskUpdate.visibleTaskCount,
345             taskUpdate.focusReason?.reason ?: UNSET_FOCUS_REASON,
346         )
347         EventLogTags.writeWmShellDesktopModeTaskUpdate(
348             /* task_event */
349             taskEvent,
350             /* instance_id */
351             taskUpdate.instanceId,
352             /* uid */
353             taskUpdate.uid,
354             /* task_height */
355             taskUpdate.taskHeight,
356             /* task_width */
357             taskUpdate.taskWidth,
358             /* task_x */
359             taskUpdate.taskX,
360             /* task_y */
361             taskUpdate.taskY,
362             /* session_id */
363             sessionId,
364             taskUpdate.minimizeReason?.reason ?: UNSET_MINIMIZE_REASON,
365             taskUpdate.unminimizeReason?.reason ?: UNSET_UNMINIMIZE_REASON,
366             /* visible_task_count */
367             taskUpdate.visibleTaskCount,
368             taskUpdate.focusReason?.reason ?: UNSET_FOCUS_REASON,
369         )
370     }
371 
logTaskSizeUpdatednull372     private fun logTaskSizeUpdated(
373         resizingStage: Int,
374         sessionId: Int,
375         taskSizeUpdate: TaskSizeUpdate,
376     ) {
377         FrameworkStatsLog.write(
378             DESKTOP_MODE_TASK_SIZE_UPDATED_ATOM_ID,
379             /* resize_trigger */
380             taskSizeUpdate.resizeTrigger?.trigger ?: ResizeTrigger.UNKNOWN_RESIZE_TRIGGER.trigger,
381             /* resizing_stage */
382             resizingStage,
383             /* input_method */
384             taskSizeUpdate.inputMethod?.method ?: InputMethod.UNKNOWN_INPUT_METHOD.method,
385             /* desktop_mode_session_id */
386             sessionId,
387             /* instance_id */
388             taskSizeUpdate.instanceId,
389             /* uid */
390             taskSizeUpdate.uid,
391             /* task_height */
392             taskSizeUpdate.taskHeight,
393             /* task_width */
394             taskSizeUpdate.taskWidth,
395             /* display_area */
396             taskSizeUpdate.displayArea ?: -1,
397         )
398     }
399 
400     companion object {
401 
402         /**
403          * Describes a task position and dimensions.
404          *
405          * @property instanceId instance id of the task
406          * @property uid uid of the app associated with the task
407          * @property taskHeight height of the task in px
408          * @property taskWidth width of the task in px
409          * @property taskX x-coordinate of the top-left corner
410          * @property taskY y-coordinate of the top-left corner
411          * @property minimizeReason the reason the task was minimized
412          * @property unminimizeReason the reason the task was unminimized
413          * @property visibleTaskCount the number of visible tasks after this update
414          * @property focusReason the reason the task was focused
415          */
416         data class TaskUpdate(
417             val instanceId: Int,
418             val uid: Int,
419             val taskHeight: Int,
420             val taskWidth: Int,
421             val taskX: Int,
422             val taskY: Int,
423             val minimizeReason: MinimizeReason? = null,
424             val unminimizeReason: UnminimizeReason? = null,
425             val visibleTaskCount: Int,
426             val focusReason: FocusReason? = null,
427         )
428 
429         /**
430          * Describes a task size update (resizing, snapping or maximizing to stable bounds).
431          *
432          * @property resizeTrigger the trigger for task resize
433          * @property inputMethod the input method for resizing this task
434          * @property instanceId instance id of the task
435          * @property uid uid of the app associated with the task
436          * @property taskHeight height of the task in dp
437          * @property taskWidth width of the task in dp
438          * @property displayArea the display size of the screen in dp
439          */
440         data class TaskSizeUpdate(
441             val resizeTrigger: ResizeTrigger? = null,
442             val inputMethod: InputMethod? = null,
443             val instanceId: Int,
444             val uid: Int,
445             val taskHeight: Int,
446             val taskWidth: Int,
447             val displayArea: Int?,
448         )
449 
450         @JvmStatic
getInputMethodFromMotionEventnull451         fun getInputMethodFromMotionEvent(e: MotionEvent?): InputMethod {
452             if (e == null) return InputMethod.UNKNOWN_INPUT_METHOD
453 
454             val toolType = e.getToolType(e.findPointerIndex(e.getPointerId(0)))
455             return when {
456                 toolType == TOOL_TYPE_STYLUS -> InputMethod.STYLUS
457                 toolType == TOOL_TYPE_MOUSE -> InputMethod.MOUSE
458                 toolType == TOOL_TYPE_FINGER && e.source == SOURCE_MOUSE -> InputMethod.TOUCHPAD
459                 toolType == TOOL_TYPE_FINGER && e.source == SOURCE_TOUCHSCREEN -> InputMethod.TOUCH
460                 else -> InputMethod.UNKNOWN_INPUT_METHOD
461             }
462         }
463 
464         // Default value used when the task was not minimized.
465         @VisibleForTesting
466         const val UNSET_MINIMIZE_REASON =
467             FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__MINIMIZE_REASON__UNSET_MINIMIZE
468 
469         /** The reason a task was minimized. */
470         enum class MinimizeReason(val reason: Int) {
471             TASK_LIMIT(
472                 FrameworkStatsLog
473                     .DESKTOP_MODE_SESSION_TASK_UPDATE__MINIMIZE_REASON__MINIMIZE_TASK_LIMIT
474             ),
475             MINIMIZE_BUTTON(
476                 FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__MINIMIZE_REASON__MINIMIZE_BUTTON
477             ),
478             KEY_GESTURE(
479                 FrameworkStatsLog
480                     .DESKTOP_MODE_SESSION_TASK_UPDATE__MINIMIZE_REASON__MINIMIZE_KEY_GESTURE
481             ),
482         }
483 
484         // Default value used when the task was not unminimized.
485         @VisibleForTesting
486         const val UNSET_UNMINIMIZE_REASON =
487             FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__UNMINIMIZE_REASON__UNSET_UNMINIMIZE
488 
489         /** The reason a task was unminimized. */
490         enum class UnminimizeReason(val reason: Int) {
491             UNKNOWN(
492                 FrameworkStatsLog
493                     .DESKTOP_MODE_SESSION_TASK_UPDATE__UNMINIMIZE_REASON__UNMINIMIZE_UNKNOWN
494             ),
495             TASKBAR_TAP(
496                 FrameworkStatsLog
497                     .DESKTOP_MODE_SESSION_TASK_UPDATE__UNMINIMIZE_REASON__UNMINIMIZE_TASKBAR_TAP
498             ),
499             ALT_TAB(
500                 FrameworkStatsLog
501                     .DESKTOP_MODE_SESSION_TASK_UPDATE__UNMINIMIZE_REASON__UNMINIMIZE_ALT_TAB
502             ),
503             TASK_LAUNCH(
504                 FrameworkStatsLog
505                     .DESKTOP_MODE_SESSION_TASK_UPDATE__UNMINIMIZE_REASON__UNMINIMIZE_TASK_LAUNCH
506             ),
507             APP_HANDLE_MENU_BUTTON(
508                 FrameworkStatsLog
509                     .DESKTOP_MODE_SESSION_TASK_UPDATE__UNMINIMIZE_REASON__UNMINIMIZE_APP_HANDLE_MENU_BUTTON
510             ),
511             TASKBAR_MANAGE_WINDOW(
512                 FrameworkStatsLog
513                     .DESKTOP_MODE_SESSION_TASK_UPDATE__UNMINIMIZE_REASON__UNMINIMIZE_TASKBAR_MANAGE_WINDOW
514             ),
515         }
516 
517         // Default value used when the task was not unminimized.
518         @VisibleForTesting
519         const val UNSET_FOCUS_REASON =
520             FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__FOCUS_REASON__UNSET_FOCUS
521 
522         /** The reason a task was unminimized. */
523         enum class FocusReason(val reason: Int) {
524             UNKNOWN(FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE__FOCUS_REASON__FOCUS_UNKNOWN)
525         }
526 
527         /**
528          * Enum EnterReason mapped to the EnterReason definition in
529          * stats/atoms/desktopmode/desktopmode_extensions_atoms.proto
530          */
531         enum class EnterReason(val reason: Int) {
532             UNKNOWN_ENTER(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__UNKNOWN_ENTER),
533             OVERVIEW(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__OVERVIEW),
534             APP_HANDLE_DRAG(
535                 FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__APP_HANDLE_DRAG
536             ),
537             APP_HANDLE_MENU_BUTTON(
538                 FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__APP_HANDLE_MENU_BUTTON
539             ),
540             APP_FREEFORM_INTENT(
541                 FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__APP_FREEFORM_INTENT
542             ),
543             KEYBOARD_SHORTCUT_ENTER(
544                 FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__KEYBOARD_SHORTCUT_ENTER
545             ),
546             SCREEN_ON(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__SCREEN_ON),
547             APP_FROM_OVERVIEW(
548                 FrameworkStatsLog.DESKTOP_MODE_UICHANGED__ENTER_REASON__APP_FROM_OVERVIEW
549             ),
550         }
551 
552         /**
553          * Enum ExitReason mapped to the ExitReason definition in
554          * stats/atoms/desktopmode/desktopmode_extensions_atoms.proto
555          */
556         enum class ExitReason(val reason: Int) {
557             UNKNOWN_EXIT(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__UNKNOWN_EXIT),
558             DRAG_TO_EXIT(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__DRAG_TO_EXIT),
559             APP_HANDLE_MENU_BUTTON_EXIT(
560                 FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__APP_HANDLE_MENU_BUTTON_EXIT
561             ),
562             KEYBOARD_SHORTCUT_EXIT(
563                 FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__KEYBOARD_SHORTCUT_EXIT
564             ),
565             RETURN_HOME_OR_OVERVIEW(
566                 FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__RETURN_HOME_OR_OVERVIEW
567             ),
568             TASK_FINISHED(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__TASK_FINISHED),
569             SCREEN_OFF(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__SCREEN_OFF),
570             TASK_MINIMIZED(FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__TASK_MINIMIZED),
571             TASK_MOVED_TO_BACK(
572                 FrameworkStatsLog.DESKTOP_MODE_UICHANGED__EXIT_REASON__TASK_MOVED_TO_BACK
573             ),
574         }
575 
576         /**
577          * Enum ResizeTrigger mapped to the ResizeTrigger definition in
578          * stats/atoms/desktopmode/desktopmode_extensions_atoms.proto
579          */
580         enum class ResizeTrigger(val trigger: Int) {
581             UNKNOWN_RESIZE_TRIGGER(
582                 FrameworkStatsLog
583                     .DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__UNKNOWN_RESIZE_TRIGGER
584             ),
585             CORNER(
586                 FrameworkStatsLog
587                     .DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__CORNER_RESIZE_TRIGGER
588             ),
589             EDGE(
590                 FrameworkStatsLog
591                     .DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__EDGE_RESIZE_TRIGGER
592             ),
593             TILING_DIVIDER(
594                 FrameworkStatsLog
595                     .DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__TILING_DIVIDER_RESIZE_TRIGGER
596             ),
597             MAXIMIZE_BUTTON(
598                 FrameworkStatsLog
599                     .DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__MAXIMIZE_BUTTON_RESIZE_TRIGGER
600             ),
601             DOUBLE_TAP_APP_HEADER(
602                 FrameworkStatsLog
603                     .DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__DOUBLE_TAP_APP_HEADER_RESIZE_TRIGGER
604             ),
605             DRAG_LEFT(
606                 FrameworkStatsLog
607                     .DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__DRAG_LEFT_RESIZE_TRIGGER
608             ),
609             DRAG_RIGHT(
610                 FrameworkStatsLog
611                     .DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__DRAG_RIGHT_RESIZE_TRIGGER
612             ),
613             SNAP_LEFT_MENU(
614                 FrameworkStatsLog
615                     .DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__SNAP_LEFT_MENU_RESIZE_TRIGGER
616             ),
617             SNAP_RIGHT_MENU(
618                 FrameworkStatsLog
619                     .DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__SNAP_RIGHT_MENU_RESIZE_TRIGGER
620             ),
621             MAXIMIZE_MENU(
622                 FrameworkStatsLog
623                     .DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__MAXIMIZE_MENU_RESIZE_TRIGGER
624             ),
625             DRAG_TO_TOP_RESIZE_TRIGGER(
626                 FrameworkStatsLog
627                     .DESKTOP_MODE_TASK_SIZE_UPDATED__RESIZE_TRIGGER__DRAG_TO_TOP_RESIZE_TRIGGER
628             ),
629         }
630 
631         /**
632          * Enum InputMethod mapped to the InputMethod definition in
633          * stats/atoms/desktopmode/desktopmode_extensions_atoms.proto
634          */
635         enum class InputMethod(val method: Int) {
636             UNKNOWN_INPUT_METHOD(
637                 FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED__INPUT_METHOD__UNKNOWN_INPUT_METHOD
638             ),
639             TOUCH(
640                 FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED__INPUT_METHOD__TOUCH_INPUT_METHOD
641             ),
642             STYLUS(
643                 FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED__INPUT_METHOD__STYLUS_INPUT_METHOD
644             ),
645             MOUSE(
646                 FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED__INPUT_METHOD__MOUSE_INPUT_METHOD
647             ),
648             TOUCHPAD(
649                 FrameworkStatsLog
650                     .DESKTOP_MODE_TASK_SIZE_UPDATED__INPUT_METHOD__TOUCHPAD_INPUT_METHOD
651             ),
652             KEYBOARD(
653                 FrameworkStatsLog
654                     .DESKTOP_MODE_TASK_SIZE_UPDATED__INPUT_METHOD__KEYBOARD_INPUT_METHOD
655             ),
656         }
657 
658         private const val DESKTOP_MODE_ATOM_ID = FrameworkStatsLog.DESKTOP_MODE_UI_CHANGED
659         private const val DESKTOP_MODE_TASK_UPDATE_ATOM_ID =
660             FrameworkStatsLog.DESKTOP_MODE_SESSION_TASK_UPDATE
661         private const val DESKTOP_MODE_TASK_SIZE_UPDATED_ATOM_ID =
662             FrameworkStatsLog.DESKTOP_MODE_TASK_SIZE_UPDATED
663         @VisibleForTesting const val NO_SESSION_ID = 0
664     }
665 }
666