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.car.displayconfig 18 19 import android.testing.AndroidTestingRunner 20 import android.testing.TestableLooper.RunWithLooper 21 import android.view.Display 22 import androidx.test.filters.SmallTest 23 import com.android.systemui.SysuiTestCase 24 import com.android.systemui.car.CarSystemUiTest 25 import com.android.systemui.display.data.repository.DisplayRepository 26 import com.android.systemui.display.data.repository.DisplayRepository.PendingDisplay 27 import com.android.systemui.process.ProcessWrapper 28 import kotlinx.coroutines.ExperimentalCoroutinesApi 29 import kotlinx.coroutines.cancelChildren 30 import kotlinx.coroutines.flow.Flow 31 import kotlinx.coroutines.flow.MutableStateFlow 32 import kotlinx.coroutines.flow.StateFlow 33 import kotlinx.coroutines.flow.emptyFlow 34 import kotlinx.coroutines.flow.flowOf 35 import kotlinx.coroutines.launch 36 import kotlinx.coroutines.test.StandardTestDispatcher 37 import kotlinx.coroutines.test.TestScope 38 import kotlinx.coroutines.test.advanceUntilIdle 39 import kotlinx.coroutines.test.runTest 40 import org.junit.Test 41 import org.junit.runner.RunWith 42 import org.mockito.kotlin.mock 43 import org.mockito.kotlin.never 44 import org.mockito.kotlin.verify 45 import org.mockito.kotlin.whenever 46 47 @CarSystemUiTest 48 @RunWith(AndroidTestingRunner::class) 49 @RunWithLooper 50 @SmallTest 51 class ExternalDisplayControllerTest : SysuiTestCase() { 52 53 private val testScope = TestScope() 54 private val bgDispatcher = 55 StandardTestDispatcher(testScope.testScheduler, name = "Background dispatcher") 56 private val pendingDisplayMock: PendingDisplay = mock() 57 private val fakePendingDisplayFlow = flowOf(null, pendingDisplayMock) 58 private val fakeDisplayRepository = FakeDisplayRepository(fakePendingDisplayFlow) 59 private val processWrapper: ProcessWrapper = mock() 60 61 private val externalDisplayController = ExternalDisplayController( 62 fakeDisplayRepository, 63 processWrapper, 64 testScope, 65 bgDispatcher 66 ) 67 68 @OptIn(ExperimentalCoroutinesApi::class) 69 @Test <lambda>null70 fun start_whenSystemUser_enablesPendingDisplays() = testScope.runTest() { 71 whenever(processWrapper.isSystemUser).thenReturn(true) 72 73 launch(StandardTestDispatcher(testScheduler)) { 74 externalDisplayController.start() 75 } 76 advanceUntilIdle() 77 coroutineContext.cancelChildren() 78 79 verify(pendingDisplayMock).enable() 80 } 81 82 @OptIn(ExperimentalCoroutinesApi::class) 83 @Test <lambda>null84 fun start_whenNonSystemUser_noOp() = testScope.runTest { 85 whenever(processWrapper.isSystemUser).thenReturn(false) 86 87 launch(StandardTestDispatcher(testScheduler)) { 88 externalDisplayController.start() 89 } 90 advanceUntilIdle() 91 coroutineContext.cancelChildren() 92 93 verify(pendingDisplayMock, never()).enable() 94 } 95 } 96 97 class FakeDisplayRepository( 98 private val fakePendingDisplayFlow: Flow<PendingDisplay?>, 99 override val displayChangeEvent: Flow<Int> = emptyFlow(), 100 override val displayAdditionEvent: Flow<Display?> = emptyFlow(), 101 override val displayRemovalEvent: Flow<Int> = emptyFlow(), 102 override val displays: StateFlow<Set<Display>> = MutableStateFlow(emptySet()), 103 override val defaultDisplayOff: Flow<Boolean> = emptyFlow(), 104 override val pendingDisplay: Flow<PendingDisplay?> = fakePendingDisplayFlow, 105 override val displayIds: StateFlow<Set<Int>> = MutableStateFlow(emptySet()), 106 ) : DisplayRepository 107