1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.volume.dialog.ringer.ui.viewmodel
18 
19 import android.media.AudioManager.RINGER_MODE_NORMAL
20 import android.media.AudioManager.RINGER_MODE_SILENT
21 import android.media.AudioManager.RINGER_MODE_VIBRATE
22 import android.media.AudioManager.STREAM_RING
23 import android.testing.TestableLooper
24 import androidx.test.ext.junit.runners.AndroidJUnit4
25 import androidx.test.filters.SmallTest
26 import com.android.settingslib.volume.shared.model.RingerMode
27 import com.android.systemui.SysuiTestCase
28 import com.android.systemui.coroutines.collectLastValue
29 import com.android.systemui.haptics.fakeVibratorHelper
30 import com.android.systemui.kosmos.testScope
31 import com.android.systemui.plugins.fakeVolumeDialogController
32 import com.android.systemui.testKosmos
33 import com.android.systemui.volume.data.repository.audioSystemRepository
34 import com.google.common.truth.Truth.assertThat
35 import kotlinx.coroutines.ExperimentalCoroutinesApi
36 import kotlinx.coroutines.test.TestScope
37 import kotlinx.coroutines.test.runCurrent
38 import kotlinx.coroutines.test.runTest
39 import org.junit.Before
40 import org.junit.Test
41 import org.junit.runner.RunWith
42 
43 @OptIn(ExperimentalCoroutinesApi::class)
44 @SmallTest
45 @RunWith(AndroidJUnit4::class)
46 @TestableLooper.RunWithLooper
47 class VolumeDialogRingerDrawerViewModelTest : SysuiTestCase() {
48 
49     private val kosmos = testKosmos()
50     private val testScope = kosmos.testScope
51     private val controller = kosmos.fakeVolumeDialogController
52     private val vibratorHelper = kosmos.fakeVibratorHelper
53 
54     private lateinit var underTest: VolumeDialogRingerDrawerViewModel
55 
56     @Before
setUpnull57     fun setUp() {
58         underTest = kosmos.volumeDialogRingerDrawerViewModel
59     }
60 
61     @Test
onSelectedRingerNormalModeButtonClicked_openDrawernull62     fun onSelectedRingerNormalModeButtonClicked_openDrawer() =
63         testScope.runTest {
64             val ringerViewModel by collectLastValue(underTest.ringerViewModel)
65             val normalRingerMode = RingerMode(RINGER_MODE_NORMAL)
66 
67             setUpRingerModeAndOpenDrawer(normalRingerMode)
68 
69             assertThat(ringerViewModel).isInstanceOf(RingerViewModelState.Available::class.java)
70             assertThat((ringerViewModel as RingerViewModelState.Available).uiModel.drawerState)
71                 .isEqualTo(RingerDrawerState.Open(normalRingerMode))
72         }
73 
74     @Test
onSelectedRingerButtonClicked_drawerOpened_closeDrawernull75     fun onSelectedRingerButtonClicked_drawerOpened_closeDrawer() =
76         testScope.runTest {
77             val ringerViewModel by collectLastValue(underTest.ringerViewModel)
78             val normalRingerMode = RingerMode(RINGER_MODE_NORMAL)
79 
80             setUpRingerModeAndOpenDrawer(normalRingerMode)
81             underTest.onRingerButtonClicked(normalRingerMode)
82             controller.getState()
83 
84             assertThat(ringerViewModel).isInstanceOf(RingerViewModelState.Available::class.java)
85             assertThat((ringerViewModel as RingerViewModelState.Available).uiModel.drawerState)
86                 .isEqualTo(RingerDrawerState.Closed(normalRingerMode, normalRingerMode))
87         }
88 
89     @Test
onNewRingerButtonClicked_drawerOpened_updateRingerMode_closeDrawernull90     fun onNewRingerButtonClicked_drawerOpened_updateRingerMode_closeDrawer() =
91         testScope.runTest {
92             val ringerViewModel by collectLastValue(underTest.ringerViewModel)
93             val vibrateRingerMode = RingerMode(RINGER_MODE_VIBRATE)
94             val normalRingerMode = RingerMode(RINGER_MODE_NORMAL)
95 
96             setUpRingerModeAndOpenDrawer(normalRingerMode)
97             // Select vibrate ringer mode.
98             underTest.onRingerButtonClicked(vibrateRingerMode)
99             controller.getState()
100             runCurrent()
101 
102             assertThat(ringerViewModel).isInstanceOf(RingerViewModelState.Available::class.java)
103 
104             var uiModel = (ringerViewModel as RingerViewModelState.Available).uiModel
105             assertThat(uiModel.availableButtons[uiModel.currentButtonIndex]?.ringerMode)
106                 .isEqualTo(vibrateRingerMode)
107             assertThat(uiModel.drawerState)
108                 .isEqualTo(RingerDrawerState.Closed(vibrateRingerMode, normalRingerMode))
109 
110             val silentRingerMode = RingerMode(RINGER_MODE_SILENT)
111             // Open drawer
112             underTest.onRingerButtonClicked(vibrateRingerMode)
113             controller.getState()
114 
115             // Select silent ringer mode.
116             underTest.onRingerButtonClicked(silentRingerMode)
117             controller.getState()
118             runCurrent()
119 
120             assertThat(ringerViewModel).isInstanceOf(RingerViewModelState.Available::class.java)
121 
122             uiModel = (ringerViewModel as RingerViewModelState.Available).uiModel
123             assertThat(uiModel.availableButtons[uiModel.currentButtonIndex]?.ringerMode)
124                 .isEqualTo(silentRingerMode)
125             assertThat(uiModel.drawerState)
126                 .isEqualTo(RingerDrawerState.Closed(silentRingerMode, vibrateRingerMode))
127             assertThat(controller.hasScheduledTouchFeedback).isFalse()
128             assertThat(vibratorHelper.totalVibrations).isEqualTo(2)
129         }
130 
131     @Test
onVolumeSingleMode_ringerIsUnavailablenull132     fun onVolumeSingleMode_ringerIsUnavailable() =
133         testScope.runTest {
134             val ringerViewModel by collectLastValue(underTest.ringerViewModel)
135 
136             kosmos.audioSystemRepository.setIsSingleVolume(true)
137             setUpRingerMode(RingerMode(RINGER_MODE_NORMAL))
138 
139             assertThat(ringerViewModel).isInstanceOf(RingerViewModelState.Unavailable::class.java)
140         }
141 
142     @Test
setUnsupportedRingerMode_ringerIsUnavailablenull143     fun setUnsupportedRingerMode_ringerIsUnavailable() =
144         testScope.runTest {
145             val ringerViewModel by collectLastValue(underTest.ringerViewModel)
146 
147             controller.setHasVibrator(false)
148             setUpRingerMode(RingerMode(RINGER_MODE_VIBRATE))
149 
150             assertThat(ringerViewModel).isInstanceOf(RingerViewModelState.Unavailable::class.java)
151         }
152 
TestScopenull153     private fun TestScope.setUpRingerModeAndOpenDrawer(selectedRingerMode: RingerMode) {
154         setUpRingerMode(selectedRingerMode)
155         underTest.onRingerButtonClicked(RingerMode(selectedRingerMode.value))
156         controller.getState()
157         runCurrent()
158     }
159 
setUpRingerModenull160     private fun TestScope.setUpRingerMode(selectedRingerMode: RingerMode) {
161         controller.setStreamVolume(STREAM_RING, 50)
162         controller.setRingerMode(selectedRingerMode.value, false)
163         runCurrent()
164     }
165 }
166