• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.systemui.media.controls.util
18 
19 import com.android.internal.logging.InstanceId
20 import com.android.internal.logging.InstanceIdSequence
21 import com.android.internal.logging.UiEvent
22 import com.android.internal.logging.UiEventLogger
23 import com.android.systemui.dagger.SysUISingleton
24 import com.android.systemui.media.controls.shared.model.MediaData
25 import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
26 import com.android.systemui.media.controls.ui.controller.MediaLocation
27 import com.android.systemui.res.R
28 import java.lang.IllegalArgumentException
29 import javax.inject.Inject
30 
31 private const val INSTANCE_ID_MAX = 1 shl 20
32 
33 /** A helper class to log events related to the media controls */
34 @SysUISingleton
35 class MediaUiEventLogger @Inject constructor(private val logger: UiEventLogger) {
36 
37     private val instanceIdSequence = InstanceIdSequence(INSTANCE_ID_MAX)
38 
39     /** Get a new instance ID for a new media control */
getNewInstanceIdnull40     fun getNewInstanceId(): InstanceId {
41         return instanceIdSequence.newInstanceId()
42     }
43 
logActiveMediaAddednull44     fun logActiveMediaAdded(
45         uid: Int,
46         packageName: String,
47         instanceId: InstanceId,
48         playbackLocation: Int,
49     ) {
50         val event =
51             when (playbackLocation) {
52                 MediaData.PLAYBACK_LOCAL -> MediaUiEvent.LOCAL_MEDIA_ADDED
53                 MediaData.PLAYBACK_CAST_LOCAL -> MediaUiEvent.CAST_MEDIA_ADDED
54                 MediaData.PLAYBACK_CAST_REMOTE -> MediaUiEvent.REMOTE_MEDIA_ADDED
55                 else -> throw IllegalArgumentException("Unknown playback location")
56             }
57         logger.logWithInstanceId(event, uid, packageName, instanceId)
58     }
59 
logPlaybackLocationChangenull60     fun logPlaybackLocationChange(
61         uid: Int,
62         packageName: String,
63         instanceId: InstanceId,
64         playbackLocation: Int,
65     ) {
66         val event =
67             when (playbackLocation) {
68                 MediaData.PLAYBACK_LOCAL -> MediaUiEvent.TRANSFER_TO_LOCAL
69                 MediaData.PLAYBACK_CAST_LOCAL -> MediaUiEvent.TRANSFER_TO_CAST
70                 MediaData.PLAYBACK_CAST_REMOTE -> MediaUiEvent.TRANSFER_TO_REMOTE
71                 else -> throw IllegalArgumentException("Unknown playback location")
72             }
73         logger.logWithInstanceId(event, uid, packageName, instanceId)
74     }
75 
logResumeMediaAddednull76     fun logResumeMediaAdded(uid: Int, packageName: String, instanceId: InstanceId) {
77         logger.logWithInstanceId(MediaUiEvent.RESUME_MEDIA_ADDED, uid, packageName, instanceId)
78     }
79 
logActiveConvertedToResumenull80     fun logActiveConvertedToResume(uid: Int, packageName: String, instanceId: InstanceId) {
81         logger.logWithInstanceId(MediaUiEvent.ACTIVE_TO_RESUME, uid, packageName, instanceId)
82     }
83 
logMediaTimeoutnull84     fun logMediaTimeout(uid: Int, packageName: String, instanceId: InstanceId) {
85         logger.logWithInstanceId(MediaUiEvent.MEDIA_TIMEOUT, uid, packageName, instanceId)
86     }
87 
logMediaRemovednull88     fun logMediaRemoved(uid: Int, packageName: String, instanceId: InstanceId) {
89         logger.logWithInstanceId(MediaUiEvent.MEDIA_REMOVED, uid, packageName, instanceId)
90     }
91 
logMediaCarouselPagenull92     fun logMediaCarouselPage(position: Int) {
93         // Since this operation is on the carousel, we don't include package information
94         logger.logWithPosition(MediaUiEvent.CAROUSEL_PAGE, 0, null, position)
95     }
96 
logSwipeDismissnull97     fun logSwipeDismiss() {
98         // Since this operation is on the carousel, we don't include package information
99         logger.log(MediaUiEvent.DISMISS_SWIPE)
100     }
101 
logLongPressOpennull102     fun logLongPressOpen(uid: Int, packageName: String, instanceId: InstanceId?) {
103         logger.logWithInstanceId(MediaUiEvent.OPEN_LONG_PRESS, uid, packageName, instanceId)
104     }
105 
logLongPressDismissnull106     fun logLongPressDismiss(uid: Int, packageName: String, instanceId: InstanceId?) {
107         logger.logWithInstanceId(MediaUiEvent.DISMISS_LONG_PRESS, uid, packageName, instanceId)
108     }
109 
logLongPressSettingsnull110     fun logLongPressSettings(uid: Int, packageName: String, instanceId: InstanceId?) {
111         logger.logWithInstanceId(
112             MediaUiEvent.OPEN_SETTINGS_LONG_PRESS,
113             uid,
114             packageName,
115             instanceId,
116         )
117     }
118 
logCarouselSettingsnull119     fun logCarouselSettings() {
120         // Since this operation is on the carousel, we don't include package information
121         logger.log(MediaUiEvent.OPEN_SETTINGS_CAROUSEL)
122     }
123 
logTapActionnull124     fun logTapAction(buttonId: Int, uid: Int, packageName: String, instanceId: InstanceId) {
125         val event =
126             when (buttonId) {
127                 R.id.actionPlayPause -> MediaUiEvent.TAP_ACTION_PLAY_PAUSE
128                 R.id.actionPrev -> MediaUiEvent.TAP_ACTION_PREV
129                 R.id.actionNext -> MediaUiEvent.TAP_ACTION_NEXT
130                 else -> MediaUiEvent.TAP_ACTION_OTHER
131             }
132 
133         logger.logWithInstanceId(event, uid, packageName, instanceId)
134     }
135 
logSeeknull136     fun logSeek(uid: Int, packageName: String, instanceId: InstanceId) {
137         logger.logWithInstanceId(MediaUiEvent.ACTION_SEEK, uid, packageName, instanceId)
138     }
139 
logOpenOutputSwitchernull140     fun logOpenOutputSwitcher(uid: Int, packageName: String, instanceId: InstanceId) {
141         logger.logWithInstanceId(MediaUiEvent.OPEN_OUTPUT_SWITCHER, uid, packageName, instanceId)
142     }
143 
logTapContentViewnull144     fun logTapContentView(uid: Int, packageName: String, instanceId: InstanceId) {
145         logger.logWithInstanceId(MediaUiEvent.MEDIA_TAP_CONTENT_VIEW, uid, packageName, instanceId)
146     }
147 
logCarouselPositionnull148     fun logCarouselPosition(@MediaLocation location: Int) {
149         val event =
150             when (location) {
151                 MediaHierarchyManager.LOCATION_QQS -> MediaUiEvent.MEDIA_CAROUSEL_LOCATION_QQS
152                 MediaHierarchyManager.LOCATION_QS -> MediaUiEvent.MEDIA_CAROUSEL_LOCATION_QS
153                 MediaHierarchyManager.LOCATION_LOCKSCREEN ->
154                     MediaUiEvent.MEDIA_CAROUSEL_LOCATION_LOCKSCREEN
155                 MediaHierarchyManager.LOCATION_DREAM_OVERLAY ->
156                     MediaUiEvent.MEDIA_CAROUSEL_LOCATION_DREAM
157                 MediaHierarchyManager.LOCATION_COMMUNAL_HUB ->
158                     MediaUiEvent.MEDIA_CAROUSEL_LOCATION_COMMUNAL
159                 MediaHierarchyManager.LOCATION_STATUS_BAR_POPUP ->
160                     MediaUiEvent.MEDIA_CAROUSEL_LOCATION_STATUS_BAR_POPUP
161                 else -> throw IllegalArgumentException("Unknown media carousel location $location")
162             }
163         logger.log(event)
164     }
165 
logRecommendationAddednull166     fun logRecommendationAdded(packageName: String, instanceId: InstanceId?) {
167         logger.logWithInstanceId(
168             MediaUiEvent.MEDIA_RECOMMENDATION_ADDED,
169             0,
170             packageName,
171             instanceId,
172         )
173     }
174 
logRecommendationRemovednull175     fun logRecommendationRemoved(packageName: String, instanceId: InstanceId?) {
176         logger.logWithInstanceId(
177             MediaUiEvent.MEDIA_RECOMMENDATION_REMOVED,
178             0,
179             packageName,
180             instanceId,
181         )
182     }
183 
logRecommendationActivatednull184     fun logRecommendationActivated(uid: Int, packageName: String, instanceId: InstanceId) {
185         logger.logWithInstanceId(
186             MediaUiEvent.MEDIA_RECOMMENDATION_ACTIVATED,
187             uid,
188             packageName,
189             instanceId,
190         )
191     }
192 
logRecommendationItemTapnull193     fun logRecommendationItemTap(packageName: String, instanceId: InstanceId?, position: Int) {
194         logger.logWithInstanceIdAndPosition(
195             MediaUiEvent.MEDIA_RECOMMENDATION_ITEM_TAP,
196             0,
197             packageName,
198             instanceId,
199             position,
200         )
201     }
202 
logRecommendationCardTapnull203     fun logRecommendationCardTap(packageName: String, instanceId: InstanceId?) {
204         logger.logWithInstanceId(
205             MediaUiEvent.MEDIA_RECOMMENDATION_CARD_TAP,
206             0,
207             packageName,
208             instanceId,
209         )
210     }
211 
logOpenBroadcastDialognull212     fun logOpenBroadcastDialog(uid: Int, packageName: String, instanceId: InstanceId) {
213         logger.logWithInstanceId(
214             MediaUiEvent.MEDIA_OPEN_BROADCAST_DIALOG,
215             uid,
216             packageName,
217             instanceId,
218         )
219     }
220 
logSingleMediaPlayerInCarouselnull221     fun logSingleMediaPlayerInCarousel(uid: Int, packageName: String, instanceId: InstanceId) {
222         logger.logWithInstanceId(
223             MediaUiEvent.MEDIA_CAROUSEL_SINGLE_PLAYER,
224             uid,
225             packageName,
226             instanceId,
227         )
228     }
229 
logMultipleMediaPlayersInCarouselnull230     fun logMultipleMediaPlayersInCarousel(uid: Int, packageName: String, instanceId: InstanceId) {
231         logger.logWithInstanceId(
232             MediaUiEvent.MEDIA_CAROUSEL_MULTIPLE_PLAYERS,
233             uid,
234             packageName,
235             instanceId,
236         )
237     }
238 }
239 
240 enum class MediaUiEvent(val metricId: Int) : UiEventLogger.UiEventEnum {
241     @UiEvent(doc = "A new media control was added for media playing locally on the device")
242     LOCAL_MEDIA_ADDED(1029),
243     @UiEvent(doc = "A new media control was added for media cast from the device")
244     CAST_MEDIA_ADDED(1030),
245     @UiEvent(doc = "A new media control was added for media playing remotely")
246     REMOTE_MEDIA_ADDED(1031),
247     @UiEvent(doc = "The media for an existing control was transferred to local playback")
248     TRANSFER_TO_LOCAL(1032),
249     @UiEvent(doc = "The media for an existing control was transferred to a cast device")
250     TRANSFER_TO_CAST(1033),
251     @UiEvent(doc = "The media for an existing control was transferred to a remote device")
252     TRANSFER_TO_REMOTE(1034),
253     @UiEvent(doc = "A new resumable media control was added") RESUME_MEDIA_ADDED(1013),
254     @UiEvent(doc = "An existing active media control was converted into resumable media")
255     ACTIVE_TO_RESUME(1014),
256     @UiEvent(doc = "A media control timed out") MEDIA_TIMEOUT(1015),
257     @UiEvent(doc = "A media control was removed from the carousel") MEDIA_REMOVED(1016),
258     @UiEvent(doc = "User swiped to another control within the media carousel") CAROUSEL_PAGE(1017),
259     @UiEvent(doc = "The user swiped away the media carousel") DISMISS_SWIPE(1018),
260     @UiEvent(doc = "The user long pressed on a media control") OPEN_LONG_PRESS(1019),
261     @UiEvent(doc = "The user dismissed a media control via its long press menu")
262     DISMISS_LONG_PRESS(1020),
263     @UiEvent(doc = "The user opened media settings from a media control's long press menu")
264     OPEN_SETTINGS_LONG_PRESS(1021),
265     @UiEvent(doc = "The user opened media settings from the media carousel")
266     OPEN_SETTINGS_CAROUSEL(1022),
267     @UiEvent(doc = "The play/pause button on a media control was tapped")
268     TAP_ACTION_PLAY_PAUSE(1023),
269     @UiEvent(doc = "The previous button on a media control was tapped") TAP_ACTION_PREV(1024),
270     @UiEvent(doc = "The next button on a media control was tapped") TAP_ACTION_NEXT(1025),
271     @UiEvent(doc = "A custom or generic action button on a media control was tapped")
272     TAP_ACTION_OTHER(1026),
273     @UiEvent(doc = "The user seeked on a media control using the seekbar") ACTION_SEEK(1027),
274     @UiEvent(doc = "The user opened the output switcher from a media control")
275     OPEN_OUTPUT_SWITCHER(1028),
276     @UiEvent(doc = "The user tapped on a media control view") MEDIA_TAP_CONTENT_VIEW(1036),
277     @UiEvent(doc = "The media carousel moved to QQS") MEDIA_CAROUSEL_LOCATION_QQS(1037),
278     @UiEvent(doc = "THe media carousel moved to QS") MEDIA_CAROUSEL_LOCATION_QS(1038),
279     @UiEvent(doc = "The media carousel moved to the lockscreen")
280     MEDIA_CAROUSEL_LOCATION_LOCKSCREEN(1039),
281     @UiEvent(doc = "The media carousel moved to the dream state")
282     MEDIA_CAROUSEL_LOCATION_DREAM(1040),
283     @UiEvent(doc = "The media carousel moved to the communal hub UI")
284     MEDIA_CAROUSEL_LOCATION_COMMUNAL(1520),
285     @UiEvent(doc = "The media carousel moved to the status bar popup")
286     MEDIA_CAROUSEL_LOCATION_STATUS_BAR_POPUP(2170),
287     @UiEvent(doc = "A media recommendation card was added to the media carousel")
288     MEDIA_RECOMMENDATION_ADDED(1041),
289     @UiEvent(doc = "A media recommendation card was removed from the media carousel")
290     MEDIA_RECOMMENDATION_REMOVED(1042),
291     @UiEvent(doc = "An existing media control was made active as a recommendation")
292     MEDIA_RECOMMENDATION_ACTIVATED(1043),
293     @UiEvent(doc = "User tapped on an item in a media recommendation card")
294     MEDIA_RECOMMENDATION_ITEM_TAP(1044),
295     @UiEvent(doc = "User tapped on a media recommendation card")
296     MEDIA_RECOMMENDATION_CARD_TAP(1045),
297     @UiEvent(doc = "User opened the broadcast dialog from a media control")
298     MEDIA_OPEN_BROADCAST_DIALOG(1079),
299     @UiEvent(doc = "The media carousel contains one media player card")
300     MEDIA_CAROUSEL_SINGLE_PLAYER(1244),
301     @UiEvent(doc = "The media carousel contains multiple media player cards")
302     MEDIA_CAROUSEL_MULTIPLE_PLAYERS(1245);
303 
getIdnull304     override fun getId() = metricId
305 }
306