Add support dual display support doze tap gesture

Test: manual, atest DozeSensorsTest
Bug: 192805135
Change-Id: I08a98bf16753631afd31cb750c541c7443df1b9e
This commit is contained in:
Beverly
2021-09-27 13:15:54 -04:00
parent 89f022ac99
commit c8d3d1adf7
11 changed files with 139 additions and 14 deletions

View File

@@ -22,6 +22,7 @@ import android.os.Build;
import android.os.SystemProperties;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import com.android.internal.R;
@@ -32,7 +33,7 @@ import com.android.internal.R;
*/
@TestApi
public class AmbientDisplayConfiguration {
private static final String TAG = "AmbientDisplayConfig";
private final Context mContext;
private final boolean mAlwaysOnByDefault;
@@ -141,10 +142,19 @@ public class AmbientDisplayConfiguration {
}
/** {@hide} */
public String tapSensorType() {
private String tapSensorType() {
return mContext.getResources().getString(R.string.config_dozeTapSensorType);
}
/** {@hide} */
public String tapSensorType(int posture) {
return getSensorTypeForPosture(
mContext.getResources().getStringArray(R.array.config_dozeTapSensorPostureMapping),
tapSensorType(),
posture
);
}
/** {@hide} */
public String longPressSensorType() {
return mContext.getResources().getString(R.string.config_dozeLongPressSensorType);
@@ -241,4 +251,18 @@ public class AmbientDisplayConfiguration {
private boolean boolSetting(String name, int user, int def) {
return Settings.Secure.getIntForUser(mContext.getContentResolver(), name, def, user) != 0;
}
private String getSensorTypeForPosture(
String[] postureMapping,
String defaultSensorType,
int posture) {
String sensorType = defaultSensorType;
if (posture < postureMapping.length) {
sensorType = postureMapping[posture];
} else {
Log.e(TAG, "Unsupported doze posture " + posture);
}
return TextUtils.isEmpty(sensorType) ? defaultSensorType : sensorType;
}
}

View File

@@ -2323,6 +2323,15 @@
<!-- Type of the tap sensor. Empty if tap is not supported. -->
<string name="config_dozeTapSensorType" translatable="false"></string>
<!-- Type of the ambient tap sensor per device posture (defined by WM Jetpack posture).
Unspecified values use config_dozeTapSensor -->
<string-array name="config_dozeTapSensorPostureMapping" translatable="false">
<item></item> <!-- UNKNOWN -->
<item></item> <!-- CLOSED -->
<item></item> <!-- HALF_OPENED -->
<item></item> <!-- OPENED -->
</string-array>
<!-- Type of the long press sensor. Empty if long press is not supported. -->
<string name="config_dozeLongPressSensorType" translatable="false"></string>

View File

@@ -3255,6 +3255,7 @@
<java-symbol type="string" name="config_dozeDoubleTapSensorType" />
<java-symbol type="string" name="config_dozeTapSensorType" />
<java-symbol type="array" name="config_dozeTapSensorPostureMapping" />
<java-symbol type="bool" name="config_dozePulsePickup" />
<!-- Used for MimeIconUtils. -->

View File

@@ -191,6 +191,15 @@
low powered state yet. -->
<bool name="doze_single_tap_uses_prox">true</bool>
<!-- Doze: whether the single tap sensor uses the proximity sensor in the given posture.
See doze_single_tap_uses_prox for usage. -->
<integer-array name="doze_single_tap_uses_prox_posture_mapping">
<item>1</item> <!-- UNKNOWN -->
<item>1</item> <!-- CLOSED -->
<item>1</item> <!-- HALF_OPENED -->
<item>1</item> <!-- OPENED -->
</integer-array>
<!-- Doze: whether the long press sensor uses the proximity sensor.
If both this parameter and doze_selectively_register_prox are true, registration for the
sensor will be delayed when the device first enters dozing but the device has not entered its

View File

@@ -47,6 +47,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.plugins.SensorManagerPlugin;
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.ProximitySensor;
import com.android.systemui.util.settings.SecureSettings;
@@ -82,6 +83,9 @@ public class DozeSensors {
private boolean mListeningTouchScreenSensors;
private boolean mListeningProxSensors;
@DevicePostureController.DevicePostureInt
private int mDevicePosture;
// whether to only register sensors that use prox when the display state is dozing or off
private boolean mSelectivelyRegisterProxSensors;
@@ -106,7 +110,8 @@ public class DozeSensors {
DozeParameters dozeParameters, AmbientDisplayConfiguration config, WakeLock wakeLock,
Callback callback, Consumer<Boolean> proxCallback, DozeLog dozeLog,
ProximitySensor proximitySensor, SecureSettings secureSettings,
AuthController authController) {
AuthController authController,
int devicePosture) {
mContext = context;
mSensorManager = sensorManager;
mConfig = config;
@@ -120,6 +125,7 @@ public class DozeSensors {
mListeningProxSensors = !mSelectivelyRegisterProxSensors;
mScreenOffUdfpsEnabled =
config.screenOffUdfpsEnabled(KeyguardUpdateMonitor.getCurrentUser());
mDevicePosture = devicePosture;
boolean udfpsEnrolled =
authController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser());
@@ -150,7 +156,7 @@ public class DozeSensors {
true /* touchscreen */,
dozeLog),
new TriggerSensor(
findSensorWithType(config.tapSensorType()),
findSensorWithType(config.tapSensorType(mDevicePosture)),
Settings.Secure.DOZE_TAP_SCREEN_GESTURE,
true /* settingDef */,
true /* configured */,
@@ -158,7 +164,7 @@ public class DozeSensors {
false /* reports touch coordinates */,
true /* touchscreen */,
false /* ignoresSetting */,
dozeParameters.singleTapUsesProx() /* requiresProx */,
dozeParameters.singleTapUsesProx(mDevicePosture) /* requiresProx */,
dozeLog),
new TriggerSensor(
findSensorWithType(config.longPressSensorType()),
@@ -370,6 +376,8 @@ public class DozeSensors {
/** Dump current state */
public void dump(PrintWriter pw) {
pw.println("mListening=" + mListening);
pw.println("mDevicePosture="
+ DevicePostureController.devicePostureToString(mDevicePosture));
pw.println("mListeningTouchScreenSensors=" + mListeningTouchScreenSensors);
pw.println("mSelectivelyRegisterProxSensors=" + mSelectivelyRegisterProxSensors);
pw.println("mListeningProxSensors=" + mListeningProxSensors);

View File

@@ -41,6 +41,7 @@ import com.android.systemui.dock.DockManager;
import com.android.systemui.doze.DozeMachine.State;
import com.android.systemui.doze.dagger.DozeScope;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.Assert;
import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -95,6 +96,9 @@ public class DozeTriggers implements DozeMachine.Part {
private final DelayableExecutor mMainExecutor;
private final KeyguardStateController mKeyguardStateController;
private final UiEventLogger mUiEventLogger;
private final DevicePostureController mDevicePostureController;
private @DevicePostureController.DevicePostureInt int mDevicePosture;
private long mNotificationPulseTime;
private boolean mPulsePending;
@@ -182,7 +186,8 @@ public class DozeTriggers implements DozeMachine.Part {
SecureSettings secureSettings, AuthController authController,
@Main DelayableExecutor mainExecutor,
UiEventLogger uiEventLogger,
KeyguardStateController keyguardStateController) {
KeyguardStateController keyguardStateController,
DevicePostureController devicePostureController) {
mContext = context;
mDozeHost = dozeHost;
mConfig = config;
@@ -190,9 +195,11 @@ public class DozeTriggers implements DozeMachine.Part {
mSensorManager = sensorManager;
mWakeLock = wakeLock;
mAllowPulseTriggers = true;
mDevicePostureController = devicePostureController;
mDevicePosture = devicePostureController.getDevicePosture();
mDozeSensors = new DozeSensors(context, mSensorManager, dozeParameters,
config, wakeLock, this::onSensor, this::onProximityFar, dozeLog, proximitySensor,
secureSettings, authController);
secureSettings, authController, mDevicePosture);
mUiModeManager = mContext.getSystemService(UiModeManager.class);
mDockManager = dockManager;
mProxCheck = proxCheck;

View File

@@ -22,6 +22,7 @@ import android.os.PowerManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.util.MathUtils;
import androidx.annotation.NonNull;
@@ -35,6 +36,7 @@ import com.android.systemui.doze.DozeScreenState;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.tuner.TunerService;
import java.io.FileDescriptor;
@@ -255,10 +257,21 @@ public class DozeParameters implements
return mResources.getBoolean(R.bool.doze_double_tap_reports_touch_coordinates);
}
/**
* Whether the single tap sensor uses the proximity sensor for this device posture.
*/
public boolean singleTapUsesProx(@DevicePostureController.DevicePostureInt int devicePosture) {
return getPostureSpecificBool(
mResources.getIntArray(R.array.doze_single_tap_uses_prox_posture_mapping),
singleTapUsesProx(),
devicePosture
);
}
/**
* Whether the single tap sensor uses the proximity sensor.
*/
public boolean singleTapUsesProx() {
private boolean singleTapUsesProx() {
return mResources.getBoolean(R.bool.doze_single_tap_uses_prox);
}
@@ -308,6 +321,20 @@ public class DozeParameters implements
pw.println(getSelectivelyRegisterSensorsUsingProx());
}
private boolean getPostureSpecificBool(
int[] postureMapping,
boolean defaultSensorBool,
int posture) {
boolean bool = defaultSensorBool;
if (posture < postureMapping.length) {
bool = postureMapping[posture] != 0;
} else {
Log.e("DozeParameters", "Unsupported doze posture " + posture);
}
return bool;
}
interface Callback {
/**
* Invoked when the value of getAlwaysOn may have changed.

View File

@@ -50,6 +50,26 @@ public interface DevicePostureController extends CallbackController<Callback> {
/** Return the current device posture. */
@DevicePostureInt int getDevicePosture();
/**
* String representation of DevicePostureInt.
*/
static String devicePostureToString(@DevicePostureInt int posture) {
switch (posture) {
case DEVICE_POSTURE_CLOSED:
return "DEVICE_POSTURE_CLOSED";
case DEVICE_POSTURE_HALF_OPENED:
return "DEVICE_POSTURE_HALF_OPENED";
case DEVICE_POSTURE_OPENED:
return "DEVICE_POSTURE_OPENED";
case DEVICE_POSTURE_FLIPPED:
return "DEVICE_POSTURE_FLIPPED";
case DEVICE_POSTURE_UNKNOWN:
return "DEVICE_POSTURE_UNKNOWN";
default:
return "UNSUPPORTED POSTURE posture=" + posture;
}
}
/** Callback to be notified about device posture changes. */
interface Callback {
/** Called when the posture changes. */

View File

@@ -40,7 +40,7 @@ public class DozeConfigurationUtil {
when(params.doubleTapReportsTouchCoordinates()).thenReturn(false);
when(params.getDisplayNeedsBlanking()).thenReturn(false);
when(params.getSelectivelyRegisterSensorsUsingProx()).thenReturn(false);
when(params.singleTapUsesProx()).thenReturn(true);
when(params.singleTapUsesProx(anyInt())).thenReturn(true);
when(params.longPressUsesProx()).thenReturn(true);
when(params.getQuickPickupAodDuration()).thenReturn(500);
@@ -61,14 +61,13 @@ public class DozeConfigurationUtil {
when(config.getWakeLockScreenDebounce()).thenReturn(0L);
when(config.doubleTapSensorType()).thenReturn(null);
when(config.tapSensorType()).thenReturn(null);
when(config.longPressSensorType()).thenReturn(null);
when(config.udfpsLongPressSensorType()).thenReturn(null);
when(config.quickPickupSensorType()).thenReturn(null);
when(config.tapGestureEnabled(anyInt())).thenReturn(true);
when(config.tapSensorAvailable()).thenReturn(true);
when(config.tapSensorType()).thenReturn(FakeSensorManager.TAP_SENSOR_TYPE);
when(config.tapSensorType(anyInt())).thenReturn(FakeSensorManager.TAP_SENSOR_TYPE);
when(config.dozePickupSensorAvailable()).thenReturn(false);
when(config.wakeScreenGestureAvailable()).thenReturn(false);

View File

@@ -47,6 +47,7 @@ import com.android.systemui.biometrics.AuthController;
import com.android.systemui.doze.DozeSensors.TriggerSensor;
import com.android.systemui.plugins.SensorManagerPlugin;
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.ProximitySensor;
import com.android.systemui.util.settings.FakeSettings;
@@ -85,6 +86,8 @@ public class DozeSensorsTest extends SysuiTestCase {
private AuthController mAuthController;
@Mock
private ProximitySensor mProximitySensor;
private @DevicePostureController.DevicePostureInt int mDevicePosture =
DevicePostureController.DEVICE_POSTURE_UNKNOWN;
private FakeSettings mFakeSettings = new FakeSettings();
private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener;
private TestableLooper mTestableLooper;
@@ -101,6 +104,7 @@ public class DozeSensorsTest extends SysuiTestCase {
((Runnable) invocation.getArgument(0)).run();
return null;
}).when(mWakeLock).wrap(any(Runnable.class));
mDevicePosture = DevicePostureController.DEVICE_POSTURE_UNKNOWN;
mDozeSensors = new TestableDozeSensors();
}
@@ -157,7 +161,7 @@ public class DozeSensorsTest extends SysuiTestCase {
// GIVEN we only should register sensors using prox when not in low-powered mode / off
// and the single tap sensor uses the proximity sensor
when(mDozeParameters.getSelectivelyRegisterSensorsUsingProx()).thenReturn(true);
when(mDozeParameters.singleTapUsesProx()).thenReturn(true);
when(mDozeParameters.singleTapUsesProx(anyInt())).thenReturn(true);
TestableDozeSensors dozeSensors = new TestableDozeSensors();
// THEN on initialization, the tap sensor isn't requested
@@ -258,12 +262,25 @@ public class DozeSensorsTest extends SysuiTestCase {
assertTrue(triggerSensor.mRegistered);
}
@Test
public void testPostureOpen_registersCorrectTapGesture() {
// GIVEN device posture open
mDevicePosture = DevicePostureController.DEVICE_POSTURE_OPENED;
// WHEN DozeSensors are initialized
new TestableDozeSensors();
// THEN we use the posture to determine which tap sensor to use
verify(mAmbientDisplayConfiguration).tapSensorType(eq(mDevicePosture));
}
private class TestableDozeSensors extends DozeSensors {
TestableDozeSensors() {
super(getContext(), mSensorManager, mDozeParameters,
mAmbientDisplayConfiguration, mWakeLock, mCallback, mProxCallback, mDozeLog,
mProximitySensor, mFakeSettings, mAuthController);
mProximitySensor, mFakeSettings, mAuthController,
mDevicePosture);
for (TriggerSensor sensor : mSensors) {
if (sensor instanceof PluginSensor
&& ((PluginSensor) sensor).mPluginSensor.getType()

View File

@@ -45,6 +45,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dock.DockManager;
import com.android.systemui.doze.DozeTriggers.DozingUpdateUiEvent;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.policy.DevicePostureController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.concurrency.FakeThreadFactory;
@@ -86,6 +87,8 @@ public class DozeTriggersTest extends SysuiTestCase {
private UiEventLogger mUiEventLogger;
@Mock
private KeyguardStateController mKeyguardStateController;
@Mock
private DevicePostureController mDevicePostureController;
private DozeTriggers mTriggers;
private FakeSensorManager mSensors;
@@ -117,7 +120,8 @@ public class DozeTriggersTest extends SysuiTestCase {
mTriggers = new DozeTriggers(mContext, mHost, config, dozeParameters,
asyncSensorManager, wakeLock, mDockManager, mProximitySensor,
mProximityCheck, mock(DozeLog.class), mBroadcastDispatcher, new FakeSettings(),
mAuthController, mExecutor, mUiEventLogger, mKeyguardStateController);
mAuthController, mExecutor, mUiEventLogger, mKeyguardStateController,
mDevicePostureController);
mTriggers.setDozeMachine(mMachine);
waitForSensorManager();
}