1 /*
2  * Copyright (C) 2023 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.wm.shell.common.pip
17 
18 import android.app.TaskInfo
19 import android.content.pm.PackageManager
20 import com.android.internal.logging.UiEvent
21 import com.android.internal.logging.UiEventLogger
22 
23 /**
24  * Helper class that ends PiP log to UiEvent, see also go/uievent
25  */
26 class PipUiEventLogger(
27     private val mUiEventLogger: UiEventLogger,
28     private val mPackageManager: PackageManager
29 ) {
30     private var mPackageName: String? = null
31     private var mPackageUid = INVALID_PACKAGE_UID
setTaskInfonull32     fun setTaskInfo(taskInfo: TaskInfo?) {
33         if (taskInfo?.topActivity != null) {
34             // safe because topActivity is guaranteed non-null here
35             mPackageName = taskInfo.topActivity!!.packageName
36             mPackageUid = getUid(mPackageName!!, taskInfo.userId)
37         } else {
38             mPackageName = null
39             mPackageUid = INVALID_PACKAGE_UID
40         }
41     }
42 
43     /**
44      * Sends log via UiEvent, reference go/uievent for how to debug locally
45      */
lognull46     fun log(event: PipUiEventEnum?) {
47         if (mPackageName == null || mPackageUid == INVALID_PACKAGE_UID) {
48             return
49         }
50         mUiEventLogger.log(event!!, mPackageUid, mPackageName)
51     }
52 
getUidnull53     private fun getUid(packageName: String, userId: Int): Int {
54         var uid = INVALID_PACKAGE_UID
55         try {
56             uid = mPackageManager.getApplicationInfoAsUser(
57                 packageName, 0 /* ApplicationInfoFlags */, userId
58             ).uid
59         } catch (e: PackageManager.NameNotFoundException) {
60             // do nothing.
61         }
62         return uid
63     }
64 
65     /**
66      * Enums for logging the PiP events to UiEvent
67      */
68     enum class PipUiEventEnum(private val mId: Int) : UiEventLogger.UiEventEnum {
69         @UiEvent(doc = "Activity enters picture-in-picture mode")
70         PICTURE_IN_PICTURE_ENTER(603),
71 
72         @UiEvent(doc = "Activity enters picture-in-picture mode with auto-enter-pip API")
73         PICTURE_IN_PICTURE_AUTO_ENTER(1313),
74 
75         @UiEvent(doc = "Activity enters picture-in-picture mode from content-pip API")
76         PICTURE_IN_PICTURE_ENTER_CONTENT_PIP(1314),
77 
78         @UiEvent(doc = "Expands from picture-in-picture to fullscreen")
79         PICTURE_IN_PICTURE_EXPAND_TO_FULLSCREEN(604),
80 
81         @UiEvent(doc = "Removes picture-in-picture by tap close button")
82         PICTURE_IN_PICTURE_TAP_TO_REMOVE(605),
83 
84         @UiEvent(doc = "Removes picture-in-picture by drag to dismiss area")
85         PICTURE_IN_PICTURE_DRAG_TO_REMOVE(606),
86 
87         @UiEvent(doc = "Shows picture-in-picture menu")
88         PICTURE_IN_PICTURE_SHOW_MENU(607),
89 
90         @UiEvent(doc = "Hides picture-in-picture menu")
91         PICTURE_IN_PICTURE_HIDE_MENU(608),
92 
93         @UiEvent(
94             doc = "Changes the aspect ratio of picture-in-picture window. This is inherited" +
95                     " from previous Tron-based logging and currently not in use."
96         )
97         PICTURE_IN_PICTURE_CHANGE_ASPECT_RATIO(609),
98 
99         @UiEvent(doc = "User resize of the picture-in-picture window")
100         PICTURE_IN_PICTURE_RESIZE(610),
101 
102         @UiEvent(doc = "User unstashed picture-in-picture")
103         PICTURE_IN_PICTURE_STASH_UNSTASHED(709),
104 
105         @UiEvent(doc = "User stashed picture-in-picture to the left side")
106         PICTURE_IN_PICTURE_STASH_LEFT(710),
107 
108         @UiEvent(doc = "User stashed picture-in-picture to the right side")
109         PICTURE_IN_PICTURE_STASH_RIGHT(711),
110 
111         @UiEvent(doc = "User taps on the settings button in PiP menu")
112         PICTURE_IN_PICTURE_SHOW_SETTINGS(933),
113 
114         @UiEvent(doc = "Closes PiP with app-provided close action")
115         PICTURE_IN_PICTURE_CUSTOM_CLOSE(1058);
116 
getIdnull117         override fun getId(): Int {
118             return mId
119         }
120     }
121 
122     companion object {
123         private const val INVALID_PACKAGE_UID = -1
124     }
125 }