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.systemui.mediaprojection
17 
18 import android.media.projection.IMediaProjectionManager
19 import android.os.RemoteException
20 import android.util.Log
21 import com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_APP as METRICS_CREATION_SOURCE_APP
22 import com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_CAST as METRICS_CREATION_SOURCE_CAST
23 import com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_SYSTEM_UI_SCREEN_RECORDER as METRICS_CREATION_SOURCE_SYSTEM_UI_SCREEN_RECORDER
24 import com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_UNKNOWN as METRICS_CREATION_SOURCE_UNKNOWN
25 import com.android.systemui.dagger.SysUISingleton
26 import javax.inject.Inject
27 
28 /**
29  * Helper class for requesting that the server emit logs describing the MediaProjection setup
30  * experience.
31  */
32 @SysUISingleton
33 class MediaProjectionMetricsLogger
34 @Inject
35 constructor(private val service: IMediaProjectionManager) {
36 
37     /**
38      * Request to log that the permission was requested.
39      *
40      * @param hostUid The UID of the package that initiates MediaProjection.
41      * @param sessionCreationSource The entry point requesting permission to capture.
42      */
notifyProjectionInitiatednull43     fun notifyProjectionInitiated(hostUid: Int, sessionCreationSource: SessionCreationSource) {
44         try {
45             service.notifyPermissionRequestInitiated(
46                 hostUid,
47                 sessionCreationSource.toMetricsConstant()
48             )
49         } catch (e: RemoteException) {
50             Log.e(TAG, "Error notifying server of projection initiated", e)
51         }
52     }
53 
54     /**
55      * Request to log that the permission request was displayed.
56      *
57      * @param hostUid The UID of the package that initiates MediaProjection.
58      */
notifyPermissionRequestDisplayednull59     fun notifyPermissionRequestDisplayed(hostUid: Int) {
60         try {
61             service.notifyPermissionRequestDisplayed(hostUid)
62         } catch (e: RemoteException) {
63             Log.e(TAG, "Error notifying server of projection displayed", e)
64         }
65     }
66 
67     /**
68      * Request to log that the permission request was cancelled.
69      *
70      * @param hostUid The UID of the package that initiates MediaProjection.
71      */
notifyProjectionRequestCancellednull72     fun notifyProjectionRequestCancelled(hostUid: Int) {
73         try {
74             service.notifyPermissionRequestCancelled(hostUid)
75         } catch (e: RemoteException) {
76             Log.e(TAG, "Error notifying server of projection cancelled", e)
77         }
78     }
79 
80     /**
81      * Request to log that the app selector was displayed.
82      *
83      * @param hostUid The UID of the package that initiates MediaProjection.
84      */
notifyAppSelectorDisplayednull85     fun notifyAppSelectorDisplayed(hostUid: Int) {
86         try {
87             service.notifyAppSelectorDisplayed(hostUid)
88         } catch (e: RemoteException) {
89             Log.e(TAG, "Error notifying server of app selector displayed", e)
90         }
91     }
92 
93     companion object {
94         const val TAG = "MediaProjectionMetricsLogger"
95     }
96 }
97 
98 enum class SessionCreationSource {
99     APP,
100     CAST,
101     SYSTEM_UI_SCREEN_RECORDER,
102     UNKNOWN;
103 
toMetricsConstantnull104     fun toMetricsConstant(): Int =
105         when (this) {
106             APP -> METRICS_CREATION_SOURCE_APP
107             CAST -> METRICS_CREATION_SOURCE_CAST
108             SYSTEM_UI_SCREEN_RECORDER -> METRICS_CREATION_SOURCE_SYSTEM_UI_SCREEN_RECORDER
109             UNKNOWN -> METRICS_CREATION_SOURCE_UNKNOWN
110         }
111 }
112