summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Caitlin Shkuratov <caitlinshk@google.com> 2024-06-13 17:37:33 +0000
committer Caitlin Shkuratov <caitlinshk@google.com> 2024-06-13 19:37:03 +0000
commit19acb607c0edfcc565f83075f0c8caee4fbbd6ea (patch)
tree7194c84f0f91be685036bbf5e95072814b2cf454
parent72b3afc154c2987b4e7f56f5b0866b39f737e12a (diff)
[SB][Screen Chips] Add view models for share-to-app and cast-to-other.
The MediaProjectionChipInteractor is currently handling two different kinds of chips (share-to-app and cast-to-other-device), and also has some UI-specific logic like how to display a dialog when the chip is tapped (which violates clean architecture principles). This CL fixes both those issues by adding two new view models: - ShareToAppChipViewModel - CastToOtherDeviceViewModel Each view model listens to MediaProjectionChipInteractor, and handles the display for *only* their type of chip. This solves our clean architecture problem and helps distinguish these two cases in code more clearly. Note that this does create a diamond in our flow graph: ShareToAppVM MediaProjIntr ---< >-- OngoingActivityChipsVM CastToOtherVM I don't think this will be a problem because only one branch can ever be active at once. This will also be useful later, because the cast-to-other-device events can come from two different sources (MediaProjection and MediaRouter). Splitting cast-to-other-device into its own class up now will make it easier to add in the MediaRouter datasource later. Future CLs will add view models for the call chip and screen record chip so the structure is the same for all chip types. Bug: 332662551 Flag: com.android.systemui.status_bar_screen_sharing_chips Test: verify share-to-app chip still works Test: verify cast-to-other-device chip still works Test: all tests in statusbar.chips Change-Id: I1bd2cc89447b76421fb4126d054beaecc278a81e
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegate.kt (renamed from packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndCastToOtherDeviceDialogDelegate.kt)17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt107
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt102
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/model/ProjectionChipModel.kt43
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegate.kt (renamed from packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndShareToAppDialogDelegate.kt)17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt101
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt (renamed from packages/SystemUI/src/com/android/systemui/statusbar/chips/domain/model/OngoingActivityChipModel.kt)2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt (renamed from packages/SystemUI/src/com/android/systemui/statusbar/chips/domain/interactor/OngoingActivityChipInteractor.kt)13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegateTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndCastToOtherDeviceDialogDelegateTest.kt)11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt216
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt203
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegateTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndShareToAppDialogDelegateTest.kt)8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt218
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModelTest.kt (renamed from packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/domain/interactor/OngoingActivityChipInteractorTest.kt)6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelKosmos.kt35
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorKosmos.kt6
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelKosmos.kt35
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt6
28 files changed, 882 insertions, 329 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt
index 49761ec3b315..7d34d690c634 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt
@@ -23,9 +23,9 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.domain.interactor.OngoingActivityChipInteractor
-import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel
+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.OngoingActivityChipViewModel
import com.android.systemui.statusbar.phone.ongoingcall.data.model.OngoingCallModel
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.OngoingCallRepository
import com.android.systemui.util.time.SystemClock
@@ -37,6 +37,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
/** Interactor for the ongoing phone call chip shown in the status bar. */
+// TODO(b/332662551): Convert this into a view model.
@SysUISingleton
open class CallChipInteractor
@Inject
@@ -45,7 +46,7 @@ constructor(
repository: OngoingCallRepository,
systemClock: SystemClock,
private val activityStarter: ActivityStarter,
-) : OngoingActivityChipInteractor {
+) : OngoingActivityChipViewModel {
override val chip: StateFlow<OngoingActivityChipModel> =
repository.ongoingCallState
.map { state ->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndCastToOtherDeviceDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegate.kt
index 596fbf89a10d..bc0f49218a75 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndCastToOtherDeviceDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegate.kt
@@ -14,19 +14,20 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.chips.mediaprojection.ui.view
+package com.android.systemui.statusbar.chips.casttootherdevice.ui.view
import android.os.Bundle
-import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractor
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel.CastToOtherDeviceChipViewModel.Companion.CAST_TO_OTHER_DEVICE_ICON
+import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
+import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
import com.android.systemui.statusbar.phone.SystemUIDialog
/** A dialog that lets the user stop an ongoing cast-screen-to-other-device event. */
class EndCastToOtherDeviceDialogDelegate(
private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
- private val interactor: MediaProjectionChipInteractor,
- private val state: MediaProjectionState.Projecting,
+ private val stopAction: () -> Unit,
+ private val state: ProjectionChipModel.Projecting,
) : SystemUIDialog.Delegate {
override fun createDialog(): SystemUIDialog {
return endMediaProjectionDialogHelper.createDialog(this)
@@ -34,11 +35,11 @@ class EndCastToOtherDeviceDialogDelegate(
override fun beforeCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
with(dialog) {
- setIcon(MediaProjectionChipInteractor.CAST_TO_OTHER_DEVICE_ICON)
+ setIcon(CAST_TO_OTHER_DEVICE_ICON)
setTitle(R.string.cast_to_other_device_stop_dialog_title)
setMessage(
endMediaProjectionDialogHelper.getDialogMessage(
- state,
+ state.projectionState,
genericMessageResId = R.string.cast_to_other_device_stop_dialog_message,
specificAppMessageResId =
R.string.cast_to_other_device_stop_dialog_message_specific_app,
@@ -48,7 +49,7 @@ class EndCastToOtherDeviceDialogDelegate(
// button is clicked anyway.
setNegativeButton(R.string.close_dialog_button, /* onClick= */ null)
setPositiveButton(R.string.cast_to_other_device_stop_dialog_button) { _, _ ->
- interactor.stopProjecting()
+ stopAction.invoke()
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
new file mode 100644
index 000000000000..a1678bf3d452
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2024 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.statusbar.chips.casttootherdevice.ui.viewmodel
+
+import androidx.annotation.DrawableRes
+import com.android.systemui.animation.DialogTransitionAnimator
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.view.EndCastToOtherDeviceDialogDelegate
+import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractor
+import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
+import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel
+import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickListener
+import com.android.systemui.util.time.SystemClock
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+/**
+ * View model for the cast-to-other-device chip, shown when sharing your phone screen content to a
+ * different device. (Triggered from the Quick Settings Cast tile or from the Settings app.)
+ */
+@SysUISingleton
+class CastToOtherDeviceChipViewModel
+@Inject
+constructor(
+ @Application private val scope: CoroutineScope,
+ private val mediaProjectionChipInteractor: MediaProjectionChipInteractor,
+ private val systemClock: SystemClock,
+ private val dialogTransitionAnimator: DialogTransitionAnimator,
+ private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
+) : OngoingActivityChipViewModel {
+ override val chip: StateFlow<OngoingActivityChipModel> =
+ // TODO(b/342169876): The MediaProjection APIs are not invoked for certain
+ // cast-to-other-device events, like audio-only casting. We should also listen to
+ // MediaRouter APIs to cover all cast events.
+ mediaProjectionChipInteractor.projection
+ .map { projectionModel ->
+ when (projectionModel) {
+ is ProjectionChipModel.NotProjecting -> OngoingActivityChipModel.Hidden
+ is ProjectionChipModel.Projecting -> {
+ if (projectionModel.type != ProjectionChipModel.Type.CAST_TO_OTHER_DEVICE) {
+ OngoingActivityChipModel.Hidden
+ } else {
+ createCastToOtherDeviceChip(projectionModel)
+ }
+ }
+ }
+ }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden)
+
+ /** Stops the currently active projection. */
+ private fun stopProjecting() {
+ mediaProjectionChipInteractor.stopProjecting()
+ }
+
+ private fun createCastToOtherDeviceChip(
+ state: ProjectionChipModel.Projecting,
+ ): OngoingActivityChipModel.Shown {
+ return OngoingActivityChipModel.Shown(
+ icon =
+ Icon.Resource(
+ CAST_TO_OTHER_DEVICE_ICON,
+ ContentDescription.Resource(R.string.accessibility_casting),
+ ),
+ // TODO(b/332662551): Maybe use a MediaProjection API to fetch this time.
+ startTimeMs = systemClock.elapsedRealtime(),
+ createDialogLaunchOnClickListener(
+ createCastToOtherDeviceDialogDelegate(state),
+ dialogTransitionAnimator,
+ ),
+ )
+ }
+
+ private fun createCastToOtherDeviceDialogDelegate(state: ProjectionChipModel.Projecting) =
+ EndCastToOtherDeviceDialogDelegate(
+ endMediaProjectionDialogHelper,
+ stopAction = this::stopProjecting,
+ state,
+ )
+
+ companion object {
+ @DrawableRes val CAST_TO_OTHER_DEVICE_ICON = R.drawable.ic_cast_connected
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
index f6fbe38554a6..20ebae72e01d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
@@ -17,23 +17,12 @@
package com.android.systemui.statusbar.chips.mediaprojection.domain.interactor
import android.content.pm.PackageManager
-import androidx.annotation.DrawableRes
-import com.android.systemui.animation.DialogTransitionAnimator
-import com.android.systemui.common.shared.model.ContentDescription
-import com.android.systemui.common.shared.model.Icon
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.data.repository.MediaProjectionRepository
-import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.domain.interactor.OngoingActivityChipInteractor
-import com.android.systemui.statusbar.chips.domain.interactor.OngoingActivityChipInteractor.Companion.createDialogLaunchOnClickListener
-import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel
-import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndCastToOtherDeviceDialogDelegate
-import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
-import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndShareToAppDialogDelegate
+import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
import com.android.systemui.util.Utils
-import com.android.systemui.util.time.SystemClock
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
@@ -43,14 +32,11 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
/**
- * Interactor for media-projection-related chips in the status bar.
- *
- * There are two kinds of media projection events that will show chips in the status bar:
- * 1) Share-to-app: Sharing your phone screen content to another app on the same device. (Triggered
- * from within each individual app.)
- * 2) Cast-to-other-device: Sharing your phone screen content to a different device. (Triggered from
- * the Quick Settings Cast tile or from the Settings app.) This interactor handles both of those
- * event types (though maybe not audio-only casting -- see b/342169876).
+ * Interactor for media projection events, used to show chips in the status bar for share-to-app and
+ * cast-to-other-device events. See
+ * [com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel.ShareToAppChipViewModel] and
+ * [com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel.CastToOtherDeviceChipViewModel]
+ * for more details on what those events are.
*/
@SysUISingleton
class MediaProjectionChipInteractor
@@ -59,25 +45,24 @@ constructor(
@Application private val scope: CoroutineScope,
private val mediaProjectionRepository: MediaProjectionRepository,
private val packageManager: PackageManager,
- private val systemClock: SystemClock,
- private val dialogTransitionAnimator: DialogTransitionAnimator,
- private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
-) : OngoingActivityChipInteractor {
- override val chip: StateFlow<OngoingActivityChipModel> =
+) {
+ val projection: StateFlow<ProjectionChipModel> =
mediaProjectionRepository.mediaProjectionState
.map { state ->
when (state) {
- is MediaProjectionState.NotProjecting -> OngoingActivityChipModel.Hidden
+ is MediaProjectionState.NotProjecting -> ProjectionChipModel.NotProjecting
is MediaProjectionState.Projecting -> {
- if (isProjectionToOtherDevice(state.hostPackage)) {
- createCastToOtherDeviceChip(state)
- } else {
- createShareToAppChip(state)
- }
+ val type =
+ if (isProjectionToOtherDevice(state.hostPackage)) {
+ ProjectionChipModel.Type.CAST_TO_OTHER_DEVICE
+ } else {
+ ProjectionChipModel.Type.SHARE_TO_APP
+ }
+ ProjectionChipModel.Projecting(type, state)
}
}
}
- .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden)
+ .stateIn(scope, SharingStarted.WhileSubscribed(), ProjectionChipModel.NotProjecting)
/** Stops the currently active projection. */
fun stopProjecting() {
@@ -96,57 +81,4 @@ constructor(
// marked as going to a different device, even if that isn't always true. See b/321078669.
return Utils.isHeadlessRemoteDisplayProvider(packageManager, packageName)
}
-
- private fun createCastToOtherDeviceChip(
- state: MediaProjectionState.Projecting,
- ): OngoingActivityChipModel.Shown {
- return OngoingActivityChipModel.Shown(
- icon =
- Icon.Resource(
- CAST_TO_OTHER_DEVICE_ICON,
- ContentDescription.Resource(R.string.accessibility_casting)
- ),
- // TODO(b/332662551): Maybe use a MediaProjection API to fetch this time.
- startTimeMs = systemClock.elapsedRealtime(),
- createDialogLaunchOnClickListener(
- createCastToOtherDeviceDialogDelegate(state),
- dialogTransitionAnimator,
- ),
- )
- }
-
- private fun createCastToOtherDeviceDialogDelegate(state: MediaProjectionState.Projecting) =
- EndCastToOtherDeviceDialogDelegate(
- endMediaProjectionDialogHelper,
- this@MediaProjectionChipInteractor,
- state,
- )
-
- private fun createShareToAppChip(
- state: MediaProjectionState.Projecting,
- ): OngoingActivityChipModel.Shown {
- return OngoingActivityChipModel.Shown(
- // TODO(b/332662551): Use the right content description.
- icon = Icon.Resource(SHARE_TO_APP_ICON, contentDescription = null),
- // TODO(b/332662551): Maybe use a MediaProjection API to fetch this time.
- startTimeMs = systemClock.elapsedRealtime(),
- createDialogLaunchOnClickListener(
- createShareToAppDialogDelegate(state),
- dialogTransitionAnimator
- ),
- )
- }
-
- private fun createShareToAppDialogDelegate(state: MediaProjectionState.Projecting) =
- EndShareToAppDialogDelegate(
- endMediaProjectionDialogHelper,
- this@MediaProjectionChipInteractor,
- state,
- )
-
- companion object {
- // TODO(b/332662551): Use the right icon.
- @DrawableRes val SHARE_TO_APP_ICON = R.drawable.ic_screenshot_share
- @DrawableRes val CAST_TO_OTHER_DEVICE_ICON = R.drawable.ic_cast_connected
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/model/ProjectionChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/model/ProjectionChipModel.kt
new file mode 100644
index 000000000000..85682f5eb8ff
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/model/ProjectionChipModel.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 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.statusbar.chips.mediaprojection.domain.model
+
+import com.android.systemui.mediaprojection.data.model.MediaProjectionState
+
+/**
+ * Represents the state of media projection needed to show chips in the status bar. In particular,
+ * also includes what type of projection is occurring.
+ */
+sealed class ProjectionChipModel {
+ /** There is no media being projected. */
+ data object NotProjecting : ProjectionChipModel()
+
+ /** Media is currently being projected. */
+ data class Projecting(
+ val type: Type,
+ val projectionState: MediaProjectionState.Projecting,
+ ) : ProjectionChipModel()
+
+ enum class Type {
+ /**
+ * This projection is sharing your phone screen content to another app on the same device.
+ */
+ SHARE_TO_APP,
+ /** This projection is sharing your phone screen content to a different device. */
+ CAST_TO_OTHER_DEVICE,
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
index 59b2e1739378..525d3b977725 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
@@ -26,11 +26,11 @@ import com.android.systemui.mediaprojection.data.repository.MediaProjectionRepos
import com.android.systemui.res.R
import com.android.systemui.screenrecord.data.model.ScreenRecordModel
import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository
-import com.android.systemui.statusbar.chips.domain.interactor.OngoingActivityChipInteractor
-import com.android.systemui.statusbar.chips.domain.interactor.OngoingActivityChipInteractor.Companion.createDialogLaunchOnClickListener
-import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
import com.android.systemui.statusbar.chips.screenrecord.ui.view.EndScreenRecordingDialogDelegate
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel
+import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickListener
import com.android.systemui.util.time.SystemClock
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -41,6 +41,7 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
/** Interactor for the screen recording chip shown in the status bar. */
+// TODO(b/332662551): Convert this into a view model.
@SysUISingleton
class ScreenRecordChipInteractor
@Inject
@@ -51,7 +52,7 @@ constructor(
private val systemClock: SystemClock,
private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
private val dialogTransitionAnimator: DialogTransitionAnimator,
-) : OngoingActivityChipInteractor {
+) : OngoingActivityChipViewModel {
override val chip: StateFlow<OngoingActivityChipModel> =
// ScreenRecordRepository has the main "is the screen being recorded?" state, and
// MediaProjectionRepository has information about what specifically is being recorded (a
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndShareToAppDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegate.kt
index 749a11f193c6..7e7ef402b226 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndShareToAppDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegate.kt
@@ -14,19 +14,20 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.chips.mediaprojection.ui.view
+package com.android.systemui.statusbar.chips.sharetoapp.ui.view
import android.os.Bundle
-import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractor
+import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
+import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
+import com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel.ShareToAppChipViewModel.Companion.SHARE_TO_APP_ICON
import com.android.systemui.statusbar.phone.SystemUIDialog
/** A dialog that lets the user stop an ongoing share-screen-to-app event. */
class EndShareToAppDialogDelegate(
private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
- private val interactor: MediaProjectionChipInteractor,
- private val state: MediaProjectionState.Projecting,
+ private val stopAction: () -> Unit,
+ private val state: ProjectionChipModel.Projecting,
) : SystemUIDialog.Delegate {
override fun createDialog(): SystemUIDialog {
return endMediaProjectionDialogHelper.createDialog(this)
@@ -34,11 +35,11 @@ class EndShareToAppDialogDelegate(
override fun beforeCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
with(dialog) {
- setIcon(MediaProjectionChipInteractor.SHARE_TO_APP_ICON)
+ setIcon(SHARE_TO_APP_ICON)
setTitle(R.string.share_to_app_stop_dialog_title)
setMessage(
endMediaProjectionDialogHelper.getDialogMessage(
- state,
+ state.projectionState,
genericMessageResId = R.string.share_to_app_stop_dialog_message,
specificAppMessageResId = R.string.share_to_app_stop_dialog_message_specific_app
)
@@ -47,7 +48,7 @@ class EndShareToAppDialogDelegate(
// button is clicked anyway.
setNegativeButton(R.string.close_dialog_button, /* onClick= */ null)
setPositiveButton(R.string.share_to_app_stop_dialog_button) { _, _ ->
- interactor.stopProjecting()
+ stopAction.invoke()
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
new file mode 100644
index 000000000000..dc4100269702
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2024 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.statusbar.chips.sharetoapp.ui.viewmodel
+
+import androidx.annotation.DrawableRes
+import com.android.systemui.animation.DialogTransitionAnimator
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractor
+import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
+import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
+import com.android.systemui.statusbar.chips.sharetoapp.ui.view.EndShareToAppDialogDelegate
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel
+import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickListener
+import com.android.systemui.util.time.SystemClock
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+/**
+ * View model for the share-to-app chip, shown when sharing your phone screen content to another app
+ * on the same device. (Triggered from within each individual app.)
+ */
+@SysUISingleton
+class ShareToAppChipViewModel
+@Inject
+constructor(
+ @Application private val scope: CoroutineScope,
+ private val mediaProjectionChipInteractor: MediaProjectionChipInteractor,
+ private val systemClock: SystemClock,
+ private val dialogTransitionAnimator: DialogTransitionAnimator,
+ private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
+) : OngoingActivityChipViewModel {
+ override val chip: StateFlow<OngoingActivityChipModel> =
+ mediaProjectionChipInteractor.projection
+ .map { projectionModel ->
+ when (projectionModel) {
+ is ProjectionChipModel.NotProjecting -> OngoingActivityChipModel.Hidden
+ is ProjectionChipModel.Projecting -> {
+ if (projectionModel.type != ProjectionChipModel.Type.SHARE_TO_APP) {
+ OngoingActivityChipModel.Hidden
+ } else {
+ createShareToAppChip(projectionModel)
+ }
+ }
+ }
+ }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden)
+
+ /** Stops the currently active projection. */
+ private fun stopProjecting() {
+ mediaProjectionChipInteractor.stopProjecting()
+ }
+
+ private fun createShareToAppChip(
+ state: ProjectionChipModel.Projecting,
+ ): OngoingActivityChipModel.Shown {
+ return OngoingActivityChipModel.Shown(
+ // TODO(b/332662551): Use the right content description.
+ icon = Icon.Resource(SHARE_TO_APP_ICON, contentDescription = null),
+ // TODO(b/332662551): Maybe use a MediaProjection API to fetch this time.
+ startTimeMs = systemClock.elapsedRealtime(),
+ createDialogLaunchOnClickListener(
+ createShareToAppDialogDelegate(state),
+ dialogTransitionAnimator
+ ),
+ )
+ }
+
+ private fun createShareToAppDialogDelegate(state: ProjectionChipModel.Projecting) =
+ EndShareToAppDialogDelegate(
+ endMediaProjectionDialogHelper,
+ stopAction = this::stopProjecting,
+ state,
+ )
+
+ companion object {
+ // TODO(b/332662551): Use the right icon.
+ @DrawableRes val SHARE_TO_APP_ICON = R.drawable.ic_screenshot_share
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/domain/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
index c7539181fe31..e63713bf1602 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/domain/model/OngoingActivityChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.chips.domain.model
+package com.android.systemui.statusbar.chips.ui.model
import android.view.View
import com.android.systemui.common.shared.model.Icon
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/domain/interactor/OngoingActivityChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt
index 086a32dfe49c..0dbf5d613038 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/domain/interactor/OngoingActivityChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModel.kt
@@ -14,19 +14,22 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.chips.domain.interactor
+package com.android.systemui.statusbar.chips.ui.viewmodel
import android.view.View
import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.phone.SystemUIDialog
import kotlinx.coroutines.flow.StateFlow
-/** Interface for an interactor that knows the state of a single type of ongoing activity chip. */
-interface OngoingActivityChipInteractor {
- /** A flow modeling the chip that should be shown. */
+/**
+ * Interface for a view model that knows the display requirements for a single type of ongoing
+ * activity chip.
+ */
+interface OngoingActivityChipViewModel {
+ /** A flow modeling the chip that should be shown (or not shown). */
val chip: StateFlow<OngoingActivityChipModel>
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
index edb2983720a8..f5b1b8f18de5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
@@ -19,9 +19,10 @@ package com.android.systemui.statusbar.chips.ui.viewmodel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.statusbar.chips.call.domain.interactor.CallChipInteractor
-import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel
-import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractor
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel.CastToOtherDeviceChipViewModel
import com.android.systemui.statusbar.chips.screenrecord.domain.interactor.ScreenRecordChipInteractor
+import com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel.ShareToAppChipViewModel
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
@@ -41,10 +42,10 @@ class OngoingActivityChipsViewModel
constructor(
@Application scope: CoroutineScope,
screenRecordChipInteractor: ScreenRecordChipInteractor,
- mediaProjectionChipInteractor: MediaProjectionChipInteractor,
+ shareToAppChipViewModel: ShareToAppChipViewModel,
+ castToOtherDeviceChipViewModel: CastToOtherDeviceChipViewModel,
callChipInteractor: CallChipInteractor,
) {
-
/**
* A flow modeling the chip that should be shown in the status bar after accounting for possibly
* multiple ongoing activities.
@@ -55,9 +56,10 @@ constructor(
val chip: StateFlow<OngoingActivityChipModel> =
combine(
screenRecordChipInteractor.chip,
- mediaProjectionChipInteractor.chip,
- callChipInteractor.chip
- ) { screenRecord, mediaProjection, call ->
+ shareToAppChipViewModel.chip,
+ castToOtherDeviceChipViewModel.chip,
+ callChipInteractor.chip,
+ ) { screenRecord, shareToApp, castToOtherDevice, call ->
// This `when` statement shows the priority order of the chips
when {
// Screen recording also activates the media projection APIs, so whenever the
@@ -65,7 +67,8 @@ constructor(
// active. We want the screen-recording-specific chip shown in this case, so we
// give the screen recording chip priority. See b/296461748.
screenRecord is OngoingActivityChipModel.Shown -> screenRecord
- mediaProjection is OngoingActivityChipModel.Shown -> mediaProjection
+ shareToApp is OngoingActivityChipModel.Shown -> shareToApp
+ castToOtherDevice is OngoingActivityChipModel.Shown -> castToOtherDevice
else -> call
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
index 44b5bafc0859..7644653306be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
@@ -27,8 +27,8 @@ import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.binder.ChipChronometerBinder
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipChronometer
import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt
index bb3a67ed49bd..95d924889301 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt
@@ -24,7 +24,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
import com.android.systemui.keyguard.shared.model.TransitionState
-import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModel
import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt
index 11f1f80f6d45..144482120600 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorTest.kt
@@ -26,7 +26,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.plugins.activityStarter
import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.phone.ongoingcall.data.model.OngoingCallModel
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndCastToOtherDeviceDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegateTest.kt
index 7b676e2b34e4..c6fb481d2d54 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndCastToOtherDeviceDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegateTest.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.chips.mediaprojection.ui.view
+package com.android.systemui.statusbar.chips.casttootherdevice.ui.view
import android.content.ComponentName
import android.content.DialogInterface
@@ -31,6 +31,8 @@ import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionR
import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
import com.android.systemui.res.R
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.mediaProjectionChipInteractor
+import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
+import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
@@ -142,8 +144,11 @@ class EndCastToOtherDeviceDialogDelegateTest : SysuiTestCase() {
underTest =
EndCastToOtherDeviceDialogDelegate(
kosmos.endMediaProjectionDialogHelper,
- kosmos.mediaProjectionChipInteractor,
- state,
+ stopAction = kosmos.mediaProjectionChipInteractor::stopProjecting,
+ ProjectionChipModel.Projecting(
+ ProjectionChipModel.Type.CAST_TO_OTHER_DEVICE,
+ state,
+ ),
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
new file mode 100644
index 000000000000..142f5ab34f8c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2024 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.statusbar.chips.casttootherdevice.ui.viewmodel
+
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.mockDialogTransitionAnimator
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.mediaprojection.data.model.MediaProjectionState
+import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
+import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.view.EndCastToOtherDeviceDialogDelegate
+import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.CAST_TO_OTHER_DEVICES_PACKAGE
+import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.NORMAL_PACKAGE
+import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.setUpPackageManagerForMediaProjection
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
+import com.android.systemui.util.time.fakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.mockito.ArgumentMatchers
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@SmallTest
+class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
+ private val kosmos = Kosmos().also { it.testCase = this }
+ private val testScope = kosmos.testScope
+ private val mediaProjectionRepo = kosmos.fakeMediaProjectionRepository
+ private val systemClock = kosmos.fakeSystemClock
+
+ private val mockCastDialog = mock<SystemUIDialog>()
+
+ private val chipBackgroundView = mock<ChipBackgroundContainer>()
+ private val chipView =
+ mock<View>().apply {
+ whenever(
+ this.requireViewById<ChipBackgroundContainer>(
+ R.id.ongoing_activity_chip_background
+ )
+ )
+ .thenReturn(chipBackgroundView)
+ }
+
+ private val underTest = kosmos.castToOtherDeviceChipViewModel
+
+ @Before
+ fun setUp() {
+ setUpPackageManagerForMediaProjection(kosmos)
+
+ whenever(kosmos.mockSystemUIDialogFactory.create(any<EndCastToOtherDeviceDialogDelegate>()))
+ .thenReturn(mockCastDialog)
+ }
+
+ @Test
+ fun chip_notProjectingState_isHidden() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+ }
+
+ @Test
+ fun chip_singleTaskState_otherDevicesPackage_isShown() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ CAST_TO_OTHER_DEVICES_PACKAGE,
+ createTask(taskId = 1),
+ )
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+ val icon = (latest as OngoingActivityChipModel.Shown).icon
+ assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+ }
+
+ @Test
+ fun chip_entireScreenState_otherDevicesPackage_isShown() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+ val icon = (latest as OngoingActivityChipModel.Shown).icon
+ assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+ }
+
+ @Test
+ fun chip_singleTaskState_normalPackage_isHidden() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(NORMAL_PACKAGE, createTask(taskId = 1))
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+ }
+
+ @Test
+ fun chip_entireScreenState_normalPackage_isHidden() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+ }
+
+ @Test
+ fun chip_timeResetsOnEachNewShare() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ systemClock.setElapsedRealtime(1234)
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+ assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(1234)
+
+ mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+
+ systemClock.setElapsedRealtime(5678)
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ CAST_TO_OTHER_DEVICES_PACKAGE,
+ createTask(taskId = 1),
+ )
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+ assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(5678)
+ }
+
+ @Test
+ fun chip_entireScreen_clickListenerShowsCastDialog() =
+ 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)
+
+ // Dialogs must be created on the main thread
+ context.mainExecutor.execute {
+ clickListener.onClick(chipView)
+ verify(kosmos.mockDialogTransitionAnimator)
+ .showFromView(
+ eq(mockCastDialog),
+ eq(chipBackgroundView),
+ eq(null),
+ ArgumentMatchers.anyBoolean(),
+ )
+ }
+ }
+
+ @Test
+ fun chip_singleTask_clickListenerShowsCastDialog() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ CAST_TO_OTHER_DEVICES_PACKAGE,
+ createTask(taskId = 1),
+ )
+
+ val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
+
+ // Dialogs must be created on the main thread
+ context.mainExecutor.execute {
+ clickListener.onClick(chipView)
+ verify(kosmos.mockDialogTransitionAnimator)
+ .showFromView(
+ eq(mockCastDialog),
+ eq(chipBackgroundView),
+ eq(null),
+ ArgumentMatchers.anyBoolean(),
+ )
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt
index 327eec494b3c..7eb4ca06b80d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorTest.kt
@@ -21,11 +21,8 @@ import android.content.Intent
import android.content.packageManager
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
-import android.view.View
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.animation.mockDialogTransitionAnimator
-import com.android.systemui.common.shared.model.Icon
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testCase
@@ -33,25 +30,15 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
-import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel
-import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndCastToOtherDeviceDialogDelegate
-import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndShareToAppDialogDelegate
-import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
-import com.android.systemui.statusbar.phone.SystemUIDialog
-import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
-import com.android.systemui.util.time.fakeSystemClock
+import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import kotlinx.coroutines.test.runTest
import org.junit.Before
-import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito.doAnswer
import org.mockito.kotlin.any
-import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
-import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@SmallTest
@@ -59,48 +46,28 @@ class MediaProjectionChipInteractorTest : SysuiTestCase() {
private val kosmos = Kosmos().also { it.testCase = this }
private val testScope = kosmos.testScope
private val mediaProjectionRepo = kosmos.fakeMediaProjectionRepository
- private val systemClock = kosmos.fakeSystemClock
-
- private val mockCastDialog = mock<SystemUIDialog>()
- private val mockShareDialog = mock<SystemUIDialog>()
-
- private val chipBackgroundView = mock<ChipBackgroundContainer>()
- private val chipView =
- mock<View>().apply {
- whenever(
- this.requireViewById<ChipBackgroundContainer>(
- R.id.ongoing_activity_chip_background
- )
- )
- .thenReturn(chipBackgroundView)
- }
@Before
fun setUp() {
setUpPackageManagerForMediaProjection(kosmos)
-
- whenever(kosmos.mockSystemUIDialogFactory.create(any<EndCastToOtherDeviceDialogDelegate>()))
- .thenReturn(mockCastDialog)
- whenever(kosmos.mockSystemUIDialogFactory.create(any<EndShareToAppDialogDelegate>()))
- .thenReturn(mockShareDialog)
}
private val underTest = kosmos.mediaProjectionChipInteractor
@Test
- fun chip_notProjectingState_isHidden() =
+ fun projection_notProjectingState_isNotProjecting() =
testScope.runTest {
- val latest by collectLastValue(underTest.chip)
+ val latest by collectLastValue(underTest.projection)
mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
- assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+ assertThat(latest).isInstanceOf(ProjectionChipModel.NotProjecting::class.java)
}
@Test
- fun chip_singleTaskState_otherDevicesPackage_castToOtherDeviceChipShown() =
+ fun projection_singleTaskState_otherDevicesPackage_isCastToOtherDeviceType() =
testScope.runTest {
- val latest by collectLastValue(underTest.chip)
+ val latest by collectLastValue(underTest.projection)
mediaProjectionRepo.mediaProjectionState.value =
MediaProjectionState.Projecting.SingleTask(
@@ -108,166 +75,50 @@ class MediaProjectionChipInteractorTest : SysuiTestCase() {
createTask(taskId = 1)
)
- assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
- }
-
- @Test
- fun chip_entireScreenState_otherDevicesPackage_castToOtherDeviceChipShown() =
- testScope.runTest {
- val latest by collectLastValue(underTest.chip)
-
- mediaProjectionRepo.mediaProjectionState.value =
- MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
-
- assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
- }
-
- @Test
- fun chip_singleTaskState_normalPackage_shareToAppChipShown() =
- testScope.runTest {
- val latest by collectLastValue(underTest.chip)
-
- mediaProjectionRepo.mediaProjectionState.value =
- MediaProjectionState.Projecting.SingleTask(NORMAL_PACKAGE, createTask(taskId = 1))
-
- assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_screenshot_share)
+ assertThat(latest).isInstanceOf(ProjectionChipModel.Projecting::class.java)
+ assertThat((latest as ProjectionChipModel.Projecting).type)
+ .isEqualTo(ProjectionChipModel.Type.CAST_TO_OTHER_DEVICE)
}
@Test
- fun chip_entireScreenState_normalPackage_shareToAppChipShown() =
+ fun projection_entireScreenState_otherDevicesPackage_isCastToOtherDeviceChipType() =
testScope.runTest {
- val latest by collectLastValue(underTest.chip)
-
- mediaProjectionRepo.mediaProjectionState.value =
- MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
-
- assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
- val icon = (latest as OngoingActivityChipModel.Shown).icon
- assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_screenshot_share)
- }
-
- @Test
- fun chip_timeResetsOnEachNewShare() =
- testScope.runTest {
- val latest by collectLastValue(underTest.chip)
-
- systemClock.setElapsedRealtime(1234)
- mediaProjectionRepo.mediaProjectionState.value =
- MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
-
- assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
- assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(1234)
-
- mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
- assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+ val latest by collectLastValue(underTest.projection)
- systemClock.setElapsedRealtime(5678)
mediaProjectionRepo.mediaProjectionState.value =
- MediaProjectionState.Projecting.SingleTask(
+ MediaProjectionState.Projecting.EntireScreen(
CAST_TO_OTHER_DEVICES_PACKAGE,
- createTask(taskId = 1)
)
- assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
- assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(5678)
+ assertThat(latest).isInstanceOf(ProjectionChipModel.Projecting::class.java)
+ assertThat((latest as ProjectionChipModel.Projecting).type)
+ .isEqualTo(ProjectionChipModel.Type.CAST_TO_OTHER_DEVICE)
}
@Test
- fun chip_castToOtherDevice_entireScreen_clickListenerShowsCastDialog() =
+ fun projection_singleTaskState_normalPackage_isShareToAppChipType() =
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)
-
- // Dialogs must be created on the main thread
- context.mainExecutor.execute {
- clickListener.onClick(chipView)
- verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- eq(mockCastDialog),
- eq(chipBackgroundView),
- eq(null),
- anyBoolean(),
- )
- }
- }
-
- @Test
- fun chip_castToOtherDevice_singleTask_clickListenerShowsCastDialog() =
- testScope.runTest {
- val latest by collectLastValue(underTest.chip)
+ val latest by collectLastValue(underTest.projection)
mediaProjectionRepo.mediaProjectionState.value =
- MediaProjectionState.Projecting.SingleTask(
- CAST_TO_OTHER_DEVICES_PACKAGE,
- createTask(taskId = 1)
- )
-
- val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
+ MediaProjectionState.Projecting.SingleTask(NORMAL_PACKAGE, createTask(taskId = 1))
- // Dialogs must be created on the main thread
- context.mainExecutor.execute {
- clickListener.onClick(chipView)
- verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- eq(mockCastDialog),
- eq(chipBackgroundView),
- eq(null),
- anyBoolean(),
- )
- }
+ assertThat(latest).isInstanceOf(ProjectionChipModel.Projecting::class.java)
+ assertThat((latest as ProjectionChipModel.Projecting).type)
+ .isEqualTo(ProjectionChipModel.Type.SHARE_TO_APP)
}
@Test
- fun chip_shareToApp_entireScreen_clickListenerShowsShareDialog() =
+ fun projection_entireScreenState_normalPackage_isShareToAppChipType() =
testScope.runTest {
- val latest by collectLastValue(underTest.chip)
- mediaProjectionRepo.mediaProjectionState.value =
- MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
+ val latest by collectLastValue(underTest.projection)
- val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
-
- // Dialogs must be created on the main thread
- context.mainExecutor.execute {
- clickListener.onClick(chipView)
- verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- eq(mockShareDialog),
- eq(chipBackgroundView),
- eq(null),
- anyBoolean(),
- )
- }
- }
-
- @Test
- fun chip_shareToApp_singleTask_clickListenerShowsShareDialog() =
- testScope.runTest {
- val latest by collectLastValue(underTest.chip)
mediaProjectionRepo.mediaProjectionState.value =
- MediaProjectionState.Projecting.SingleTask(NORMAL_PACKAGE, createTask(taskId = 1))
-
- val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
+ MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
- // Dialogs must be created on the main thread
- context.mainExecutor.execute {
- clickListener.onClick(chipView)
- verify(kosmos.mockDialogTransitionAnimator)
- .showFromView(
- eq(mockShareDialog),
- eq(chipBackgroundView),
- eq(null),
- anyBoolean(),
- )
- }
+ assertThat(latest).isInstanceOf(ProjectionChipModel.Projecting::class.java)
+ assertThat((latest as ProjectionChipModel.Projecting).type)
+ .isEqualTo(ProjectionChipModel.Type.SHARE_TO_APP)
}
companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
index 03fd5031e5f2..f6185c48c408 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt
@@ -31,8 +31,8 @@ import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager
import com.android.systemui.res.R
import com.android.systemui.screenrecord.data.model.ScreenRecordModel
import com.android.systemui.screenrecord.data.repository.screenRecordRepository
-import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.screenrecord.ui.view.EndScreenRecordingDialogDelegate
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndShareToAppDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegateTest.kt
index 4ddca521abd3..4c2546e141fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndShareToAppDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegateTest.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.chips.mediaprojection.ui.view
+package com.android.systemui.statusbar.chips.sharetoapp.ui.view
import android.content.ComponentName
import android.content.DialogInterface
@@ -31,6 +31,8 @@ import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionR
import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
import com.android.systemui.res.R
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.mediaProjectionChipInteractor
+import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
+import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
import com.android.systemui.statusbar.phone.SystemUIDialog
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
@@ -141,8 +143,8 @@ class EndShareToAppDialogDelegateTest : SysuiTestCase() {
underTest =
EndShareToAppDialogDelegate(
kosmos.endMediaProjectionDialogHelper,
- kosmos.mediaProjectionChipInteractor,
- state,
+ stopAction = kosmos.mediaProjectionChipInteractor::stopProjecting,
+ ProjectionChipModel.Projecting(ProjectionChipModel.Type.SHARE_TO_APP, state),
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
new file mode 100644
index 000000000000..9e54d9985549
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2024 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.statusbar.chips.sharetoapp.ui.viewmodel
+
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.mockDialogTransitionAnimator
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.mediaprojection.data.model.MediaProjectionState
+import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
+import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.CAST_TO_OTHER_DEVICES_PACKAGE
+import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.NORMAL_PACKAGE
+import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.setUpPackageManagerForMediaProjection
+import com.android.systemui.statusbar.chips.sharetoapp.ui.view.EndShareToAppDialogDelegate
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
+import com.android.systemui.util.time.fakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.mockito.ArgumentMatchers
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@SmallTest
+class ShareToAppChipViewModelTest : SysuiTestCase() {
+ private val kosmos = Kosmos().also { it.testCase = this }
+ private val testScope = kosmos.testScope
+ private val mediaProjectionRepo = kosmos.fakeMediaProjectionRepository
+ private val systemClock = kosmos.fakeSystemClock
+
+ private val mockShareDialog = mock<SystemUIDialog>()
+
+ private val chipBackgroundView = mock<ChipBackgroundContainer>()
+ private val chipView =
+ mock<View>().apply {
+ whenever(
+ this.requireViewById<ChipBackgroundContainer>(
+ R.id.ongoing_activity_chip_background
+ )
+ )
+ .thenReturn(chipBackgroundView)
+ }
+
+ private val underTest = kosmos.shareToAppChipViewModel
+
+ @Before
+ fun setUp() {
+ setUpPackageManagerForMediaProjection(kosmos)
+
+ whenever(kosmos.mockSystemUIDialogFactory.create(any<EndShareToAppDialogDelegate>()))
+ .thenReturn(mockShareDialog)
+ }
+
+ @Test
+ fun chip_notProjectingState_isHidden() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+ }
+
+ @Test
+ fun chip_singleTaskState_otherDevicesPackage_isHidden() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ CAST_TO_OTHER_DEVICES_PACKAGE,
+ createTask(taskId = 1),
+ )
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+ }
+
+ @Test
+ fun chip_entireScreenState_otherDevicesPackage_isHidden() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+ }
+
+ @Test
+ fun chip_singleTaskState_normalPackage_isShown() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ NORMAL_PACKAGE,
+ createTask(taskId = 1),
+ )
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+ val icon = (latest as OngoingActivityChipModel.Shown).icon
+ assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_screenshot_share)
+ }
+
+ @Test
+ fun chip_entireScreenState_normalPackage_isShown() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+ val icon = (latest as OngoingActivityChipModel.Shown).icon
+ assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_screenshot_share)
+ }
+
+ @Test
+ fun chip_timeResetsOnEachNewShare() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+
+ systemClock.setElapsedRealtime(1234)
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+ assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(1234)
+
+ mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+
+ systemClock.setElapsedRealtime(5678)
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ NORMAL_PACKAGE,
+ createTask(taskId = 1),
+ )
+
+ assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+ assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(5678)
+ }
+
+ @Test
+ fun chip_entireScreen_clickListenerShowsShareDialog() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
+
+ val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
+
+ // Dialogs must be created on the main thread
+ context.mainExecutor.execute {
+ clickListener.onClick(chipView)
+ verify(kosmos.mockDialogTransitionAnimator)
+ .showFromView(
+ eq(mockShareDialog),
+ eq(chipBackgroundView),
+ eq(null),
+ ArgumentMatchers.anyBoolean(),
+ )
+ }
+ }
+
+ @Test
+ fun chip_singleTask_clickListenerShowsShareDialog() =
+ testScope.runTest {
+ val latest by collectLastValue(underTest.chip)
+ mediaProjectionRepo.mediaProjectionState.value =
+ MediaProjectionState.Projecting.SingleTask(
+ NORMAL_PACKAGE,
+ createTask(taskId = 1),
+ )
+
+ val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
+
+ // Dialogs must be created on the main thread
+ context.mainExecutor.execute {
+ clickListener.onClick(chipView)
+ verify(kosmos.mockDialogTransitionAnimator)
+ .showFromView(
+ eq(mockShareDialog),
+ eq(chipBackgroundView),
+ eq(null),
+ ArgumentMatchers.anyBoolean(),
+ )
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/domain/interactor/OngoingActivityChipInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModelTest.kt
index abb6e2b02103..c9c7359a89eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/domain/interactor/OngoingActivityChipInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipViewModelTest.kt
@@ -14,15 +14,15 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.chips.domain.interactor
+package com.android.systemui.statusbar.chips.ui.viewmodel
import android.view.View
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.DialogTransitionAnimator
import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.domain.interactor.OngoingActivityChipInteractor.Companion.createDialogLaunchOnClickListener
import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
+import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickListener
import com.android.systemui.statusbar.phone.SystemUIDialog
import kotlin.test.Test
import org.mockito.ArgumentMatchers.anyBoolean
@@ -32,7 +32,7 @@ import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
@SmallTest
-class OngoingActivityChipInteractorTest : SysuiTestCase() {
+class OngoingActivityChipViewModelTest : SysuiTestCase() {
private val mockSystemUIDialog = mock<SystemUIDialog>()
private val dialogDelegate = SystemUIDialog.Delegate { mockSystemUIDialog }
private val dialogTransitionAnimator = mock<DialogTransitionAnimator>()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
index 0d7b87b95785..57beb3ecc729 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
@@ -29,9 +29,9 @@ import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager
import com.android.systemui.res.R
import com.android.systemui.screenrecord.data.model.ScreenRecordModel
import com.android.systemui.screenrecord.data.repository.screenRecordRepository
-import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.NORMAL_PACKAGE
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.setUpPackageManagerForMediaProjection
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.phone.ongoingcall.data.model.OngoingCallModel
import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
import com.google.common.truth.Truth.assertThat
@@ -92,7 +92,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
}
@Test
- fun chip_screenRecordShowAndMediaProjectionShow_screenRecordShown() =
+ fun chip_screenRecordShowAndShareToAppShow_screenRecordShown() =
testScope.runTest {
screenRecordState.value = ScreenRecordModel.Recording
mediaProjectionState.value =
@@ -105,7 +105,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
}
@Test
- fun chip_mediaProjectionShowAndCallShow_mediaProjectionShown() =
+ fun chip_shareToAppShowAndCallShow_shareToAppShown() =
testScope.runTest {
screenRecordState.value = ScreenRecordModel.DoingNothing
mediaProjectionState.value =
@@ -118,9 +118,10 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() {
}
@Test
- fun chip_screenRecordAndMediaProjectionHideAndCallShown_callShown() =
+ fun chip_screenRecordAndShareToAppAndCastToOtherHideAndCallShown_callShown() =
testScope.runTest {
screenRecordState.value = ScreenRecordModel.DoingNothing
+ // MediaProjection covers both share-to-app and cast-to-other-device
mediaProjectionState.value = MediaProjectionState.NotProjecting
callRepo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 34, intent = null))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt
index b8299e5ef3ad..92de8662928f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt
@@ -37,9 +37,9 @@ import com.android.systemui.mediaprojection.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
import com.android.systemui.screenrecord.data.model.ScreenRecordModel
import com.android.systemui.screenrecord.data.repository.screenRecordRepository
-import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.NORMAL_PACKAGE
import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.setUpPackageManagerForMediaProjection
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsScreenRecordChip
import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModelTest.Companion.assertIsShareToAppChip
import com.android.systemui.statusbar.chips.ui.viewmodel.ongoingActivityChipsViewModel
@@ -64,10 +64,11 @@ import org.junit.Test
@SmallTest
@OptIn(ExperimentalCoroutinesApi::class)
class CollapsedStatusBarViewModelImplTest : SysuiTestCase() {
- private val kosmos = Kosmos().also {
- it.testCase = this
- it.testDispatcher = UnconfinedTestDispatcher()
- }
+ private val kosmos =
+ Kosmos().also {
+ it.testCase = this
+ it.testDispatcher = UnconfinedTestDispatcher()
+ }
private val testScope = kosmos.testScope
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt
index c3c9907bc891..b66eed05fa0d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt
@@ -16,7 +16,7 @@
package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel
-import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelKosmos.kt
new file mode 100644
index 000000000000..4baa8d0b117e
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelKosmos.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 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.statusbar.chips.casttootherdevice.ui.viewmodel
+
+import com.android.systemui.animation.mockDialogTransitionAnimator
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.mediaProjectionChipInteractor
+import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
+import com.android.systemui.util.time.fakeSystemClock
+
+val Kosmos.castToOtherDeviceChipViewModel: CastToOtherDeviceChipViewModel by
+ Kosmos.Fixture {
+ CastToOtherDeviceChipViewModel(
+ scope = applicationCoroutineScope,
+ mediaProjectionChipInteractor = mediaProjectionChipInteractor,
+ systemClock = fakeSystemClock,
+ endMediaProjectionDialogHelper = endMediaProjectionDialogHelper,
+ dialogTransitionAnimator = mockDialogTransitionAnimator,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorKosmos.kt
index 9d2281167fbf..6812a9df8973 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorKosmos.kt
@@ -17,12 +17,9 @@
package com.android.systemui.statusbar.chips.mediaprojection.domain.interactor
import android.content.packageManager
-import com.android.systemui.animation.mockDialogTransitionAnimator
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
-import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
-import com.android.systemui.util.time.fakeSystemClock
val Kosmos.mediaProjectionChipInteractor: MediaProjectionChipInteractor by
Kosmos.Fixture {
@@ -30,8 +27,5 @@ val Kosmos.mediaProjectionChipInteractor: MediaProjectionChipInteractor by
scope = applicationCoroutineScope,
mediaProjectionRepository = fakeMediaProjectionRepository,
packageManager = packageManager,
- systemClock = fakeSystemClock,
- endMediaProjectionDialogHelper = endMediaProjectionDialogHelper,
- dialogTransitionAnimator = mockDialogTransitionAnimator,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelKosmos.kt
new file mode 100644
index 000000000000..535f81a7d63e
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelKosmos.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 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.statusbar.chips.sharetoapp.ui.viewmodel
+
+import com.android.systemui.animation.mockDialogTransitionAnimator
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.mediaProjectionChipInteractor
+import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
+import com.android.systemui.util.time.fakeSystemClock
+
+val Kosmos.shareToAppChipViewModel: ShareToAppChipViewModel by
+ Kosmos.Fixture {
+ ShareToAppChipViewModel(
+ scope = applicationCoroutineScope,
+ mediaProjectionChipInteractor = mediaProjectionChipInteractor,
+ systemClock = fakeSystemClock,
+ endMediaProjectionDialogHelper = endMediaProjectionDialogHelper,
+ dialogTransitionAnimator = mockDialogTransitionAnimator,
+ )
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt
index 859d2e398024..6fff9b72662a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt
@@ -19,15 +19,17 @@ package com.android.systemui.statusbar.chips.ui.viewmodel
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.statusbar.chips.call.domain.interactor.callChipInteractor
-import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.mediaProjectionChipInteractor
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel.castToOtherDeviceChipViewModel
import com.android.systemui.statusbar.chips.screenrecord.domain.interactor.screenRecordChipInteractor
+import com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel.shareToAppChipViewModel
val Kosmos.ongoingActivityChipsViewModel: OngoingActivityChipsViewModel by
Kosmos.Fixture {
OngoingActivityChipsViewModel(
testScope.backgroundScope,
screenRecordChipInteractor = screenRecordChipInteractor,
- mediaProjectionChipInteractor = mediaProjectionChipInteractor,
+ shareToAppChipViewModel = shareToAppChipViewModel,
+ castToOtherDeviceChipViewModel = castToOtherDeviceChipViewModel,
callChipInteractor = callChipInteractor,
)
}