Create end of animation callback for Activity
Activities cannot draw while their entering animations are active.
This change introduces a callback, onEnterAnimationComplete() so
that activities can know when their draws will be effective.
Fixes bug 13658460.
Change-Id: Ic48540cd4c7e37538f10cb2dc0852aa3f55d11e1
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index fed68f9..314e906 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1158,6 +1158,7 @@
static final int UPDATE_TIME = 41;
static final int SYSTEM_USER_START_MSG = 42;
static final int SYSTEM_USER_CURRENT_MSG = 43;
+ static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1813,6 +1814,18 @@
mSystemServiceManager.switchUser(msg.arg1);
break;
}
+ case ENTER_ANIMATION_COMPLETE_MSG: {
+ synchronized (ActivityManagerService.this) {
+ ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
+ if (r != null && r.app != null && r.app.thread != null) {
+ try {
+ r.app.thread.scheduleEnterAnimationComplete(r.appToken);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ break;
+ }
}
}
};
@@ -5699,6 +5712,11 @@
}
@Override
+ public final void notifyEnterAnimationComplete(IBinder token) {
+ mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
+ }
+
+ @Override
public String getCallingPackage(IBinder token) {
synchronized (this) {
ActivityRecord r = getCallingRecordLocked(token);
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 874e105..9b69ce2 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -297,6 +297,13 @@
mAppToken.mLaunchTaskBehind = false;
} else {
mAppToken.updateReportedVisibilityLocked();
+ if (mAppToken.mEnteringAnimation) {
+ mAppToken.mEnteringAnimation = false;
+ try {
+ mService.mActivityManager.notifyEnterAnimationComplete(mAppToken.token);
+ } catch (RemoteException e) {
+ }
+ }
}
return false;
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 312689b..3fcd067 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -110,6 +110,7 @@
boolean mDeferRemoval;
boolean mLaunchTaskBehind;
+ boolean mEnteringAnimation;
AppWindowToken(WindowManagerService _service, IApplicationToken _token,
boolean _voiceInteraction) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 170ecbd..670ba55 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4450,6 +4450,7 @@
if (visible) {
mOpeningApps.add(wtoken);
wtoken.startingMoved = false;
+ wtoken.mEnteringAnimation = true;
// If the token is currently hidden (should be the
// common case), then we need to set up to wait for
@@ -4472,6 +4473,7 @@
}
} else {
mClosingApps.add(wtoken);
+ wtoken.mEnteringAnimation = false;
// If the token is currently visible (should be the
// common case), then set up to wait for it to be hidden.