1 /*
2  * Copyright (C) 2023 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 package com.android.systemui.display.data.repository
17 
18 import android.view.Display
19 import com.android.systemui.dagger.SysUISingleton
20 import com.android.systemui.util.mockito.mock
21 import dagger.Binds
22 import dagger.Module
23 import javax.inject.Inject
24 import kotlinx.coroutines.flow.Flow
25 import kotlinx.coroutines.flow.MutableSharedFlow
26 import kotlinx.coroutines.flow.MutableStateFlow
27 import kotlinx.coroutines.flow.asStateFlow
28 import org.mockito.Mockito.`when` as whenever
29 
30 /** Creates a mock display. */
displaynull31 fun display(
32     type: Int,
33     flags: Int = 0,
34     id: Int = 0,
35     state: Int? = null,
36 ): Display {
37     return mock {
38         whenever(this.displayId).thenReturn(id)
39         whenever(this.type).thenReturn(type)
40         whenever(this.flags).thenReturn(flags)
41         if (state != null) {
42             whenever(this.state).thenReturn(state)
43         }
44     }
45 }
46 
47 /** Creates a mock [DisplayRepository.PendingDisplay]. */
createPendingDisplaynull48 fun createPendingDisplay(id: Int = 0): DisplayRepository.PendingDisplay =
49     mock<DisplayRepository.PendingDisplay> { whenever(this.id).thenReturn(id) }
50 
51 @SysUISingleton
52 /** Fake [DisplayRepository] implementation for testing. */
53 class FakeDisplayRepository @Inject constructor() : DisplayRepository {
54     private val flow = MutableSharedFlow<Set<Display>>(replay = 1)
55     private val pendingDisplayFlow =
56         MutableSharedFlow<DisplayRepository.PendingDisplay?>(replay = 1)
57     private val displayAdditionEventFlow = MutableSharedFlow<Display?>(replay = 1)
58 
59     /** Emits [value] as [displayAdditionEvent] flow value. */
emitnull60     suspend fun emit(value: Display?) = displayAdditionEventFlow.emit(value)
61 
62     /** Emits [value] as [displays] flow value. */
63     suspend fun emit(value: Set<Display>) = flow.emit(value)
64 
65     /** Emits [value] as [pendingDisplay] flow value. */
66     suspend fun emit(value: DisplayRepository.PendingDisplay?) = pendingDisplayFlow.emit(value)
67 
68     override val displays: Flow<Set<Display>>
69         get() = flow
70 
71     override val pendingDisplay: Flow<DisplayRepository.PendingDisplay?>
72         get() = pendingDisplayFlow
73 
74     val _defaultDisplayOff: MutableStateFlow<Boolean> = MutableStateFlow(false)
75     override val defaultDisplayOff: Flow<Boolean>
76         get() = _defaultDisplayOff.asStateFlow()
77 
78     override val displayAdditionEvent: Flow<Display?>
79         get() = displayAdditionEventFlow
80 
81     private val _displayChangeEvent = MutableSharedFlow<Int>(replay = 1)
82     override val displayChangeEvent: Flow<Int> = _displayChangeEvent
83     suspend fun emitDisplayChangeEvent(displayId: Int) = _displayChangeEvent.emit(displayId)
84 
85     fun setDefaultDisplayOff(defaultDisplayOff: Boolean) {
86         _defaultDisplayOff.value = defaultDisplayOff
87     }
88 }
89 
90 @Module
91 interface FakeDisplayRepositoryModule {
bindFakenull92     @Binds fun bindFake(fake: FakeDisplayRepository): DisplayRepository
93 }
94