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 DozeScrimController(ScrimController scrimController, Context context, DozeParameters dozeParameters)81 public DozeScrimController(ScrimController scrimController, Context context, 82 DozeParameters dozeParameters) { 83 mScrimController = scrimController; 84 mDozeParameters = dozeParameters; 85 } 86 setDozing(boolean dozing)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. */ pulse(@onNull DozeHost.PulseCallback callback, int reason)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 pulseOutNow()119 public void pulseOutNow() { 120 if (mPulseCallback != null && mFullyPulsing) { 121 mPulseOut.run(); 122 } 123 } 124 isPulsing()125 public boolean isPulsing() { 126 return mPulseCallback != null; 127 } 128 isDozing()129 public boolean isDozing() { 130 return mDozing; 131 } 132 extendPulse()133 public void extendPulse() { 134 mHandler.removeCallbacks(mPulseOut); 135 } 136 cancelPulsing()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 pulseStarted()147 private void pulseStarted() { 148 DozeLog.tracePulseStart(mPulseReason); 149 if (mPulseCallback != null) { 150 mPulseCallback.onPulseStarted(); 151 } 152 } 153 pulseFinished()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 }