blob: 44e5d3de5ca7e387afa81a0f2f5915e4290f578c [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;
29import android.hardware.SensorManager;
30import android.hardware.TriggerEvent;
31import android.hardware.TriggerEventListener;
Issei Suzukica19e6e2019-02-26 12:39:11 +010032import android.hardware.display.AmbientDisplayConfiguration;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070033import android.net.Uri;
34import android.os.Handler;
Adrian Roos6023ccb2017-06-28 16:22:02 +020035import android.os.SystemClock;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070036import android.os.UserHandle;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070037import android.provider.Settings;
38import android.text.TextUtils;
39import android.util.Log;
40
Lucas Dupin8a13aa72019-02-22 12:45:21 -080041import androidx.annotation.VisibleForTesting;
42
Adrian Roosff2c4562016-11-03 12:13:36 -070043import com.android.internal.logging.MetricsLogger;
Tamas Berghammer383db5eb2016-06-22 15:21:38 +010044import com.android.internal.logging.nano.MetricsProto;
Lucas Dupin3d951752018-10-10 12:00:40 -070045import com.android.systemui.plugins.SensorManagerPlugin;
Adrian Roosff2c4562016-11-03 12:13:36 -070046import com.android.systemui.statusbar.phone.DozeParameters;
Dave Mankoff63a12822019-09-16 14:38:06 -040047import com.android.systemui.util.sensors.AsyncSensorManager;
48import com.android.systemui.util.sensors.ProximitySensor;
Adrian Roosc1b50322017-02-27 21:07:58 +010049import com.android.systemui.util.wakelock.WakeLock;
Adrian Roosff2c4562016-11-03 12:13:36 -070050
51import java.io.PrintWriter;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070052import java.util.List;
Adrian Roos67cca742017-04-13 16:52:51 -070053import java.util.function.Consumer;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070054
55public class DozeSensors {
56
57 private static final boolean DEBUG = DozeService.DEBUG;
58
59 private static final String TAG = "DozeSensors";
60
61 private final Context mContext;
Adrian Roos6023ccb2017-06-28 16:22:02 +020062 private final AlarmManager mAlarmManager;
Dave Mankoff63a12822019-09-16 14:38:06 -040063 private final AsyncSensorManager mSensorManager;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070064 private final ContentResolver mResolver;
65 private final TriggerSensor mPickupSensor;
66 private final DozeParameters mDozeParameters;
67 private final AmbientDisplayConfiguration mConfig;
Adrian Roosc1b50322017-02-27 21:07:58 +010068 private final WakeLock mWakeLock;
Adrian Roos67cca742017-04-13 16:52:51 -070069 private final Consumer<Boolean> mProxCallback;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070070 private final Callback mCallback;
Lucas Dupin8a13aa72019-02-22 12:45:21 -080071 @VisibleForTesting
lpeteraca97632019-06-11 11:13:54 +080072 protected TriggerSensor[] mSensors;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070073
74 private final Handler mHandler = new Handler();
Dave Mankoff63a12822019-09-16 14:38:06 -040075 private final ProximitySensor mProximitySensor;
Lucas Dupin8a13aa72019-02-22 12:45:21 -080076 private long mDebounceFrom;
lpeteraca97632019-06-11 11:13:54 +080077 private boolean mSettingRegistered;
Lucas Dupinfac2e8e2019-06-27 16:10:19 -070078 private boolean mListening;
79 private boolean mPaused;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070080
Dave Mankoff63a12822019-09-16 14:38:06 -040081 public DozeSensors(Context context, AlarmManager alarmManager, AsyncSensorManager sensorManager,
Lucas Dupin323f9ff2018-08-27 16:55:56 -070082 DozeParameters dozeParameters, AmbientDisplayConfiguration config, WakeLock wakeLock,
Dave Mankoff86c73442019-12-17 12:15:16 -050083 Callback callback, Consumer<Boolean> proxCallback, DozeLog dozeLog) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -070084 mContext = context;
Adrian Roos6023ccb2017-06-28 16:22:02 +020085 mAlarmManager = alarmManager;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070086 mSensorManager = sensorManager;
87 mDozeParameters = dozeParameters;
88 mConfig = config;
89 mWakeLock = wakeLock;
Adrian Roos67cca742017-04-13 16:52:51 -070090 mProxCallback = proxCallback;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070091 mResolver = mContext.getContentResolver();
Dave Mankoff63a12822019-09-16 14:38:06 -040092 mCallback = callback;
Adrian Roosea8d6ae2016-10-26 10:40:12 -070093
Lucas Dupin70bda672018-12-27 15:43:40 -080094 boolean alwaysOn = mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT);
Adrian Roosea8d6ae2016-10-26 10:40:12 -070095 mSensors = new TriggerSensor[] {
96 new TriggerSensor(
97 mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
98 null /* setting */,
99 dozeParameters.getPulseOnSigMotion(),
Ned Burns30d67702020-01-28 12:58:45 -0500100 DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */,
Beverlycc4a62f2019-09-26 14:55:28 -0400101 false /* touchscreen */, dozeLog),
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700102 mPickupSensor = new TriggerSensor(
103 mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
Lucas Dupin4359b552018-08-09 15:07:54 -0700104 Settings.Secure.DOZE_PICK_UP_GESTURE,
Lucas Dupinfac2e8e2019-06-27 16:10:19 -0700105 true /* settingDef */,
Lucas Dupin4359b552018-08-09 15:07:54 -0700106 config.dozePickupSensorAvailable(),
Ned Burns30d67702020-01-28 12:58:45 -0500107 DozeLog.REASON_SENSOR_PICKUP, false /* touchCoords */,
Lucas Dupinfac2e8e2019-06-27 16:10:19 -0700108 false /* touchscreen */,
Beverlycc4a62f2019-09-26 14:55:28 -0400109 false /* ignoresSetting */,
110 dozeLog),
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700111 new TriggerSensor(
112 findSensorWithType(config.doubleTapSensorType()),
Lucas Dupin4359b552018-08-09 15:07:54 -0700113 Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700114 true /* configured */,
Ned Burns30d67702020-01-28 12:58:45 -0500115 DozeLog.REASON_SENSOR_DOUBLE_TAP,
Adrian Roos98d31982017-08-02 20:50:16 +0200116 dozeParameters.doubleTapReportsTouchCoordinates(),
Beverlycc4a62f2019-09-26 14:55:28 -0400117 true /* touchscreen */,
118 dozeLog),
Adrian Roosd0963a02017-05-15 14:33:37 -0700119 new TriggerSensor(
Lucas Dupind43bf702019-01-15 13:40:42 -0800120 findSensorWithType(config.tapSensorType()),
121 Settings.Secure.DOZE_TAP_SCREEN_GESTURE,
122 true /* configured */,
Ned Burns30d67702020-01-28 12:58:45 -0500123 DozeLog.REASON_SENSOR_TAP,
Lucas Dupind43bf702019-01-15 13:40:42 -0800124 false /* reports touch coordinates */,
Beverlycc4a62f2019-09-26 14:55:28 -0400125 true /* touchscreen */,
126 dozeLog),
Lucas Dupind43bf702019-01-15 13:40:42 -0800127 new TriggerSensor(
Adrian Roosd0963a02017-05-15 14:33:37 -0700128 findSensorWithType(config.longPressSensorType()),
129 Settings.Secure.DOZE_PULSE_ON_LONG_PRESS,
130 false /* settingDef */,
131 true /* configured */,
Ned Burns30d67702020-01-28 12:58:45 -0500132 DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
Adrian Roos98d31982017-08-02 20:50:16 +0200133 true /* reports touch coordinates */,
Beverlycc4a62f2019-09-26 14:55:28 -0400134 true /* touchscreen */,
135 dozeLog),
Lucas Dupin1ae6cf92018-12-14 18:06:38 -0800136 new PluginSensor(
Lucas Dupinb2d9f482018-11-16 18:55:13 -0800137 new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY),
Lucas Dupin7c7b8c22019-06-12 15:23:17 -0700138 Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
Lucas Dupin70bda672018-12-27 15:43:40 -0800139 mConfig.wakeScreenGestureAvailable() && alwaysOn,
Ned Burns30d67702020-01-28 12:58:45 -0500140 DozeLog.REASON_SENSOR_WAKE_UP,
Lucas Dupinb2d9f482018-11-16 18:55:13 -0800141 false /* reports touch coordinates */,
Beverlycc4a62f2019-09-26 14:55:28 -0400142 false /* touchscreen */,
143 dozeLog),
Lucas Dupinde64ee02018-12-21 14:45:12 -0800144 new PluginSensor(
145 new SensorManagerPlugin.Sensor(TYPE_WAKE_LOCK_SCREEN),
Lucas Dupin7c7b8c22019-06-12 15:23:17 -0700146 Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
147 mConfig.wakeScreenGestureAvailable(),
Ned Burns30d67702020-01-28 12:58:45 -0500148 DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN,
Lucas Dupinde64ee02018-12-21 14:45:12 -0800149 false /* reports touch coordinates */,
Beverlycc4a62f2019-09-26 14:55:28 -0400150 false /* touchscreen */,
151 mConfig.getWakeLockScreenDebounce(),
152 dozeLog),
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700153 };
Adrian Roos67cca742017-04-13 16:52:51 -0700154
Dave Mankoffd94c9692019-10-18 12:38:21 -0400155 mProximitySensor = new ProximitySensor(context.getResources(), sensorManager);
Dave Mankoff86c73442019-12-17 12:15:16 -0500156 setProxListening(false); // Don't immediately start listening when we register.
Dave Mankoff63a12822019-09-16 14:38:06 -0400157 mProximitySensor.register(
Dave Mankoffa8a82562019-09-25 09:48:12 -0400158 proximityEvent -> {
159 if (proximityEvent != null) {
160 mProxCallback.accept(!proximityEvent.getNear());
161 }
162 });
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700163 }
164
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800165 /**
166 * Temporarily disable some sensors to avoid turning on the device while the user is
167 * turning it off.
168 */
169 public void requestTemporaryDisable() {
170 mDebounceFrom = SystemClock.uptimeMillis();
171 }
172
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700173 private Sensor findSensorWithType(String type) {
Adrian Roos2981eb02017-05-26 18:40:09 -0700174 return findSensorWithType(mSensorManager, type);
175 }
176
177 static Sensor findSensorWithType(SensorManager sensorManager, String type) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700178 if (TextUtils.isEmpty(type)) {
179 return null;
180 }
Adrian Roos2981eb02017-05-26 18:40:09 -0700181 List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700182 for (Sensor s : sensorList) {
183 if (type.equals(s.getStringType())) {
184 return s;
185 }
186 }
187 return null;
188 }
189
Lucas Dupinfac2e8e2019-06-27 16:10:19 -0700190 /**
191 * If sensors should be registered and sending signals.
192 */
Adrian Roosd6ec13132016-10-27 11:50:47 -0700193 public void setListening(boolean listen) {
Lucas Dupinfac2e8e2019-06-27 16:10:19 -0700194 if (mListening == listen) {
195 return;
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700196 }
Lucas Dupinfac2e8e2019-06-27 16:10:19 -0700197 mListening = listen;
198 updateListening();
199 }
200
201 /**
202 * Unregister sensors, when listening, unless they are prox gated.
203 * @see #setListening(boolean)
204 */
205 public void setPaused(boolean paused) {
206 if (mPaused == paused) {
207 return;
208 }
209 mPaused = paused;
210 updateListening();
211 }
212
Lucas Dupin3174c662019-07-15 15:49:54 -0700213 /**
214 * Registers/unregisters sensors based on internal state.
215 */
216 public void updateListening() {
Lucas Dupinfac2e8e2019-06-27 16:10:19 -0700217 boolean anyListening = false;
218 for (TriggerSensor s : mSensors) {
Lucas Dupinf40bd8f2019-08-07 15:55:00 -0700219 s.setListening(mListening);
220 if (mListening) {
Lucas Dupinfac2e8e2019-06-27 16:10:19 -0700221 anyListening = true;
222 }
223 }
224
225 if (!anyListening) {
226 mResolver.unregisterContentObserver(mSettingsObserver);
227 } else if (!mSettingRegistered) {
228 for (TriggerSensor s : mSensors) {
229 s.registerSettingsObserver(mSettingsObserver);
230 }
231 }
232 mSettingRegistered = anyListening;
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700233 }
234
Adrian Roos98d31982017-08-02 20:50:16 +0200235 /** Set the listening state of only the sensors that require the touchscreen. */
236 public void setTouchscreenSensorsListening(boolean listening) {
237 for (TriggerSensor sensor : mSensors) {
238 if (sensor.mRequiresTouchscreen) {
239 sensor.setListening(listening);
240 }
241 }
242 }
243
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700244 public void onUserSwitched() {
245 for (TriggerSensor s : mSensors) {
Lucas Dupin3174c662019-07-15 15:49:54 -0700246 s.updateListening();
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700247 }
248 }
249
Adrian Roos67cca742017-04-13 16:52:51 -0700250 public void setProxListening(boolean listen) {
Dave Mankoff63a12822019-09-16 14:38:06 -0400251 if (mProximitySensor.isRegistered() && listen) {
252 mProximitySensor.alertListeners();
253 } else {
254 if (listen) {
255 mProximitySensor.resume();
256 } else {
257 mProximitySensor.pause();
258 }
259 }
Adrian Roos67cca742017-04-13 16:52:51 -0700260 }
261
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700262 private final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
263 @Override
264 public void onChange(boolean selfChange, Uri uri, int userId) {
265 if (userId != ActivityManager.getCurrentUser()) {
266 return;
267 }
268 for (TriggerSensor s : mSensors) {
Lucas Dupin3174c662019-07-15 15:49:54 -0700269 s.updateListening();
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700270 }
271 }
272 };
273
274 public void setDisableSensorsInterferingWithProximity(boolean disable) {
275 mPickupSensor.setDisabled(disable);
276 }
277
lpeter8a5f4702019-01-18 16:53:07 +0800278 /** Ignore the setting value of only the sensors that require the touchscreen. */
279 public void ignoreTouchScreenSensorsSettingInterferingWithDocking(boolean ignore) {
280 for (TriggerSensor sensor : mSensors) {
281 if (sensor.mRequiresTouchscreen) {
282 sensor.ignoreSetting(ignore);
283 }
284 }
285 }
286
Adrian Roosff2c4562016-11-03 12:13:36 -0700287 /** Dump current state */
288 public void dump(PrintWriter pw) {
289 for (TriggerSensor s : mSensors) {
Dave Mankoff63a12822019-09-16 14:38:06 -0400290 pw.println(" Sensor: " + s.toString());
Adrian Roosff2c4562016-11-03 12:13:36 -0700291 }
Dave Mankoff63a12822019-09-16 14:38:06 -0400292 pw.println(" ProxSensor: " + mProximitySensor.toString());
Adrian Roosff2c4562016-11-03 12:13:36 -0700293 }
294
Adrian Roos70da03a2017-07-24 16:42:57 +0200295 /**
Dave Mankoff63a12822019-09-16 14:38:06 -0400296 * @return true if prox is currently near, false if far or null if unknown.
Adrian Roos70da03a2017-07-24 16:42:57 +0200297 */
Dave Mankoff63a12822019-09-16 14:38:06 -0400298 public Boolean isProximityCurrentlyNear() {
299 return mProximitySensor.isNear();
Adrian Roos67cca742017-04-13 16:52:51 -0700300 }
301
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800302 @VisibleForTesting
303 class TriggerSensor extends TriggerEventListener {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700304 final Sensor mSensor;
305 final boolean mConfigured;
306 final int mPulseReason;
Lucas Dupinfac2e8e2019-06-27 16:10:19 -0700307 private final String mSetting;
308 private final boolean mReportsTouchCoordinates;
309 private final boolean mSettingDefault;
310 private final boolean mRequiresTouchscreen;
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700311
Lucas Dupin323f9ff2018-08-27 16:55:56 -0700312 protected boolean mRequested;
313 protected boolean mRegistered;
314 protected boolean mDisabled;
lpeter8a5f4702019-01-18 16:53:07 +0800315 protected boolean mIgnoresSetting;
Beverlycc4a62f2019-09-26 14:55:28 -0400316 protected final DozeLog mDozeLog;
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700317
Adrian Roos25c7a582017-06-02 12:50:38 -0700318 public TriggerSensor(Sensor sensor, String setting, boolean configured, int pulseReason,
Beverlycc4a62f2019-09-26 14:55:28 -0400319 boolean reportsTouchCoordinates, boolean requiresTouchscreen, DozeLog dozeLog) {
Adrian Roosd0963a02017-05-15 14:33:37 -0700320 this(sensor, setting, true /* settingDef */, configured, pulseReason,
Beverlycc4a62f2019-09-26 14:55:28 -0400321 reportsTouchCoordinates, requiresTouchscreen, dozeLog);
Adrian Roosd0963a02017-05-15 14:33:37 -0700322 }
323
324 public TriggerSensor(Sensor sensor, String setting, boolean settingDef,
Adrian Roos98d31982017-08-02 20:50:16 +0200325 boolean configured, int pulseReason, boolean reportsTouchCoordinates,
Beverlycc4a62f2019-09-26 14:55:28 -0400326 boolean requiresTouchscreen, DozeLog dozeLog) {
lpeter8a5f4702019-01-18 16:53:07 +0800327 this(sensor, setting, settingDef, configured, pulseReason, reportsTouchCoordinates,
Beverlycc4a62f2019-09-26 14:55:28 -0400328 requiresTouchscreen, false /* ignoresSetting */, dozeLog);
lpeter8a5f4702019-01-18 16:53:07 +0800329 }
330
331 private TriggerSensor(Sensor sensor, String setting, boolean settingDef,
332 boolean configured, int pulseReason, boolean reportsTouchCoordinates,
Beverlycc4a62f2019-09-26 14:55:28 -0400333 boolean requiresTouchscreen, boolean ignoresSetting, DozeLog dozeLog) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700334 mSensor = sensor;
335 mSetting = setting;
Adrian Roosd0963a02017-05-15 14:33:37 -0700336 mSettingDefault = settingDef;
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700337 mConfigured = configured;
338 mPulseReason = pulseReason;
Adrian Roos25c7a582017-06-02 12:50:38 -0700339 mReportsTouchCoordinates = reportsTouchCoordinates;
Adrian Roos98d31982017-08-02 20:50:16 +0200340 mRequiresTouchscreen = requiresTouchscreen;
lpeter8a5f4702019-01-18 16:53:07 +0800341 mIgnoresSetting = ignoresSetting;
Beverlycc4a62f2019-09-26 14:55:28 -0400342 mDozeLog = dozeLog;
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700343 }
344
345 public void setListening(boolean listen) {
346 if (mRequested == listen) return;
347 mRequested = listen;
Lucas Dupin3174c662019-07-15 15:49:54 -0700348 updateListening();
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700349 }
350
351 public void setDisabled(boolean disabled) {
352 if (mDisabled == disabled) return;
353 mDisabled = disabled;
Lucas Dupin3174c662019-07-15 15:49:54 -0700354 updateListening();
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700355 }
356
lpeter8a5f4702019-01-18 16:53:07 +0800357 public void ignoreSetting(boolean ignored) {
358 if (mIgnoresSetting == ignored) return;
359 mIgnoresSetting = ignored;
Lucas Dupin3174c662019-07-15 15:49:54 -0700360 updateListening();
lpeter8a5f4702019-01-18 16:53:07 +0800361 }
362
Lucas Dupin3174c662019-07-15 15:49:54 -0700363 public void updateListening() {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700364 if (!mConfigured || mSensor == null) return;
lpeter8a5f4702019-01-18 16:53:07 +0800365 if (mRequested && !mDisabled && (enabledBySetting() || mIgnoresSetting)
366 && !mRegistered) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700367 mRegistered = mSensorManager.requestTriggerSensor(this, mSensor);
368 if (DEBUG) Log.d(TAG, "requestTriggerSensor " + mRegistered);
369 } else if (mRegistered) {
370 final boolean rt = mSensorManager.cancelTriggerSensor(this, mSensor);
371 if (DEBUG) Log.d(TAG, "cancelTriggerSensor " + rt);
372 mRegistered = false;
373 }
374 }
375
Lucas Dupin323f9ff2018-08-27 16:55:56 -0700376 protected boolean enabledBySetting() {
Jerry Chang5d3eb4472018-12-21 11:49:06 +0800377 if (!mConfig.enabled(UserHandle.USER_CURRENT)) {
378 return false;
379 } else if (TextUtils.isEmpty(mSetting)) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700380 return true;
381 }
Adrian Roosd0963a02017-05-15 14:33:37 -0700382 return Settings.Secure.getIntForUser(mResolver, mSetting, mSettingDefault ? 1 : 0,
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700383 UserHandle.USER_CURRENT) != 0;
384 }
385
386 @Override
387 public String toString() {
388 return new StringBuilder("{mRegistered=").append(mRegistered)
389 .append(", mRequested=").append(mRequested)
390 .append(", mDisabled=").append(mDisabled)
391 .append(", mConfigured=").append(mConfigured)
lpeter8a5f4702019-01-18 16:53:07 +0800392 .append(", mIgnoresSetting=").append(mIgnoresSetting)
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700393 .append(", mSensor=").append(mSensor).append("}").toString();
394 }
395
396 @Override
397 @AnyThread
398 public void onTrigger(TriggerEvent event) {
Beverlycc4a62f2019-09-26 14:55:28 -0400399 mDozeLog.traceSensor(mPulseReason);
Adrian Roos79bacbb2016-10-26 11:00:12 -0700400 mHandler.post(mWakeLock.wrap(() -> {
Adrian Roosd6ec13132016-10-27 11:50:47 -0700401 if (DEBUG) Log.d(TAG, "onTrigger: " + triggerEventToString(event));
Lucas Dupin3d951752018-10-10 12:00:40 -0700402 if (mSensor != null && mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700403 int subType = (int) event.values[0];
404 MetricsLogger.action(
Adrian Roos79bacbb2016-10-26 11:00:12 -0700405 mContext, MetricsProto.MetricsEvent.ACTION_AMBIENT_GESTURE,
406 subType);
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700407 }
408
409 mRegistered = false;
Adrian Roos25c7a582017-06-02 12:50:38 -0700410 float screenX = -1;
411 float screenY = -1;
412 if (mReportsTouchCoordinates && event.values.length >= 2) {
413 screenX = event.values[0];
414 screenY = event.values[1];
415 }
Lucas Dupinf40bd8f2019-08-07 15:55:00 -0700416 mCallback.onSensorPulse(mPulseReason, screenX, screenY, event.values);
Lucas Dupin65104382018-12-04 11:53:42 -0800417 if (!mRegistered) {
Lucas Dupin3174c662019-07-15 15:49:54 -0700418 updateListening(); // reregister, this sensor only fires once
Lucas Dupin65104382018-12-04 11:53:42 -0800419 }
Adrian Roos79bacbb2016-10-26 11:00:12 -0700420 }));
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700421 }
422
423 public void registerSettingsObserver(ContentObserver settingsObserver) {
424 if (mConfigured && !TextUtils.isEmpty(mSetting)) {
425 mResolver.registerContentObserver(
426 Settings.Secure.getUriFor(mSetting), false /* descendants */,
427 mSettingsObserver, UserHandle.USER_ALL);
428 }
429 }
430
Lucas Dupin323f9ff2018-08-27 16:55:56 -0700431 protected String triggerEventToString(TriggerEvent event) {
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700432 if (event == null) return null;
Lucas Dupin1ae6cf92018-12-14 18:06:38 -0800433 final StringBuilder sb = new StringBuilder("SensorEvent[")
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700434 .append(event.timestamp).append(',')
435 .append(event.sensor.getName());
436 if (event.values != null) {
437 for (int i = 0; i < event.values.length; i++) {
438 sb.append(',').append(event.values[i]);
439 }
440 }
441 return sb.append(']').toString();
442 }
443 }
444
Lucas Dupin3d951752018-10-10 12:00:40 -0700445 /**
Kevin Chynf7c39032018-10-11 00:44:39 -0700446 * A Sensor that is injected via plugin.
Lucas Dupin3d951752018-10-10 12:00:40 -0700447 */
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800448 @VisibleForTesting
449 class PluginSensor extends TriggerSensor implements SensorManagerPlugin.SensorEventListener {
Lucas Dupin3d951752018-10-10 12:00:40 -0700450
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800451 final SensorManagerPlugin.Sensor mPluginSensor;
452 private long mDebounce;
Lucas Dupin3d951752018-10-10 12:00:40 -0700453
Lucas Dupin1ae6cf92018-12-14 18:06:38 -0800454 PluginSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured,
Beverlycc4a62f2019-09-26 14:55:28 -0400455 int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen,
456 DozeLog dozeLog) {
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800457 this(sensor, setting, configured, pulseReason, reportsTouchCoordinates,
Beverlycc4a62f2019-09-26 14:55:28 -0400458 requiresTouchscreen, 0L /* debounce */, dozeLog);
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800459 }
460
461 PluginSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured,
462 int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen,
Beverlycc4a62f2019-09-26 14:55:28 -0400463 long debounce, DozeLog dozeLog) {
Lucas Dupin3d951752018-10-10 12:00:40 -0700464 super(null, setting, configured, pulseReason, reportsTouchCoordinates,
Beverlycc4a62f2019-09-26 14:55:28 -0400465 requiresTouchscreen, dozeLog);
Lucas Dupin3d951752018-10-10 12:00:40 -0700466 mPluginSensor = sensor;
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800467 mDebounce = debounce;
Lucas Dupin3d951752018-10-10 12:00:40 -0700468 }
469
470 @Override
Lucas Dupin3174c662019-07-15 15:49:54 -0700471 public void updateListening() {
Lucas Dupin3d951752018-10-10 12:00:40 -0700472 if (!mConfigured) return;
473 AsyncSensorManager asyncSensorManager = (AsyncSensorManager) mSensorManager;
lpeter8a5f4702019-01-18 16:53:07 +0800474 if (mRequested && !mDisabled && (enabledBySetting() || mIgnoresSetting)
475 && !mRegistered) {
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800476 asyncSensorManager.registerPluginListener(mPluginSensor, this);
Lucas Dupin3d951752018-10-10 12:00:40 -0700477 mRegistered = true;
Lucas Dupin1ae6cf92018-12-14 18:06:38 -0800478 if (DEBUG) Log.d(TAG, "registerPluginListener");
Lucas Dupin3d951752018-10-10 12:00:40 -0700479 } else if (mRegistered) {
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800480 asyncSensorManager.unregisterPluginListener(mPluginSensor, this);
Lucas Dupin3d951752018-10-10 12:00:40 -0700481 mRegistered = false;
Lucas Dupin1ae6cf92018-12-14 18:06:38 -0800482 if (DEBUG) Log.d(TAG, "unregisterPluginListener");
Lucas Dupin3d951752018-10-10 12:00:40 -0700483 }
484 }
485
486 @Override
487 public String toString() {
488 return new StringBuilder("{mRegistered=").append(mRegistered)
489 .append(", mRequested=").append(mRequested)
490 .append(", mDisabled=").append(mDisabled)
491 .append(", mConfigured=").append(mConfigured)
lpeter8a5f4702019-01-18 16:53:07 +0800492 .append(", mIgnoresSetting=").append(mIgnoresSetting)
Lucas Dupin3d951752018-10-10 12:00:40 -0700493 .append(", mSensor=").append(mPluginSensor).append("}").toString();
494 }
495
Lucas Dupin1ae6cf92018-12-14 18:06:38 -0800496 private String triggerEventToString(SensorManagerPlugin.SensorEvent event) {
Lucas Dupinb2d9f482018-11-16 18:55:13 -0800497 if (event == null) return null;
498 final StringBuilder sb = new StringBuilder("PluginTriggerEvent[")
499 .append(event.getSensor()).append(',')
500 .append(event.getVendorType());
501 if (event.getValues() != null) {
502 for (int i = 0; i < event.getValues().length; i++) {
503 sb.append(',').append(event.getValues()[i]);
504 }
505 }
506 return sb.append(']').toString();
Lucas Dupin323f9ff2018-08-27 16:55:56 -0700507 }
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800508
509 @Override
510 public void onSensorChanged(SensorManagerPlugin.SensorEvent event) {
Beverlycc4a62f2019-09-26 14:55:28 -0400511 mDozeLog.traceSensor(mPulseReason);
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800512 mHandler.post(mWakeLock.wrap(() -> {
513 final long now = SystemClock.uptimeMillis();
514 if (now < mDebounceFrom + mDebounce) {
Lucas Dupinbca7ec72019-05-30 10:24:54 -0700515 Log.d(TAG, "onSensorEvent dropped: " + triggerEventToString(event));
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800516 return;
517 }
518 if (DEBUG) Log.d(TAG, "onSensorEvent: " + triggerEventToString(event));
Lucas Dupinf40bd8f2019-08-07 15:55:00 -0700519 mCallback.onSensorPulse(mPulseReason, -1, -1, event.getValues());
Lucas Dupin8a13aa72019-02-22 12:45:21 -0800520 }));
521 }
Lucas Dupin323f9ff2018-08-27 16:55:56 -0700522 }
523
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700524 public interface Callback {
Adrian Roosd6ec13132016-10-27 11:50:47 -0700525
526 /**
527 * Called when a sensor requests a pulse
Ned Burns30d67702020-01-28 12:58:45 -0500528 * @param pulseReason Requesting sensor, e.g. {@link DozeLog#REASON_SENSOR_PICKUP}
Adrian Roos25c7a582017-06-02 12:50:38 -0700529 * @param screenX the location on the screen where the sensor fired or -1
Lucas Dupinf40bd8f2019-08-07 15:55:00 -0700530 * if the sensor doesn't support reporting screen locations.
Adrian Roos25c7a582017-06-02 12:50:38 -0700531 * @param screenY the location on the screen where the sensor fired or -1
Lucas Dupinb2d9f482018-11-16 18:55:13 -0800532 * @param rawValues raw values array from the event.
Adrian Roosd6ec13132016-10-27 11:50:47 -0700533 */
Lucas Dupinf40bd8f2019-08-07 15:55:00 -0700534 void onSensorPulse(int pulseReason, float screenX, float screenY, float[] rawValues);
Adrian Roosea8d6ae2016-10-26 10:40:12 -0700535 }
536}