Merge "Avoid NPE when removing fixed rotation transform" into udc-dev

This commit is contained in:
Riddle Hsu
2023-04-13 07:52:37 +00:00
committed by Android (Google) Code Review

View File

@@ -119,24 +119,20 @@ class WindowToken extends WindowContainer<WindowState> {
final DisplayInfo mDisplayInfo; final DisplayInfo mDisplayInfo;
final DisplayFrames mDisplayFrames; final DisplayFrames mDisplayFrames;
final Configuration mRotatedOverrideConfiguration; final Configuration mRotatedOverrideConfiguration;
final SeamlessRotator mRotator;
/** /**
* The tokens that share the same transform. Their end time of transform are the same. The * The tokens that share the same transform. Their end time of transform are the same. The
* list should at least contain the token who creates this state. * list should at least contain the token who creates this state.
*/ */
final ArrayList<WindowToken> mAssociatedTokens = new ArrayList<>(3); final ArrayList<WindowToken> mAssociatedTokens = new ArrayList<>(3);
final ArrayList<WindowContainer<?>> mRotatedContainers = new ArrayList<>(3);
boolean mIsTransforming = true; boolean mIsTransforming = true;
FixedRotationTransformState(DisplayInfo rotatedDisplayInfo, FixedRotationTransformState(DisplayInfo rotatedDisplayInfo,
DisplayFrames rotatedDisplayFrames, Configuration rotatedConfig, DisplayFrames rotatedDisplayFrames, Configuration rotatedConfig) {
int currentRotation) {
mDisplayInfo = rotatedDisplayInfo; mDisplayInfo = rotatedDisplayInfo;
mDisplayFrames = rotatedDisplayFrames; mDisplayFrames = rotatedDisplayFrames;
mRotatedOverrideConfiguration = rotatedConfig; mRotatedOverrideConfiguration = rotatedConfig;
// This will use unrotate as rotate, so the new and old rotation are inverted.
mRotator = new SeamlessRotator(rotatedDisplayInfo.rotation, currentRotation,
rotatedDisplayInfo, true /* applyFixedTransformationHint */);
} }
/** /**
@@ -144,16 +140,48 @@ class WindowToken extends WindowContainer<WindowState> {
* showing the window in a display with different rotation. * showing the window in a display with different rotation.
*/ */
void transform(WindowContainer<?> container) { void transform(WindowContainer<?> container) {
mRotator.unrotate(container.getPendingTransaction(), container); // The default implementation assumes shell transition is enabled, so the transform
if (!mRotatedContainers.contains(container)) { // is done by getOrCreateFixedRotationLeash().
mRotatedContainers.add(container);
}
} }
/** /**
* Resets the transformation of the window containers which have been rotated. This should * Resets the transformation of the window containers which have been rotated. This should
* be called when the window has the same rotation as display. * be called when the window has the same rotation as display.
*/ */
void resetTransform() {
for (int i = mAssociatedTokens.size() - 1; i >= 0; --i) {
mAssociatedTokens.get(i).removeFixedRotationLeash();
}
}
/** The state may not only be used by self. Make sure to leave the influence by others. */
void disassociate(WindowToken token) {
mAssociatedTokens.remove(token);
}
}
private static class FixedRotationTransformStateLegacy extends FixedRotationTransformState {
final SeamlessRotator mRotator;
final ArrayList<WindowContainer<?>> mRotatedContainers = new ArrayList<>(3);
FixedRotationTransformStateLegacy(DisplayInfo rotatedDisplayInfo,
DisplayFrames rotatedDisplayFrames, Configuration rotatedConfig,
int currentRotation) {
super(rotatedDisplayInfo, rotatedDisplayFrames, rotatedConfig);
// This will use unrotate as rotate, so the new and old rotation are inverted.
mRotator = new SeamlessRotator(rotatedDisplayInfo.rotation, currentRotation,
rotatedDisplayInfo, true /* applyFixedTransformationHint */);
}
@Override
void transform(WindowContainer<?> container) {
mRotator.unrotate(container.getPendingTransaction(), container);
if (!mRotatedContainers.contains(container)) {
mRotatedContainers.add(container);
}
}
@Override
void resetTransform() { void resetTransform() {
for (int i = mRotatedContainers.size() - 1; i >= 0; i--) { for (int i = mRotatedContainers.size() - 1; i >= 0; i--) {
final WindowContainer<?> c = mRotatedContainers.get(i); final WindowContainer<?> c = mRotatedContainers.get(i);
@@ -164,9 +192,9 @@ class WindowToken extends WindowContainer<WindowState> {
} }
} }
/** The state may not only be used by self. Make sure to leave the influence by others. */ @Override
void disassociate(WindowToken token) { void disassociate(WindowToken token) {
mAssociatedTokens.remove(token); super.disassociate(token);
mRotatedContainers.remove(token); mRotatedContainers.remove(token);
} }
} }
@@ -437,8 +465,11 @@ class WindowToken extends WindowContainer<WindowState> {
if (mFixedRotationTransformState != null) { if (mFixedRotationTransformState != null) {
mFixedRotationTransformState.disassociate(this); mFixedRotationTransformState.disassociate(this);
} }
mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames, config = new Configuration(config);
new Configuration(config), mDisplayContent.getRotation()); mFixedRotationTransformState = mTransitionController.isShellTransitionsEnabled()
? new FixedRotationTransformState(info, displayFrames, config)
: new FixedRotationTransformStateLegacy(info, displayFrames, config,
mDisplayContent.getRotation());
mFixedRotationTransformState.mAssociatedTokens.add(this); mFixedRotationTransformState.mAssociatedTokens.add(this);
mDisplayContent.getDisplayPolicy().simulateLayoutDisplay(displayFrames); mDisplayContent.getDisplayPolicy().simulateLayoutDisplay(displayFrames);
onFixedRotationStatePrepared(); onFixedRotationStatePrepared();
@@ -508,14 +539,7 @@ class WindowToken extends WindowContainer<WindowState> {
if (state == null) { if (state == null) {
return; return;
} }
if (!mTransitionController.isShellTransitionsEnabled()) {
state.resetTransform(); state.resetTransform();
} else {
// Remove all the leashes
for (int i = state.mAssociatedTokens.size() - 1; i >= 0; --i) {
state.mAssociatedTokens.get(i).removeFixedRotationLeash();
}
}
// Clear the flag so if the display will be updated to the same orientation, the transform // Clear the flag so if the display will be updated to the same orientation, the transform
// won't take effect. // won't take effect.
state.mIsTransforming = false; state.mIsTransforming = false;
@@ -589,7 +613,9 @@ class WindowToken extends WindowContainer<WindowState> {
void removeFixedRotationLeash() { void removeFixedRotationLeash() {
if (mFixedRotationTransformLeash == null) return; if (mFixedRotationTransformLeash == null) return;
final SurfaceControl.Transaction t = getSyncTransaction(); final SurfaceControl.Transaction t = getSyncTransaction();
t.reparent(getSurfaceControl(), getParentSurfaceControl()); if (mSurfaceControl != null) {
t.reparent(mSurfaceControl, getParentSurfaceControl());
}
t.remove(mFixedRotationTransformLeash); t.remove(mFixedRotationTransformLeash);
mFixedRotationTransformLeash = null; mFixedRotationTransformLeash = null;
} }