Loading packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelTest.kt +68 −48 Original line number Diff line number Diff line Loading @@ -16,22 +16,26 @@ package com.android.systemui.volume.panel.ui.viewmodel import android.content.Intent import android.content.applicationContext import android.content.res.Configuration import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.broadcastDispatcher import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.statusbar.policy.fakeConfigurationController import com.android.systemui.testKosmos import com.android.systemui.volume.panel.componentByKey import com.android.systemui.volume.panel.componentsLayoutManager import com.android.systemui.volume.panel.criteriaByKey import com.android.systemui.volume.panel.dagger.factory.KosmosVolumePanelComponentFactory import com.android.systemui.volume.panel.mockVolumePanelUiComponentProvider import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey import com.android.systemui.volume.panel.ui.layout.DefaultComponentsLayoutManager import com.android.systemui.volume.panel.unavailableCriteria import com.android.systemui.volume.panel.volumePanelViewModel import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent Loading @@ -51,21 +55,9 @@ class VolumePanelViewModelTest : SysuiTestCase() { private lateinit var underTest: VolumePanelViewModel private fun initUnderTest() { underTest = VolumePanelViewModel( testableResources.resources, kosmos.testScope.backgroundScope, KosmosVolumePanelComponentFactory(kosmos), kosmos.fakeConfigurationController, ) } @Test fun dismissingPanel_changesVisibility() { with(kosmos) { fun dismissingPanel_changesVisibility() = test { testScope.runTest { initUnderTest() assertThat(underTest.volumePanelState.value.isVisible).isTrue() underTest.dismissPanel() Loading @@ -74,19 +66,15 @@ class VolumePanelViewModelTest : SysuiTestCase() { assertThat(underTest.volumePanelState.value.isVisible).isFalse() } } } @Test fun orientationChanges_panelOrientationChanges() { with(kosmos) { fun orientationChanges_panelOrientationChanges() = test { testScope.runTest { initUnderTest() val volumePanelState by collectLastValue(underTest.volumePanelState) testableResources.overrideConfiguration( Configuration().apply { orientation = Configuration.ORIENTATION_PORTRAIT } ) assertThat(volumePanelState!!.orientation) .isEqualTo(Configuration.ORIENTATION_PORTRAIT) assertThat(volumePanelState!!.orientation).isEqualTo(Configuration.ORIENTATION_PORTRAIT) fakeConfigurationController.onConfigurationChanged( Configuration().apply { orientation = Configuration.ORIENTATION_LANDSCAPE } Loading @@ -97,12 +85,10 @@ class VolumePanelViewModelTest : SysuiTestCase() { .isEqualTo(Configuration.ORIENTATION_LANDSCAPE) } } } @Test fun components_areReturned() { with(kosmos) { testScope.runTest { fun components_areReturned() = test({ componentByKey = mapOf( COMPONENT_1 to mockVolumePanelUiComponentProvider, Loading @@ -110,8 +96,8 @@ class VolumePanelViewModelTest : SysuiTestCase() { BOTTOM_BAR to mockVolumePanelUiComponentProvider, ) criteriaByKey = mapOf(COMPONENT_2 to unavailableCriteria) initUnderTest() }) { testScope.runTest { val componentsLayout by collectLastValue(underTest.componentsLayout) runCurrent() Loading @@ -124,11 +110,45 @@ class VolumePanelViewModelTest : SysuiTestCase() { assertThat(componentsLayout!!.bottomBarComponent.isVisible).isTrue() } } @Test fun dismissPanel_dismissesPanel() = test { testScope.runTest { val volumePanelState by collectLastValue(underTest.volumePanelState) underTest.dismissPanel() runCurrent() assertThat(volumePanelState!!.isVisible).isFalse() } } @Test fun dismissBroadcast_dismissesPanel() = test { testScope.runTest { runCurrent() // run the flows to let allow the receiver to be registered val volumePanelState by collectLastValue(underTest.volumePanelState) broadcastDispatcher.sendIntentToMatchingReceiversOnly( applicationContext, Intent(DISMISS_ACTION), ) runCurrent() assertThat(volumePanelState!!.isVisible).isFalse() } } private fun test(setup: Kosmos.() -> Unit = {}, test: Kosmos.() -> Unit) = with(kosmos) { setup() underTest = volumePanelViewModel test() } private companion object { const val BOTTOM_BAR: VolumePanelComponentKey = "test_bottom_bar" const val COMPONENT_1: VolumePanelComponentKey = "test_component:1" const val COMPONENT_2: VolumePanelComponentKey = "test_component:2" const val DISMISS_ACTION = "com.android.systemui.action.DISMISS_VOLUME_PANEL_DIALOG" } } packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java +0 −10 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import com.android.systemui.media.dialog.MediaOutputDialogReceiver; import com.android.systemui.people.widget.PeopleSpaceWidgetPinnedReceiver; import com.android.systemui.people.widget.PeopleSpaceWidgetProvider; import com.android.systemui.screenshot.SmartActionsReceiver; import com.android.systemui.volume.VolumePanelDialogReceiver; import dagger.Binds; import dagger.Module; Loading Loading @@ -54,15 +53,6 @@ public abstract class DefaultBroadcastReceiverBinder { public abstract BroadcastReceiver bindMediaOutputDialogReceiver( MediaOutputDialogReceiver broadcastReceiver); /** * */ @Binds @IntoMap @ClassKey(VolumePanelDialogReceiver.class) public abstract BroadcastReceiver bindVolumePanelDialogReceiver( VolumePanelDialogReceiver broadcastReceiver); /** * */ Loading packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialogReceiver.kt +19 −16 Original line number Diff line number Diff line Loading @@ -21,26 +21,29 @@ import android.content.Context import android.content.Intent import android.provider.Settings import android.text.TextUtils import android.util.Log import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor import com.android.systemui.volume.ui.navigation.VolumeNavigator import javax.inject.Inject private const val TAG = "VolumePanelDialogReceiver" private const val LAUNCH_ACTION = "com.android.systemui.action.LAUNCH_VOLUME_PANEL_DIALOG" private const val DISMISS_ACTION = "com.android.systemui.action.DISMISS_VOLUME_PANEL_DIALOG" /** * BroadcastReceiver for handling volume panel dialog intent */ class VolumePanelDialogReceiver @Inject constructor( private val volumePanelFactory: VolumePanelFactory /** [BroadcastReceiver] for handling volume panel dialog intent */ class VolumePanelDialogReceiver @Inject constructor( private val volumeNavigator: VolumeNavigator, private val volumePanelNavigationInteractor: VolumePanelNavigationInteractor, ) : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Log.d(TAG, "onReceive intent" + intent.action) if (TextUtils.equals(LAUNCH_ACTION, intent.action) || TextUtils.equals(Settings.Panel.ACTION_VOLUME, intent.action)) { volumePanelFactory.create(true, null) } else if (TextUtils.equals(DISMISS_ACTION, intent.action)) { volumePanelFactory.dismiss() if ( TextUtils.equals(LAUNCH_ACTION, intent.action) || TextUtils.equals(Settings.Panel.ACTION_VOLUME, intent.action) ) { volumeNavigator.openVolumePanel(volumePanelNavigationInteractor.getVolumePanelRoute()) } } companion object { const val LAUNCH_ACTION = "com.android.systemui.action.LAUNCH_VOLUME_PANEL_DIALOG" const val DISMISS_ACTION = "com.android.systemui.action.DISMISS_VOLUME_PANEL_DIALOG" } } packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java +11 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.volume.dagger; import android.content.BroadcastReceiver; import android.content.Context; import android.media.AudioManager; import android.os.Looper; Loading @@ -37,6 +38,7 @@ import com.android.systemui.volume.CsdWarningDialog; import com.android.systemui.volume.VolumeComponent; import com.android.systemui.volume.VolumeDialogComponent; import com.android.systemui.volume.VolumeDialogImpl; import com.android.systemui.volume.VolumePanelDialogReceiver; import com.android.systemui.volume.VolumeUI; import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor; import com.android.systemui.volume.panel.dagger.VolumePanelComponent; Loading Loading @@ -65,6 +67,15 @@ import dagger.multibindings.IntoSet; } ) public interface VolumeModule { /** * Binds [VolumePanelDialogReceiver] */ @Binds @IntoMap @ClassKey(VolumePanelDialogReceiver.class) BroadcastReceiver bindVolumePanelDialogReceiver(VolumePanelDialogReceiver receiver); /** Starts VolumeUI. */ @Binds @IntoMap Loading packages/SystemUI/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModel.kt +12 −0 Original line number Diff line number Diff line Loading @@ -17,11 +17,14 @@ package com.android.systemui.volume.panel.ui.viewmodel import android.content.Context import android.content.IntentFilter import android.content.res.Resources import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.res.R import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.onConfigChanged import com.android.systemui.volume.VolumePanelDialogReceiver import com.android.systemui.volume.panel.dagger.VolumePanelComponent import com.android.systemui.volume.panel.dagger.factory.VolumePanelComponentFactory import com.android.systemui.volume.panel.domain.VolumePanelStartable Loading @@ -37,6 +40,8 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.flow.stateIn Loading @@ -49,6 +54,7 @@ class VolumePanelViewModel( coroutineScope: CoroutineScope, daggerComponentFactory: VolumePanelComponentFactory, configurationController: ConfigurationController, broadcastDispatcher: BroadcastDispatcher, ) { private val volumePanelComponent: VolumePanelComponent = Loading Loading @@ -113,6 +119,10 @@ class VolumePanelViewModel( init { volumePanelComponent.volumePanelStartables().onEach(VolumePanelStartable::start) broadcastDispatcher .broadcastFlow(IntentFilter(VolumePanelDialogReceiver.DISMISS_ACTION)) .onEach { dismissPanel() } .launchIn(scope) } fun dismissPanel() { Loading @@ -125,6 +135,7 @@ class VolumePanelViewModel( @Application private val context: Context, private val daggerComponentFactory: VolumePanelComponentFactory, private val configurationController: ConfigurationController, private val broadcastDispatcher: BroadcastDispatcher, ) { fun create(coroutineScope: CoroutineScope): VolumePanelViewModel { Loading @@ -133,6 +144,7 @@ class VolumePanelViewModel( coroutineScope, daggerComponentFactory, configurationController, broadcastDispatcher ) } } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModelTest.kt +68 −48 Original line number Diff line number Diff line Loading @@ -16,22 +16,26 @@ package com.android.systemui.volume.panel.ui.viewmodel import android.content.Intent import android.content.applicationContext import android.content.res.Configuration import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.broadcastDispatcher import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.statusbar.policy.fakeConfigurationController import com.android.systemui.testKosmos import com.android.systemui.volume.panel.componentByKey import com.android.systemui.volume.panel.componentsLayoutManager import com.android.systemui.volume.panel.criteriaByKey import com.android.systemui.volume.panel.dagger.factory.KosmosVolumePanelComponentFactory import com.android.systemui.volume.panel.mockVolumePanelUiComponentProvider import com.android.systemui.volume.panel.shared.model.VolumePanelComponentKey import com.android.systemui.volume.panel.ui.layout.DefaultComponentsLayoutManager import com.android.systemui.volume.panel.unavailableCriteria import com.android.systemui.volume.panel.volumePanelViewModel import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent Loading @@ -51,21 +55,9 @@ class VolumePanelViewModelTest : SysuiTestCase() { private lateinit var underTest: VolumePanelViewModel private fun initUnderTest() { underTest = VolumePanelViewModel( testableResources.resources, kosmos.testScope.backgroundScope, KosmosVolumePanelComponentFactory(kosmos), kosmos.fakeConfigurationController, ) } @Test fun dismissingPanel_changesVisibility() { with(kosmos) { fun dismissingPanel_changesVisibility() = test { testScope.runTest { initUnderTest() assertThat(underTest.volumePanelState.value.isVisible).isTrue() underTest.dismissPanel() Loading @@ -74,19 +66,15 @@ class VolumePanelViewModelTest : SysuiTestCase() { assertThat(underTest.volumePanelState.value.isVisible).isFalse() } } } @Test fun orientationChanges_panelOrientationChanges() { with(kosmos) { fun orientationChanges_panelOrientationChanges() = test { testScope.runTest { initUnderTest() val volumePanelState by collectLastValue(underTest.volumePanelState) testableResources.overrideConfiguration( Configuration().apply { orientation = Configuration.ORIENTATION_PORTRAIT } ) assertThat(volumePanelState!!.orientation) .isEqualTo(Configuration.ORIENTATION_PORTRAIT) assertThat(volumePanelState!!.orientation).isEqualTo(Configuration.ORIENTATION_PORTRAIT) fakeConfigurationController.onConfigurationChanged( Configuration().apply { orientation = Configuration.ORIENTATION_LANDSCAPE } Loading @@ -97,12 +85,10 @@ class VolumePanelViewModelTest : SysuiTestCase() { .isEqualTo(Configuration.ORIENTATION_LANDSCAPE) } } } @Test fun components_areReturned() { with(kosmos) { testScope.runTest { fun components_areReturned() = test({ componentByKey = mapOf( COMPONENT_1 to mockVolumePanelUiComponentProvider, Loading @@ -110,8 +96,8 @@ class VolumePanelViewModelTest : SysuiTestCase() { BOTTOM_BAR to mockVolumePanelUiComponentProvider, ) criteriaByKey = mapOf(COMPONENT_2 to unavailableCriteria) initUnderTest() }) { testScope.runTest { val componentsLayout by collectLastValue(underTest.componentsLayout) runCurrent() Loading @@ -124,11 +110,45 @@ class VolumePanelViewModelTest : SysuiTestCase() { assertThat(componentsLayout!!.bottomBarComponent.isVisible).isTrue() } } @Test fun dismissPanel_dismissesPanel() = test { testScope.runTest { val volumePanelState by collectLastValue(underTest.volumePanelState) underTest.dismissPanel() runCurrent() assertThat(volumePanelState!!.isVisible).isFalse() } } @Test fun dismissBroadcast_dismissesPanel() = test { testScope.runTest { runCurrent() // run the flows to let allow the receiver to be registered val volumePanelState by collectLastValue(underTest.volumePanelState) broadcastDispatcher.sendIntentToMatchingReceiversOnly( applicationContext, Intent(DISMISS_ACTION), ) runCurrent() assertThat(volumePanelState!!.isVisible).isFalse() } } private fun test(setup: Kosmos.() -> Unit = {}, test: Kosmos.() -> Unit) = with(kosmos) { setup() underTest = volumePanelViewModel test() } private companion object { const val BOTTOM_BAR: VolumePanelComponentKey = "test_bottom_bar" const val COMPONENT_1: VolumePanelComponentKey = "test_component:1" const val COMPONENT_2: VolumePanelComponentKey = "test_component:2" const val DISMISS_ACTION = "com.android.systemui.action.DISMISS_VOLUME_PANEL_DIALOG" } }
packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java +0 −10 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import com.android.systemui.media.dialog.MediaOutputDialogReceiver; import com.android.systemui.people.widget.PeopleSpaceWidgetPinnedReceiver; import com.android.systemui.people.widget.PeopleSpaceWidgetProvider; import com.android.systemui.screenshot.SmartActionsReceiver; import com.android.systemui.volume.VolumePanelDialogReceiver; import dagger.Binds; import dagger.Module; Loading Loading @@ -54,15 +53,6 @@ public abstract class DefaultBroadcastReceiverBinder { public abstract BroadcastReceiver bindMediaOutputDialogReceiver( MediaOutputDialogReceiver broadcastReceiver); /** * */ @Binds @IntoMap @ClassKey(VolumePanelDialogReceiver.class) public abstract BroadcastReceiver bindVolumePanelDialogReceiver( VolumePanelDialogReceiver broadcastReceiver); /** * */ Loading
packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialogReceiver.kt +19 −16 Original line number Diff line number Diff line Loading @@ -21,26 +21,29 @@ import android.content.Context import android.content.Intent import android.provider.Settings import android.text.TextUtils import android.util.Log import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor import com.android.systemui.volume.ui.navigation.VolumeNavigator import javax.inject.Inject private const val TAG = "VolumePanelDialogReceiver" private const val LAUNCH_ACTION = "com.android.systemui.action.LAUNCH_VOLUME_PANEL_DIALOG" private const val DISMISS_ACTION = "com.android.systemui.action.DISMISS_VOLUME_PANEL_DIALOG" /** * BroadcastReceiver for handling volume panel dialog intent */ class VolumePanelDialogReceiver @Inject constructor( private val volumePanelFactory: VolumePanelFactory /** [BroadcastReceiver] for handling volume panel dialog intent */ class VolumePanelDialogReceiver @Inject constructor( private val volumeNavigator: VolumeNavigator, private val volumePanelNavigationInteractor: VolumePanelNavigationInteractor, ) : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Log.d(TAG, "onReceive intent" + intent.action) if (TextUtils.equals(LAUNCH_ACTION, intent.action) || TextUtils.equals(Settings.Panel.ACTION_VOLUME, intent.action)) { volumePanelFactory.create(true, null) } else if (TextUtils.equals(DISMISS_ACTION, intent.action)) { volumePanelFactory.dismiss() if ( TextUtils.equals(LAUNCH_ACTION, intent.action) || TextUtils.equals(Settings.Panel.ACTION_VOLUME, intent.action) ) { volumeNavigator.openVolumePanel(volumePanelNavigationInteractor.getVolumePanelRoute()) } } companion object { const val LAUNCH_ACTION = "com.android.systemui.action.LAUNCH_VOLUME_PANEL_DIALOG" const val DISMISS_ACTION = "com.android.systemui.action.DISMISS_VOLUME_PANEL_DIALOG" } }
packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java +11 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.systemui.volume.dagger; import android.content.BroadcastReceiver; import android.content.Context; import android.media.AudioManager; import android.os.Looper; Loading @@ -37,6 +38,7 @@ import com.android.systemui.volume.CsdWarningDialog; import com.android.systemui.volume.VolumeComponent; import com.android.systemui.volume.VolumeDialogComponent; import com.android.systemui.volume.VolumeDialogImpl; import com.android.systemui.volume.VolumePanelDialogReceiver; import com.android.systemui.volume.VolumeUI; import com.android.systemui.volume.domain.interactor.VolumePanelNavigationInteractor; import com.android.systemui.volume.panel.dagger.VolumePanelComponent; Loading Loading @@ -65,6 +67,15 @@ import dagger.multibindings.IntoSet; } ) public interface VolumeModule { /** * Binds [VolumePanelDialogReceiver] */ @Binds @IntoMap @ClassKey(VolumePanelDialogReceiver.class) BroadcastReceiver bindVolumePanelDialogReceiver(VolumePanelDialogReceiver receiver); /** Starts VolumeUI. */ @Binds @IntoMap Loading
packages/SystemUI/src/com/android/systemui/volume/panel/ui/viewmodel/VolumePanelViewModel.kt +12 −0 Original line number Diff line number Diff line Loading @@ -17,11 +17,14 @@ package com.android.systemui.volume.panel.ui.viewmodel import android.content.Context import android.content.IntentFilter import android.content.res.Resources import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.res.R import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.statusbar.policy.onConfigChanged import com.android.systemui.volume.VolumePanelDialogReceiver import com.android.systemui.volume.panel.dagger.VolumePanelComponent import com.android.systemui.volume.panel.dagger.factory.VolumePanelComponentFactory import com.android.systemui.volume.panel.domain.VolumePanelStartable Loading @@ -37,6 +40,8 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.flow.stateIn Loading @@ -49,6 +54,7 @@ class VolumePanelViewModel( coroutineScope: CoroutineScope, daggerComponentFactory: VolumePanelComponentFactory, configurationController: ConfigurationController, broadcastDispatcher: BroadcastDispatcher, ) { private val volumePanelComponent: VolumePanelComponent = Loading Loading @@ -113,6 +119,10 @@ class VolumePanelViewModel( init { volumePanelComponent.volumePanelStartables().onEach(VolumePanelStartable::start) broadcastDispatcher .broadcastFlow(IntentFilter(VolumePanelDialogReceiver.DISMISS_ACTION)) .onEach { dismissPanel() } .launchIn(scope) } fun dismissPanel() { Loading @@ -125,6 +135,7 @@ class VolumePanelViewModel( @Application private val context: Context, private val daggerComponentFactory: VolumePanelComponentFactory, private val configurationController: ConfigurationController, private val broadcastDispatcher: BroadcastDispatcher, ) { fun create(coroutineScope: CoroutineScope): VolumePanelViewModel { Loading @@ -133,6 +144,7 @@ class VolumePanelViewModel( coroutineScope, daggerComponentFactory, configurationController, broadcastDispatcher ) } } Loading