summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCraig Mautner <cmautner@google.com>2012-03-23 16:11:14 -0700
committerCraig Mautner <cmautner@google.com>2012-03-23 16:11:14 -0700
commitbb1449b392b4fb14f17fa747c2261d7195405df3 (patch)
tree4650ad11d3c2e94aa07979a55374d3eabd869467
parent764983d16925daeeba3f29fd1f844187655d1386 (diff)
downloadframeworks_base-bb1449b392b4fb14f17fa747c2261d7195405df3.zip
frameworks_base-bb1449b392b4fb14f17fa747c2261d7195405df3.tar.gz
frameworks_base-bb1449b392b4fb14f17fa747c2261d7195405df3.tar.bz2
Reset layout needed at each animation step.
The member variable WindowAnimator.mPendingLayoutChanges was never being reset to 0. Consequently once it was set it was causing endless calls to the layout method. Fixes bug 6208114, 6220403, 6219546. Fixed NPE in RecentsPanelView. Change-Id: Ie529b8f31e535543cb5ae0af9447146306b14eeb
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java7
-rw-r--r--services/java/com/android/server/wm/WindowAnimator.java19
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java49
3 files changed, 51 insertions, 24 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 66cb32c..4d5c342 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -615,10 +615,11 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
if (!mFirstScreenful && tasks.size() == 0) {
return;
}
- mNumItemsWaitingForThumbnailsAndIcons =
- mFirstScreenful ? tasks.size() : mRecentTaskDescriptions.size();
+ mNumItemsWaitingForThumbnailsAndIcons = mFirstScreenful
+ ? tasks.size() : mRecentTaskDescriptions == null
+ ? 0 : mRecentTaskDescriptions.size();
if (mRecentTaskDescriptions == null) {
- mRecentTaskDescriptions = new ArrayList(tasks);
+ mRecentTaskDescriptions = new ArrayList<TaskDescription>(tasks);
} else {
mRecentTaskDescriptions.addAll(tasks);
}
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index b3dbee1..28dd0ba 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -23,7 +23,7 @@ import com.android.internal.policy.impl.PhoneWindowManager;
* on behalf of WindowManagerService.
*/
public class WindowAnimator {
- private static final String TAG = "WindowAnimations";
+ private static final String TAG = "WindowAnimator";
final WindowManagerService mService;
final Context mContext;
@@ -67,8 +67,24 @@ public class WindowAnimator {
final int NAT = mService.mAppTokens.size();
for (i=0; i<NAT; i++) {
final AppWindowToken appToken = mService.mAppTokens.get(i);
+ final boolean wasAnimating = appToken.animation != null;
if (appToken.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) {
mAnimating = true;
+ } else if (wasAnimating) {
+ // stopped animating, do one more pass through the layout
+ mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+ }
+ }
+
+ final int NEAT = mService.mExitingAppTokens.size();
+ for (i=0; i<NEAT; i++) {
+ final AppWindowToken appToken = mService.mExitingAppTokens.get(i);
+ final boolean wasAnimating = appToken.animation != null;
+ if (appToken.stepAnimationLocked(mCurrentTime, mInnerDw, mInnerDh)) {
+ mAnimating = true;
+ } else if (wasAnimating) {
+ // stopped animating, do one more pass through the layout
+ mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
}
}
@@ -517,6 +533,7 @@ public class WindowAnimator {
}
void animate() {
+ mPendingLayoutChanges = 0;
mCurrentTime = SystemClock.uptimeMillis();
// Update animations of all applications, including those
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 26367d2..ea1a9db 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -588,6 +588,9 @@ public class WindowManagerService extends IWindowManager.Stub
}
LayoutAndSurfaceFields mInnerFields = new LayoutAndSurfaceFields();
+ /** Only do a maximum of 6 repeated layouts. After that quit */
+ private int mLayoutRepeatCount;
+
private final class AnimationRunnable implements Runnable {
@Override
public void run() {
@@ -1897,7 +1900,7 @@ public class WindowManagerService extends IWindowManager.Stub
rawChanged = true;
}
- if (rawChanged && (wallpaperWin.getAttrs().privateFlags &
+ if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
try {
if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
@@ -2296,7 +2299,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (wasVisible) {
int transit = WindowManagerPolicy.TRANSIT_EXIT;
- if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
+ if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
}
// Try starting an animation.
@@ -2761,7 +2764,7 @@ public class WindowManagerService extends IWindowManager.Stub
// Try starting an animation; if there isn't one, we
// can destroy the surface right away.
int transit = WindowManagerPolicy.TRANSIT_EXIT;
- if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
+ if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
}
if (!win.mSurfacePendingDestroy && win.isWinVisibleLw() &&
@@ -7459,10 +7462,25 @@ public class WindowManagerService extends IWindowManager.Stub
} else {
mInLayout = false;
- if (mLayoutNeeded) {
+ }
+
+ if (mLayoutNeeded) {
+ if (++mLayoutRepeatCount < 6) {
requestTraversalLocked();
+ } else {
+ Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
+ mLayoutRepeatCount = 0;
}
+ } else {
+ mLayoutRepeatCount = 0;
+ }
+
+ if (mAnimator.mAnimating) {
+ // Do this even if requestTraversalLocked was called above so we get a frame drawn
+ // at the proper time as well as the one drawn early.
+ scheduleAnimationLocked();
}
+
if (mWindowsChanged && !mWindowChangeListeners.isEmpty()) {
mH.removeMessages(H.REPORT_WINDOWS_CHANGE);
mH.sendMessage(mH.obtainMessage(H.REPORT_WINDOWS_CHANGE));
@@ -8192,6 +8210,7 @@ public class WindowManagerService extends IWindowManager.Stub
mLayoutNeeded = true;
}
}
+
if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) {
if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
if (updateOrientationFromAppTokensLocked(true)) {
@@ -8199,6 +8218,7 @@ public class WindowManagerService extends IWindowManager.Stub
mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
}
}
+
if ((mPendingLayoutChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) {
mLayoutNeeded = true;
}
@@ -8409,8 +8429,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- boolean needRelayout = false;
-
if (!mAnimator.mAnimating && mAppTransitionRunning) {
// We have finished the animation of an app transition. To do
// this, we have delayed a lot of operations like showing and
@@ -8419,7 +8437,7 @@ public class WindowManagerService extends IWindowManager.Stub
// be out of sync with it. So here we will just rebuild the
// entire app window list. Fun!
mAppTransitionRunning = false;
- needRelayout = true;
+ mLayoutNeeded = true;
rebuildAppWindowListLocked();
assignLayersLocked();
// Clear information about apps that were moving.
@@ -8430,19 +8448,10 @@ public class WindowManagerService extends IWindowManager.Stub
mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
}
if (wallpaperDestroyed) {
- needRelayout = adjustWallpaperWindowsLocked() != 0;
- }
- if ((mPendingLayoutChanges & (
- WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER |
- ADJUST_WALLPAPER_LAYERS_CHANGED |
- WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG |
- WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) {
- needRelayout = true;
+ mLayoutNeeded |= adjustWallpaperWindowsLocked() != 0;
}
- if (needRelayout) {
- requestTraversalLocked();
- } else if (mAnimator.mAnimating) {
- scheduleAnimationLocked();
+ if (mPendingLayoutChanges != 0) {
+ mLayoutNeeded = true;
}
// Finally update all input windows now that the window changes have stabilized.
@@ -8485,7 +8494,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- if (mInnerFields.mOrientationChangeComplete && !needRelayout &&
+ if (mInnerFields.mOrientationChangeComplete && !mLayoutNeeded &&
!mInnerFields.mUpdateRotation) {
checkDrawnWindowsLocked();
}