DozeTriggers.java revision d0963a07d148426d7b872862697ae1ca538a834b
1ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos/* 2ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos * Copyright (C) 2016 The Android Open Source Project 3ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos * 4ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos * Licensed under the Apache License, Version 2.0 (the "License"); 5ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos * you may not use this file except in compliance with the License. 6ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos * You may obtain a copy of the License at 7ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos * 8ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos * http://www.apache.org/licenses/LICENSE-2.0 9ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos * 10ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos * Unless required by applicable law or agreed to in writing, software 11ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos * distributed under the License is distributed on an "AS IS" BASIS, 12ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos * See the License for the specific language governing permissions and 14ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos * limitations under the License. 15ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos */ 16ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 17ff2c4563cdee60576847e161678549bc501e8d84Adrian Roospackage com.android.systemui.doze; 18ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 196023ccbea1568d8b22db82cac9bf7a03367d0a61Adrian Roosimport android.app.AlarmManager; 20ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.app.UiModeManager; 21ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.content.BroadcastReceiver; 22ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.content.Context; 23ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.content.Intent; 24ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.content.IntentFilter; 25ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.content.res.Configuration; 26ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.hardware.Sensor; 27ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.hardware.SensorEvent; 28ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.hardware.SensorEventListener; 29ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.hardware.SensorManager; 30ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.os.Handler; 31ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.os.SystemClock; 32ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.os.UserHandle; 33ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.text.format.Formatter; 34ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport android.util.Log; 35ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 36ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport com.android.internal.hardware.AmbientDisplayConfiguration; 37ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport com.android.internal.util.Preconditions; 38ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport com.android.systemui.statusbar.phone.DozeParameters; 39ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport com.android.systemui.util.Assert; 40c1b50324a2286b24b691b8a7190743cbc341727eAdrian Roosimport com.android.systemui.util.wakelock.WakeLock; 41ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 42ff2c4563cdee60576847e161678549bc501e8d84Adrian Roosimport java.io.PrintWriter; 43d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roosimport java.util.function.IntConsumer; 44ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 45ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos/** 46ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos * Handles triggers for ambient state changes. 47ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos */ 48ff2c4563cdee60576847e161678549bc501e8d84Adrian Roospublic class DozeTriggers implements DozeMachine.Part { 49ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 50ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private static final String TAG = "DozeTriggers"; 5167cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos private static final boolean DEBUG = DozeService.DEBUG; 52ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 53ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos /** adb shell am broadcast -a com.android.systemui.doze.pulse com.android.systemui */ 54ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private static final String PULSE_ACTION = "com.android.systemui.doze.pulse"; 55ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 56ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private final Context mContext; 57ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private final DozeMachine mMachine; 58ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private final DozeSensors mDozeSensors; 59ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private final DozeHost mDozeHost; 60ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private final AmbientDisplayConfiguration mConfig; 61ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private final DozeParameters mDozeParameters; 62ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private final SensorManager mSensorManager; 63ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private final Handler mHandler; 64c1b50324a2286b24b691b8a7190743cbc341727eAdrian Roos private final WakeLock mWakeLock; 65f9d13f6d7a6fda22620cd4eab74ec98cafdbd147Adrian Roos private final boolean mAllowPulseTriggers; 66ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private final UiModeManager mUiModeManager; 67ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private final TriggerReceiver mBroadcastReceiver = new TriggerReceiver(); 68ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 69ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private long mNotificationPulseTime; 70ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private boolean mPulsePending; 71ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 72ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 73ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos public DozeTriggers(Context context, DozeMachine machine, DozeHost dozeHost, 746023ccbea1568d8b22db82cac9bf7a03367d0a61Adrian Roos AlarmManager alarmManager, AmbientDisplayConfiguration config, 75ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos DozeParameters dozeParameters, SensorManager sensorManager, Handler handler, 76c1b50324a2286b24b691b8a7190743cbc341727eAdrian Roos WakeLock wakeLock, boolean allowPulseTriggers) { 77ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mContext = context; 78ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mMachine = machine; 79ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mDozeHost = dozeHost; 80ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mConfig = config; 81ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mDozeParameters = dozeParameters; 82ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mSensorManager = sensorManager; 83ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mHandler = handler; 84ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mWakeLock = wakeLock; 85f9d13f6d7a6fda22620cd4eab74ec98cafdbd147Adrian Roos mAllowPulseTriggers = allowPulseTriggers; 866023ccbea1568d8b22db82cac9bf7a03367d0a61Adrian Roos mDozeSensors = new DozeSensors(context, alarmManager, mSensorManager, dozeParameters, 876023ccbea1568d8b22db82cac9bf7a03367d0a61Adrian Roos config, wakeLock, this::onSensor, this::onProximityFar); 88ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mUiModeManager = mContext.getSystemService(UiModeManager.class); 89ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 90ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 91ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private void onNotification() { 92ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (DozeMachine.DEBUG) Log.d(TAG, "requestNotificationPulse"); 93ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mNotificationPulseTime = SystemClock.elapsedRealtime(); 94ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (!mConfig.pulseOnNotificationEnabled(UserHandle.USER_CURRENT)) return; 95ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos requestPulse(DozeLog.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */); 96181c320ee4b464244296ceddfbce7c0503110d03Adrian Roos DozeLog.traceNotificationPulse(mContext); 97ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 98ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 99ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private void onWhisper() { 100ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos requestPulse(DozeLog.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */); 101ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 102ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 103d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos private void proximityCheckThenCall(IntConsumer callback, 104d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos boolean alreadyPerformedProxCheck, 105d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos int pulseReason) { 106d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos if (alreadyPerformedProxCheck) { 107d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos callback.accept(ProximityCheck.RESULT_NOT_CHECKED); 108d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos } else { 109d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos final long start = SystemClock.uptimeMillis(); 110d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos new ProximityCheck() { 111d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos @Override 112d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos public void onProximityResult(int result) { 113d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos final long end = SystemClock.uptimeMillis(); 114d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos DozeLog.traceProximityResult(mContext, result == RESULT_NEAR, 115d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos end - start, pulseReason); 116d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos callback.accept(result); 117d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos } 118d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos }.check(); 119d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos } 120d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos } 121d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos 12225c7a58f33c7c24e59f522b86e3cf064fdfd3b8cAdrian Roos private void onSensor(int pulseReason, boolean sensorPerformedProxCheck, 12325c7a58f33c7c24e59f522b86e3cf064fdfd3b8cAdrian Roos float screenX, float screenY) { 124ed85e58656685f0ac28be7678db61edc88cd95e7Adrian Roos boolean isDoubleTap = pulseReason == DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP; 125ed85e58656685f0ac28be7678db61edc88cd95e7Adrian Roos boolean isPickup = pulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP; 126d0963a07d148426d7b872862697ae1ca538a834bAdrian Roos boolean isLongPress = pulseReason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS; 127ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 128d0963a07d148426d7b872862697ae1ca538a834bAdrian Roos if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT) && !isLongPress) { 129d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos proximityCheckThenCall((result) -> { 130d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos if (result == ProximityCheck.RESULT_NEAR) { 131d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos // In pocket, drop event. 132d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos return; 133d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos } 134d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos if (isDoubleTap) { 135d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos mDozeHost.onDoubleTap(screenX, screenY); 136d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos mMachine.wakeUp(); 137d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos } else { 138d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos mDozeHost.extendPulse(); 139d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos } 140d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos }, sensorPerformedProxCheck, pulseReason); 141d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos return; 142ed85e58656685f0ac28be7678db61edc88cd95e7Adrian Roos } else { 143ed85e58656685f0ac28be7678db61edc88cd95e7Adrian Roos requestPulse(pulseReason, sensorPerformedProxCheck); 144ed85e58656685f0ac28be7678db61edc88cd95e7Adrian Roos } 145ed85e58656685f0ac28be7678db61edc88cd95e7Adrian Roos 146ed85e58656685f0ac28be7678db61edc88cd95e7Adrian Roos if (isPickup) { 147ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos final long timeSinceNotification = 148ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos SystemClock.elapsedRealtime() - mNotificationPulseTime; 149ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos final boolean withinVibrationThreshold = 150ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos timeSinceNotification < mDozeParameters.getPickupVibrationThreshold(); 151ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos DozeLog.tracePickupPulse(mContext, withinVibrationThreshold); 152ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 153ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 154ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 15567cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos private void onProximityFar(boolean far) { 15667cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos final boolean near = !far; 1576023ccbea1568d8b22db82cac9bf7a03367d0a61Adrian Roos final DozeMachine.State state = mMachine.getState(); 1586023ccbea1568d8b22db82cac9bf7a03367d0a61Adrian Roos final boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED); 1596023ccbea1568d8b22db82cac9bf7a03367d0a61Adrian Roos final boolean pausing = (state == DozeMachine.State.DOZE_AOD_PAUSING); 1606023ccbea1568d8b22db82cac9bf7a03367d0a61Adrian Roos final boolean aod = (state == DozeMachine.State.DOZE_AOD); 1616023ccbea1568d8b22db82cac9bf7a03367d0a61Adrian Roos 16267cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos if (near && state == DozeMachine.State.DOZE_PULSING) { 16367cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos if (DEBUG) Log.i(TAG, "Prox NEAR, ending pulse"); 164d35d4ca69f06cc53c02036f418275c255dc6ed68Adrian Roos DozeLog.tracePulseCanceledByProx(mContext); 16567cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos mMachine.requestState(DozeMachine.State.DOZE_PULSE_DONE); 16667cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos } 1676023ccbea1568d8b22db82cac9bf7a03367d0a61Adrian Roos if (far && (paused || pausing)) { 16867cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos if (DEBUG) Log.i(TAG, "Prox FAR, unpausing AOD"); 16967cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos mMachine.requestState(DozeMachine.State.DOZE_AOD); 1706023ccbea1568d8b22db82cac9bf7a03367d0a61Adrian Roos } else if (near && aod) { 17167cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos if (DEBUG) Log.i(TAG, "Prox NEAR, pausing AOD"); 1726023ccbea1568d8b22db82cac9bf7a03367d0a61Adrian Roos mMachine.requestState(DozeMachine.State.DOZE_AOD_PAUSING); 17367cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos } 17467cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos } 17567cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos 176ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos @Override 177ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) { 178ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos switch (newState) { 179ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos case INITIALIZED: 180ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mBroadcastReceiver.register(mContext); 181ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mDozeHost.addCallback(mHostCallback); 182ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos checkTriggersAtInit(); 183ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos break; 184ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos case DOZE: 185ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos case DOZE_AOD: 18667cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos mDozeSensors.setProxListening(newState != DozeMachine.State.DOZE); 187ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (oldState != DozeMachine.State.INITIALIZED) { 188ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mDozeSensors.reregisterAllSensors(); 189ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 190e3ac6f853f5ef9a034ef4d8a8c66ac47f3b66188Adrian Roos mDozeSensors.setListening(true); 191ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos break; 1925f7bee46e1561e293e646565be6851d86a6b7f1eAdrian Roos case DOZE_AOD_PAUSED: 1936023ccbea1568d8b22db82cac9bf7a03367d0a61Adrian Roos case DOZE_AOD_PAUSING: 1945f7bee46e1561e293e646565be6851d86a6b7f1eAdrian Roos mDozeSensors.setProxListening(true); 1955f7bee46e1561e293e646565be6851d86a6b7f1eAdrian Roos mDozeSensors.setListening(false); 1965f7bee46e1561e293e646565be6851d86a6b7f1eAdrian Roos break; 19767cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos case DOZE_PULSING: 19867cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos mDozeSensors.setProxListening(true); 19967cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos break; 200ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos case FINISH: 201ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mBroadcastReceiver.unregister(mContext); 202ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mDozeHost.removeCallback(mHostCallback); 203ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mDozeSensors.setListening(false); 20467cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos mDozeSensors.setProxListening(false); 205ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos break; 206ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos default: 207ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 208ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 209ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 210ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private void checkTriggersAtInit() { 211f2d545e30717c09c39df36aa601cf39e44dcdc50Adrian Roos if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR 212f2d545e30717c09c39df36aa601cf39e44dcdc50Adrian Roos || mDozeHost.isPowerSaveActive() 213710a0b13628be61899472959526fa5e6fbb06b1fAdrian Roos || mDozeHost.isBlockingDoze() 214f2d545e30717c09c39df36aa601cf39e44dcdc50Adrian Roos || !mDozeHost.isProvisioned()) { 215f2d545e30717c09c39df36aa601cf39e44dcdc50Adrian Roos mMachine.requestState(DozeMachine.State.FINISH); 216ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 217ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 218ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 219ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private void requestPulse(final int reason, boolean performedProxCheck) { 220ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos Assert.isMainThread(); 22167cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos mDozeHost.extendPulse(); 222f9d13f6d7a6fda22620cd4eab74ec98cafdbd147Adrian Roos if (mPulsePending || !mAllowPulseTriggers || !canPulse()) { 223d35d4ca69f06cc53c02036f418275c255dc6ed68Adrian Roos if (mAllowPulseTriggers) { 224d35d4ca69f06cc53c02036f418275c255dc6ed68Adrian Roos DozeLog.tracePulseDropped(mContext, mPulsePending, mMachine.getState(), 225d35d4ca69f06cc53c02036f418275c255dc6ed68Adrian Roos mDozeHost.isPulsingBlocked()); 226d35d4ca69f06cc53c02036f418275c255dc6ed68Adrian Roos } 227ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos return; 228ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 229ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 230ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mPulsePending = true; 231d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos proximityCheckThenCall((result) -> { 232d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos if (result == ProximityCheck.RESULT_NEAR) { 233d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos // in pocket, abort pulse 234d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos mPulsePending = false; 235d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos } else { 236d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos // not in pocket, continue pulsing 237ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos continuePulseRequest(reason); 238ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 239d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos }, !mDozeParameters.getProxCheckBeforePulse() || performedProxCheck, reason); 240ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 241ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 242ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private boolean canPulse() { 243ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos return mMachine.getState() == DozeMachine.State.DOZE 244ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos || mMachine.getState() == DozeMachine.State.DOZE_AOD; 245ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 246ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 247ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private void continuePulseRequest(int reason) { 248ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mPulsePending = false; 249ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (mDozeHost.isPulsingBlocked() || !canPulse()) { 250d35d4ca69f06cc53c02036f418275c255dc6ed68Adrian Roos DozeLog.tracePulseDropped(mContext, mPulsePending, mMachine.getState(), 251d35d4ca69f06cc53c02036f418275c255dc6ed68Adrian Roos mDozeHost.isPulsingBlocked()); 252ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos return; 253ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 254d7b9d10d569438968f75d2453c4293caf89774f2Adrian Roos mMachine.requestPulse(reason); 255ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 256ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 257ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos @Override 258ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos public void dump(PrintWriter pw) { 259ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos pw.print(" notificationPulseTime="); 260ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos pw.println(Formatter.formatShortElapsedTime(mContext, mNotificationPulseTime)); 261ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 262ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos pw.print(" pulsePending="); pw.println(mPulsePending); 263ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos pw.println("DozeSensors:"); 264ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mDozeSensors.dump(pw); 265ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 266ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 267ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private abstract class ProximityCheck implements SensorEventListener, Runnable { 268ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private static final int TIMEOUT_DELAY_MS = 500; 269ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 270ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos protected static final int RESULT_UNKNOWN = 0; 271ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos protected static final int RESULT_NEAR = 1; 272ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos protected static final int RESULT_FAR = 2; 273d32b366a1752d1735cfe4b87058596d05fcf9588Adrian Roos protected static final int RESULT_NOT_CHECKED = 3; 274ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 275ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private boolean mRegistered; 276ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private boolean mFinished; 277ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private float mMaxRange; 278ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 279ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos protected abstract void onProximityResult(int result); 280ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 281ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos public void check() { 282ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos Preconditions.checkState(!mFinished && !mRegistered); 283ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos final Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); 284ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (sensor == null) { 285ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (DozeMachine.DEBUG) Log.d(TAG, "ProxCheck: No sensor found"); 286ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos finishWithResult(RESULT_UNKNOWN); 287ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos return; 288ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 289ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mDozeSensors.setDisableSensorsInterferingWithProximity(true); 290ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 291ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mMaxRange = sensor.getMaximumRange(); 292ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL, 0, 293ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mHandler); 294ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mHandler.postDelayed(this, TIMEOUT_DELAY_MS); 295ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mWakeLock.acquire(); 296ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mRegistered = true; 297ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 298ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 299ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos @Override 300ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos public void onSensorChanged(SensorEvent event) { 301ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (event.values.length == 0) { 302ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (DozeMachine.DEBUG) Log.d(TAG, "ProxCheck: Event has no values!"); 303ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos finishWithResult(RESULT_UNKNOWN); 304ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } else { 305ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (DozeMachine.DEBUG) { 306ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos Log.d(TAG, "ProxCheck: Event: value=" + event.values[0] + " max=" + mMaxRange); 307ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 308ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos final boolean isNear = event.values[0] < mMaxRange; 309ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos finishWithResult(isNear ? RESULT_NEAR : RESULT_FAR); 310ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 311ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 312ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 313ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos @Override 314ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos public void run() { 315ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (DozeMachine.DEBUG) Log.d(TAG, "ProxCheck: No event received before timeout"); 316ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos finishWithResult(RESULT_UNKNOWN); 317ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 318ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 319ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private void finishWithResult(int result) { 320ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (mFinished) return; 321ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos boolean wasRegistered = mRegistered; 322ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (mRegistered) { 323ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mHandler.removeCallbacks(this); 324ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mSensorManager.unregisterListener(this); 325ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mDozeSensors.setDisableSensorsInterferingWithProximity(false); 326ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mRegistered = false; 327ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 328ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos onProximityResult(result); 329ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (wasRegistered) { 330ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mWakeLock.release(); 331ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 332ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mFinished = true; 333ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 334ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 335ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos @Override 336ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos public void onAccuracyChanged(Sensor sensor, int accuracy) { 337ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos // noop 338ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 339ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 340ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 341ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private class TriggerReceiver extends BroadcastReceiver { 34267cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos private boolean mRegistered; 34367cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos 344ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos @Override 345ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos public void onReceive(Context context, Intent intent) { 346ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (PULSE_ACTION.equals(intent.getAction())) { 347ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (DozeMachine.DEBUG) Log.d(TAG, "Received pulse intent"); 348ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos requestPulse(DozeLog.PULSE_REASON_INTENT, false /* performedProxCheck */); 349ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 350ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) { 351f2d545e30717c09c39df36aa601cf39e44dcdc50Adrian Roos mMachine.requestState(DozeMachine.State.FINISH); 352ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 353ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { 354ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos mDozeSensors.onUserSwitched(); 355ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 356ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 357ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 358ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos public void register(Context context) { 35967cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos if (mRegistered) { 36067cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos return; 36167cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos } 362ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos IntentFilter filter = new IntentFilter(PULSE_ACTION); 363ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE); 364ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos filter.addAction(Intent.ACTION_USER_SWITCHED); 365ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos context.registerReceiver(this, filter); 36667cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos mRegistered = true; 367ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 368ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 369ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos public void unregister(Context context) { 37067cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos if (!mRegistered) { 37167cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos return; 37267cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos } 373ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos context.unregisterReceiver(this); 37467cca7442bfeffc0bace506a796cfdd39e5d511cAdrian Roos mRegistered = false; 375ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 376ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 377ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 378ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos private DozeHost.Callback mHostCallback = new DozeHost.Callback() { 379ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos @Override 3804b820e4e5e0404adbf9f9678b79fa7e988e3e597Adrian Roos public void onNotificationHeadsUp() { 381ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos onNotification(); 382ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 383ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos 384ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos @Override 385ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos public void onPowerSaveChanged(boolean active) { 386ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos if (active) { 387f2d545e30717c09c39df36aa601cf39e44dcdc50Adrian Roos mMachine.requestState(DozeMachine.State.FINISH); 388ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 389ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos } 390ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos }; 391ff2c4563cdee60576847e161678549bc501e8d84Adrian Roos} 392