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.data.repository.UserSwitcherRepository
40 import com.android.systemui.qs.footer.data.repository.UserSwitcherRepositoryImpl
41 import com.android.systemui.qs.footer.domain.interactor.FooterActionsInteractor
42 import com.android.systemui.qs.footer.domain.interactor.FooterActionsInteractorImpl
43 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
44 import com.android.systemui.security.data.repository.SecurityRepository
45 import com.android.systemui.security.data.repository.SecurityRepositoryImpl
46 import com.android.systemui.settings.FakeUserTracker
47 import com.android.systemui.settings.UserTracker
48 import com.android.systemui.statusbar.policy.DeviceProvisionedController
49 import com.android.systemui.statusbar.policy.FakeSecurityController
50 import com.android.systemui.statusbar.policy.FakeUserInfoController
51 import com.android.systemui.statusbar.policy.SecurityController
52 import com.android.systemui.statusbar.policy.UserInfoController
53 import com.android.systemui.statusbar.policy.UserSwitcherController
54 import com.android.systemui.user.domain.interactor.UserInteractor
55 import com.android.systemui.util.mockito.mock
56 import com.android.systemui.util.settings.FakeSettings
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     /** Enable or disable the user switcher in the settings. */
72     fun setUserSwitcherEnabled(settings: GlobalSettings, enabled: Boolean, userId: Int) {
73         settings.putBoolForUser(Settings.Global.USER_SWITCHER_ENABLED, enabled, userId)
74 
75         // The settings listener is processing messages on the bgHandler (usually backed by a
76         // testableLooper in tests), so let's make sure we process the callback before continuing.
77         testableLooper.processAllMessages()
78     }
79 
80     /** Create a [FooterActionsViewModel] to be used in tests. */
81     fun footerActionsViewModel(
82         @Application context: Context = this.context.applicationContext,
83         footerActionsInteractor: FooterActionsInteractor = footerActionsInteractor(),
84         falsingManager: FalsingManager = FalsingManagerFake(),
85         globalActionsDialogLite: GlobalActionsDialogLite = mock(),
86         showPowerButton: Boolean = true,
87     ): FooterActionsViewModel {
88         return FooterActionsViewModel(
89             context,
90             footerActionsInteractor,
91             falsingManager,
92             globalActionsDialogLite,
93             showPowerButton,
94         )
95     }
96 
97     /** Create a [FooterActionsInteractor] to be used in tests. */
98     fun footerActionsInteractor(
99         activityStarter: ActivityStarter = mock(),
100         metricsLogger: MetricsLogger = FakeMetricsLogger(),
101         uiEventLogger: UiEventLogger = UiEventLoggerFake(),
102         deviceProvisionedController: DeviceProvisionedController = mock(),
103         qsSecurityFooterUtils: QSSecurityFooterUtils = mock(),
104         fgsManagerController: FgsManagerController = mock(),
105         userInteractor: UserInteractor = mock(),
106         securityRepository: SecurityRepository = securityRepository(),
107         foregroundServicesRepository: ForegroundServicesRepository = foregroundServicesRepository(),
108         userSwitcherRepository: UserSwitcherRepository = userSwitcherRepository(),
109         broadcastDispatcher: BroadcastDispatcher = mock(),
110         bgDispatcher: CoroutineDispatcher = StandardTestDispatcher(scheduler),
111     ): FooterActionsInteractor {
112         return FooterActionsInteractorImpl(
113             activityStarter,
114             metricsLogger,
115             uiEventLogger,
116             deviceProvisionedController,
117             qsSecurityFooterUtils,
118             fgsManagerController,
119             userInteractor,
120             securityRepository,
121             foregroundServicesRepository,
122             userSwitcherRepository,
123             broadcastDispatcher,
124             bgDispatcher,
125         )
126     }
127 
128     /** Create a [SecurityRepository] to be used in tests. */
129     fun securityRepository(
130         securityController: SecurityController = FakeSecurityController(),
131         bgDispatcher: CoroutineDispatcher = StandardTestDispatcher(scheduler),
132     ): SecurityRepository {
133         return SecurityRepositoryImpl(
134             securityController,
135             bgDispatcher,
136         )
137     }
138 
139     /** Create a [SecurityRepository] to be used in tests. */
140     fun foregroundServicesRepository(
141         fgsManagerController: FakeFgsManagerController = FakeFgsManagerController(),
142     ): ForegroundServicesRepository {
143         return ForegroundServicesRepositoryImpl(fgsManagerController)
144     }
145 
146     /** Create a [UserSwitcherRepository] to be used in tests. */
147     fun userSwitcherRepository(
148         @Application context: Context = this.context.applicationContext,
149         bgHandler: Handler = Handler(testableLooper.looper),
150         bgDispatcher: CoroutineDispatcher = StandardTestDispatcher(scheduler),
151         userManager: UserManager = mock(),
152         userTracker: UserTracker = FakeUserTracker(),
153         userSwitcherController: UserSwitcherController = mock(),
154         userInfoController: UserInfoController = FakeUserInfoController(),
155         settings: GlobalSettings = FakeSettings(),
156     ): UserSwitcherRepository {
157         return UserSwitcherRepositoryImpl(
158             context,
159             bgHandler,
160             bgDispatcher,
161             userManager,
162             userTracker,
163             userSwitcherController,
164             userInfoController,
165             settings,
166         )
167     }
168 }
169