Support rotation on secondary displays (2/N)
Move partial operations of rotation/orientation from
PhoneWindowManager to DisplayRotation.
Bug: 111361251
Test: go/wm-smoke
Test: atest FrameworksServicesTests:PhoneWindowManagerLayoutTest
Test: atest FrameworksServicesTests:PhoneWindowManagerInsetsTest
Change-Id: I7507e25f14e7fd1733ffd2a71789673d6a7ee17d
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index e46c03e..79d9b11 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -288,6 +288,7 @@
import com.android.server.wm.ActivityTaskManagerInternal.SleepToken;
import com.android.server.wm.AppTransition;
import com.android.server.wm.DisplayFrames;
+import com.android.server.wm.DisplayRotation;
import com.android.server.wm.WindowFrames;
import com.android.server.wm.WindowManagerInternal;
import com.android.server.wm.WindowManagerInternal.AppTransitionListener;
@@ -619,8 +620,6 @@
ScreenOnListener mScreenOnListener;
boolean mKeyguardDrawComplete;
boolean mWindowManagerDrawComplete;
- boolean mOrientationSensorEnabled = false;
- int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
boolean mHasSoftInput = false;
boolean mTranslucentDecorEnabled = true;
boolean mUseTvRouting;
@@ -735,12 +734,10 @@
// Whether system navigation keys are enabled
boolean mSystemNavigationKeysEnabled;
- Display mDisplay;
-
- int mLandscapeRotation = 0; // default landscape rotation
- int mSeascapeRotation = 0; // "other" landscape rotation, 180 degrees from mLandscapeRotation
- int mPortraitRotation = 0; // default portrait rotation
- int mUpsideDownRotation = 0; // "other" portrait rotation
+ // TODO(multi-display): Remove default when the dependencies are multi-display ready.
+ Display mDefaultDisplay;
+ DisplayRotation mDefaultDisplayRotation;
+ MyOrientationListener mDefaultOrientationListener;
// What we do when the user long presses on home
private int mLongPressOnHomeBehavior;
@@ -1043,9 +1040,11 @@
}
}
- class MyOrientationListener extends WindowOrientationListener {
+ class MyOrientationListener extends WindowOrientationListener
+ implements WindowManagerPolicy.RotationSource {
private SparseArray<Runnable> mRunnableCache;
+ private boolean mEnabled;
MyOrientationListener(Context context, Handler handler) {
super(context, handler);
@@ -1062,9 +1061,9 @@
public void run() {
// send interaction hint to improve redraw performance
mPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0);
- if (isRotationChoicePossible(mCurrentAppOrientation)) {
- final boolean isValid = isValidRotationChoice(mCurrentAppOrientation,
- mRotation);
+ if (isRotationChoicePossible(mDefaultDisplayRotation.getCurrentAppOrientation())) {
+ final boolean isValid = mDefaultDisplayRotation
+ .isValidRotationChoice(mRotation);
sendProposedRotationChangeToStatusBarInternal(mRotation, isValid);
} else {
updateRotation(false);
@@ -1082,8 +1081,21 @@
}
mHandler.post(r);
}
+
+ @Override
+ public void enable(boolean clearCurrentRotation) {
+ super.enable(clearCurrentRotation);
+ mEnabled = true;
+ if(localLOGV) Slog.v(TAG, "Enabling listeners");
+ }
+
+ @Override
+ public void disable() {
+ super.disable();
+ mEnabled = false;
+ if(localLOGV) Slog.v(TAG, "Disabling listeners");
+ }
}
- MyOrientationListener mOrientationListener;
final IPersistentVrStateCallbacks mPersistentVrModeListener =
new IPersistentVrStateCallbacks.Stub() {
@@ -1178,10 +1190,11 @@
*/
boolean needSensorRunningLp() {
if (mSupportAutoRotation) {
- if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
- || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
- || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
- || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
+ final int currentAppOrientation = mDefaultDisplayRotation.getCurrentAppOrientation();
+ if (currentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
+ || currentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
+ || currentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
+ || currentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
// If the application has explicitly requested to follow the
// orientation, then we need to turn the sensor on.
return true;
@@ -1213,6 +1226,13 @@
return mSupportAutoRotation;
}
+ @Override
+ public void updateOrientationListener() {
+ synchronized (mLock) {
+ updateOrientationListenerLp();
+ }
+ }
+
/*
* Various use cases for invoking this function
* screen turning off, should always disable listeners if already enabled
@@ -1224,15 +1244,16 @@
* screen turning on and current app has nosensor based orientation, do nothing
*/
void updateOrientationListenerLp() {
- if (!mOrientationListener.canDetectOrientation()) {
+ if (!mDefaultOrientationListener.canDetectOrientation()) {
// If sensor is turned off or nonexistent for some reason
return;
}
// Could have been invoked due to screen turning on or off or
// change of the currently visible window's orientation.
if (localLOGV) Slog.v(TAG, "mScreenOnEarly=" + mScreenOnEarly
- + ", mAwake=" + mAwake + ", mCurrentAppOrientation=" + mCurrentAppOrientation
- + ", mOrientationSensorEnabled=" + mOrientationSensorEnabled
+ + ", mAwake=" + mAwake + ", mCurrentAppOrientation="
+ + mDefaultDisplayRotation.getCurrentAppOrientation()
+ + ", mOrientationSensorEnabled=" + mDefaultOrientationListener.mEnabled
+ ", mKeyguardDrawComplete=" + mKeyguardDrawComplete
+ ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
@@ -1244,24 +1265,20 @@
if (needSensorRunningLp()) {
disable = false;
//enable listener if not already enabled
- if (!mOrientationSensorEnabled) {
+ if (!mDefaultOrientationListener.mEnabled) {
// Don't clear the current sensor orientation if the keyguard is going away in
// dismiss mode. This allows window manager to use the last sensor reading to
// determine the orientation vs. falling back to the last known orientation if
// the sensor reading was cleared which can cause it to relaunch the app that
// will show in the wrong orientation first before correcting leading to app
// launch delays.
- mOrientationListener.enable(true /* clearCurrentRotation */);
- if(localLOGV) Slog.v(TAG, "Enabling listeners");
- mOrientationSensorEnabled = true;
+ mDefaultOrientationListener.enable(true /* clearCurrentRotation */);
}
}
}
//check if sensors need to be disabled
- if (disable && mOrientationSensorEnabled) {
- mOrientationListener.disable();
- if(localLOGV) Slog.v(TAG, "Disabling listeners");
- mOrientationSensorEnabled = false;
+ if (disable && mDefaultOrientationListener.mEnabled) {
+ mDefaultOrientationListener.disable();
}
}
@@ -2046,9 +2063,14 @@
mHandler = new PolicyHandler();
mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
- mOrientationListener = new MyOrientationListener(mContext, mHandler);
+ final DisplayContentInfo displayContentInfo =
+ windowManagerFuncs.getDefaultDisplayContentInfo();
+ mDefaultDisplay = displayContentInfo.getDisplay();
+ mDefaultDisplayRotation = displayContentInfo.getDisplayRotation();
+ mDefaultOrientationListener = new MyOrientationListener(mContext, mHandler);
try {
- mOrientationListener.setCurrentRotation(windowManager.getDefaultDisplayRotation());
+ mDefaultOrientationListener.setCurrentRotation(
+ windowManager.getDefaultDisplayRotation());
} catch (RemoteException ex) { }
mSettingsObserver = new SettingsObserver(mHandler);
mSettingsObserver.observe();
@@ -2222,11 +2244,11 @@
}
@Override
public void onDown() {
- mOrientationListener.onTouchStart();
+ mDefaultOrientationListener.onTouchStart();
}
@Override
public void onUpOrCancel() {
- mOrientationListener.onTouchEnd();
+ mDefaultOrientationListener.onTouchEnd();
}
@Override
public void onMouseHoverAtTop() {
@@ -2334,50 +2356,33 @@
}
@Override
- public void setInitialDisplaySize(Display display, int width, int height, int density) {
+ public void setInitialDisplaySize(DisplayRotation displayRotation, int width, int height,
+ int density) {
// This method might be called before the policy has been fully initialized
// or for other displays we don't care about.
// TODO(multi-display): Define policy for secondary displays.
- if (mContext == null || display.getDisplayId() != DEFAULT_DISPLAY) {
+ if (mContext == null || !displayRotation.isDefaultDisplay()) {
return;
}
- mDisplay = display;
- final Resources res = mContext.getResources();
- int shortSize, longSize;
+ final int shortSize;
+ final int longSize;
if (width > height) {
shortSize = height;
longSize = width;
- mLandscapeRotation = Surface.ROTATION_0;
- mSeascapeRotation = Surface.ROTATION_180;
- if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
- mPortraitRotation = Surface.ROTATION_90;
- mUpsideDownRotation = Surface.ROTATION_270;
- } else {
- mPortraitRotation = Surface.ROTATION_270;
- mUpsideDownRotation = Surface.ROTATION_90;
- }
} else {
shortSize = width;
longSize = height;
- mPortraitRotation = Surface.ROTATION_0;
- mUpsideDownRotation = Surface.ROTATION_180;
- if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
- mLandscapeRotation = Surface.ROTATION_270;
- mSeascapeRotation = Surface.ROTATION_90;
- } else {
- mLandscapeRotation = Surface.ROTATION_90;
- mSeascapeRotation = Surface.ROTATION_270;
- }
}
// SystemUI (status bar) layout policy
- int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density;
- int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density;
+ final int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density;
+ final int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density;
// Allow the navigation bar to move on non-square small devices (phones).
mNavigationBarCanMove = width != height && shortSizeDp < 600;
+ final Resources res = mContext.getResources();
mHasNavigationBar = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);
// Allow a system property to override this. Used by the emulator.
@@ -2392,18 +2397,18 @@
// For demo purposes, allow the rotation of the HDMI display to be controlled.
// By default, HDMI locks rotation to landscape.
if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
- mDemoHdmiRotation = mPortraitRotation;
+ mDemoHdmiRotation = displayRotation.getPortraitRotation();
} else {
- mDemoHdmiRotation = mLandscapeRotation;
+ mDemoHdmiRotation = displayRotation.getLandscapeRotation();
}
mDemoHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", false);
// For demo purposes, allow the rotation of the remote display to be controlled.
// By default, remote display locks rotation to landscape.
if ("portrait".equals(SystemProperties.get("persist.demo.remoterotation"))) {
- mDemoRotation = mPortraitRotation;
+ mDemoRotation = displayRotation.getPortraitRotation();
} else {
- mDemoRotation = mLandscapeRotation;
+ mDemoRotation = displayRotation.getLandscapeRotation();
}
mDemoRotationLock = SystemProperties.getBoolean(
"persist.demo.rotationlock", false);
@@ -2873,53 +2878,62 @@
}
@Override
- public void onOverlayChangedLw() {
- onConfigurationChanged();
+ public void onOverlayChangedLw(DisplayContentInfo displayContentInfo) {
+ onConfigurationChanged(displayContentInfo);
}
@Override
- public void onConfigurationChanged() {
+ public void onConfigurationChanged(DisplayContentInfo displayContentInfo) {
+ final DisplayRotation displayRotation = displayContentInfo.getDisplayRotation();
// TODO(multi-display): Define policy for secondary displays.
- Context uiContext = getSystemUiContext();
- final Resources res = uiContext.getResources();
+ if (!displayRotation.isDefaultDisplay()) {
+ return;
+ }
- mStatusBarHeightForRotation[mPortraitRotation] =
- mStatusBarHeightForRotation[mUpsideDownRotation] = res.getDimensionPixelSize(
+ final Context uiContext = getSystemUiContext();
+ final Resources res = uiContext.getResources();
+ final int portraitRotation = displayRotation.getPortraitRotation();
+ final int upsideDownRotation = displayRotation.getUpsideDownRotation();
+ final int landscapeRotation = displayRotation.getLandscapeRotation();
+ final int seascapeRotation = displayRotation.getSeascapeRotation();
+
+ mStatusBarHeightForRotation[portraitRotation] =
+ mStatusBarHeightForRotation[upsideDownRotation] = res.getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_height_portrait);
- mStatusBarHeightForRotation[mLandscapeRotation] =
- mStatusBarHeightForRotation[mSeascapeRotation] = res.getDimensionPixelSize(
+ mStatusBarHeightForRotation[landscapeRotation] =
+ mStatusBarHeightForRotation[seascapeRotation] = res.getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_height_landscape);
// Height of the navigation bar when presented horizontally at bottom
- mNavigationBarHeightForRotationDefault[mPortraitRotation] =
- mNavigationBarHeightForRotationDefault[mUpsideDownRotation] =
+ mNavigationBarHeightForRotationDefault[portraitRotation] =
+ mNavigationBarHeightForRotationDefault[upsideDownRotation] =
res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height);
- mNavigationBarHeightForRotationDefault[mLandscapeRotation] =
- mNavigationBarHeightForRotationDefault[mSeascapeRotation] = res.getDimensionPixelSize(
+ mNavigationBarHeightForRotationDefault[landscapeRotation] =
+ mNavigationBarHeightForRotationDefault[seascapeRotation] = res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height_landscape);
// Width of the navigation bar when presented vertically along one side
- mNavigationBarWidthForRotationDefault[mPortraitRotation] =
- mNavigationBarWidthForRotationDefault[mUpsideDownRotation] =
- mNavigationBarWidthForRotationDefault[mLandscapeRotation] =
- mNavigationBarWidthForRotationDefault[mSeascapeRotation] =
+ mNavigationBarWidthForRotationDefault[portraitRotation] =
+ mNavigationBarWidthForRotationDefault[upsideDownRotation] =
+ mNavigationBarWidthForRotationDefault[landscapeRotation] =
+ mNavigationBarWidthForRotationDefault[seascapeRotation] =
res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);
if (ALTERNATE_CAR_MODE_NAV_SIZE) {
// Height of the navigation bar when presented horizontally at bottom
- mNavigationBarHeightForRotationInCarMode[mPortraitRotation] =
- mNavigationBarHeightForRotationInCarMode[mUpsideDownRotation] =
+ mNavigationBarHeightForRotationInCarMode[portraitRotation] =
+ mNavigationBarHeightForRotationInCarMode[upsideDownRotation] =
res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height_car_mode);
- mNavigationBarHeightForRotationInCarMode[mLandscapeRotation] =
- mNavigationBarHeightForRotationInCarMode[mSeascapeRotation] = res.getDimensionPixelSize(
+ mNavigationBarHeightForRotationInCarMode[landscapeRotation] =
+ mNavigationBarHeightForRotationInCarMode[seascapeRotation] = res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height_landscape_car_mode);
// Width of the navigation bar when presented vertically along one side
- mNavigationBarWidthForRotationInCarMode[mPortraitRotation] =
- mNavigationBarWidthForRotationInCarMode[mUpsideDownRotation] =
- mNavigationBarWidthForRotationInCarMode[mLandscapeRotation] =
- mNavigationBarWidthForRotationInCarMode[mSeascapeRotation] =
+ mNavigationBarWidthForRotationInCarMode[portraitRotation] =
+ mNavigationBarWidthForRotationInCarMode[upsideDownRotation] =
+ mNavigationBarWidthForRotationInCarMode[landscapeRotation] =
+ mNavigationBarWidthForRotationInCarMode[seascapeRotation] =
res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_width_car_mode);
}
@@ -6500,7 +6514,8 @@
}
private boolean shouldDispatchInputWhenNonInteractive(KeyEvent event) {
- final boolean displayOff = (mDisplay == null || mDisplay.getState() == STATE_OFF);
+ final boolean displayOff = (mDefaultDisplay == null
+ || mDefaultDisplay.getState() == STATE_OFF);
if (displayOff && !mHasFeatureWatch) {
return false;
@@ -7202,7 +7217,8 @@
}
@Override
- public int rotationForOrientationLw(int orientation, int lastRotation, boolean defaultDisplay) {
+ public int rotationForOrientationLw(DisplayRotation displayRotation, int orientation,
+ int lastRotation) {
if (false) {
Slog.v(TAG, "rotationForOrientationLw(orient="
+ orientation + ", last=" + lastRotation
@@ -7217,13 +7233,13 @@
}
synchronized (mLock) {
- int sensorRotation = mOrientationListener.getProposedRotation(); // may be -1
+ int sensorRotation = displayRotation.getSensorRotation(); // may be -1
if (sensorRotation < 0) {
sensorRotation = lastRotation;
}
final int preferredRotation;
- if (!defaultDisplay) {
+ if (!displayRotation.isDefaultDisplay()) {
// For secondary displays we ignore things like displays sensors, docking mode and
// rotation lock, and always prefer a default rotation.
preferredRotation = Surface.ROTATION_0;
@@ -7266,7 +7282,7 @@
// any apps that explicitly set landscape, but does cause sensors be ignored,
// and ignored any orientation lock that the user has set (this conditional
// should remain above the ORIENTATION_LOCKED conditional below).
- preferredRotation = mPortraitRotation;
+ preferredRotation = displayRotation.getPortraitRotation();
} else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
// Application just wants to remain locked in the last rotation.
preferredRotation = lastRotation;
@@ -7314,89 +7330,15 @@
preferredRotation = -1;
}
- switch (orientation) {
- case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
- // Return portrait unless overridden.
- if (isAnyPortrait(preferredRotation)) {
- return preferredRotation;
- }
- return mPortraitRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
- // Return landscape unless overridden.
- if (isLandscapeOrSeascape(preferredRotation)) {
- return preferredRotation;
- }
- return mLandscapeRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
- // Return reverse portrait unless overridden.
- if (isAnyPortrait(preferredRotation)) {
- return preferredRotation;
- }
- return mUpsideDownRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
- // Return seascape unless overridden.
- if (isLandscapeOrSeascape(preferredRotation)) {
- return preferredRotation;
- }
- return mSeascapeRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
- case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
- // Return either landscape rotation.
- if (isLandscapeOrSeascape(preferredRotation)) {
- return preferredRotation;
- }
- if (isLandscapeOrSeascape(lastRotation)) {
- return lastRotation;
- }
- return mLandscapeRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
- case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
- // Return either portrait rotation.
- if (isAnyPortrait(preferredRotation)) {
- return preferredRotation;
- }
- if (isAnyPortrait(lastRotation)) {
- return lastRotation;
- }
- return mPortraitRotation;
-
- default:
- // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR,
- // just return the preferred orientation we already calculated.
- if (preferredRotation >= 0) {
- return preferredRotation;
- }
- return Surface.ROTATION_0;
- }
+ return displayRotation.rotationForOrientation(orientation, lastRotation,
+ preferredRotation);
}
}
@Override
- public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) {
- switch (orientation) {
- case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
- case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
- return isAnyPortrait(rotation);
-
- case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
- case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
- return isLandscapeOrSeascape(rotation);
-
- default:
- return true;
- }
- }
-
- @Override
- public void setRotationLw(int rotation) {
- mOrientationListener.setCurrentRotation(rotation);
+ public WindowManagerPolicy.RotationSource getRotationSource(int displayId) {
+ // TODO(multi-display): Distinguish sensor for different displays.
+ return displayId == DEFAULT_DISPLAY ? mDefaultOrientationListener : null;
}
public boolean isRotationChoicePossible(int orientation) {
@@ -7454,40 +7396,6 @@
return false;
}
- public boolean isValidRotationChoice(int orientation, final int preferredRotation) {
- // Determine if the given app orientation is compatible with the provided rotation choice
- switch (orientation) {
- case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
- // Works with any of the 4 rotations
- return preferredRotation >= 0;
-
- case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
- // It's possible for the user pref to be set at 180 because of FULL_USER. This would
- // make switching to USER_PORTRAIT appear at 180. Provide choice to back to portrait
- // but never to go to 180.
- return preferredRotation == mPortraitRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
- // Works landscape or seascape
- return isLandscapeOrSeascape(preferredRotation);
-
- case ActivityInfo.SCREEN_ORIENTATION_USER:
- case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
- // Works with any rotation except upside down
- return (preferredRotation >= 0) && (preferredRotation != mUpsideDownRotation);
- }
-
- return false;
- }
-
- private boolean isLandscapeOrSeascape(int rotation) {
- return rotation == mLandscapeRotation || rotation == mSeascapeRotation;
- }
-
- private boolean isAnyPortrait(int rotation) {
- return rotation == mPortraitRotation || rotation == mUpsideDownRotation;
- }
-
@Override
public int getUserRotationMode() {
return Settings.System.getIntForUser(mContext.getContentResolver(),
@@ -7987,16 +7895,6 @@
return true;
}
- @Override
- public void setCurrentOrientationLw(int newOrientation) {
- synchronized (mLock) {
- if (newOrientation != mCurrentAppOrientation) {
- mCurrentAppOrientation = newOrientation;
- updateOrientationListenerLp();
- }
- }
- }
-
private boolean isTheaterModeEnabled() {
return Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.THEATER_MODE_ON, 0) == 1;
@@ -8511,13 +8409,15 @@
}
@Override
- public boolean shouldRotateSeamlessly(int oldRotation, int newRotation) {
+ public boolean shouldRotateSeamlessly(DisplayRotation displayRotation, int oldRotation,
+ int newRotation) {
// For the upside down rotation we don't rotate seamlessly as the navigation
// bar moves position.
// Note most apps (using orientation:sensor or user as opposed to fullSensor)
// will not enter the reverse portrait orientation, so actually the
// orientation won't change at all.
- if (oldRotation == mUpsideDownRotation || newRotation == mUpsideDownRotation) {
+ if (oldRotation == displayRotation.getUpsideDownRotation()
+ || newRotation == displayRotation.getUpsideDownRotation()) {
return false;
}
// If the navigation bar can't change sides, then it will
@@ -8559,7 +8459,7 @@
proto.write(LAST_SYSTEM_UI_FLAGS, mLastSystemUiFlags);
proto.write(ROTATION_MODE, mUserRotationMode);
proto.write(ROTATION, mUserRotation);
- proto.write(ORIENTATION, mCurrentAppOrientation);
+ proto.write(ORIENTATION, mDefaultDisplayRotation.getCurrentAppOrientation());
proto.write(SCREEN_ON_FULLY, mScreenOnFully);
proto.write(KEYGUARD_DRAW_COMPLETE, mKeyguardDrawComplete);
proto.write(WINDOW_MANAGER_DRAW_COMPLETE, mWindowManagerDrawComplete);
@@ -8584,8 +8484,8 @@
proto.write(FORCE_STATUS_BAR_FROM_KEYGUARD, mForceStatusBarFromKeyguard);
mStatusBarController.writeToProto(proto, STATUS_BAR);
mNavigationBarController.writeToProto(proto, NAVIGATION_BAR);
- if (mOrientationListener != null) {
- mOrientationListener.writeToProto(proto, ORIENTATION_LISTENER);
+ if (mDefaultOrientationListener != null) {
+ mDefaultOrientationListener.writeToProto(proto, ORIENTATION_LISTENER);
}
if (mKeyguardDelegate != null) {
mKeyguardDelegate.writeToProto(proto, KEYGUARD_DELEGATE);
@@ -8623,7 +8523,8 @@
pw.print(prefix);
pw.print("mSupportAutoRotation="); pw.print(mSupportAutoRotation);
- pw.print(" mOrientationSensorEnabled="); pw.println(mOrientationSensorEnabled);
+ pw.print(" mOrientationSensorEnabled=");
+ pw.println(mDefaultOrientationListener.mEnabled);
pw.print(prefix); pw.print("mUiMode="); pw.print(Configuration.uiModeToString(mUiMode));
pw.print(" mDockMode="); pw.println(Intent.dockStateToString(mDockMode));
pw.print(prefix); pw.print("mEnableCarDockHomeCapture=");
@@ -8637,8 +8538,6 @@
pw.print(" mUserRotation="); pw.print(Surface.rotationToString(mUserRotation));
pw.print(" mAllowAllRotations=");
pw.println(allowAllRotationsToString(mAllowAllRotations));
- pw.print(prefix); pw.print("mCurrentAppOrientation=");
- pw.println(ActivityInfo.screenOrientationToString(mCurrentAppOrientation));
pw.print(prefix); pw.print("mCarDockEnablesAccelerometer=");
pw.print(mCarDockEnablesAccelerometer);
pw.print(" mDeskDockEnablesAccelerometer=");
@@ -8752,14 +8651,6 @@
pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn);
pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout);
pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive);
- pw.print(prefix); pw.print("mLandscapeRotation=");
- pw.print(Surface.rotationToString(mLandscapeRotation));
- pw.print(" mSeascapeRotation=");
- pw.println(Surface.rotationToString(mSeascapeRotation));
- pw.print(prefix); pw.print("mPortraitRotation=");
- pw.print(Surface.rotationToString(mPortraitRotation));
- pw.print(" mUpsideDownRotation=");
- pw.println(Surface.rotationToString(mUpsideDownRotation));
pw.print(prefix); pw.print("mDemoHdmiRotation=");
pw.print(Surface.rotationToString(mDemoHdmiRotation));
pw.print(" mDemoHdmiRotationLock="); pw.println(mDemoHdmiRotationLock);
@@ -8782,8 +8673,8 @@
if (mWakeGestureListener != null) {
mWakeGestureListener.dump(pw, prefix);
}
- if (mOrientationListener != null) {
- mOrientationListener.dump(pw, prefix);
+ if (mDefaultOrientationListener != null) {
+ mDefaultOrientationListener.dump(pw, prefix);
}
if (mBurnInProtectionHelper != null) {
mBurnInProtectionHelper.dump(prefix, pw);
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 0060328..70b2165 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -93,6 +93,7 @@
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
import com.android.server.wm.DisplayFrames;
+import com.android.server.wm.DisplayRotation;
import com.android.server.wm.WindowFrames;
import com.android.server.wm.utils.WmDisplayCutout;
@@ -177,7 +178,7 @@
/**
* Called when the resource overlays change.
*/
- default void onOverlayChangedLw() {}
+ default void onOverlayChangedLw(DisplayContentInfo displayContentInfo) {}
/**
* Interface to the Window Manager state associated with a particular
@@ -638,6 +639,27 @@
* The keyguard showing state has changed
*/
void onKeyguardShowingAndNotOccludedChanged();
+
+ DisplayContentInfo getDefaultDisplayContentInfo();
+ }
+
+ /**
+ * Provides the rotation of a device.
+ *
+ * @see com.android.server.policy.WindowOrientationListener
+ */
+ public interface RotationSource {
+ int getProposedRotation();
+
+ void setCurrentRotation(int rotation);
+ }
+
+ /**
+ * Interface to get public information of a display content.
+ */
+ public interface DisplayContentInfo {
+ DisplayRotation getDisplayRotation();
+ Display getDisplay();
}
/** Window has been added to the screen. */
@@ -685,7 +707,8 @@
* Called by window manager once it has the initial, default native
* display dimensions.
*/
- public void setInitialDisplaySize(Display display, int width, int height, int density);
+ public void setInitialDisplaySize(DisplayRotation displayRotation, int width, int height,
+ int density);
/**
* Check permissions when adding a window.
@@ -1421,31 +1444,15 @@
* rotation lock and other factors are ignored.
* @return The surface rotation to use.
*/
- public int rotationForOrientationLw(@ActivityInfo.ScreenOrientation int orientation,
- int lastRotation, boolean defaultDisplay);
+ public int rotationForOrientationLw(DisplayRotation displayRotation,
+ @ActivityInfo.ScreenOrientation int orientation, int lastRotation);
+
+ public void updateOrientationListener();
/**
- * Given an orientation constant and a rotation, returns true if the rotation
- * has compatible metrics to the requested orientation. For example, if
- * the application requested landscape and got seascape, then the rotation
- * has compatible metrics; if the application requested portrait and got landscape,
- * then the rotation has incompatible metrics; if the application did not specify
- * a preference, then anything goes.
- *
- * @param orientation An orientation constant, such as
- * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
- * @param rotation The rotation to check.
- * @return True if the rotation is compatible with the requested orientation.
+ * Get rotation source for the given display id.
*/
- public boolean rotationHasCompatibleMetricsLw(@ActivityInfo.ScreenOrientation int orientation,
- int rotation);
-
- /**
- * Called by the window manager when the rotation changes.
- *
- * @param rotation The new rotation.
- */
- public void setRotationLw(int rotation);
+ public RotationSource getRotationSource(int displayId);
/**
* Called when the system is mostly done booting to set whether
@@ -1487,8 +1494,6 @@
*/
public void enableScreenAfterBoot();
- public void setCurrentOrientationLw(@ActivityInfo.ScreenOrientation int newOrientation);
-
/**
* Call from application to perform haptic feedback on its window.
*/
@@ -1702,9 +1707,10 @@
/**
* Called when the configuration has changed, and it's safe to load new values from resources.
*/
- public void onConfigurationChanged();
+ public void onConfigurationChanged(DisplayContentInfo displayContentInfo);
- public boolean shouldRotateSeamlessly(int oldRotation, int newRotation);
+ public boolean shouldRotateSeamlessly(DisplayRotation displayRotation,
+ int oldRotation, int newRotation);
/**
* Called when System UI has been started.
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index cea5f4c6..605705e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -173,7 +173,8 @@
* IMPORTANT: No method from this class should ever be used without holding
* WindowManagerService.mWindowMap.
*/
-class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer> {
+class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer>
+ implements WindowManagerPolicy.DisplayContentInfo {
private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayContent" : TAG_WM;
/** Unique identifier of this stack. */
@@ -234,6 +235,7 @@
private final DisplayInfo mDisplayInfo = new DisplayInfo();
private final Display mDisplay;
private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
+ final DisplayRotation mDisplayRotation;
DisplayFrames mDisplayFrames;
/**
@@ -762,6 +764,7 @@
mDisplayFrames = new DisplayFrames(mDisplayId, mDisplayInfo,
calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
initializeDisplayBaseInfo();
+ mDisplayRotation = new DisplayRotation(this, mService.mPolicy, mService.mContext);
mDividerControllerLocked = new DockedStackDividerController(service, this);
mPinnedStackControllerLocked = new PinnedStackController(service, this);
@@ -905,7 +908,8 @@
appToken.onRemovedFromDisplay();
}
- Display getDisplay() {
+ @Override
+ public Display getDisplay() {
return mDisplay;
}
@@ -917,6 +921,11 @@
return mDisplayMetrics;
}
+ @Override
+ public DisplayRotation getDisplayRotation() {
+ return mDisplayRotation;
+ }
+
int getRotation() {
return mRotation;
}
@@ -924,6 +933,7 @@
@VisibleForTesting
void setRotation(int newRotation) {
mRotation = newRotation;
+ mDisplayRotation.setRotation(newRotation);
}
int getLastOrientation() {
@@ -977,6 +987,28 @@
}
/**
+ * If this is true we have updated our desired orientation, but not yet changed the real
+ * orientation our applied our screen rotation animation. For example, because a previous
+ * screen rotation was in progress.
+ *
+ * @return {@code true} if the there is an ongoing rotation change.
+ */
+ boolean rotationNeedsUpdate() {
+ final int lastOrientation = getLastOrientation();
+ final int oldRotation = getRotation();
+ final boolean oldAltOrientation = getAltOrientation();
+
+ final int rotation = mService.mPolicy.rotationForOrientationLw(
+ mDisplayRotation, lastOrientation, oldRotation);
+ final boolean altOrientation = !mDisplayRotation.rotationHasCompatibleMetrics(
+ lastOrientation, rotation);
+ if (oldRotation == rotation && oldAltOrientation == altOrientation) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
* Update rotation of the display.
*
* @return {@code true} if the rotation has been changed. In this case YOU MUST CALL
@@ -1034,13 +1066,13 @@
final int oldRotation = mRotation;
final int lastOrientation = mLastOrientation;
final boolean oldAltOrientation = mAltOrientation;
- final int rotation = mService.mPolicy.rotationForOrientationLw(lastOrientation, oldRotation,
- isDefaultDisplay);
+ final int rotation = mService.mPolicy.rotationForOrientationLw(mDisplayRotation,
+ lastOrientation, oldRotation);
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Computed rotation=" + rotation + " for display id="
+ mDisplayId + " based on lastOrientation=" + lastOrientation
+ " and oldRotation=" + oldRotation);
- boolean mayRotateSeamlessly = mService.mPolicy.shouldRotateSeamlessly(oldRotation,
- rotation);
+ boolean mayRotateSeamlessly = mService.mPolicy.shouldRotateSeamlessly(mDisplayRotation,
+ oldRotation, rotation);
if (mayRotateSeamlessly) {
final WindowState seamlessRotated = getWindow((w) -> w.mSeamlesslyRotated);
@@ -1071,7 +1103,7 @@
// an orientation that has different metrics than it expected.
// eg. Portrait instead of Landscape.
- final boolean altOrientation = !mService.mPolicy.rotationHasCompatibleMetricsLw(
+ final boolean altOrientation = !mDisplayRotation.rotationHasCompatibleMetrics(
lastOrientation, rotation);
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId
@@ -1093,11 +1125,8 @@
mService.mWaitingForConfig = true;
}
- mRotation = rotation;
+ setRotation(rotation);
mAltOrientation = altOrientation;
- if (isDefaultDisplay) {
- mService.mPolicy.setRotationLw(rotation);
- }
mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
mService.mH.sendNewMessageDelayed(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT,
@@ -1191,9 +1220,7 @@
}
void configureDisplayPolicy() {
- mService.mPolicy.setInitialDisplaySize(getDisplay(),
- mBaseDisplayWidth, mBaseDisplayHeight, mBaseDisplayDensity);
-
+ mDisplayRotation.configure();
mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
}
@@ -2367,6 +2394,8 @@
pw.println();
mDisplayFrames.dump(prefix, pw);
pw.println();
+ mDisplayRotation.dump(prefix, pw);
+ pw.println();
mInputMonitor.dump(pw, " ");
}
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
new file mode 100644
index 0000000..2074ecf
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Resources;
+import android.view.Surface;
+
+import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.policy.WindowManagerPolicy.RotationSource;
+
+import java.io.PrintWriter;
+
+/**
+ * Defines the mapping between orientation and rotation of a display.
+ */
+public class DisplayRotation {
+ private final DisplayContent mDisplayContent;
+ private final WindowManagerPolicy mPolicy;
+ private final Context mContext;
+ private RotationSource mRotationSource;
+
+ int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+ int mLandscapeRotation; // default landscape
+ int mSeascapeRotation; // "other" landscape, 180 degrees from mLandscapeRotation
+ int mPortraitRotation; // default portrait
+ int mUpsideDownRotation; // "other" portrait
+
+ DisplayRotation(DisplayContent displayContent, WindowManagerPolicy policy, Context context) {
+ mDisplayContent = displayContent;
+ mPolicy = policy;
+ mContext = context;
+ }
+
+ void configure() {
+ mRotationSource = mPolicy.getRotationSource(mDisplayContent.getDisplayId());
+
+ final int width = mDisplayContent.mBaseDisplayWidth;
+ final int height = mDisplayContent.mBaseDisplayHeight;
+ final Resources res = mContext.getResources();
+ if (width > height) {
+ mLandscapeRotation = Surface.ROTATION_0;
+ mSeascapeRotation = Surface.ROTATION_180;
+ if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
+ mPortraitRotation = Surface.ROTATION_90;
+ mUpsideDownRotation = Surface.ROTATION_270;
+ } else {
+ mPortraitRotation = Surface.ROTATION_270;
+ mUpsideDownRotation = Surface.ROTATION_90;
+ }
+ } else {
+ mPortraitRotation = Surface.ROTATION_0;
+ mUpsideDownRotation = Surface.ROTATION_180;
+ if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
+ mLandscapeRotation = Surface.ROTATION_270;
+ mSeascapeRotation = Surface.ROTATION_90;
+ } else {
+ mLandscapeRotation = Surface.ROTATION_90;
+ mSeascapeRotation = Surface.ROTATION_270;
+ }
+ }
+
+ mPolicy.setInitialDisplaySize(this, width, height, mDisplayContent.mBaseDisplayDensity);
+ }
+
+ public int getLandscapeRotation() {
+ return mLandscapeRotation;
+ }
+
+ public int getSeascapeRotation() {
+ return mSeascapeRotation;
+ }
+
+ public int getPortraitRotation() {
+ return mPortraitRotation;
+ }
+
+ public int getUpsideDownRotation() {
+ return mUpsideDownRotation;
+ }
+
+ public int getCurrentAppOrientation() {
+ return mCurrentAppOrientation;
+ }
+
+ public int getSensorRotation() {
+ return mRotationSource != null ? mRotationSource.getProposedRotation() : -1;
+ }
+
+ public boolean isDefaultDisplay() {
+ return mDisplayContent.isDefaultDisplay;
+ }
+
+ void setRotation(int rotation) {
+ if (mRotationSource != null) {
+ mRotationSource.setCurrentRotation(rotation);
+ }
+ }
+
+ void setCurrentOrientation(int newOrientation) {
+ if (newOrientation != mCurrentAppOrientation) {
+ mCurrentAppOrientation = newOrientation;
+ // TODO(multi-display): Separate orientation listeners.
+ if (mDisplayContent.isDefaultDisplay) {
+ mPolicy.updateOrientationListener();
+ }
+ }
+ }
+
+ public int rotationForOrientation(int orientation, int lastRotation, int preferredRotation) {
+ switch (orientation) {
+ case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
+ // Return portrait unless overridden.
+ if (isAnyPortrait(preferredRotation)) {
+ return preferredRotation;
+ }
+ return mPortraitRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
+ // Return landscape unless overridden.
+ if (isLandscapeOrSeascape(preferredRotation)) {
+ return preferredRotation;
+ }
+ return mLandscapeRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
+ // Return reverse portrait unless overridden.
+ if (isAnyPortrait(preferredRotation)) {
+ return preferredRotation;
+ }
+ return mUpsideDownRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
+ // Return seascape unless overridden.
+ if (isLandscapeOrSeascape(preferredRotation)) {
+ return preferredRotation;
+ }
+ return mSeascapeRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
+ // Return either landscape rotation.
+ if (isLandscapeOrSeascape(preferredRotation)) {
+ return preferredRotation;
+ }
+ if (isLandscapeOrSeascape(lastRotation)) {
+ return lastRotation;
+ }
+ return mLandscapeRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
+ case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
+ // Return either portrait rotation.
+ if (isAnyPortrait(preferredRotation)) {
+ return preferredRotation;
+ }
+ if (isAnyPortrait(lastRotation)) {
+ return lastRotation;
+ }
+ return mPortraitRotation;
+
+ default:
+ // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR,
+ // just return the preferred orientation we already calculated.
+ if (preferredRotation >= 0) {
+ return preferredRotation;
+ }
+ return Surface.ROTATION_0;
+ }
+ }
+
+ /**
+ * Given an orientation constant and a rotation, returns true if the rotation
+ * has compatible metrics to the requested orientation. For example, if
+ * the application requested landscape and got seascape, then the rotation
+ * has compatible metrics; if the application requested portrait and got landscape,
+ * then the rotation has incompatible metrics; if the application did not specify
+ * a preference, then anything goes.
+ *
+ * @param orientation An orientation constant, such as
+ * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
+ * @param rotation The rotation to check.
+ * @return True if the rotation is compatible with the requested orientation.
+ */
+ boolean rotationHasCompatibleMetrics(int orientation, int rotation) {
+ switch (orientation) {
+ case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
+ return isAnyPortrait(rotation);
+
+ case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
+ return isLandscapeOrSeascape(rotation);
+
+ default:
+ return true;
+ }
+ }
+
+ public boolean isValidRotationChoice(final int preferredRotation) {
+ // Determine if the given app orientation is compatible with the provided rotation choice.
+ switch (mCurrentAppOrientation) {
+ case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
+ // Works with any of the 4 rotations.
+ return preferredRotation >= 0;
+
+ case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
+ // It's possible for the user pref to be set at 180 because of FULL_USER. This would
+ // make switching to USER_PORTRAIT appear at 180. Provide choice to back to portrait
+ // but never to go to 180.
+ return preferredRotation == mPortraitRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
+ // Works landscape or seascape.
+ return isLandscapeOrSeascape(preferredRotation);
+
+ case ActivityInfo.SCREEN_ORIENTATION_USER:
+ case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
+ // Works with any rotation except upside down.
+ return (preferredRotation >= 0) && (preferredRotation != mUpsideDownRotation);
+ }
+
+ return false;
+ }
+
+ private boolean isLandscapeOrSeascape(int rotation) {
+ return rotation == mLandscapeRotation || rotation == mSeascapeRotation;
+ }
+
+ private boolean isAnyPortrait(int rotation) {
+ return rotation == mPortraitRotation || rotation == mUpsideDownRotation;
+ }
+
+ void dump(String prefix, PrintWriter pw) {
+ pw.println(prefix + "DisplayRotation");
+ pw.println(prefix + " mCurrentAppOrientation="
+ + ActivityInfo.screenOrientationToString(mCurrentAppOrientation));
+ pw.print(prefix + " mLandscapeRotation=" + Surface.rotationToString(mLandscapeRotation));
+ pw.println(" mSeascapeRotation=" + Surface.rotationToString(mSeascapeRotation));
+ pw.print(prefix + " mPortraitRotation=" + Surface.rotationToString(mPortraitRotation));
+ pw.println(" mUpsideDownRotation=" + Surface.rotationToString(mUpsideDownRotation));
+ }
+}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 3df4eb7..ca4fa64 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -134,6 +134,9 @@
// transaction from the global transaction.
private final SurfaceControl.Transaction mDisplayTransaction = new SurfaceControl.Transaction();
+ private final Consumer<DisplayContent> mDisplayContentConfigChangesConsumer =
+ mService.mPolicy::onConfigurationChanged;
+
private final Consumer<WindowState> mCloseSystemDialogsConsumer = w -> {
if (w.mHasSurface) {
try {
@@ -379,7 +382,7 @@
prepareFreezingTaskBounds();
super.onConfigurationChanged(newParentConfig);
- mService.mPolicy.onConfigurationChanged();
+ forAllDisplays(mDisplayContentConfigChangesConsumer);
}
/**
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 9b792e3..a2b3783 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2480,10 +2480,7 @@
dc.setLastOrientation(req);
//send a message to Policy indicating orientation change to take
//action like disabling/enabling sensors etc.,
- // TODO(multi-display): Implement policy for secondary displays.
- if (dc.isDefaultDisplay) {
- mPolicy.setCurrentOrientationLw(req);
- }
+ dc.mDisplayRotation.setCurrentOrientation(req);
return dc.updateRotationUnchecked(forceUpdate);
}
return false;
@@ -2492,27 +2489,6 @@
}
}
- // If this is true we have updated our desired orientation, but not yet
- // changed the real orientation our applied our screen rotation animation.
- // For example, because a previous screen rotation was in progress.
- boolean rotationNeedsUpdateLocked() {
- // TODO(multi-display): Check for updates on all displays. Need to have per-display policy
- // to implement WindowManagerPolicy#rotationForOrientationLw() correctly.
- final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
- final int lastOrientation = defaultDisplayContent.getLastOrientation();
- final int oldRotation = defaultDisplayContent.getRotation();
- final boolean oldAltOrientation = defaultDisplayContent.getAltOrientation();
-
- final int rotation = mPolicy.rotationForOrientationLw(lastOrientation, oldRotation,
- true /* defaultDisplay */);
- boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
- lastOrientation, rotation);
- if (oldRotation == rotation && oldAltOrientation == altOrientation) {
- return false;
- }
- return true;
- }
-
@Override
public int[] setNewDisplayOverrideConfiguration(Configuration overrideConfig, int displayId) {
if (!checkCallingPermission(MANAGE_APP_TOKENS, "setNewDisplayOverrideConfiguration()")) {
@@ -3871,6 +3847,13 @@
}
@Override
+ public WindowManagerPolicy.DisplayContentInfo getDefaultDisplayContentInfo() {
+ synchronized (mWindowMap) {
+ return getDefaultDisplayContentLocked();
+ }
+ }
+
+ @Override
public int getDefaultDisplayRotation() {
synchronized (mWindowMap) {
return getDefaultDisplayContentLocked().getRotation();
@@ -6761,8 +6744,10 @@
public void onOverlayChanged() {
synchronized (mWindowMap) {
- mPolicy.onOverlayChangedLw();
- getDefaultDisplayContentLocked().updateDisplayInfo();
+ mRoot.forAllDisplays(displayContent -> {
+ mPolicy.onOverlayChangedLw(displayContent);
+ displayContent.updateDisplayInfo();
+ });
requestTraversal();
}
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index aced8e4..08decdf 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -569,7 +569,7 @@
// animation after the old one finally finishes. It's better to defer the
// app transition.
if (screenRotationAnimation != null && screenRotationAnimation.isAnimating() &&
- mService.rotationNeedsUpdateLocked()) {
+ mService.getDefaultDisplayContentLocked().rotationNeedsUpdate()) {
if (DEBUG_APP_TRANSITIONS) {
Slog.v(TAG, "Delaying app transition for screen rotation animation to finish");
}