diff options
author | Dianne Hackborn <hackbod@google.com> | 2010-03-10 16:51:13 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-03-10 16:51:13 -0800 |
commit | c3243e242d05f1f7b45964bf36aa4a56ed6ee66b (patch) | |
tree | 065e0e14fdb86de8d71dc83644f97fce84010db9 /services | |
parent | 0f344060096329f091af20a16d69547a47c1a9d5 (diff) | |
parent | b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55 (diff) | |
download | frameworks_base-c3243e242d05f1f7b45964bf36aa4a56ed6ee66b.zip frameworks_base-c3243e242d05f1f7b45964bf36aa4a56ed6ee66b.tar.gz frameworks_base-c3243e242d05f1f7b45964bf36aa4a56ed6ee66b.tar.bz2 |
Merge "Further improvements to window management!"
Diffstat (limited to 'services')
3 files changed, 328 insertions, 245 deletions
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java index 5f23a90..8103d7c 100644 --- a/services/java/com/android/server/UiModeManagerService.java +++ b/services/java/com/android/server/UiModeManagerService.java @@ -88,7 +88,9 @@ class UiModeManagerService extends IUiModeManager.Stub { private boolean mComputedNightMode; private int mCurUiMode = 0; + private int mSetUiMode = 0; + private boolean mHoldingConfiguration = false; private Configuration mConfiguration = new Configuration(); private boolean mSystemReady; @@ -114,25 +116,32 @@ class UiModeManagerService extends IUiModeManager.Stub { return; } - // Launch a dock activity - String category; - if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) { - // Only launch car home when car mode is enabled. - category = Intent.CATEGORY_CAR_DOCK; - } else if (UiModeManager.ACTION_ENTER_DESK_MODE.equals(intent.getAction())) { - category = Intent.CATEGORY_DESK_DOCK; - } else { - category = null; - } - if (category != null) { - intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(category); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - try { - mContext.startActivity(intent); - } catch (ActivityNotFoundException e) { - Slog.w(TAG, e.getCause()); + synchronized (mLock) { + // Launch a dock activity + String category; + if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) { + // Only launch car home when car mode is enabled. + category = Intent.CATEGORY_CAR_DOCK; + } else if (UiModeManager.ACTION_ENTER_DESK_MODE.equals(intent.getAction())) { + category = Intent.CATEGORY_DESK_DOCK; + } else { + category = null; + } + if (category != null) { + intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(category); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + try { + mContext.startActivity(intent); + } catch (ActivityNotFoundException e) { + Slog.w(TAG, e.getCause()); + } + } + + if (mHoldingConfiguration) { + mHoldingConfiguration = false; + updateConfigurationLocked(); } } } @@ -370,42 +379,46 @@ class UiModeManagerService extends IUiModeManager.Stub { } } - final void updateLocked() { - long ident = Binder.clearCallingIdentity(); - - try { - int uiMode = 0; - if (mCarModeEnabled) { - uiMode = Configuration.UI_MODE_TYPE_CAR; - } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) { - uiMode = Configuration.UI_MODE_TYPE_DESK; - } - if (uiMode != 0) { - if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) { - updateTwilightLocked(); - uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES - : Configuration.UI_MODE_NIGHT_NO; - } else { - uiMode |= mNightMode << 4; - } + final void updateConfigurationLocked() { + int uiMode = 0; + if (mCarModeEnabled) { + uiMode = Configuration.UI_MODE_TYPE_CAR; + } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) { + uiMode = Configuration.UI_MODE_TYPE_DESK; + } + if (uiMode != 0) { + if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) { + updateTwilightLocked(); + uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES + : Configuration.UI_MODE_NIGHT_NO; } else { - // Disabling the car mode clears the night mode. - uiMode = Configuration.UI_MODE_TYPE_NORMAL | - Configuration.UI_MODE_NIGHT_NO; + uiMode |= mNightMode << 4; } + } else { + // Disabling the car mode clears the night mode. + uiMode = Configuration.UI_MODE_TYPE_NORMAL | + Configuration.UI_MODE_NIGHT_NO; + } + + mCurUiMode = uiMode; + + if (!mHoldingConfiguration && uiMode != mSetUiMode) { + mSetUiMode = uiMode; - if (uiMode != mCurUiMode) { - mCurUiMode = uiMode; - - try { - final IActivityManager am = ActivityManagerNative.getDefault(); - mConfiguration.uiMode = uiMode; - am.updateConfiguration(mConfiguration); - } catch (RemoteException e) { - Slog.w(TAG, "Failure communicating with activity manager", e); - } + try { + final IActivityManager am = ActivityManagerNative.getDefault(); + mConfiguration.uiMode = uiMode; + am.updateConfiguration(mConfiguration); + } catch (RemoteException e) { + Slog.w(TAG, "Failure communicating with activity manager", e); } - + } + } + + final void updateLocked() { + long ident = Binder.clearCallingIdentity(); + + try { String action = null; String oldAction = null; if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_CAR) { @@ -450,7 +463,13 @@ class UiModeManagerService extends IUiModeManager.Stub { // placed into a dock. mContext.sendOrderedBroadcast(new Intent(action), null, mResultReceiver, null, Activity.RESULT_OK, null, null); + // Attempting to make this transition a little more clean, we are going + // to hold off on doing a configuration change until we have finished + // the broacast and started the home activity. + mHoldingConfiguration = true; } + + updateConfigurationLocked(); // keep screen on when charging and in car mode boolean keepScreenOn = mCharging && @@ -685,6 +704,8 @@ class UiModeManagerService extends IUiModeManager.Stub { pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled); pw.print(" mComputedNightMode="); pw.println(mComputedNightMode); pw.print(" mCurUiMode=0x"); pw.print(Integer.toHexString(mCurUiMode)); + pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode)); + pw.print(" mHoldingConfiguration="); pw.print(mHoldingConfiguration); pw.print(" mSystemReady="); pw.println(mSystemReady); if (mLocation != null) { pw.print(" mLocation="); pw.println(mLocation); diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 34a7fc0..989fe2a 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -43,6 +43,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import com.android.internal.app.IBatteryStats; import com.android.internal.policy.PolicyManager; +import com.android.internal.policy.impl.PhoneWindowManager; import com.android.internal.view.IInputContext; import com.android.internal.view.IInputMethodClient; import com.android.internal.view.IInputMethodManager; @@ -984,10 +985,15 @@ public class WindowManagerService extends IWindowManager.Stub //Slog.i(TAG, "Placing input method @" + (i+1)); if (w != null) { if (willMove) { - RuntimeException e = new RuntimeException(); - if (!HIDE_STACK_CRAWLS) e.fillInStackTrace(); - if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " - + mInputMethodTarget + " to " + w, e); + if (DEBUG_INPUT_METHOD) { + RuntimeException e = null; + if (!HIDE_STACK_CRAWLS) { + e = new RuntimeException(); + e.fillInStackTrace(); + } + Slog.w(TAG, "Moving IM target from " + + mInputMethodTarget + " to " + w, e); + } mInputMethodTarget = w; if (w.mAppToken != null) { setInputMethodAnimLayerAdjustment(w.mAppToken.animLayerAdjustment); @@ -998,10 +1004,15 @@ public class WindowManagerService extends IWindowManager.Stub return i+1; } if (willMove) { - RuntimeException e = new RuntimeException(); - if (!HIDE_STACK_CRAWLS) e.fillInStackTrace(); - if (DEBUG_INPUT_METHOD) Slog.w(TAG, "Moving IM target from " - + mInputMethodTarget + " to null", e); + if (DEBUG_INPUT_METHOD) { + RuntimeException e = null; + if (!HIDE_STACK_CRAWLS) { + e = new RuntimeException(); + e.fillInStackTrace(); + } + Slog.w(TAG, "Moving IM target from " + + mInputMethodTarget + " to null", e); + } mInputMethodTarget = null; setInputMethodAnimLayerAdjustment(0); } @@ -2178,6 +2189,16 @@ public class WindowManagerService extends IWindowManager.Stub } } + private static void logSurface(WindowState w, String msg, RuntimeException where) { + String str = " SURFACE " + Integer.toHexString(w.hashCode()) + + ": " + msg + " / " + w.mAttrs.getTitle(); + if (where != null) { + Slog.i(TAG, str, where); + } else { + Slog.i(TAG, str); + } + } + private void setTransparentRegionWindow(Session session, IWindow client, Region region) { long origId = Binder.clearCallingIdentity(); try { @@ -2187,9 +2208,8 @@ public class WindowManagerService extends IWindowManager.Stub if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION"); Surface.openTransaction(); try { - if (SHOW_TRANSACTIONS) Slog.i( - TAG, " SURFACE " + w.mSurface - + ": transparentRegionHint=" + region); + if (SHOW_TRANSACTIONS) logSurface(w, + "transparentRegionHint=" + region, null); w.mSurface.setTransparentRegionHint(region); } finally { if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION"); @@ -2654,8 +2674,11 @@ public class WindowManagerService extends IWindowManager.Stub + " isEntrance=" + isEntrance); if (a != null) { if (DEBUG_ANIM) { - RuntimeException e = new RuntimeException(); - if (!HIDE_STACK_CRAWLS) e.fillInStackTrace(); + RuntimeException e = null; + if (!HIDE_STACK_CRAWLS) { + e = new RuntimeException(); + e.fillInStackTrace(); + } Slog.v(TAG, "Loaded animation " + a + " for " + win, e); } win.setAnimation(a); @@ -2777,8 +2800,11 @@ public class WindowManagerService extends IWindowManager.Stub } if (a != null) { if (DEBUG_ANIM) { - RuntimeException e = new RuntimeException(); - if (!HIDE_STACK_CRAWLS) e.fillInStackTrace(); + RuntimeException e = null; + if (!HIDE_STACK_CRAWLS) { + e = new RuntimeException(); + e.fillInStackTrace(); + } Slog.v(TAG, "Loaded animation " + a + " for " + wtoken, e); } wtoken.setAnimation(a); @@ -3569,8 +3595,11 @@ public class WindowManagerService extends IWindowManager.Stub } if (DEBUG_APP_TRANSITIONS || DEBUG_ORIENTATION) { - RuntimeException e = new RuntimeException(); - if (!HIDE_STACK_CRAWLS) e.fillInStackTrace(); + RuntimeException e = null; + if (!HIDE_STACK_CRAWLS) { + e = new RuntimeException(); + e.fillInStackTrace(); + } Slog.v(TAG, "setAppVisibility(" + token + ", " + visible + "): mNextAppTransition=" + mNextAppTransition + " hidden=" + wtoken.hidden @@ -3671,8 +3700,11 @@ public class WindowManagerService extends IWindowManager.Stub public void startAppFreezingScreenLocked(AppWindowToken wtoken, int configChanges) { if (DEBUG_ORIENTATION) { - RuntimeException e = new RuntimeException(); - if (!HIDE_STACK_CRAWLS) e.fillInStackTrace(); + RuntimeException e = null; + if (!HIDE_STACK_CRAWLS) { + e = new RuntimeException(); + e.fillInStackTrace(); + } Slog.i(TAG, "Set freezing of " + wtoken.appToken + ": hidden=" + wtoken.hidden + " freezing=" + wtoken.freezingScreen, e); @@ -7305,7 +7337,8 @@ public class WindowManagerService extends IWindowManager.Stub + mSession.mSurfaceSession + ": pid=" + mSession.mPid + " format=" + mAttrs.format + " flags=0x" - + Integer.toHexString(flags)); + + Integer.toHexString(flags) + + " / " + this); } catch (Surface.OutOfResourcesException e) { Slog.w(TAG, "OutOfResourcesException creating surface"); reclaimSomeSurfaceMemoryLocked(this, "create"); @@ -7321,11 +7354,10 @@ public class WindowManagerService extends IWindowManager.Stub + ", animLayer=" + mAnimLayer); if (SHOW_TRANSACTIONS) { Slog.i(TAG, ">>> OPEN TRANSACTION"); - Slog.i(TAG, " SURFACE " + mSurface + ": CREATE (" - + mAttrs.getTitle() + ") pos=(" + - mFrame.left + "," + mFrame.top + ") (" + - mFrame.width() + "x" + mFrame.height() + "), layer=" + - mAnimLayer + " HIDE"); + if (SHOW_TRANSACTIONS) logSurface(this, + "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" + + mFrame.width() + "x" + mFrame.height() + "), layer=" + + mAnimLayer + " HIDE", null); } Surface.openTransaction(); try { @@ -7335,8 +7367,7 @@ public class WindowManagerService extends IWindowManager.Stub mSurface.setLayer(mAnimLayer); mSurface.hide(); if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) { - if (SHOW_TRANSACTIONS) Slog.i(TAG, " SURFACE " - + mSurface + ": DITHER"); + if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null); mSurface.setFlags(Surface.SURFACE_DITHER, Surface.SURFACE_DITHER); } @@ -7393,16 +7424,21 @@ public class WindowManagerService extends IWindowManager.Stub try { if (DEBUG_VISIBILITY) { - RuntimeException e = new RuntimeException(); - if (!HIDE_STACK_CRAWLS) e.fillInStackTrace(); + RuntimeException e = null; + if (!HIDE_STACK_CRAWLS) { + e = new RuntimeException(); + e.fillInStackTrace(); + } Slog.w(TAG, "Window " + this + " destroying surface " + mSurface + ", session " + mSession, e); } if (SHOW_TRANSACTIONS) { - RuntimeException ex = new RuntimeException(); - if (!HIDE_STACK_CRAWLS) ex.fillInStackTrace(); - Slog.i(TAG, " SURFACE " + mSurface + ": DESTROY (" - + mAttrs.getTitle() + ")", ex); + RuntimeException e = null; + if (!HIDE_STACK_CRAWLS) { + e = new RuntimeException(); + e.fillInStackTrace(); + } + if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e); } mSurface.destroy(); } catch (RuntimeException e) { @@ -7445,15 +7481,18 @@ public class WindowManagerService extends IWindowManager.Stub // This must be called while inside a transaction. boolean performShowLocked() { if (DEBUG_VISIBILITY) { - RuntimeException e = new RuntimeException(); - if (!HIDE_STACK_CRAWLS) e.fillInStackTrace(); + RuntimeException e = null; + if (!HIDE_STACK_CRAWLS) { + e = new RuntimeException(); + e.fillInStackTrace(); + } Slog.v(TAG, "performShow on " + this + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay() + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e); } if (mReadyToShow && isReadyForDisplay()) { - if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.i( - TAG, " SURFACE " + mSurface + ": SHOW (performShowLocked)"); + if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this, + "SHOW (performShowLocked)", null); if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this + " during animation: policyVis=" + mPolicyVisibility + " attHidden=" + mAttachedHidden @@ -7666,8 +7705,7 @@ public class WindowManagerService extends IWindowManager.Stub if (mSurface != null) { mDestroySurface.add(this); mDestroying = true; - if (SHOW_TRANSACTIONS) Slog.i( - TAG, " SURFACE " + mSurface + ": HIDE (finishExit)"); + if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null); try { mSurface.hide(); } catch (RuntimeException e) { @@ -7826,6 +7864,7 @@ public class WindowManagerService extends IWindowManager.Stub final AppWindowToken atoken = mAppToken; return mSurface != null && !mAttachedHidden && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested) + && !mDrawPending && !mCommitDrawPending && !mExiting && !mDestroying; } @@ -8045,6 +8084,18 @@ public class WindowManagerService extends IWindowManager.Stub return false; } if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this); + if (doAnimation) { + if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility=" + + mPolicyVisibility + " mAnimation=" + mAnimation); + if (mDisplayFrozen || !mPolicy.isScreenOn()) { + doAnimation = false; + } else if (mPolicyVisibility && mAnimation == null) { + // Check for the case where we are currently visible and + // not animating; we do not want to do animation at such a + // point to become visible when we already are. + doAnimation = false; + } + } mPolicyVisibility = true; mPolicyVisibilityAfterAnim = true; if (doAnimation) { @@ -8061,6 +8112,11 @@ public class WindowManagerService extends IWindowManager.Stub } boolean hideLw(boolean doAnimation, boolean requestAnim) { + if (doAnimation) { + if (mDisplayFrozen || !mPolicy.isScreenOn()) { + doAnimation = false; + } + } boolean current = doAnimation ? mPolicyVisibilityAfterAnim : mPolicyVisibility; if (!current) { @@ -8082,6 +8138,9 @@ public class WindowManagerService extends IWindowManager.Stub // for it to be displayed before enabling the display, that // we allow the display to be enabled now. enableScreenIfNeededLocked(); + if (mCurrentFocus == this) { + mFocusMayChange = true; + } } if (requestAnim) { requestAnimationLocked(0); @@ -9283,131 +9342,106 @@ public class WindowManagerService extends IWindowManager.Stub } } - private final void performLayoutLockedInner() { + private final int performLayoutLockedInner() { + if (!mLayoutNeeded) { + return 0; + } + + mLayoutNeeded = false; + final int dw = mDisplay.getWidth(); final int dh = mDisplay.getHeight(); final int N = mWindows.size(); - int repeats = 0; int i; if (DEBUG_LAYOUT) Slog.v(TAG, "performLayout: needed=" + mLayoutNeeded + " dw=" + dw + " dh=" + dh); - // FIRST LOOP: Perform a layout, if needed. + mPolicy.beginLayoutLw(dw, dh); - while (mLayoutNeeded) { - mPolicy.beginLayoutLw(dw, dh); - - int seq = mLayoutSeq+1; - if (seq < 0) seq = 0; - mLayoutSeq = seq; + int seq = mLayoutSeq+1; + if (seq < 0) seq = 0; + mLayoutSeq = seq; + + // First perform layout of any root windows (not attached + // to another window). + int topAttached = -1; + for (i = N-1; i >= 0; i--) { + WindowState win = (WindowState) mWindows.get(i); + + // Don't do layout of a window if it is not visible, or + // soon won't be visible, to avoid wasting time and funky + // changes while a window is animating away. + final AppWindowToken atoken = win.mAppToken; + final boolean gone = win.mViewVisibility == View.GONE + || !win.mRelayoutCalled + || win.mRootToken.hidden + || (atoken != null && atoken.hiddenRequested) + || win.mAttachedHidden + || win.mExiting || win.mDestroying; + + if (!win.mLayoutAttached) { + if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win + + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame + + " mLayoutAttached=" + win.mLayoutAttached); + if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility=" + + win.mViewVisibility + " mRelayoutCalled=" + + win.mRelayoutCalled + " hidden=" + + win.mRootToken.hidden + " hiddenRequested=" + + (atoken != null && atoken.hiddenRequested) + + " mAttachedHidden=" + win.mAttachedHidden); + } - // First perform layout of any root windows (not attached - // to another window). - int topAttached = -1; - for (i = N-1; i >= 0; i--) { - WindowState win = (WindowState) mWindows.get(i); - - // Don't do layout of a window if it is not visible, or - // soon won't be visible, to avoid wasting time and funky - // changes while a window is animating away. - final AppWindowToken atoken = win.mAppToken; - final boolean gone = win.mViewVisibility == View.GONE - || !win.mRelayoutCalled - || win.mRootToken.hidden - || (atoken != null && atoken.hiddenRequested) - || win.mAttachedHidden - || win.mExiting || win.mDestroying; - + // If this view is GONE, then skip it -- keep the current + // frame, and let the caller know so they can ignore it + // if they want. (We do the normal layout for INVISIBLE + // windows, since that means "perform layout as normal, + // just don't display"). + if (!gone || !win.mHaveFrame) { if (!win.mLayoutAttached) { - if (DEBUG_LAYOUT) Slog.v(TAG, "First pass " + win - + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame - + " mLayoutAttached=" + win.mLayoutAttached); - if (DEBUG_LAYOUT && gone) Slog.v(TAG, " (mViewVisibility=" - + win.mViewVisibility + " mRelayoutCalled=" - + win.mRelayoutCalled + " hidden=" - + win.mRootToken.hidden + " hiddenRequested=" - + (atoken != null && atoken.hiddenRequested) - + " mAttachedHidden=" + win.mAttachedHidden); - } - - // If this view is GONE, then skip it -- keep the current - // frame, and let the caller know so they can ignore it - // if they want. (We do the normal layout for INVISIBLE - // windows, since that means "perform layout as normal, - // just don't display"). - if (!gone || !win.mHaveFrame) { - if (!win.mLayoutAttached) { - mPolicy.layoutWindowLw(win, win.mAttrs, null); - win.mLayoutSeq = seq; - if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame=" - + win.mFrame + " mContainingFrame=" - + win.mContainingFrame + " mDisplayFrame=" - + win.mDisplayFrame); - } else { - if (topAttached < 0) topAttached = i; - } + mPolicy.layoutWindowLw(win, win.mAttrs, null); + win.mLayoutSeq = seq; + if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame=" + + win.mFrame + " mContainingFrame=" + + win.mContainingFrame + " mDisplayFrame=" + + win.mDisplayFrame); + } else { + if (topAttached < 0) topAttached = i; } } + } - // Now perform layout of attached windows, which usually - // depend on the position of the window they are attached to. - // XXX does not deal with windows that are attached to windows - // that are themselves attached. - for (i = topAttached; i >= 0; i--) { - WindowState win = (WindowState) mWindows.get(i); + // Now perform layout of attached windows, which usually + // depend on the position of the window they are attached to. + // XXX does not deal with windows that are attached to windows + // that are themselves attached. + for (i = topAttached; i >= 0; i--) { + WindowState win = (WindowState) mWindows.get(i); - // If this view is GONE, then skip it -- keep the current - // frame, and let the caller know so they can ignore it - // if they want. (We do the normal layout for INVISIBLE - // windows, since that means "perform layout as normal, - // just don't display"). - if (win.mLayoutAttached) { - if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win - + " mHaveFrame=" + win.mHaveFrame - + " mViewVisibility=" + win.mViewVisibility - + " mRelayoutCalled=" + win.mRelayoutCalled); - if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled) - || !win.mHaveFrame) { - mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow); - win.mLayoutSeq = seq; - if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame=" - + win.mFrame + " mContainingFrame=" - + win.mContainingFrame + " mDisplayFrame=" - + win.mDisplayFrame); - } - } - } - - int changes = mPolicy.finishLayoutLw(); - if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) { - if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) { - assignLayersLocked(); - } - } - if (changes == 0) { - mLayoutNeeded = false; - } else if (repeats > 2) { - Slog.w(TAG, "Layout repeat aborted after too many iterations"); - mLayoutNeeded = false; - if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) { - if (updateOrientationFromAppTokensLocked()) { - mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); - } - } - } else { - if (DEBUG_LAYOUT) Slog.v(TAG, "Repeating layout because changes=0x" - + Integer.toHexString(changes)); - repeats++; - if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) { - if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout"); - if (updateOrientationFromAppTokensLocked()) { - mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); - } + // If this view is GONE, then skip it -- keep the current + // frame, and let the caller know so they can ignore it + // if they want. (We do the normal layout for INVISIBLE + // windows, since that means "perform layout as normal, + // just don't display"). + if (win.mLayoutAttached) { + if (DEBUG_LAYOUT) Slog.v(TAG, "Second pass " + win + + " mHaveFrame=" + win.mHaveFrame + + " mViewVisibility=" + win.mViewVisibility + + " mRelayoutCalled=" + win.mRelayoutCalled); + if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled) + || !win.mHaveFrame) { + mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow); + win.mLayoutSeq = seq; + if (DEBUG_LAYOUT) Slog.v(TAG, "-> mFrame=" + + win.mFrame + " mContainingFrame=" + + win.mContainingFrame + " mDisplayFrame=" + + win.mDisplayFrame); } } } + + return mPolicy.finishLayoutLw(); } private final void performLayoutAndPlaceSurfacesLockedInner( @@ -9423,9 +9457,6 @@ public class WindowManagerService extends IWindowManager.Stub updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES); } - // FIRST LOOP: Perform a layout, if needed. - performLayoutLockedInner(); - if (mFxSession == null) { mFxSession = new SurfaceSession(); } @@ -9442,7 +9473,6 @@ public class WindowManagerService extends IWindowManager.Stub mExitingAppTokens.get(i).hasVisible = false; } - // SECOND LOOP: Execute animations and update visibility of windows. boolean orientationChangeComplete = true; Session holdScreen = null; float screenBrightness = -1; @@ -9452,11 +9482,50 @@ public class WindowManagerService extends IWindowManager.Stub Surface.openTransaction(); try { - boolean restart; - boolean forceHiding = false; boolean wallpaperForceHidingChanged = false; - + int repeats = 0; + int changes = 0; + do { + repeats++; + if (repeats > 6) { + Slog.w(TAG, "Animation repeat aborted after too many iterations"); + mLayoutNeeded = false; + break; + } + + if ((changes&(WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER + | WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG + | WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT)) != 0) { + if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) { + if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) { + assignLayersLocked(); + mLayoutNeeded = true; + } + } + if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG) != 0) { + if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout"); + if (updateOrientationFromAppTokensLocked()) { + mLayoutNeeded = true; + mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION); + } + } + if ((changes&WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT) != 0) { + mLayoutNeeded = true; + } + } + + // FIRST LOOP: Perform a layout, if needed. + if (repeats < 4) { + changes = performLayoutLockedInner(); + if (changes != 0) { + continue; + } + } else { + Slog.w(TAG, "Layout repeat skipped after too many iterations"); + changes = 0; + } + final int transactionSequence = ++mTransactionSequence; // Update animations of all applications, including those @@ -9475,15 +9544,17 @@ public class WindowManagerService extends IWindowManager.Stub } } + // SECOND LOOP: Execute animations and update visibility of windows. + if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq=" + transactionSequence + " tokensAnimating=" + tokensAnimating); animating = tokensAnimating; - restart = false; boolean tokenMayBeDrawn = false; boolean wallpaperMayChange = false; + boolean forceHiding = false; mPolicy.beginAnimationLw(dw, dh); @@ -9536,7 +9607,7 @@ public class WindowManagerService extends IWindowManager.Stub "Now policy shown: " + w); if (changed) { if (wallpaperForceHidingChanged - && w.isReadyForDisplay()) { + && w.isVisibleNow() /*w.isReadyForDisplay()*/) { // Assume we will need to animate. If // we don't (because the wallpaper will // stay with the lock screen), then we will @@ -9609,9 +9680,7 @@ public class WindowManagerService extends IWindowManager.Stub } } - if (mPolicy.finishAnimationLw()) { - restart = true; - } + changes |= mPolicy.finishAnimationLw(); if (tokenMayBeDrawn) { // See if any windows have been drawn, so they (and others @@ -9641,7 +9710,7 @@ public class WindowManagerService extends IWindowManager.Stub + " interesting=" + numInteresting + " drawn=" + wtoken.numDrawnWindows); wtoken.allDrawn = true; - restart = true; + changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM; // We can now show all of the drawn windows! if (!mOpeningApps.contains(wtoken)) { @@ -9856,15 +9925,13 @@ public class WindowManagerService extends IWindowManager.Stub // This has changed the visibility of windows, so perform // a new layout to get them all up-to-date. + changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT; mLayoutNeeded = true; if (!moveInputMethodWindowsIfNeededLocked(true)) { assignLayersLocked(); } - performLayoutLockedInner(); updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES); mFocusMayChange = false; - - restart = true; } } @@ -9880,10 +9947,9 @@ public class WindowManagerService extends IWindowManager.Stub mToBottomApps.clear(); rebuildAppWindowListLocked(); - restart = true; + changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT; moveInputMethodWindowsIfNeededLocked(false); wallpaperMayChange = true; - mLayoutNeeded = true; // Since the window list has been rebuilt, focus might // have to be recomputed since the actual order of windows // might have changed again. @@ -9892,7 +9958,7 @@ public class WindowManagerService extends IWindowManager.Stub int adjResult = 0; - if (wallpaperForceHidingChanged && !restart && !mAppTransitionReady) { + if (wallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) { // At this point, there was a window with a wallpaper that // was force hiding other windows behind it, but now it // is going away. This may be simple -- just animate @@ -9913,7 +9979,7 @@ public class WindowManagerService extends IWindowManager.Stub // actually started the animation... let's completely // re-evaluate everything. mLowerWallpaperTarget = mUpperWallpaperTarget = null; - restart = true; + changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM; } } adjResult = adjustWallpaperWindowsLocked(); @@ -9954,33 +10020,30 @@ public class WindowManagerService extends IWindowManager.Stub if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) { if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper layer changed: assigning layers + relayout"); - restart = true; - mLayoutNeeded = true; + changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT; assignLayersLocked(); } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) { if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility changed: relayout"); - restart = true; - mLayoutNeeded = true; + changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT; } if (mFocusMayChange) { mFocusMayChange = false; if (updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES)) { - restart = true; + changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM; adjResult = 0; } } if (mLayoutNeeded) { - restart = true; - performLayoutLockedInner(); + changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT; } - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: restart=" - + restart); + if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: changes=0x" + + Integer.toHexString(changes)); - } while (restart); + } while (changes != 0); // THIRD LOOP: Update the surfaces of all windows. @@ -10022,10 +10085,9 @@ public class WindowManagerService extends IWindowManager.Stub w.mLastRequestedHeight = height; w.mLastShownFrame.set(w.mShownFrame); try { - if (SHOW_TRANSACTIONS) Slog.i( - TAG, " SURFACE " + w.mSurface - + ": POS " + w.mShownFrame.left - + ", " + w.mShownFrame.top); + if (SHOW_TRANSACTIONS) logSurface(w, + "POS " + w.mShownFrame.left + + ", " + w.mShownFrame.top, null); w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top); } catch (RuntimeException e) { Slog.w(TAG, "Error positioning surface in " + w, e); @@ -10045,12 +10107,11 @@ public class WindowManagerService extends IWindowManager.Stub if (height < 1) height = 1; if (w.mSurface != null) { try { - if (SHOW_TRANSACTIONS) Slog.i( - TAG, " SURFACE " + w.mSurface + ": POS " - + w.mShownFrame.left + "," + if (SHOW_TRANSACTIONS) logSurface(w, + "POS " + w.mShownFrame.left + "," + w.mShownFrame.top + " SIZE " + w.mShownFrame.width() + "x" - + w.mShownFrame.height()); + + w.mShownFrame.height(), null); w.mSurface.setSize(width, height); w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top); @@ -10136,8 +10197,8 @@ public class WindowManagerService extends IWindowManager.Stub if (!w.mLastHidden) { //dump(); w.mLastHidden = true; - if (SHOW_TRANSACTIONS) Slog.i( - TAG, " SURFACE " + w.mSurface + ": HIDE (performLayout)"); + if (SHOW_TRANSACTIONS) logSurface(w, + "HIDE (performLayout)", null); if (w.mSurface != null) { try { w.mSurface.hide(); @@ -10176,13 +10237,12 @@ public class WindowManagerService extends IWindowManager.Stub w.mLastDtDy = w.mDtDy; w.mLastHScale = w.mHScale; w.mLastVScale = w.mVScale; - if (SHOW_TRANSACTIONS) Slog.i( - TAG, " SURFACE " + w.mSurface + ": alpha=" - + w.mShownAlpha + " layer=" + w.mAnimLayer + if (SHOW_TRANSACTIONS) logSurface(w, + "alpha=" + w.mShownAlpha + " layer=" + w.mAnimLayer + " matrix=[" + (w.mDsDx*w.mHScale) + "," + (w.mDtDx*w.mVScale) + "][" + (w.mDsDy*w.mHScale) - + "," + (w.mDtDy*w.mVScale) + "]"); + + "," + (w.mDtDy*w.mVScale) + "]", null); if (w.mSurface != null) { try { w.mSurface.setAlpha(w.mShownAlpha); @@ -10201,8 +10261,8 @@ public class WindowManagerService extends IWindowManager.Stub if (w.mLastHidden && !w.mDrawPending && !w.mCommitDrawPending && !w.mReadyToShow) { - if (SHOW_TRANSACTIONS) Slog.i( - TAG, " SURFACE " + w.mSurface + ": SHOW (performLayout)"); + if (SHOW_TRANSACTIONS) logSurface(w, + "SHOW (performLayout)", null); if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w + " during relayout"); if (showSurfaceRobustlyLocked(w)) { diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index b53100f..f6289ae 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -13226,9 +13226,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen ac.updateConfiguration(mConfiguration); } - Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); - msg.obj = new Configuration(mConfiguration); - mHandler.sendMessage(msg); + if (Settings.System.hasInterestingConfigurationChanges(changes)) { + Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); + msg.obj = new Configuration(mConfiguration); + mHandler.sendMessage(msg); + } for (int i=mLruProcesses.size()-1; i>=0; i--) { ProcessRecord app = mLruProcesses.get(i); |