Loading packages/SystemUI/compose/features/src/com/android/systemui/ambientcue/ui/compose/Chip.kt +2 −2 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ package com.android.systemui.ambientcue.ui.compose import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding Loading Loading @@ -48,7 +48,7 @@ fun Chip(action: ActionViewModel, modifier: Modifier = Modifier) { modifier .clip(RoundedCornerShape(24.dp)) .background(backgroundColor) .clickable { action.onClick() } .combinedClickable(onClick = action.onClick, onLongClick = action.onLongClick) .padding(horizontal = 8.dp, vertical = 12.dp), ) { val painter = rememberDrawablePainter(action.icon) Loading packages/SystemUI/multivalentTests/src/com/android/systemui/ambientcue/data/repository/AmbientCueRepositoryTest.kt +38 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import com.android.systemui.SysuiTestCase 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_ACTIVITY_ID import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.EXTRA_ATTRIBUTION_DIALOG_PENDING_INTENT import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.EXTRA_AUTOFILL_ID import com.android.systemui.ambientcue.shared.model.ActionModel import com.android.systemui.concurrency.fakeExecutor Loading Loading @@ -248,6 +249,23 @@ class AmbientCueRepositoryTest : SysuiTestCase() { verify(pendingIntent).send(any<Bundle>()) } @Test fun action_performLongClick_pendingIntentSent() = kosmos.runTest { val actions by collectLastValue(underTest.actions) runCurrent() verify(smartSpaceSession) .addOnTargetsAvailableListener(any(), onTargetsAvailableListenerCaptor.capture()) onTargetsAvailableListenerCaptor.firstValue.onTargetsAvailable( listOf(attributionDialogPendingIntentTarget) ) val action: ActionModel = actions!!.first() action.onPerformLongClick() runCurrent() verify(attributionDialogPendingIntent).send(any<Bundle>()) } @Test fun targetTaskId_updatedWithAction() = kosmos.runTest { Loading Loading @@ -367,6 +385,26 @@ class AmbientCueRepositoryTest : SysuiTestCase() { ) } private val attributionDialogPendingIntent = mock<PendingIntent>() private val attributionDialogPendingIntentTarget = mock<SmartspaceTarget> { on { smartspaceTargetId } doReturn AMBIENT_CUE_SURFACE on { actionChips } doReturn listOf( SmartspaceAction.Builder("action1-id", "title 1") .setSubtitle("subtitle 1") .setExtras( Bundle().apply { putParcelable( EXTRA_ATTRIBUTION_DIALOG_PENDING_INTENT, attributionDialogPendingIntent, ) } ) .build() ) } private val invalidTarget1 = mock<SmartspaceTarget> { on { smartspaceTargetId } doReturn "home" Loading packages/SystemUI/multivalentTests/src/com/android/systemui/ambientcue/domain/interactor/AmbientCueInteractorTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ class AmbientCueInteractorTest : SysuiTestCase() { label = "Sunday Morning", attribution = null, onPerformAction = {}, onPerformLongClick = {}, ) ) ambientCueRepository.fake.setActions(testActions) Loading packages/SystemUI/multivalentTests/src/com/android/systemui/ambientcue/ui/viewmodel/AmbientCueViewModelTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -188,6 +188,7 @@ class AmbientCueViewModelTest : SysuiTestCase() { label = "Sunday Morning", attribution = null, onPerformAction = {}, onPerformLongClick = {}, ) ) Loading packages/SystemUI/src/com/android/systemui/ambientcue/data/repository/AmbientCueRepository.kt +30 −13 Original line number Diff line number Diff line Loading @@ -172,24 +172,25 @@ constructor( activityId.taskId, ) } else if (pendingIntent != null) { val options = BroadcastOptions.makeBasic() options.isInteractive = true options.pendingIntentBackgroundActivityStartMode = ActivityOptions .MODE_BACKGROUND_ACTIVITY_START_ALLOWED try { pendingIntent.send(options.toBundle()) } catch (e: PendingIntent.CanceledException) { Log.e( TAG, "pending intent of $pendingIntent was canceled", ) } launchPendingIntent(pendingIntent) } else if (intent != null) { activityStarter.startActivity(intent, false) } } }, onPerformLongClick = { Log.v(TAG, "AmbientCueRepositoryImpl: onPerformLongClick") trace("performAmbientCueLongClick") { val pendingIntent = chip.extras?.getParcelable<PendingIntent>( EXTRA_ATTRIBUTION_DIALOG_PENDING_INTENT ) if (pendingIntent != null) { Log.v(TAG, "Performing long click: $pendingIntent") launchPendingIntent(pendingIntent) } } }, taskId = activityId?.taskId ?: INVALID_TASK_ID, actionType = actionType, ) Loading Loading @@ -221,6 +222,18 @@ constructor( initialValue = emptyList(), ) private fun launchPendingIntent(pendingIntent: PendingIntent) { val options = BroadcastOptions.makeBasic() options.isInteractive = true options.pendingIntentBackgroundActivityStartMode = ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED try { pendingIntent.send(options.toBundle()) } catch (e: PendingIntent.CanceledException) { Log.e(TAG, "pending intent of $pendingIntent was canceled") } } override val isGestureNav: StateFlow<Boolean> = conflatedCallbackFlow { val listener = Loading Loading @@ -278,9 +291,13 @@ constructor( companion object { // Surface that PCC wants to push cards into @VisibleForTesting const val AMBIENT_CUE_SURFACE = "ambientcue" // In-coming intent extras from the intelligent service. @VisibleForTesting const val EXTRA_ACTIVITY_ID = "activityId" @VisibleForTesting const val EXTRA_AUTOFILL_ID = "autofillId" @VisibleForTesting const val EXTRA_ATTRIBUTION_DIALOG_PENDING_INTENT = "attributionDialogPendingIntent" private const val EXTRA_ACTION_TYPE = "actionType" // Timeout to hide cuebar if it wasn't interacted with private const val TAG = "AmbientCueRepository" private const val DEBUG = false Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/ambientcue/ui/compose/Chip.kt +2 −2 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ package com.android.systemui.ambientcue.ui.compose import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding Loading Loading @@ -48,7 +48,7 @@ fun Chip(action: ActionViewModel, modifier: Modifier = Modifier) { modifier .clip(RoundedCornerShape(24.dp)) .background(backgroundColor) .clickable { action.onClick() } .combinedClickable(onClick = action.onClick, onLongClick = action.onLongClick) .padding(horizontal = 8.dp, vertical = 12.dp), ) { val painter = rememberDrawablePainter(action.icon) Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/ambientcue/data/repository/AmbientCueRepositoryTest.kt +38 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import com.android.systemui.SysuiTestCase 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_ACTIVITY_ID import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.EXTRA_ATTRIBUTION_DIALOG_PENDING_INTENT import com.android.systemui.ambientcue.data.repository.AmbientCueRepositoryImpl.Companion.EXTRA_AUTOFILL_ID import com.android.systemui.ambientcue.shared.model.ActionModel import com.android.systemui.concurrency.fakeExecutor Loading Loading @@ -248,6 +249,23 @@ class AmbientCueRepositoryTest : SysuiTestCase() { verify(pendingIntent).send(any<Bundle>()) } @Test fun action_performLongClick_pendingIntentSent() = kosmos.runTest { val actions by collectLastValue(underTest.actions) runCurrent() verify(smartSpaceSession) .addOnTargetsAvailableListener(any(), onTargetsAvailableListenerCaptor.capture()) onTargetsAvailableListenerCaptor.firstValue.onTargetsAvailable( listOf(attributionDialogPendingIntentTarget) ) val action: ActionModel = actions!!.first() action.onPerformLongClick() runCurrent() verify(attributionDialogPendingIntent).send(any<Bundle>()) } @Test fun targetTaskId_updatedWithAction() = kosmos.runTest { Loading Loading @@ -367,6 +385,26 @@ class AmbientCueRepositoryTest : SysuiTestCase() { ) } private val attributionDialogPendingIntent = mock<PendingIntent>() private val attributionDialogPendingIntentTarget = mock<SmartspaceTarget> { on { smartspaceTargetId } doReturn AMBIENT_CUE_SURFACE on { actionChips } doReturn listOf( SmartspaceAction.Builder("action1-id", "title 1") .setSubtitle("subtitle 1") .setExtras( Bundle().apply { putParcelable( EXTRA_ATTRIBUTION_DIALOG_PENDING_INTENT, attributionDialogPendingIntent, ) } ) .build() ) } private val invalidTarget1 = mock<SmartspaceTarget> { on { smartspaceTargetId } doReturn "home" Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/ambientcue/domain/interactor/AmbientCueInteractorTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ class AmbientCueInteractorTest : SysuiTestCase() { label = "Sunday Morning", attribution = null, onPerformAction = {}, onPerformLongClick = {}, ) ) ambientCueRepository.fake.setActions(testActions) Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/ambientcue/ui/viewmodel/AmbientCueViewModelTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -188,6 +188,7 @@ class AmbientCueViewModelTest : SysuiTestCase() { label = "Sunday Morning", attribution = null, onPerformAction = {}, onPerformLongClick = {}, ) ) Loading
packages/SystemUI/src/com/android/systemui/ambientcue/data/repository/AmbientCueRepository.kt +30 −13 Original line number Diff line number Diff line Loading @@ -172,24 +172,25 @@ constructor( activityId.taskId, ) } else if (pendingIntent != null) { val options = BroadcastOptions.makeBasic() options.isInteractive = true options.pendingIntentBackgroundActivityStartMode = ActivityOptions .MODE_BACKGROUND_ACTIVITY_START_ALLOWED try { pendingIntent.send(options.toBundle()) } catch (e: PendingIntent.CanceledException) { Log.e( TAG, "pending intent of $pendingIntent was canceled", ) } launchPendingIntent(pendingIntent) } else if (intent != null) { activityStarter.startActivity(intent, false) } } }, onPerformLongClick = { Log.v(TAG, "AmbientCueRepositoryImpl: onPerformLongClick") trace("performAmbientCueLongClick") { val pendingIntent = chip.extras?.getParcelable<PendingIntent>( EXTRA_ATTRIBUTION_DIALOG_PENDING_INTENT ) if (pendingIntent != null) { Log.v(TAG, "Performing long click: $pendingIntent") launchPendingIntent(pendingIntent) } } }, taskId = activityId?.taskId ?: INVALID_TASK_ID, actionType = actionType, ) Loading Loading @@ -221,6 +222,18 @@ constructor( initialValue = emptyList(), ) private fun launchPendingIntent(pendingIntent: PendingIntent) { val options = BroadcastOptions.makeBasic() options.isInteractive = true options.pendingIntentBackgroundActivityStartMode = ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED try { pendingIntent.send(options.toBundle()) } catch (e: PendingIntent.CanceledException) { Log.e(TAG, "pending intent of $pendingIntent was canceled") } } override val isGestureNav: StateFlow<Boolean> = conflatedCallbackFlow { val listener = Loading Loading @@ -278,9 +291,13 @@ constructor( companion object { // Surface that PCC wants to push cards into @VisibleForTesting const val AMBIENT_CUE_SURFACE = "ambientcue" // In-coming intent extras from the intelligent service. @VisibleForTesting const val EXTRA_ACTIVITY_ID = "activityId" @VisibleForTesting const val EXTRA_AUTOFILL_ID = "autofillId" @VisibleForTesting const val EXTRA_ATTRIBUTION_DIALOG_PENDING_INTENT = "attributionDialogPendingIntent" private const val EXTRA_ACTION_TYPE = "actionType" // Timeout to hide cuebar if it wasn't interacted with private const val TAG = "AmbientCueRepository" private const val DEBUG = false Loading