diff options
author | Craig Mautner <cmautner@google.com> | 2012-12-28 17:14:38 -0800 |
---|---|---|
committer | Craig Mautner <cmautner@google.com> | 2013-01-08 00:22:22 -0800 |
commit | 1420b93fa5606979fd67eaf80f50294d4f8c191b (patch) | |
tree | dae8e33d3f9e660398e3215b6eaf165d92756285 /services | |
parent | a22f980f993876570eab8297d3c2207c7fe3d65e (diff) | |
download | frameworks_base-1420b93fa5606979fd67eaf80f50294d4f8c191b.zip frameworks_base-1420b93fa5606979fd67eaf80f50294d4f8c191b.tar.gz frameworks_base-1420b93fa5606979fd67eaf80f50294d4f8c191b.tar.bz2 |
Combine DimAnimator and DimSurface into DimLayer
Replace two classes that did similar things in a complicated manner
with one class that does it more simply.
Bug 7064755 fixed.
Change-Id: I8c415671f60d1d2ece9da5916421f4d24aed2d65
Diffstat (limited to 'services')
6 files changed, 342 insertions, 462 deletions
diff --git a/services/java/com/android/server/wm/DimAnimator.java b/services/java/com/android/server/wm/DimAnimator.java deleted file mode 100644 index 5874202..0000000 --- a/services/java/com/android/server/wm/DimAnimator.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wm; - -import android.content.res.Resources; -import android.graphics.PixelFormat; -import android.util.Slog; -import android.util.TypedValue; -import android.view.Surface; -import android.view.SurfaceSession; - -import java.io.PrintWriter; - -/** - * DimAnimator class that controls the dim animation. This holds the surface and - * all state used for dim animation. - */ -class DimAnimator { - static final String TAG = "DimAnimator"; - - Surface mDimSurface; - boolean mDimShown = false; - float mDimCurrentAlpha; - float mDimTargetAlpha; - float mDimDeltaPerMs; - long mLastDimAnimTime; - - int mLastDimWidth, mLastDimHeight; - - DimAnimator (SurfaceSession session, final int layerStack) { - try { - if (WindowManagerService.DEBUG_SURFACE_TRACE) { - mDimSurface = new WindowStateAnimator.SurfaceTrace(session, - "DimAnimator", - 16, 16, PixelFormat.OPAQUE, - Surface.FX_SURFACE_DIM | Surface.HIDDEN); - } else { - mDimSurface = new Surface(session, "DimAnimator", - 16, 16, PixelFormat.OPAQUE, - Surface.FX_SURFACE_DIM | Surface.HIDDEN); - } - if (WindowManagerService.SHOW_TRANSACTIONS || - WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG, - " DIM " + mDimSurface + ": CREATE"); - mDimSurface.setLayerStack(layerStack); - mDimSurface.setAlpha(0.0f); - mDimSurface.show(); - } catch (Exception e) { - Slog.e(WindowManagerService.TAG, "Exception creating Dim surface", e); - } - } - - /** - * Set's the dim surface's layer and update dim parameters that will be used in - * {@link #updateSurface} after all windows are examined. - */ - void updateParameters(final Resources res, final Parameters params, final long currentTime) { - if (mDimSurface == null) { - Slog.e(TAG, "updateParameters: no Surface"); - return; - } - - // Multiply by 1.5 so that rotating a frozen surface that includes this does not expose a - // corner. - final int dw = (int) (params.mDimWidth * 1.5); - final int dh = (int) (params.mDimHeight * 1.5); - final WindowStateAnimator winAnimator = params.mDimWinAnimator; - final float target = params.mDimTarget; - if (!mDimShown) { - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, - " DIM " + mDimSurface + ": SHOW pos=(0,0) (" + dw + "x" + dh + ")"); - mDimShown = true; - try { - mLastDimWidth = dw; - mLastDimHeight = dh; - // back off position so mDimXXX/4 is before and mDimXXX/4 is after - mDimSurface.setPosition(-1 * dw / 6, -1 * dh /6); - mDimSurface.setSize(dw, dh); - mDimSurface.show(); - } catch (RuntimeException e) { - Slog.w(WindowManagerService.TAG, "Failure showing dim surface", e); - } - } else if (mLastDimWidth != dw || mLastDimHeight != dh) { - mLastDimWidth = dw; - mLastDimHeight = dh; - mDimSurface.setSize(dw, dh); - // back off position so mDimXXX/4 is before and mDimXXX/4 is after - mDimSurface.setPosition(-1 * dw / 6, -1 * dh /6); - } - - mDimSurface.setLayer(winAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM); - - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " - + mDimSurface + ": layer=" + (winAnimator.mAnimLayer-1) + " target=" + target); - if (mDimTargetAlpha != target) { - // If the desired dim level has changed, then - // start an animation to it. - mLastDimAnimTime = currentTime; - long duration = (winAnimator.mAnimating && winAnimator.mAnimation != null) - ? winAnimator.mAnimation.computeDurationHint() - : WindowManagerService.DEFAULT_DIM_DURATION; - if (target > mDimTargetAlpha) { - TypedValue tv = new TypedValue(); - res.getValue(com.android.internal.R.fraction.config_dimBehindFadeDuration, - tv, true); - if (tv.type == TypedValue.TYPE_FRACTION) { - duration = (long)tv.getFraction(duration, duration); - } else if (tv.type >= TypedValue.TYPE_FIRST_INT - && tv.type <= TypedValue.TYPE_LAST_INT) { - duration = tv.data; - } - } - if (duration < 1) { - // Don't divide by zero - duration = 1; - } - mDimTargetAlpha = target; - mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration; - } - } - - /** - * Updating the surface's alpha. Returns true if the animation continues, or returns - * false when the animation is finished and the dim surface is hidden. - */ - boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) { - if (mDimSurface == null) { - Slog.e(TAG, "updateSurface: no Surface"); - return false; - } - - if (!dimming) { - if (mDimTargetAlpha != 0) { - mLastDimAnimTime = currentTime; - mDimTargetAlpha = 0; - mDimDeltaPerMs = (-mDimCurrentAlpha) / WindowManagerService.DEFAULT_DIM_DURATION; - } - } - - boolean animating = mLastDimAnimTime != 0; - if (animating) { - mDimCurrentAlpha += mDimDeltaPerMs - * (currentTime-mLastDimAnimTime); - if (displayFrozen) { - // If the display is frozen, there is no reason to animate. - animating = false; - } else if (mDimDeltaPerMs > 0) { - if (mDimCurrentAlpha > mDimTargetAlpha) { - animating = false; - } - } else if (mDimDeltaPerMs < 0) { - if (mDimCurrentAlpha < mDimTargetAlpha) { - animating = false; - } - } else { - animating = false; - } - - // Do we need to continue animating? - if (animating) { - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " - + mDimSurface + ": alpha=" + mDimCurrentAlpha); - mLastDimAnimTime = currentTime; - mDimSurface.setAlpha(mDimCurrentAlpha); - } else { - mDimCurrentAlpha = mDimTargetAlpha; - mLastDimAnimTime = 0; - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " - + mDimSurface + ": final alpha=" + mDimCurrentAlpha); - mDimSurface.setAlpha(mDimCurrentAlpha); - if (!dimming) { - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface - + ": HIDE"); - try { - mDimSurface.hide(); - } catch (RuntimeException e) { - Slog.w(WindowManagerService.TAG, "Illegal argument exception hiding dim surface"); - } - mDimShown = false; - } - } - } - return animating; - } - - public void kill() { - if (mDimSurface != null) { - mDimSurface.destroy(); - mDimSurface = null; - } - } - - public void printTo(String prefix, PrintWriter pw) { - pw.print(prefix); - pw.print("mDimSurface="); pw.print(mDimSurface); - pw.print(" "); pw.print(mLastDimWidth); pw.print(" x "); - pw.println(mLastDimHeight); - pw.print(prefix); - pw.print("mDimShown="); pw.print(mDimShown); - pw.print(" current="); pw.print(mDimCurrentAlpha); - pw.print(" target="); pw.print(mDimTargetAlpha); - pw.print(" delta="); pw.print(mDimDeltaPerMs); - pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime); - } - - static class Parameters { - final WindowStateAnimator mDimWinAnimator; - final int mDimWidth; - final int mDimHeight; - final float mDimTarget; - Parameters(final WindowStateAnimator dimWinAnimator, final int dimWidth, - final int dimHeight, final float dimTarget) { - mDimWinAnimator = dimWinAnimator; - mDimWidth = dimWidth; - mDimHeight = dimHeight; - mDimTarget = dimTarget; - } - - Parameters(Parameters o) { - mDimWinAnimator = o.mDimWinAnimator; - mDimWidth = o.mDimWidth; - mDimHeight = o.mDimHeight; - mDimTarget = o.mDimTarget; - } - - public void printTo(String prefix, PrintWriter pw) { - pw.print(prefix); - pw.print("mDimWinAnimator="); pw.print(mDimWinAnimator.mWin.mAttrs.getTitle()); - pw.print(" "); pw.print(mDimWidth); pw.print(" x "); - pw.print(mDimHeight); - pw.print(" mDimTarget="); pw.println(mDimTarget); - } - } -} diff --git a/services/java/com/android/server/wm/DimLayer.java b/services/java/com/android/server/wm/DimLayer.java new file mode 100644 index 0000000..162caf5 --- /dev/null +++ b/services/java/com/android/server/wm/DimLayer.java @@ -0,0 +1,257 @@ +// Copyright 2012 Google Inc. All Rights Reserved. + +package com.android.server.wm; + +import android.graphics.PixelFormat; +import android.os.SystemClock; +import android.util.Slog; +import android.view.DisplayInfo; +import android.view.Surface; + +import java.io.PrintWriter; + +public class DimLayer { + private static final String TAG = "DimLayer"; + private static final boolean DEBUG = true; + + /** Reference to the owner of this object. */ + final DisplayContent mDisplayContent; + + /** Actual surface that dims */ + Surface mDimSurface; + + /** Last value passed to mDimSurface.setAlpha() */ + float mAlpha = 0; + + /** Last value passed to mDimSurface.setLayer() */ + int mLayer = -1; + + /** Last values passed to mDimSurface.setSize() */ + int mLastDimWidth, mLastDimHeight; + + /** True after mDimSurface.show() has been called, false after mDimSurface.hide(). */ + private boolean mShowing = false; + + /** Value of mAlpha when beginning transition to mTargetAlpha */ + float mStartAlpha = 0; + + /** Final value of mAlpha following transition */ + float mTargetAlpha = 0; + + /** Time in units of SystemClock.uptimeMillis() at which the current transition started */ + long mStartTime; + + /** Time in milliseconds to take to transition from mStartAlpha to mTargetAlpha */ + long mDuration; + + DimLayer(WindowManagerService service, int displayId) { + if (DEBUG) Slog.v(TAG, "Ctor: displayId=" + displayId); + mDisplayContent = service.getDisplayContentLocked(displayId); + Surface.openTransaction(); + try { + if (WindowManagerService.DEBUG_SURFACE_TRACE) { + mDimSurface = new WindowStateAnimator.SurfaceTrace(service.mFxSession, + "DimSurface", + 16, 16, PixelFormat.OPAQUE, + Surface.FX_SURFACE_DIM | Surface.HIDDEN); + } else { + mDimSurface = new Surface(service.mFxSession, TAG, + 16, 16, PixelFormat.OPAQUE, + Surface.FX_SURFACE_DIM | Surface.HIDDEN); + } + if (WindowManagerService.SHOW_TRANSACTIONS || + WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(TAG, + " DIM " + mDimSurface + ": CREATE"); + mDimSurface.setLayerStack(displayId); + } catch (Exception e) { + Slog.e(WindowManagerService.TAG, "Exception creating Dim surface", e); + } finally { + Surface.closeTransaction(); + } + } + + /** Return true if dim layer is showing */ + boolean isDimming() { + return mTargetAlpha != 0; + } + + /** Return true if in a transition period */ + boolean isAnimating() { + return mTargetAlpha != mAlpha; + } + + float getTargetAlpha() { + return mTargetAlpha; + } + + private void setAlpha(float alpha) { + if (mAlpha != alpha) { + if (DEBUG) Slog.v(TAG, "setAlpha alpha=" + alpha); + try { + mDimSurface.setAlpha(alpha); + if (alpha == 0 && mShowing) { + if (DEBUG) Slog.v(TAG, "setAlpha hiding"); + mDimSurface.hide(); + mShowing = false; + } else if (alpha > 0 && !mShowing) { + if (DEBUG) Slog.v(TAG, "setAlpha showing"); + mDimSurface.show(); + mShowing = true; + } + } catch (RuntimeException e) { + Slog.w(TAG, "Failure setting alpha immediately", e); + } + mAlpha = alpha; + } + } + + /** + * @param duration The time to test. + * @return True if the duration would lead to an earlier end to the current animation. + */ + private boolean durationEndsEarlier(long duration) { + return SystemClock.uptimeMillis() + duration < mStartTime + mDuration; + } + + /** Jump to the end of the animation. + * NOTE: Must be called with Surface transaction open. */ + void show() { + if (isAnimating()) { + if (DEBUG) Slog.v(TAG, "show: immediate"); + show(mLayer, mTargetAlpha, 0); + } + } + + /** + * Begin an animation to a new dim value. + * NOTE: Must be called with Surface transaction open. + * + * @param layer The layer to set the surface to. + * @param alpha The dim value to end at. + * @param duration How long to take to get there in milliseconds. + */ + void show(int layer, float alpha, long duration) { + if (DEBUG) Slog.v(TAG, "show: layer=" + layer + " alpha=" + alpha + + " duration=" + duration); + if (mDimSurface == null) { + Slog.e(TAG, "show: no Surface"); + // Make sure isAnimating() returns false. + mTargetAlpha = mAlpha = 0; + return; + } + + // Set surface size to screen size. + final DisplayInfo info = mDisplayContent.getDisplayInfo(); + // Multiply by 1.5 so that rotating a frozen surface that includes this does not expose a + // corner. + final int dw = (int) (info.logicalWidth * 1.5); + final int dh = (int) (info.logicalHeight * 1.5); + // back off position so 1/4 of Surface is before and 1/4 is after. + final float xPos = -1 * dw / 6; + final float yPos = -1 * dh / 6; + + if (mLastDimWidth != dw || mLastDimHeight != dh || mLayer != layer) { + try { + mDimSurface.setPosition(xPos, yPos); + mDimSurface.setSize(dw, dh); + mDimSurface.setLayer(layer); + } catch (RuntimeException e) { + Slog.w(TAG, "Failure setting size or layer", e); + } + mLastDimWidth = dw; + mLastDimHeight = dh; + mLayer = layer; + } + + long curTime = SystemClock.uptimeMillis(); + final boolean animating = isAnimating(); + if ((animating && (mTargetAlpha != alpha || durationEndsEarlier(duration))) + || (!animating && mAlpha != alpha)) { + if (duration <= 0) { + // No animation required, just set values. + setAlpha(alpha); + } else { + // Start or continue animation with new parameters. + mStartAlpha = mAlpha; + mStartTime = curTime; + mDuration = duration; + } + } + if (DEBUG) Slog.v(TAG, "show: mStartAlpha=" + mStartAlpha + " mStartTime=" + mStartTime); + mTargetAlpha = alpha; + } + + /** Immediate hide. + * NOTE: Must be called with Surface transaction open. */ + void hide() { + if (mShowing) { + if (DEBUG) Slog.v(TAG, "hide: immediate"); + hide(0); + } + } + + /** + * Gradually fade to transparent. + * NOTE: Must be called with Surface transaction open. + * + * @param duration Time to fade in milliseconds. + */ + void hide(long duration) { + if (mShowing && (mTargetAlpha != 0 || durationEndsEarlier(duration))) { + if (DEBUG) Slog.v(TAG, "hide: duration=" + duration); + show(mLayer, 0, duration); + } + } + + /** + * Advance the dimming per the last #show(int, float, long) call. + * NOTE: Must be called with Surface transaction open. + * + * @return True if animation is still required after this step. + */ + boolean stepAnimation() { + if (mDimSurface == null) { + Slog.e(TAG, "stepAnimation: null Surface"); + // Ensure that isAnimating() returns false; + mTargetAlpha = mAlpha = 0; + return false; + } + + if (isAnimating()) { + final long curTime = SystemClock.uptimeMillis(); + final float alphaDelta = mTargetAlpha - mStartAlpha; + float alpha = mStartAlpha + alphaDelta * (curTime - mStartTime) / mDuration; + if (alphaDelta > 0 && alpha > mTargetAlpha || + alphaDelta < 0 && alpha < mTargetAlpha) { + // Don't exceed limits. + alpha = mTargetAlpha; + } + if (DEBUG) Slog.v(TAG, "stepAnimation: curTime=" + curTime + " alpha=" + alpha); + setAlpha(alpha); + } + + return isAnimating(); + } + + /** Cleanup */ + void destroySurface() { + if (DEBUG) Slog.v(TAG, "destroySurface."); + if (mDimSurface != null) { + mDimSurface.destroy(); + mDimSurface = null; + } + } + + public void printTo(String prefix, PrintWriter pw) { + pw.print(prefix); pw.print("mDimSurface="); pw.println(mDimSurface); + pw.print(prefix); pw.print(" mLayer="); pw.print(mLayer); + pw.print(" mAlpha="); pw.println(mAlpha); + pw.print(prefix); pw.print("mLastDimWidth="); pw.print(mLastDimWidth); + pw.print(" mLastDimWidth="); pw.println(mLastDimWidth); + pw.print(prefix); pw.print("Last animation: mStartTime="); pw.print(mStartTime); + pw.print(" mDuration="); pw.print(mDuration); + pw.print(" curTime="); pw.println(SystemClock.uptimeMillis()); + pw.print(" mStartAlpha="); pw.println(mStartAlpha); + pw.print(" mTargetAlpha="); pw.print(mTargetAlpha); + } +} diff --git a/services/java/com/android/server/wm/DimSurface.java b/services/java/com/android/server/wm/DimSurface.java deleted file mode 100644 index 511d388..0000000 --- a/services/java/com/android/server/wm/DimSurface.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wm; - -import android.graphics.PixelFormat; -import android.util.Slog; -import android.view.DisplayInfo; -import android.view.Surface; -import android.view.SurfaceSession; - -import java.io.PrintWriter; - -class DimSurface { - static final String TAG = "DimSurface"; - - Surface mDimSurface; - boolean mDimShown = false; - int mDimColor = 0; - int mLayer = -1; - int mLastDimWidth, mLastDimHeight; - final DisplayContent mDisplayContent; - - DimSurface(SurfaceSession session, DisplayContent displayContent) { - mDisplayContent = displayContent; - final int layerStack = displayContent.getDisplayId(); - try { - if (WindowManagerService.DEBUG_SURFACE_TRACE) { - mDimSurface = new WindowStateAnimator.SurfaceTrace(session, - "DimSurface", - 16, 16, PixelFormat.OPAQUE, - Surface.FX_SURFACE_DIM | Surface.HIDDEN); - } else { - mDimSurface = new Surface(session, "DimSurface", - 16, 16, PixelFormat.OPAQUE, - Surface.FX_SURFACE_DIM | Surface.HIDDEN); - } - if (WindowManagerService.SHOW_TRANSACTIONS || - WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG, - " DIM " + mDimSurface + ": CREATE"); - mDimSurface.setLayerStack(layerStack); - mDimSurface.setAlpha(0.0f); - mDimSurface.show(); - } catch (Exception e) { - Slog.e(WindowManagerService.TAG, "Exception creating Dim surface", e); - } - } - - /** - * Show the dim surface. - */ - void show(int layer, int color) { - final DisplayInfo info = mDisplayContent.getDisplayInfo(); - final int dw = info.logicalWidth; - final int dh = info.logicalHeight; - if (mDimSurface == null) { - Slog.e(TAG, "show: no Surface"); - return; - } - - if (!mDimShown) { - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" + - dw + "x" + dh + " layer=" + layer + ")"); - mDimShown = true; - try { - mLastDimWidth = dw; - mLastDimHeight = dh; - mDimSurface.setPosition(0, 0); - mDimSurface.setSize(dw, dh); - mDimSurface.setLayer(layer); - mDimSurface.show(); - } catch (RuntimeException e) { - Slog.w(WindowManagerService.TAG, "Failure showing dim surface", e); - } - } else if (mLastDimWidth != dw || mLastDimHeight != dh || mDimColor != color - || mLayer != layer) { - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface + ": pos=(0,0) (" + - dw + "x" + dh + " layer=" + layer + ")"); - mLastDimWidth = dw; - mLastDimHeight = dh; - mLayer = layer; - mDimColor = color; - mDimSurface.setSize(dw, dh); - mDimSurface.setLayer(layer); - mDimSurface.setAlpha(((color>>24)&0xff)/255.0f); - } - } - - void hide() { - if (mDimSurface == null) { - Slog.e(TAG, "hide: no Surface"); - return; - } - - if (mDimShown) { - mDimShown = false; - try { - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " HIDE " + mDimSurface); - mDimSurface.hide(); - } catch (RuntimeException e) { - Slog.w(WindowManagerService.TAG, "Illegal argument exception hiding dim surface"); - } - } - } - - void kill() { - if (mDimSurface != null) { - mDimSurface.destroy(); - mDimSurface = null; - } - } - - public void printTo(String prefix, PrintWriter pw) { - pw.print(prefix); pw.print("mDimSurface="); pw.println(mDimSurface); - pw.print(prefix); pw.print("mDimShown="); pw.print(mDimShown); - pw.print(" mLayer="); pw.print(mLayer); - pw.print(" mDimColor=0x"); pw.println(Integer.toHexString(mDimColor)); - pw.print(prefix); pw.print("mLastDimWidth="); pw.print(mLastDimWidth); - pw.print(" mLastDimWidth="); pw.println(mLastDimWidth); - } -} diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java index a9f3c0f..d5144fb 100644 --- a/services/java/com/android/server/wm/WindowAnimator.java +++ b/services/java/com/android/server/wm/WindowAnimator.java @@ -19,6 +19,7 @@ import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.TimeUtils; +import android.util.TypedValue; import android.view.Display; import android.view.Surface; import android.view.WindowManagerPolicy; @@ -37,6 +38,10 @@ import java.util.ArrayList; public class WindowAnimator { private static final String TAG = "WindowAnimator"; + /** Amount of time in milliseconds to animate the dim surface from one value to another, + * when no window animation is driving it. */ + static final int DEFAULT_DIM_DURATION = 200; + final WindowManagerService mService; final Context mContext; final WindowManagerPolicy mPolicy; @@ -115,7 +120,7 @@ public class WindowAnimator { final DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId); if (displayAnimator != null) { if (displayAnimator.mWindowAnimationBackgroundSurface != null) { - displayAnimator.mWindowAnimationBackgroundSurface.kill(); + displayAnimator.mWindowAnimationBackgroundSurface.destroySurface(); displayAnimator.mWindowAnimationBackgroundSurface = null; } if (displayAnimator.mScreenRotationAnimation != null) { @@ -123,7 +128,7 @@ public class WindowAnimator { displayAnimator.mScreenRotationAnimation = null; } if (displayAnimator.mDimAnimator != null) { - displayAnimator.mDimAnimator.kill(); + displayAnimator.mDimAnimator.destroySurface(); displayAnimator.mDimAnimator = null; } } @@ -359,8 +364,6 @@ public class WindowAnimator { WindowStateAnimator windowAnimationBackground = null; int windowAnimationBackgroundColor = 0; WindowState detachedWallpaper = null; - final DimSurface windowAnimationBackgroundSurface = - displayAnimator.mWindowAnimationBackgroundSurface; for (int i = windows.size() - 1; i >= 0; i--) { final WindowState win = windows.get(i); @@ -440,15 +443,11 @@ public class WindowAnimator { } } - if (windowAnimationBackgroundSurface != null) { - windowAnimationBackgroundSurface.show( - animLayer - WindowManagerService.LAYER_OFFSET_DIM, - windowAnimationBackgroundColor); - } + displayAnimator.mWindowAnimationBackgroundSurface.show( + animLayer - WindowManagerService.LAYER_OFFSET_DIM, + ((windowAnimationBackgroundColor >> 24) & 0xff) / 255f, 0); } else { - if (windowAnimationBackgroundSurface != null) { - windowAnimationBackgroundSurface.hide(); - } + displayAnimator.mWindowAnimationBackgroundSurface.hide(); } } @@ -499,8 +498,19 @@ public class WindowAnimator { updateWallpaperLocked(displayId); } - // TODO(cmautner): Change the following comment when no longer locked on mWindowMap */ - /** Locked on mService.mWindowMap and this. */ + private long getDimBehindFadeDuration(long duration) { + TypedValue tv = new TypedValue(); + mContext.getResources().getValue( + com.android.internal.R.fraction.config_dimBehindFadeDuration, tv, true); + if (tv.type == TypedValue.TYPE_FRACTION) { + duration = (long)tv.getFraction(duration, duration); + } else if (tv.type >= TypedValue.TYPE_FIRST_INT && tv.type <= TypedValue.TYPE_LAST_INT) { + duration = tv.data; + } + return duration; + } + + /** Locked on mService.mWindowMap. */ private void animateLocked() { if (!mInitialized) { return; @@ -561,15 +571,38 @@ public class WindowAnimator { screenRotationAnimation.updateSurfacesInTransaction(); } - final DimAnimator.Parameters dimParams = displayAnimator.mDimParams; - final DimAnimator dimAnimator = displayAnimator.mDimAnimator; - if (dimAnimator != null && dimParams != null) { - dimAnimator.updateParameters(mContext.getResources(), dimParams, mCurrentTime); + final DimLayer dimAnimator = displayAnimator.mDimAnimator; + final WindowStateAnimator winAnimator = displayAnimator.mDimWinAnimator; + final float dimAmount; + if (winAnimator == null) { + dimAmount = 0; + } else { + dimAmount = winAnimator.mWin.mAttrs.dimAmount; } - if (dimAnimator != null && dimAnimator.mDimShown) { - mAnimating |= dimAnimator.updateSurface(isDimmingLocked(displayId), - mCurrentTime, !mService.okToDisplay()); + final float targetAlpha = dimAnimator.getTargetAlpha(); + if (targetAlpha != dimAmount) { + if (winAnimator == null) { + dimAnimator.hide(DEFAULT_DIM_DURATION); + } else { + long duration = (winAnimator.mAnimating && winAnimator.mAnimation != null) + ? winAnimator.mAnimation.computeDurationHint() + : DEFAULT_DIM_DURATION; + if (targetAlpha > dimAmount) { + duration = getDimBehindFadeDuration(duration); + } + dimAnimator.show(winAnimator.mAnimLayer - + WindowManagerService.LAYER_OFFSET_DIM, dimAmount, duration); + } + } + if (dimAnimator.isAnimating()) { + if (!mService.okToDisplay()) { + // Jump to the end of the animation. + dimAnimator.show(); + } else { + mAnimating |= dimAnimator.stepAnimation(); + } } + //TODO (multidisplay): Magnification is supported only for the default display. if (mService.mDisplayMagnifier != null && displayId == Display.DEFAULT_DISPLAY) { mService.mDisplayMagnifier.drawMagnifiedRegionBorderIfNeededLocked(); @@ -628,13 +661,18 @@ public class WindowAnimator { } boolean isDimmingLocked(int displayId) { - return getDisplayContentsAnimatorLocked(displayId).mDimParams != null; + return getDisplayContentsAnimatorLocked(displayId).mDimAnimator.isDimming(); } boolean isDimmingLocked(final WindowStateAnimator winAnimator) { - DimAnimator.Parameters dimParams = - getDisplayContentsAnimatorLocked(winAnimator.mWin.getDisplayId()).mDimParams; - return dimParams != null && dimParams.mDimWinAnimator == winAnimator; + final int displayId = winAnimator.mWin.getDisplayId(); + DisplayContentsAnimator displayAnimator = + getDisplayContentsAnimatorLocked(displayId); + if (displayAnimator != null) { + return displayAnimator.mDimWinAnimator == winAnimator + && displayAnimator.mDimAnimator.isDimming(); + } + return false; } static String bulkUpdateParamsToString(int bulkUpdateParams) { @@ -675,24 +713,16 @@ public class WindowAnimator { pw.print(": "); pw.println(wanim); } if (displayAnimator.mWindowAnimationBackgroundSurface != null) { - if (dumpAll || displayAnimator.mWindowAnimationBackgroundSurface.mDimShown) { + if (dumpAll || displayAnimator.mWindowAnimationBackgroundSurface.isDimming()) { pw.print(subPrefix); pw.println("mWindowAnimationBackgroundSurface:"); displayAnimator.mWindowAnimationBackgroundSurface.printTo(subSubPrefix, pw); } } - if (displayAnimator.mDimAnimator != null) { - if (dumpAll || displayAnimator.mDimAnimator.mDimShown) { - pw.print(subPrefix); pw.println("mDimAnimator:"); - displayAnimator.mDimAnimator.printTo(subSubPrefix, pw); - } - } else if (dumpAll) { - pw.print(subPrefix); pw.println("no DimAnimator "); - } - if (displayAnimator.mDimParams != null) { - pw.print(subPrefix); pw.println("mDimParams:"); - displayAnimator.mDimParams.printTo(subSubPrefix, pw); - } else if (dumpAll) { - pw.print(subPrefix); pw.println("no DimParams "); + if (dumpAll || displayAnimator.mDimAnimator.isDimming()) { + pw.print(subPrefix); pw.println("mDimAnimator:"); + displayAnimator.mDimAnimator.printTo(subSubPrefix, pw); + pw.print(subPrefix); pw.print("mDimWinAnimator="); + pw.println(displayAnimator.mDimWinAnimator); } if (displayAnimator.mScreenRotationAnimation != null) { pw.print(subPrefix); pw.println("mScreenRotationAnimation:"); @@ -751,23 +781,18 @@ public class WindowAnimator { } } - void setDimParamsLocked(int displayId, DimAnimator.Parameters dimParams) { + void setDimWinAnimatorLocked(int displayId, WindowStateAnimator newWinAnimator) { DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId); - if (dimParams == null) { - displayAnimator.mDimParams = null; + if (newWinAnimator == null) { + displayAnimator.mDimWinAnimator = null; } else { - final WindowStateAnimator newWinAnimator = dimParams.mDimWinAnimator; - // Only set dim params on the highest dimmed layer. - final WindowStateAnimator existingDimWinAnimator = - displayAnimator.mDimParams == null ? - null : displayAnimator.mDimParams.mDimWinAnimator; - // Don't turn on for an unshown surface, or for any layer but the highest - // dimmed layer. + final WindowStateAnimator existingDimWinAnimator = displayAnimator.mDimWinAnimator; + // Don't turn on for an unshown surface, or for any layer but the highest dimmed layer. if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null || !existingDimWinAnimator.mSurfaceShown || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) { - displayAnimator.mDimParams = new DimAnimator.Parameters(dimParams); + displayAnimator.mDimWinAnimator = newWinAnimator; } } } @@ -790,15 +815,14 @@ public class WindowAnimator { } private class DisplayContentsAnimator { - DimAnimator mDimAnimator = null; - DimAnimator.Parameters mDimParams = null; - DimSurface mWindowAnimationBackgroundSurface = null; + DimLayer mDimAnimator = null; + WindowStateAnimator mDimWinAnimator = null; + DimLayer mWindowAnimationBackgroundSurface = null; ScreenRotationAnimation mScreenRotationAnimation = null; public DisplayContentsAnimator(int displayId) { - mDimAnimator = new DimAnimator(mService.mFxSession, displayId); - mWindowAnimationBackgroundSurface = new DimSurface(mService.mFxSession, - mService.getDisplayContentLocked(displayId)); + mDimAnimator = new DimLayer(mService, displayId); + mWindowAnimationBackgroundSurface = new DimLayer(mService, displayId); } } } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index c67a465..220cfd3 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -250,11 +250,6 @@ public class WindowManagerService extends IWindowManager.Stub */ static final int MAX_ANIMATION_DURATION = 10*1000; - /** Amount of time (in milliseconds) to animate the dim surface from one - * value to another, when no window animation is driving it. - */ - static final int DEFAULT_DIM_DURATION = 200; - /** Amount of time (in milliseconds) to animate the fade-in-out transition for * compatible windows. */ @@ -8219,18 +8214,8 @@ public class WindowManagerService extends IWindowManager.Stub mInnerFields.mDimming = true; final WindowStateAnimator winAnimator = w.mWinAnimator; if (!mAnimator.isDimmingLocked(winAnimator)) { - final int width, height; - if (attrs.type == TYPE_BOOT_PROGRESS) { - final DisplayInfo displayInfo = w.mDisplayContent.getDisplayInfo(); - width = displayInfo.logicalWidth; - height = displayInfo.logicalHeight; - } else { - width = innerDw; - height = innerDh; - } if (localLOGV) Slog.v(TAG, "Win " + w + " start dimming."); - startDimmingLocked( - winAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount, width, height); + startDimmingLocked(winAnimator, w.mExiting ? 0 : w.mAttrs.dimAmount); } } } @@ -8926,14 +8911,12 @@ public class WindowManagerService extends IWindowManager.Stub } } - void startDimmingLocked(final WindowStateAnimator winAnimator, final float target, - final int width, final int height) { - mAnimator.setDimParamsLocked(winAnimator.mWin.getDisplayId(), - new DimAnimator.Parameters(winAnimator, width, height, target)); + void startDimmingLocked(final WindowStateAnimator winAnimator, final float target) { + mAnimator.setDimWinAnimatorLocked(winAnimator.mWin.getDisplayId(), winAnimator); } void stopDimmingLocked(int displayId) { - mAnimator.setDimParamsLocked(displayId, null); + mAnimator.setDimWinAnimatorLocked(displayId, null); } private boolean needsLayout() { diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index 5b7cb99..78b1460 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -1183,9 +1183,7 @@ class WindowStateAnimator { mAnimator.setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) { - final DisplayInfo displayInfo = mWin.mDisplayContent.getDisplayInfo(); - mService.startDimmingLocked(this, w.mExiting ? 0 : w.mAttrs.dimAmount, - displayInfo.appWidth, displayInfo.appHeight); + mService.startDimmingLocked(this, w.mExiting ? 0 : w.mAttrs.dimAmount); } } catch (RuntimeException e) { // If something goes wrong with the surface (such |