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