diff options
7 files changed, 272 insertions, 66 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java index 525e98971266..7ae3e73caa23 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistHandleBehaviorController.java @@ -164,7 +164,7 @@ public final class AssistHandleBehaviorController implements AssistHandleCallbac return Long.max(mShowAndGoEndsAt - SystemClock.elapsedRealtime(), 0); } - boolean areHandlesShowing() { + public boolean areHandlesShowing() { return mHandlesShowing; } diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistLogger.kt b/packages/SystemUI/src/com/android/systemui/assist/AssistLogger.kt new file mode 100644 index 000000000000..e65139275685 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistLogger.kt @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.assist + +import android.content.ComponentName +import android.content.Context +import android.content.pm.PackageManager +import android.util.Log +import com.android.internal.app.AssistUtils +import com.android.internal.logging.InstanceId +import com.android.internal.logging.InstanceIdSequence +import com.android.internal.logging.UiEventLogger +import com.android.internal.util.FrameworkStatsLog +import com.android.keyguard.KeyguardUpdateMonitor +import com.android.systemui.assist.AssistantInvocationEvent.Companion.deviceStateFromLegacyDeviceState +import com.android.systemui.assist.AssistantInvocationEvent.Companion.eventFromLegacyInvocationType +import javax.inject.Inject +import javax.inject.Singleton + +/** Class for reporting events related to Assistant sessions. */ +@Singleton +open class AssistLogger @Inject constructor( + protected val context: Context, + protected val uiEventLogger: UiEventLogger, + private val assistUtils: AssistUtils, + private val phoneStateMonitor: PhoneStateMonitor, + private val assistHandleBehaviorController: AssistHandleBehaviorController +) { + + private val instanceIdSequence = InstanceIdSequence(INSTANCE_ID_MAX) + + private var currentInstanceId: InstanceId? = null + + fun reportAssistantInvocationEventFromLegacy( + legacyInvocationType: Int, + isInvocationComplete: Boolean, + assistantComponent: ComponentName? = null, + legacyDeviceState: Int? = null + ) { + val deviceState = if (legacyDeviceState == null) { + null + } else { + deviceStateFromLegacyDeviceState(legacyDeviceState) + } + reportAssistantInvocationEvent( + eventFromLegacyInvocationType(legacyInvocationType, isInvocationComplete), + assistantComponent, + deviceState) + } + + fun reportAssistantInvocationEvent( + invocationEvent: AssistantInvocationEvent, + assistantComponent: ComponentName? = null, + deviceState: Int? = null + ) { + + val assistComponentFinal = assistantComponent ?: getAssistantComponentForCurrentUser() + + val assistantUid = getAssistantUid(assistComponentFinal) + + val deviceStateFinal = deviceState + ?: deviceStateFromLegacyDeviceState(phoneStateMonitor.phoneState) + + FrameworkStatsLog.write( + FrameworkStatsLog.ASSISTANT_INVOCATION_REPORTED, + invocationEvent.id, + assistantUid, + assistComponentFinal.flattenToString(), + getOrCreateInstanceId().id, + deviceStateFinal, + assistHandleBehaviorController.areHandlesShowing()) + reportAssistantInvocationExtraData() + } + + fun reportAssistantSessionEvent(sessionEvent: AssistantSessionEvent) { + val assistantComponent = getAssistantComponentForCurrentUser() + val assistantUid = getAssistantUid(assistantComponent) + uiEventLogger.logWithInstanceId( + sessionEvent, + assistantUid, + assistantComponent.flattenToString(), + getOrCreateInstanceId()) + + if (SESSION_END_EVENTS.contains(sessionEvent)) { + clearInstanceId() + } + } + + protected open fun reportAssistantInvocationExtraData() { + } + + protected fun getOrCreateInstanceId(): InstanceId { + val instanceId = currentInstanceId ?: instanceIdSequence.newInstanceId() + currentInstanceId = instanceId + return instanceId + } + + protected fun clearInstanceId() { + currentInstanceId = null + } + + protected fun getAssistantComponentForCurrentUser(): ComponentName { + return assistUtils.getAssistComponentForUser(KeyguardUpdateMonitor.getCurrentUser()) + } + + protected fun getAssistantUid(assistantComponent: ComponentName): Int { + var assistantUid = 0 + try { + assistantUid = context.packageManager.getApplicationInfo( + assistantComponent.packageName, /* flags = */ + 0).uid + } catch (e: PackageManager.NameNotFoundException) { + Log.e(TAG, "Unable to find Assistant UID", e) + } + return assistantUid + } + + companion object { + protected const val TAG = "AssistLogger" + + private const val INSTANCE_ID_MAX = 1 shl 20 + + private val SESSION_END_EVENTS = + setOf( + AssistantSessionEvent.ASSISTANT_SESSION_INVOCATION_CANCELLED, + AssistantSessionEvent.ASSISTANT_SESSION_CLOSE) + } +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index a7533adc795e..6d179f27f4fb 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -40,11 +40,8 @@ import android.widget.ImageView; import com.android.internal.app.AssistUtils; import com.android.internal.app.IVoiceInteractionSessionListener; import com.android.internal.app.IVoiceInteractionSessionShowCallback; -import com.android.internal.logging.InstanceId; -import com.android.internal.logging.InstanceIdSequence; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.internal.util.FrameworkStatsLog; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.settingslib.applications.InterestingConfigChanges; import com.android.systemui.R; @@ -124,7 +121,6 @@ public class AssistManager { private static final long TIMEOUT_SERVICE = 2500; private static final long TIMEOUT_ACTIVITY = 1000; - private static final int INSTANCE_ID_MAX = 1 << 20; protected final Context mContext; private final WindowManager mWindowManager; @@ -134,8 +130,7 @@ public class AssistManager { private final AssistHandleBehaviorController mHandleController; private final UiController mUiController; protected final Lazy<SysUiState> mSysUiState; - protected final InstanceIdSequence mInstanceIdSequence = - new InstanceIdSequence(INSTANCE_ID_MAX); + protected final AssistLogger mAssistLogger; private AssistOrbContainer mView; private final DeviceProvisionedController mDeviceProvisionedController; @@ -202,7 +197,9 @@ public class AssistManager { PhoneStateMonitor phoneStateMonitor, OverviewProxyService overviewProxyService, ConfigurationController configurationController, - Lazy<SysUiState> sysUiState) { + Lazy<SysUiState> sysUiState, + DefaultUiController defaultUiController, + AssistLogger assistLogger) { mContext = context; mDeviceProvisionedController = controller; mCommandQueue = commandQueue; @@ -211,6 +208,7 @@ public class AssistManager { mAssistDisclosure = new AssistDisclosure(context, new Handler()); mPhoneStateMonitor = phoneStateMonitor; mHandleController = handleController; + mAssistLogger = assistLogger; configurationController.addCallback(mConfigurationListener); @@ -221,7 +219,7 @@ public class AssistManager { mConfigurationListener.onConfigChanged(context.getResources().getConfiguration()); mShouldEnableOrb = !ActivityManager.isLowRamDeviceStatic(); - mUiController = new DefaultUiController(mContext); + mUiController = defaultUiController; mSysUiState = sysUiState; @@ -248,6 +246,8 @@ public class AssistManager { if (VERBOSE) { Log.v(TAG, "Voice open"); } + mAssistLogger.reportAssistantSessionEvent( + AssistantSessionEvent.ASSISTANT_SESSION_UPDATE); } @Override @@ -255,6 +255,8 @@ public class AssistManager { if (VERBOSE) { Log.v(TAG, "Voice closed"); } + mAssistLogger.reportAssistantSessionEvent( + AssistantSessionEvent.ASSISTANT_SESSION_CLOSE); } @Override @@ -298,15 +300,19 @@ public class AssistManager { if (args == null) { args = new Bundle(); } - int invocationType = args.getInt(INVOCATION_TYPE_KEY, 0); - if (invocationType == INVOCATION_TYPE_GESTURE) { + int legacyInvocationType = args.getInt(INVOCATION_TYPE_KEY, 0); + if (legacyInvocationType == INVOCATION_TYPE_GESTURE) { mHandleController.onAssistantGesturePerformed(); } - int phoneState = mPhoneStateMonitor.getPhoneState(); - args.putInt(INVOCATION_PHONE_STATE_KEY, phoneState); + int legacyDeviceState = mPhoneStateMonitor.getPhoneState(); + args.putInt(INVOCATION_PHONE_STATE_KEY, legacyDeviceState); args.putLong(INVOCATION_TIME_MS_KEY, SystemClock.elapsedRealtime()); - logStartAssist(/* instanceId = */ null, invocationType, phoneState); - logStartAssistLegacy(invocationType, phoneState); + mAssistLogger.reportAssistantInvocationEventFromLegacy( + legacyInvocationType, + /* isInvocationComplete = */ true, + assistComponent, + legacyDeviceState); + logStartAssistLegacy(legacyInvocationType, legacyDeviceState); startAssistInternal(args, assistComponent, isService); } @@ -506,34 +512,6 @@ public class AssistManager { return toLoggingSubType(invocationType, mPhoneStateMonitor.getPhoneState()); } - protected void logStartAssist( - @Nullable InstanceId instanceId, int invocationType, int deviceState) { - InstanceId currentInstanceId = - instanceId == null ? mInstanceIdSequence.newInstanceId() : instanceId; - ComponentName assistantComponent = - mAssistUtils.getAssistComponentForUser(UserHandle.USER_CURRENT); - int assistantUid = 0; - try { - assistantUid = - mContext.getPackageManager() - .getApplicationInfo( - assistantComponent.getPackageName(), - /* flags = */ 0) - .uid; - } catch (PackageManager.NameNotFoundException e) { - Log.e(TAG, "Unable to find Assistant UID", e); - } - - FrameworkStatsLog.write( - FrameworkStatsLog.ASSISTANT_INVOCATION_REPORTED, - AssistantInvocationEvent.Companion.eventIdFromLegacyInvocationType(invocationType), - assistantUid, - assistantComponent.flattenToString(), - currentInstanceId.getId(), - AssistantInvocationEvent.Companion.deviceStateFromLegacyDeviceState(deviceState), - mHandleController.areHandlesShowing()); - } - protected void logStartAssistLegacy(int invocationType, int phoneState) { MetricsLogger.action( new LogMaker(MetricsEvent.ASSISTANT) diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistantInvocationEvent.kt b/packages/SystemUI/src/com/android/systemui/assist/AssistantInvocationEvent.kt index 1de7b8423617..fb5f1d1f725f 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistantInvocationEvent.kt +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistantInvocationEvent.kt @@ -50,33 +50,55 @@ enum class AssistantInvocationEvent(private val id: Int) : UiEventLogger.UiEvent ASSISTANT_INVOCATION_HOME_LONG_PRESS(447), @UiEvent(doc = "Assistant invoked by physical gesture") - ASSISTANT_INVOCATION_PHYSICAL_GESTURE(448); + ASSISTANT_INVOCATION_PHYSICAL_GESTURE(448), + + @UiEvent(doc = "Assistant invocation started by unknown method") + ASSISTANT_INVOCATION_START_UNKNOWN(530), + + @UiEvent(doc = "Assistant invocation started by touch gesture") + ASSISTANT_INVOCATION_START_TOUCH_GESTURE(531), + + @UiEvent(doc = "Assistant invocation started by physical gesture") + ASSISTANT_INVOCATION_START_PHYSICAL_GESTURE(532); override fun getId(): Int { return id } companion object { - fun eventIdFromLegacyInvocationType(legacyInvocationType: Int): Int { - return when (legacyInvocationType) { - AssistManager.INVOCATION_TYPE_GESTURE -> - ASSISTANT_INVOCATION_TOUCH_GESTURE - - AssistManager.INVOCATION_TYPE_OTHER -> - ASSISTANT_INVOCATION_PHYSICAL_GESTURE - - AssistManager.INVOCATION_TYPE_VOICE -> - ASSISTANT_INVOCATION_HOTWORD - - AssistManager.INVOCATION_TYPE_QUICK_SEARCH_BAR -> - ASSISTANT_INVOCATION_QUICK_SEARCH_BAR - - AssistManager.INVOCATION_HOME_BUTTON_LONG_PRESS -> - ASSISTANT_INVOCATION_HOME_LONG_PRESS - - else -> - ASSISTANT_INVOCATION_UNKNOWN - }.id + fun eventFromLegacyInvocationType(legacyInvocationType: Int, isInvocationComplete: Boolean) + : AssistantInvocationEvent { + return if (isInvocationComplete) { + when (legacyInvocationType) { + AssistManager.INVOCATION_TYPE_GESTURE -> + ASSISTANT_INVOCATION_TOUCH_GESTURE + + AssistManager.INVOCATION_TYPE_OTHER -> + ASSISTANT_INVOCATION_PHYSICAL_GESTURE + + AssistManager.INVOCATION_TYPE_VOICE -> + ASSISTANT_INVOCATION_HOTWORD + + AssistManager.INVOCATION_TYPE_QUICK_SEARCH_BAR -> + ASSISTANT_INVOCATION_QUICK_SEARCH_BAR + + AssistManager.INVOCATION_HOME_BUTTON_LONG_PRESS -> + ASSISTANT_INVOCATION_HOME_LONG_PRESS + + else -> + ASSISTANT_INVOCATION_UNKNOWN + } + } else { + when (legacyInvocationType) { + AssistManager.INVOCATION_TYPE_GESTURE -> + ASSISTANT_INVOCATION_START_TOUCH_GESTURE + + AssistManager.INVOCATION_TYPE_OTHER -> + ASSISTANT_INVOCATION_START_PHYSICAL_GESTURE + + else -> ASSISTANT_INVOCATION_START_UNKNOWN + } + } } fun deviceStateFromLegacyDeviceState(legacyDeviceState: Int): Int { diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistantSessionEvent.kt b/packages/SystemUI/src/com/android/systemui/assist/AssistantSessionEvent.kt new file mode 100644 index 000000000000..8b953fa46441 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistantSessionEvent.kt @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.assist + +import com.android.internal.logging.UiEvent +import com.android.internal.logging.UiEventLogger + +enum class AssistantSessionEvent(private val id: Int) : UiEventLogger.UiEventEnum { + @UiEvent(doc = "Unknown assistant session event") + ASSISTANT_SESSION_UNKNOWN(523), + + @UiEvent(doc = "Assistant session dismissed due to timeout") + ASSISTANT_SESSION_TIMEOUT_DISMISS(524), + + @UiEvent(doc = "User began a gesture for invoking the Assistant") + ASSISTANT_SESSION_INVOCATION_START(525), + + @UiEvent(doc = + "User stopped a gesture for invoking the Assistant before the gesture was completed") + ASSISTANT_SESSION_INVOCATION_CANCELLED(526), + + @UiEvent(doc = "User manually dismissed the Assistant session") + ASSISTANT_SESSION_USER_DISMISS(527), + + @UiEvent(doc = "The Assistant session has changed modes") + ASSISTANT_SESSION_UPDATE(528), + + @UiEvent(doc = "The Assistant session completed") + ASSISTANT_SESSION_CLOSE(529); + + override fun getId(): Int { + return id + } +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java index 652ce6f04db0..257ad50eff61 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java +++ b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java @@ -104,7 +104,7 @@ public final class PhoneStateMonitor { }); } - int getPhoneState() { + public int getPhoneState() { int phoneState; if (isShadeFullscreen()) { phoneState = getPhoneLockscreenState(); diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java index 68242f0a0ac2..05f3617dd1d6 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java @@ -38,15 +38,21 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.assist.AssistHandleViewController; +import com.android.systemui.assist.AssistLogger; import com.android.systemui.assist.AssistManager; +import com.android.systemui.assist.AssistantSessionEvent; import com.android.systemui.statusbar.NavigationBarController; import java.util.Locale; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Default UiController implementation. Shows white edge lights along the bottom of the phone, * expanding from the corners to meet in the center. */ +@Singleton public class DefaultUiController implements AssistManager.UiController { private static final String TAG = "DefaultUiController"; @@ -58,6 +64,7 @@ public class DefaultUiController implements AssistManager.UiController { protected final FrameLayout mRoot; protected InvocationLightsView mInvocationLightsView; + protected final AssistLogger mAssistLogger; private final WindowManager mWindowManager; private final WindowManager.LayoutParams mLayoutParams; @@ -69,7 +76,9 @@ public class DefaultUiController implements AssistManager.UiController { private ValueAnimator mInvocationAnimator = new ValueAnimator(); - public DefaultUiController(Context context) { + @Inject + public DefaultUiController(Context context, AssistLogger assistLogger) { + mAssistLogger = assistLogger; mRoot = new FrameLayout(context); mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); @@ -142,6 +151,11 @@ public class DefaultUiController implements AssistManager.UiController { if (VERBOSE) { Log.v(TAG, "Invocation started: type=" + type); } + mAssistLogger.reportAssistantInvocationEventFromLegacy( + type, + /* isInvocationComplete = */ false, + /* assistantComponent = */ null, + /* legacyDeviceState = */ null); MetricsLogger.action(new LogMaker(MetricsEvent.ASSISTANT) .setType(MetricsEvent.TYPE_ACTION) .setSubtype(Dependency.get(AssistManager.class).toLoggingSubType(type))); @@ -152,6 +166,8 @@ public class DefaultUiController implements AssistManager.UiController { if (VERBOSE) { Log.v(TAG, "Invocation cancelled: type=" + type); } + mAssistLogger.reportAssistantSessionEvent( + AssistantSessionEvent.ASSISTANT_SESSION_INVOCATION_CANCELLED); MetricsLogger.action(new LogMaker(MetricsEvent.ASSISTANT) .setType(MetricsEvent.TYPE_DISMISS) .setSubtype(DISMISS_REASON_INVOCATION_CANCELLED)); |