Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98b6789a authored by amehfooz's avatar amehfooz Committed by Ahmed Mehfooz
Browse files

Show dialogs on click for OngoingActivityChip Composable

This CL adds a new ClickBehavior field in OngoingActivityChipModel
to define click actions for chips. The ExpandAction is used to
animate the chip into a dialog or activity when it is clicked.
This CL only implements dialogs for now.

Test: Make sure chips expand into a dialog.
Video provided in b/372657935 comment#16
Bug: b/372657935
Flag: com.android.systemui.status_bar_chips_modernization
Change-Id: I284dab65df30246d884a361f4cbbe94558cc5414
parent 26c34fed
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -343,7 +343,7 @@ class CallChipViewModelTest : SysuiTestCase() {

            repo.setOngoingCallState(inCallModel(startTimeMs = 1000, intent = null))

            assertThat((latest as OngoingActivityChipModel.Shown).onClickListener).isNull()
            assertThat((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy).isNull()
        }

    @Test
@@ -353,7 +353,7 @@ class CallChipViewModelTest : SysuiTestCase() {

            val pendingIntent = mock<PendingIntent>()
            repo.setOngoingCallState(inCallModel(startTimeMs = 1000, intent = pendingIntent))
            val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListener
            val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListenerLegacy
            assertThat(clickListener).isNotNull()

            clickListener!!.onClick(chipView)
@@ -370,7 +370,8 @@ class CallChipViewModelTest : SysuiTestCase() {

            val pendingIntent = mock<PendingIntent>()
            repo.setOngoingCallState(inCallModel(startTimeMs = 0, intent = pendingIntent))
            val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListener
            val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListenerLegacy

            assertThat(clickListener).isNotNull()

            clickListener!!.onClick(chipView)
+129 −7
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel

import android.content.DialogInterface
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.view.View
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -25,6 +26,7 @@ import com.android.internal.jank.Cuj
import com.android.systemui.Flags.FLAG_STATUS_BAR_SHOW_AUDIO_ONLY_PROJECTION_CHIP
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.Expandable
import com.android.systemui.animation.mockDialogTransitionAnimator
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
@@ -46,8 +48,10 @@ import com.android.systemui.statusbar.chips.ui.model.ColorsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.getStopActionFromDialog
import com.android.systemui.statusbar.core.StatusBarRootModernization
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
import com.android.systemui.statusbar.policy.CastDevice
import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
@@ -84,6 +88,8 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
                )
                .thenReturn(chipBackgroundView)
        }
    private val mockExpandable: Expandable =
        mock<Expandable>().apply { whenever(dialogTransitionController(any())).thenReturn(mock()) }

    private val underTest = kosmos.castToOtherDeviceChipViewModel

@@ -263,7 +269,13 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {

            // WHEN the stop action on the dialog is clicked
            val dialogStopAction =
                getStopActionFromDialog(latest, chipView, mockScreenCastDialog, kosmos)
                getStopActionFromDialog(
                    latest,
                    chipView,
                    mockExpandable,
                    mockScreenCastDialog,
                    kosmos,
                )
            dialogStopAction.onClick(mock<DialogInterface>(), 0)

            // THEN the chip is immediately hidden...
@@ -296,7 +308,13 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {

            // WHEN the stop action on the dialog is clicked
            val dialogStopAction =
                getStopActionFromDialog(latest, chipView, mockGenericCastDialog, kosmos)
                getStopActionFromDialog(
                    latest,
                    chipView,
                    mockExpandable,
                    mockGenericCastDialog,
                    kosmos,
                )
            dialogStopAction.onClick(mock<DialogInterface>(), 0)

            // THEN the chip is immediately hidden...
@@ -416,13 +434,14 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
    fun chip_projectionStateEntireScreen_clickListenerShowsScreenCastDialog() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)
            mediaProjectionRepo.mediaProjectionState.value =
                MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)

            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy)
            assertThat(clickListener).isNotNull()

            clickListener!!.onClick(chipView)
@@ -431,6 +450,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
    fun chip_projectionStateSingleTask_clickListenerShowsScreenCastDialog() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)
@@ -442,7 +462,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
                    createTask(taskId = 1),
                )

            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy)
            assertThat(clickListener).isNotNull()

            clickListener!!.onClick(chipView)
@@ -451,6 +471,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
    fun chip_routerStateCasting_clickListenerShowsGenericCastDialog() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)
@@ -466,7 +487,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
                    )
                )

            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy)
            assertThat(clickListener).isNotNull()

            clickListener!!.onClick(chipView)
@@ -480,13 +501,14 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
    fun chip_projectionStateCasting_clickListenerHasCuj() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)
            mediaProjectionRepo.mediaProjectionState.value =
                MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)

            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy)
            clickListener!!.onClick(chipView)

            val cujCaptor = argumentCaptor<DialogCuj>()
@@ -499,6 +521,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
    fun chip_routerStateCasting_clickListenerHasCuj() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)
@@ -514,7 +537,7 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
                    )
                )

            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy)
            clickListener!!.onClick(chipView)

            val cujCaptor = argumentCaptor<DialogCuj>()
@@ -525,4 +548,103 @@ class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
                .isEqualTo(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP)
            assertThat(cujCaptor.firstValue.tag).contains("Cast")
        }

    @Test
    @EnableFlags(StatusBarChipsModernization.FLAG_NAME)
    fun chip_routerStateCasting_hasClickBehavior() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)

            mediaRouterRepo.castDevices.value =
                listOf(
                    CastDevice(
                        state = CastDevice.CastState.Connected,
                        id = "id",
                        name = "name",
                        description = "desc",
                        origin = CastDevice.CastOrigin.MediaRouter,
                    )
                )

            assertThat((latest as OngoingActivityChipModel.Shown).clickBehavior)
                .isInstanceOf(OngoingActivityChipModel.ClickBehavior.ExpandAction::class.java)
        }

    @Test
    @EnableFlags(StatusBarChipsModernization.FLAG_NAME)
    fun chip_projectionStateCasting_hasClickBehavior() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)

            mediaProjectionRepo.mediaProjectionState.value =
                MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)

            assertThat((latest as OngoingActivityChipModel.Shown).clickBehavior)
                .isInstanceOf(OngoingActivityChipModel.ClickBehavior.ExpandAction::class.java)
        }

    @Test
    @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
    fun chip_projectionStateEntireScreen_clickBehaviorShowsScreenCastDialog() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)
            mediaProjectionRepo.mediaProjectionState.value =
                MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)

            val expandAction =
                ((latest as OngoingActivityChipModel.Shown).clickBehavior
                    as OngoingActivityChipModel.ClickBehavior.ExpandAction)
            expandAction.onClick(mockExpandable)

            verify(kosmos.mockDialogTransitionAnimator)
                .show(eq(mockScreenCastDialog), any(), anyBoolean())
        }

    @Test
    @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
    fun chip_projectionStateSingleTask_clickBehaviorShowsScreenCastDialog() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)

            mediaProjectionRepo.mediaProjectionState.value =
                MediaProjectionState.Projecting.SingleTask(
                    CAST_TO_OTHER_DEVICES_PACKAGE,
                    hostDeviceName = null,
                    createTask(taskId = 1),
                )

            val expandAction =
                ((latest as OngoingActivityChipModel.Shown).clickBehavior
                    as OngoingActivityChipModel.ClickBehavior.ExpandAction)
            expandAction.onClick(mockExpandable)

            verify(kosmos.mockDialogTransitionAnimator)
                .show(eq(mockScreenCastDialog), any(), anyBoolean())
        }

    @Test
    @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
    fun chip_routerStateCasting_clickBehaviorShowsGenericCastDialog() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)

            mediaRouterRepo.castDevices.value =
                listOf(
                    CastDevice(
                        state = CastDevice.CastState.Connected,
                        id = "id",
                        name = "name",
                        description = "desc",
                        origin = CastDevice.CastOrigin.MediaRouter,
                    )
                )

            val expandAction =
                ((latest as OngoingActivityChipModel.Shown).clickBehavior
                    as OngoingActivityChipModel.ClickBehavior.ExpandAction)
            expandAction.onClick(mockExpandable)

            verify(kosmos.mockDialogTransitionAnimator)
                .show(eq(mockGenericCastDialog), any(), anyBoolean())
        }
}
+1 −1
Original line number Diff line number Diff line
@@ -650,7 +650,7 @@ class NotifChipsViewModelTest : SysuiTestCase() {
            )
            val chip = latest!![0]

            chip.onClickListener!!.onClick(mock<View>())
            chip.onClickListenerLegacy!!.onClick(mock<View>())

            assertThat(latestChipTap).isEqualTo("clickTest")
        }
+87 −8
Original line number Diff line number Diff line
@@ -17,12 +17,15 @@
package com.android.systemui.statusbar.chips.screenrecord.ui.viewmodel

import android.content.DialogInterface
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.view.View
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.jank.Cuj
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.DialogCuj
import com.android.systemui.animation.Expandable
import com.android.systemui.animation.mockDialogTransitionAnimator
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
@@ -41,8 +44,10 @@ import com.android.systemui.statusbar.chips.ui.model.ColorsModel
import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.getStopActionFromDialog
import com.android.systemui.statusbar.core.StatusBarRootModernization
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
import com.android.systemui.testKosmos
import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
@@ -77,6 +82,8 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
                )
                .thenReturn(chipBackgroundView)
        }
    private val mockExpandable: Expandable =
        mock<Expandable>().apply { whenever(dialogTransitionController(any())).thenReturn(mock()) }

    private val underTest = kosmos.screenRecordChipViewModel

@@ -106,7 +113,7 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {

            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Countdown::class.java)
            assertThat((latest as OngoingActivityChipModel.Shown).icon).isNull()
            assertThat((latest as OngoingActivityChipModel.Shown).onClickListener).isNull()
            assertThat((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy).isNull()
        }

    // The millis we typically get from [ScreenRecordRepository] are around 2995, 1995, and 995.
@@ -177,7 +184,13 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {

            // WHEN the stop action on the dialog is clicked
            val dialogStopAction =
                getStopActionFromDialog(latest, chipView, mockSystemUIDialog, kosmos)
                getStopActionFromDialog(
                    latest,
                    chipView,
                    mockExpandable,
                    mockSystemUIDialog,
                    kosmos,
                )
            dialogStopAction.onClick(mock<DialogInterface>(), 0)

            // THEN both the screen record chip and the share-to-app chip are immediately hidden...
@@ -263,13 +276,14 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
    fun chip_notProjecting_clickListenerShowsDialog() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)
            screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
            mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting

            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy)
            assertThat(clickListener).isNotNull()

            clickListener!!.onClick(chipView)
@@ -279,6 +293,7 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
    fun chip_projectingEntireScreen_clickListenerShowsDialog() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)
@@ -286,7 +301,7 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
            mediaProjectionRepo.mediaProjectionState.value =
                MediaProjectionState.Projecting.EntireScreen("host.package")

            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy)
            assertThat(clickListener).isNotNull()

            clickListener!!.onClick(chipView)
@@ -296,6 +311,7 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
        }

    @Test
    @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
    fun chip_projectingSingleTask_clickListenerShowsDialog() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)
@@ -307,7 +323,7 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
                    FakeActivityTaskManager.createTask(taskId = 1),
                )

            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy)
            assertThat(clickListener).isNotNull()

            clickListener!!.onClick(chipView)
@@ -317,22 +333,85 @@ class ScreenRecordChipViewModelTest : SysuiTestCase() {
        }

    @Test
    fun chip_clickListenerHasCuj() =
    @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
    fun chip_clickListenerHasCujLegacy() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)
            screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
            mediaProjectionRepo.mediaProjectionState.value =
                MediaProjectionState.Projecting.EntireScreen("host.package")

            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListenerLegacy)
            clickListener!!.onClick(chipView)

            val cujCaptor = argumentCaptor<DialogCuj>()
            verify(kosmos.mockDialogTransitionAnimator)
                .showFromView(any(), any(), cujCaptor.capture(), anyBoolean())

            assertThat(cujCaptor.firstValue.cujType)
                .isEqualTo(Cuj.CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP)
            assertThat(cujCaptor.firstValue.tag).contains("Screen record")
        }

    @Test
    @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
    fun chip_recordingState_hasClickBehavior() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)
            screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
            assertThat((latest as OngoingActivityChipModel.Shown).clickBehavior)
                .isInstanceOf(OngoingActivityChipModel.ClickBehavior.ExpandAction::class.java)
        }

    @Test
    @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
    fun chip_notProjecting_expandActionBehaviorShowsDialog() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)
            screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
            mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting

            val expandAction =
                ((latest as OngoingActivityChipModel.Shown).clickBehavior
                    as OngoingActivityChipModel.ClickBehavior.ExpandAction)

            expandAction.onClick(mockExpandable)
            verify(kosmos.mockDialogTransitionAnimator).show(any(), any(), anyBoolean())
        }

    @Test
    @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
    fun chip_projectingEntireScreen_expandActionBehaviorShowsDialog() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)
            screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording

            val expandAction =
                ((latest as OngoingActivityChipModel.Shown).clickBehavior
                    as OngoingActivityChipModel.ClickBehavior.ExpandAction)

            expandAction.onClick(mockExpandable)
            verify(kosmos.mockDialogTransitionAnimator).show(any(), any(), anyBoolean())
        }

    @Test
    @EnableFlags(StatusBarRootModernization.FLAG_NAME, StatusBarChipsModernization.FLAG_NAME)
    fun chip_projectingSingleTask_expandActionBehaviorShowsDialog() =
        testScope.runTest {
            val latest by collectLastValue(underTest.chip)
            screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
            mediaProjectionRepo.mediaProjectionState.value =
                MediaProjectionState.Projecting.SingleTask(
                    "host.package",
                    hostDeviceName = null,
                    FakeActivityTaskManager.createTask(taskId = 1),
                )

            val expandAction =
                ((latest as OngoingActivityChipModel.Shown).clickBehavior
                    as OngoingActivityChipModel.ClickBehavior.ExpandAction)

            expandAction.onClick(mockExpandable)
            verify(kosmos.mockDialogTransitionAnimator).show(any(), any(), anyBoolean())
        }
}
+118 −5

File changed.

Preview size limit exceeded, changes collapsed.

Loading