auto import from //branches/cupcake/...@131421
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 09f5d8f..fed6d12 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -768,27 +768,55 @@
if (willMove && w != null) {
final WindowState curTarget = mInputMethodTarget;
if (curTarget != null && curTarget.mAppToken != null) {
- int curIndex = -1;
- if (DEBUG_INPUT_METHOD) Log.v(TAG, "mNextAppTransition="
- + mNextAppTransition + " curTarget animating="
- + curTarget.isAnimating()
- + " layer=" + curTarget.mAnimLayer
- + " new layer=" + w.mAnimLayer);
- if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
- // If we are currently setting up for an animation,
- // hold everything until we can find out what will happen.
- mInputMethodTargetWaitingAnim = true;
- curIndex = localmWindows.indexOf(curTarget);
- } else if (curTarget.isAnimating() &&
- curTarget.mAnimLayer > w.mAnimLayer) {
- // If the window we are currently targeting is involved
- // with an animation, and it is on top of the next target
- // we will be over, then hold off on moving until
- // that is done.
- curIndex = localmWindows.indexOf(curTarget);
+
+ // Now some fun for dealing with window animations that
+ // modify the Z order. We need to look at all windows below
+ // the current target that are in this app, finding the highest
+ // visible one in layering.
+ AppWindowToken token = curTarget.mAppToken;
+ WindowState highestTarget = null;
+ int highestPos = 0;
+ if (token.animating || token.animation != null) {
+ int pos = 0;
+ pos = localmWindows.indexOf(curTarget);
+ while (pos >= 0) {
+ WindowState win = (WindowState)localmWindows.get(pos);
+ if (win.mAppToken != token) {
+ break;
+ }
+ if (!win.mRemoved) {
+ if (highestTarget == null || win.mAnimLayer >
+ highestTarget.mAnimLayer) {
+ highestTarget = win;
+ highestPos = pos;
+ }
+ }
+ pos--;
+ }
}
- if (curIndex >= 0) {
- return curIndex + 1;
+
+ if (highestTarget != null) {
+ if (DEBUG_INPUT_METHOD) Log.v(TAG, "mNextAppTransition="
+ + mNextAppTransition + " " + highestTarget
+ + " animating=" + highestTarget.isAnimating()
+ + " layer=" + highestTarget.mAnimLayer
+ + " new layer=" + w.mAnimLayer);
+
+ if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
+ // If we are currently setting up for an animation,
+ // hold everything until we can find out what will happen.
+ mInputMethodTargetWaitingAnim = true;
+ mInputMethodTarget = highestTarget;
+ return highestPos + 1;
+ } else if (highestTarget.isAnimating() &&
+ highestTarget.mAnimLayer > w.mAnimLayer) {
+ // If the window we are currently targeting is involved
+ // with an animation, and it is on top of the next target
+ // we will be over, then hold off on moving until
+ // that is done.
+ mInputMethodTarget = highestTarget;
+ return highestPos + 1;
+ }
}
}
}
@@ -891,12 +919,27 @@
}
}
+ void logWindowList(String prefix) {
+ int N = mWindows.size();
+ while (N > 0) {
+ N--;
+ Log.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
+ }
+ }
+
void moveInputMethodDialogsLocked(int pos) {
ArrayList<WindowState> dialogs = mInputMethodDialogs;
+
final int N = dialogs.size();
+ if (DEBUG_INPUT_METHOD) Log.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
for (int i=0; i<N; i++) {
pos = tmpRemoveWindowLocked(pos, dialogs.get(i));
}
+ if (DEBUG_INPUT_METHOD) {
+ Log.v(TAG, "Window list w/pos=" + pos);
+ logWindowList(" ");
+ }
+
if (pos >= 0) {
final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
if (pos < mWindows.size()) {
@@ -905,17 +948,26 @@
pos++;
}
}
+ if (DEBUG_INPUT_METHOD) Log.v(TAG, "Adding " + N + " dialogs at pos=" + pos);
for (int i=0; i<N; i++) {
WindowState win = dialogs.get(i);
win.mTargetAppToken = targetAppToken;
pos = reAddWindowLocked(pos, win);
}
+ if (DEBUG_INPUT_METHOD) {
+ Log.v(TAG, "Final window list:");
+ logWindowList(" ");
+ }
return;
}
for (int i=0; i<N; i++) {
WindowState win = dialogs.get(i);
win.mTargetAppToken = null;
reAddWindowToListInOrderLocked(win);
+ if (DEBUG_INPUT_METHOD) {
+ Log.v(TAG, "No IM target, final list:");
+ logWindowList(" ");
+ }
}
}
@@ -971,9 +1023,21 @@
}
if (imWin != null) {
+ if (DEBUG_INPUT_METHOD) {
+ Log.v(TAG, "Moving IM from " + imPos);
+ logWindowList(" ");
+ }
imPos = tmpRemoveWindowLocked(imPos, imWin);
+ if (DEBUG_INPUT_METHOD) {
+ Log.v(TAG, "List after moving with new pos " + imPos + ":");
+ logWindowList(" ");
+ }
imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
reAddWindowLocked(imPos, imWin);
+ if (DEBUG_INPUT_METHOD) {
+ Log.v(TAG, "List after moving IM to " + imPos + ":");
+ logWindowList(" ");
+ }
if (DN > 0) moveInputMethodDialogsLocked(imPos+1);
} else {
moveInputMethodDialogsLocked(imPos);
@@ -984,9 +1048,14 @@
// because they aren't currently associated with a focus window.
if (imWin != null) {
+ if (DEBUG_INPUT_METHOD) Log.v(TAG, "Moving IM from " + imPos);
tmpRemoveWindowLocked(0, imWin);
imWin.mTargetAppToken = null;
reAddWindowToListInOrderLocked(imWin);
+ if (DEBUG_INPUT_METHOD) {
+ Log.v(TAG, "List with no IM target:");
+ logWindowList(" ");
+ }
if (DN > 0) moveInputMethodDialogsLocked(-1);;
} else {
moveInputMethodDialogsLocked(-1);;
@@ -1233,7 +1302,7 @@
if (win.mSurface != null && !mDisplayFrozen) {
// If we are not currently running the exit animation, we
// need to see about starting one.
- if (wasVisible=win.isVisibleLw()) {
+ if (wasVisible=win.isWinVisibleLw()) {
int transit = WindowManagerPolicy.TRANSIT_EXIT;
if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
@@ -1277,6 +1346,12 @@
mKeyWaiter.releasePendingPointerLocked(win.mSession);
mKeyWaiter.releasePendingTrackballLocked(win.mSession);
+ win.mRemoved = true;
+
+ if (mInputMethodTarget == win) {
+ moveInputMethodWindowsIfNeededLocked(false);
+ }
+
mPolicy.removeWindowLw(win);
win.removeLocked();
@@ -1501,7 +1576,7 @@
if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
}
- if (win.isVisibleLw() &&
+ if (win.isWinVisibleLw() &&
applyAnimationLocked(win, transit, false)) {
win.mExiting = true;
mKeyWaiter.finishedKey(session, client, true,
@@ -1511,13 +1586,13 @@
// an exit.
win.mExiting = true;
} else {
+ if (mInputMethodWindow == win) {
+ mInputMethodWindow = null;
+ }
win.destroySurfaceLocked();
}
}
}
- if (mInputMethodWindow == win) {
- mInputMethodWindow = null;
- }
outSurface.clear();
}
@@ -1620,7 +1695,7 @@
private boolean applyAnimationLocked(WindowState win,
int transit, boolean isEntrance) {
- if (win.mAnimating && win.mAnimationIsEntrance == isEntrance) {
+ if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
// If we are trying to apply an animation, but already running
// an animation of the same type, then just leave that one alone.
return true;
@@ -1666,6 +1741,7 @@
Log.v(TAG, "Loaded animation " + a + " for " + win, e);
}
win.setAnimation(a);
+ win.mAnimationIsEntrance = isEntrance;
}
} else {
win.clearAnimation();
@@ -2724,7 +2800,7 @@
boolean added = false;
for (int j=0; j<NCW; j++) {
WindowState cwin = (WindowState)win.mChildWindows.get(j);
- if (cwin.mSubLayer >= 0) {
+ if (!added && cwin.mSubLayer >= 0) {
mWindows.add(index, win);
index++;
added = true;
@@ -4645,8 +4721,8 @@
KeyQ() {
super(mContext);
PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
- mHoldingScreen = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
- | PowerManager.ON_AFTER_RELEASE, "KEEP_SCREEN_ON_FLAG");
+ mHoldingScreen = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
+ "KEEP_SCREEN_ON_FLAG");
mHoldingScreen.setReferenceCounted(false);
}
@@ -4769,8 +4845,7 @@
if (holding) {
mHoldingScreen.acquire();
} else {
- long curTime = SystemClock.uptimeMillis();
- mPowerManager.userActivity(curTime, false, LocalPowerManager.OTHER_EVENT);
+ mPolicy.screenOnStopped();
mHoldingScreen.release();
}
}
@@ -5095,6 +5170,19 @@
}
}
+ public boolean performHapticFeedback(IWindow window, int effectId,
+ boolean always) {
+ synchronized(mWindowMap) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ return mPolicy.performHapticFeedback(
+ windowForClientLocked(this, window), effectId, always);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
void windowAddedLocked() {
if (mSurfaceSession == null) {
if (localLOGV) Log.v(
@@ -5255,9 +5343,11 @@
// Currently running animation.
boolean mAnimating;
+ boolean mLocalAnimating;
Animation mAnimation;
boolean mAnimationIsEntrance;
boolean mHasTransformation;
+ boolean mHasLocalTransformation;
final Transformation mTransformation = new Transformation();
// This is set after IWindowSession.relayout() has been called at
@@ -5297,6 +5387,9 @@
// been updated for the new orientation.
boolean mOrientationChanging;
+ // Is this window now (or just being) removed?
+ boolean mRemoved;
+
WindowState(Session s, IWindow c, WindowToken token,
WindowState attachedWindow, WindowManager.LayoutParams a,
int viewVisibility) {
@@ -5516,6 +5609,7 @@
if (localLOGV) Log.v(
TAG, "Setting animation in " + this + ": " + anim);
mAnimating = false;
+ mLocalAnimating = false;
mAnimation = anim;
mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
mAnimation.scaleCurrentDuration(mWindowAnimationScale);
@@ -5524,6 +5618,7 @@
public void clearAnimation() {
if (mAnimation != null) {
mAnimating = true;
+ mLocalAnimating = false;
mAnimation = null;
}
}
@@ -5752,13 +5847,15 @@
if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
mHasTransformation = true;
- if (!mAnimating) {
+ mHasLocalTransformation = true;
+ if (!mLocalAnimating) {
if (DEBUG_ANIM) Log.v(
TAG, "Starting animation in " + this +
" @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
" dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
mAnimation.setStartTime(currentTime);
+ mLocalAnimating = true;
mAnimating = true;
}
mTransformation.clear();
@@ -5767,9 +5864,6 @@
if (DEBUG_ANIM) Log.v(
TAG, "Stepped animation in " + this +
": more=" + more + ", xform=" + mTransformation);
- if (mAppToken != null && mAppToken.hasTransformation) {
- mTransformation.compose(mAppToken.transformation);
- }
if (more) {
// we're not done!
return true;
@@ -5780,10 +5874,19 @@
mAnimation = null;
//WindowManagerService.this.dump();
}
- if (mAppToken != null && mAppToken.hasTransformation) {
+ mHasLocalTransformation = false;
+ if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
+ && mAppToken.hasTransformation) {
+ // When our app token is animating, we kind-of pretend like
+ // we are as well. Note the mLocalAnimating mAnimationIsEntrance
+ // part of this check means that we will only do this if
+ // our window is not currently exiting, or it is not
+ // locally animating itself. The idea being that one that
+ // is exiting and doing a local animation should be removed
+ // once that animation is done.
mAnimating = true;
mHasTransformation = true;
- mTransformation.set(mAppToken.transformation);
+ mTransformation.clear();
return false;
} else if (mHasTransformation) {
// Little trick to get through the path below to act like
@@ -5796,10 +5899,11 @@
// If the display is frozen, and there is a pending animation,
// clear it and make sure we run the cleanup code.
mAnimating = true;
+ mLocalAnimating = true;
mAnimation = null;
}
- if (!mAnimating) {
+ if (!mAnimating && !mLocalAnimating) {
return false;
}
@@ -5809,6 +5913,7 @@
+ (mAppToken != null ? mAppToken.reportedVisible : false));
mAnimating = false;
+ mLocalAnimating = false;
mAnimation = null;
mAnimLayer = mLayer;
if (mIsImWindow) {
@@ -5817,6 +5922,7 @@
if (DEBUG_LAYERS) Log.v(TAG, "Stepping win " + this
+ " anim layer: " + mAnimLayer);
mHasTransformation = false;
+ mHasLocalTransformation = false;
mPolicyVisibility = mPolicyVisibilityAfterAnim;
mTransformation.clear();
if (mHasDrawn
@@ -5891,10 +5997,15 @@
}
void computeShownFrameLocked() {
- final boolean selfTransformation = mHasTransformation;
- final boolean attachedTransformation = (mAttachedWindow != null
- && mAttachedWindow.mHasTransformation);
- if (selfTransformation || attachedTransformation) {
+ final boolean selfTransformation = mHasLocalTransformation;
+ Transformation attachedTransformation =
+ (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
+ ? mAttachedWindow.mTransformation : null;
+ Transformation appTransformation =
+ (mAppToken != null && mAppToken.hasTransformation)
+ ? mAppToken.transformation : null;
+ if (selfTransformation || attachedTransformation != null
+ || appTransformation != null) {
// cache often used attributes locally
final Rect frame = mFrame;
final float tmpFloats[] = mTmpFloats;
@@ -5905,8 +6016,11 @@
if (selfTransformation) {
tmpMatrix.preConcat(mTransformation.getMatrix());
}
- if (attachedTransformation) {
- tmpMatrix.preConcat(mAttachedWindow.mTransformation.getMatrix());
+ if (attachedTransformation != null) {
+ tmpMatrix.preConcat(attachedTransformation.getMatrix());
+ }
+ if (appTransformation != null) {
+ tmpMatrix.preConcat(appTransformation.getMatrix());
}
// "convert" it into SurfaceFlinger's format
@@ -5940,8 +6054,11 @@
if (selfTransformation) {
mShownAlpha *= mTransformation.getAlpha();
}
- if (attachedTransformation) {
- mShownAlpha *= mAttachedWindow.mTransformation.getAlpha();
+ if (attachedTransformation != null) {
+ mShownAlpha *= attachedTransformation.getAlpha();
+ }
+ if (appTransformation != null) {
+ mShownAlpha *= appTransformation.getAlpha();
}
} else {
//Log.i(TAG, "Not applying alpha transform");
@@ -5965,7 +6082,7 @@
/**
* Is this window visible? It is not visible if there is no
* surface, or we are in the process of running an exit animation
- * that will remove the surface.
+ * that will remove the surface, or its app token has been hidden.
*/
public boolean isVisibleLw() {
final AppWindowToken atoken = mAppToken;
@@ -5975,6 +6092,18 @@
}
/**
+ * Is this window visible, ignoring its app token? It is not visible
+ * if there is no surface, or we are in the process of running an exit animation
+ * that will remove the surface.
+ */
+ public boolean isWinVisibleLw() {
+ final AppWindowToken atoken = mAppToken;
+ return mSurface != null && mPolicyVisibility && !mAttachedHidden
+ && (atoken == null || !atoken.hiddenRequested || atoken.animating)
+ && !mExiting && !mDestroying;
+ }
+
+ /**
* The same as isVisible(), but follows the current hidden state of
* the associated app token, not the pending requested hidden state.
*/
@@ -6203,6 +6332,7 @@
pw.println(prefix + "mShownAlpha=" + mShownAlpha
+ " mAlpha=" + mAlpha + " mLastAlpha=" + mLastAlpha);
pw.println(prefix + "mAnimating=" + mAnimating
+ + " mLocalAnimating=" + mLocalAnimating
+ " mAnimationIsEntrance=" + mAnimationIsEntrance
+ " mAnimation=" + mAnimation);
pw.println(prefix + "XForm: has=" + mHasTransformation
@@ -6213,7 +6343,8 @@
+ " mHasDrawn=" + mHasDrawn);
pw.println(prefix + "mExiting=" + mExiting
+ " mRemoveOnExit=" + mRemoveOnExit
- + " mDestroying=" + mDestroying);
+ + " mDestroying=" + mDestroying
+ + " mRemoved=" + mRemoved);
pw.println(prefix + "mOrientationChanging=" + mOrientationChanging
+ " mAppFreezing=" + mAppFreezing);
}
@@ -7959,6 +8090,9 @@
i--;
WindowState win = mDestroySurface.get(i);
win.mDestroying = false;
+ if (mInputMethodWindow == win) {
+ mInputMethodWindow = null;
+ }
win.destroySurfaceLocked();
} while (i > 0);
mDestroySurface.clear();