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.keyguard.KeyguardUpdateMonitor 29 import com.android.systemui.assist.AssistantInvocationEvent.Companion.deviceStateFromLegacyDeviceState 30 import com.android.systemui.assist.AssistantInvocationEvent.Companion.eventFromLegacyInvocationType 31 import javax.inject.Inject 32 import javax.inject.Singleton 33 34 /** Class for reporting events related to Assistant sessions. */ 35 @Singleton 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 assistHandleBehaviorController: AssistHandleBehaviorController 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 assistHandleBehaviorController.areHandlesShowing()) 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(KeyguardUpdateMonitor.getCurrentUser()) 118 } 119 getAssistantUidnull120 protected fun getAssistantUid(assistantComponent: ComponentName): Int { 121 var assistantUid = 0 122 try { 123 assistantUid = context.packageManager.getApplicationInfo( 124 assistantComponent.packageName, /* flags = */ 125 0).uid 126 } catch (e: PackageManager.NameNotFoundException) { 127 Log.e(TAG, "Unable to find Assistant UID", e) 128 } 129 return assistantUid 130 } 131 132 companion object { 133 protected const val TAG = "AssistLogger" 134 135 private const val INSTANCE_ID_MAX = 1 shl 20 136 137 private val SESSION_END_EVENTS = 138 setOf( 139 AssistantSessionEvent.ASSISTANT_SESSION_INVOCATION_CANCELLED, 140 AssistantSessionEvent.ASSISTANT_SESSION_CLOSE) 141 } 142 }