summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Arthur Hung <arthurhung@google.com> 2019-05-07 19:49:31 +0800
committer Arthur Hung <arthurhung@google.com> 2019-05-10 11:11:07 +0000
commit442aff2d0b82790a08b792990d625c10a63f9570 (patch)
treebb1240b12bfb952ec6936f1e989b87d09aab60ba
parent906e4169864f38488a661552ad45bd890a992f26 (diff)
Fix window didn't disappear if enable/disable ime at same time
When starting to freeze display, AppTransition also clear all status and data, but if the RemoteAnimation didn't start. The window can't recevice the finish animation callback, that would make the state is always EXITING. Bug: 130618911 Test: atest DocumentsTest Test: atest WmTests:RemoteAnimationControllerTest Test: atest WmTests:AppTransitionTests Change-Id: I5695a291f26323eb78cced435722b459b963a9f1
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java7
-rw-r--r--services/core/java/com/android/server/wm/RemoteAnimationController.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java68
3 files changed, 72 insertions, 5 deletions
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index e053ff338a25..0915caedd6bc 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -452,6 +452,13 @@ public class AppTransition implements Dump {
void freeze() {
final int transit = mNextAppTransition;
+ // The RemoteAnimationControl didn't register AppTransitionListener and
+ // only initialized the finish and timeout callback when goodToGo().
+ // So cancel the remote animation here to prevent the animation can't do
+ // finish after transition state cleared.
+ if (mRemoteAnimationController != null) {
+ mRemoteAnimationController.cancelAnimation("freeze");
+ }
setAppTransition(TRANSIT_UNSET, 0 /* flags */);
clear();
setReady();
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 5f95691d5307..b4bfedda94c7 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -132,7 +132,7 @@ class RemoteAnimationController implements DeathRecipient {
sendRunningRemoteAnimation(true);
}
- private void cancelAnimation(String reason) {
+ void cancelAnimation(String reason) {
if (DEBUG_REMOTE_ANIMATIONS) Slog.d(TAG, "cancelAnimation(): reason=" + reason);
synchronized (mService.getWindowManagerLock()) {
if (mCanceled) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index 5fc7f44588e1..5a72a584b122 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -18,30 +18,40 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
+
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import android.graphics.Rect;
+import android.os.IBinder;
+import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.view.Display;
-
-import org.junit.Before;
-import org.junit.Test;
+import android.view.IRemoteAnimationFinishedCallback;
+import android.view.IRemoteAnimationRunner;
+import android.view.RemoteAnimationAdapter;
+import android.view.RemoteAnimationTarget;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
+import org.junit.Before;
+import org.junit.Test;
+
/**
* Test class for {@link AppTransition}.
*
@@ -51,7 +61,6 @@ import androidx.test.filters.SmallTest;
@SmallTest
@Presubmit
public class AppTransitionTests extends WindowTestsBase {
-
private DisplayContent mDc;
@Before
@@ -181,4 +190,55 @@ public class AppTransitionTests extends WindowTestsBase {
getInstrumentation().getTargetContext(), -1));
}
+ @Test
+ public void testCancelRemoteAnimationWhenFreeze() {
+ final DisplayContent dc = createNewDisplay(Display.STATE_ON);
+ final WindowState exitingAppWindow = createWindow(null /* parent */, TYPE_BASE_APPLICATION,
+ dc, "exiting app");
+ final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken;
+ // Wait until everything in animation handler get executed to prevent the exiting window
+ // from being removed during WindowSurfacePlacer Traversal.
+ waitUntilHandlersIdle();
+
+ // Set a remote animator.
+ final TestRemoteAnimationRunner runner = new TestRemoteAnimationRunner();
+ final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
+ runner, 100, 50, true /* changeNeedsSnapshot */);
+ // RemoteAnimationController will tracking RemoteAnimationAdapter's caller with calling pid.
+ adapter.setCallingPid(123);
+
+ // Simulate activity finish flows to prepare app transition & set visibility,
+ // make sure transition is set as expected.
+ dc.prepareAppTransition(TRANSIT_ACTIVITY_CLOSE,
+ false /* alwaysKeepCurrent */, 0 /* flags */, false /* forceOverride */);
+ assertEquals(TRANSIT_ACTIVITY_CLOSE, dc.mAppTransition.getAppTransition());
+ dc.mAppTransition.overridePendingAppTransitionRemote(adapter);
+ exitingAppToken.setVisibility(false, false);
+ assertTrue(dc.mClosingApps.size() > 0);
+
+ // Make sure window is in animating stage before freeze, and cancel after freeze.
+ assertTrue(dc.isAppAnimating());
+ assertFalse(runner.mCancelled);
+ dc.mAppTransition.freeze();
+ assertFalse(dc.isAppAnimating());
+ assertTrue(runner.mCancelled);
+ }
+
+ private class TestRemoteAnimationRunner implements IRemoteAnimationRunner {
+ boolean mCancelled = false;
+ @Override
+ public void onAnimationStart(RemoteAnimationTarget[] apps,
+ IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
+ }
+
+ @Override
+ public void onAnimationCancelled() {
+ mCancelled = true;
+ }
+
+ @Override
+ public IBinder asBinder() {
+ return null;
+ }
+ }
}