blob: 77180f8cc07a5db9dd29cb5ba60a23cae7b8e977 [file] [log] [blame]
Adrian Roosea8d6ae2016-10-26 10:40:12 -07001/*
2 * Copyright (C) 2016 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
Adrian Roosff2c4562016-11-03 12:13:36 -070014 * limitations under the License.
Adrian Roosea8d6ae2016-10-26 10:40:12 -070015 */
16
17package com.android.systemui.doze;
18
Lucas Dupinb2d9f482018-11-16 18:55:13 -080019import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_DISPLAY;
Lucas Dupinde64ee02018-12-21 14:45:12 -080020import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_LOCK_SCREEN;
Lucas Dupin3d951752018-10-10 12:00:40 -070021
Adrian Roosea8d6ae2016-10-26 10:40:12 -070022import android.annotation.AnyThread;
23import android.app.ActivityManager;
Adrian Roos6023ccb2017-06-28 16:22:02 +020024import android.app.AlarmManager;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070025import android.content.ContentResolver;
26import android.content.Context;
27import android.database.ContentObserver;
28import android.hardware.Sensor;
Adrian Roos67cca742017-04-13 16:52:51 -070029import android.hardware.SensorEventListener;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070030import android.hardware.SensorManager;
31import android.hardware.TriggerEvent;
32import android.hardware.TriggerEventListener;
Issei Suzukica19e6e2019-02-26 12:39:11 +010033import android.hardware.display.AmbientDisplayConfiguration;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070034import android.net.Uri;
35import android.os.Handler;
Adrian Roos6023ccb2017-06-28 16:22:02 +020036import android.os.SystemClock;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070037import android.os.UserHandle;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070038import android.provider.Settings;
39import android.text.TextUtils;
40import android.util.Log;
41
Lucas Dupin8a13aa72019-02-22 12:45:21 -080042import androidx.annotation.VisibleForTesting;
43
Adrian Roosff2c4562016-11-03 12:13:36 -070044import com.android.internal.logging.MetricsLogger;
Tamas Berghammer383db5eb2016-06-22 15:21:38 +010045import com.android.internal.logging.nano.MetricsProto;
Lucas Dupin3d951752018-10-10 12:00:40 -070046import com.android.systemui.plugins.SensorManagerPlugin;
Adrian Roosff2c4562016-11-03 12:13:36 -070047import com.android.systemui.statusbar.phone.DozeParameters;
Adrian Roos6023ccb2017-06-28 16:22:02 +020048import com.android.systemui.util.AlarmTimeout;
Lucas Dupin3d951752018-10-10 12:00:40 -070049import com.android.systemui.util.AsyncSensorManager;
Adrian Roosc1b50322017-02-27 21:07:58 +010050import com.android.systemui.util.wakelock.WakeLock;
Adrian Roosff2c4562016-11-03 12:13:36 -070051
52import java.io.PrintWriter;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070053import java.util.List;
Adrian Roos67cca742017-04-13 16:52:51 -070054import java.util.function.Consumer;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070055
56public class DozeSensors {
57
58 private static final boolean DEBUG = DozeService.DEBUG;
59
60 private static final String TAG = "DozeSensors";
61
62 private final Context mContext;
Adrian Roos6023ccb2017-06-28 16:22:02 +020063 private final AlarmManager mAlarmManager;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070064 private final SensorManager mSensorManager;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070065 private final ContentResolver mResolver;
66 private final TriggerSensor mPickupSensor;
67 private final DozeParameters mDozeParameters;
68 private final AmbientDisplayConfiguration mConfig;
Adrian Roosc1b50322017-02-27 21:07:58 +010069 private final WakeLock mWakeLock;
Adrian Roos67cca742017-04-13 16:52:51 -070070 private final Consumer<Boolean> mProxCallback;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070071 private final Callback mCallback;
Lucas Dupin8a13aa72019-02-22 12:45:21 -080072 @VisibleForTesting
73 protected final TriggerSensor[] mSensors;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070074
75 private final Handler mHandler = new Handler();
Adrian Roos67cca742017-04-13 16:52:51 -070076 private final ProxSensor mProxSensor;
Lucas Dupin8a13aa72019-02-22 12:45:21 -080077 private long mDebounceFrom;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070078
Adrian Roos6023ccb2017-06-28 16:22:02 +020079 public DozeSensors(Context context, AlarmManager alarmManager, SensorManager sensorManager,
Lucas Dupin323f9ff2018-08-27 16:55:56 -070080 DozeParameters dozeParameters, AmbientDisplayConfiguration config, WakeLock wakeLock,
Lucas Dupinb2d9f482018-11-16 18:55:13 -080081 Callback callback, Consumer<Boolean> proxCallback, AlwaysOnDisplayPolicy policy) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -070082 mContext = context;
Adrian Roos6023ccb2017-06-28 16:22:02 +020083 mAlarmManager = alarmManager;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070084 mSensorManager = sensorManager;
85 mDozeParameters = dozeParameters;
86 mConfig = config;
87 mWakeLock = wakeLock;
Adrian Roos67cca742017-04-13 16:52:51 -070088 mProxCallback = proxCallback;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070089 mResolver = mContext.getContentResolver();
90
Lucas Dupin70bda672018-12-27 15:43:40 -080091 boolean alwaysOn = mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT);
Adrian Roosea8d6ae2016-10-26 10:40:12 -070092 mSensors = new TriggerSensor[] {
93 new TriggerSensor(
94 mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
95 null /* setting */,
96 dozeParameters.getPulseOnSigMotion(),
Adrian Roos98d31982017-08-02 20:50:16 +020097 DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */,
98 false /* touchscreen */),
Adrian Roosea8d6ae2016-10-26 10:40:12 -070099 mPickupSensor = new TriggerSensor(
100 mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
Lucas Dupin4359b552018-08-09 15:07:54 -0700101 Settings.Secure.DOZE_PICK_UP_GESTURE,
102 config.dozePickupSensorAvailable(),
Lucas Dupin3d053532019-01-29 12:35:22 -0800103 DozeLog.REASON_SENSOR_PICKUP, false /* touchCoords */,
Adrian Roos98d31982017-08-02 20:50:16 +0200104 false /* touchscreen */),
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700105 new TriggerSensor(
106 findSensorWithType(config.doubleTapSensorType()),
Lucas Dupin4359b552018-08-09 15:07:54 -0700107 Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700108 true /* configured */,
Lucas Dupin3d053532019-01-29 12:35:22 -0800109 DozeLog.REASON_SENSOR_DOUBLE_TAP,
Adrian Roos98d31982017-08-02 20:50:16 +0200110 dozeParameters.doubleTapReportsTouchCoordinates(),
111 true /* touchscreen */),
Adrian Roosd0963a02017-05-15 14:33:37 -0700112 new TriggerSensor(
Lucas Dupind43bf702019-01-15 13:40:42 -0800113 findSensorWithType(config.tapSensorType()),
114 Settings.Secure.DOZE_TAP_SCREEN_GESTURE,
115 true /* configured */,
Lucas Dupin3d053532019-01-29 12:35:22 -0800116 DozeLog.REASON_SENSOR_TAP,
Lucas Dupind43bf702019-01-15 13:40:42 -0800117 false /* reports touch coordinates */,
118 true /* touchscreen */),
119 new TriggerSensor(
Adrian Roosd0963a02017-05-15 14:33:37 -0700120 findSensorWithType(config.longPressSensorType()),
121 Settings.Secure.DOZE_PULSE_ON_LONG_PRESS,
122 false /* settingDef */,
123 true /* configured */,
124 DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
Adrian Roos98d31982017-08-02 20:50:16 +0200125 true /* reports touch coordinates */,
126 true /* touchscreen */),
Lucas Dupin1ae6cf92018-12-14 18:06:38 -0800127 new PluginSensor(
Lucas Dupinb2d9f482018-11-16 18:55:13 -0800128 new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY),
129 Settings.Secure.DOZE_WAKE_SCREEN_GESTURE,
Lucas Dupin70bda672018-12-27 15:43:40 -0800130 mConfig.wakeScreenGestureAvailable() && alwaysOn,
Lucas Dupinb2d9f482018-11-16 18:55:13 -0800131 DozeLog.REASON_SENSOR_WAKE_UP,
132 false /* reports touch coordinates */,
133 false /* touchscreen */),
Lucas Dupinde64ee02018-12-21 14:45:12 -0800134 new PluginSensor(
135 new SensorManagerPlugin.Sensor(TYPE_WAKE_LOCK_SCREEN),
Lucas Dupine3218c12019-01-18 16:48:41 -0800136 Settings.Secure.DOZE_WAKE_SCREEN_GESTURE,
Lucas Dupine076c6d2019-02-13 13:53:10 -0800137 mConfig.wakeScreenGestureAvailable() && alwaysOn,
Lucas Dupinde64ee02018-12-21 14:45:12 -0800138 DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN,
139 false /* reports touch coordinates */,
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800140 false /* touchscreen */, mConfig.getWakeLockScreenDebounce()),
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700141 };
Adrian Roos67cca742017-04-13 16:52:51 -0700142
jackqdyulei8443dd02017-08-24 16:14:34 -0700143 mProxSensor = new ProxSensor(policy);
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700144 mCallback = callback;
145 }
146
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800147 /**
148 * Temporarily disable some sensors to avoid turning on the device while the user is
149 * turning it off.
150 */
151 public void requestTemporaryDisable() {
152 mDebounceFrom = SystemClock.uptimeMillis();
153 }
154
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700155 private Sensor findSensorWithType(String type) {
Adrian Roos2981eb02017-05-26 18:40:09 -0700156 return findSensorWithType(mSensorManager, type);
157 }
158
159 static Sensor findSensorWithType(SensorManager sensorManager, String type) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700160 if (TextUtils.isEmpty(type)) {
161 return null;
162 }
Adrian Roos2981eb02017-05-26 18:40:09 -0700163 List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700164 for (Sensor s : sensorList) {
165 if (type.equals(s.getStringType())) {
166 return s;
167 }
168 }
169 return null;
170 }
171
Adrian Roosd6ec13132016-10-27 11:50:47 -0700172 public void setListening(boolean listen) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700173 for (TriggerSensor s : mSensors) {
174 s.setListening(listen);
175 if (listen) {
176 s.registerSettingsObserver(mSettingsObserver);
177 }
178 }
179 if (!listen) {
180 mResolver.unregisterContentObserver(mSettingsObserver);
181 }
182 }
183
Adrian Roos98d31982017-08-02 20:50:16 +0200184 /** Set the listening state of only the sensors that require the touchscreen. */
185 public void setTouchscreenSensorsListening(boolean listening) {
186 for (TriggerSensor sensor : mSensors) {
187 if (sensor.mRequiresTouchscreen) {
188 sensor.setListening(listening);
189 }
190 }
191 }
192
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700193 public void onUserSwitched() {
194 for (TriggerSensor s : mSensors) {
195 s.updateListener();
196 }
197 }
198
Adrian Roos67cca742017-04-13 16:52:51 -0700199 public void setProxListening(boolean listen) {
Adrian Roos6023ccb2017-06-28 16:22:02 +0200200 mProxSensor.setRequested(listen);
Adrian Roos67cca742017-04-13 16:52:51 -0700201 }
202
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700203 private final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
204 @Override
205 public void onChange(boolean selfChange, Uri uri, int userId) {
206 if (userId != ActivityManager.getCurrentUser()) {
207 return;
208 }
209 for (TriggerSensor s : mSensors) {
210 s.updateListener();
211 }
212 }
213 };
214
215 public void setDisableSensorsInterferingWithProximity(boolean disable) {
216 mPickupSensor.setDisabled(disable);
217 }
218
lpeter8a5f4702019-01-18 16:53:07 +0800219 /** Ignore the setting value of only the sensors that require the touchscreen. */
220 public void ignoreTouchScreenSensorsSettingInterferingWithDocking(boolean ignore) {
221 for (TriggerSensor sensor : mSensors) {
222 if (sensor.mRequiresTouchscreen) {
223 sensor.ignoreSetting(ignore);
224 }
225 }
226 }
227
Adrian Roosff2c4562016-11-03 12:13:36 -0700228 /** Dump current state */
229 public void dump(PrintWriter pw) {
230 for (TriggerSensor s : mSensors) {
231 pw.print("Sensor: "); pw.println(s.toString());
232 }
Adrian Roos2ca9cd72017-07-03 15:14:37 +0200233 pw.print("ProxSensor: "); pw.println(mProxSensor.toString());
Adrian Roosff2c4562016-11-03 12:13:36 -0700234 }
235
Adrian Roos70da03a2017-07-24 16:42:57 +0200236 /**
237 * @return true if prox is currently far, false if near or null if unknown.
238 */
239 public Boolean isProximityCurrentlyFar() {
240 return mProxSensor.mCurrentlyFar;
241 }
242
Adrian Roos67cca742017-04-13 16:52:51 -0700243 private class ProxSensor implements SensorEventListener {
244
Adrian Roos6023ccb2017-06-28 16:22:02 +0200245 boolean mRequested;
Adrian Roos67cca742017-04-13 16:52:51 -0700246 boolean mRegistered;
247 Boolean mCurrentlyFar;
Adrian Roos6023ccb2017-06-28 16:22:02 +0200248 long mLastNear;
249 final AlarmTimeout mCooldownTimer;
jackqdyulei8443dd02017-08-24 16:14:34 -0700250 final AlwaysOnDisplayPolicy mPolicy;
Adrian Roos67cca742017-04-13 16:52:51 -0700251
Adrian Roos6023ccb2017-06-28 16:22:02 +0200252
jackqdyulei8443dd02017-08-24 16:14:34 -0700253 public ProxSensor(AlwaysOnDisplayPolicy policy) {
254 mPolicy = policy;
Adrian Roos6023ccb2017-06-28 16:22:02 +0200255 mCooldownTimer = new AlarmTimeout(mAlarmManager, this::updateRegistered,
256 "prox_cooldown", mHandler);
257 }
258
259 void setRequested(boolean requested) {
260 if (mRequested == requested) {
Adrian Roos67cca742017-04-13 16:52:51 -0700261 // Send an update even if we don't re-register.
262 mHandler.post(() -> {
263 if (mCurrentlyFar != null) {
264 mProxCallback.accept(mCurrentlyFar);
265 }
266 });
267 return;
268 }
Adrian Roos6023ccb2017-06-28 16:22:02 +0200269 mRequested = requested;
270 updateRegistered();
271 }
272
273 private void updateRegistered() {
274 setRegistered(mRequested && !mCooldownTimer.isScheduled());
275 }
276
277 private void setRegistered(boolean register) {
278 if (mRegistered == register) {
279 return;
280 }
Adrian Roos67cca742017-04-13 16:52:51 -0700281 if (register) {
282 mRegistered = mSensorManager.registerListener(this,
283 mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY),
284 SensorManager.SENSOR_DELAY_NORMAL, mHandler);
285 } else {
286 mSensorManager.unregisterListener(this);
287 mRegistered = false;
288 mCurrentlyFar = null;
289 }
290 }
291
292 @Override
Lucas Dupin1ae6cf92018-12-14 18:06:38 -0800293 public void onSensorChanged(android.hardware.SensorEvent event) {
Lucas Dupin58543842018-02-15 14:00:54 -0800294 if (DEBUG) Log.d(TAG, "onSensorChanged " + event);
295
Adrian Roos67cca742017-04-13 16:52:51 -0700296 mCurrentlyFar = event.values[0] >= event.sensor.getMaximumRange();
297 mProxCallback.accept(mCurrentlyFar);
Adrian Roos6023ccb2017-06-28 16:22:02 +0200298
299 long now = SystemClock.elapsedRealtime();
Adrian Roos8f72b3c2017-07-07 12:20:21 +0200300 if (mCurrentlyFar == null) {
301 // Sensor has been unregistered by the proxCallback. Do nothing.
302 } else if (!mCurrentlyFar) {
Adrian Roos6023ccb2017-06-28 16:22:02 +0200303 mLastNear = now;
jackqdyulei8443dd02017-08-24 16:14:34 -0700304 } else if (mCurrentlyFar && now - mLastNear < mPolicy.proxCooldownTriggerMs) {
Adrian Roos6023ccb2017-06-28 16:22:02 +0200305 // If the last near was very recent, we might be using more power for prox
306 // wakeups than we're saving from turning of the screen. Instead, turn it off
307 // for a while.
jackqdyulei8443dd02017-08-24 16:14:34 -0700308 mCooldownTimer.schedule(mPolicy.proxCooldownPeriodMs,
309 AlarmTimeout.MODE_IGNORE_IF_SCHEDULED);
Adrian Roos6023ccb2017-06-28 16:22:02 +0200310 updateRegistered();
311 }
Adrian Roos67cca742017-04-13 16:52:51 -0700312 }
313
314 @Override
315 public void onAccuracyChanged(Sensor sensor, int accuracy) {
316 }
Adrian Roos2ca9cd72017-07-03 15:14:37 +0200317
318 @Override
319 public String toString() {
320 return String.format("{registered=%s, requested=%s, coolingDown=%s, currentlyFar=%s}",
321 mRegistered, mRequested, mCooldownTimer.isScheduled(), mCurrentlyFar);
322 }
Adrian Roos67cca742017-04-13 16:52:51 -0700323 }
324
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800325 @VisibleForTesting
326 class TriggerSensor extends TriggerEventListener {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700327 final Sensor mSensor;
328 final boolean mConfigured;
329 final int mPulseReason;
330 final String mSetting;
Adrian Roos25c7a582017-06-02 12:50:38 -0700331 final boolean mReportsTouchCoordinates;
Adrian Roosd0963a02017-05-15 14:33:37 -0700332 final boolean mSettingDefault;
Adrian Roos98d31982017-08-02 20:50:16 +0200333 final boolean mRequiresTouchscreen;
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700334
Lucas Dupin323f9ff2018-08-27 16:55:56 -0700335 protected boolean mRequested;
336 protected boolean mRegistered;
337 protected boolean mDisabled;
lpeter8a5f4702019-01-18 16:53:07 +0800338 protected boolean mIgnoresSetting;
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700339
Adrian Roos25c7a582017-06-02 12:50:38 -0700340 public TriggerSensor(Sensor sensor, String setting, boolean configured, int pulseReason,
Adrian Roos98d31982017-08-02 20:50:16 +0200341 boolean reportsTouchCoordinates, boolean requiresTouchscreen) {
Adrian Roosd0963a02017-05-15 14:33:37 -0700342 this(sensor, setting, true /* settingDef */, configured, pulseReason,
Adrian Roos98d31982017-08-02 20:50:16 +0200343 reportsTouchCoordinates, requiresTouchscreen);
Adrian Roosd0963a02017-05-15 14:33:37 -0700344 }
345
346 public TriggerSensor(Sensor sensor, String setting, boolean settingDef,
Adrian Roos98d31982017-08-02 20:50:16 +0200347 boolean configured, int pulseReason, boolean reportsTouchCoordinates,
348 boolean requiresTouchscreen) {
lpeter8a5f4702019-01-18 16:53:07 +0800349 this(sensor, setting, settingDef, configured, pulseReason, reportsTouchCoordinates,
350 requiresTouchscreen, false /* ignoresSetting */);
351 }
352
353 private TriggerSensor(Sensor sensor, String setting, boolean settingDef,
354 boolean configured, int pulseReason, boolean reportsTouchCoordinates,
355 boolean requiresTouchscreen, boolean ignoresSetting) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700356 mSensor = sensor;
357 mSetting = setting;
Adrian Roosd0963a02017-05-15 14:33:37 -0700358 mSettingDefault = settingDef;
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700359 mConfigured = configured;
360 mPulseReason = pulseReason;
Adrian Roos25c7a582017-06-02 12:50:38 -0700361 mReportsTouchCoordinates = reportsTouchCoordinates;
Adrian Roos98d31982017-08-02 20:50:16 +0200362 mRequiresTouchscreen = requiresTouchscreen;
lpeter8a5f4702019-01-18 16:53:07 +0800363 mIgnoresSetting = ignoresSetting;
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700364 }
365
366 public void setListening(boolean listen) {
367 if (mRequested == listen) return;
368 mRequested = listen;
369 updateListener();
370 }
371
372 public void setDisabled(boolean disabled) {
373 if (mDisabled == disabled) return;
374 mDisabled = disabled;
375 updateListener();
376 }
377
lpeter8a5f4702019-01-18 16:53:07 +0800378 public void ignoreSetting(boolean ignored) {
379 if (mIgnoresSetting == ignored) return;
380 mIgnoresSetting = ignored;
381 updateListener();
382 }
383
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700384 public void updateListener() {
385 if (!mConfigured || mSensor == null) return;
lpeter8a5f4702019-01-18 16:53:07 +0800386 if (mRequested && !mDisabled && (enabledBySetting() || mIgnoresSetting)
387 && !mRegistered) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700388 mRegistered = mSensorManager.requestTriggerSensor(this, mSensor);
389 if (DEBUG) Log.d(TAG, "requestTriggerSensor " + mRegistered);
390 } else if (mRegistered) {
391 final boolean rt = mSensorManager.cancelTriggerSensor(this, mSensor);
392 if (DEBUG) Log.d(TAG, "cancelTriggerSensor " + rt);
393 mRegistered = false;
394 }
395 }
396
Lucas Dupin323f9ff2018-08-27 16:55:56 -0700397 protected boolean enabledBySetting() {
Jerry Chang5d3eb4472018-12-21 11:49:06 +0800398 if (!mConfig.enabled(UserHandle.USER_CURRENT)) {
399 return false;
400 } else if (TextUtils.isEmpty(mSetting)) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700401 return true;
402 }
Adrian Roosd0963a02017-05-15 14:33:37 -0700403 return Settings.Secure.getIntForUser(mResolver, mSetting, mSettingDefault ? 1 : 0,
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700404 UserHandle.USER_CURRENT) != 0;
405 }
406
407 @Override
408 public String toString() {
409 return new StringBuilder("{mRegistered=").append(mRegistered)
410 .append(", mRequested=").append(mRequested)
411 .append(", mDisabled=").append(mDisabled)
412 .append(", mConfigured=").append(mConfigured)
lpeter8a5f4702019-01-18 16:53:07 +0800413 .append(", mIgnoresSetting=").append(mIgnoresSetting)
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700414 .append(", mSensor=").append(mSensor).append("}").toString();
415 }
416
417 @Override
418 @AnyThread
419 public void onTrigger(TriggerEvent event) {
Adrian Roos2ca9cd72017-07-03 15:14:37 +0200420 DozeLog.traceSensor(mContext, mPulseReason);
Adrian Roos79bacbb2016-10-26 11:00:12 -0700421 mHandler.post(mWakeLock.wrap(() -> {
Adrian Roosd6ec13132016-10-27 11:50:47 -0700422 if (DEBUG) Log.d(TAG, "onTrigger: " + triggerEventToString(event));
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700423 boolean sensorPerformsProxCheck = false;
Lucas Dupin3d951752018-10-10 12:00:40 -0700424 if (mSensor != null && mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700425 int subType = (int) event.values[0];
426 MetricsLogger.action(
Adrian Roos79bacbb2016-10-26 11:00:12 -0700427 mContext, MetricsProto.MetricsEvent.ACTION_AMBIENT_GESTURE,
428 subType);
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700429 sensorPerformsProxCheck =
430 mDozeParameters.getPickupSubtypePerformsProxCheck(subType);
431 }
432
433 mRegistered = false;
Adrian Roos25c7a582017-06-02 12:50:38 -0700434 float screenX = -1;
435 float screenY = -1;
436 if (mReportsTouchCoordinates && event.values.length >= 2) {
437 screenX = event.values[0];
438 screenY = event.values[1];
439 }
Lucas Dupinb2d9f482018-11-16 18:55:13 -0800440 mCallback.onSensorPulse(mPulseReason, sensorPerformsProxCheck, screenX, screenY,
441 event.values);
Lucas Dupin65104382018-12-04 11:53:42 -0800442 if (!mRegistered) {
443 updateListener(); // reregister, this sensor only fires once
444 }
Adrian Roos79bacbb2016-10-26 11:00:12 -0700445 }));
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700446 }
447
448 public void registerSettingsObserver(ContentObserver settingsObserver) {
449 if (mConfigured && !TextUtils.isEmpty(mSetting)) {
450 mResolver.registerContentObserver(
451 Settings.Secure.getUriFor(mSetting), false /* descendants */,
452 mSettingsObserver, UserHandle.USER_ALL);
453 }
454 }
455
Lucas Dupin323f9ff2018-08-27 16:55:56 -0700456 protected String triggerEventToString(TriggerEvent event) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700457 if (event == null) return null;
Lucas Dupin1ae6cf92018-12-14 18:06:38 -0800458 final StringBuilder sb = new StringBuilder("SensorEvent[")
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700459 .append(event.timestamp).append(',')
460 .append(event.sensor.getName());
461 if (event.values != null) {
462 for (int i = 0; i < event.values.length; i++) {
463 sb.append(',').append(event.values[i]);
464 }
465 }
466 return sb.append(']').toString();
467 }
468 }
469
Lucas Dupin3d951752018-10-10 12:00:40 -0700470 /**
Kevin Chynf7c39032018-10-11 00:44:39 -0700471 * A Sensor that is injected via plugin.
Lucas Dupin3d951752018-10-10 12:00:40 -0700472 */
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800473 @VisibleForTesting
474 class PluginSensor extends TriggerSensor implements SensorManagerPlugin.SensorEventListener {
Lucas Dupin3d951752018-10-10 12:00:40 -0700475
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800476 final SensorManagerPlugin.Sensor mPluginSensor;
477 private long mDebounce;
Lucas Dupin3d951752018-10-10 12:00:40 -0700478
Lucas Dupin1ae6cf92018-12-14 18:06:38 -0800479 PluginSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured,
Lucas Dupin3d951752018-10-10 12:00:40 -0700480 int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen) {
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800481 this(sensor, setting, configured, pulseReason, reportsTouchCoordinates,
482 requiresTouchscreen, 0L /* debounce */);
483 }
484
485 PluginSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured,
486 int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen,
487 long debounce) {
Lucas Dupin3d951752018-10-10 12:00:40 -0700488 super(null, setting, configured, pulseReason, reportsTouchCoordinates,
489 requiresTouchscreen);
490 mPluginSensor = sensor;
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800491 mDebounce = debounce;
Lucas Dupin3d951752018-10-10 12:00:40 -0700492 }
493
494 @Override
495 public void updateListener() {
496 if (!mConfigured) return;
497 AsyncSensorManager asyncSensorManager = (AsyncSensorManager) mSensorManager;
lpeter8a5f4702019-01-18 16:53:07 +0800498 if (mRequested && !mDisabled && (enabledBySetting() || mIgnoresSetting)
499 && !mRegistered) {
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800500 asyncSensorManager.registerPluginListener(mPluginSensor, this);
Lucas Dupin3d951752018-10-10 12:00:40 -0700501 mRegistered = true;
Lucas Dupin1ae6cf92018-12-14 18:06:38 -0800502 if (DEBUG) Log.d(TAG, "registerPluginListener");
Lucas Dupin3d951752018-10-10 12:00:40 -0700503 } else if (mRegistered) {
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800504 asyncSensorManager.unregisterPluginListener(mPluginSensor, this);
Lucas Dupin3d951752018-10-10 12:00:40 -0700505 mRegistered = false;
Lucas Dupin1ae6cf92018-12-14 18:06:38 -0800506 if (DEBUG) Log.d(TAG, "unregisterPluginListener");
Lucas Dupin3d951752018-10-10 12:00:40 -0700507 }
508 }
509
510 @Override
511 public String toString() {
512 return new StringBuilder("{mRegistered=").append(mRegistered)
513 .append(", mRequested=").append(mRequested)
514 .append(", mDisabled=").append(mDisabled)
515 .append(", mConfigured=").append(mConfigured)
lpeter8a5f4702019-01-18 16:53:07 +0800516 .append(", mIgnoresSetting=").append(mIgnoresSetting)
Lucas Dupin3d951752018-10-10 12:00:40 -0700517 .append(", mSensor=").append(mPluginSensor).append("}").toString();
518 }
519
Lucas Dupin1ae6cf92018-12-14 18:06:38 -0800520 private String triggerEventToString(SensorManagerPlugin.SensorEvent event) {
Lucas Dupinb2d9f482018-11-16 18:55:13 -0800521 if (event == null) return null;
522 final StringBuilder sb = new StringBuilder("PluginTriggerEvent[")
523 .append(event.getSensor()).append(',')
524 .append(event.getVendorType());
525 if (event.getValues() != null) {
526 for (int i = 0; i < event.getValues().length; i++) {
527 sb.append(',').append(event.getValues()[i]);
528 }
529 }
530 return sb.append(']').toString();
Lucas Dupin323f9ff2018-08-27 16:55:56 -0700531 }
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800532
533 @Override
534 public void onSensorChanged(SensorManagerPlugin.SensorEvent event) {
535 DozeLog.traceSensor(mContext, mPulseReason);
536 mHandler.post(mWakeLock.wrap(() -> {
537 final long now = SystemClock.uptimeMillis();
538 if (now < mDebounceFrom + mDebounce) {
539 if (DEBUG) Log.d(TAG, "onSensorEvent dropped: " + triggerEventToString(event));
540 return;
541 }
542 if (DEBUG) Log.d(TAG, "onSensorEvent: " + triggerEventToString(event));
543 mCallback.onSensorPulse(mPulseReason, true /* sensorPerformsProxCheck */, -1, -1,
544 event.getValues());
545 }));
546 }
Lucas Dupin323f9ff2018-08-27 16:55:56 -0700547 }
548
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700549 public interface Callback {
Adrian Roosd6ec13132016-10-27 11:50:47 -0700550
551 /**
552 * Called when a sensor requests a pulse
Lucas Dupin3d053532019-01-29 12:35:22 -0800553 * @param pulseReason Requesting sensor, e.g. {@link DozeLog#REASON_SENSOR_PICKUP}
Adrian Roosd6ec13132016-10-27 11:50:47 -0700554 * @param sensorPerformedProxCheck true if the sensor already checked for FAR proximity.
Adrian Roos25c7a582017-06-02 12:50:38 -0700555 * @param screenX the location on the screen where the sensor fired or -1
Lucas Dupinb2d9f482018-11-16 18:55:13 -0800556 * if the sensor doesn't support reporting screen locations.
Adrian Roos25c7a582017-06-02 12:50:38 -0700557 * @param screenY the location on the screen where the sensor fired or -1
Lucas Dupinb2d9f482018-11-16 18:55:13 -0800558 * @param rawValues raw values array from the event.
Adrian Roosd6ec13132016-10-27 11:50:47 -0700559 */
Adrian Roos25c7a582017-06-02 12:50:38 -0700560 void onSensorPulse(int pulseReason, boolean sensorPerformedProxCheck,
Lucas Dupinb2d9f482018-11-16 18:55:13 -0800561 float screenX, float screenY, float[] rawValues);
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700562 }
563}