summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/IWindow.aidl11
-rw-r--r--core/java/android/view/ViewRootImpl.java51
-rw-r--r--core/java/android/view/WindowManagerImpl.java5
-rw-r--r--core/java/com/android/internal/view/BaseIWindow.java3
-rwxr-xr-xservices/java/com/android/server/wm/WindowManagerService.java26
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java4
6 files changed, 90 insertions, 10 deletions
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 497bc90b..d73723a 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -70,11 +70,18 @@ oneway interface IWindow {
/**
* Drag/drop events
*/
- void dispatchDragEvent(in DragEvent event);
+ void dispatchDragEvent(in DragEvent event);
/**
* System chrome visibility changes
*/
- void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
+ void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
int localValue, int localChanges);
+
+ /**
+ * If the window manager returned RELAYOUT_RES_ANIMATING
+ * from relayout(), this method will be called when the animation
+ * is done.
+ */
+ void doneAnimating();
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 59f0917..ef9649a 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -229,6 +229,7 @@ public final class ViewRootImpl implements ViewParent,
boolean mNewSurfaceNeeded;
boolean mHasHadWindowFocus;
boolean mLastWasImTarget;
+ boolean mWindowsAnimating;
int mLastSystemUiVisibility;
// Pool of queued input events.
@@ -1768,6 +1769,8 @@ public final class ViewRootImpl implements ViewParent,
}
}
+ boolean skipDraw = false;
+
if (mFirst) {
// handle first focus request
if (DEBUG_INPUT_RESIZE) Log.v(TAG, "First: mView.hasFocus()="
@@ -1784,6 +1787,14 @@ public final class ViewRootImpl implements ViewParent,
+ mRealFocusedView);
}
}
+ if ((relayoutResult&WindowManagerImpl.RELAYOUT_RES_ANIMATING) != 0) {
+ // The first time we relayout the window, if the system is
+ // doing window animations, we want to hold of on any future
+ // draws until the animation is done.
+ mWindowsAnimating = true;
+ }
+ } else if (mWindowsAnimating) {
+ skipDraw = true;
}
mFirst = false;
@@ -1815,14 +1826,16 @@ public final class ViewRootImpl implements ViewParent,
viewVisibility != View.VISIBLE;
if (!cancelDraw && !newSurface) {
- if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
- for (int i = 0; i < mPendingTransitions.size(); ++i) {
- mPendingTransitions.get(i).startChangingAnimations();
+ if (!skipDraw || mReportNextDraw) {
+ if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
+ for (int i = 0; i < mPendingTransitions.size(); ++i) {
+ mPendingTransitions.get(i).startChangingAnimations();
+ }
+ mPendingTransitions.clear();
}
- mPendingTransitions.clear();
+
+ performDraw();
}
-
- performDraw();
} else {
// End any pending transitions on this non-visible window
if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
@@ -2680,6 +2693,7 @@ public final class ViewRootImpl implements ViewParent,
private final static int MSG_DISPATCH_SCREEN_STATE = 20;
private final static int MSG_INVALIDATE_DISPLAY_LIST = 21;
private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 22;
+ private final static int MSG_DISPATCH_DONE_ANIMATING = 23;
final class ViewRootHandler extends Handler {
@Override
@@ -2729,6 +2743,8 @@ public final class ViewRootImpl implements ViewParent,
return "MSG_INVALIDATE_DISPLAY_LIST";
case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST:
return "MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST";
+ case MSG_DISPATCH_DONE_ANIMATING:
+ return "MSG_DISPATCH_DONE_ANIMATING";
}
return super.getMessageName(message);
}
@@ -2941,6 +2957,9 @@ public final class ViewRootImpl implements ViewParent,
case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
setAccessibilityFocusedHost(null);
} break;
+ case MSG_DISPATCH_DONE_ANIMATING: {
+ handleDispatchDoneAnimating();
+ } break;
}
}
}
@@ -3756,6 +3775,15 @@ public final class ViewRootImpl implements ViewParent,
mView.dispatchSystemUiVisibilityChanged(args.globalVisibility);
}
+ public void handleDispatchDoneAnimating() {
+ if (mWindowsAnimating) {
+ mWindowsAnimating = false;
+ if (!mDirty.isEmpty() || mIsAnimating) {
+ scheduleTraversals();
+ }
+ }
+ }
+
public void getLastTouchPoint(Point outLocation) {
outLocation.x = (int) mLastTouchPoint.x;
outLocation.y = (int) mLastTouchPoint.y;
@@ -4476,6 +4504,10 @@ public final class ViewRootImpl implements ViewParent,
mHandler.sendMessage(mHandler.obtainMessage(MSG_DISPATCH_SYSTEM_UI_VISIBILITY, args));
}
+ public void dispatchDoneAnimating() {
+ mHandler.sendEmptyMessage(MSG_DISPATCH_DONE_ANIMATING);
+ }
+
public void dispatchCheckFocus() {
if (!mHandler.hasMessages(MSG_CHECK_FOCUS)) {
// This will result in a call to checkFocus() below.
@@ -4783,6 +4815,13 @@ public final class ViewRootImpl implements ViewParent,
localValue, localChanges);
}
}
+
+ public void doneAnimating() {
+ final ViewRootImpl viewAncestor = mViewAncestor.get();
+ if (viewAncestor != null) {
+ viewAncestor.dispatchDoneAnimating();
+ }
+ }
}
/**
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index a0f1041..56e8b30 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -73,6 +73,11 @@ public class WindowManagerImpl implements WindowManager {
* The window manager has changed the surface from the last call.
*/
public static final int RELAYOUT_RES_SURFACE_CHANGED = 0x4;
+ /**
+ * The window manager is currently animating. It will call
+ * IWindow.doneAnimating() when done.
+ */
+ public static final int RELAYOUT_RES_ANIMATING = 0x8;
/**
* Flag for relayout: the client will be later giving
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 15d11d8..a649ee1 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -87,4 +87,7 @@ public class BaseIWindow extends IWindow.Stub {
}
}
}
+
+ public void doneAnimating() {
+ }
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index b270cee..276bc5b 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -424,6 +424,12 @@ public class WindowManagerService extends IWindowManager.Stub
= new ArrayList<Pair<WindowState, IRemoteCallback>>();
/**
+ * Windows that have called relayout() while we were running animations,
+ * so we need to tell when the animation is done.
+ */
+ final ArrayList<WindowState> mRelayoutWhileAnimating = new ArrayList<WindowState>();
+
+ /**
* Used when rebuilding window list to keep track of windows that have
* been removed.
*/
@@ -2647,6 +2653,7 @@ public class WindowManagerService extends IWindowManager.Stub
boolean inTouchMode;
boolean configChanged;
boolean surfaceChanged = false;
+ boolean animating;
// if they don't have this permission, mask out the status bar bits
int systemUiVisibility = 0;
@@ -2946,7 +2953,11 @@ public class WindowManagerService extends IWindowManager.Stub
TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
inTouchMode = mInTouchMode;
-
+ animating = mAnimator.mAnimating;
+ if (animating && !mRelayoutWhileAnimating.contains(win)) {
+ mRelayoutWhileAnimating.add(win);
+ }
+
mInputMonitor.updateInputWindowsLw(true /*force*/);
}
@@ -2958,7 +2969,8 @@ public class WindowManagerService extends IWindowManager.Stub
return (inTouchMode ? WindowManagerImpl.RELAYOUT_RES_IN_TOUCH_MODE : 0)
| (displayed ? WindowManagerImpl.RELAYOUT_RES_FIRST_TIME : 0)
- | (surfaceChanged ? WindowManagerImpl.RELAYOUT_RES_SURFACE_CHANGED : 0);
+ | (surfaceChanged ? WindowManagerImpl.RELAYOUT_RES_SURFACE_CHANGED : 0)
+ | (animating ? WindowManagerImpl.RELAYOUT_RES_ANIMATING : 0);
}
public void performDeferredDestroyWindow(Session session, IWindow client) {
@@ -8579,6 +8591,16 @@ public class WindowManagerService extends IWindowManager.Stub
mToBottomApps.clear();
}
+ if (!mAnimator.mAnimating && mRelayoutWhileAnimating.size() > 0) {
+ for (int j=mRelayoutWhileAnimating.size()-1; j>=0; j--) {
+ try {
+ mRelayoutWhileAnimating.get(j).mClient.doneAnimating();
+ } catch (RemoteException e) {
+ }
+ }
+ mRelayoutWhileAnimating.clear();
+ }
+
if (wallpaperDestroyed) {
mLayoutNeeded |= adjustWallpaperWindowsLocked() != 0;
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
index 7c683c9..434ae9d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
@@ -91,6 +91,10 @@ public final class BridgeWindow implements IWindow {
}
@Override
+ public void doneAnimating() {
+ }
+
+ @Override
public IBinder asBinder() {
// pass for now.
return null;