1 /*
2  * Copyright (C) 2022 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.qs.footer
18 
19 import android.content.Context
20 import android.os.Handler
21 import android.os.UserManager
22 import android.provider.Settings
23 import android.testing.TestableLooper
24 import com.android.internal.logging.MetricsLogger
25 import com.android.internal.logging.UiEventLogger
26 import com.android.internal.logging.testing.FakeMetricsLogger
27 import com.android.internal.logging.testing.UiEventLoggerFake
28 import com.android.systemui.broadcast.BroadcastDispatcher
29 import com.android.systemui.classifier.FalsingManagerFake
30 import com.android.systemui.dagger.qualifiers.Application
31 import com.android.systemui.globalactions.GlobalActionsDialogLite
32 import com.android.systemui.plugins.ActivityStarter
33 import com.android.systemui.plugins.FalsingManager
34 import com.android.systemui.qs.FakeFgsManagerController
35 import com.android.systemui.qs.FgsManagerController
36 import com.android.systemui.qs.QSSecurityFooterUtils
37 import com.android.systemui.qs.footer.data.repository.ForegroundServicesRepository
38 import com.android.systemui.qs.footer.data.repository.ForegroundServicesRepositoryImpl
39 import com.android.systemui.qs.footer.domain.interactor.FooterActionsInteractor
40 import com.android.systemui.qs.footer.domain.interactor.FooterActionsInteractorImpl
41 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
42 import com.android.systemui.security.data.repository.SecurityRepository
43 import com.android.systemui.security.data.repository.SecurityRepositoryImpl
44 import com.android.systemui.statusbar.policy.DeviceProvisionedController
45 import com.android.systemui.statusbar.policy.FakeSecurityController
46 import com.android.systemui.statusbar.policy.FakeUserInfoController
47 import com.android.systemui.statusbar.policy.SecurityController
48 import com.android.systemui.statusbar.policy.UserInfoController
49 import com.android.systemui.statusbar.policy.UserSwitcherController
50 import com.android.systemui.user.data.repository.FakeUserRepository
51 import com.android.systemui.user.data.repository.UserRepository
52 import com.android.systemui.user.data.repository.UserSwitcherRepository
53 import com.android.systemui.user.data.repository.UserSwitcherRepositoryImpl
54 import com.android.systemui.user.domain.interactor.UserSwitcherInteractor
55 import com.android.systemui.util.mockito.mock
56 import com.android.systemui.util.settings.FakeGlobalSettings
57 import com.android.systemui.util.settings.GlobalSettings
58 import kotlinx.coroutines.CoroutineDispatcher
59 import kotlinx.coroutines.test.StandardTestDispatcher
60 import kotlinx.coroutines.test.TestCoroutineScheduler
61 
62 /**
63  * Util class to create real implementations of the FooterActions repositories, viewModel and
64  * interactor to be used in tests.
65  */
66 class FooterActionsTestUtils(
67     private val context: Context,
68     private val testableLooper: TestableLooper,
69     private val scheduler: TestCoroutineScheduler,
70 ) {
71     private val mockActivityStarter: ActivityStarter = mock<ActivityStarter>()
72     /** Enable or disable the user switcher in the settings. */
setUserSwitcherEnablednull73     fun setUserSwitcherEnabled(settings: GlobalSettings, enabled: Boolean) {
74         settings.putBool(Settings.Global.USER_SWITCHER_ENABLED, enabled)
75 
76         // The settings listener is processing messages on the bgHandler (usually backed by a
77         // testableLooper in tests), so let's make sure we process the callback before continuing.
78         testableLooper.processAllMessages()
79     }
80 
81     /** Create a [FooterActionsViewModel] to be used in tests. */
footerActionsViewModelnull82     fun footerActionsViewModel(
83         @Application context: Context = this.context.applicationContext,
84         footerActionsInteractor: FooterActionsInteractor = footerActionsInteractor(),
85         falsingManager: FalsingManager = FalsingManagerFake(),
86         globalActionsDialogLite: GlobalActionsDialogLite = mock(),
87         showPowerButton: Boolean = true,
88     ): FooterActionsViewModel {
89         return FooterActionsViewModel(
90             context,
91             footerActionsInteractor,
92             falsingManager,
93             globalActionsDialogLite,
94             mockActivityStarter,
95             showPowerButton,
96         )
97     }
98 
99     /** Create a [FooterActionsInteractor] to be used in tests. */
footerActionsInteractornull100     fun footerActionsInteractor(
101         activityStarter: ActivityStarter = mockActivityStarter,
102         metricsLogger: MetricsLogger = FakeMetricsLogger(),
103         uiEventLogger: UiEventLogger = UiEventLoggerFake(),
104         deviceProvisionedController: DeviceProvisionedController = mock(),
105         qsSecurityFooterUtils: QSSecurityFooterUtils = mock(),
106         fgsManagerController: FgsManagerController = mock(),
107         userSwitcherInteractor: UserSwitcherInteractor = mock(),
108         securityRepository: SecurityRepository = securityRepository(),
109         foregroundServicesRepository: ForegroundServicesRepository = foregroundServicesRepository(),
110         userSwitcherRepository: UserSwitcherRepository = userSwitcherRepository(),
111         broadcastDispatcher: BroadcastDispatcher = mock(),
112         bgDispatcher: CoroutineDispatcher = StandardTestDispatcher(scheduler),
113     ): FooterActionsInteractor {
114         return FooterActionsInteractorImpl(
115             activityStarter,
116             metricsLogger,
117             uiEventLogger,
118             deviceProvisionedController,
119             qsSecurityFooterUtils,
120             fgsManagerController,
121             userSwitcherInteractor,
122             securityRepository,
123             foregroundServicesRepository,
124             userSwitcherRepository,
125             broadcastDispatcher,
126             bgDispatcher,
127         )
128     }
129 
130     /** Create a [SecurityRepository] to be used in tests. */
securityRepositorynull131     fun securityRepository(
132         securityController: SecurityController = FakeSecurityController(),
133         bgDispatcher: CoroutineDispatcher = StandardTestDispatcher(scheduler),
134     ): SecurityRepository {
135         return SecurityRepositoryImpl(
136             securityController,
137             bgDispatcher,
138         )
139     }
140 
141     /** Create a [SecurityRepository] to be used in tests. */
foregroundServicesRepositorynull142     fun foregroundServicesRepository(
143         fgsManagerController: FakeFgsManagerController = FakeFgsManagerController(),
144     ): ForegroundServicesRepository {
145         return ForegroundServicesRepositoryImpl(fgsManagerController)
146     }
147 
148     /** Create a [UserSwitcherRepository] to be used in tests. */
userSwitcherRepositorynull149     fun userSwitcherRepository(
150         @Application context: Context = this.context.applicationContext,
151         bgHandler: Handler = Handler(testableLooper.looper),
152         bgDispatcher: CoroutineDispatcher = StandardTestDispatcher(scheduler),
153         userManager: UserManager = mock(),
154         userRepository: UserRepository = FakeUserRepository(),
155         userSwitcherController: UserSwitcherController = mock(),
156         userInfoController: UserInfoController = FakeUserInfoController(),
157         settings: GlobalSettings = FakeGlobalSettings(),
158     ): UserSwitcherRepository {
159         return UserSwitcherRepositoryImpl(
160             context,
161             bgHandler,
162             bgDispatcher,
163             userManager,
164             userSwitcherController,
165             userInfoController,
166             settings,
167             userRepository,
168         )
169     }
170 }
171