1 /*
2  * Copyright (C) 2021 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.qs.external
18 
19 import android.app.StatusBarManager
20 import androidx.annotation.VisibleForTesting
21 import com.android.internal.logging.InstanceId
22 import com.android.internal.logging.InstanceIdSequence
23 import com.android.internal.logging.UiEvent
24 import com.android.internal.logging.UiEventLogger
25 import com.android.internal.logging.UiEventLoggerImpl
26 
27 class TileRequestDialogEventLogger @VisibleForTesting constructor(
28     private val uiEventLogger: UiEventLogger,
29     private val instanceIdSequence: InstanceIdSequence
30 ) {
31     companion object {
32         const val MAX_INSTANCE_ID = 1 shl 20
33     }
34 
35     constructor() : this(UiEventLoggerImpl(), InstanceIdSequence(MAX_INSTANCE_ID))
36 
37     /**
38      * Obtain a new [InstanceId] to log a session for a dialog request.
39      */
newInstanceIdnull40     fun newInstanceId(): InstanceId = instanceIdSequence.newInstanceId()
41 
42     /**
43      * Log that the dialog has been shown to the user for a tile in the given [packageName]. This
44      * call should use a new [instanceId].
45      */
46     fun logDialogShown(packageName: String, instanceId: InstanceId) {
47         uiEventLogger.logWithInstanceId(
48                 TileRequestDialogEvent.TILE_REQUEST_DIALOG_SHOWN,
49                 /* uid */ 0,
50                 packageName,
51                 instanceId
52         )
53     }
54 
55     /**
56      * Log the user response to the dialog being shown. Must follow a call to [logDialogShown] that
57      * used the same [packageName] and [instanceId]. Only the following responses are valid:
58      * * [StatusBarManager.TILE_ADD_REQUEST_RESULT_DIALOG_DISMISSED]
59      * * [StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_NOT_ADDED]
60      * * [StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ADDED]
61      */
logUserResponsenull62     fun logUserResponse(
63         @StatusBarManager.RequestResult response: Int,
64         packageName: String,
65         instanceId: InstanceId
66     ) {
67         val event = when (response) {
68             StatusBarManager.TILE_ADD_REQUEST_RESULT_DIALOG_DISMISSED -> {
69                 TileRequestDialogEvent.TILE_REQUEST_DIALOG_DISMISSED
70             }
71             StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_NOT_ADDED -> {
72                 TileRequestDialogEvent.TILE_REQUEST_DIALOG_TILE_NOT_ADDED
73             }
74             StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ADDED -> {
75                 TileRequestDialogEvent.TILE_REQUEST_DIALOG_TILE_ADDED
76             }
77             else -> {
78                 throw IllegalArgumentException("User response not valid: $response")
79             }
80         }
81         uiEventLogger.logWithInstanceId(event, /* uid */ 0, packageName, instanceId)
82     }
83 
84     /**
85      * Log that the dialog will not be shown because the tile was already part of the active set.
86      * Corresponds to a response of [StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ALREADY_ADDED].
87      */
logTileAlreadyAddednull88     fun logTileAlreadyAdded(packageName: String, instanceId: InstanceId) {
89         uiEventLogger.logWithInstanceId(
90                 TileRequestDialogEvent.TILE_REQUEST_DIALOG_TILE_ALREADY_ADDED,
91                 /* uid */ 0,
92                 packageName,
93                 instanceId
94         )
95     }
96 }
97 
98 enum class TileRequestDialogEvent(private val _id: Int) : UiEventLogger.UiEventEnum {
99 
100     @UiEvent(doc = "Tile request dialog not shown because tile is already added.")
101     TILE_REQUEST_DIALOG_TILE_ALREADY_ADDED(917),
102 
103     @UiEvent(doc = "Tile request dialog shown to user.")
104     TILE_REQUEST_DIALOG_SHOWN(918),
105 
106     @UiEvent(doc = "User dismisses dialog without choosing an option.")
107     TILE_REQUEST_DIALOG_DISMISSED(919),
108 
109     @UiEvent(doc = "User accepts adding tile from dialog.")
110     TILE_REQUEST_DIALOG_TILE_ADDED(920),
111 
112     @UiEvent(doc = "User denies adding tile from dialog.")
113     TILE_REQUEST_DIALOG_TILE_NOT_ADDED(921);
114 
getIdnull115     override fun getId() = _id
116 }