Home | History | Annotate | Download | only in phone
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License
     15  */
     16 
     17 package com.android.systemui.statusbar.phone;
     18 
     19 import android.annotation.NonNull;
     20 import android.content.Context;
     21 import android.os.Handler;
     22 import android.util.Log;
     23 
     24 import com.android.systemui.doze.DozeHost;
     25 import com.android.systemui.doze.DozeLog;
     26 
     27 /**
     28  * Controller which handles all the doze animations of the scrims.
     29  */
     30 public class DozeScrimController {
     31     private static final String TAG = "DozeScrimController";
     32     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     33 
     34     private final DozeParameters mDozeParameters;
     35     private final Handler mHandler = new Handler();
     36     private final ScrimController mScrimController;
     37 
     38     private boolean mDozing;
     39     private DozeHost.PulseCallback mPulseCallback;
     40     private int mPulseReason;
     41     private boolean mFullyPulsing;
     42 
     43     private final ScrimController.Callback mScrimCallback = new ScrimController.Callback() {
     44         @Override
     45         public void onDisplayBlanked() {
     46             if (DEBUG) {
     47                 Log.d(TAG, "Pulse in, mDozing=" + mDozing + " mPulseReason="
     48                         + DozeLog.pulseReasonToString(mPulseReason));
     49             }
     50             if (!mDozing) {
     51                 return;
     52             }
     53 
     54             // Signal that the pulse is ready to turn the screen on and draw.
     55             pulseStarted();
     56         }
     57 
     58         @Override
     59         public void onFinished() {
     60             if (DEBUG) {
     61                 Log.d(TAG, "Pulse in finished, mDozing=" + mDozing);
     62             }
     63             if (!mDozing) {
     64                 return;
     65             }
     66             mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
     67             mHandler.postDelayed(mPulseOutExtended,
     68                     mDozeParameters.getPulseVisibleDurationExtended());
     69             mFullyPulsing = true;
     70         }
     71 
     72         /**
     73          * Transition was aborted before it was over.
     74          */
     75         @Override
     76         public void onCancelled() {
     77             pulseFinished();
     78         }
     79     };
     80 
     81     public DozeScrimController(ScrimController scrimController, Context context,
     82             DozeParameters dozeParameters) {
     83         mScrimController = scrimController;
     84         mDozeParameters = dozeParameters;
     85     }
     86 
     87     public void setDozing(boolean dozing) {
     88         if (mDozing == dozing) return;
     89         mDozing = dozing;
     90         if (!mDozing) {
     91             cancelPulsing();
     92         }
     93     }
     94 
     95     /** When dozing, fade screen contents in and out using the front scrim. */
     96     public void pulse(@NonNull DozeHost.PulseCallback callback, int reason) {
     97         if (callback == null) {
     98             throw new IllegalArgumentException("callback must not be null");
     99         }
    100 
    101         if (!mDozing || mPulseCallback != null) {
    102             if (DEBUG) {
    103                 Log.d(TAG, "Pulse supressed. Dozing: " + mDozeParameters + " had callback? "
    104                         + (mPulseCallback != null));
    105             }
    106             // Pulse suppressed.
    107             callback.onPulseFinished();
    108             return;
    109         }
    110 
    111         // Begin pulse. Note that it's very important that the pulse finished callback
    112         // be invoked when we're done so that the caller can drop the pulse wakelock.
    113         mPulseCallback = callback;
    114         mPulseReason = reason;
    115 
    116         mScrimController.transitionTo(ScrimState.PULSING, mScrimCallback);
    117     }
    118 
    119     public void pulseOutNow() {
    120         if (mPulseCallback != null && mFullyPulsing) {
    121             mPulseOut.run();
    122         }
    123     }
    124 
    125     public boolean isPulsing() {
    126         return mPulseCallback != null;
    127     }
    128 
    129     public boolean isDozing() {
    130         return mDozing;
    131     }
    132 
    133     public void extendPulse() {
    134         mHandler.removeCallbacks(mPulseOut);
    135     }
    136 
    137     private void cancelPulsing() {
    138         if (mPulseCallback != null) {
    139             if (DEBUG) Log.d(TAG, "Cancel pulsing");
    140             mFullyPulsing = false;
    141             mHandler.removeCallbacks(mPulseOut);
    142             mHandler.removeCallbacks(mPulseOutExtended);
    143             pulseFinished();
    144         }
    145     }
    146 
    147     private void pulseStarted() {
    148         DozeLog.tracePulseStart(mPulseReason);
    149         if (mPulseCallback != null) {
    150             mPulseCallback.onPulseStarted();
    151         }
    152     }
    153 
    154     private void pulseFinished() {
    155         DozeLog.tracePulseFinish();
    156         if (mPulseCallback != null) {
    157             mPulseCallback.onPulseFinished();
    158             mPulseCallback = null;
    159         }
    160     }
    161 
    162     private final Runnable mPulseOutExtended = new Runnable() {
    163         @Override
    164         public void run() {
    165             mHandler.removeCallbacks(mPulseOut);
    166             mPulseOut.run();
    167         }
    168     };
    169 
    170     private final Runnable mPulseOut = new Runnable() {
    171         @Override
    172         public void run() {
    173             mFullyPulsing = false;
    174             mHandler.removeCallbacks(mPulseOut);
    175             mHandler.removeCallbacks(mPulseOutExtended);
    176             if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
    177             if (!mDozing) return;
    178             mScrimController.transitionTo(ScrimState.AOD,
    179                     new ScrimController.Callback() {
    180                         @Override
    181                         public void onDisplayBlanked() {
    182                             pulseFinished();
    183                         }
    184                     });
    185         }
    186     };
    187 }