Prevent any rotation while seamless rotation is pending.
am: b14d4abc16
Change-Id: Id6c19bec943592c5c39bdd75a563132650506151
This commit is contained in:
@@ -654,6 +654,12 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
|
WindowManagerInternal.OnHardKeyboardStatusChangeListener mHardKeyboardStatusChangeListener;
|
||||||
SettingsObserver mSettingsObserver;
|
SettingsObserver mSettingsObserver;
|
||||||
|
|
||||||
|
// A count of the windows which are 'seamlessly rotated', e.g. a surface
|
||||||
|
// at an old orientation is being transformed. We freeze orientation updates
|
||||||
|
// while any windows are seamlessly rotated, so we need to track when this
|
||||||
|
// hits zero so we can apply deferred orientation updates.
|
||||||
|
int mSeamlessRotationCount = 0;
|
||||||
|
|
||||||
private final class SettingsObserver extends ContentObserver {
|
private final class SettingsObserver extends ContentObserver {
|
||||||
private final Uri mDisplayInversionEnabledUri =
|
private final Uri mDisplayInversionEnabledUri =
|
||||||
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
|
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
|
||||||
@@ -6821,62 +6827,20 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement forced rotation changes.
|
|
||||||
// Set mAltOrientation to indicate that the application is receiving
|
|
||||||
// an orientation that has different metrics than it expected.
|
|
||||||
// eg. Portrait instead of Landscape.
|
|
||||||
|
|
||||||
int rotation = mPolicy.rotationForOrientationLw(mLastOrientation, mRotation);
|
|
||||||
boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
|
|
||||||
mLastOrientation, rotation);
|
|
||||||
|
|
||||||
if (DEBUG_ORIENTATION) {
|
|
||||||
Slog.v(TAG_WM, "Selected orientation "
|
|
||||||
+ mLastOrientation + ", got rotation " + rotation
|
|
||||||
+ " which has " + (altOrientation ? "incompatible" : "compatible")
|
|
||||||
+ " metrics");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mRotation == rotation && mAltOrientation == altOrientation) {
|
|
||||||
// No change.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DEBUG_ORIENTATION) {
|
|
||||||
Slog.v(TAG_WM,
|
|
||||||
"Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
|
|
||||||
+ " from " + mRotation + (mAltOrientation ? " (alt)" : "")
|
|
||||||
+ ", lastOrientation=" + mLastOrientation);
|
|
||||||
}
|
|
||||||
|
|
||||||
int oldRotation = mRotation;
|
|
||||||
|
|
||||||
mRotation = rotation;
|
|
||||||
mAltOrientation = altOrientation;
|
|
||||||
mPolicy.setRotationLw(mRotation);
|
|
||||||
|
|
||||||
mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
|
|
||||||
mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
|
|
||||||
mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, WINDOW_FREEZE_TIMEOUT_DURATION);
|
|
||||||
mWaitingForConfig = true;
|
|
||||||
final DisplayContent displayContent = getDefaultDisplayContentLocked();
|
final DisplayContent displayContent = getDefaultDisplayContentLocked();
|
||||||
displayContent.layoutNeeded = true;
|
|
||||||
final int[] anim = new int[2];
|
|
||||||
if (displayContent.isDimming()) {
|
|
||||||
anim[0] = anim[1] = 0;
|
|
||||||
} else {
|
|
||||||
mPolicy.selectRotationAnimationLw(anim);
|
|
||||||
}
|
|
||||||
boolean rotateSeamlessly = mPolicy.shouldRotateSeamlessly(oldRotation, mRotation);
|
|
||||||
final WindowList windows = displayContent.getWindowList();
|
final WindowList windows = displayContent.getWindowList();
|
||||||
// We can't rotate seamlessly while an existing seamless rotation is still
|
|
||||||
// waiting on windows to finish drawing.
|
final int oldRotation = mRotation;
|
||||||
|
boolean rotateSeamlessly = mPolicy.shouldRotateSeamlessly(oldRotation, mRotation);
|
||||||
|
|
||||||
if (rotateSeamlessly) {
|
if (rotateSeamlessly) {
|
||||||
for (int i = windows.size() - 1; i >= 0; i--) {
|
for (int i = windows.size() - 1; i >= 0; i--) {
|
||||||
WindowState w = windows.get(i);
|
WindowState w = windows.get(i);
|
||||||
|
// We can't rotate (seamlessly or not) while waiting for the last seamless rotation
|
||||||
|
// to complete (that is, waiting for windows to redraw). It's tempting to check
|
||||||
|
// w.mSeamlessRotationCount but that could be incorrect in the case of window-removal.
|
||||||
if (w.mSeamlesslyRotated) {
|
if (w.mSeamlesslyRotated) {
|
||||||
rotateSeamlessly = false;
|
return false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// In what can only be called an unfortunate workaround we require
|
// In what can only be called an unfortunate workaround we require
|
||||||
// seamlessly rotated child windows to have the TRANSFORM_TO_DISPLAY_INVERSE
|
// seamlessly rotated child windows to have the TRANSFORM_TO_DISPLAY_INVERSE
|
||||||
@@ -6895,6 +6859,50 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Implement forced rotation changes.
|
||||||
|
// Set mAltOrientation to indicate that the application is receiving
|
||||||
|
// an orientation that has different metrics than it expected.
|
||||||
|
// eg. Portrait instead of Landscape.
|
||||||
|
|
||||||
|
int rotation = mPolicy.rotationForOrientationLw(mLastOrientation, mRotation);
|
||||||
|
boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
|
||||||
|
mLastOrientation, rotation);
|
||||||
|
|
||||||
|
if (DEBUG_ORIENTATION) {
|
||||||
|
Slog.v(TAG_WM, "Selected orientation "
|
||||||
|
+ mLastOrientation + ", got rotation " + rotation
|
||||||
|
+ " which has " + (altOrientation ? "incompatible" : "compatible")
|
||||||
|
+ " metrics");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mRotation == rotation && mAltOrientation == altOrientation) {
|
||||||
|
// No change.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DEBUG_ORIENTATION) {
|
||||||
|
Slog.v(TAG_WM,
|
||||||
|
"Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
|
||||||
|
+ " from " + mRotation + (mAltOrientation ? " (alt)" : "")
|
||||||
|
+ ", lastOrientation=" + mLastOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
mRotation = rotation;
|
||||||
|
mAltOrientation = altOrientation;
|
||||||
|
mPolicy.setRotationLw(mRotation);
|
||||||
|
|
||||||
|
mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
|
||||||
|
mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
|
||||||
|
mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, WINDOW_FREEZE_TIMEOUT_DURATION);
|
||||||
|
mWaitingForConfig = true;
|
||||||
|
displayContent.layoutNeeded = true;
|
||||||
|
final int[] anim = new int[2];
|
||||||
|
if (displayContent.isDimming()) {
|
||||||
|
anim[0] = anim[1] = 0;
|
||||||
|
} else {
|
||||||
|
mPolicy.selectRotationAnimationLw(anim);
|
||||||
|
}
|
||||||
|
|
||||||
if (!rotateSeamlessly) {
|
if (!rotateSeamlessly) {
|
||||||
startFreezingDisplayLocked(inTransaction, anim[0], anim[1]);
|
startFreezingDisplayLocked(inTransaction, anim[0], anim[1]);
|
||||||
// startFreezingDisplayLocked can reset the ScreenRotationAnimation.
|
// startFreezingDisplayLocked can reset the ScreenRotationAnimation.
|
||||||
@@ -6906,6 +6914,10 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
// When we are rotating seamlessly, we allow the elements to transition
|
// When we are rotating seamlessly, we allow the elements to transition
|
||||||
// to their rotated state independently and without a freeze required.
|
// to their rotated state independently and without a freeze required.
|
||||||
screenRotationAnimation = null;
|
screenRotationAnimation = null;
|
||||||
|
|
||||||
|
// We have to reset this in case a window was removed before it
|
||||||
|
// finished seamless rotation.
|
||||||
|
mSeamlessRotationCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to update our screen size information to match the new rotation. If the rotation
|
// We need to update our screen size information to match the new rotation. If the rotation
|
||||||
@@ -8921,8 +8933,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
if (w.mSeamlesslyRotated) {
|
if (w.mSeamlesslyRotated) {
|
||||||
layoutNeeded = true;
|
layoutNeeded = true;
|
||||||
w.setDisplayLayoutNeeded();
|
w.setDisplayLayoutNeeded();
|
||||||
|
markForSeamlessRotation(w, false);
|
||||||
}
|
}
|
||||||
w.mSeamlesslyRotated = false;
|
|
||||||
}
|
}
|
||||||
if (layoutNeeded) {
|
if (layoutNeeded) {
|
||||||
mWindowPlacerLocked.performSurfacePlacement();
|
mWindowPlacerLocked.performSurfacePlacement();
|
||||||
@@ -11508,6 +11520,26 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
mPolicy.registerShortcutKey(shortcutCode, shortcutKeyReceiver);
|
mPolicy.registerShortcutKey(shortcutCode, shortcutKeyReceiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void markForSeamlessRotation(WindowState w, boolean seamlesslyRotated) {
|
||||||
|
if (seamlesslyRotated == w.mSeamlesslyRotated) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
w.mSeamlesslyRotated = seamlesslyRotated;
|
||||||
|
if (seamlesslyRotated) {
|
||||||
|
mSeamlessRotationCount++;
|
||||||
|
} else {
|
||||||
|
mSeamlessRotationCount--;
|
||||||
|
}
|
||||||
|
if (mSeamlessRotationCount == 0) {
|
||||||
|
if (DEBUG_ORIENTATION) {
|
||||||
|
Slog.i(TAG, "Performing post-rotate rotation after seamless rotation");
|
||||||
|
}
|
||||||
|
if (updateRotationUncheckedLocked(false)) {
|
||||||
|
mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final class LocalService extends WindowManagerInternal {
|
private final class LocalService extends WindowManagerInternal {
|
||||||
@Override
|
@Override
|
||||||
public void requestTraversalFromDisplayManager() {
|
public void requestTraversalFromDisplayManager() {
|
||||||
|
|||||||
@@ -1431,7 +1431,7 @@ class WindowStateAnimator {
|
|||||||
// If we are undergoing seamless rotation, the surface has already
|
// If we are undergoing seamless rotation, the surface has already
|
||||||
// been set up to persist at it's old location. We need to freeze
|
// been set up to persist at it's old location. We need to freeze
|
||||||
// updates until a resize occurs.
|
// updates until a resize occurs.
|
||||||
w.mSeamlesslyRotated = w.mSeamlesslyRotated && !mSurfaceResized;
|
mService.markForSeamlessRotation(w, w.mSeamlesslyRotated && !mSurfaceResized);
|
||||||
|
|
||||||
calculateSurfaceWindowCrop(mTmpClipRect, mTmpFinalClipRect);
|
calculateSurfaceWindowCrop(mTmpClipRect, mTmpFinalClipRect);
|
||||||
|
|
||||||
@@ -2156,7 +2156,7 @@ class WindowStateAnimator {
|
|||||||
cropRect.set(0, 0, w.mRequestedWidth, w.mRequestedWidth + w.mRequestedHeight);
|
cropRect.set(0, 0, w.mRequestedWidth, w.mRequestedWidth + w.mRequestedHeight);
|
||||||
mSurfaceController.setCropInTransaction(cropRect, false);
|
mSurfaceController.setCropInTransaction(cropRect, false);
|
||||||
} else {
|
} else {
|
||||||
w.mSeamlesslyRotated = true;
|
mService.markForSeamlessRotation(w, true);
|
||||||
transform.getValues(mService.mTmpFloats);
|
transform.getValues(mService.mTmpFloats);
|
||||||
|
|
||||||
float DsDx = mService.mTmpFloats[Matrix.MSCALE_X];
|
float DsDx = mService.mTmpFloats[Matrix.MSCALE_X];
|
||||||
|
|||||||
Reference in New Issue
Block a user