Merge "Update DozeSensors and DozeBrightnessSensor on posture changes" into sc-v2-dev

This commit is contained in:
TreeHugger Robot
2021-10-18 20:11:34 +00:00
committed by Android (Google) Code Review
17 changed files with 700 additions and 191 deletions

View File

@@ -22,11 +22,9 @@ import android.os.Build;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import java.util.Arrays;
import com.android.internal.R; import com.android.internal.R;
import com.android.internal.util.ArrayUtils;
/** /**
* AmbientDisplayConfiguration encapsulates reading access to the configuration of ambient display. * AmbientDisplayConfiguration encapsulates reading access to the configuration of ambient display.
@@ -90,7 +88,12 @@ public class AmbientDisplayConfiguration {
/** {@hide} */ /** {@hide} */
public boolean tapSensorAvailable() { public boolean tapSensorAvailable() {
return !TextUtils.isEmpty(tapSensorType()); for (String tapType : tapSensorTypeMapping()) {
if (!TextUtils.isEmpty(tapType)) {
return true;
}
}
return false;
} }
/** {@hide} */ /** {@hide} */
@@ -143,18 +146,18 @@ public class AmbientDisplayConfiguration {
return mContext.getResources().getString(R.string.config_dozeDoubleTapSensorType); return mContext.getResources().getString(R.string.config_dozeDoubleTapSensorType);
} }
/** {@hide} */ /** {@hide}
private String tapSensorType() { * May support multiple postures.
return mContext.getResources().getString(R.string.config_dozeTapSensorType); */
} public String[] tapSensorTypeMapping() {
String[] postureMapping =
/** {@hide} */ mContext.getResources().getStringArray(R.array.config_dozeTapSensorPostureMapping);
public String tapSensorType(int posture) { if (ArrayUtils.isEmpty(postureMapping)) {
return getSensorFromPostureMapping( return new String[] {
mContext.getResources().getStringArray(R.array.config_dozeTapSensorPostureMapping), mContext.getResources().getString(R.string.config_dozeTapSensorType)
tapSensorType(), };
posture }
); return postureMapping;
} }
/** {@hide} */ /** {@hide} */
@@ -253,20 +256,4 @@ public class AmbientDisplayConfiguration {
private boolean boolSetting(String name, int user, int def) { private boolean boolSetting(String name, int user, int def) {
return Settings.Secure.getIntForUser(mContext.getContentResolver(), name, def, user) != 0; return Settings.Secure.getIntForUser(mContext.getContentResolver(), name, def, user) != 0;
} }
/** {@hide} */
public static String getSensorFromPostureMapping(
String[] postureMapping,
String defaultValue,
int posture) {
String sensorType = defaultValue;
if (postureMapping != null && posture < postureMapping.length) {
sensorType = postureMapping[posture];
} else {
Log.e(TAG, "Unsupported doze posture " + posture
+ " postureMapping=" + Arrays.toString(postureMapping));
}
return TextUtils.isEmpty(sensorType) ? defaultValue : sensorType;
}
} }

View File

@@ -26,6 +26,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.Dumpable; import com.android.systemui.Dumpable;
import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager; import com.android.systemui.dump.DumpManager;
import com.android.systemui.statusbar.policy.DevicePostureController;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.PrintWriter; import java.io.PrintWriter;
@@ -267,6 +268,16 @@ public class DozeLog implements Dumpable {
} }
} }
/**
* Appends doze updates due to a posture change.
*/
public void tracePostureChanged(
@DevicePostureController.DevicePostureInt int posture,
String partUpdated
) {
mLogger.logPostureChanged(posture, partUpdated);
}
/** /**
* Appends pulse dropped event to logs * Appends pulse dropped event to logs
*/ */
@@ -391,8 +402,8 @@ public class DozeLog implements Dumpable {
case REASON_SENSOR_DOUBLE_TAP: return "doubletap"; case REASON_SENSOR_DOUBLE_TAP: return "doubletap";
case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress"; case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress";
case PULSE_REASON_DOCKING: return "docking"; case PULSE_REASON_DOCKING: return "docking";
case PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN: return "reach-wakelockscreen"; case PULSE_REASON_SENSOR_WAKE_REACH: return "reach-wakelockscreen";
case REASON_SENSOR_WAKE_UP: return "presence-wakeup"; case REASON_SENSOR_WAKE_UP_PRESENCE: return "presence-wakeup";
case REASON_SENSOR_TAP: return "tap"; case REASON_SENSOR_TAP: return "tap";
case REASON_SENSOR_UDFPS_LONG_PRESS: return "udfps"; case REASON_SENSOR_UDFPS_LONG_PRESS: return "udfps";
case REASON_SENSOR_QUICK_PICKUP: return "quickPickup"; case REASON_SENSOR_QUICK_PICKUP: return "quickPickup";
@@ -403,8 +414,8 @@ public class DozeLog implements Dumpable {
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef({PULSE_REASON_NONE, PULSE_REASON_INTENT, PULSE_REASON_NOTIFICATION, @IntDef({PULSE_REASON_NONE, PULSE_REASON_INTENT, PULSE_REASON_NOTIFICATION,
PULSE_REASON_SENSOR_SIGMOTION, REASON_SENSOR_PICKUP, REASON_SENSOR_DOUBLE_TAP, PULSE_REASON_SENSOR_SIGMOTION, REASON_SENSOR_PICKUP, REASON_SENSOR_DOUBLE_TAP,
PULSE_REASON_SENSOR_LONG_PRESS, PULSE_REASON_DOCKING, REASON_SENSOR_WAKE_UP, PULSE_REASON_SENSOR_LONG_PRESS, PULSE_REASON_DOCKING, REASON_SENSOR_WAKE_UP_PRESENCE,
PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, REASON_SENSOR_TAP, PULSE_REASON_SENSOR_WAKE_REACH, REASON_SENSOR_TAP,
REASON_SENSOR_UDFPS_LONG_PRESS, REASON_SENSOR_QUICK_PICKUP}) REASON_SENSOR_UDFPS_LONG_PRESS, REASON_SENSOR_QUICK_PICKUP})
public @interface Reason {} public @interface Reason {}
public static final int PULSE_REASON_NONE = -1; public static final int PULSE_REASON_NONE = -1;
@@ -415,8 +426,8 @@ public class DozeLog implements Dumpable {
public static final int REASON_SENSOR_DOUBLE_TAP = 4; public static final int REASON_SENSOR_DOUBLE_TAP = 4;
public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5; public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5;
public static final int PULSE_REASON_DOCKING = 6; public static final int PULSE_REASON_DOCKING = 6;
public static final int REASON_SENSOR_WAKE_UP = 7; public static final int REASON_SENSOR_WAKE_UP_PRESENCE = 7;
public static final int PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN = 8; public static final int PULSE_REASON_SENSOR_WAKE_REACH = 8;
public static final int REASON_SENSOR_TAP = 9; public static final int REASON_SENSOR_TAP = 9;
public static final int REASON_SENSOR_UDFPS_LONG_PRESS = 10; public static final int REASON_SENSOR_UDFPS_LONG_PRESS = 10;
public static final int REASON_SENSOR_QUICK_PICKUP = 11; public static final int REASON_SENSOR_QUICK_PICKUP = 11;

View File

@@ -24,6 +24,7 @@ import com.android.systemui.log.LogLevel.DEBUG
import com.android.systemui.log.LogLevel.ERROR import com.android.systemui.log.LogLevel.ERROR
import com.android.systemui.log.LogLevel.INFO import com.android.systemui.log.LogLevel.INFO
import com.android.systemui.log.dagger.DozeLog import com.android.systemui.log.dagger.DozeLog
import com.android.systemui.statusbar.policy.DevicePostureController
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
@@ -195,6 +196,16 @@ class DozeLogger @Inject constructor(
}) })
} }
fun logPostureChanged(posture: Int, partUpdated: String) {
buffer.log(TAG, INFO, {
int1 = posture
str1 = partUpdated
}, {
"Posture changed, posture=${DevicePostureController.devicePostureToString(int1)}" +
" partUpdated=$str1"
})
}
fun logPulseDropped(pulsePending: Boolean, state: DozeMachine.State, blocked: Boolean) { fun logPulseDropped(pulsePending: Boolean, state: DozeMachine.State, blocked: Boolean) {
buffer.log(TAG, INFO, { buffer.log(TAG, INFO, {
bool1 = pulsePending bool1 = pulsePending

View File

@@ -29,16 +29,18 @@ import android.os.SystemProperties;
import android.os.Trace; import android.os.Trace;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
import android.util.IndentingPrintWriter;
import com.android.systemui.dock.DockManager;
import com.android.systemui.doze.dagger.BrightnessSensor; import com.android.systemui.doze.dagger.BrightnessSensor;
import com.android.systemui.doze.dagger.DozeScope; import com.android.systemui.doze.dagger.DozeScope;
import com.android.systemui.doze.dagger.WrappedService; import com.android.systemui.doze.dagger.WrappedService;
import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.util.sensors.AsyncSensorManager; import com.android.systemui.util.sensors.AsyncSensorManager;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import javax.inject.Inject; import javax.inject.Inject;
@@ -60,14 +62,17 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi
private final DozeHost mDozeHost; private final DozeHost mDozeHost;
private final Handler mHandler; private final Handler mHandler;
private final SensorManager mSensorManager; private final SensorManager mSensorManager;
private final Optional<Sensor> mLightSensorOptional; private final Optional<Sensor>[] mLightSensorOptional; // light sensors to use per posture
private final WakefulnessLifecycle mWakefulnessLifecycle; private final WakefulnessLifecycle mWakefulnessLifecycle;
private final DozeParameters mDozeParameters; private final DozeParameters mDozeParameters;
private final DockManager mDockManager; private final DevicePostureController mDevicePostureController;
private final DozeLog mDozeLog;
private final int[] mSensorToBrightness; private final int[] mSensorToBrightness;
private final int[] mSensorToScrimOpacity; private final int[] mSensorToScrimOpacity;
private final int mScreenBrightnessDim; private final int mScreenBrightnessDim;
@DevicePostureController.DevicePostureInt
private int mDevicePosture;
private boolean mRegistered; private boolean mRegistered;
private int mDefaultDozeBrightness; private int mDefaultDozeBrightness;
private boolean mPaused = false; private boolean mPaused = false;
@@ -83,27 +88,36 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi
private int mDebugBrightnessBucket = -1; private int mDebugBrightnessBucket = -1;
@Inject @Inject
public DozeScreenBrightness(Context context, @WrappedService DozeMachine.Service service, public DozeScreenBrightness(
Context context,
@WrappedService DozeMachine.Service service,
AsyncSensorManager sensorManager, AsyncSensorManager sensorManager,
@BrightnessSensor Optional<Sensor> lightSensorOptional, DozeHost host, Handler handler, @BrightnessSensor Optional<Sensor>[] lightSensorOptional,
DozeHost host, Handler handler,
AlwaysOnDisplayPolicy alwaysOnDisplayPolicy, AlwaysOnDisplayPolicy alwaysOnDisplayPolicy,
WakefulnessLifecycle wakefulnessLifecycle, WakefulnessLifecycle wakefulnessLifecycle,
DozeParameters dozeParameters, DozeParameters dozeParameters,
DockManager dockManager) { DevicePostureController devicePostureController,
DozeLog dozeLog
) {
mContext = context; mContext = context;
mDozeService = service; mDozeService = service;
mSensorManager = sensorManager; mSensorManager = sensorManager;
mLightSensorOptional = lightSensorOptional; mLightSensorOptional = lightSensorOptional;
mDevicePostureController = devicePostureController;
mDevicePosture = mDevicePostureController.getDevicePosture();
mWakefulnessLifecycle = wakefulnessLifecycle; mWakefulnessLifecycle = wakefulnessLifecycle;
mDozeParameters = dozeParameters; mDozeParameters = dozeParameters;
mDozeHost = host; mDozeHost = host;
mHandler = handler; mHandler = handler;
mDockManager = dockManager; mDozeLog = dozeLog;
mDefaultDozeBrightness = alwaysOnDisplayPolicy.defaultDozeBrightness; mDefaultDozeBrightness = alwaysOnDisplayPolicy.defaultDozeBrightness;
mScreenBrightnessDim = alwaysOnDisplayPolicy.dimBrightness; mScreenBrightnessDim = alwaysOnDisplayPolicy.dimBrightness;
mSensorToBrightness = alwaysOnDisplayPolicy.screenBrightnessArray; mSensorToBrightness = alwaysOnDisplayPolicy.screenBrightnessArray;
mSensorToScrimOpacity = alwaysOnDisplayPolicy.dimmingScrimArray; mSensorToScrimOpacity = alwaysOnDisplayPolicy.dimmingScrimArray;
mDevicePostureController.addCallback(mDevicePostureCallback);
} }
@Override @Override
@@ -133,6 +147,7 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi
private void onDestroy() { private void onDestroy() {
setLightSensorEnabled(false); setLightSensorEnabled(false);
mDevicePostureController.removeCallback(mDevicePostureCallback);
} }
@Override @Override
@@ -159,7 +174,7 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi
} }
int scrimOpacity = -1; int scrimOpacity = -1;
if (!mLightSensorOptional.isPresent()) { if (!isLightSensorPresent()) {
// No light sensor, scrims are always transparent. // No light sensor, scrims are always transparent.
scrimOpacity = 0; scrimOpacity = 0;
} else if (brightnessReady) { } else if (brightnessReady) {
@@ -172,6 +187,27 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi
} }
} }
private boolean lightSensorSupportsCurrentPosture() {
return mLightSensorOptional != null
&& mDevicePosture < mLightSensorOptional.length;
}
private boolean isLightSensorPresent() {
if (!lightSensorSupportsCurrentPosture()) {
return mLightSensorOptional != null && mLightSensorOptional[0].isPresent();
}
return mLightSensorOptional[mDevicePosture].isPresent();
}
private Sensor getLightSensor() {
if (!lightSensorSupportsCurrentPosture()) {
return null;
}
return mLightSensorOptional[mDevicePosture].get();
}
private int computeScrimOpacity(int sensorValue) { private int computeScrimOpacity(int sensorValue) {
if (sensorValue < 0 || sensorValue >= mSensorToScrimOpacity.length) { if (sensorValue < 0 || sensorValue >= mSensorToScrimOpacity.length) {
return -1; return -1;
@@ -220,9 +256,9 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi
} }
private void setLightSensorEnabled(boolean enabled) { private void setLightSensorEnabled(boolean enabled) {
if (enabled && !mRegistered && mLightSensorOptional.isPresent()) { if (enabled && !mRegistered && isLightSensorPresent()) {
// Wait until we get an event from the sensor until indicating ready. // Wait until we get an event from the sensor until indicating ready.
mRegistered = mSensorManager.registerListener(this, mLightSensorOptional.get(), mRegistered = mSensorManager.registerListener(this, getLightSensor(),
SensorManager.SENSOR_DELAY_NORMAL, mHandler); SensorManager.SENSOR_DELAY_NORMAL, mHandler);
mLastSensorValue = -1; mLastSensorValue = -1;
} else if (!enabled && mRegistered) { } else if (!enabled && mRegistered) {
@@ -255,6 +291,41 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi
/** Dump current state */ /** Dump current state */
public void dump(PrintWriter pw) { public void dump(PrintWriter pw) {
pw.println("DozeScreenBrightnessSensorRegistered=" + mRegistered); pw.println("DozeScreenBrightness:");
IndentingPrintWriter idpw = new IndentingPrintWriter(pw);
idpw.increaseIndent();
idpw.println("registered=" + mRegistered);
idpw.println("posture=" + DevicePostureController.devicePostureToString(mDevicePosture));
} }
private final DevicePostureController.Callback mDevicePostureCallback =
new DevicePostureController.Callback() {
@Override
public void onPostureChanged(int posture) {
if (mDevicePosture == posture
|| mLightSensorOptional.length < 2
|| posture >= mLightSensorOptional.length) {
return;
}
final Sensor oldSensor = mLightSensorOptional[mDevicePosture].get();
final Sensor newSensor = mLightSensorOptional[posture].get();
if (Objects.equals(oldSensor, newSensor)) {
mDevicePosture = posture;
// uses the same sensor for the new posture
return;
}
// cancel the previous sensor:
if (mRegistered) {
setLightSensorEnabled(false);
mDevicePosture = posture;
setLightSensorEnabled(true);
} else {
mDevicePosture = posture;
}
mDozeLog.tracePostureChanged(mDevicePosture, "DozeScreenBrightness swap "
+ "{" + oldSensor + "} => {" + newSensor + "}, mRegistered=" + mRegistered);
}
};
} }

View File

@@ -38,6 +38,7 @@ import android.util.IndentingPrintWriter;
import android.util.Log; import android.util.Log;
import android.view.Display; import android.view.Display;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEvent;
@@ -54,10 +55,36 @@ import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.wakelock.WakeLock; import com.android.systemui.util.wakelock.WakeLock;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
/**
* Tracks and registers/unregisters sensors while the device is dozing based on the config
* provided by {@link AmbientDisplayConfiguration} and parameters provided by {@link DozeParameters}
*
* Sensors registration depends on:
* - sensor existence/availability
* - user configuration (some can be toggled on/off via settings)
* - use of the proximity sensor (sometimes prox cannot be registered in certain display states)
* - touch state
* - device posture
*
* Sensors will trigger the provided Callback's {@link Callback#onSensorPulse} method.
* These sensors include:
* - pickup gesture
* - single and double tap gestures
* - udfps long-press gesture
* - reach and presence gestures
* - quick pickup gesture (low-threshold pickup gesture)
*
* This class also registers a ProximitySensor that reports near/far events and will
* trigger callbacks on the provided {@link mProxCallback}.
*/
public class DozeSensors { public class DozeSensors {
private static final boolean DEBUG = DozeService.DEBUG; private static final boolean DEBUG = DozeService.DEBUG;
@@ -68,15 +95,21 @@ public class DozeSensors {
private final AsyncSensorManager mSensorManager; private final AsyncSensorManager mSensorManager;
private final AmbientDisplayConfiguration mConfig; private final AmbientDisplayConfiguration mConfig;
private final WakeLock mWakeLock; private final WakeLock mWakeLock;
private final Consumer<Boolean> mProxCallback; private final DozeLog mDozeLog;
private final SecureSettings mSecureSettings; private final SecureSettings mSecureSettings;
private final Callback mCallback; private final DevicePostureController mDevicePostureController;
private final boolean mScreenOffUdfpsEnabled; private final boolean mScreenOffUdfpsEnabled;
// Sensors
@VisibleForTesting @VisibleForTesting
protected TriggerSensor[] mSensors; protected TriggerSensor[] mTriggerSensors;
private final ProximitySensor mProximitySensor;
// Sensor callbacks
private final Callback mSensorCallback; // receives callbacks on registered sensor events
private final Consumer<Boolean> mProxCallback; // receives callbacks on near/far updates
private final Handler mHandler = new Handler(); private final Handler mHandler = new Handler();
private final ProximitySensor mProximitySensor;
private long mDebounceFrom; private long mDebounceFrom;
private boolean mSettingRegistered; private boolean mSettingRegistered;
private boolean mListening; private boolean mListening;
@@ -106,37 +139,47 @@ public class DozeSensors {
} }
} }
DozeSensors(Context context, AsyncSensorManager sensorManager, DozeSensors(
DozeParameters dozeParameters, AmbientDisplayConfiguration config, WakeLock wakeLock, Context context,
Callback callback, Consumer<Boolean> proxCallback, DozeLog dozeLog, AsyncSensorManager sensorManager,
ProximitySensor proximitySensor, SecureSettings secureSettings, DozeParameters dozeParameters,
AmbientDisplayConfiguration config,
WakeLock wakeLock,
Callback sensorCallback,
Consumer<Boolean> proxCallback,
DozeLog dozeLog,
ProximitySensor proximitySensor,
SecureSettings secureSettings,
AuthController authController, AuthController authController,
int devicePosture) { DevicePostureController devicePostureController
) {
mContext = context; mContext = context;
mSensorManager = sensorManager; mSensorManager = sensorManager;
mConfig = config; mConfig = config;
mWakeLock = wakeLock; mWakeLock = wakeLock;
mProxCallback = proxCallback; mProxCallback = proxCallback;
mSecureSettings = secureSettings; mSecureSettings = secureSettings;
mCallback = callback; mSensorCallback = sensorCallback;
mDozeLog = dozeLog;
mProximitySensor = proximitySensor; mProximitySensor = proximitySensor;
mProximitySensor.setTag(TAG); mProximitySensor.setTag(TAG);
mSelectivelyRegisterProxSensors = dozeParameters.getSelectivelyRegisterSensorsUsingProx(); mSelectivelyRegisterProxSensors = dozeParameters.getSelectivelyRegisterSensorsUsingProx();
mListeningProxSensors = !mSelectivelyRegisterProxSensors; mListeningProxSensors = !mSelectivelyRegisterProxSensors;
mScreenOffUdfpsEnabled = mScreenOffUdfpsEnabled =
config.screenOffUdfpsEnabled(KeyguardUpdateMonitor.getCurrentUser()); config.screenOffUdfpsEnabled(KeyguardUpdateMonitor.getCurrentUser());
mDevicePosture = devicePosture; mDevicePostureController = devicePostureController;
mDevicePosture = mDevicePostureController.getDevicePosture();
boolean udfpsEnrolled = boolean udfpsEnrolled =
authController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser()); authController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser());
boolean alwaysOn = mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT); boolean alwaysOn = mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT);
mSensors = new TriggerSensor[] { mTriggerSensors = new TriggerSensor[] {
new TriggerSensor( new TriggerSensor(
mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION), mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
null /* setting */, null /* setting */,
dozeParameters.getPulseOnSigMotion(), dozeParameters.getPulseOnSigMotion(),
DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */, DozeLog.PULSE_REASON_SENSOR_SIGMOTION, false /* touchCoords */,
false /* touchscreen */, dozeLog), false /* touchscreen */),
new TriggerSensor( new TriggerSensor(
mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE), mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
Settings.Secure.DOZE_PICK_UP_GESTURE, Settings.Secure.DOZE_PICK_UP_GESTURE,
@@ -145,18 +188,16 @@ public class DozeSensors {
DozeLog.REASON_SENSOR_PICKUP, false /* touchCoords */, DozeLog.REASON_SENSOR_PICKUP, false /* touchCoords */,
false /* touchscreen */, false /* touchscreen */,
false /* ignoresSetting */, false /* ignoresSetting */,
false /* requires prox */, false /* requires prox */),
dozeLog),
new TriggerSensor( new TriggerSensor(
findSensor(config.doubleTapSensorType()), findSensor(config.doubleTapSensorType()),
Settings.Secure.DOZE_DOUBLE_TAP_GESTURE, Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
true /* configured */, true /* configured */,
DozeLog.REASON_SENSOR_DOUBLE_TAP, DozeLog.REASON_SENSOR_DOUBLE_TAP,
dozeParameters.doubleTapReportsTouchCoordinates(), dozeParameters.doubleTapReportsTouchCoordinates(),
true /* touchscreen */, true /* touchscreen */),
dozeLog),
new TriggerSensor( new TriggerSensor(
findSensor(config.tapSensorType(mDevicePosture)), findSensors(config.tapSensorTypeMapping()),
Settings.Secure.DOZE_TAP_SCREEN_GESTURE, Settings.Secure.DOZE_TAP_SCREEN_GESTURE,
true /* settingDef */, true /* settingDef */,
true /* configured */, true /* configured */,
@@ -165,7 +206,7 @@ public class DozeSensors {
true /* touchscreen */, true /* touchscreen */,
false /* ignoresSetting */, false /* ignoresSetting */,
dozeParameters.singleTapUsesProx(mDevicePosture) /* requiresProx */, dozeParameters.singleTapUsesProx(mDevicePosture) /* requiresProx */,
dozeLog), mDevicePosture),
new TriggerSensor( new TriggerSensor(
findSensor(config.longPressSensorType()), findSensor(config.longPressSensorType()),
Settings.Secure.DOZE_PULSE_ON_LONG_PRESS, Settings.Secure.DOZE_PULSE_ON_LONG_PRESS,
@@ -175,8 +216,7 @@ public class DozeSensors {
true /* reports touch coordinates */, true /* reports touch coordinates */,
true /* touchscreen */, true /* touchscreen */,
false /* ignoresSetting */, false /* ignoresSetting */,
dozeParameters.longPressUsesProx() /* requiresProx */, dozeParameters.longPressUsesProx() /* requiresProx */),
dozeLog),
new TriggerSensor( new TriggerSensor(
findSensor(config.udfpsLongPressSensorType()), findSensor(config.udfpsLongPressSensorType()),
"doze_pulse_on_auth", "doze_pulse_on_auth",
@@ -186,25 +226,22 @@ public class DozeSensors {
true /* reports touch coordinates */, true /* reports touch coordinates */,
true /* touchscreen */, true /* touchscreen */,
false /* ignoresSetting */, false /* ignoresSetting */,
dozeParameters.longPressUsesProx(), dozeParameters.longPressUsesProx()),
dozeLog),
new PluginSensor( new PluginSensor(
new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY), new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY),
Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE, Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
mConfig.wakeScreenGestureAvailable() && alwaysOn, mConfig.wakeScreenGestureAvailable() && alwaysOn,
DozeLog.REASON_SENSOR_WAKE_UP, DozeLog.REASON_SENSOR_WAKE_UP_PRESENCE,
false /* reports touch coordinates */, false /* reports touch coordinates */,
false /* touchscreen */, false /* touchscreen */),
dozeLog),
new PluginSensor( new PluginSensor(
new SensorManagerPlugin.Sensor(TYPE_WAKE_LOCK_SCREEN), new SensorManagerPlugin.Sensor(TYPE_WAKE_LOCK_SCREEN),
Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE, Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
mConfig.wakeScreenGestureAvailable(), mConfig.wakeScreenGestureAvailable(),
DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, DozeLog.PULSE_REASON_SENSOR_WAKE_REACH,
false /* reports touch coordinates */, false /* reports touch coordinates */,
false /* touchscreen */, false /* touchscreen */,
mConfig.getWakeLockScreenDebounce(), mConfig.getWakeLockScreenDebounce()),
dozeLog),
new TriggerSensor( new TriggerSensor(
findSensor(config.quickPickupSensorType()), findSensor(config.quickPickupSensorType()),
Settings.Secure.DOZE_QUICK_PICKUP_GESTURE, Settings.Secure.DOZE_QUICK_PICKUP_GESTURE,
@@ -212,10 +249,11 @@ public class DozeSensors {
config.quickPickupSensorEnabled(KeyguardUpdateMonitor.getCurrentUser()) config.quickPickupSensorEnabled(KeyguardUpdateMonitor.getCurrentUser())
&& udfpsEnrolled, && udfpsEnrolled,
DozeLog.REASON_SENSOR_QUICK_PICKUP, DozeLog.REASON_SENSOR_QUICK_PICKUP,
false /* touchCoords */, false /* requiresTouchCoordinates */,
false /* touchscreen */, dozeLog), false /* requiresTouchscreen */,
false /* ignoresSetting */,
false /* requiresProx */),
}; };
setProxListening(false); // Don't immediately start listening when we register. setProxListening(false); // Don't immediately start listening when we register.
mProximitySensor.register( mProximitySensor.register(
proximityEvent -> { proximityEvent -> {
@@ -223,17 +261,21 @@ public class DozeSensors {
mProxCallback.accept(!proximityEvent.getBelow()); mProxCallback.accept(!proximityEvent.getBelow());
} }
}); });
mDevicePostureController.addCallback(mDevicePostureCallback);
} }
/** /**
* Unregister any sensors. * Unregister all sensors and callbacks.
*/ */
public void destroy() { public void destroy() {
// Unregisters everything, which is enough to allow gc. // Unregisters everything, which is enough to allow gc.
for (TriggerSensor triggerSensor : mSensors) { for (TriggerSensor triggerSensor : mTriggerSensors) {
triggerSensor.setListening(false); triggerSensor.setListening(false);
} }
mProximitySensor.pause(); mProximitySensor.pause();
mDevicePostureController.removeCallback(mDevicePostureCallback);
} }
/** /**
@@ -248,6 +290,24 @@ public class DozeSensors {
return findSensor(mSensorManager, type, null); return findSensor(mSensorManager, type, null);
} }
@NonNull
private Sensor[] findSensors(@NonNull String[] types) {
Sensor[] sensorMap = new Sensor[DevicePostureController.SUPPORTED_POSTURES_SIZE];
// Map of sensorType => Sensor, so we reuse the same sensor if it's the same between
// postures
Map<String, Sensor> typeToSensorMap = new HashMap<>();
for (int i = 0; i < types.length; i++) {
String sensorType = types[i];
if (!typeToSensorMap.containsKey(sensorType)) {
typeToSensorMap.put(sensorType, findSensor(sensorType));
}
sensorMap[i] = typeToSensorMap.get(sensorType);
}
return sensorMap;
}
/** /**
* Utility method to find a {@link Sensor} for the supplied string type and string name. * Utility method to find a {@link Sensor} for the supplied string type and string name.
* *
@@ -306,7 +366,7 @@ public class DozeSensors {
*/ */
private void updateListening() { private void updateListening() {
boolean anyListening = false; boolean anyListening = false;
for (TriggerSensor s : mSensors) { for (TriggerSensor s : mTriggerSensors) {
boolean listen = mListening boolean listen = mListening
&& (!s.mRequiresTouchscreen || mListeningTouchScreenSensors) && (!s.mRequiresTouchscreen || mListeningTouchScreenSensors)
&& (!s.mRequiresProx || mListeningProxSensors); && (!s.mRequiresProx || mListeningProxSensors);
@@ -319,7 +379,7 @@ public class DozeSensors {
if (!anyListening) { if (!anyListening) {
mSecureSettings.unregisterContentObserver(mSettingsObserver); mSecureSettings.unregisterContentObserver(mSettingsObserver);
} else if (!mSettingRegistered) { } else if (!mSettingRegistered) {
for (TriggerSensor s : mSensors) { for (TriggerSensor s : mTriggerSensors) {
s.registerSettingsObserver(mSettingsObserver); s.registerSettingsObserver(mSettingsObserver);
} }
} }
@@ -328,7 +388,7 @@ public class DozeSensors {
/** Set the listening state of only the sensors that require the touchscreen. */ /** Set the listening state of only the sensors that require the touchscreen. */
public void setTouchscreenSensorsListening(boolean listening) { public void setTouchscreenSensorsListening(boolean listening) {
for (TriggerSensor sensor : mSensors) { for (TriggerSensor sensor : mTriggerSensors) {
if (sensor.mRequiresTouchscreen) { if (sensor.mRequiresTouchscreen) {
sensor.setListening(listening); sensor.setListening(listening);
} }
@@ -336,7 +396,7 @@ public class DozeSensors {
} }
public void onUserSwitched() { public void onUserSwitched() {
for (TriggerSensor s : mSensors) { for (TriggerSensor s : mTriggerSensors) {
s.updateListening(); s.updateListening();
} }
} }
@@ -366,7 +426,7 @@ public class DozeSensors {
if (userId != ActivityManager.getCurrentUser()) { if (userId != ActivityManager.getCurrentUser()) {
return; return;
} }
for (TriggerSensor s : mSensors) { for (TriggerSensor s : mTriggerSensors) {
s.updateListening(); s.updateListening();
} }
} }
@@ -374,7 +434,7 @@ public class DozeSensors {
/** Ignore the setting value of only the sensors that require the touchscreen. */ /** Ignore the setting value of only the sensors that require the touchscreen. */
public void ignoreTouchScreenSensorsSettingInterferingWithDocking(boolean ignore) { public void ignoreTouchScreenSensorsSettingInterferingWithDocking(boolean ignore) {
for (TriggerSensor sensor : mSensors) { for (TriggerSensor sensor : mTriggerSensors) {
if (sensor.mRequiresTouchscreen) { if (sensor.mRequiresTouchscreen) {
sensor.ignoreSetting(ignore); sensor.ignoreSetting(ignore);
} }
@@ -392,7 +452,7 @@ public class DozeSensors {
pw.println("mScreenOffUdfpsEnabled=" + mScreenOffUdfpsEnabled); pw.println("mScreenOffUdfpsEnabled=" + mScreenOffUdfpsEnabled);
IndentingPrintWriter idpw = new IndentingPrintWriter(pw); IndentingPrintWriter idpw = new IndentingPrintWriter(pw);
idpw.increaseIndent(); idpw.increaseIndent();
for (TriggerSensor s : mSensors) { for (TriggerSensor s : mTriggerSensors) {
idpw.println("Sensor: " + s.toString()); idpw.println("Sensor: " + s.toString());
} }
idpw.println("ProxSensor: " + mProximitySensor.toString()); idpw.println("ProxSensor: " + mProximitySensor.toString());
@@ -407,7 +467,7 @@ public class DozeSensors {
@VisibleForTesting @VisibleForTesting
class TriggerSensor extends TriggerEventListener { class TriggerSensor extends TriggerEventListener {
final Sensor mSensor; @NonNull final Sensor[] mSensors; // index = posture, value = sensor
final boolean mConfigured; final boolean mConfigured;
final int mPulseReason; final int mPulseReason;
private final String mSetting; private final String mSetting;
@@ -420,27 +480,67 @@ public class DozeSensors {
protected boolean mRegistered; protected boolean mRegistered;
protected boolean mDisabled; protected boolean mDisabled;
protected boolean mIgnoresSetting; protected boolean mIgnoresSetting;
protected final DozeLog mDozeLog; private @DevicePostureController.DevicePostureInt int mPosture;
public TriggerSensor(Sensor sensor, String setting, boolean configured, int pulseReason, TriggerSensor(
boolean reportsTouchCoordinates, boolean requiresTouchscreen, DozeLog dozeLog) { Sensor sensor,
this(sensor, setting, true /* settingDef */, configured, pulseReason, String setting,
reportsTouchCoordinates, requiresTouchscreen, dozeLog); boolean configured,
int pulseReason,
boolean reportsTouchCoordinates,
boolean requiresTouchscreen
) {
this(
sensor,
setting,
true /* settingDef */,
configured,
pulseReason,
false /* ignoresSetting */,
false /* requiresProx */,
reportsTouchCoordinates,
requiresTouchscreen
);
} }
public TriggerSensor(Sensor sensor, String setting, boolean settingDef, TriggerSensor(
boolean configured, int pulseReason, boolean reportsTouchCoordinates, Sensor sensor,
boolean requiresTouchscreen, DozeLog dozeLog) { String setting,
this(sensor, setting, settingDef, configured, pulseReason, reportsTouchCoordinates, boolean settingDef,
requiresTouchscreen, false /* ignoresSetting */, boolean configured,
false /* requiresProx */, dozeLog); int pulseReason,
boolean reportsTouchCoordinates,
boolean requiresTouchscreen,
boolean ignoresSetting,
boolean requiresProx
) {
this(
new Sensor[]{ sensor },
setting,
settingDef,
configured,
pulseReason,
reportsTouchCoordinates,
requiresTouchscreen,
ignoresSetting,
requiresProx,
DevicePostureController.DEVICE_POSTURE_UNKNOWN
);
} }
private TriggerSensor(Sensor sensor, String setting, boolean settingDef, TriggerSensor(
boolean configured, int pulseReason, boolean reportsTouchCoordinates, @NonNull Sensor[] sensors,
boolean requiresTouchscreen, boolean ignoresSetting, boolean requiresProx, String setting,
DozeLog dozeLog) { boolean settingDef,
mSensor = sensor; boolean configured,
int pulseReason,
boolean reportsTouchCoordinates,
boolean requiresTouchscreen,
boolean ignoresSetting,
boolean requiresProx,
@DevicePostureController.DevicePostureInt int posture
) {
mSensors = sensors;
mSetting = setting; mSetting = setting;
mSettingDefault = settingDef; mSettingDefault = settingDef;
mConfigured = configured; mConfigured = configured;
@@ -449,7 +549,43 @@ public class DozeSensors {
mRequiresTouchscreen = requiresTouchscreen; mRequiresTouchscreen = requiresTouchscreen;
mIgnoresSetting = ignoresSetting; mIgnoresSetting = ignoresSetting;
mRequiresProx = requiresProx; mRequiresProx = requiresProx;
mDozeLog = dozeLog; mPosture = posture;
}
/**
* @return true if the sensor changed based for the new posture
*/
public boolean setPosture(@DevicePostureController.DevicePostureInt int posture) {
if (mPosture == posture
|| mSensors.length < 2
|| posture >= mSensors.length) {
return false;
}
Sensor oldSensor = mSensors[mPosture];
Sensor newSensor = mSensors[posture];
if (Objects.equals(oldSensor, newSensor)) {
mPosture = posture;
// uses the same sensor for the new posture
return false;
}
// cancel the previous sensor:
if (mRegistered) {
final boolean rt = mSensorManager.cancelTriggerSensor(this, oldSensor);
if (DEBUG) {
Log.d(TAG, "posture changed, cancelTriggerSensor[" + oldSensor + "] "
+ rt);
}
mRegistered = false;
}
// update the new sensor:
mPosture = posture;
updateListening();
mDozeLog.tracePostureChanged(mPosture, "DozeSensors swap "
+ "{" + oldSensor + "} => {" + newSensor + "}, mRegistered=" + mRegistered);
return true;
} }
public void setListening(boolean listen) { public void setListening(boolean listen) {
@@ -471,24 +607,23 @@ public class DozeSensors {
} }
public void updateListening() { public void updateListening() {
if (!mConfigured || mSensor == null) return; final Sensor sensor = mSensors[mPosture];
if (!mConfigured || sensor == null) return;
if (mRequested && !mDisabled && (enabledBySetting() || mIgnoresSetting)) { if (mRequested && !mDisabled && (enabledBySetting() || mIgnoresSetting)) {
if (!mRegistered) { if (!mRegistered) {
mRegistered = mSensorManager.requestTriggerSensor(this, mSensor); mRegistered = mSensorManager.requestTriggerSensor(this, sensor);
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "requestTriggerSensor[" + mSensor Log.d(TAG, "requestTriggerSensor[" + sensor + "] " + mRegistered);
+ "] " + mRegistered);
} }
} else { } else {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "requestTriggerSensor[" + mSensor Log.d(TAG, "requestTriggerSensor[" + sensor + "] already registered");
+ "] already registered");
} }
} }
} else if (mRegistered) { } else if (mRegistered) {
final boolean rt = mSensorManager.cancelTriggerSensor(this, mSensor); final boolean rt = mSensorManager.cancelTriggerSensor(this, sensor);
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "cancelTriggerSensor[" + mSensor + "] " + rt); Log.d(TAG, "cancelTriggerSensor[" + sensor + "] " + rt);
} }
mRegistered = false; mRegistered = false;
} }
@@ -506,21 +641,29 @@ public class DozeSensors {
@Override @Override
public String toString() { public String toString() {
return new StringBuilder("{mRegistered=").append(mRegistered) StringBuilder sb = new StringBuilder();
sb.append("{")
.append("mRegistered=").append(mRegistered)
.append(", mRequested=").append(mRequested) .append(", mRequested=").append(mRequested)
.append(", mDisabled=").append(mDisabled) .append(", mDisabled=").append(mDisabled)
.append(", mConfigured=").append(mConfigured) .append(", mConfigured=").append(mConfigured)
.append(", mIgnoresSetting=").append(mIgnoresSetting) .append(", mIgnoresSetting=").append(mIgnoresSetting)
.append(", mSensor=").append(mSensor).append("}").toString(); .append(", mSensors=").append(Arrays.toString(mSensors));
if (mSensors.length > 2) {
sb.append(", mPosture=")
.append(DevicePostureController.devicePostureToString(mDevicePosture));
}
return sb.append("}").toString();
} }
@Override @Override
@AnyThread @AnyThread
public void onTrigger(TriggerEvent event) { public void onTrigger(TriggerEvent event) {
final Sensor sensor = mSensors[mDevicePosture];
mDozeLog.traceSensor(mPulseReason); mDozeLog.traceSensor(mPulseReason);
mHandler.post(mWakeLock.wrap(() -> { mHandler.post(mWakeLock.wrap(() -> {
if (DEBUG) Log.d(TAG, "onTrigger: " + triggerEventToString(event)); if (DEBUG) Log.d(TAG, "onTrigger: " + triggerEventToString(event));
if (mSensor != null && mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) { if (sensor != null && sensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
UI_EVENT_LOGGER.log(DozeSensorsUiEvent.ACTION_AMBIENT_GESTURE_PICKUP); UI_EVENT_LOGGER.log(DozeSensorsUiEvent.ACTION_AMBIENT_GESTURE_PICKUP);
} }
@@ -531,7 +674,7 @@ public class DozeSensors {
screenX = event.values[0]; screenX = event.values[0];
screenY = event.values[1]; screenY = event.values[1];
} }
mCallback.onSensorPulse(mPulseReason, screenX, screenY, event.values); mSensorCallback.onSensorPulse(mPulseReason, screenX, screenY, event.values);
if (!mRegistered) { if (!mRegistered) {
updateListening(); // reregister, this sensor only fires once updateListening(); // reregister, this sensor only fires once
} }
@@ -569,17 +712,16 @@ public class DozeSensors {
private long mDebounce; private long mDebounce;
PluginSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured, PluginSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured,
int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen, int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen) {
DozeLog dozeLog) {
this(sensor, setting, configured, pulseReason, reportsTouchCoordinates, this(sensor, setting, configured, pulseReason, reportsTouchCoordinates,
requiresTouchscreen, 0L /* debounce */, dozeLog); requiresTouchscreen, 0L /* debounce */);
} }
PluginSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured, PluginSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured,
int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen, int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen,
long debounce, DozeLog dozeLog) { long debounce) {
super(null, setting, configured, pulseReason, reportsTouchCoordinates, super(null, setting, configured, pulseReason, reportsTouchCoordinates,
requiresTouchscreen, dozeLog); requiresTouchscreen);
mPluginSensor = sensor; mPluginSensor = sensor;
mDebounce = debounce; mDebounce = debounce;
} }
@@ -633,11 +775,22 @@ public class DozeSensors {
return; return;
} }
if (DEBUG) Log.d(TAG, "onSensorEvent: " + triggerEventToString(event)); if (DEBUG) Log.d(TAG, "onSensorEvent: " + triggerEventToString(event));
mCallback.onSensorPulse(mPulseReason, -1, -1, event.getValues()); mSensorCallback.onSensorPulse(mPulseReason, -1, -1, event.getValues());
})); }));
} }
} }
private final DevicePostureController.Callback mDevicePostureCallback = posture -> {
if (mDevicePosture == posture) {
return;
}
mDevicePosture = posture;
for (TriggerSensor triggerSensor : mTriggerSensors) {
triggerSensor.setPosture(mDevicePosture);
}
};
public interface Callback { public interface Callback {
/** /**

View File

@@ -99,8 +99,6 @@ public class DozeTriggers implements DozeMachine.Part {
private final UiEventLogger mUiEventLogger; private final UiEventLogger mUiEventLogger;
private final DevicePostureController mDevicePostureController; private final DevicePostureController mDevicePostureController;
private @DevicePostureController.DevicePostureInt int mDevicePosture;
private long mNotificationPulseTime; private long mNotificationPulseTime;
private boolean mPulsePending; private boolean mPulsePending;
private Runnable mAodInterruptRunnable; private Runnable mAodInterruptRunnable;
@@ -197,11 +195,12 @@ public class DozeTriggers implements DozeMachine.Part {
mSensorManager = sensorManager; mSensorManager = sensorManager;
mWakeLock = wakeLock; mWakeLock = wakeLock;
mAllowPulseTriggers = true; mAllowPulseTriggers = true;
mDevicePostureController = devicePostureController; mDevicePostureController = devicePostureController;
mDevicePosture = devicePostureController.getDevicePosture();
mDozeSensors = new DozeSensors(context, mSensorManager, dozeParameters, mDozeSensors = new DozeSensors(context, mSensorManager, dozeParameters,
config, wakeLock, this::onSensor, this::onProximityFar, dozeLog, proximitySensor, config, wakeLock, this::onSensor, this::onProximityFar, dozeLog, proximitySensor,
secureSettings, authController, mDevicePosture); secureSettings, authController, devicePostureController);
mUiModeManager = mContext.getSystemService(UiModeManager.class); mUiModeManager = mContext.getSystemService(UiModeManager.class);
mDockManager = dockManager; mDockManager = dockManager;
mProxCheck = proxCheck; mProxCheck = proxCheck;
@@ -212,6 +211,10 @@ public class DozeTriggers implements DozeMachine.Part {
mUiEventLogger = uiEventLogger; mUiEventLogger = uiEventLogger;
mKeyguardStateController = keyguardStateController; mKeyguardStateController = keyguardStateController;
} }
private final DevicePostureController.Callback mDevicePostureCallback =
posture -> {
};
@Override @Override
public void setDozeMachine(DozeMachine dozeMachine) { public void setDozeMachine(DozeMachine dozeMachine) {
@@ -284,8 +287,8 @@ public class DozeTriggers implements DozeMachine.Part {
boolean isTap = pulseReason == DozeLog.REASON_SENSOR_TAP; boolean isTap = pulseReason == DozeLog.REASON_SENSOR_TAP;
boolean isPickup = pulseReason == DozeLog.REASON_SENSOR_PICKUP; boolean isPickup = pulseReason == DozeLog.REASON_SENSOR_PICKUP;
boolean isLongPress = pulseReason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS; boolean isLongPress = pulseReason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS;
boolean isWakeOnPresence = pulseReason == DozeLog.REASON_SENSOR_WAKE_UP; boolean isWakeOnPresence = pulseReason == DozeLog.REASON_SENSOR_WAKE_UP_PRESENCE;
boolean isWakeOnReach = pulseReason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN; boolean isWakeOnReach = pulseReason == DozeLog.PULSE_REASON_SENSOR_WAKE_REACH;
boolean isUdfpsLongPress = pulseReason == DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS; boolean isUdfpsLongPress = pulseReason == DozeLog.REASON_SENSOR_UDFPS_LONG_PRESS;
boolean isQuickPickup = pulseReason == DozeLog.REASON_SENSOR_QUICK_PICKUP; boolean isQuickPickup = pulseReason == DozeLog.REASON_SENSOR_QUICK_PICKUP;
boolean isWakeDisplayEvent = isQuickPickup || ((isWakeOnPresence || isWakeOnReach) boolean isWakeDisplayEvent = isQuickPickup || ((isWakeOnPresence || isWakeOnReach)
@@ -455,7 +458,7 @@ public class DozeTriggers implements DozeMachine.Part {
mWantSensors = true; mWantSensors = true;
mWantTouchScreenSensors = true; mWantTouchScreenSensors = true;
if (newState == DozeMachine.State.DOZE_AOD && !sWakeDisplaySensorState) { if (newState == DozeMachine.State.DOZE_AOD && !sWakeDisplaySensorState) {
onWakeScreen(false, newState, DozeLog.REASON_SENSOR_WAKE_UP); onWakeScreen(false, newState, DozeLog.REASON_SENSOR_WAKE_UP_PRESENCE);
} }
break; break;
case DOZE_AOD_PAUSED: case DOZE_AOD_PAUSED:
@@ -524,7 +527,7 @@ public class DozeTriggers implements DozeMachine.Part {
// When already pulsing we're allowed to show the wallpaper directly without // When already pulsing we're allowed to show the wallpaper directly without
// requesting a new pulse. // requesting a new pulse.
if (dozeState == DozeMachine.State.DOZE_PULSING if (dozeState == DozeMachine.State.DOZE_PULSING
&& reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) { && reason == DozeLog.PULSE_REASON_SENSOR_WAKE_REACH) {
mMachine.requestState(DozeMachine.State.DOZE_PULSING_BRIGHT); mMachine.requestState(DozeMachine.State.DOZE_PULSING_BRIGHT);
return; return;
} }

View File

@@ -155,7 +155,7 @@ public class DozeUi implements DozeMachine.Part, TunerService.Tunable,
public void onPulseStarted() { public void onPulseStarted() {
try { try {
mMachine.requestState( mMachine.requestState(
reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN reason == DozeLog.PULSE_REASON_SENSOR_WAKE_REACH
? DozeMachine.State.DOZE_PULSING_BRIGHT ? DozeMachine.State.DOZE_PULSING_BRIGHT
: DozeMachine.State.DOZE_PULSING); : DozeMachine.State.DOZE_PULSING);
} catch (IllegalStateException e) { } catch (IllegalStateException e) {

View File

@@ -43,6 +43,9 @@ import com.android.systemui.util.sensors.AsyncSensorManager;
import com.android.systemui.util.wakelock.DelayedWakeLock; import com.android.systemui.util.wakelock.DelayedWakeLock;
import com.android.systemui.util.wakelock.WakeLock; import com.android.systemui.util.wakelock.WakeLock;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import dagger.Module; import dagger.Module;
@@ -94,16 +97,43 @@ public abstract class DozeModule {
@Provides @Provides
@BrightnessSensor @BrightnessSensor
static Optional<Sensor> providesBrightnessSensor( static Optional<Sensor>[] providesBrightnessSensors(
AsyncSensorManager sensorManager, AsyncSensorManager sensorManager,
Context context, Context context,
DozeParameters dozeParameters, DozeParameters dozeParameters) {
DevicePostureController devicePostureController) { String[] sensorNames = dozeParameters.brightnessNames();
return Optional.ofNullable( if (sensorNames.length == 0 || sensorNames == null) {
DozeSensors.findSensor( // if no brightness names are specified, just use the brightness sensor type
sensorManager, return new Optional[]{
context.getString(R.string.doze_brightness_sensor_type), Optional.ofNullable(DozeSensors.findSensor(
dozeParameters.brightnessName(devicePostureController.getDevicePosture()) sensorManager,
)); context.getString(R.string.doze_brightness_sensor_type),
null
))
};
}
// length and index of brightnessMap correspond to DevicePostureController.DevicePostureInt:
final Optional<Sensor>[] brightnessSensorMap =
new Optional[DevicePostureController.SUPPORTED_POSTURES_SIZE];
Arrays.fill(brightnessSensorMap, Optional.empty());
// Map of sensorName => Sensor, so we reuse the same sensor if it's the same between
// postures
Map<String, Optional<Sensor>> nameToSensorMap = new HashMap<>();
for (int i = 0; i < sensorNames.length; i++) {
final String sensorName = sensorNames[i];
if (!nameToSensorMap.containsKey(sensorName)) {
nameToSensorMap.put(sensorName,
Optional.ofNullable(
DozeSensors.findSensor(
sensorManager,
context.getString(R.string.doze_brightness_sensor_type),
sensorNames[i]
)));
}
brightnessSensorMap[i] = nameToSensorMap.get(sensorName);
}
return brightnessSensorMap;
} }
} }

View File

@@ -283,14 +283,12 @@ public class DozeParameters implements
} }
/** /**
* Sensor to use for brightness changes. * Gets the brightness string array per posture. Brightness names along with
* doze_brightness_sensor_type is used to determine the brightness sensor to use for
* the current posture.
*/ */
public String brightnessName(@DevicePostureController.DevicePostureInt int posture) { public String[] brightnessNames() {
return AmbientDisplayConfiguration.getSensorFromPostureMapping( return mResources.getStringArray(R.array.doze_brightness_sensor_name_posture_mapping);
mResources.getStringArray(R.array.doze_brightness_sensor_name_posture_mapping),
null /* defaultValue */,
posture
);
} }
/** /**

View File

@@ -226,11 +226,11 @@ public final class DozeServiceHost implements DozeHost {
return; return;
} }
if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) { if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_REACH) {
mScrimController.setWakeLockScreenSensorActive(true); mScrimController.setWakeLockScreenSensorActive(true);
} }
boolean passiveAuthInterrupt = reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN boolean passiveAuthInterrupt = reason == DozeLog.PULSE_REASON_SENSOR_WAKE_REACH
&& mWakeLockScreenPerformsAuth; && mWakeLockScreenPerformsAuth;
// Set the state to pulsing, so ScrimController will know what to do once we ask it to // Set the state to pulsing, so ScrimController will know what to do once we ask it to
// execute the transition. The pulse callback will then be invoked when the scrims // execute the transition. The pulse callback will then be invoked when the scrims
@@ -329,7 +329,7 @@ public final class DozeServiceHost implements DozeHost {
@Override @Override
public void extendPulse(int reason) { public void extendPulse(int reason) {
if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) { if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_REACH) {
mScrimController.setWakeLockScreenSensorActive(true); mScrimController.setWakeLockScreenSensorActive(true);
} }
if (mDozeScrimController.isPulsing() && mHeadsUpManagerPhone.hasNotifications()) { if (mDozeScrimController.isPulsing() && mHeadsUpManagerPhone.hasNotifications()) {

View File

@@ -29,6 +29,7 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.policy.DevicePostureController; import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.concurrency.DelayableExecutor;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -177,9 +178,7 @@ public class SensorModule {
// length and index of sensorMap correspond to DevicePostureController.DevicePostureInt: // length and index of sensorMap correspond to DevicePostureController.DevicePostureInt:
final ThresholdSensor[] sensorMap = final ThresholdSensor[] sensorMap =
new ThresholdSensor[DevicePostureController.SUPPORTED_POSTURES_SIZE]; new ThresholdSensor[DevicePostureController.SUPPORTED_POSTURES_SIZE];
for (int i = 0; i < DevicePostureController.SUPPORTED_POSTURES_SIZE; i++) { Arrays.fill(sensorMap, noProxSensor);
sensorMap[i] = noProxSensor;
}
if (!hasPostureSupport(sensorTypes)) { if (!hasPostureSupport(sensorTypes)) {
Log.e("SensorModule", "config doesn't support postures," Log.e("SensorModule", "config doesn't support postures,"

View File

@@ -67,7 +67,8 @@ public class DozeConfigurationUtil {
when(config.tapGestureEnabled(anyInt())).thenReturn(true); when(config.tapGestureEnabled(anyInt())).thenReturn(true);
when(config.tapSensorAvailable()).thenReturn(true); when(config.tapSensorAvailable()).thenReturn(true);
when(config.tapSensorType(anyInt())).thenReturn(FakeSensorManager.TAP_SENSOR_TYPE); when(config.tapSensorTypeMapping()).thenReturn(
new String[]{FakeSensorManager.TAP_SENSOR_TYPE});
when(config.dozePickupSensorAvailable()).thenReturn(false); when(config.dozePickupSensorAvailable()).thenReturn(false);
when(config.wakeScreenGestureAvailable()).thenReturn(false); when(config.wakeScreenGestureAvailable()).thenReturn(false);

View File

@@ -51,6 +51,7 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.concurrency.FakeThreadFactory; import com.android.systemui.util.concurrency.FakeThreadFactory;
import com.android.systemui.util.sensors.AsyncSensorManager; import com.android.systemui.util.sensors.AsyncSensorManager;
@@ -60,6 +61,7 @@ import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
@@ -76,6 +78,7 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
private DozeServiceFake mServiceFake; private DozeServiceFake mServiceFake;
private FakeSensorManager.FakeGenericSensor mSensor; private FakeSensorManager.FakeGenericSensor mSensor;
private FakeSensorManager.FakeGenericSensor mSensorInner;
private AsyncSensorManager mSensorManager; private AsyncSensorManager mSensorManager;
private AlwaysOnDisplayPolicy mAlwaysOnDisplayPolicy; private AlwaysOnDisplayPolicy mAlwaysOnDisplayPolicy;
@Mock @Mock
@@ -86,6 +89,10 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
DozeParameters mDozeParameters; DozeParameters mDozeParameters;
@Mock @Mock
DockManager mDockManager; DockManager mDockManager;
@Mock
DevicePostureController mDevicePostureController;
@Mock
DozeLog mDozeLog;
private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock()); private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
private FakeThreadFactory mFakeThreadFactory = new FakeThreadFactory(mFakeExecutor); private FakeThreadFactory mFakeThreadFactory = new FakeThreadFactory(mFakeExecutor);
@@ -111,9 +118,19 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
mAlwaysOnDisplayPolicy.dimBrightness = DIM_BRIGHTNESS; mAlwaysOnDisplayPolicy.dimBrightness = DIM_BRIGHTNESS;
mAlwaysOnDisplayPolicy.dimmingScrimArray = SENSOR_TO_OPACITY; mAlwaysOnDisplayPolicy.dimmingScrimArray = SENSOR_TO_OPACITY;
mSensor = fakeSensorManager.getFakeLightSensor(); mSensor = fakeSensorManager.getFakeLightSensor();
mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager, mSensorInner = fakeSensorManager.getFakeLightSensor2();
Optional.of(mSensor.getSensor()), mDozeHost, null /* handler */, mScreen = new DozeScreenBrightness(
mAlwaysOnDisplayPolicy, mWakefulnessLifecycle, mDozeParameters, mDockManager); mContext,
mServiceFake,
mSensorManager,
new Optional[]{Optional.of(mSensor.getSensor())},
mDozeHost,
null /* handler */,
mAlwaysOnDisplayPolicy,
mWakefulnessLifecycle,
mDozeParameters,
mDevicePostureController,
mDozeLog);
} }
@Test @Test
@@ -151,7 +168,7 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
@Test @Test
public void doze_doesNotUseLightSensor() { public void doze_doesNotUseLightSensor() {
// GIVEN the device is docked and the display state changes to ON // GIVEN the device is DOZE and the display state changes to ON
mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE); mScreen.transitionTo(INITIALIZED, DOZE);
waitForSensorManager(); waitForSensorManager();
@@ -166,7 +183,7 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
@Test @Test
public void aod_usesLightSensor() { public void aod_usesLightSensor() {
// GIVEN the device is docked and the display state changes to ON // GIVEN the device is DOZE_AOD and the display state changes to ON
mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_AOD); mScreen.transitionTo(INITIALIZED, DOZE_AOD);
waitForSensorManager(); waitForSensorManager();
@@ -209,9 +226,17 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
@Test @Test
public void testPulsing_withoutLightSensor_setsAoDDimmingScrimTransparent() throws Exception { public void testPulsing_withoutLightSensor_setsAoDDimmingScrimTransparent() throws Exception {
mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager, mScreen = new DozeScreenBrightness(
Optional.empty() /* sensor */, mDozeHost, null /* handler */, mContext,
mAlwaysOnDisplayPolicy, mWakefulnessLifecycle, mDozeParameters, mDockManager); mServiceFake,
mSensorManager,
new Optional[] {Optional.empty()} /* sensor */,
mDozeHost, null /* handler */,
mAlwaysOnDisplayPolicy,
mWakefulnessLifecycle,
mDozeParameters,
mDevicePostureController,
mDozeLog);
mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE); mScreen.transitionTo(INITIALIZED, DOZE);
reset(mDozeHost); reset(mDozeHost);
@@ -238,9 +263,17 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
@Test @Test
public void testNullSensor() throws Exception { public void testNullSensor() throws Exception {
mScreen = new DozeScreenBrightness(mContext, mServiceFake, mSensorManager, mScreen = new DozeScreenBrightness(
Optional.empty() /* sensor */, mDozeHost, null /* handler */, mContext,
mAlwaysOnDisplayPolicy, mWakefulnessLifecycle, mDozeParameters, mDockManager); mServiceFake,
mSensorManager,
new Optional[]{Optional.empty()} /* sensor */,
mDozeHost, null /* handler */,
mAlwaysOnDisplayPolicy,
mWakefulnessLifecycle,
mDozeParameters,
mDevicePostureController,
mDozeLog);
mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_AOD); mScreen.transitionTo(INITIALIZED, DOZE_AOD);
@@ -248,6 +281,130 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED); mScreen.transitionTo(DOZE_AOD_PAUSING, DOZE_AOD_PAUSED);
} }
@Test
public void testSensorsSupportPostures_closed() throws Exception {
// GIVEN the device is CLOSED
when(mDevicePostureController.getDevicePosture()).thenReturn(
DevicePostureController.DEVICE_POSTURE_CLOSED);
// GIVEN closed and opened postures use different light sensors
mScreen = new DozeScreenBrightness(
mContext,
mServiceFake,
mSensorManager,
new Optional[]{
Optional.empty() /* unknown */,
Optional.of(mSensor.getSensor()) /* closed */,
Optional.of(mSensorInner.getSensor()) /* half-opened */,
Optional.of(mSensorInner.getSensor()) /* opened */,
Optional.empty() /* flipped */
},
mDozeHost, null /* handler */,
mAlwaysOnDisplayPolicy,
mWakefulnessLifecycle,
mDozeParameters,
mDevicePostureController,
mDozeLog);
// GIVEN the device is in AOD
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
waitForSensorManager();
// WHEN new different events are sent from the inner and outer sensors
mSensor.sendSensorEvent(3); // CLOSED sensor
mSensorInner.sendSensorEvent(4); // OPENED sensor
// THEN brightness is updated according to the sensor for CLOSED
assertEquals(3, mServiceFake.screenBrightness);
}
@Test
public void testSensorsSupportPostures_open() throws Exception {
// GIVEN the device is OPENED
when(mDevicePostureController.getDevicePosture()).thenReturn(
DevicePostureController.DEVICE_POSTURE_OPENED);
// GIVEN closed and opened postures use different light sensors
mScreen = new DozeScreenBrightness(
mContext,
mServiceFake,
mSensorManager,
new Optional[]{
Optional.empty() /* unknown */,
Optional.of(mSensor.getSensor()) /* closed */,
Optional.of(mSensorInner.getSensor()) /* half-opened */,
Optional.of(mSensorInner.getSensor()) /* opened */,
Optional.empty() /* flipped */
},
mDozeHost, null /* handler */,
mAlwaysOnDisplayPolicy,
mWakefulnessLifecycle,
mDozeParameters,
mDevicePostureController,
mDozeLog);
// GIVEN device is in AOD
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
waitForSensorManager();
// WHEN new different events are sent from the inner and outer sensors
mSensorInner.sendSensorEvent(4); // OPENED sensor
mSensor.sendSensorEvent(3); // CLOSED sensor
// THEN brightness is updated according to the sensor for OPENED
assertEquals(4, mServiceFake.screenBrightness);
}
@Test
public void testSensorsSupportPostures_swapPostures() throws Exception {
ArgumentCaptor<DevicePostureController.Callback> postureCallbackCaptor =
ArgumentCaptor.forClass(DevicePostureController.Callback.class);
reset(mDevicePostureController);
// GIVEN the device starts up AOD OPENED
when(mDevicePostureController.getDevicePosture()).thenReturn(
DevicePostureController.DEVICE_POSTURE_OPENED);
// GIVEN closed and opened postures use different light sensors
mScreen = new DozeScreenBrightness(
mContext,
mServiceFake,
mSensorManager,
new Optional[]{
Optional.empty() /* unknown */,
Optional.of(mSensor.getSensor()) /* closed */,
Optional.of(mSensorInner.getSensor()) /* half-opened */,
Optional.of(mSensorInner.getSensor()) /* opened */,
Optional.empty() /* flipped */
},
mDozeHost, null /* handler */,
mAlwaysOnDisplayPolicy,
mWakefulnessLifecycle,
mDozeParameters,
mDevicePostureController,
mDozeLog);
verify(mDevicePostureController).addCallback(postureCallbackCaptor.capture());
// GIVEN device is in AOD
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
waitForSensorManager();
// WHEN the posture changes to CLOSED
postureCallbackCaptor.getValue().onPostureChanged(
DevicePostureController.DEVICE_POSTURE_CLOSED);
waitForSensorManager();
// WHEN new different events are sent from the inner and outer sensors
mSensor.sendSensorEvent(3); // CLOSED sensor
mSensorInner.sendSensorEvent(4); // OPENED sensor
// THEN brightness is updated according to the sensor for CLOSED
assertEquals(3, mServiceFake.screenBrightness);
}
@Test @Test
public void testNoBrightnessDeliveredAfterFinish() throws Exception { public void testNoBrightnessDeliveredAfterFinish() throws Exception {
mScreen.transitionTo(UNINITIALIZED, INITIALIZED); mScreen.transitionTo(UNINITIALIZED, INITIALIZED);

View File

@@ -91,9 +91,9 @@ public class DozeSensorsTest extends SysuiTestCase {
@Mock @Mock
private AuthController mAuthController; private AuthController mAuthController;
@Mock @Mock
private DevicePostureController mDevicePostureController;
@Mock
private ProximitySensor mProximitySensor; private ProximitySensor mProximitySensor;
private @DevicePostureController.DevicePostureInt int mDevicePosture =
DevicePostureController.DEVICE_POSTURE_UNKNOWN;
private FakeSettings mFakeSettings = new FakeSettings(); private FakeSettings mFakeSettings = new FakeSettings();
private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener; private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener;
private TestableLooper mTestableLooper; private TestableLooper mTestableLooper;
@@ -104,13 +104,14 @@ public class DozeSensorsTest extends SysuiTestCase {
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mTestableLooper = TestableLooper.get(this); mTestableLooper = TestableLooper.get(this);
when(mAmbientDisplayConfiguration.tapSensorTypeMapping())
.thenReturn(new String[]{"tapSEnsor"});
when(mAmbientDisplayConfiguration.getWakeLockScreenDebounce()).thenReturn(5000L); when(mAmbientDisplayConfiguration.getWakeLockScreenDebounce()).thenReturn(5000L);
when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true); when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
doAnswer(invocation -> { doAnswer(invocation -> {
((Runnable) invocation.getArgument(0)).run(); ((Runnable) invocation.getArgument(0)).run();
return null; return null;
}).when(mWakeLock).wrap(any(Runnable.class)); }).when(mWakeLock).wrap(any(Runnable.class));
mDevicePosture = DevicePostureController.DEVICE_POSTURE_UNKNOWN;
mDozeSensors = new TestableDozeSensors(); mDozeSensors = new TestableDozeSensors();
} }
@@ -127,14 +128,14 @@ public class DozeSensorsTest extends SysuiTestCase {
mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class)); mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class));
mTestableLooper.processAllMessages(); mTestableLooper.processAllMessages();
verify(mCallback).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN), verify(mCallback).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_REACH),
anyFloat(), anyFloat(), eq(null)); anyFloat(), anyFloat(), eq(null));
mDozeSensors.requestTemporaryDisable(); mDozeSensors.requestTemporaryDisable();
reset(mCallback); reset(mCallback);
mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class)); mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class));
mTestableLooper.processAllMessages(); mTestableLooper.processAllMessages();
verify(mCallback, never()).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN), verify(mCallback, never()).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_REACH),
anyFloat(), anyFloat(), eq(null)); anyFloat(), anyFloat(), eq(null));
} }
@@ -269,15 +270,80 @@ public class DozeSensorsTest extends SysuiTestCase {
} }
@Test @Test
public void testPostureOpen_registersCorrectTapGesture() { public void testPostureStartStateClosed_registersCorrectSensor() throws Exception {
// GIVEN device posture open // GIVEN doze sensor that supports postures
mDevicePosture = DevicePostureController.DEVICE_POSTURE_OPENED; Sensor closedSensor = createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
Sensor openedSensor = createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_LIGHT);
TriggerSensor triggerSensor = mDozeSensors.createDozeSensor(
new Sensor[] {
null /* unknown */,
closedSensor,
null /* half-opened */,
openedSensor},
DevicePostureController.DEVICE_POSTURE_CLOSED);
// WHEN DozeSensors are initialized // WHEN trigger sensor requests listening
new TestableDozeSensors(); triggerSensor.setListening(true);
// THEN we use the posture to determine which tap sensor to use // THEN the correct sensor is registered
verify(mAmbientDisplayConfiguration).tapSensorType(eq(mDevicePosture)); verify(mSensorManager).requestTriggerSensor(eq(triggerSensor), eq(closedSensor));
verify(mSensorManager, never()).requestTriggerSensor(eq(triggerSensor), eq(openedSensor));
}
@Test
public void testPostureChange_registersCorrectSensor() throws Exception {
// GIVEN doze sensor that supports postures
Sensor closedSensor = createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
Sensor openedSensor = createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_LIGHT);
TriggerSensor triggerSensor = mDozeSensors.createDozeSensor(
new Sensor[] {
null /* unknown */,
closedSensor,
null /* half-opened */,
openedSensor},
DevicePostureController.DEVICE_POSTURE_CLOSED);
// GIVEN sensor is listening
when(mSensorManager.requestTriggerSensor(any(), any())).thenReturn(true);
triggerSensor.setListening(true);
reset(mSensorManager);
assertTrue(triggerSensor.mRegistered);
// WHEN posture changes
boolean sensorChanged =
triggerSensor.setPosture(DevicePostureController.DEVICE_POSTURE_OPENED);
// THEN the correct sensor is registered
assertTrue(sensorChanged);
verify(mSensorManager).requestTriggerSensor(eq(triggerSensor), eq(openedSensor));
verify(mSensorManager, never()).requestTriggerSensor(eq(triggerSensor), eq(closedSensor));
}
@Test
public void testPostureChange_noSensorChange() throws Exception {
// GIVEN doze sensor that supports postures
Sensor closedSensor = createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
Sensor openedSensor = createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_LIGHT);
TriggerSensor triggerSensor = mDozeSensors.createDozeSensor(
new Sensor[] {
null /* unknown */,
closedSensor,
openedSensor /* half-opened uses the same sensor as opened*/,
openedSensor},
DevicePostureController.DEVICE_POSTURE_HALF_OPENED);
// GIVEN sensor is listening
when(mSensorManager.requestTriggerSensor(any(), any())).thenReturn(true);
triggerSensor.setListening(true);
reset(mSensorManager);
// WHEN posture changes
boolean sensorChanged =
triggerSensor.setPosture(DevicePostureController.DEVICE_POSTURE_OPENED);
// THEN no change in sensor
assertFalse(sensorChanged);
verify(mSensorManager, never()).requestTriggerSensor(eq(triggerSensor), any());
} }
@Test @Test
@@ -311,13 +377,12 @@ public class DozeSensorsTest extends SysuiTestCase {
private class TestableDozeSensors extends DozeSensors { private class TestableDozeSensors extends DozeSensors {
TestableDozeSensors() { TestableDozeSensors() {
super(getContext(), mSensorManager, mDozeParameters, super(getContext(), mSensorManager, mDozeParameters,
mAmbientDisplayConfiguration, mWakeLock, mCallback, mProxCallback, mDozeLog, mAmbientDisplayConfiguration, mWakeLock, mCallback, mProxCallback, mDozeLog,
mProximitySensor, mFakeSettings, mAuthController, mProximitySensor, mFakeSettings, mAuthController,
mDevicePosture); mDevicePostureController);
for (TriggerSensor sensor : mSensors) { for (TriggerSensor sensor : mTriggerSensors) {
if (sensor instanceof PluginSensor if (sensor instanceof PluginSensor
&& ((PluginSensor) sensor).mPluginSensor.getType() && ((PluginSensor) sensor).mPluginSensor.getType()
== TYPE_WAKE_LOCK_SCREEN) { == TYPE_WAKE_LOCK_SCREEN) {
@@ -326,7 +391,7 @@ public class DozeSensorsTest extends SysuiTestCase {
mSensorTap = sensor; mSensorTap = sensor;
} }
} }
mSensors = new TriggerSensor[] {mTriggerSensor, mSensorTap}; mTriggerSensors = new TriggerSensor[] {mTriggerSensor, mSensorTap};
} }
public TriggerSensor createDozeSensor(Sensor sensor, boolean settingEnabled, public TriggerSensor createDozeSensor(Sensor sensor, boolean settingEnabled,
@@ -337,8 +402,25 @@ public class DozeSensorsTest extends SysuiTestCase {
/* configured */ true, /* configured */ true,
/* pulseReason*/ 0, /* pulseReason*/ 0,
/* reportsTouchCoordinate*/ false, /* reportsTouchCoordinate*/ false,
requiresTouchScreen, /* requiresTouchscreen */ false,
mDozeLog); /* ignoresSetting */ false,
requiresTouchScreen);
}
/**
* create a doze sensor that supports postures and is enabled
*/
public TriggerSensor createDozeSensor(Sensor[] sensors, int posture) {
return new TriggerSensor(/* sensor */ sensors,
/* setting name */ "test_setting",
/* settingDefault */ true,
/* configured */ true,
/* pulseReason*/ 0,
/* reportsTouchCoordinate*/ false,
/* requiresTouchscreen */ false,
/* ignoresSetting */ true,
/* requiresProx */false,
posture);
} }
} }

View File

@@ -204,7 +204,7 @@ public class DozeTriggersTest extends SysuiTestCase {
public void testProximitySensorNotAvailablel() { public void testProximitySensorNotAvailablel() {
mProximitySensor.setSensorAvailable(false); mProximitySensor.setSensorAvailable(false);
mTriggers.onSensor(DozeLog.PULSE_REASON_SENSOR_LONG_PRESS, 100, 100, null); mTriggers.onSensor(DozeLog.PULSE_REASON_SENSOR_LONG_PRESS, 100, 100, null);
mTriggers.onSensor(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN, 100, 100, mTriggers.onSensor(DozeLog.PULSE_REASON_SENSOR_WAKE_REACH, 100, 100,
new float[]{1}); new float[]{1});
mTriggers.onSensor(DozeLog.REASON_SENSOR_TAP, 100, 100, null); mTriggers.onSensor(DozeLog.REASON_SENSOR_TAP, 100, 100, null);
} }

View File

@@ -164,7 +164,7 @@ public class DozeServiceHostTest extends SysuiTestCase {
@Test @Test
public void testPulseWhileDozing_notifyAuthInterrupt() { public void testPulseWhileDozing_notifyAuthInterrupt() {
HashSet<Integer> reasonsWantingAuth = new HashSet<>( HashSet<Integer> reasonsWantingAuth = new HashSet<>(
Collections.singletonList(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN)); Collections.singletonList(DozeLog.PULSE_REASON_SENSOR_WAKE_REACH));
HashSet<Integer> reasonsSkippingAuth = new HashSet<>( HashSet<Integer> reasonsSkippingAuth = new HashSet<>(
Arrays.asList(DozeLog.PULSE_REASON_INTENT, Arrays.asList(DozeLog.PULSE_REASON_INTENT,
DozeLog.PULSE_REASON_NOTIFICATION, DozeLog.PULSE_REASON_NOTIFICATION,
@@ -173,7 +173,7 @@ public class DozeServiceHostTest extends SysuiTestCase {
DozeLog.REASON_SENSOR_DOUBLE_TAP, DozeLog.REASON_SENSOR_DOUBLE_TAP,
DozeLog.PULSE_REASON_SENSOR_LONG_PRESS, DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
DozeLog.PULSE_REASON_DOCKING, DozeLog.PULSE_REASON_DOCKING,
DozeLog.REASON_SENSOR_WAKE_UP, DozeLog.REASON_SENSOR_WAKE_UP_PRESENCE,
DozeLog.REASON_SENSOR_QUICK_PICKUP, DozeLog.REASON_SENSOR_QUICK_PICKUP,
DozeLog.REASON_SENSOR_TAP)); DozeLog.REASON_SENSOR_TAP));
HashSet<Integer> reasonsThatDontPulse = new HashSet<>( HashSet<Integer> reasonsThatDontPulse = new HashSet<>(

View File

@@ -55,6 +55,7 @@ public class FakeSensorManager extends SensorManager {
private final FakeProximitySensor mFakeProximitySensor; private final FakeProximitySensor mFakeProximitySensor;
private final FakeGenericSensor mFakeLightSensor; private final FakeGenericSensor mFakeLightSensor;
private final FakeGenericSensor mFakeLightSensor2;
private final FakeGenericSensor mFakeTapSensor; private final FakeGenericSensor mFakeTapSensor;
private final FakeGenericSensor[] mSensors; private final FakeGenericSensor[] mSensors;
@@ -70,7 +71,8 @@ public class FakeSensorManager extends SensorManager {
mSensors = new FakeGenericSensor[]{ mSensors = new FakeGenericSensor[]{
mFakeProximitySensor = new FakeProximitySensor(proxSensor), mFakeProximitySensor = new FakeProximitySensor(proxSensor),
mFakeLightSensor = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT, null)), mFakeLightSensor = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT, null)),
mFakeTapSensor = new FakeGenericSensor(createSensor(99, TAP_SENSOR_TYPE)) mFakeTapSensor = new FakeGenericSensor(createSensor(99, TAP_SENSOR_TYPE)),
mFakeLightSensor2 = new FakeGenericSensor(createSensor(Sensor.TYPE_LIGHT, null))
}; };
} }
@@ -82,6 +84,10 @@ public class FakeSensorManager extends SensorManager {
return mFakeLightSensor; return mFakeLightSensor;
} }
public FakeGenericSensor getFakeLightSensor2() {
return mFakeLightSensor2;
}
public FakeGenericSensor getFakeTapSensor() { public FakeGenericSensor getFakeTapSensor() {
return mFakeTapSensor; return mFakeTapSensor;
} }