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 com.android.systemui.dagger.SysUISingleton 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 ) { 42 43 private val instanceIdSequence = InstanceIdSequence(INSTANCE_ID_MAX) 44 45 private var currentInstanceId: InstanceId? = null 46 reportAssistantInvocationEventFromLegacynull47 fun reportAssistantInvocationEventFromLegacy( 48 legacyInvocationType: Int, 49 isInvocationComplete: Boolean, 50 assistantComponent: ComponentName? = null, 51 legacyDeviceState: Int? = null 52 ) { 53 val deviceState = if (legacyDeviceState == null) { 54 null 55 } else { 56 deviceStateFromLegacyDeviceState(legacyDeviceState) 57 } 58 reportAssistantInvocationEvent( 59 eventFromLegacyInvocationType(legacyInvocationType, isInvocationComplete), 60 assistantComponent, 61 deviceState) 62 } 63 reportAssistantInvocationEventnull64 fun reportAssistantInvocationEvent( 65 invocationEvent: UiEventLogger.UiEventEnum, 66 assistantComponent: ComponentName? = null, 67 deviceState: Int? = null 68 ) { 69 70 val assistComponentFinal = assistantComponent ?: getAssistantComponentForCurrentUser() 71 72 val assistantUid = getAssistantUid(assistComponentFinal) 73 74 val deviceStateFinal = deviceState 75 ?: deviceStateFromLegacyDeviceState(phoneStateMonitor.phoneState) 76 77 FrameworkStatsLog.write( 78 FrameworkStatsLog.ASSISTANT_INVOCATION_REPORTED, 79 invocationEvent.id, 80 assistantUid, 81 assistComponentFinal.flattenToString(), 82 getOrCreateInstanceId().id, 83 deviceStateFinal, 84 false) 85 reportAssistantInvocationExtraData() 86 } 87 reportAssistantSessionEventnull88 fun reportAssistantSessionEvent(sessionEvent: UiEventLogger.UiEventEnum) { 89 val assistantComponent = getAssistantComponentForCurrentUser() 90 val assistantUid = getAssistantUid(assistantComponent) 91 uiEventLogger.logWithInstanceId( 92 sessionEvent, 93 assistantUid, 94 assistantComponent.flattenToString(), 95 getOrCreateInstanceId()) 96 97 if (SESSION_END_EVENTS.contains(sessionEvent)) { 98 clearInstanceId() 99 } 100 } 101 reportAssistantInvocationExtraDatanull102 protected open fun reportAssistantInvocationExtraData() { 103 } 104 getOrCreateInstanceIdnull105 protected fun getOrCreateInstanceId(): InstanceId { 106 val instanceId = currentInstanceId ?: instanceIdSequence.newInstanceId() 107 currentInstanceId = instanceId 108 return instanceId 109 } 110 clearInstanceIdnull111 protected fun clearInstanceId() { 112 currentInstanceId = null 113 } 114 getAssistantComponentForCurrentUsernull115 protected fun getAssistantComponentForCurrentUser(): ComponentName { 116 return assistUtils.getAssistComponentForUser(KeyguardUpdateMonitor.getCurrentUser()) 117 } 118 getAssistantUidnull119 protected fun getAssistantUid(assistantComponent: ComponentName): Int { 120 var assistantUid = 0 121 try { 122 assistantUid = context.packageManager.getApplicationInfo( 123 assistantComponent.packageName, /* flags = */ 124 0).uid 125 } catch (e: PackageManager.NameNotFoundException) { 126 Log.e(TAG, "Unable to find Assistant UID", e) 127 } 128 return assistantUid 129 } 130 131 companion object { 132 protected const val TAG = "AssistLogger" 133 134 private const val INSTANCE_ID_MAX = 1 shl 20 135 136 private val SESSION_END_EVENTS = 137 setOf( 138 AssistantSessionEvent.ASSISTANT_SESSION_INVOCATION_CANCELLED, 139 AssistantSessionEvent.ASSISTANT_SESSION_CLOSE) 140 } 141 }