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 17 package com.android.systemui.recents 18 19 import android.content.ComponentName 20 import android.content.Context 21 import android.content.pm.PackageManager 22 import android.content.pm.ResolveInfo 23 import android.os.PowerManager 24 import android.os.Process 25 import android.os.UserHandle 26 import android.testing.TestableContext 27 import android.testing.TestableLooper 28 import androidx.test.ext.junit.runners.AndroidJUnit4 29 import androidx.test.filters.SmallTest 30 import com.android.dx.mockito.inline.extended.ExtendedMockito 31 import com.android.internal.app.AssistUtils 32 import com.android.internal.logging.UiEventLogger 33 import com.android.systemui.SysuiTestCase 34 import com.android.systemui.broadcast.BroadcastDispatcher 35 import com.android.systemui.dagger.qualifiers.Main 36 import com.android.systemui.dump.DumpManager 37 import com.android.systemui.keyguard.KeyguardUnlockAnimationController 38 import com.android.systemui.keyguard.WakefulnessLifecycle 39 import com.android.systemui.keyguard.ui.view.InWindowLauncherUnlockAnimationManager 40 import com.android.systemui.model.SysUiState 41 import com.android.systemui.model.sceneContainerPlugin 42 import com.android.systemui.navigationbar.NavigationBarController 43 import com.android.systemui.navigationbar.NavigationModeController 44 import com.android.systemui.recents.OverviewProxyService.ACTION_QUICKSTEP 45 import com.android.systemui.settings.FakeDisplayTracker 46 import com.android.systemui.settings.UserTracker 47 import com.android.systemui.shade.ShadeViewController 48 import com.android.systemui.shared.recents.IOverviewProxy 49 import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_WAKEFULNESS_MASK 50 import com.android.systemui.shared.system.QuickStepContract.WAKEFULNESS_ASLEEP 51 import com.android.systemui.shared.system.QuickStepContract.WAKEFULNESS_AWAKE 52 import com.android.systemui.shared.system.QuickStepContract.WAKEFULNESS_GOING_TO_SLEEP 53 import com.android.systemui.shared.system.QuickStepContract.WAKEFULNESS_WAKING 54 import com.android.systemui.statusbar.CommandQueue 55 import com.android.systemui.statusbar.NotificationShadeWindowController 56 import com.android.systemui.testKosmos 57 import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder 58 import com.android.systemui.util.mockito.mock 59 import com.android.systemui.util.mockito.whenever 60 import com.android.systemui.util.time.FakeSystemClock 61 import com.android.wm.shell.sysui.ShellInterface 62 import com.google.common.util.concurrent.MoreExecutors 63 import java.util.Optional 64 import java.util.concurrent.Executor 65 import org.junit.After 66 import org.junit.Before 67 import org.junit.Test 68 import org.junit.runner.RunWith 69 import org.mockito.ArgumentMatchers 70 import org.mockito.Mock 71 import org.mockito.Mockito.any 72 import org.mockito.Mockito.anyInt 73 import org.mockito.Mockito.atLeast 74 import org.mockito.Mockito.clearInvocations 75 import org.mockito.Mockito.longThat 76 import org.mockito.Mockito.mock 77 import org.mockito.Mockito.spy 78 import org.mockito.Mockito.times 79 import org.mockito.Mockito.verify 80 import org.mockito.Mockito.`when` 81 import org.mockito.MockitoAnnotations 82 83 @SmallTest 84 @RunWith(AndroidJUnit4::class) 85 @TestableLooper.RunWithLooper(setAsMainLooper = true) 86 class OverviewProxyServiceTest : SysuiTestCase() { 87 88 @Main private val executor: Executor = MoreExecutors.directExecutor() 89 90 private val kosmos = testKosmos() 91 private lateinit var subject: OverviewProxyService 92 @Mock private val dumpManager = DumpManager() 93 private val displayTracker = FakeDisplayTracker(mContext) 94 private val fakeSystemClock = FakeSystemClock() 95 private val sysUiState = SysUiState(displayTracker, kosmos.sceneContainerPlugin) 96 private val wakefulnessLifecycle = 97 WakefulnessLifecycle(mContext, null, fakeSystemClock, dumpManager) 98 99 @Mock private lateinit var overviewProxy: IOverviewProxy.Stub 100 @Mock private lateinit var packageManager: PackageManager 101 102 // The following mocks belong to not-yet-tested parts of OverviewProxyService. 103 @Mock private lateinit var commandQueue: CommandQueue 104 @Mock private lateinit var shellInterface: ShellInterface 105 @Mock private lateinit var navBarController: NavigationBarController 106 @Mock private lateinit var shadeViewController: ShadeViewController 107 @Mock private lateinit var screenPinningRequest: ScreenPinningRequest 108 @Mock private lateinit var navModeController: NavigationModeController 109 @Mock private lateinit var statusBarWinController: NotificationShadeWindowController 110 @Mock private lateinit var userTracker: UserTracker 111 @Mock private lateinit var uiEventLogger: UiEventLogger 112 @Mock private lateinit var sysuiUnlockAnimationController: KeyguardUnlockAnimationController 113 @Mock 114 private lateinit var inWindowLauncherUnlockAnimationManager: 115 InWindowLauncherUnlockAnimationManager 116 @Mock private lateinit var assistUtils: AssistUtils 117 @Mock 118 private lateinit var unfoldTransitionProgressForwarder: 119 Optional<UnfoldTransitionProgressForwarder> 120 @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher 121 122 @Before setUpnull123 fun setUp() { 124 MockitoAnnotations.initMocks(this) 125 126 val serviceComponent = ComponentName("test_package", "service_provider") 127 context.addMockService(serviceComponent, overviewProxy) 128 context.addMockServiceResolver( 129 TestableContext.MockServiceResolver { 130 if (it.action == ACTION_QUICKSTEP) serviceComponent else null 131 } 132 ) 133 whenever(overviewProxy.queryLocalInterface(ArgumentMatchers.anyString())) 134 .thenReturn(overviewProxy) 135 whenever(overviewProxy.asBinder()).thenReturn(overviewProxy) 136 137 // packageManager.resolveServiceAsUser has to return non-null for 138 // OverviewProxyService#isEnabled to become true. 139 context.setMockPackageManager(packageManager) 140 whenever(packageManager.resolveServiceAsUser(any(), anyInt(), anyInt())) 141 .thenReturn(mock(ResolveInfo::class.java)) 142 143 mSetFlagsRule.disableFlags( 144 com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR, 145 ) 146 147 subject = createOverviewProxyService(context) 148 } 149 150 @After tearDownnull151 fun tearDown() { 152 subject.shutdownForTest() 153 } 154 155 @Test wakefulnessLifecycle_dispatchFinishedWakingUpSetsSysUIflagToAWAKEnull156 fun wakefulnessLifecycle_dispatchFinishedWakingUpSetsSysUIflagToAWAKE() { 157 // WakefulnessLifecycle is initialized to AWAKE initially, and won't emit a noop. 158 wakefulnessLifecycle.dispatchFinishedGoingToSleep() 159 clearInvocations(overviewProxy) 160 161 wakefulnessLifecycle.dispatchFinishedWakingUp() 162 163 verify(overviewProxy) 164 .onSystemUiStateChanged( 165 longThat { it and SYSUI_STATE_WAKEFULNESS_MASK == WAKEFULNESS_AWAKE } 166 ) 167 } 168 169 @Test wakefulnessLifecycle_dispatchStartedWakingUpSetsSysUIflagToWAKINGnull170 fun wakefulnessLifecycle_dispatchStartedWakingUpSetsSysUIflagToWAKING() { 171 wakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN) 172 173 verify(overviewProxy) 174 .onSystemUiStateChanged( 175 longThat { it and SYSUI_STATE_WAKEFULNESS_MASK == WAKEFULNESS_WAKING } 176 ) 177 } 178 179 @Test wakefulnessLifecycle_dispatchFinishedGoingToSleepSetsSysUIflagToASLEEPnull180 fun wakefulnessLifecycle_dispatchFinishedGoingToSleepSetsSysUIflagToASLEEP() { 181 wakefulnessLifecycle.dispatchFinishedGoingToSleep() 182 183 verify(overviewProxy) 184 .onSystemUiStateChanged( 185 longThat { it and SYSUI_STATE_WAKEFULNESS_MASK == WAKEFULNESS_ASLEEP } 186 ) 187 } 188 189 @Test wakefulnessLifecycle_dispatchStartedGoingToSleepSetsSysUIflagToGOING_TO_SLEEPnull190 fun wakefulnessLifecycle_dispatchStartedGoingToSleepSetsSysUIflagToGOING_TO_SLEEP() { 191 wakefulnessLifecycle.dispatchStartedGoingToSleep( 192 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON 193 ) 194 195 verify(overviewProxy) 196 .onSystemUiStateChanged( 197 longThat { it and SYSUI_STATE_WAKEFULNESS_MASK == WAKEFULNESS_GOING_TO_SLEEP } 198 ) 199 } 200 201 @Test connectToOverviewService_primaryUser_expectBindServicenull202 fun connectToOverviewService_primaryUser_expectBindService() { 203 val mockitoSession = 204 ExtendedMockito.mockitoSession().spyStatic(Process::class.java).startMocking() 205 try { 206 `when`(Process.myUserHandle()).thenReturn(UserHandle.SYSTEM) 207 val spyContext = spy(context) 208 val ops = createOverviewProxyService(spyContext) 209 ops.startConnectionToCurrentUser() 210 verify(spyContext, atLeast(1)).bindServiceAsUser(any(), any(), anyInt(), any()) 211 } finally { 212 mockitoSession.finishMocking() 213 } 214 } 215 216 @Test connectToOverviewService_nonPrimaryUser_expectNoBindServicenull217 fun connectToOverviewService_nonPrimaryUser_expectNoBindService() { 218 val mockitoSession = 219 ExtendedMockito.mockitoSession().spyStatic(Process::class.java).startMocking() 220 try { 221 `when`(Process.myUserHandle()).thenReturn(UserHandle.of(12345)) 222 val spyContext = spy(context) 223 val ops = createOverviewProxyService(spyContext) 224 ops.startConnectionToCurrentUser() 225 verify(spyContext, times(0)).bindServiceAsUser(any(), any(), anyInt(), any()) 226 } finally { 227 mockitoSession.finishMocking() 228 } 229 } 230 createOverviewProxyServicenull231 private fun createOverviewProxyService(ctx: Context): OverviewProxyService { 232 return OverviewProxyService( 233 ctx, 234 executor, 235 commandQueue, 236 shellInterface, 237 { navBarController }, 238 { shadeViewController }, 239 screenPinningRequest, 240 navModeController, 241 statusBarWinController, 242 sysUiState, 243 mock(), 244 userTracker, 245 wakefulnessLifecycle, 246 uiEventLogger, 247 displayTracker, 248 sysuiUnlockAnimationController, 249 inWindowLauncherUnlockAnimationManager, 250 assistUtils, 251 dumpManager, 252 unfoldTransitionProgressForwarder, 253 broadcastDispatcher 254 ) 255 } 256 } 257