Added OnSetRequestedOrientation callback
DisplayRotation disables Auto-Rotation for immersive applications. But during the rotation of the device, application may change the requested orientation by calling ActivityRecord.setRequestedOrientation This CL makes sure that onProposedRotationChanged gets reevaluated if previously user was shown with the rotation button, and then setRequestedOrientation being invoked by the application. Bug: 275810916 Test: atest DisplayRotationTests ActivityRecordTests Change-Id: I4fe6ef7716398047a757a5c761f316f6145d00b6 Merged-In: I4fe6ef7716398047a757a5c761f316f6145d00b6
This commit is contained in:
@@ -7867,6 +7867,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
|
||||
mAtmService.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
|
||||
task.mTaskId, requestedOrientation);
|
||||
|
||||
mDisplayContent.getDisplayRotation().onSetRequestedOrientation();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -92,6 +92,8 @@ public class DisplayRotation {
|
||||
// config changes and unexpected jumps while folding the device to closed state.
|
||||
private static final int FOLDING_RECOMPUTE_CONFIG_DELAY_MS = 800;
|
||||
|
||||
private static final int ROTATION_UNDEFINED = -1;
|
||||
|
||||
private static class RotationAnimationPair {
|
||||
@AnimRes
|
||||
int mEnter;
|
||||
@@ -179,6 +181,12 @@ public class DisplayRotation {
|
||||
*/
|
||||
private int mShowRotationSuggestions;
|
||||
|
||||
/**
|
||||
* The most recent {@link Surface.Rotation} choice shown to the user for confirmation, or
|
||||
* {@link #ROTATION_UNDEFINED}
|
||||
*/
|
||||
private int mRotationChoiceShownToUserForConfirmation = ROTATION_UNDEFINED;
|
||||
|
||||
private static final int ALLOW_ALL_ROTATIONS_UNDEFINED = -1;
|
||||
private static final int ALLOW_ALL_ROTATIONS_DISABLED = 0;
|
||||
private static final int ALLOW_ALL_ROTATIONS_ENABLED = 1;
|
||||
@@ -856,6 +864,7 @@ public class DisplayRotation {
|
||||
|
||||
@VisibleForTesting
|
||||
void setUserRotation(int userRotationMode, int userRotation) {
|
||||
mRotationChoiceShownToUserForConfirmation = ROTATION_UNDEFINED;
|
||||
if (isDefaultDisplay) {
|
||||
// We'll be notified via settings listener, so we don't need to update internal values.
|
||||
final ContentResolver res = mContext.getContentResolver();
|
||||
@@ -1545,6 +1554,17 @@ public class DisplayRotation {
|
||||
return shouldUpdateRotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from {@link ActivityRecord#setRequestedOrientation(int)}
|
||||
*/
|
||||
void onSetRequestedOrientation() {
|
||||
if (mCompatPolicyForImmersiveApps == null
|
||||
|| mRotationChoiceShownToUserForConfirmation == ROTATION_UNDEFINED) {
|
||||
return;
|
||||
}
|
||||
mOrientationListener.onProposedRotationChanged(mRotationChoiceShownToUserForConfirmation);
|
||||
}
|
||||
|
||||
void dump(String prefix, PrintWriter pw) {
|
||||
pw.println(prefix + "DisplayRotation");
|
||||
pw.println(prefix + " mCurrentAppOrientation="
|
||||
@@ -1786,9 +1806,11 @@ public class DisplayRotation {
|
||||
// Send interaction power boost to improve redraw performance.
|
||||
mService.mPowerManagerInternal.setPowerBoost(Boost.INTERACTION, 0);
|
||||
if (isRotationChoiceAllowed(rotation)) {
|
||||
mRotationChoiceShownToUserForConfirmation = rotation;
|
||||
final boolean isValid = isValidRotationChoice(rotation);
|
||||
sendProposedRotationChangeToStatusBarInternal(rotation, isValid);
|
||||
} else {
|
||||
mRotationChoiceShownToUserForConfirmation = ROTATION_UNDEFINED;
|
||||
mService.updateRotation(false /* alwaysSendConfiguration */,
|
||||
false /* forceRelayout */);
|
||||
}
|
||||
|
||||
@@ -588,12 +588,18 @@ public class ActivityRecordTests extends WindowTestsBase {
|
||||
throw new IllegalStateException("Orientation in new config should be either"
|
||||
+ "landscape or portrait.");
|
||||
}
|
||||
|
||||
final DisplayRotation displayRotation = activity.mDisplayContent.getDisplayRotation();
|
||||
spyOn(displayRotation);
|
||||
|
||||
activity.setRequestedOrientation(requestedOrientation);
|
||||
|
||||
final ActivityConfigurationChangeItem expected =
|
||||
ActivityConfigurationChangeItem.obtain(newConfig);
|
||||
verify(mAtm.getLifecycleManager()).scheduleTransaction(eq(activity.app.getThread()),
|
||||
eq(activity.token), eq(expected));
|
||||
|
||||
verify(displayRotation).onSetRequestedOrientation();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -67,6 +67,7 @@ import android.view.DisplayAddress;
|
||||
import android.view.Surface;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.util.test.FakeSettingsProvider;
|
||||
@@ -126,6 +127,8 @@ public class DisplayRotationTests {
|
||||
|
||||
private DeviceStateController mDeviceStateController;
|
||||
private DisplayRotation mTarget;
|
||||
@Nullable
|
||||
private DisplayRotationImmersiveAppCompatPolicy mDisplayRotationImmersiveAppCompatPolicyMock;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpOnce() {
|
||||
@@ -149,7 +152,7 @@ public class DisplayRotationTests {
|
||||
LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
|
||||
mMockStatusBarManagerInternal = mock(StatusBarManagerInternal.class);
|
||||
LocalServices.addService(StatusBarManagerInternal.class, mMockStatusBarManagerInternal);
|
||||
|
||||
mDisplayRotationImmersiveAppCompatPolicyMock = null;
|
||||
mBuilder = new DisplayRotationBuilder();
|
||||
}
|
||||
|
||||
@@ -557,6 +560,38 @@ public class DisplayRotationTests {
|
||||
verify(mMockStatusBarManagerInternal).onProposedRotationChanged(Surface.ROTATION_90, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotifiesChoiceWhenSensorUpdates_immersiveApp() throws Exception {
|
||||
mDisplayRotationImmersiveAppCompatPolicyMock = mock(
|
||||
DisplayRotationImmersiveAppCompatPolicy.class);
|
||||
when(mDisplayRotationImmersiveAppCompatPolicyMock.isRotationLockEnforced(
|
||||
Surface.ROTATION_90)).thenReturn(true);
|
||||
|
||||
mBuilder.build();
|
||||
configureDisplayRotation(SCREEN_ORIENTATION_PORTRAIT, false, false);
|
||||
|
||||
thawRotation();
|
||||
|
||||
enableOrientationSensor();
|
||||
|
||||
mOrientationSensorListener.onSensorChanged(createSensorEvent(Surface.ROTATION_90));
|
||||
assertTrue(waitForUiHandler());
|
||||
|
||||
verify(mMockStatusBarManagerInternal).onProposedRotationChanged(Surface.ROTATION_90, true);
|
||||
|
||||
// An imaginary ActivityRecord.setRequestedOrientation call disables immersive mode:
|
||||
when(mDisplayRotationImmersiveAppCompatPolicyMock.isRotationLockEnforced(
|
||||
Surface.ROTATION_90)).thenReturn(false);
|
||||
|
||||
// And then ActivityRecord.setRequestedOrientation calls onSetRequestedOrientation.
|
||||
mTarget.onSetRequestedOrientation();
|
||||
|
||||
// onSetRequestedOrientation should lead to a second call to
|
||||
// mOrientationListener.onProposedRotationChanged
|
||||
// but now, instead of notifying mMockStatusBarManagerInternal, it calls updateRotation:
|
||||
verify(sMockWm).updateRotation(false, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllowAllRotations_allowsUpsideDownSuggestion()
|
||||
throws Exception {
|
||||
@@ -1158,7 +1193,7 @@ public class DisplayRotationTests {
|
||||
@Override
|
||||
DisplayRotationImmersiveAppCompatPolicy initImmersiveAppCompatPolicy(
|
||||
WindowManagerService service, DisplayContent displayContent) {
|
||||
return null;
|
||||
return mDisplayRotationImmersiveAppCompatPolicyMock;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user