1048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi/*
2048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi * Copyright (C) 2014 The Android Open Source Project
3048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi *
4048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License");
5048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi * you may not use this file except in compliance with the License.
6048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi * You may obtain a copy of the License at
7048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi *
8048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi *      http://www.apache.org/licenses/LICENSE-2.0
9048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi *
10048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi * Unless required by applicable law or agreed to in writing, software
11048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS,
12048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi * See the License for the specific language governing permissions and
14048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi * limitations under the License
15048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi */
16048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
17048af1f727dc81a6450e004391d072599ac449eeJorim Jaggipackage com.android.systemui.statusbar.phone;
18048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
19048af1f727dc81a6450e004391d072599ac449eeJorim Jaggiimport android.animation.Animator;
20048af1f727dc81a6450e004391d072599ac449eeJorim Jaggiimport android.animation.AnimatorListenerAdapter;
21048af1f727dc81a6450e004391d072599ac449eeJorim Jaggiimport android.animation.ValueAnimator;
22048af1f727dc81a6450e004391d072599ac449eeJorim Jaggiimport android.annotation.NonNull;
23048af1f727dc81a6450e004391d072599ac449eeJorim Jaggiimport android.content.Context;
24048af1f727dc81a6450e004391d072599ac449eeJorim Jaggiimport android.os.Handler;
25048af1f727dc81a6450e004391d072599ac449eeJorim Jaggiimport android.util.Log;
26048af1f727dc81a6450e004391d072599ac449eeJorim Jaggiimport android.view.animation.Interpolator;
27048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
28c0d7058b14c24cd07912f5629c26b39b7b4673d5Winsonimport com.android.systemui.Interpolators;
29048af1f727dc81a6450e004391d072599ac449eeJorim Jaggiimport com.android.systemui.doze.DozeHost;
30048af1f727dc81a6450e004391d072599ac449eeJorim Jaggiimport com.android.systemui.doze.DozeLog;
31048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
32048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi/**
33048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi * Controller which handles all the doze animations of the scrims.
34048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi */
35048af1f727dc81a6450e004391d072599ac449eeJorim Jaggipublic class DozeScrimController {
36048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private static final String TAG = "DozeScrimController";
37048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
38048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
39048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private final DozeParameters mDozeParameters;
40048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private final Handler mHandler = new Handler();
41048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private final ScrimController mScrimController;
42048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
43048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private boolean mDozing;
44048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private DozeHost.PulseCallback mPulseCallback;
45eab28e660223b6e02f2fbd8dc31c8bde3ce5b22dJohn Spurlock    private int mPulseReason;
46048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private Animator mInFrontAnimator;
47048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private Animator mBehindAnimator;
48048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private float mInFrontTarget;
49048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private float mBehindTarget;
50048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
51048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    public DozeScrimController(ScrimController scrimController, Context context) {
52048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        mScrimController = scrimController;
53048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        mDozeParameters = new DozeParameters(context);
54048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
55048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
56048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    public void setDozing(boolean dozing, boolean animate) {
57048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        if (mDozing == dozing) return;
58048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        mDozing = dozing;
59048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        if (mDozing) {
60048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            abortAnimations();
61048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mScrimController.setDozeBehindAlpha(1f);
62048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mScrimController.setDozeInFrontAlpha(1f);
63048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        } else {
64048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            cancelPulsing();
65048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            if (animate) {
66048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi                startScrimAnimation(false /* inFront */, 0f /* target */,
67c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinek                        NotificationPanelView.DOZE_ANIMATION_DURATION,
68c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinek                        Interpolators.LINEAR_OUT_SLOW_IN);
69048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi                startScrimAnimation(true /* inFront */, 0f /* target */,
70c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinek                        NotificationPanelView.DOZE_ANIMATION_DURATION,
71c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinek                        Interpolators.LINEAR_OUT_SLOW_IN);
72048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            } else {
73048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi                abortAnimations();
74048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi                mScrimController.setDozeBehindAlpha(0f);
75048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi                mScrimController.setDozeInFrontAlpha(0f);
76048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            }
77048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
78048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
79048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
80048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    /** When dozing, fade screen contents in and out using the front scrim. */
81eab28e660223b6e02f2fbd8dc31c8bde3ce5b22dJohn Spurlock    public void pulse(@NonNull DozeHost.PulseCallback callback, int reason) {
82048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        if (callback == null) {
83048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            throw new IllegalArgumentException("callback must not be null");
84048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
85048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
86048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        if (!mDozing || mPulseCallback != null) {
87048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            // Pulse suppressed.
88048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            callback.onPulseFinished();
89048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            return;
90048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
91048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
92048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        // Begin pulse.  Note that it's very important that the pulse finished callback
93048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        // be invoked when we're done so that the caller can drop the pulse wakelock.
94048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        mPulseCallback = callback;
95eab28e660223b6e02f2fbd8dc31c8bde3ce5b22dJohn Spurlock        mPulseReason = reason;
96048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        mHandler.post(mPulseIn);
97048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
98048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
99007f0e8f207d3d6d2f47d725b72459edf317cce9Jorim Jaggi    /**
100007f0e8f207d3d6d2f47d725b72459edf317cce9Jorim Jaggi     * Aborts pulsing immediately.
101007f0e8f207d3d6d2f47d725b72459edf317cce9Jorim Jaggi     */
102007f0e8f207d3d6d2f47d725b72459edf317cce9Jorim Jaggi    public void abortPulsing() {
1035fb4b98bdd33475703f8928699c8a6b91fd06550Jorim Jaggi        cancelPulsing();
10483eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi        if (mDozing) {
10583eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi            mScrimController.setDozeBehindAlpha(1f);
10683eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi            mScrimController.setDozeInFrontAlpha(1f);
10783eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi        }
108007f0e8f207d3d6d2f47d725b72459edf317cce9Jorim Jaggi    }
109007f0e8f207d3d6d2f47d725b72459edf317cce9Jorim Jaggi
11050ff3afb01f2ac4a93dba418a71d54ad8adeba9dJorim Jaggi    public void onScreenTurnedOn() {
11150ff3afb01f2ac4a93dba418a71d54ad8adeba9dJorim Jaggi        if (isPulsing()) {
1127294c115fd33a9259bf584092a1131dbeccf04bdAdrian Roos            final boolean pickupOrDoubleTap = mPulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP
1137294c115fd33a9259bf584092a1131dbeccf04bdAdrian Roos                    || mPulseReason == DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP;
11450ff3afb01f2ac4a93dba418a71d54ad8adeba9dJorim Jaggi            startScrimAnimation(true /* inFront */, 0f,
1157294c115fd33a9259bf584092a1131dbeccf04bdAdrian Roos                    mDozeParameters.getPulseInDuration(pickupOrDoubleTap),
1167294c115fd33a9259bf584092a1131dbeccf04bdAdrian Roos                    pickupOrDoubleTap ? Interpolators.LINEAR_OUT_SLOW_IN : Interpolators.ALPHA_OUT,
11750ff3afb01f2ac4a93dba418a71d54ad8adeba9dJorim Jaggi                    mPulseInFinished);
11850ff3afb01f2ac4a93dba418a71d54ad8adeba9dJorim Jaggi        }
11950ff3afb01f2ac4a93dba418a71d54ad8adeba9dJorim Jaggi    }
12050ff3afb01f2ac4a93dba418a71d54ad8adeba9dJorim Jaggi
121048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    public boolean isPulsing() {
122048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        return mPulseCallback != null;
123048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
124048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
12583eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi    public boolean isDozing() {
12683eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi        return mDozing;
12783eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi    }
12883eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi
129048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private void cancelPulsing() {
130048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        if (DEBUG) Log.d(TAG, "Cancel pulsing");
131048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
132048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        if (mPulseCallback != null) {
133048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mHandler.removeCallbacks(mPulseIn);
134048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mHandler.removeCallbacks(mPulseOut);
135048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            pulseFinished();
136048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
137048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
138048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
139048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private void pulseStarted() {
140048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        if (mPulseCallback != null) {
141048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mPulseCallback.onPulseStarted();
142048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
143048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
144048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
145048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private void pulseFinished() {
146048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        if (mPulseCallback != null) {
147048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mPulseCallback.onPulseFinished();
148048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mPulseCallback = null;
149048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
150048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
151048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
152048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private void abortAnimations() {
153048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        if (mInFrontAnimator != null) {
154048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mInFrontAnimator.cancel();
155048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
156048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        if (mBehindAnimator != null) {
157048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mBehindAnimator.cancel();
158048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
159048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
160048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
161048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private void startScrimAnimation(final boolean inFront, float target, long duration,
162048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            Interpolator interpolator) {
16350ff3afb01f2ac4a93dba418a71d54ad8adeba9dJorim Jaggi        startScrimAnimation(inFront, target, duration, interpolator, null /* endRunnable */);
164048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
165048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
166048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private void startScrimAnimation(final boolean inFront, float target, long duration,
16750ff3afb01f2ac4a93dba418a71d54ad8adeba9dJorim Jaggi            Interpolator interpolator, final Runnable endRunnable) {
168048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        Animator current = getCurrentAnimator(inFront);
169048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        if (current != null) {
170048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            float currentTarget = getCurrentTarget(inFront);
171048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            if (currentTarget == target) {
172048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi                return;
173048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            }
174048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            current.cancel();
175048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
176048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        ValueAnimator anim = ValueAnimator.ofFloat(getDozeAlpha(inFront), target);
177048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
178048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            @Override
179048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            public void onAnimationUpdate(ValueAnimator animation) {
180048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi                float value = (float) animation.getAnimatedValue();
181048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi                setDozeAlpha(inFront, value);
182048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            }
183048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        });
184048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        anim.setInterpolator(interpolator);
185048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        anim.setDuration(duration);
186048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        anim.addListener(new AnimatorListenerAdapter() {
187048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            @Override
188048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            public void onAnimationEnd(Animator animation) {
189048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi                setCurrentAnimator(inFront, null);
190048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi                if (endRunnable != null) {
191048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi                    endRunnable.run();
192048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi                }
193048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            }
194048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        });
195048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        anim.start();
196048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        setCurrentAnimator(inFront, anim);
197048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        setCurrentTarget(inFront, target);
198048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
199048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
200048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private float getCurrentTarget(boolean inFront) {
201048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        return inFront ? mInFrontTarget : mBehindTarget;
202048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
203048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
204048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private void setCurrentTarget(boolean inFront, float target) {
205048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        if (inFront) {
206048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mInFrontTarget = target;
207048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        } else {
208048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mBehindTarget = target;
209048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
210048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
211048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
212048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private Animator getCurrentAnimator(boolean inFront) {
213048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        return inFront ? mInFrontAnimator : mBehindAnimator;
214048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
215048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
216048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private void setCurrentAnimator(boolean inFront, Animator animator) {
217048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        if (inFront) {
218048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mInFrontAnimator = animator;
219048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        } else {
220048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mBehindAnimator = animator;
221048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
222048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
223048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
224048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private void setDozeAlpha(boolean inFront, float alpha) {
225048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        if (inFront) {
226048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mScrimController.setDozeInFrontAlpha(alpha);
227048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        } else {
228048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mScrimController.setDozeBehindAlpha(alpha);
229048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
230048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
231048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
232048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private float getDozeAlpha(boolean inFront) {
233048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        return inFront
234048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi                ? mScrimController.getDozeInFrontAlpha()
235048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi                : mScrimController.getDozeBehindAlpha();
236048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    }
237048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
238048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private final Runnable mPulseIn = new Runnable() {
239048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        @Override
240048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        public void run() {
241f5d250deecc4ce79ef8a74f1c4eb76e268556115John Spurlock            if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing + " mPulseReason="
242f5d250deecc4ce79ef8a74f1c4eb76e268556115John Spurlock                    + DozeLog.pulseReasonToString(mPulseReason));
243048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            if (!mDozing) return;
244eab28e660223b6e02f2fbd8dc31c8bde3ce5b22dJohn Spurlock            DozeLog.tracePulseStart(mPulseReason);
245048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
246048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            // Signal that the pulse is ready to turn the screen on and draw.
247048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            pulseStarted();
248048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
249048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    };
250048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
251048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private final Runnable mPulseInFinished = new Runnable() {
252048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        @Override
253048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        public void run() {
254048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            if (DEBUG) Log.d(TAG, "Pulse in finished, mDozing=" + mDozing);
255048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            if (!mDozing) return;
256048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
257048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
258048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    };
259048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
260048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private final Runnable mPulseOut = new Runnable() {
261048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        @Override
262048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        public void run() {
263048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
264048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            if (!mDozing) return;
265048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            startScrimAnimation(true /* inFront */, 1f, mDozeParameters.getPulseOutDuration(),
266c18010f6720f606003cde3cd376ddacaca30f6e5Selim Cinek                    Interpolators.ALPHA_IN, mPulseOutFinished);
267048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
268048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    };
269048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
270048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    private final Runnable mPulseOutFinished = new Runnable() {
271048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        @Override
272048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        public void run() {
273048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            if (DEBUG) Log.d(TAG, "Pulse out finished");
274048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            DozeLog.tracePulseFinish();
275048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi
276048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            // Signal that the pulse is all finished so we can turn the screen off now.
277048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi            pulseFinished();
278048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi        }
279048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi    };
280048af1f727dc81a6450e004391d072599ac449eeJorim Jaggi}
281