11420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner// Copyright 2012 Google Inc. All Rights Reserved.
21420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
31420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautnerpackage com.android.server.wm;
41420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
51420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautnerimport android.graphics.PixelFormat;
605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautnerimport android.graphics.Rect;
71420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautnerimport android.os.SystemClock;
81420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautnerimport android.util.Slog;
91420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautnerimport android.view.DisplayInfo;
103866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopianimport android.view.SurfaceControl;
111420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
121420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautnerimport java.io.PrintWriter;
131420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
141420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautnerpublic class DimLayer {
151420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    private static final String TAG = "DimLayer";
16c34bc1178b3d5e60651e4b1ffb416ff8235bf388Craig Mautner    private static final boolean DEBUG = false;
171420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
181420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /** Reference to the owner of this object. */
191420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    final DisplayContent mDisplayContent;
201420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
211420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /** Actual surface that dims */
223866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian    SurfaceControl mDimSurface;
231420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
241420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /** Last value passed to mDimSurface.setAlpha() */
251420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    float mAlpha = 0;
261420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
271420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /** Last value passed to mDimSurface.setLayer() */
281420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    int mLayer = -1;
291420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
3005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    /** Next values to pass to mDimSurface.setPosition() and mDimSurface.setSize() */
3105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    Rect mBounds = new Rect();
3205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
3305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    /** Last values passed to mDimSurface.setPosition() and mDimSurface.setSize() */
3405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    Rect mLastBounds = new Rect();
351420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
361420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /** True after mDimSurface.show() has been called, false after mDimSurface.hide(). */
371420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    private boolean mShowing = false;
381420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
391420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /** Value of mAlpha when beginning transition to mTargetAlpha */
401420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    float mStartAlpha = 0;
411420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
421420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /** Final value of mAlpha following transition */
431420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    float mTargetAlpha = 0;
441420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
451420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /** Time in units of SystemClock.uptimeMillis() at which the current transition started */
461420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    long mStartTime;
471420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
481420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /** Time in milliseconds to take to transition from mStartAlpha to mTargetAlpha */
491420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    long mDuration;
501420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
51c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner    /** Owning stack */
52c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner    final TaskStack mStack;
53c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner
54c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner    DimLayer(WindowManagerService service, TaskStack stack) {
55c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner        mStack = stack;
56c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner        mDisplayContent = stack.getDisplayContent();
57c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner        final int displayId = mDisplayContent.getDisplayId();
581420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        if (DEBUG) Slog.v(TAG, "Ctor: displayId=" + displayId);
593866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian        SurfaceControl.openTransaction();
601420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        try {
611420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            if (WindowManagerService.DEBUG_SURFACE_TRACE) {
621420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                mDimSurface = new WindowStateAnimator.SurfaceTrace(service.mFxSession,
631420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                    "DimSurface",
641420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                    16, 16, PixelFormat.OPAQUE,
653866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                    SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
661420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            } else {
673866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                mDimSurface = new SurfaceControl(service.mFxSession, TAG,
681420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                    16, 16, PixelFormat.OPAQUE,
693866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian                    SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
701420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            }
711420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            if (WindowManagerService.SHOW_TRANSACTIONS ||
721420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                    WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(TAG,
731420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                            "  DIM " + mDimSurface + ": CREATE");
741420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            mDimSurface.setLayerStack(displayId);
751420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        } catch (Exception e) {
761420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            Slog.e(WindowManagerService.TAG, "Exception creating Dim surface", e);
771420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        } finally {
783866f0d581ceaa165710feeee9f37fe1b0d7067dMathias Agopian            SurfaceControl.closeTransaction();
791420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        }
801420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    }
811420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
821420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /** Return true if dim layer is showing */
831420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    boolean isDimming() {
841420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        return mTargetAlpha != 0;
851420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    }
861420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
871420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /** Return true if in a transition period */
881420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    boolean isAnimating() {
891420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        return mTargetAlpha != mAlpha;
901420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    }
911420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
921420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    float getTargetAlpha() {
931420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        return mTargetAlpha;
941420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    }
951420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
9613131e74ea93d82c004ab1567351eadcedd799a5Craig Mautner    void setLayer(int layer) {
9713131e74ea93d82c004ab1567351eadcedd799a5Craig Mautner        if (mLayer != layer) {
9813131e74ea93d82c004ab1567351eadcedd799a5Craig Mautner            mLayer = layer;
9913131e74ea93d82c004ab1567351eadcedd799a5Craig Mautner            mDimSurface.setLayer(layer);
10013131e74ea93d82c004ab1567351eadcedd799a5Craig Mautner        }
10113131e74ea93d82c004ab1567351eadcedd799a5Craig Mautner    }
10213131e74ea93d82c004ab1567351eadcedd799a5Craig Mautner
10313131e74ea93d82c004ab1567351eadcedd799a5Craig Mautner    int getLayer() {
10413131e74ea93d82c004ab1567351eadcedd799a5Craig Mautner        return mLayer;
10513131e74ea93d82c004ab1567351eadcedd799a5Craig Mautner    }
10613131e74ea93d82c004ab1567351eadcedd799a5Craig Mautner
1071420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    private void setAlpha(float alpha) {
1081420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        if (mAlpha != alpha) {
1091420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            if (DEBUG) Slog.v(TAG, "setAlpha alpha=" + alpha);
1101420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            try {
1111420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                mDimSurface.setAlpha(alpha);
1121420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                if (alpha == 0 && mShowing) {
1131420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                    if (DEBUG) Slog.v(TAG, "setAlpha hiding");
1141420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                    mDimSurface.hide();
1151420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                    mShowing = false;
1161420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                } else if (alpha > 0 && !mShowing) {
1171420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                    if (DEBUG) Slog.v(TAG, "setAlpha showing");
1181420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                    mDimSurface.show();
1191420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                    mShowing = true;
1201420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                }
1211420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            } catch (RuntimeException e) {
1221420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                Slog.w(TAG, "Failure setting alpha immediately", e);
1231420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            }
1241420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            mAlpha = alpha;
1251420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        }
1261420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    }
1271420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
12805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    void setBounds(Rect bounds) {
12905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        mBounds.set(bounds);
13005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    }
13105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
1321420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /**
1331420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * @param duration The time to test.
1341420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * @return True if the duration would lead to an earlier end to the current animation.
1351420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     */
1361420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    private boolean durationEndsEarlier(long duration) {
1371420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        return SystemClock.uptimeMillis() + duration < mStartTime + mDuration;
1381420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    }
1391420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
1401420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /** Jump to the end of the animation.
1411420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * NOTE: Must be called with Surface transaction open. */
1421420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    void show() {
1431420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        if (isAnimating()) {
1441420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            if (DEBUG) Slog.v(TAG, "show: immediate");
1451420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            show(mLayer, mTargetAlpha, 0);
1461420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        }
1471420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    }
1481420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
1491420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /**
1501420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * Begin an animation to a new dim value.
1511420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * NOTE: Must be called with Surface transaction open.
1521420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     *
1531420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * @param layer The layer to set the surface to.
1541420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * @param alpha The dim value to end at.
1551420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * @param duration How long to take to get there in milliseconds.
1561420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     */
1571420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    void show(int layer, float alpha, long duration) {
1581420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        if (DEBUG) Slog.v(TAG, "show: layer=" + layer + " alpha=" + alpha
1591420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                + " duration=" + duration);
1601420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        if (mDimSurface == null) {
1611420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            Slog.e(TAG, "show: no Surface");
1621420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            // Make sure isAnimating() returns false.
1631420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            mTargetAlpha = mAlpha = 0;
1641420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            return;
1651420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        }
1661420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
167c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner        final int dw, dh;
168c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner        final float xPos, yPos;
169c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner        if (mStack.hasSibling()) {
170c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner            dw = mBounds.width();
171c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner            dh = mBounds.height();
172c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner            xPos = mBounds.left;
173c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner            yPos = mBounds.right;
174c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner        } else {
175c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner            // Set surface size to screen size.
176c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner            final DisplayInfo info = mDisplayContent.getDisplayInfo();
177c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner            // Multiply by 1.5 so that rotating a frozen surface that includes this does not expose a
178c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner            // corner.
179c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner            dw = (int) (info.logicalWidth * 1.5);
180c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner            dh = (int) (info.logicalHeight * 1.5);
181c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner            // back off position so 1/4 of Surface is before and 1/4 is after.
182c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner            xPos = -1 * dw / 6;
183c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner            yPos = -1 * dh / 6;
184c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner        }
1851420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
18605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        if (!mLastBounds.equals(mBounds) || mLayer != layer) {
1871420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            try {
188c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner                mDimSurface.setPosition(xPos, yPos);
189c7b8a1004006f08fbd1fb32133ccd1b9ec73819aCraig Mautner                mDimSurface.setSize(dw, dh);
1901420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                mDimSurface.setLayer(layer);
1911420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            } catch (RuntimeException e) {
1921420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                Slog.w(TAG, "Failure setting size or layer", e);
1931420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            }
19405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            mLastBounds.set(mBounds);
1951420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            mLayer = layer;
1961420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        }
1971420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
1981420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        long curTime = SystemClock.uptimeMillis();
1991420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        final boolean animating = isAnimating();
2001420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        if ((animating && (mTargetAlpha != alpha || durationEndsEarlier(duration)))
2011420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                || (!animating && mAlpha != alpha)) {
2021420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            if (duration <= 0) {
2031420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                // No animation required, just set values.
2041420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                setAlpha(alpha);
2051420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            } else {
2061420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                // Start or continue animation with new parameters.
2071420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                mStartAlpha = mAlpha;
2081420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                mStartTime = curTime;
2091420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                mDuration = duration;
2101420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            }
2111420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        }
2121420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        if (DEBUG) Slog.v(TAG, "show: mStartAlpha=" + mStartAlpha + " mStartTime=" + mStartTime);
2131420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        mTargetAlpha = alpha;
2141420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    }
2151420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
2161420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /** Immediate hide.
2171420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * NOTE: Must be called with Surface transaction open. */
2181420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    void hide() {
2191420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        if (mShowing) {
2201420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            if (DEBUG) Slog.v(TAG, "hide: immediate");
2211420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            hide(0);
2221420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        }
2231420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    }
2241420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
2251420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /**
2261420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * Gradually fade to transparent.
2271420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * NOTE: Must be called with Surface transaction open.
2281420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     *
2291420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * @param duration Time to fade in milliseconds.
2301420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     */
2311420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    void hide(long duration) {
2321420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        if (mShowing && (mTargetAlpha != 0 || durationEndsEarlier(duration))) {
2331420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            if (DEBUG) Slog.v(TAG, "hide: duration=" + duration);
2341420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            show(mLayer, 0, duration);
2351420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        }
2361420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    }
2371420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
2381420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /**
2391420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * Advance the dimming per the last #show(int, float, long) call.
2401420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * NOTE: Must be called with Surface transaction open.
2411420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     *
2421420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     * @return True if animation is still required after this step.
2431420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner     */
2441420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    boolean stepAnimation() {
2451420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        if (mDimSurface == null) {
2461420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            Slog.e(TAG, "stepAnimation: null Surface");
2471420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            // Ensure that isAnimating() returns false;
2481420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            mTargetAlpha = mAlpha = 0;
2491420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            return false;
2501420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        }
2511420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
2521420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        if (isAnimating()) {
2531420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            final long curTime = SystemClock.uptimeMillis();
2541420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            final float alphaDelta = mTargetAlpha - mStartAlpha;
2551420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            float alpha = mStartAlpha + alphaDelta * (curTime - mStartTime) / mDuration;
2561420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            if (alphaDelta > 0 && alpha > mTargetAlpha ||
2571420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                    alphaDelta < 0 && alpha < mTargetAlpha) {
2581420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                // Don't exceed limits.
2591420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                alpha = mTargetAlpha;
2601420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            }
2611420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            if (DEBUG) Slog.v(TAG, "stepAnimation: curTime=" + curTime + " alpha=" + alpha);
2621420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            setAlpha(alpha);
2631420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        }
2641420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
2651420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        return isAnimating();
2661420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    }
2671420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
2681420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    /** Cleanup */
2691420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    void destroySurface() {
2701420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        if (DEBUG) Slog.v(TAG, "destroySurface.");
2711420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        if (mDimSurface != null) {
2721420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            mDimSurface.destroy();
2731420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner            mDimSurface = null;
2741420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner        }
2751420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    }
2761420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner
2771420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    public void printTo(String prefix, PrintWriter pw) {
278967212cb542e6eeb308678367b53381bff984c31Craig Mautner        pw.print(prefix); pw.print("mDimSurface="); pw.print(mDimSurface);
279967212cb542e6eeb308678367b53381bff984c31Craig Mautner                pw.print(" mLayer="); pw.print(mLayer);
2801420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                pw.print(" mAlpha="); pw.println(mAlpha);
28105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        pw.print(prefix); pw.print("mLastBounds="); pw.print(mLastBounds.toShortString());
28205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                pw.print(" mBounds="); pw.println(mBounds.toShortString());
283967212cb542e6eeb308678367b53381bff984c31Craig Mautner        pw.print(prefix); pw.print("Last animation: ");
2841420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                pw.print(" mDuration="); pw.print(mDuration);
285967212cb542e6eeb308678367b53381bff984c31Craig Mautner                pw.print(" mStartTime="); pw.print(mStartTime);
2861420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner                pw.print(" curTime="); pw.println(SystemClock.uptimeMillis());
287967212cb542e6eeb308678367b53381bff984c31Craig Mautner        pw.print(prefix); pw.print(" mStartAlpha="); pw.print(mStartAlpha);
288967212cb542e6eeb308678367b53381bff984c31Craig Mautner                pw.print(" mTargetAlpha="); pw.println(mTargetAlpha);
2891420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner    }
2901420b93fa5606979fd67eaf80f50294d4f8c191bCraig Mautner}
291