Merge "Fix extra configuration change when unlocking directly" into rvc-dev am: 54e3542b96 am: a35ab2884a
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12055451 Change-Id: I399b7e078a2e197d96ad8614d2120bc34637f5dc
This commit is contained in:
@@ -954,8 +954,6 @@ class ActivityStack extends Task {
|
|||||||
void awakeFromSleepingLocked() {
|
void awakeFromSleepingLocked() {
|
||||||
// Ensure activities are no longer sleeping.
|
// Ensure activities are no longer sleeping.
|
||||||
forAllActivities((Consumer<ActivityRecord>) (r) -> r.setSleeping(false));
|
forAllActivities((Consumer<ActivityRecord>) (r) -> r.setSleeping(false));
|
||||||
ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
|
|
||||||
false /* preserveWindows */);
|
|
||||||
if (mPausingActivity != null) {
|
if (mPausingActivity != null) {
|
||||||
Slog.d(TAG, "awakeFromSleepingLocked: previously pausing activity didn't pause");
|
Slog.d(TAG, "awakeFromSleepingLocked: previously pausing activity didn't pause");
|
||||||
mPausingActivity.activityPaused(true);
|
mPausingActivity.activityPaused(true);
|
||||||
|
|||||||
@@ -253,6 +253,7 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {
|
|||||||
req = mLastKeyguardForcedOrientation;
|
req = mLastKeyguardForcedOrientation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mLastOrientationSource = win;
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1189,6 +1189,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
|||||||
|
|
||||||
activity.onRemovedFromDisplay();
|
activity.onRemovedFromDisplay();
|
||||||
if (activity == mFixedRotationLaunchingApp) {
|
if (activity == mFixedRotationLaunchingApp) {
|
||||||
|
// Make sure the states of associated tokens are also cleared.
|
||||||
|
activity.finishFixedRotationTransform();
|
||||||
setFixedRotationLaunchingAppUnchecked(null);
|
setFixedRotationLaunchingAppUnchecked(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1487,6 +1489,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
|||||||
// window was transferred ({@link #mSkipAppTransitionAnimation}).
|
// window was transferred ({@link #mSkipAppTransitionAnimation}).
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if ((mAppTransition.getTransitFlags()
|
||||||
|
& WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) != 0) {
|
||||||
|
// The transition may be finished before keyguard hidden. In order to avoid the
|
||||||
|
// intermediate orientation change, it is more stable to freeze the display.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else if (r != topRunningActivity()) {
|
} else if (r != topRunningActivity()) {
|
||||||
// If the transition has not started yet, the activity must be the top.
|
// If the transition has not started yet, the activity must be the top.
|
||||||
return false;
|
return false;
|
||||||
@@ -2310,6 +2318,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
|||||||
void onAppTransitionDone() {
|
void onAppTransitionDone() {
|
||||||
super.onAppTransitionDone();
|
super.onAppTransitionDone();
|
||||||
mWmService.mWindowsChanged = true;
|
mWmService.mWindowsChanged = true;
|
||||||
|
// If the transition finished callback cannot match the token for some reason, make sure the
|
||||||
|
// rotated state is cleared if it is already invisible.
|
||||||
|
if (mFixedRotationLaunchingApp != null && !mFixedRotationLaunchingApp.mVisibleRequested
|
||||||
|
&& !mFixedRotationLaunchingApp.isVisible()
|
||||||
|
&& !mDisplayRotation.isRotatingSeamlessly()) {
|
||||||
|
clearFixedRotationLaunchingApp();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -3011,11 +3026,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
|
|||||||
|
|
||||||
final ScreenRotationAnimation rotationAnimation = getRotationAnimation();
|
final ScreenRotationAnimation rotationAnimation = getRotationAnimation();
|
||||||
if (rotationAnimation != null) {
|
if (rotationAnimation != null) {
|
||||||
pw.print(subPrefix);
|
|
||||||
pw.println(" mScreenRotationAnimation:");
|
pw.println(" mScreenRotationAnimation:");
|
||||||
rotationAnimation.printTo(" ", pw);
|
rotationAnimation.printTo(subPrefix, pw);
|
||||||
} else if (dumpAll) {
|
} else if (dumpAll) {
|
||||||
pw.print(subPrefix);
|
|
||||||
pw.println(" no ScreenRotationAnimation ");
|
pw.println(" no ScreenRotationAnimation ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2391,6 +2391,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
|
|||||||
// activity here.
|
// activity here.
|
||||||
resumeFocusedStacksTopActivities();
|
resumeFocusedStacksTopActivities();
|
||||||
}
|
}
|
||||||
|
// The visibility update must not be called before resuming the top, so the
|
||||||
|
// display orientation can be updated first if needed. Otherwise there may
|
||||||
|
// have redundant configuration changes due to apply outdated display
|
||||||
|
// orientation (from keyguard) to activity.
|
||||||
|
stack.ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
|
||||||
|
false /* preserveWindows */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1864,14 +1864,14 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
|
|||||||
@Override
|
@Override
|
||||||
void dump(PrintWriter pw, String prefix, boolean dumpAll) {
|
void dump(PrintWriter pw, String prefix, boolean dumpAll) {
|
||||||
pw.println(prefix + "TaskDisplayArea " + getName());
|
pw.println(prefix + "TaskDisplayArea " + getName());
|
||||||
super.dump(pw, prefix, dumpAll);
|
final String doublePrefix = prefix + " ";
|
||||||
|
super.dump(pw, doublePrefix, dumpAll);
|
||||||
if (mPreferredTopFocusableStack != null) {
|
if (mPreferredTopFocusableStack != null) {
|
||||||
pw.println(prefix + " mPreferredTopFocusableStack=" + mPreferredTopFocusableStack);
|
pw.println(doublePrefix + "mPreferredTopFocusableStack=" + mPreferredTopFocusableStack);
|
||||||
}
|
}
|
||||||
if (mLastFocusedStack != null) {
|
if (mLastFocusedStack != null) {
|
||||||
pw.println(prefix + " mLastFocusedStack=" + mLastFocusedStack);
|
pw.println(doublePrefix + "mLastFocusedStack=" + mLastFocusedStack);
|
||||||
}
|
}
|
||||||
final String doublePrefix = prefix + " ";
|
|
||||||
final String triplePrefix = doublePrefix + " ";
|
final String triplePrefix = doublePrefix + " ";
|
||||||
pw.println(doublePrefix + "Application tokens in top down Z order:");
|
pw.println(doublePrefix + "Application tokens in top down Z order:");
|
||||||
for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) {
|
for (int stackNdx = getChildCount() - 1; stackNdx >= 0; --stackNdx) {
|
||||||
|
|||||||
@@ -2555,6 +2555,9 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
|||||||
pw.print(prefix); pw.println("ContainerAnimator:");
|
pw.print(prefix); pw.println("ContainerAnimator:");
|
||||||
mSurfaceAnimator.dump(pw, prefix + " ");
|
mSurfaceAnimator.dump(pw, prefix + " ");
|
||||||
}
|
}
|
||||||
|
if (mLastOrientationSource != null) {
|
||||||
|
pw.println(prefix + "mLastOrientationSource=" + mLastOrientationSource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final void updateSurfacePosition() {
|
final void updateSurfacePosition() {
|
||||||
|
|||||||
@@ -127,8 +127,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
|
|||||||
mTask = mStack.getBottomMostTask();
|
mTask = mStack.getBottomMostTask();
|
||||||
mActivity = mTask.getTopNonFinishingActivity();
|
mActivity = mTask.getTopNonFinishingActivity();
|
||||||
|
|
||||||
doReturn(false).when(mService).isBooting();
|
setBooted(mService);
|
||||||
doReturn(true).when(mService).isBooted();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1535,7 +1534,7 @@ public class ActivityRecordTests extends ActivityTestsBase {
|
|||||||
* Sets orientation without notifying the parent to simulate that the display has not applied
|
* Sets orientation without notifying the parent to simulate that the display has not applied
|
||||||
* the requested orientation yet.
|
* the requested orientation yet.
|
||||||
*/
|
*/
|
||||||
private static void setRotatedScreenOrientationSilently(ActivityRecord r) {
|
static void setRotatedScreenOrientationSilently(ActivityRecord r) {
|
||||||
final int rotatedOrentation = r.getConfiguration().orientation == ORIENTATION_PORTRAIT
|
final int rotatedOrentation = r.getConfiguration().orientation == ORIENTATION_PORTRAIT
|
||||||
? SCREEN_ORIENTATION_LANDSCAPE
|
? SCREEN_ORIENTATION_LANDSCAPE
|
||||||
: SCREEN_ORIENTATION_PORTRAIT;
|
: SCREEN_ORIENTATION_PORTRAIT;
|
||||||
|
|||||||
@@ -1392,8 +1392,7 @@ public class ActivityStackTests extends ActivityTestsBase {
|
|||||||
}
|
}
|
||||||
mSupervisor.endDeferResume();
|
mSupervisor.endDeferResume();
|
||||||
|
|
||||||
doReturn(false).when(mService).isBooting();
|
setBooted(mService);
|
||||||
doReturn(true).when(mService).isBooted();
|
|
||||||
// 2 activities are started while keyguard is locked, so they are waiting to be resolved.
|
// 2 activities are started while keyguard is locked, so they are waiting to be resolved.
|
||||||
assertFalse(unknownAppVisibilityController.allResolved());
|
assertFalse(unknownAppVisibilityController.allResolved());
|
||||||
|
|
||||||
|
|||||||
@@ -67,8 +67,7 @@ public class ActivityTaskManagerServiceTests extends ActivityTestsBase {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
doReturn(false).when(mService).isBooting();
|
setBooted(mService);
|
||||||
doReturn(true).when(mService).isBooted();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Verify that activity is finished correctly upon request. */
|
/** Verify that activity is finished correctly upon request. */
|
||||||
|
|||||||
@@ -1239,8 +1239,7 @@ public class DisplayContentTests extends WindowTestsBase {
|
|||||||
@Test
|
@Test
|
||||||
public void testNoFixedRotationWithPip() {
|
public void testNoFixedRotationWithPip() {
|
||||||
// Make resume-top really update the activity state.
|
// Make resume-top really update the activity state.
|
||||||
doReturn(false).when(mWm.mAtmService).isBooting();
|
setBooted(mWm.mAtmService);
|
||||||
doReturn(true).when(mWm.mAtmService).isBooted();
|
|
||||||
// Speed up the test by a few seconds.
|
// Speed up the test by a few seconds.
|
||||||
mWm.mAtmService.deferWindowLayout();
|
mWm.mAtmService.deferWindowLayout();
|
||||||
doNothing().when(mWm).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt());
|
doNothing().when(mWm).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt());
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import static com.android.server.wm.RootWindowContainer.MATCH_TASK_IN_STACKS_OR_
|
|||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@@ -57,8 +58,10 @@ import android.content.Intent;
|
|||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
|
import android.util.MergedConfiguration;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
import androidx.test.filters.MediumTest;
|
import androidx.test.filters.MediumTest;
|
||||||
@@ -221,6 +224,35 @@ public class RootActivityContainerTests extends ActivityTestsBase {
|
|||||||
null /* target */, null /* targetOptions */);
|
null /* target */, null /* targetOptions */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAwakeFromSleepingWithAppConfiguration() {
|
||||||
|
final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
|
||||||
|
final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true).build();
|
||||||
|
activity.moveFocusableActivityToTop("test");
|
||||||
|
assertTrue(activity.getStack().isFocusedStackOnDisplay());
|
||||||
|
ActivityRecordTests.setRotatedScreenOrientationSilently(activity);
|
||||||
|
|
||||||
|
final Configuration rotatedConfig = new Configuration();
|
||||||
|
display.computeScreenConfiguration(rotatedConfig, display.getDisplayRotation()
|
||||||
|
.rotationForOrientation(activity.getOrientation(), display.getRotation()));
|
||||||
|
assertNotEquals(activity.getConfiguration().orientation, rotatedConfig.orientation);
|
||||||
|
// Assume the activity was shown in different orientation. For example, the top activity is
|
||||||
|
// landscape and the portrait lockscreen is shown.
|
||||||
|
activity.setLastReportedConfiguration(
|
||||||
|
new MergedConfiguration(mService.getGlobalConfiguration(), rotatedConfig));
|
||||||
|
activity.setState(ActivityState.STOPPED, "sleep");
|
||||||
|
|
||||||
|
display.setIsSleeping(true);
|
||||||
|
doReturn(false).when(display).shouldSleep();
|
||||||
|
// Allow to resume when awaking.
|
||||||
|
setBooted(mService);
|
||||||
|
mRootWindowContainer.applySleepTokens(true);
|
||||||
|
|
||||||
|
// The display orientation should be changed by the activity so there is no relaunch.
|
||||||
|
verify(activity, never()).relaunchActivityLocked(anyBoolean());
|
||||||
|
assertEquals(rotatedConfig.orientation, display.getConfiguration().orientation);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that removal of activity with task and stack is done correctly.
|
* Verifies that removal of activity with task and stack is done correctly.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
||||||
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.testing.DexmakerShareClassLoaderRule;
|
import android.testing.DexmakerShareClassLoaderRule;
|
||||||
|
|
||||||
@@ -66,6 +68,15 @@ class SystemServiceTestsBase {
|
|||||||
return mLockRule.waitForLocked(callable);
|
return mLockRule.waitForLocked(callable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the system booted, so that {@link ActivityStack#resumeTopActivityInnerLocked} can really
|
||||||
|
* be executed to update activity state and configuration when resuming the current top.
|
||||||
|
*/
|
||||||
|
static void setBooted(ActivityTaskManagerService atmService) {
|
||||||
|
doReturn(false).when(atmService).isBooting();
|
||||||
|
doReturn(true).when(atmService).isBooted();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to compare the output of T#toString. It is convenient to have readable output
|
* Utility class to compare the output of T#toString. It is convenient to have readable output
|
||||||
* of assertion if the string content can represent the expected states.
|
* of assertion if the string content can represent the expected states.
|
||||||
|
|||||||
Reference in New Issue
Block a user