Merge "Ignore wake-up sensor right after sleeping"
This commit is contained in:
@@ -86,6 +86,10 @@ public class AmbientDisplayConfiguration {
|
||||
&& wakeScreenGestureAvailable();
|
||||
}
|
||||
|
||||
public long getWakeLockScreenDebounce() {
|
||||
return mContext.getResources().getInteger(R.integer.config_dozeWakeLockScreenDebounce);
|
||||
}
|
||||
|
||||
public String doubleTapSensorType() {
|
||||
return mContext.getResources().getString(R.string.config_dozeDoubleTapSensorType);
|
||||
}
|
||||
|
||||
@@ -2272,6 +2272,7 @@
|
||||
|
||||
<!-- If the sensor that wakes up the lock screen is available or not. -->
|
||||
<bool name="config_dozeWakeLockScreenSensorAvailable">false</bool>
|
||||
<integer name="config_dozeWakeLockScreenDebounce">3000</integer>
|
||||
|
||||
<!-- Control whether the always on display mode is available. This should only be enabled on
|
||||
devices where the display has been tuned to be power efficient in DOZE and/or DOZE_SUSPEND
|
||||
|
||||
@@ -3404,6 +3404,7 @@
|
||||
|
||||
<java-symbol type="string" name="config_dozeLongPressSensorType" />
|
||||
<java-symbol type="bool" name="config_dozeWakeLockScreenSensorAvailable" />
|
||||
<java-symbol type="integer" name="config_dozeWakeLockScreenDebounce" />
|
||||
|
||||
<java-symbol type="array" name="config_allowedGlobalInstantAppSettings" />
|
||||
<java-symbol type="array" name="config_allowedSystemInstantAppSettings" />
|
||||
|
||||
@@ -38,6 +38,8 @@ import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.hardware.AmbientDisplayConfiguration;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
@@ -60,7 +62,6 @@ public class DozeSensors {
|
||||
private final Context mContext;
|
||||
private final AlarmManager mAlarmManager;
|
||||
private final SensorManager mSensorManager;
|
||||
private final TriggerSensor[] mSensors;
|
||||
private final ContentResolver mResolver;
|
||||
private final TriggerSensor mPickupSensor;
|
||||
private final DozeParameters mDozeParameters;
|
||||
@@ -68,10 +69,12 @@ public class DozeSensors {
|
||||
private final WakeLock mWakeLock;
|
||||
private final Consumer<Boolean> mProxCallback;
|
||||
private final Callback mCallback;
|
||||
@VisibleForTesting
|
||||
protected final TriggerSensor[] mSensors;
|
||||
|
||||
private final Handler mHandler = new Handler();
|
||||
private final ProxSensor mProxSensor;
|
||||
|
||||
private long mDebounceFrom;
|
||||
|
||||
public DozeSensors(Context context, AlarmManager alarmManager, SensorManager sensorManager,
|
||||
DozeParameters dozeParameters, AmbientDisplayConfiguration config, WakeLock wakeLock,
|
||||
@@ -134,13 +137,21 @@ public class DozeSensors {
|
||||
mConfig.wakeScreenGestureAvailable() && alwaysOn,
|
||||
DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN,
|
||||
false /* reports touch coordinates */,
|
||||
false /* touchscreen */),
|
||||
false /* touchscreen */, mConfig.getWakeLockScreenDebounce()),
|
||||
};
|
||||
|
||||
mProxSensor = new ProxSensor(policy);
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporarily disable some sensors to avoid turning on the device while the user is
|
||||
* turning it off.
|
||||
*/
|
||||
public void requestTemporaryDisable() {
|
||||
mDebounceFrom = SystemClock.uptimeMillis();
|
||||
}
|
||||
|
||||
private Sensor findSensorWithType(String type) {
|
||||
return findSensorWithType(mSensorManager, type);
|
||||
}
|
||||
@@ -320,7 +331,8 @@ public class DozeSensors {
|
||||
}
|
||||
}
|
||||
|
||||
private class TriggerSensor extends TriggerEventListener {
|
||||
@VisibleForTesting
|
||||
class TriggerSensor extends TriggerEventListener {
|
||||
final Sensor mSensor;
|
||||
final boolean mConfigured;
|
||||
final int mPulseReason;
|
||||
@@ -467,23 +479,25 @@ public class DozeSensors {
|
||||
/**
|
||||
* A Sensor that is injected via plugin.
|
||||
*/
|
||||
private class PluginSensor extends TriggerSensor {
|
||||
@VisibleForTesting
|
||||
class PluginSensor extends TriggerSensor implements SensorManagerPlugin.SensorEventListener {
|
||||
|
||||
private final SensorManagerPlugin.Sensor mPluginSensor;
|
||||
private final SensorManagerPlugin.SensorEventListener mTriggerEventListener = (event) -> {
|
||||
DozeLog.traceSensor(mContext, mPulseReason);
|
||||
mHandler.post(mWakeLock.wrap(() -> {
|
||||
if (DEBUG) Log.d(TAG, "onSensorEvent: " + triggerEventToString(event));
|
||||
mCallback.onSensorPulse(mPulseReason, true /* sensorPerformsProxCheck */, -1, -1,
|
||||
event.getValues());
|
||||
}));
|
||||
};
|
||||
final SensorManagerPlugin.Sensor mPluginSensor;
|
||||
private long mDebounce;
|
||||
|
||||
PluginSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured,
|
||||
int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen) {
|
||||
this(sensor, setting, configured, pulseReason, reportsTouchCoordinates,
|
||||
requiresTouchscreen, 0L /* debounce */);
|
||||
}
|
||||
|
||||
PluginSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured,
|
||||
int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen,
|
||||
long debounce) {
|
||||
super(null, setting, configured, pulseReason, reportsTouchCoordinates,
|
||||
requiresTouchscreen);
|
||||
mPluginSensor = sensor;
|
||||
mDebounce = debounce;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -492,11 +506,11 @@ public class DozeSensors {
|
||||
AsyncSensorManager asyncSensorManager = (AsyncSensorManager) mSensorManager;
|
||||
if (mRequested && !mDisabled && (enabledBySetting() || mIgnoresSetting)
|
||||
&& !mRegistered) {
|
||||
asyncSensorManager.registerPluginListener(mPluginSensor, mTriggerEventListener);
|
||||
asyncSensorManager.registerPluginListener(mPluginSensor, this);
|
||||
mRegistered = true;
|
||||
if (DEBUG) Log.d(TAG, "registerPluginListener");
|
||||
} else if (mRegistered) {
|
||||
asyncSensorManager.unregisterPluginListener(mPluginSensor, mTriggerEventListener);
|
||||
asyncSensorManager.unregisterPluginListener(mPluginSensor, this);
|
||||
mRegistered = false;
|
||||
if (DEBUG) Log.d(TAG, "unregisterPluginListener");
|
||||
}
|
||||
@@ -524,6 +538,21 @@ public class DozeSensors {
|
||||
}
|
||||
return sb.append(']').toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorManagerPlugin.SensorEvent event) {
|
||||
DozeLog.traceSensor(mContext, mPulseReason);
|
||||
mHandler.post(mWakeLock.wrap(() -> {
|
||||
final long now = SystemClock.uptimeMillis();
|
||||
if (now < mDebounceFrom + mDebounce) {
|
||||
if (DEBUG) Log.d(TAG, "onSensorEvent dropped: " + triggerEventToString(event));
|
||||
return;
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "onSensorEvent: " + triggerEventToString(event));
|
||||
mCallback.onSensorPulse(mPulseReason, true /* sensorPerformsProxCheck */, -1, -1,
|
||||
event.getValues());
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
|
||||
@@ -143,8 +143,12 @@ public class DozeTriggers implements DozeMachine.Part {
|
||||
|
||||
if (isWakeDisplay) {
|
||||
onWakeScreen(wakeEvent, mMachine.getState());
|
||||
} else if (isLongPress || isWakeLockScreen) {
|
||||
} else if (isLongPress) {
|
||||
requestPulse(pulseReason, sensorPerformedProxCheck);
|
||||
} else if (isWakeLockScreen) {
|
||||
if (wakeEvent) {
|
||||
requestPulse(pulseReason, sensorPerformedProxCheck);
|
||||
}
|
||||
} else {
|
||||
proximityCheckThenCall((result) -> {
|
||||
if (result == ProximityCheck.RESULT_NEAR) {
|
||||
@@ -228,6 +232,7 @@ public class DozeTriggers implements DozeMachine.Part {
|
||||
if (mDockManager != null) {
|
||||
mDockManager.addListener(mDockEventListener);
|
||||
}
|
||||
mDozeSensors.requestTemporaryDisable();
|
||||
checkTriggersAtInit();
|
||||
break;
|
||||
case DOZE:
|
||||
@@ -250,6 +255,9 @@ public class DozeTriggers implements DozeMachine.Part {
|
||||
mDozeSensors.setTouchscreenSensorsListening(false);
|
||||
mDozeSensors.setProxListening(true);
|
||||
break;
|
||||
case DOZE_PULSE_DONE:
|
||||
mDozeSensors.requestTemporaryDisable();
|
||||
break;
|
||||
case FINISH:
|
||||
mBroadcastReceiver.unregister(mContext);
|
||||
mDozeHost.removeCallback(mHostCallback);
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.doze;
|
||||
|
||||
import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_LOCK_SCREEN;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyFloat;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.testing.TestableLooper.RunWithLooper;
|
||||
|
||||
import com.android.internal.hardware.AmbientDisplayConfiguration;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.plugins.SensorManagerPlugin;
|
||||
import com.android.systemui.statusbar.phone.DozeParameters;
|
||||
import com.android.systemui.util.AsyncSensorManager;
|
||||
import com.android.systemui.util.wakelock.WakeLock;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@RunWithLooper
|
||||
@SmallTest
|
||||
public class DozeSensorsTest extends SysuiTestCase {
|
||||
|
||||
@Mock
|
||||
private AlarmManager mAlarmManager;
|
||||
@Mock
|
||||
private AsyncSensorManager mSensorManager;
|
||||
@Mock
|
||||
private DozeParameters mDozeParameters;
|
||||
@Mock
|
||||
private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
|
||||
@Mock
|
||||
private WakeLock mWakeLock;
|
||||
@Mock
|
||||
private DozeSensors.Callback mCallback;
|
||||
@Mock
|
||||
private Consumer<Boolean> mProxCallback;
|
||||
@Mock
|
||||
private AlwaysOnDisplayPolicy mAlwaysOnDisplayPolicy;
|
||||
private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener;
|
||||
private TestableLooper mTestableLooper;
|
||||
private DozeSensors mDozeSensors;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mTestableLooper = TestableLooper.get(this);
|
||||
when(mAmbientDisplayConfiguration.getWakeLockScreenDebounce()).thenReturn(5000L);
|
||||
when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
|
||||
doAnswer(invocation -> {
|
||||
((Runnable) invocation.getArgument(0)).run();
|
||||
return null;
|
||||
}).when(mWakeLock).wrap(any(Runnable.class));
|
||||
mDozeSensors = new TestableDozeSensors();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSensorDebounce() {
|
||||
mDozeSensors.setListening(true);
|
||||
|
||||
mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class));
|
||||
mTestableLooper.processAllMessages();
|
||||
verify(mCallback).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN),
|
||||
anyBoolean(), anyFloat(), anyFloat(), eq(null));
|
||||
|
||||
mDozeSensors.requestTemporaryDisable();
|
||||
reset(mCallback);
|
||||
mWakeLockScreenListener.onSensorChanged(mock(SensorManagerPlugin.SensorEvent.class));
|
||||
mTestableLooper.processAllMessages();
|
||||
verify(mCallback, never()).onSensorPulse(eq(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN),
|
||||
anyBoolean(), anyFloat(), anyFloat(), eq(null));
|
||||
}
|
||||
|
||||
private class TestableDozeSensors extends DozeSensors {
|
||||
|
||||
TestableDozeSensors() {
|
||||
super(getContext(), mAlarmManager, mSensorManager, mDozeParameters,
|
||||
mAmbientDisplayConfiguration, mWakeLock, mCallback, mProxCallback,
|
||||
mAlwaysOnDisplayPolicy);
|
||||
for (TriggerSensor sensor : mSensors) {
|
||||
if (sensor instanceof PluginSensor
|
||||
&& ((PluginSensor) sensor).mPluginSensor.getType()
|
||||
== TYPE_WAKE_LOCK_SCREEN) {
|
||||
mWakeLockScreenListener = (PluginSensor) sensor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user