Loading packages/SystemUI/res/values/config.xml +13 −1 Original line number Diff line number Diff line Loading @@ -205,14 +205,26 @@ far break points. A sensor value less than this is considered "near". --> <item name="proximity_sensor_threshold" translatable="false" format="float" type="dimen"></item> <!-- If using proximity_sensor_type, specifies a threshold value to distinguish near and far break points. A sensor value more than this is considered "far". If not set, proximity_sensor_threshold is used. This allows one to implement a latching mechanism for noisy sensors. --> <item name="proximity_sensor_threshold_latch" translatable="false" format="float" type="dimen"></item> <!-- Override value to use for proximity sensor as confirmation for proximity_sensor_type. --> <string name="proximity_sensor_secondary_type" translatable="false"></string> <!-- If using proximity_sensor_confirmation_type, specifies a threshold value to distinguish <!-- If using proximity_sensor_secondary_type, specifies a threshold value to distinguish near and far break points. A sensor value less than this is considered "near". --> <item name="proximity_sensor_secondary_threshold" translatable="false" format="float" type="dimen"></item> <!-- If using proximity_sensor_secondary_type, specifies a threshold value to distinguish near and far break points. A sensor value more than this is considered "far". If not set, proximity_sensor_secondary_threshold is used. This allows one to implement a latching mechanism for noisy sensors. --> <item name="proximity_sensor_secondary_threshold_latch" translatable="false" format="float" type="dimen"></item> <!-- Doze: pulse parameter - how long does it take to fade in? --> <integer name="doze_pulse_duration_in">130</integer> Loading packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java +2 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ public class SensorModule { .setSensorDelay(SensorManager.SENSOR_DELAY_NORMAL) .setSensorResourceId(R.string.proximity_sensor_type) .setThresholdResourceId(R.dimen.proximity_sensor_threshold) .setThresholdLatchResourceId(R.dimen.proximity_sensor_threshold_latch) .build(); } catch (IllegalStateException e) { Sensor defaultSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); Loading @@ -56,6 +57,7 @@ public class SensorModule { return thresholdSensorBuilder .setSensorResourceId(R.string.proximity_sensor_secondary_type) .setThresholdResourceId(R.dimen.proximity_sensor_secondary_threshold) .setThresholdLatchResourceId(R.dimen.proximity_sensor_secondary_threshold_latch) .build(); } catch (IllegalStateException e) { return thresholdSensorBuilder.setSensor(null).setThresholdValue(0).build(); Loading packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java +54 −7 Original line number Diff line number Diff line Loading @@ -44,14 +44,16 @@ class ThresholdSensorImpl implements ThresholdSensor { private List<Listener> mListeners = new ArrayList<>(); private Boolean mLastBelow; private String mTag; private final float mThresholdLatch; private int mSensorDelay; private SensorEventListener mSensorEventListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { boolean below = event.values[0] < mThreshold; boolean above = event.values[0] > mThresholdLatch; logDebug("Sensor value: " + event.values[0]); onSensorEvent(below, event.timestamp); onSensorEvent(below, above, event.timestamp); } @Override Loading @@ -60,10 +62,11 @@ class ThresholdSensorImpl implements ThresholdSensor { }; private ThresholdSensorImpl(AsyncSensorManager sensorManager, Sensor sensor, float threshold, int sensorDelay) { Sensor sensor, float threshold, float thresholdLatch, int sensorDelay) { mSensorManager = sensorManager; mSensor = sensor; mThreshold = threshold; mThresholdLatch = thresholdLatch; mSensorDelay = sensorDelay; } Loading Loading @@ -165,13 +168,32 @@ class ThresholdSensorImpl implements ThresholdSensor { mLastBelow = null; // Forget what we know. } private void onSensorEvent(boolean below, long timestampNs) { /** * Call when the sensor reports a new value. * * Separate below-threshold and above-thresholds are specified. this allows latching behavior, * where a different threshold can be specified for triggering the sensor depending on if it's * going from above to below or below to above. To outside listeners of this class, the class * still appears entirely binary. */ private void onSensorEvent(boolean belowThreshold, boolean aboveThreshold, long timestampNs) { Assert.isMainThread(); if (!mRegistered || mLastBelow != null && mLastBelow == below) { if (!mRegistered) { return; } mLastBelow = below; alertListenersInternal(below, timestampNs); if (mLastBelow != null) { // If we last reported below and are not yet above, change nothing. if (mLastBelow && !aboveThreshold) { return; } // If we last reported above and are not yet below, change nothing. if (!mLastBelow && !belowThreshold) { return; } } mLastBelow = belowThreshold; logDebug("Alerting below: " + belowThreshold); alertListenersInternal(belowThreshold, timestampNs); } Loading @@ -192,9 +214,11 @@ class ThresholdSensorImpl implements ThresholdSensor { private final AsyncSensorManager mSensorManager; private int mSensorDelay = SensorManager.SENSOR_DELAY_NORMAL;; private float mThresholdValue; private float mThresholdLatchValue; private Sensor mSensor; private boolean mSensorSet; private boolean mThresholdSet; private boolean mThresholdLatchValueSet; @Inject Builder(@Main Resources resources, AsyncSensorManager sensorManager) { Loading Loading @@ -222,6 +246,15 @@ class ThresholdSensorImpl implements ThresholdSensor { return this; } Builder setThresholdLatchResourceId(int thresholdLatchResourceId) { try { setThresholdLatchValue(mResources.getFloat(thresholdLatchResourceId)); } catch (Resources.NotFoundException e) { // no-op } return this; } Builder setSensorType(String sensorType) { Sensor sensor = findSensorByType(sensorType); if (sensor != null) { Loading @@ -233,6 +266,15 @@ class ThresholdSensorImpl implements ThresholdSensor { Builder setThresholdValue(float thresholdValue) { mThresholdValue = thresholdValue; mThresholdSet = true; if (!mThresholdLatchValueSet) { mThresholdLatchValue = mThresholdValue; } return this; } Builder setThresholdLatchValue(float thresholdLatchValue) { mThresholdLatchValue = thresholdLatchValue; mThresholdLatchValueSet = true; return this; } Loading @@ -254,8 +296,13 @@ class ThresholdSensorImpl implements ThresholdSensor { throw new IllegalStateException("A threshold was not successfully set."); } if (mThresholdValue > mThresholdLatchValue) { throw new IllegalStateException( "Threshold must be less than or equal to Threshold Latch"); } return new ThresholdSensorImpl( mSensorManager, mSensor, mThresholdValue, mSensorDelay); mSensorManager, mSensor, mThresholdValue, mThresholdLatchValue, mSensorDelay); } private Sensor findSensorByType(String sensorType) { Loading packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java +55 −5 Original line number Diff line number Diff line Loading @@ -37,19 +37,21 @@ import org.junit.runner.RunWith; public class ThresholdSensorImplTest extends SysuiTestCase { private ThresholdSensorImpl mThresholdSensor; private FakeSensorManager mSensorManager; private AsyncSensorManager mAsyncSensorManager; private FakeSensorManager.FakeProximitySensor mFakeProximitySensor; @Before public void setUp() throws Exception { allowTestableLooperAsMainThread(); FakeSensorManager sensorManager = new FakeSensorManager(getContext()); mSensorManager = new FakeSensorManager(getContext()); AsyncSensorManager asyncSensorManager = new AsyncSensorManager( sensorManager, null, new Handler()); mAsyncSensorManager = new AsyncSensorManager( mSensorManager, null, new Handler()); mFakeProximitySensor = sensorManager.getFakeProximitySensor(); mFakeProximitySensor = mSensorManager.getFakeProximitySensor(); ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder( null, asyncSensorManager); null, mAsyncSensorManager); mThresholdSensor = (ThresholdSensorImpl) thresholdSensorBuilder .setSensor(mFakeProximitySensor.getSensor()) .setThresholdValue(mFakeProximitySensor.getSensor().getMaximumRange()) Loading Loading @@ -226,6 +228,54 @@ public class ThresholdSensorImplTest extends SysuiTestCase { waitForSensorManager(); } @Test public void testHysteresis() { float lowValue = 10f; float highValue = 100f; FakeSensorManager.FakeGenericSensor sensor = mSensorManager.getFakeLightSensor(); ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder( null, mAsyncSensorManager); ThresholdSensorImpl thresholdSensor = (ThresholdSensorImpl) thresholdSensorBuilder .setSensor(sensor.getSensor()) .setThresholdValue(lowValue) .setThresholdLatchValue(highValue) .build(); TestableListener listener = new TestableListener(); assertFalse(thresholdSensor.isRegistered()); thresholdSensor.register(listener); waitForSensorManager(); assertTrue(thresholdSensor.isRegistered()); assertEquals(0, listener.mCallCount); sensor.sendSensorEvent(lowValue - 1); assertTrue(listener.mBelow); assertEquals(1, listener.mCallCount); sensor.sendSensorEvent(lowValue + 1); assertTrue(listener.mBelow); assertEquals(1, listener.mCallCount); sensor.sendSensorEvent(highValue + 1); assertFalse(listener.mBelow); assertEquals(2, listener.mCallCount); sensor.sendSensorEvent(highValue - 1); assertFalse(listener.mBelow); assertEquals(2, listener.mCallCount); sensor.sendSensorEvent(lowValue - 1); assertTrue(listener.mBelow); assertEquals(3, listener.mCallCount); } @Test public void testAlertAfterPause() { TestableListener listener = new TestableListener(); Loading Loading
packages/SystemUI/res/values/config.xml +13 −1 Original line number Diff line number Diff line Loading @@ -205,14 +205,26 @@ far break points. A sensor value less than this is considered "near". --> <item name="proximity_sensor_threshold" translatable="false" format="float" type="dimen"></item> <!-- If using proximity_sensor_type, specifies a threshold value to distinguish near and far break points. A sensor value more than this is considered "far". If not set, proximity_sensor_threshold is used. This allows one to implement a latching mechanism for noisy sensors. --> <item name="proximity_sensor_threshold_latch" translatable="false" format="float" type="dimen"></item> <!-- Override value to use for proximity sensor as confirmation for proximity_sensor_type. --> <string name="proximity_sensor_secondary_type" translatable="false"></string> <!-- If using proximity_sensor_confirmation_type, specifies a threshold value to distinguish <!-- If using proximity_sensor_secondary_type, specifies a threshold value to distinguish near and far break points. A sensor value less than this is considered "near". --> <item name="proximity_sensor_secondary_threshold" translatable="false" format="float" type="dimen"></item> <!-- If using proximity_sensor_secondary_type, specifies a threshold value to distinguish near and far break points. A sensor value more than this is considered "far". If not set, proximity_sensor_secondary_threshold is used. This allows one to implement a latching mechanism for noisy sensors. --> <item name="proximity_sensor_secondary_threshold_latch" translatable="false" format="float" type="dimen"></item> <!-- Doze: pulse parameter - how long does it take to fade in? --> <integer name="doze_pulse_duration_in">130</integer> Loading
packages/SystemUI/src/com/android/systemui/util/sensors/SensorModule.java +2 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ public class SensorModule { .setSensorDelay(SensorManager.SENSOR_DELAY_NORMAL) .setSensorResourceId(R.string.proximity_sensor_type) .setThresholdResourceId(R.dimen.proximity_sensor_threshold) .setThresholdLatchResourceId(R.dimen.proximity_sensor_threshold_latch) .build(); } catch (IllegalStateException e) { Sensor defaultSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); Loading @@ -56,6 +57,7 @@ public class SensorModule { return thresholdSensorBuilder .setSensorResourceId(R.string.proximity_sensor_secondary_type) .setThresholdResourceId(R.dimen.proximity_sensor_secondary_threshold) .setThresholdLatchResourceId(R.dimen.proximity_sensor_secondary_threshold_latch) .build(); } catch (IllegalStateException e) { return thresholdSensorBuilder.setSensor(null).setThresholdValue(0).build(); Loading
packages/SystemUI/src/com/android/systemui/util/sensors/ThresholdSensorImpl.java +54 −7 Original line number Diff line number Diff line Loading @@ -44,14 +44,16 @@ class ThresholdSensorImpl implements ThresholdSensor { private List<Listener> mListeners = new ArrayList<>(); private Boolean mLastBelow; private String mTag; private final float mThresholdLatch; private int mSensorDelay; private SensorEventListener mSensorEventListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { boolean below = event.values[0] < mThreshold; boolean above = event.values[0] > mThresholdLatch; logDebug("Sensor value: " + event.values[0]); onSensorEvent(below, event.timestamp); onSensorEvent(below, above, event.timestamp); } @Override Loading @@ -60,10 +62,11 @@ class ThresholdSensorImpl implements ThresholdSensor { }; private ThresholdSensorImpl(AsyncSensorManager sensorManager, Sensor sensor, float threshold, int sensorDelay) { Sensor sensor, float threshold, float thresholdLatch, int sensorDelay) { mSensorManager = sensorManager; mSensor = sensor; mThreshold = threshold; mThresholdLatch = thresholdLatch; mSensorDelay = sensorDelay; } Loading Loading @@ -165,13 +168,32 @@ class ThresholdSensorImpl implements ThresholdSensor { mLastBelow = null; // Forget what we know. } private void onSensorEvent(boolean below, long timestampNs) { /** * Call when the sensor reports a new value. * * Separate below-threshold and above-thresholds are specified. this allows latching behavior, * where a different threshold can be specified for triggering the sensor depending on if it's * going from above to below or below to above. To outside listeners of this class, the class * still appears entirely binary. */ private void onSensorEvent(boolean belowThreshold, boolean aboveThreshold, long timestampNs) { Assert.isMainThread(); if (!mRegistered || mLastBelow != null && mLastBelow == below) { if (!mRegistered) { return; } mLastBelow = below; alertListenersInternal(below, timestampNs); if (mLastBelow != null) { // If we last reported below and are not yet above, change nothing. if (mLastBelow && !aboveThreshold) { return; } // If we last reported above and are not yet below, change nothing. if (!mLastBelow && !belowThreshold) { return; } } mLastBelow = belowThreshold; logDebug("Alerting below: " + belowThreshold); alertListenersInternal(belowThreshold, timestampNs); } Loading @@ -192,9 +214,11 @@ class ThresholdSensorImpl implements ThresholdSensor { private final AsyncSensorManager mSensorManager; private int mSensorDelay = SensorManager.SENSOR_DELAY_NORMAL;; private float mThresholdValue; private float mThresholdLatchValue; private Sensor mSensor; private boolean mSensorSet; private boolean mThresholdSet; private boolean mThresholdLatchValueSet; @Inject Builder(@Main Resources resources, AsyncSensorManager sensorManager) { Loading Loading @@ -222,6 +246,15 @@ class ThresholdSensorImpl implements ThresholdSensor { return this; } Builder setThresholdLatchResourceId(int thresholdLatchResourceId) { try { setThresholdLatchValue(mResources.getFloat(thresholdLatchResourceId)); } catch (Resources.NotFoundException e) { // no-op } return this; } Builder setSensorType(String sensorType) { Sensor sensor = findSensorByType(sensorType); if (sensor != null) { Loading @@ -233,6 +266,15 @@ class ThresholdSensorImpl implements ThresholdSensor { Builder setThresholdValue(float thresholdValue) { mThresholdValue = thresholdValue; mThresholdSet = true; if (!mThresholdLatchValueSet) { mThresholdLatchValue = mThresholdValue; } return this; } Builder setThresholdLatchValue(float thresholdLatchValue) { mThresholdLatchValue = thresholdLatchValue; mThresholdLatchValueSet = true; return this; } Loading @@ -254,8 +296,13 @@ class ThresholdSensorImpl implements ThresholdSensor { throw new IllegalStateException("A threshold was not successfully set."); } if (mThresholdValue > mThresholdLatchValue) { throw new IllegalStateException( "Threshold must be less than or equal to Threshold Latch"); } return new ThresholdSensorImpl( mSensorManager, mSensor, mThresholdValue, mSensorDelay); mSensorManager, mSensor, mThresholdValue, mThresholdLatchValue, mSensorDelay); } private Sensor findSensorByType(String sensorType) { Loading
packages/SystemUI/tests/src/com/android/systemui/util/sensors/ThresholdSensorImplTest.java +55 −5 Original line number Diff line number Diff line Loading @@ -37,19 +37,21 @@ import org.junit.runner.RunWith; public class ThresholdSensorImplTest extends SysuiTestCase { private ThresholdSensorImpl mThresholdSensor; private FakeSensorManager mSensorManager; private AsyncSensorManager mAsyncSensorManager; private FakeSensorManager.FakeProximitySensor mFakeProximitySensor; @Before public void setUp() throws Exception { allowTestableLooperAsMainThread(); FakeSensorManager sensorManager = new FakeSensorManager(getContext()); mSensorManager = new FakeSensorManager(getContext()); AsyncSensorManager asyncSensorManager = new AsyncSensorManager( sensorManager, null, new Handler()); mAsyncSensorManager = new AsyncSensorManager( mSensorManager, null, new Handler()); mFakeProximitySensor = sensorManager.getFakeProximitySensor(); mFakeProximitySensor = mSensorManager.getFakeProximitySensor(); ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder( null, asyncSensorManager); null, mAsyncSensorManager); mThresholdSensor = (ThresholdSensorImpl) thresholdSensorBuilder .setSensor(mFakeProximitySensor.getSensor()) .setThresholdValue(mFakeProximitySensor.getSensor().getMaximumRange()) Loading Loading @@ -226,6 +228,54 @@ public class ThresholdSensorImplTest extends SysuiTestCase { waitForSensorManager(); } @Test public void testHysteresis() { float lowValue = 10f; float highValue = 100f; FakeSensorManager.FakeGenericSensor sensor = mSensorManager.getFakeLightSensor(); ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder( null, mAsyncSensorManager); ThresholdSensorImpl thresholdSensor = (ThresholdSensorImpl) thresholdSensorBuilder .setSensor(sensor.getSensor()) .setThresholdValue(lowValue) .setThresholdLatchValue(highValue) .build(); TestableListener listener = new TestableListener(); assertFalse(thresholdSensor.isRegistered()); thresholdSensor.register(listener); waitForSensorManager(); assertTrue(thresholdSensor.isRegistered()); assertEquals(0, listener.mCallCount); sensor.sendSensorEvent(lowValue - 1); assertTrue(listener.mBelow); assertEquals(1, listener.mCallCount); sensor.sendSensorEvent(lowValue + 1); assertTrue(listener.mBelow); assertEquals(1, listener.mCallCount); sensor.sendSensorEvent(highValue + 1); assertFalse(listener.mBelow); assertEquals(2, listener.mCallCount); sensor.sendSensorEvent(highValue - 1); assertFalse(listener.mBelow); assertEquals(2, listener.mCallCount); sensor.sendSensorEvent(lowValue - 1); assertTrue(listener.mBelow); assertEquals(3, listener.mCallCount); } @Test public void testAlertAfterPause() { TestableListener listener = new TestableListener(); Loading