Merge "When a window is first shown only draw once while animating." into jb-dev

This commit is contained in:
Dianne Hackborn
2012-04-27 17:42:48 -07:00
committed by Android (Google) Code Review
6 changed files with 90 additions and 10 deletions

View File

@@ -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();
}

View File

@@ -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.
@@ -1766,6 +1767,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()="
@@ -1782,6 +1785,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;
@@ -1813,14 +1824,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) {
@@ -2677,6 +2690,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
@@ -2726,6 +2740,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);
}
@@ -2938,6 +2954,9 @@ public final class ViewRootImpl implements ViewParent,
case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
setAccessibilityFocusedHost(null);
} break;
case MSG_DISPATCH_DONE_ANIMATING: {
handleDispatchDoneAnimating();
} break;
}
}
}
@@ -3753,6 +3772,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;
@@ -4465,6 +4493,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.
@@ -4772,6 +4804,13 @@ public final class ViewRootImpl implements ViewParent,
localValue, localChanges);
}
}
public void doneAnimating() {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
viewAncestor.dispatchDoneAnimating();
}
}
}
/**

View File

@@ -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

View File

@@ -87,4 +87,7 @@ public class BaseIWindow extends IWindow.Stub {
}
}
}
public void doneAnimating() {
}
}

View File

@@ -423,6 +423,12 @@ public class WindowManagerService extends IWindowManager.Stub
ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
= 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;
}

View File

@@ -90,6 +90,10 @@ public final class BridgeWindow implements IWindow {
// pass for now.
}
@Override
public void doneAnimating() {
}
@Override
public IBinder asBinder() {
// pass for now.