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.reardisplay
18 
19 import android.hardware.devicestate.feature.flags.Flags.FLAG_DEVICE_STATE_RDM_V2
20 import android.hardware.display.rearDisplay
21 import android.platform.test.annotations.DisableFlags
22 import android.platform.test.annotations.EnableFlags
23 import android.view.Display
24 import androidx.test.filters.SmallTest
25 import com.android.systemui.SysuiTestCase
26 import com.android.systemui.deviceStateManager
27 import com.android.systemui.display.domain.interactor.RearDisplayStateInteractor
28 import com.android.systemui.kosmos.Kosmos
29 import com.android.systemui.kosmos.runTest
30 import com.android.systemui.kosmos.testScope
31 import com.android.systemui.kosmos.useUnconfinedTestDispatcher
32 import com.android.systemui.rearDisplayInnerDialogDelegateFactory
33 import com.android.systemui.statusbar.phone.SystemUIDialog
34 import com.android.systemui.testKosmos
35 import com.google.common.truth.Truth.assertThat
36 import kotlinx.coroutines.flow.Flow
37 import kotlinx.coroutines.flow.MutableSharedFlow
38 import org.junit.Before
39 import org.junit.Test
40 import org.mockito.kotlin.any
41 import org.mockito.kotlin.mock
42 import org.mockito.kotlin.never
43 import org.mockito.kotlin.verify
44 import org.mockito.kotlin.whenever
45 
46 /** atest SystemUITests:com.android.systemui.reardisplay.RearDisplayCoreStartableTest */
47 @SmallTest
48 @kotlinx.coroutines.ExperimentalCoroutinesApi
49 class RearDisplayCoreStartableTest : SysuiTestCase() {
50 
51     private val kosmos = testKosmos().useUnconfinedTestDispatcher()
52     private val mockDelegate: RearDisplayInnerDialogDelegate = mock()
53     private val mockDialog: SystemUIDialog = mock()
54 
55     private val fakeRearDisplayStateInteractor = FakeRearDisplayStateInteractor(kosmos)
56     private val impl =
57         RearDisplayCoreStartable(
58             mContext,
59             kosmos.deviceStateManager,
60             fakeRearDisplayStateInteractor,
61             kosmos.rearDisplayInnerDialogDelegateFactory,
62             kosmos.testScope,
63         )
64 
65     @Before
setupnull66     fun setup() {
67         whenever(kosmos.rearDisplay.flags).thenReturn(Display.FLAG_REAR)
68         whenever(kosmos.rearDisplay.displayAdjustments)
69             .thenReturn(mContext.display.displayAdjustments)
70         whenever(kosmos.rearDisplayInnerDialogDelegateFactory.create(any(), any()))
71             .thenReturn(mockDelegate)
72         whenever(mockDelegate.createDialog()).thenReturn(mockDialog)
73     }
74 
75     @Test
76     @DisableFlags(FLAG_DEVICE_STATE_RDM_V2)
testWhenFlagDisablednull77     fun testWhenFlagDisabled() =
78         kosmos.runTest {
79             impl.use {
80                 it.start()
81                 assertThat(impl.stateChangeListener).isNull()
82             }
83         }
84 
85     @Test
86     @EnableFlags(FLAG_DEVICE_STATE_RDM_V2)
testShowAndDismissDialognull87     fun testShowAndDismissDialog() =
88         kosmos.runTest {
89             impl.use {
90                 it.start()
91                 fakeRearDisplayStateInteractor.emitRearDisplay()
92                 verify(mockDialog).show()
93                 verify(mockDialog, never()).dismiss()
94 
95                 fakeRearDisplayStateInteractor.emitDisabled()
96                 verify(mockDialog).dismiss()
97             }
98         }
99 
100     private class FakeRearDisplayStateInteractor(private val kosmos: Kosmos) :
101         RearDisplayStateInteractor {
102         private val stateFlow = MutableSharedFlow<RearDisplayStateInteractor.State>()
103 
emitRearDisplaynull104         suspend fun emitRearDisplay() =
105             stateFlow.emit(RearDisplayStateInteractor.State.Enabled(kosmos.rearDisplay))
106 
107         suspend fun emitDisabled() = stateFlow.emit(RearDisplayStateInteractor.State.Disabled)
108 
109         override val state: Flow<RearDisplayStateInteractor.State>
110             get() = stateFlow
111     }
112 }
113