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.server.wm; 18 19 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; 20 import static android.app.servertransaction.ActivityLifecycleItem.ON_PAUSE; 21 import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP; 22 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; 23 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED; 24 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; 25 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; 26 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 27 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; 28 import static android.content.res.Configuration.ORIENTATION_PORTRAIT; 29 import static android.view.Surface.ROTATION_0; 30 import static android.view.Surface.ROTATION_90; 31 32 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; 33 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 34 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; 35 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; 36 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; 37 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; 38 39 import static org.junit.Assert.assertEquals; 40 import static org.junit.Assert.assertTrue; 41 import static org.mockito.ArgumentMatchers.any; 42 import static org.mockito.ArgumentMatchers.anyBoolean; 43 import static org.mockito.ArgumentMatchers.anyLong; 44 import static org.mockito.ArgumentMatchers.eq; 45 import static org.mockito.Mockito.mock; 46 import static org.mockito.Mockito.times; 47 import static org.mockito.Mockito.verify; 48 49 import android.app.servertransaction.ClientTransaction; 50 import android.app.servertransaction.RefreshCallbackItem; 51 import android.app.servertransaction.ResumeActivityItem; 52 import android.content.ComponentName; 53 import android.content.pm.ActivityInfo.ScreenOrientation; 54 import android.content.res.Configuration; 55 import android.content.res.Configuration.Orientation; 56 import android.hardware.camera2.CameraManager; 57 import android.os.Handler; 58 import android.platform.test.annotations.Presubmit; 59 import android.view.Display; 60 import android.view.Surface.Rotation; 61 62 import androidx.test.filters.SmallTest; 63 64 import com.android.internal.R; 65 66 import org.junit.Before; 67 import org.junit.Test; 68 import org.junit.runner.RunWith; 69 70 import java.util.concurrent.Executor; 71 72 /** 73 * Tests for {@link DisplayRotationCompatPolicy}. 74 * 75 * Build/Install/Run: 76 * atest WmTests:DisplayRotationCompatPolicyTests 77 */ 78 @SmallTest 79 @Presubmit 80 @RunWith(WindowTestRunner.class) 81 public final class DisplayRotationCompatPolicyTests extends WindowTestsBase { 82 83 private static final String TEST_PACKAGE_1 = "com.test.package.one"; 84 private static final String TEST_PACKAGE_2 = "com.test.package.two"; 85 private static final String CAMERA_ID_1 = "camera-1"; 86 private static final String CAMERA_ID_2 = "camera-2"; 87 88 private CameraManager mMockCameraManager; 89 private Handler mMockHandler; 90 private LetterboxConfiguration mLetterboxConfiguration; 91 92 private DisplayRotationCompatPolicy mDisplayRotationCompatPolicy; 93 private CameraManager.AvailabilityCallback mCameraAvailabilityCallback; 94 95 private ActivityRecord mActivity; 96 private Task mTask; 97 98 @Before setUp()99 public void setUp() throws Exception { 100 mLetterboxConfiguration = mDisplayContent.mWmService.mLetterboxConfiguration; 101 spyOn(mLetterboxConfiguration); 102 when(mLetterboxConfiguration.isCameraCompatTreatmentEnabled( 103 /* checkDeviceConfig */ anyBoolean())) 104 .thenReturn(true); 105 when(mLetterboxConfiguration.isCameraCompatRefreshEnabled()) 106 .thenReturn(true); 107 when(mLetterboxConfiguration.isCameraCompatRefreshCycleThroughStopEnabled()) 108 .thenReturn(true); 109 110 mMockCameraManager = mock(CameraManager.class); 111 doAnswer(invocation -> { 112 mCameraAvailabilityCallback = invocation.getArgument(1); 113 return null; 114 }).when(mMockCameraManager).registerAvailabilityCallback( 115 any(Executor.class), any(CameraManager.AvailabilityCallback.class)); 116 117 spyOn(mContext); 118 when(mContext.getSystemService(CameraManager.class)).thenReturn(mMockCameraManager); 119 120 spyOn(mDisplayContent); 121 122 mDisplayContent.setIgnoreOrientationRequest(true); 123 124 mMockHandler = mock(Handler.class); 125 126 when(mMockHandler.postDelayed(any(Runnable.class), anyLong())).thenAnswer( 127 invocation -> { 128 ((Runnable) invocation.getArgument(0)).run(); 129 return null; 130 }); 131 mDisplayRotationCompatPolicy = new DisplayRotationCompatPolicy( 132 mDisplayContent, mMockHandler); 133 } 134 135 @Test testOpenedCameraInSplitScreen_showToast()136 public void testOpenedCameraInSplitScreen_showToast() { 137 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 138 spyOn(mTask); 139 spyOn(mDisplayRotationCompatPolicy); 140 doReturn(WINDOWING_MODE_MULTI_WINDOW).when(mActivity).getWindowingMode(); 141 doReturn(WINDOWING_MODE_MULTI_WINDOW).when(mTask).getWindowingMode(); 142 143 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 144 145 verify(mDisplayRotationCompatPolicy).showToast( 146 R.string.display_rotation_camera_compat_toast_in_split_screen); 147 } 148 149 @Test testOpenedCameraInSplitScreen_orientationNotFixed_doNotShowToast()150 public void testOpenedCameraInSplitScreen_orientationNotFixed_doNotShowToast() { 151 configureActivity(SCREEN_ORIENTATION_UNSPECIFIED); 152 spyOn(mTask); 153 spyOn(mDisplayRotationCompatPolicy); 154 doReturn(WINDOWING_MODE_MULTI_WINDOW).when(mActivity).getWindowingMode(); 155 doReturn(WINDOWING_MODE_MULTI_WINDOW).when(mTask).getWindowingMode(); 156 157 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 158 159 verify(mDisplayRotationCompatPolicy, never()).showToast( 160 R.string.display_rotation_camera_compat_toast_in_split_screen); 161 } 162 163 @Test testOnScreenRotationAnimationFinished_treatmentNotEnabled_doNotShowToast()164 public void testOnScreenRotationAnimationFinished_treatmentNotEnabled_doNotShowToast() { 165 when(mLetterboxConfiguration.isCameraCompatTreatmentEnabled( 166 /* checkDeviceConfig */ anyBoolean())) 167 .thenReturn(false); 168 spyOn(mDisplayRotationCompatPolicy); 169 170 mDisplayRotationCompatPolicy.onScreenRotationAnimationFinished(); 171 172 verify(mDisplayRotationCompatPolicy, never()).showToast( 173 R.string.display_rotation_camera_compat_toast_after_rotation); 174 } 175 176 @Test testOnScreenRotationAnimationFinished_noOpenCamera_doNotShowToast()177 public void testOnScreenRotationAnimationFinished_noOpenCamera_doNotShowToast() { 178 spyOn(mDisplayRotationCompatPolicy); 179 180 mDisplayRotationCompatPolicy.onScreenRotationAnimationFinished(); 181 182 verify(mDisplayRotationCompatPolicy, never()).showToast( 183 R.string.display_rotation_camera_compat_toast_after_rotation); 184 } 185 186 @Test testOnScreenRotationAnimationFinished_notFullscreen_doNotShowToast()187 public void testOnScreenRotationAnimationFinished_notFullscreen_doNotShowToast() { 188 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 189 doReturn(true).when(mActivity).inMultiWindowMode(); 190 spyOn(mDisplayRotationCompatPolicy); 191 192 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 193 194 mDisplayRotationCompatPolicy.onScreenRotationAnimationFinished(); 195 196 verify(mDisplayRotationCompatPolicy, never()).showToast( 197 R.string.display_rotation_camera_compat_toast_after_rotation); 198 } 199 200 @Test testOnScreenRotationAnimationFinished_orientationNotFixed_doNotShowToast()201 public void testOnScreenRotationAnimationFinished_orientationNotFixed_doNotShowToast() { 202 configureActivity(SCREEN_ORIENTATION_UNSPECIFIED); 203 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 204 spyOn(mDisplayRotationCompatPolicy); 205 206 mDisplayRotationCompatPolicy.onScreenRotationAnimationFinished(); 207 208 verify(mDisplayRotationCompatPolicy, never()).showToast( 209 R.string.display_rotation_camera_compat_toast_after_rotation); 210 } 211 212 @Test testOnScreenRotationAnimationFinished_showToast()213 public void testOnScreenRotationAnimationFinished_showToast() { 214 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 215 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 216 spyOn(mDisplayRotationCompatPolicy); 217 218 mDisplayRotationCompatPolicy.onScreenRotationAnimationFinished(); 219 220 verify(mDisplayRotationCompatPolicy).showToast( 221 R.string.display_rotation_camera_compat_toast_after_rotation); 222 } 223 224 @Test testTreatmentNotEnabled_noForceRotationOrRefresh()225 public void testTreatmentNotEnabled_noForceRotationOrRefresh() throws Exception { 226 when(mLetterboxConfiguration.isCameraCompatTreatmentEnabled( 227 /* checkDeviceConfig */ anyBoolean())) 228 .thenReturn(false); 229 230 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 231 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 232 233 assertEquals(mDisplayRotationCompatPolicy.getOrientation(), 234 SCREEN_ORIENTATION_UNSPECIFIED); 235 236 assertNoForceRotationOrRefresh(); 237 } 238 239 @Test testTreatmentDisabledViaDeviceConfig_noForceRotationOrRefresh()240 public void testTreatmentDisabledViaDeviceConfig_noForceRotationOrRefresh() throws Exception { 241 when(mLetterboxConfiguration.isCameraCompatTreatmentEnabled( 242 /* checkDeviceConfig */ true)) 243 .thenReturn(false); 244 245 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 246 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 247 248 assertNoForceRotationOrRefresh(); 249 } 250 251 @Test testTreatmentDisabledPerApp_noForceRotationOrRefresh()252 public void testTreatmentDisabledPerApp_noForceRotationOrRefresh() 253 throws Exception { 254 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 255 when(mActivity.mLetterboxUiController.shouldForceRotateForCameraCompat()) 256 .thenReturn(false); 257 258 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 259 260 assertNoForceRotationOrRefresh(); 261 } 262 263 @Test testMultiWindowMode_returnUnspecified_noForceRotationOrRefresh()264 public void testMultiWindowMode_returnUnspecified_noForceRotationOrRefresh() throws Exception { 265 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 266 final TestSplitOrganizer organizer = new TestSplitOrganizer(mAtm, mDisplayContent); 267 mActivity.getTask().reparent(organizer.mPrimary, WindowContainer.POSITION_TOP, 268 false /* moveParents */, "test" /* reason */); 269 270 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 271 272 assertTrue(mActivity.inMultiWindowMode()); 273 assertNoForceRotationOrRefresh(); 274 } 275 276 @Test testOrientationUnspecified_noForceRotationOrRefresh()277 public void testOrientationUnspecified_noForceRotationOrRefresh() throws Exception { 278 configureActivity(SCREEN_ORIENTATION_UNSPECIFIED); 279 280 assertNoForceRotationOrRefresh(); 281 } 282 283 @Test testOrientationLocked_noForceRotationOrRefresh()284 public void testOrientationLocked_noForceRotationOrRefresh() throws Exception { 285 configureActivity(SCREEN_ORIENTATION_LOCKED); 286 287 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 288 289 assertNoForceRotationOrRefresh(); 290 } 291 292 @Test testOrientationNoSensor_noForceRotationOrRefresh()293 public void testOrientationNoSensor_noForceRotationOrRefresh() throws Exception { 294 configureActivity(SCREEN_ORIENTATION_NOSENSOR); 295 296 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 297 298 assertNoForceRotationOrRefresh(); 299 } 300 301 @Test testIgnoreOrientationRequestIsFalse_noForceRotationOrRefresh()302 public void testIgnoreOrientationRequestIsFalse_noForceRotationOrRefresh() throws Exception { 303 mDisplayContent.setIgnoreOrientationRequest(false); 304 305 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 306 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 307 308 assertNoForceRotationOrRefresh(); 309 } 310 311 @Test testDisplayNotInternal_noForceRotationOrRefresh()312 public void testDisplayNotInternal_noForceRotationOrRefresh() throws Exception { 313 Display display = mDisplayContent.getDisplay(); 314 spyOn(display); 315 316 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 317 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 318 319 when(display.getType()).thenReturn(Display.TYPE_EXTERNAL); 320 assertNoForceRotationOrRefresh(); 321 322 when(display.getType()).thenReturn(Display.TYPE_WIFI); 323 assertNoForceRotationOrRefresh(); 324 325 when(display.getType()).thenReturn(Display.TYPE_OVERLAY); 326 assertNoForceRotationOrRefresh(); 327 328 when(display.getType()).thenReturn(Display.TYPE_VIRTUAL); 329 assertNoForceRotationOrRefresh(); 330 } 331 332 @Test testNoCameraConnection_noForceRotationOrRefresh()333 public void testNoCameraConnection_noForceRotationOrRefresh() throws Exception { 334 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 335 336 assertNoForceRotationOrRefresh(); 337 } 338 339 @Test testCameraReconnected_forceRotationAndRefresh()340 public void testCameraReconnected_forceRotationAndRefresh() throws Exception { 341 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 342 343 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 344 mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1); 345 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 346 callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true); 347 348 assertEquals(mDisplayRotationCompatPolicy.getOrientation(), 349 SCREEN_ORIENTATION_PORTRAIT); 350 assertActivityRefreshRequested(/* refreshRequested */ true); 351 } 352 353 @Test testReconnectedToDifferentCamera_forceRotationAndRefresh()354 public void testReconnectedToDifferentCamera_forceRotationAndRefresh() throws Exception { 355 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 356 357 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 358 mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1); 359 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_2, TEST_PACKAGE_1); 360 callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true); 361 362 assertEquals(mDisplayRotationCompatPolicy.getOrientation(), 363 SCREEN_ORIENTATION_PORTRAIT); 364 assertActivityRefreshRequested(/* refreshRequested */ true); 365 } 366 367 @Test testCameraDisconnected_revertRotationAndRefresh()368 public void testCameraDisconnected_revertRotationAndRefresh() throws Exception { 369 configureActivityAndDisplay(SCREEN_ORIENTATION_PORTRAIT, ORIENTATION_LANDSCAPE); 370 // Open camera and test for compat treatment 371 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 372 callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true); 373 assertEquals(mDisplayRotationCompatPolicy.getOrientation(), 374 SCREEN_ORIENTATION_LANDSCAPE); 375 assertActivityRefreshRequested(/* refreshRequested */ true); 376 // Close camera and test for revert 377 mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1); 378 callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true); 379 assertEquals(mDisplayRotationCompatPolicy.getOrientation(), 380 SCREEN_ORIENTATION_UNSPECIFIED); 381 assertActivityRefreshRequested(/* refreshRequested */ true); 382 } 383 384 @Test testGetOrientation_cameraConnectionClosed_returnUnspecified()385 public void testGetOrientation_cameraConnectionClosed_returnUnspecified() { 386 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 387 388 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 389 390 assertEquals(mDisplayRotationCompatPolicy.getOrientation(), 391 SCREEN_ORIENTATION_PORTRAIT); 392 393 mCameraAvailabilityCallback.onCameraClosed(CAMERA_ID_1); 394 395 assertEquals(mDisplayRotationCompatPolicy.getOrientation(), 396 SCREEN_ORIENTATION_UNSPECIFIED); 397 } 398 399 @Test testCameraOpenedForDifferentPackage_noForceRotationOrRefresh()400 public void testCameraOpenedForDifferentPackage_noForceRotationOrRefresh() throws Exception { 401 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 402 403 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_2); 404 405 assertNoForceRotationOrRefresh(); 406 } 407 408 @Test testGetOrientation_portraitActivity_portraitNaturalOrientation_returnPortrait()409 public void testGetOrientation_portraitActivity_portraitNaturalOrientation_returnPortrait() { 410 testGetOrientationForActivityAndNaturalOrientations( 411 /* activityOrientation */ SCREEN_ORIENTATION_PORTRAIT, 412 /* naturalOrientation */ ORIENTATION_PORTRAIT, 413 /* expectedOrientation */ SCREEN_ORIENTATION_PORTRAIT); 414 } 415 416 @Test testGetOrientation_portraitActivity_landscapeNaturalOrientation_returnLandscape()417 public void testGetOrientation_portraitActivity_landscapeNaturalOrientation_returnLandscape() { 418 testGetOrientationForActivityAndNaturalOrientations( 419 /* activityOrientation */ SCREEN_ORIENTATION_PORTRAIT, 420 /* naturalOrientation */ ORIENTATION_LANDSCAPE, 421 /* expectedOrientation */ SCREEN_ORIENTATION_LANDSCAPE); 422 } 423 424 @Test testGetOrientation_landscapeActivity_portraitNaturalOrientation_returnLandscape()425 public void testGetOrientation_landscapeActivity_portraitNaturalOrientation_returnLandscape() { 426 testGetOrientationForActivityAndNaturalOrientations( 427 /* activityOrientation */ SCREEN_ORIENTATION_LANDSCAPE, 428 /* naturalOrientation */ ORIENTATION_PORTRAIT, 429 /* expectedOrientation */ SCREEN_ORIENTATION_LANDSCAPE); 430 } 431 432 @Test testGetOrientation_landscapeActivity_landscapeNaturalOrientation_returnPortrait()433 public void testGetOrientation_landscapeActivity_landscapeNaturalOrientation_returnPortrait() { 434 testGetOrientationForActivityAndNaturalOrientations( 435 /* activityOrientation */ SCREEN_ORIENTATION_LANDSCAPE, 436 /* naturalOrientation */ ORIENTATION_LANDSCAPE, 437 /* expectedOrientation */ SCREEN_ORIENTATION_PORTRAIT); 438 } 439 testGetOrientationForActivityAndNaturalOrientations( @creenOrientation int activityOrientation, @Orientation int naturalOrientation, @ScreenOrientation int expectedOrientation)440 private void testGetOrientationForActivityAndNaturalOrientations( 441 @ScreenOrientation int activityOrientation, 442 @Orientation int naturalOrientation, 443 @ScreenOrientation int expectedOrientation) { 444 configureActivityAndDisplay(activityOrientation, naturalOrientation); 445 446 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 447 448 assertEquals(mDisplayRotationCompatPolicy.getOrientation(), 449 expectedOrientation); 450 } 451 452 @Test testOnActivityConfigurationChanging_refreshDisabledViaFlag_noRefresh()453 public void testOnActivityConfigurationChanging_refreshDisabledViaFlag_noRefresh() 454 throws Exception { 455 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 456 when(mActivity.mLetterboxUiController.shouldRefreshActivityForCameraCompat()) 457 .thenReturn(false); 458 459 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 460 callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true); 461 462 assertActivityRefreshRequested(/* refreshRequested */ false); 463 } 464 465 @Test testOnActivityConfigurationChanging_refreshDisabledPerApp_noRefresh()466 public void testOnActivityConfigurationChanging_refreshDisabledPerApp_noRefresh() 467 throws Exception { 468 when(mLetterboxConfiguration.isCameraCompatRefreshEnabled()).thenReturn(false); 469 470 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 471 472 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 473 callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true); 474 475 assertActivityRefreshRequested(/* refreshRequested */ false); 476 } 477 478 @Test testOnActivityConfigurationChanging_displayRotationNotChanging_noRefresh()479 public void testOnActivityConfigurationChanging_displayRotationNotChanging_noRefresh() 480 throws Exception { 481 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 482 483 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 484 callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ false); 485 486 assertActivityRefreshRequested(/* refreshRequested */ false); 487 } 488 489 @Test testOnActivityConfigurationChanging_cycleThroughStopDisabled()490 public void testOnActivityConfigurationChanging_cycleThroughStopDisabled() throws Exception { 491 when(mLetterboxConfiguration.isCameraCompatRefreshCycleThroughStopEnabled()) 492 .thenReturn(false); 493 494 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 495 496 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 497 callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true); 498 499 assertActivityRefreshRequested(/* refreshRequested */ true, /* cycleThroughStop */ false); 500 } 501 502 @Test testOnActivityConfigurationChanging_cycleThroughStopDisabledForApp()503 public void testOnActivityConfigurationChanging_cycleThroughStopDisabledForApp() 504 throws Exception { 505 configureActivity(SCREEN_ORIENTATION_PORTRAIT); 506 when(mActivity.mLetterboxUiController.shouldRefreshActivityViaPauseForCameraCompat()) 507 .thenReturn(true); 508 509 mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); 510 callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true); 511 512 assertActivityRefreshRequested(/* refreshRequested */ true, /* cycleThroughStop */ false); 513 } 514 configureActivity(@creenOrientation int activityOrientation)515 private void configureActivity(@ScreenOrientation int activityOrientation) { 516 configureActivityAndDisplay(activityOrientation, ORIENTATION_PORTRAIT); 517 } 518 configureActivityAndDisplay(@creenOrientation int activityOrientation, @Orientation int naturalOrientation)519 private void configureActivityAndDisplay(@ScreenOrientation int activityOrientation, 520 @Orientation int naturalOrientation) { 521 522 mTask = new TaskBuilder(mSupervisor) 523 .setDisplay(mDisplayContent) 524 .build(); 525 526 mActivity = new ActivityBuilder(mAtm) 527 .setComponent(new ComponentName(TEST_PACKAGE_1, ".TestActivity")) 528 .setScreenOrientation(activityOrientation) 529 .setTask(mTask) 530 .build(); 531 532 spyOn(mActivity.mAtmService.getLifecycleManager()); 533 spyOn(mActivity.mLetterboxUiController); 534 535 doReturn(mActivity).when(mDisplayContent).topRunningActivity(anyBoolean()); 536 doReturn(naturalOrientation).when(mDisplayContent).getNaturalOrientation(); 537 } 538 assertActivityRefreshRequested(boolean refreshRequested)539 private void assertActivityRefreshRequested(boolean refreshRequested) throws Exception { 540 assertActivityRefreshRequested(refreshRequested, /* cycleThroughStop*/ true); 541 } 542 assertActivityRefreshRequested(boolean refreshRequested, boolean cycleThroughStop)543 private void assertActivityRefreshRequested(boolean refreshRequested, 544 boolean cycleThroughStop) throws Exception { 545 verify(mActivity.mLetterboxUiController, times(refreshRequested ? 1 : 0)) 546 .setIsRefreshAfterRotationRequested(true); 547 548 final ClientTransaction transaction = ClientTransaction.obtain( 549 mActivity.app.getThread(), mActivity.token); 550 transaction.addCallback(RefreshCallbackItem.obtain(cycleThroughStop ? ON_STOP : ON_PAUSE)); 551 transaction.setLifecycleStateRequest(ResumeActivityItem.obtain( 552 /* isForward */ false, /* shouldSendCompatFakeFocus */ false)); 553 554 verify(mActivity.mAtmService.getLifecycleManager(), times(refreshRequested ? 1 : 0)) 555 .scheduleTransaction(eq(transaction)); 556 } 557 assertNoForceRotationOrRefresh()558 private void assertNoForceRotationOrRefresh() throws Exception { 559 callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true); 560 561 assertEquals(mDisplayRotationCompatPolicy.getOrientation(), 562 SCREEN_ORIENTATION_UNSPECIFIED); 563 assertActivityRefreshRequested(/* refreshRequested */ false); 564 } 565 callOnActivityConfigurationChanging( ActivityRecord activity, boolean isDisplayRotationChanging)566 private void callOnActivityConfigurationChanging( 567 ActivityRecord activity, boolean isDisplayRotationChanging) { 568 mDisplayRotationCompatPolicy.onActivityConfigurationChanging(activity, 569 /* newConfig */ createConfigurationWithDisplayRotation(ROTATION_0), 570 /* newConfig */ createConfigurationWithDisplayRotation( 571 isDisplayRotationChanging ? ROTATION_90 : ROTATION_0)); 572 } 573 createConfigurationWithDisplayRotation(@otation int rotation)574 private static Configuration createConfigurationWithDisplayRotation(@Rotation int rotation) { 575 final Configuration config = new Configuration(); 576 config.windowConfiguration.setDisplayRotation(rotation); 577 return config; 578 } 579 } 580