1 /* 2 * Copyright (C) 2020 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.navigationbar; 18 19 import static android.view.Display.DEFAULT_DISPLAY; 20 import static android.view.Display.INVALID_DISPLAY; 21 22 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; 23 24 import static org.mockito.ArgumentMatchers.any; 25 import static org.mockito.ArgumentMatchers.anyBoolean; 26 import static org.mockito.ArgumentMatchers.anyInt; 27 import static org.mockito.ArgumentMatchers.anyLong; 28 import static org.mockito.ArgumentMatchers.argThat; 29 import static org.mockito.ArgumentMatchers.eq; 30 import static org.mockito.Mockito.doNothing; 31 import static org.mockito.Mockito.doReturn; 32 import static org.mockito.Mockito.mock; 33 import static org.mockito.Mockito.never; 34 import static org.mockito.Mockito.spy; 35 import static org.mockito.Mockito.times; 36 import static org.mockito.Mockito.verify; 37 import static org.mockito.Mockito.when; 38 39 import android.content.res.Configuration; 40 import android.testing.AndroidTestingRunner; 41 import android.testing.TestableLooper.RunWithLooper; 42 import android.util.SparseArray; 43 44 import androidx.test.filters.SmallTest; 45 46 import com.android.dx.mockito.inline.extended.StaticMockitoSession; 47 import com.android.systemui.Dependency; 48 import com.android.systemui.SysuiTestCase; 49 import com.android.systemui.dump.DumpManager; 50 import com.android.systemui.flags.FeatureFlags; 51 import com.android.systemui.model.SysUiState; 52 import com.android.systemui.recents.OverviewProxyService; 53 import com.android.systemui.settings.FakeDisplayTracker; 54 import com.android.systemui.shared.recents.utilities.Utilities; 55 import com.android.systemui.shared.system.TaskStackChangeListeners; 56 import com.android.systemui.statusbar.CommandQueue; 57 import com.android.systemui.statusbar.phone.AutoHideController; 58 import com.android.systemui.statusbar.phone.LightBarController; 59 import com.android.systemui.statusbar.policy.ConfigurationController; 60 import com.android.systemui.util.settings.SecureSettings; 61 import com.android.wm.shell.back.BackAnimation; 62 import com.android.wm.shell.pip.Pip; 63 64 import org.junit.After; 65 import org.junit.Before; 66 import org.junit.Test; 67 import org.junit.runner.RunWith; 68 import org.mockito.Mock; 69 import org.mockito.MockitoAnnotations; 70 71 import java.util.Optional; 72 73 /** atest NavigationBarControllerTest */ 74 @RunWith(AndroidTestingRunner.class) 75 @RunWithLooper 76 @SmallTest 77 public class NavigationBarControllerTest extends SysuiTestCase { 78 79 private static final int SECONDARY_DISPLAY = 1; 80 81 private NavigationBarController mNavigationBarController; 82 private NavigationBar mDefaultNavBar; 83 private NavigationBar mSecondaryNavBar; 84 private StaticMockitoSession mMockitoSession; 85 private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext); 86 87 @Mock 88 private CommandQueue mCommandQueue; 89 @Mock 90 private NavigationBarComponent.Factory mNavigationBarFactory; 91 @Mock 92 TaskbarDelegate mTaskbarDelegate; 93 94 @Before setUp()95 public void setUp() { 96 MockitoAnnotations.initMocks(this); 97 mNavigationBarController = spy( 98 new NavigationBarController(mContext, 99 mock(OverviewProxyService.class), 100 mock(NavigationModeController.class), 101 mock(SysUiState.class), 102 mCommandQueue, 103 Dependency.get(Dependency.MAIN_HANDLER), 104 mock(ConfigurationController.class), 105 mock(NavBarHelper.class), 106 mTaskbarDelegate, 107 mNavigationBarFactory, 108 mock(DumpManager.class), 109 mock(AutoHideController.class), 110 mock(LightBarController.class), 111 TaskStackChangeListeners.getTestInstance(), 112 Optional.of(mock(Pip.class)), 113 Optional.of(mock(BackAnimation.class)), 114 mock(FeatureFlags.class), 115 mock(SecureSettings.class), 116 mDisplayTracker)); 117 initializeNavigationBars(); 118 mMockitoSession = mockitoSession().mockStatic(Utilities.class).startMocking(); 119 } 120 initializeNavigationBars()121 private void initializeNavigationBars() { 122 mNavigationBarController.mNavigationBars = mock(SparseArray.class); 123 mDefaultNavBar = mock(NavigationBar.class); 124 mDefaultNavBar.mDisplayId = DEFAULT_DISPLAY; 125 doReturn(mDefaultNavBar) 126 .when(mNavigationBarController.mNavigationBars).get(DEFAULT_DISPLAY); 127 128 mSecondaryNavBar = mock(NavigationBar.class); 129 mSecondaryNavBar.mDisplayId = SECONDARY_DISPLAY; 130 doReturn(mSecondaryNavBar) 131 .when(mNavigationBarController.mNavigationBars).get(SECONDARY_DISPLAY); 132 } 133 134 @After tearDown()135 public void tearDown() { 136 mNavigationBarController = null; 137 mDefaultNavBar = null; 138 mSecondaryNavBar = null; 139 mMockitoSession.finishMocking(); 140 } 141 142 @Test testCreateNavigationBarsIncludeDefaultTrue()143 public void testCreateNavigationBarsIncludeDefaultTrue() { 144 // Large screens may be using taskbar and the logic is different 145 mNavigationBarController.mIsLargeScreen = false; 146 doNothing().when(mNavigationBarController).createNavigationBar(any(), any(), any()); 147 148 mNavigationBarController.createNavigationBars(true, null); 149 150 verify(mNavigationBarController).createNavigationBar( 151 argThat(display -> display.getDisplayId() == DEFAULT_DISPLAY), any(), any()); 152 } 153 154 @Test testCreateNavigationBarsIncludeDefaultFalse()155 public void testCreateNavigationBarsIncludeDefaultFalse() { 156 doNothing().when(mNavigationBarController).createNavigationBar(any(), any(), any()); 157 158 mNavigationBarController.createNavigationBars(false, null); 159 160 verify(mNavigationBarController, never()).createNavigationBar( 161 argThat(display -> display.getDisplayId() == DEFAULT_DISPLAY), any(), any()); 162 } 163 164 // Tests if NPE occurs when call checkNavBarModes() with invalid display. 165 @Test testCheckNavBarModesWithInvalidDisplay()166 public void testCheckNavBarModesWithInvalidDisplay() { 167 mNavigationBarController.checkNavBarModes(INVALID_DISPLAY); 168 } 169 170 @Test testCheckNavBarModesWithDefaultDisplay()171 public void testCheckNavBarModesWithDefaultDisplay() { 172 doNothing().when(mDefaultNavBar).checkNavBarModes(); 173 174 mNavigationBarController.checkNavBarModes(DEFAULT_DISPLAY); 175 176 verify(mDefaultNavBar).checkNavBarModes(); 177 } 178 179 @Test testCheckNavBarModesWithSecondaryDisplay()180 public void testCheckNavBarModesWithSecondaryDisplay() { 181 doNothing().when(mSecondaryNavBar).checkNavBarModes(); 182 183 mNavigationBarController.checkNavBarModes(SECONDARY_DISPLAY); 184 185 verify(mSecondaryNavBar).checkNavBarModes(); 186 } 187 188 // Tests if NPE occurs when call finishBarAnimations() with invalid display. 189 @Test testFinishBarAnimationsWithInvalidDisplay()190 public void testFinishBarAnimationsWithInvalidDisplay() { 191 mNavigationBarController.finishBarAnimations(INVALID_DISPLAY); 192 } 193 194 @Test testFinishBarAnimationsWithDefaultDisplay()195 public void testFinishBarAnimationsWithDefaultDisplay() { 196 doNothing().when(mDefaultNavBar).finishBarAnimations(); 197 198 mNavigationBarController.finishBarAnimations(DEFAULT_DISPLAY); 199 200 verify(mDefaultNavBar).finishBarAnimations(); 201 } 202 203 @Test testFinishBarAnimationsWithSecondaryDisplay()204 public void testFinishBarAnimationsWithSecondaryDisplay() { 205 doNothing().when(mSecondaryNavBar).finishBarAnimations(); 206 207 mNavigationBarController.finishBarAnimations(SECONDARY_DISPLAY); 208 209 verify(mSecondaryNavBar).finishBarAnimations(); 210 } 211 212 // Tests if NPE occurs when call touchAutoDim() with invalid display. 213 @Test testTouchAutoDimWithInvalidDisplay()214 public void testTouchAutoDimWithInvalidDisplay() { 215 mNavigationBarController.touchAutoDim(INVALID_DISPLAY); 216 } 217 218 @Test testTouchAutoDimWithDefaultDisplay()219 public void testTouchAutoDimWithDefaultDisplay() { 220 doNothing().when(mDefaultNavBar).touchAutoDim(); 221 222 mNavigationBarController.touchAutoDim(DEFAULT_DISPLAY); 223 224 verify(mDefaultNavBar).touchAutoDim(); 225 } 226 227 @Test testTouchAutoDimWithSecondaryDisplay()228 public void testTouchAutoDimWithSecondaryDisplay() { 229 doNothing().when(mSecondaryNavBar).touchAutoDim(); 230 231 mNavigationBarController.touchAutoDim(SECONDARY_DISPLAY); 232 233 verify(mSecondaryNavBar).touchAutoDim(); 234 } 235 236 // Tests if NPE occurs when call transitionTo() with invalid display. 237 @Test testTransitionToWithInvalidDisplay()238 public void testTransitionToWithInvalidDisplay() { 239 mNavigationBarController.transitionTo(INVALID_DISPLAY, 3, true); 240 } 241 242 @Test testTransitionToWithDefaultDisplay()243 public void testTransitionToWithDefaultDisplay() { 244 doNothing().when(mDefaultNavBar).transitionTo(anyInt(), anyBoolean()); 245 246 mNavigationBarController.transitionTo(DEFAULT_DISPLAY, 3, true); 247 248 verify(mDefaultNavBar).transitionTo(eq(3), eq(true)); 249 } 250 251 @Test testTransitionToWithSecondaryDisplay()252 public void testTransitionToWithSecondaryDisplay() { 253 doNothing().when(mSecondaryNavBar).transitionTo(anyInt(), anyBoolean()); 254 255 mNavigationBarController.transitionTo(SECONDARY_DISPLAY, 3, true); 256 257 verify(mSecondaryNavBar).transitionTo(eq(3), eq(true)); 258 } 259 260 // Tests if NPE occurs when call disableAnimationsDuringHide() with invalid display. 261 @Test testDisableAnimationsDuringHideWithInvalidDisplay()262 public void testDisableAnimationsDuringHideWithInvalidDisplay() { 263 mNavigationBarController.disableAnimationsDuringHide(INVALID_DISPLAY, 500L); 264 } 265 266 @Test testDisableAnimationsDuringHideWithDefaultDisplay()267 public void testDisableAnimationsDuringHideWithDefaultDisplay() { 268 doNothing().when(mDefaultNavBar).disableAnimationsDuringHide(anyLong()); 269 270 mNavigationBarController.disableAnimationsDuringHide(DEFAULT_DISPLAY, 500L); 271 272 verify(mDefaultNavBar).disableAnimationsDuringHide(eq(500L)); 273 } 274 275 @Test testDisableAnimationsDuringHideWithSecondaryDisplay()276 public void testDisableAnimationsDuringHideWithSecondaryDisplay() { 277 doNothing().when(mSecondaryNavBar).disableAnimationsDuringHide(anyLong()); 278 279 mNavigationBarController.disableAnimationsDuringHide(SECONDARY_DISPLAY, 500L); 280 281 verify(mSecondaryNavBar).disableAnimationsDuringHide(eq(500L)); 282 } 283 284 @Test test3ButtonTaskbarFlagDisabledNoRegister()285 public void test3ButtonTaskbarFlagDisabledNoRegister() { 286 verify(mCommandQueue, never()).addCallback(any(TaskbarDelegate.class)); 287 } 288 289 290 @Test testConfigurationChange_taskbarNotInitialized()291 public void testConfigurationChange_taskbarNotInitialized() { 292 Configuration configuration = mContext.getResources().getConfiguration(); 293 when(Utilities.isLargeScreen(any())).thenReturn(true); 294 mNavigationBarController.onConfigChanged(configuration); 295 verify(mTaskbarDelegate, never()).onConfigurationChanged(configuration); 296 } 297 298 @Test testConfigurationChange_taskbarInitialized()299 public void testConfigurationChange_taskbarInitialized() { 300 Configuration configuration = mContext.getResources().getConfiguration(); 301 when(Utilities.isLargeScreen(any())).thenReturn(true); 302 when(mTaskbarDelegate.isInitialized()).thenReturn(true); 303 mNavigationBarController.onConfigChanged(configuration); 304 verify(mTaskbarDelegate, times(1)).onConfigurationChanged(configuration); 305 } 306 } 307