Merge "Avoid clearing size compat when app is shown from paused"
This commit is contained in:
@@ -6372,7 +6372,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
}
|
||||
|
||||
final IBinder freezeToken = mayFreezeScreenLocked() ? appToken : null;
|
||||
onDescendantOrientationChanged(freezeToken, this);
|
||||
if (onDescendantOrientationChanged(freezeToken, this)) {
|
||||
// The app is just becoming visible, and the parent Task has updated with the
|
||||
// orientation request. Update the size compat mode.
|
||||
updateSizeCompatMode();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6538,6 +6542,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
return;
|
||||
}
|
||||
|
||||
if (task == null || (!handlesOrientationChangeFromDescendant()
|
||||
&& task.getLastTaskBoundsComputeActivity() != this)) {
|
||||
// Don't compute when Task hasn't computed its bounds for this app, because the Task can
|
||||
// be letterboxed, and its bounds may not be accurate until then.
|
||||
return;
|
||||
}
|
||||
|
||||
Configuration overrideConfig = getRequestedOverrideConfiguration();
|
||||
final Configuration fullConfig = getConfiguration();
|
||||
|
||||
@@ -6562,20 +6573,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
mCompatDisplayInsets = new CompatDisplayInsets(mDisplayContent, this);
|
||||
}
|
||||
|
||||
void clearSizeCompatMode(boolean recomputeTask) {
|
||||
@VisibleForTesting
|
||||
void clearSizeCompatMode() {
|
||||
mSizeCompatScale = 1f;
|
||||
mSizeCompatBounds = null;
|
||||
mCompatDisplayInsets = null;
|
||||
|
||||
if (recomputeTask) {
|
||||
// Recompute from Task because letterbox can also happen on Task level.
|
||||
task.onRequestedOverrideConfigurationChanged(task.getRequestedOverrideConfiguration());
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void clearSizeCompatMode() {
|
||||
clearSizeCompatMode(true /* recomputeTask */);
|
||||
// Recompute from Task because letterbox can also happen on Task level.
|
||||
task.onRequestedOverrideConfigurationChanged(task.getRequestedOverrideConfiguration());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -571,6 +571,10 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
/** Current activity that is resumed, or null if there is none. */
|
||||
ActivityRecord mResumedActivity = null;
|
||||
|
||||
/** Last activity that is used to compute the Task bounds. */
|
||||
@Nullable
|
||||
private ActivityRecord mLastTaskBoundsComputeActivity;
|
||||
|
||||
private boolean mForceShowForAllUsers;
|
||||
|
||||
/** When set, will force the task to report as invisible. */
|
||||
@@ -1496,6 +1500,11 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
}
|
||||
|
||||
void cleanUpActivityReferences(ActivityRecord r) {
|
||||
// mLastTaskBoundsComputeActivity is set at leaf Task
|
||||
if (mLastTaskBoundsComputeActivity == r) {
|
||||
mLastTaskBoundsComputeActivity = null;
|
||||
}
|
||||
|
||||
final WindowContainer parent = getParent();
|
||||
if (parent != null && parent.asTask() != null) {
|
||||
parent.asTask().cleanUpActivityReferences(r);
|
||||
@@ -2833,6 +2842,8 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
|
||||
private void resolveLeafOnlyOverrideConfigs(Configuration newParentConfig,
|
||||
Rect previousBounds) {
|
||||
mLastTaskBoundsComputeActivity = getTopNonFinishingActivity(false /* includeOverlays */);
|
||||
|
||||
int windowingMode =
|
||||
getResolvedOverrideConfiguration().windowConfiguration.getWindowingMode();
|
||||
if (windowingMode == WINDOWING_MODE_UNDEFINED) {
|
||||
@@ -2963,6 +2974,11 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
return bounds;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
ActivityRecord getLastTaskBoundsComputeActivity() {
|
||||
return mLastTaskBoundsComputeActivity;
|
||||
}
|
||||
|
||||
/** Updates the task's bounds and override configuration to match what is expected for the
|
||||
* input stack. */
|
||||
void updateOverrideConfigurationForStack(Task inStack) {
|
||||
@@ -3307,18 +3323,6 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
// No one in higher hierarchy handles this request, let's adjust our bounds to fulfill
|
||||
// it if possible.
|
||||
if (getParent() != null) {
|
||||
final ActivityRecord activity = requestingContainer.asActivityRecord();
|
||||
if (activity != null) {
|
||||
// Clear the size compat cache to recompute the bounds for requested orientation;
|
||||
// otherwise when Task#computeFullscreenBounds(), it will not try to do Task level
|
||||
// letterboxing because app may prefer to keep its original size (size compat).
|
||||
//
|
||||
// Normally, ActivityRecord#clearSizeCompatMode() recomputes from its parent Task,
|
||||
// which is the leaf Task. However, because this orientation request is new to all
|
||||
// Tasks, pass false to clearSizeCompatMode, and trigger onConfigurationChanged from
|
||||
// here (root Task) to make sure all Tasks are up-to-date.
|
||||
activity.clearSizeCompatMode(false /* recomputeTask */);
|
||||
}
|
||||
onConfigurationChanged(getParent().getConfiguration());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.same;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.doCallRealMethod;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
@@ -702,7 +703,6 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// size compat cache.
|
||||
verify(mTask).onDescendantOrientationChanged(any(), same(newActivity));
|
||||
verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt());
|
||||
verify(newActivity).clearSizeCompatMode(false /* recomputeTask */);
|
||||
|
||||
final Rect displayBounds = display.getBounds();
|
||||
final Rect taskBounds = mTask.getBounds();
|
||||
@@ -744,7 +744,6 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
// size compat cache.
|
||||
verify(mTask).onDescendantOrientationChanged(any(), same(newActivity));
|
||||
verify(mTask).computeFullscreenBounds(any(), any(), any(), anyInt());
|
||||
verify(newActivity).clearSizeCompatMode(false /* recomputeTask */);
|
||||
|
||||
final Rect displayBounds = display.getBounds();
|
||||
final Rect taskBounds = mTask.getBounds();
|
||||
@@ -761,6 +760,40 @@ public class SizeCompatTests extends WindowTestsBase {
|
||||
assertEquals(taskBounds, newActivityBounds);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisplayIgnoreOrientationRequest_pausedAppNotLostSizeCompat() {
|
||||
// Set up a display in landscape and ignoring orientation request.
|
||||
setUpDisplaySizeWithApp(2800, 1400);
|
||||
final DisplayContent display = mActivity.mDisplayContent;
|
||||
display.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
|
||||
|
||||
// Portrait fixed app.
|
||||
prepareUnresizable(0, SCREEN_ORIENTATION_PORTRAIT);
|
||||
clearInvocations(mActivity);
|
||||
|
||||
assertTrue(mTask.isTaskLetterboxed());
|
||||
assertFalse(mActivity.inSizeCompatMode());
|
||||
assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity);
|
||||
|
||||
// Rotate display to portrait.
|
||||
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
|
||||
|
||||
// App should be in size compat.
|
||||
assertFalse(mTask.isTaskLetterboxed());
|
||||
assertScaled();
|
||||
assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity);
|
||||
|
||||
final Rect activityBounds = new Rect(mActivity.getBounds());
|
||||
mStack.resumeTopActivityUncheckedLocked(null /* prev */, null /* options */);
|
||||
|
||||
// App still in size compat, and the bounds don't change.
|
||||
verify(mActivity, never()).clearSizeCompatMode();
|
||||
assertFalse(mTask.isTaskLetterboxed());
|
||||
assertScaled();
|
||||
assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity);
|
||||
assertEquals(activityBounds, mActivity.getBounds());
|
||||
}
|
||||
|
||||
private static WindowState addWindowToActivity(ActivityRecord activity) {
|
||||
final WindowManager.LayoutParams params = new WindowManager.LayoutParams();
|
||||
params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
|
||||
|
||||
@@ -257,4 +257,24 @@ public class TaskTests extends WindowTestsBase {
|
||||
task.resolveOverrideConfiguration(parentConfig);
|
||||
assertThat(resolvedOverride.getWindowingMode()).isEqualTo(WINDOWING_MODE_UNDEFINED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCleanUpActivityReferences_clearLastTaskBoundsComputeActivity() {
|
||||
final Task rootTask = createTaskStackOnDisplay(mDisplayContent);
|
||||
final Task leafTask = createTaskInStack(rootTask, 0 /* userId */);
|
||||
final ActivityRecord activity2 = createActivityRecord(mDisplayContent, leafTask);
|
||||
final ActivityRecord activity1 = createActivityRecord(mDisplayContent, leafTask);
|
||||
activity1.finishing = false;
|
||||
leafTask.resolveOverrideConfiguration(rootTask.getConfiguration());
|
||||
|
||||
assertEquals(activity1, leafTask.getLastTaskBoundsComputeActivity());
|
||||
|
||||
leafTask.cleanUpActivityReferences(activity2);
|
||||
|
||||
assertNotNull(leafTask.getLastTaskBoundsComputeActivity());
|
||||
|
||||
leafTask.cleanUpActivityReferences(activity1);
|
||||
|
||||
assertNull(leafTask.getLastTaskBoundsComputeActivity());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user