Notify client to clear intermediate rotated adjustments am: 8fea9c8e89
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13660605 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I6842db2e211bce2997293b66b2888aa49f1d7f75
This commit is contained in:
@@ -1513,6 +1513,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
||||
}
|
||||
final int rotation = rotationForActivityInDifferentOrientation(r);
|
||||
if (rotation == ROTATION_UNDEFINED) {
|
||||
// The display rotation won't be changed by current top activity. The client side
|
||||
// adjustments of previous rotated activity should be cleared earlier. Otherwise if
|
||||
// the current top is in the same process, it may get the rotated state. The transform
|
||||
// will be cleared later with transition callback to ensure smooth animation.
|
||||
if (hasTopFixedRotationLaunchingApp()) {
|
||||
mFixedRotationLaunchingApp.notifyFixedRotationTransform(false /* enabled */);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (!r.getParent().matchParentBounds()) {
|
||||
|
||||
@@ -622,11 +622,6 @@ class WindowToken extends WindowContainer<WindowState> {
|
||||
state.mIsTransforming = false;
|
||||
if (applyDisplayRotation != null) {
|
||||
applyDisplayRotation.run();
|
||||
} else {
|
||||
// The display will not rotate to the rotation of this container, let's cancel them.
|
||||
for (int i = state.mAssociatedTokens.size() - 1; i >= 0; i--) {
|
||||
state.mAssociatedTokens.get(i).cancelFixedRotationTransform();
|
||||
}
|
||||
}
|
||||
// The state is cleared at the end, because it is used to indicate that other windows can
|
||||
// use seamless rotation when applying rotation to display.
|
||||
@@ -634,11 +629,15 @@ class WindowToken extends WindowContainer<WindowState> {
|
||||
final WindowToken token = state.mAssociatedTokens.get(i);
|
||||
token.mFixedRotationTransformState = null;
|
||||
token.notifyFixedRotationTransform(false /* enabled */);
|
||||
if (applyDisplayRotation == null) {
|
||||
// Notify cancellation because the display does not change rotation.
|
||||
token.cancelFixedRotationTransform();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Notifies application side to enable or disable the rotation adjustment of display info. */
|
||||
private void notifyFixedRotationTransform(boolean enabled) {
|
||||
void notifyFixedRotationTransform(boolean enabled) {
|
||||
FixedRotationAdjustments adjustments = null;
|
||||
// A token may contain windows of the same processes or different processes. The list is
|
||||
// used to avoid sending the same adjustments to a process multiple times.
|
||||
@@ -682,7 +681,6 @@ class WindowToken extends WindowContainer<WindowState> {
|
||||
// The window may be detached or detaching.
|
||||
return;
|
||||
}
|
||||
notifyFixedRotationTransform(false /* enabled */);
|
||||
final int originalRotation = getWindowConfiguration().getRotation();
|
||||
onConfigurationChanged(parent.getConfiguration());
|
||||
onCancelFixedRotationTransform(originalRotation);
|
||||
|
||||
@@ -88,6 +88,7 @@ import static org.mockito.Mockito.doCallRealMethod;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.app.WindowConfiguration;
|
||||
import android.app.servertransaction.FixedRotationAdjustmentsItem;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
@@ -1345,6 +1346,36 @@ public class DisplayContentTests extends WindowTestsBase {
|
||||
assertFalse(recentsActivity.hasFixedRotationTransform());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearIntermediateFixedRotationAdjustments() throws RemoteException {
|
||||
final ActivityRecord activity = new ActivityTestsBase.StackBuilder(mWm.mRoot)
|
||||
.setDisplay(mDisplayContent).build().getTopMostActivity();
|
||||
mDisplayContent.setFixedRotationLaunchingApp(activity,
|
||||
(mDisplayContent.getRotation() + 1) % 4);
|
||||
// Create a window so FixedRotationAdjustmentsItem can be sent.
|
||||
createWindow(null, TYPE_APPLICATION_STARTING, activity, "AppWin");
|
||||
final ActivityRecord activity2 = new ActivityTestsBase.StackBuilder(mWm.mRoot)
|
||||
.setDisplay(mDisplayContent).build().getTopMostActivity();
|
||||
activity2.setVisible(false);
|
||||
clearInvocations(mWm.mAtmService.getLifecycleManager());
|
||||
// The first activity has applied fixed rotation but the second activity becomes the top
|
||||
// before the transition is done and it has the same rotation as display, so the dispatched
|
||||
// rotation adjustment of first activity must be cleared.
|
||||
mDisplayContent.handleTopActivityLaunchingInDifferentOrientation(activity2,
|
||||
false /* checkOpening */);
|
||||
|
||||
final ArgumentCaptor<FixedRotationAdjustmentsItem> adjustmentsCaptor =
|
||||
ArgumentCaptor.forClass(FixedRotationAdjustmentsItem.class);
|
||||
verify(mWm.mAtmService.getLifecycleManager(), atLeastOnce()).scheduleTransaction(
|
||||
eq(activity.app.getThread()), adjustmentsCaptor.capture());
|
||||
// The transformation is kept for animation in real case.
|
||||
assertTrue(activity.hasFixedRotationTransform());
|
||||
final FixedRotationAdjustmentsItem clearAdjustments = FixedRotationAdjustmentsItem.obtain(
|
||||
activity.token, null /* fixedRotationAdjustments */);
|
||||
// The captor may match other items. The first one must be the item to clear adjustments.
|
||||
assertEquals(clearAdjustments, adjustmentsCaptor.getAllValues().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoteRotation() {
|
||||
DisplayContent dc = createNewDisplay();
|
||||
|
||||
Reference in New Issue
Block a user