• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.assist
18 
19 import android.content.ComponentName
20 import android.content.Context
21 import android.content.pm.PackageManager
22 import android.util.Log
23 import com.android.internal.app.AssistUtils
24 import com.android.internal.logging.InstanceId
25 import com.android.internal.logging.InstanceIdSequence
26 import com.android.internal.logging.UiEventLogger
27 import com.android.internal.util.FrameworkStatsLog
28 import com.android.systemui.assist.AssistantInvocationEvent.Companion.deviceStateFromLegacyDeviceState
29 import com.android.systemui.assist.AssistantInvocationEvent.Companion.eventFromLegacyInvocationType
30 import com.android.systemui.dagger.SysUISingleton
31 import com.android.systemui.settings.UserTracker
32 import javax.inject.Inject
33 
34 /** Class for reporting events related to Assistant sessions. */
35 @SysUISingleton
36 open class AssistLogger @Inject constructor(
37     protected val context: Context,
38     protected val uiEventLogger: UiEventLogger,
39     private val assistUtils: AssistUtils,
40     private val phoneStateMonitor: PhoneStateMonitor,
41     private val userTracker: UserTracker,
42 ) {
43 
44     private val instanceIdSequence = InstanceIdSequence(INSTANCE_ID_MAX)
45 
46     private var currentInstanceId: InstanceId? = null
47 
reportAssistantInvocationEventFromLegacynull48     fun reportAssistantInvocationEventFromLegacy(
49         legacyInvocationType: Int,
50         isInvocationComplete: Boolean,
51         assistantComponent: ComponentName? = null,
52         legacyDeviceState: Int? = null
53     ) {
54         val deviceState = if (legacyDeviceState == null) {
55             null
56         } else {
57             deviceStateFromLegacyDeviceState(legacyDeviceState)
58         }
59         reportAssistantInvocationEvent(
60                 eventFromLegacyInvocationType(legacyInvocationType, isInvocationComplete),
61                 assistantComponent,
62                 deviceState)
63     }
64 
reportAssistantInvocationEventnull65     fun reportAssistantInvocationEvent(
66         invocationEvent: UiEventLogger.UiEventEnum,
67         assistantComponent: ComponentName? = null,
68         deviceState: Int? = null
69     ) {
70 
71         val assistComponentFinal = assistantComponent ?: getAssistantComponentForCurrentUser()
72 
73         val assistantUid = getAssistantUid(assistComponentFinal)
74 
75         val deviceStateFinal = deviceState
76                 ?: deviceStateFromLegacyDeviceState(phoneStateMonitor.phoneState)
77 
78         FrameworkStatsLog.write(
79                 FrameworkStatsLog.ASSISTANT_INVOCATION_REPORTED,
80                 invocationEvent.id,
81                 assistantUid,
82                 assistComponentFinal?.flattenToString() ?: "",
83                 getOrCreateInstanceId().id,
84                 deviceStateFinal,
85                 false)
86         reportAssistantInvocationExtraData()
87     }
88 
reportAssistantSessionEventnull89     fun reportAssistantSessionEvent(sessionEvent: UiEventLogger.UiEventEnum) {
90         val assistantComponent = getAssistantComponentForCurrentUser()
91         val assistantUid = getAssistantUid(assistantComponent)
92         uiEventLogger.logWithInstanceId(
93                 sessionEvent,
94                 assistantUid,
95                 assistantComponent?.flattenToString(),
96                 getOrCreateInstanceId())
97 
98         if (SESSION_END_EVENTS.contains(sessionEvent)) {
99             clearInstanceId()
100         }
101     }
102 
reportAssistantInvocationExtraDatanull103     protected open fun reportAssistantInvocationExtraData() {
104     }
105 
getOrCreateInstanceIdnull106     protected fun getOrCreateInstanceId(): InstanceId {
107         val instanceId = currentInstanceId ?: instanceIdSequence.newInstanceId()
108         currentInstanceId = instanceId
109         return instanceId
110     }
111 
clearInstanceIdnull112     protected fun clearInstanceId() {
113         currentInstanceId = null
114     }
115 
getAssistantComponentForCurrentUsernull116     protected fun getAssistantComponentForCurrentUser(): ComponentName? {
117         return assistUtils.getAssistComponentForUser(userTracker.userId)
118     }
119 
getAssistantUidnull120     protected fun getAssistantUid(assistantComponent: ComponentName?): Int {
121         if (assistantComponent == null) {
122             return 0
123         }
124 
125         var assistantUid = 0
126         try {
127             assistantUid = context.packageManager.getApplicationInfo(
128                     assistantComponent.packageName, /* flags = */
129                     0).uid
130         } catch (e: PackageManager.NameNotFoundException) {
131             Log.e(TAG, "Unable to find Assistant UID", e)
132         }
133         return assistantUid
134     }
135 
136     companion object {
137         protected const val TAG = "AssistLogger"
138 
139         private const val INSTANCE_ID_MAX = 1 shl 20
140 
141         private val SESSION_END_EVENTS =
142                 setOf(
143                         AssistantSessionEvent.ASSISTANT_SESSION_INVOCATION_CANCELLED,
144                         AssistantSessionEvent.ASSISTANT_SESSION_CLOSE)
145     }
146 }
147