Loading packages/SystemUI/multivalentTests/src/com/android/systemui/ambientcue/data/repository/AmbientCueRepositoryTest.kt +12 −4 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.app.smartspace.SmartspaceManager import android.app.smartspace.SmartspaceSession import android.app.smartspace.SmartspaceSession.OnTargetsAvailableListener import android.app.smartspace.SmartspaceTarget import android.content.ComponentName import android.content.Intent import android.content.applicationContext import android.content.testableContext Loading @@ -37,7 +38,6 @@ import androidx.test.filters.SmallTest import com.android.systemui.LauncherProxyService import com.android.systemui.LauncherProxyService.LauncherProxyListener import com.android.systemui.SysuiTestCase import com.android.systemui.ambientcue.shared.logger.ambientCueLogger import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.AMBIENT_CUE_SURFACE import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.DEBOUNCE_DELAY_MS import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.EXTRA_ACTION_TYPE Loading @@ -46,6 +46,7 @@ import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl. import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.EXTRA_AUTOFILL_ID import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.MA_ACTION_TYPE_NAME import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.MR_ACTION_TYPE_NAME import com.android.systemui.ambientcue.shared.logger.ambientCueLogger import com.android.systemui.ambientcue.shared.model.ActionModel import com.android.systemui.concurrency.fakeExecutor import com.android.systemui.dump.DumpManager Loading Loading @@ -276,10 +277,14 @@ class AmbientCueRepositoryTest : SysuiTestCase() { } @Test fun isRootViewAttached_isAttachedAndSessionNotStartedBefore_setsAmbientCueDisplayStatus() = fun isRootViewAttached_isAttachedAndSessionNotStartedBefore_setsAmbientCueLogs() = kosmos.runTest { val actions by collectLastValue(underTest.actions) val isRootViewAttached by collectLastValue(underTest.isRootViewAttached) val componentName = ComponentName(PACKAGE_NAME, ACTIVITY_NAME) val intent = Intent() intent.component = componentName val runningTaskInfo = RunningTaskInfo().apply { this.baseIntent = intent } underTest.isDeactivated.update { true } secureSettingsRepository.setInt( AmbientCueRepositoryImpl.AMBIENT_CUE_SETTING, Loading @@ -287,7 +292,7 @@ class AmbientCueRepositoryTest : SysuiTestCase() { ) runCurrent() taskStackChangeListeners.listenerImpl.onTaskMovedToFront( RunningTaskInfo().apply { taskId = TASK_ID } runningTaskInfo.apply { taskId = TASK_ID } ) verify(smartSpaceSession) .addOnTargetsAvailableListener(any(), onTargetsAvailableListenerCaptor.capture()) Loading @@ -300,9 +305,10 @@ class AmbientCueRepositoryTest : SysuiTestCase() { // Verify that the ambient cue displayed status is set. verify(kosmos.ambientCueLogger).setAmbientCueDisplayStatus(any(), any()) verify(kosmos.ambientCueLogger).setPackageName(PACKAGE_NAME) taskStackChangeListeners.listenerImpl.onTaskMovedToFront( RunningTaskInfo().apply { taskId = TASK_ID_2 } runningTaskInfo.apply { taskId = TASK_ID_2 } ) underTest.isDeactivated.update { true } advanceTimeBy(DEBOUNCE_DELAY_MS) Loading Loading @@ -535,6 +541,8 @@ class AmbientCueRepositoryTest : SysuiTestCase() { private const val SUBTITLE_2 = "subtitle 2" private const val TASK_ID = 1 private const val TASK_ID_2 = 2 private const val PACKAGE_NAME = "com.package.name" private const val ACTIVITY_NAME = "com.package.name.activity" private val validTarget = mock<SmartspaceTarget> { on { smartspaceTargetId } doReturn AMBIENT_CUE_SURFACE Loading packages/SystemUI/src/com/android/systemui/ambientcue/data/repository/AmbientCueRepository.kt +9 −0 Original line number Diff line number Diff line Loading @@ -310,12 +310,19 @@ constructor( override val isDeactivated: MutableStateFlow<Boolean> = MutableStateFlow(false) /** * The [RunningTaskInfo] for the task that is currently in the foreground. Updated whenever a * new task moves to the front. Used to derive the package name for logging. */ private var frontRunningTask: RunningTaskInfo? = null @OptIn(FlowPreview::class) override val globallyFocusedTaskId: StateFlow<Int> = conflatedCallbackFlow { val taskListener = object : TaskStackChangeListener { override fun onTaskMovedToFront(runningTaskInfo: RunningTaskInfo) { frontRunningTask = runningTaskInfo trySend(runningTaskInfo.taskId) } } Loading Loading @@ -364,6 +371,7 @@ constructor( isSessionStarted = true var maCount = 0 var mrCount = 0 val packageName = frontRunningTask?.baseIntent?.component?.packageName ?: "" actions.value.forEach { action -> when (action.actionType) { MA_ACTION_TYPE_NAME -> maCount++ Loading @@ -371,6 +379,7 @@ constructor( else -> {} } } ambientCueLogger.setPackageName(packageName) ambientCueLogger.setAmbientCueDisplayStatus(maCount, mrCount) } if (!isAttached && isSessionStarted) { Loading packages/SystemUI/src/com/android/systemui/ambientcue/shared/logger/AmbientCueLogger.kt +30 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.systemui.ambientcue.shared.logger import android.content.pm.PackageManager import android.content.pm.PackageManager.NameNotFoundException import android.util.Log import com.android.internal.util.FrameworkStatsLog import com.android.systemui.util.time.SystemClock import javax.inject.Inject Loading @@ -36,6 +39,7 @@ data class AmbientCueEventReported( var fulfilledWithMrIntent: Boolean = false, var clickedCloseButton: Boolean = false, var reachedTimeout: Boolean = false, var packageName: String = "", ) /** Loading @@ -51,6 +55,13 @@ interface AmbientCueLogger { */ fun setAmbientCueDisplayStatus(maCount: Int, mrCount: Int) /** * Sets AmbientCue package name. * * @param packageName The package name of the target app. */ fun setPackageName(packageName: String) /** * Sets AmbientCue lose focus time. * Loading Loading @@ -78,7 +89,9 @@ interface AmbientCueLogger { } /** Implementation for logging UI events related to controls. */ class AmbientCueLoggerImpl @Inject constructor(private val systemClock: SystemClock) : class AmbientCueLoggerImpl @Inject constructor(private val systemClock: SystemClock, private val packageManager: PackageManager) : AmbientCueLogger { private var report = AmbientCueEventReported() private var displayTimeMillis: Long = 0L Loading @@ -90,6 +103,11 @@ class AmbientCueLoggerImpl @Inject constructor(private val systemClock: SystemCl report.mrCount = mrCount } /** {@see AmbientCueLogger#setPackageName} */ override fun setPackageName(packageName: String) { report.packageName = packageName } /** {@see AmbientCueLogger#setLoseFocusMillis} */ override fun setLoseFocusMillis() { report.loseFocusMillis = systemClock.currentTimeMillis() Loading Loading @@ -117,6 +135,12 @@ class AmbientCueLoggerImpl @Inject constructor(private val systemClock: SystemCl /** {@see AmbientCueLogger#flushAmbientCueEventReported} */ override fun flushAmbientCueEventReported() { var uid = 0 try { uid = packageManager.getPackageUid(report.packageName, 0) } catch (e: NameNotFoundException) { Log.w(TAG, "Package name not found: ${report.packageName}") } report.displayDurationMillis = systemClock.currentTimeMillis() - displayTimeMillis FrameworkStatsLog.write( FrameworkStatsLog.AMBIENT_CUE_EVENT_REPORTED, Loading @@ -130,6 +154,7 @@ class AmbientCueLoggerImpl @Inject constructor(private val systemClock: SystemCl report.fulfilledWithMrIntent, report.clickedCloseButton, report.reachedTimeout, uid, ) } Loading @@ -138,4 +163,8 @@ class AmbientCueLoggerImpl @Inject constructor(private val systemClock: SystemCl report = AmbientCueEventReported() displayTimeMillis = 0L } companion object { private const val TAG = "AmbientCueLogger" } } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/ambientcue/data/repository/AmbientCueRepositoryTest.kt +12 −4 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.app.smartspace.SmartspaceManager import android.app.smartspace.SmartspaceSession import android.app.smartspace.SmartspaceSession.OnTargetsAvailableListener import android.app.smartspace.SmartspaceTarget import android.content.ComponentName import android.content.Intent import android.content.applicationContext import android.content.testableContext Loading @@ -37,7 +38,6 @@ import androidx.test.filters.SmallTest import com.android.systemui.LauncherProxyService import com.android.systemui.LauncherProxyService.LauncherProxyListener import com.android.systemui.SysuiTestCase import com.android.systemui.ambientcue.shared.logger.ambientCueLogger import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.AMBIENT_CUE_SURFACE import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.DEBOUNCE_DELAY_MS import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.EXTRA_ACTION_TYPE Loading @@ -46,6 +46,7 @@ import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl. import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.EXTRA_AUTOFILL_ID import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.MA_ACTION_TYPE_NAME import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.MR_ACTION_TYPE_NAME import com.android.systemui.ambientcue.shared.logger.ambientCueLogger import com.android.systemui.ambientcue.shared.model.ActionModel import com.android.systemui.concurrency.fakeExecutor import com.android.systemui.dump.DumpManager Loading Loading @@ -276,10 +277,14 @@ class AmbientCueRepositoryTest : SysuiTestCase() { } @Test fun isRootViewAttached_isAttachedAndSessionNotStartedBefore_setsAmbientCueDisplayStatus() = fun isRootViewAttached_isAttachedAndSessionNotStartedBefore_setsAmbientCueLogs() = kosmos.runTest { val actions by collectLastValue(underTest.actions) val isRootViewAttached by collectLastValue(underTest.isRootViewAttached) val componentName = ComponentName(PACKAGE_NAME, ACTIVITY_NAME) val intent = Intent() intent.component = componentName val runningTaskInfo = RunningTaskInfo().apply { this.baseIntent = intent } underTest.isDeactivated.update { true } secureSettingsRepository.setInt( AmbientCueRepositoryImpl.AMBIENT_CUE_SETTING, Loading @@ -287,7 +292,7 @@ class AmbientCueRepositoryTest : SysuiTestCase() { ) runCurrent() taskStackChangeListeners.listenerImpl.onTaskMovedToFront( RunningTaskInfo().apply { taskId = TASK_ID } runningTaskInfo.apply { taskId = TASK_ID } ) verify(smartSpaceSession) .addOnTargetsAvailableListener(any(), onTargetsAvailableListenerCaptor.capture()) Loading @@ -300,9 +305,10 @@ class AmbientCueRepositoryTest : SysuiTestCase() { // Verify that the ambient cue displayed status is set. verify(kosmos.ambientCueLogger).setAmbientCueDisplayStatus(any(), any()) verify(kosmos.ambientCueLogger).setPackageName(PACKAGE_NAME) taskStackChangeListeners.listenerImpl.onTaskMovedToFront( RunningTaskInfo().apply { taskId = TASK_ID_2 } runningTaskInfo.apply { taskId = TASK_ID_2 } ) underTest.isDeactivated.update { true } advanceTimeBy(DEBOUNCE_DELAY_MS) Loading Loading @@ -535,6 +541,8 @@ class AmbientCueRepositoryTest : SysuiTestCase() { private const val SUBTITLE_2 = "subtitle 2" private const val TASK_ID = 1 private const val TASK_ID_2 = 2 private const val PACKAGE_NAME = "com.package.name" private const val ACTIVITY_NAME = "com.package.name.activity" private val validTarget = mock<SmartspaceTarget> { on { smartspaceTargetId } doReturn AMBIENT_CUE_SURFACE Loading
packages/SystemUI/src/com/android/systemui/ambientcue/data/repository/AmbientCueRepository.kt +9 −0 Original line number Diff line number Diff line Loading @@ -310,12 +310,19 @@ constructor( override val isDeactivated: MutableStateFlow<Boolean> = MutableStateFlow(false) /** * The [RunningTaskInfo] for the task that is currently in the foreground. Updated whenever a * new task moves to the front. Used to derive the package name for logging. */ private var frontRunningTask: RunningTaskInfo? = null @OptIn(FlowPreview::class) override val globallyFocusedTaskId: StateFlow<Int> = conflatedCallbackFlow { val taskListener = object : TaskStackChangeListener { override fun onTaskMovedToFront(runningTaskInfo: RunningTaskInfo) { frontRunningTask = runningTaskInfo trySend(runningTaskInfo.taskId) } } Loading Loading @@ -364,6 +371,7 @@ constructor( isSessionStarted = true var maCount = 0 var mrCount = 0 val packageName = frontRunningTask?.baseIntent?.component?.packageName ?: "" actions.value.forEach { action -> when (action.actionType) { MA_ACTION_TYPE_NAME -> maCount++ Loading @@ -371,6 +379,7 @@ constructor( else -> {} } } ambientCueLogger.setPackageName(packageName) ambientCueLogger.setAmbientCueDisplayStatus(maCount, mrCount) } if (!isAttached && isSessionStarted) { Loading
packages/SystemUI/src/com/android/systemui/ambientcue/shared/logger/AmbientCueLogger.kt +30 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.systemui.ambientcue.shared.logger import android.content.pm.PackageManager import android.content.pm.PackageManager.NameNotFoundException import android.util.Log import com.android.internal.util.FrameworkStatsLog import com.android.systemui.util.time.SystemClock import javax.inject.Inject Loading @@ -36,6 +39,7 @@ data class AmbientCueEventReported( var fulfilledWithMrIntent: Boolean = false, var clickedCloseButton: Boolean = false, var reachedTimeout: Boolean = false, var packageName: String = "", ) /** Loading @@ -51,6 +55,13 @@ interface AmbientCueLogger { */ fun setAmbientCueDisplayStatus(maCount: Int, mrCount: Int) /** * Sets AmbientCue package name. * * @param packageName The package name of the target app. */ fun setPackageName(packageName: String) /** * Sets AmbientCue lose focus time. * Loading Loading @@ -78,7 +89,9 @@ interface AmbientCueLogger { } /** Implementation for logging UI events related to controls. */ class AmbientCueLoggerImpl @Inject constructor(private val systemClock: SystemClock) : class AmbientCueLoggerImpl @Inject constructor(private val systemClock: SystemClock, private val packageManager: PackageManager) : AmbientCueLogger { private var report = AmbientCueEventReported() private var displayTimeMillis: Long = 0L Loading @@ -90,6 +103,11 @@ class AmbientCueLoggerImpl @Inject constructor(private val systemClock: SystemCl report.mrCount = mrCount } /** {@see AmbientCueLogger#setPackageName} */ override fun setPackageName(packageName: String) { report.packageName = packageName } /** {@see AmbientCueLogger#setLoseFocusMillis} */ override fun setLoseFocusMillis() { report.loseFocusMillis = systemClock.currentTimeMillis() Loading Loading @@ -117,6 +135,12 @@ class AmbientCueLoggerImpl @Inject constructor(private val systemClock: SystemCl /** {@see AmbientCueLogger#flushAmbientCueEventReported} */ override fun flushAmbientCueEventReported() { var uid = 0 try { uid = packageManager.getPackageUid(report.packageName, 0) } catch (e: NameNotFoundException) { Log.w(TAG, "Package name not found: ${report.packageName}") } report.displayDurationMillis = systemClock.currentTimeMillis() - displayTimeMillis FrameworkStatsLog.write( FrameworkStatsLog.AMBIENT_CUE_EVENT_REPORTED, Loading @@ -130,6 +154,7 @@ class AmbientCueLoggerImpl @Inject constructor(private val systemClock: SystemCl report.fulfilledWithMrIntent, report.clickedCloseButton, report.reachedTimeout, uid, ) } Loading @@ -138,4 +163,8 @@ class AmbientCueLoggerImpl @Inject constructor(private val systemClock: SystemCl report = AmbientCueEventReported() displayTimeMillis = 0L } companion object { private const val TAG = "AmbientCueLogger" } }