Merge "Add latching threshold for ThresholdSensorImpl" into rvc-d1-dev am: d4fd553c18
Change-Id: I4801d2ad1b79e05af0f4f159ce1066a25f86b291
This commit is contained in:
@@ -205,14 +205,26 @@
|
|||||||
far break points. A sensor value less than this is considered "near". -->
|
far break points. A sensor value less than this is considered "near". -->
|
||||||
<item name="proximity_sensor_threshold" translatable="false" format="float" type="dimen"></item>
|
<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. -->
|
<!-- Override value to use for proximity sensor as confirmation for proximity_sensor_type. -->
|
||||||
<string name="proximity_sensor_secondary_type" translatable="false"></string>
|
<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". -->
|
near and far break points. A sensor value less than this is considered "near". -->
|
||||||
<item name="proximity_sensor_secondary_threshold" translatable="false" format="float"
|
<item name="proximity_sensor_secondary_threshold" translatable="false" format="float"
|
||||||
type="dimen"></item>
|
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? -->
|
<!-- Doze: pulse parameter - how long does it take to fade in? -->
|
||||||
<integer name="doze_pulse_duration_in">130</integer>
|
<integer name="doze_pulse_duration_in">130</integer>
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class SensorModule {
|
|||||||
.setSensorDelay(SensorManager.SENSOR_DELAY_NORMAL)
|
.setSensorDelay(SensorManager.SENSOR_DELAY_NORMAL)
|
||||||
.setSensorResourceId(R.string.proximity_sensor_type)
|
.setSensorResourceId(R.string.proximity_sensor_type)
|
||||||
.setThresholdResourceId(R.dimen.proximity_sensor_threshold)
|
.setThresholdResourceId(R.dimen.proximity_sensor_threshold)
|
||||||
|
.setThresholdLatchResourceId(R.dimen.proximity_sensor_threshold_latch)
|
||||||
.build();
|
.build();
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
Sensor defaultSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
|
Sensor defaultSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
|
||||||
@@ -56,6 +57,7 @@ public class SensorModule {
|
|||||||
return thresholdSensorBuilder
|
return thresholdSensorBuilder
|
||||||
.setSensorResourceId(R.string.proximity_sensor_secondary_type)
|
.setSensorResourceId(R.string.proximity_sensor_secondary_type)
|
||||||
.setThresholdResourceId(R.dimen.proximity_sensor_secondary_threshold)
|
.setThresholdResourceId(R.dimen.proximity_sensor_secondary_threshold)
|
||||||
|
.setThresholdLatchResourceId(R.dimen.proximity_sensor_secondary_threshold_latch)
|
||||||
.build();
|
.build();
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
return thresholdSensorBuilder.setSensor(null).setThresholdValue(0).build();
|
return thresholdSensorBuilder.setSensor(null).setThresholdValue(0).build();
|
||||||
|
|||||||
@@ -44,14 +44,16 @@ class ThresholdSensorImpl implements ThresholdSensor {
|
|||||||
private List<Listener> mListeners = new ArrayList<>();
|
private List<Listener> mListeners = new ArrayList<>();
|
||||||
private Boolean mLastBelow;
|
private Boolean mLastBelow;
|
||||||
private String mTag;
|
private String mTag;
|
||||||
|
private final float mThresholdLatch;
|
||||||
private int mSensorDelay;
|
private int mSensorDelay;
|
||||||
|
|
||||||
private SensorEventListener mSensorEventListener = new SensorEventListener() {
|
private SensorEventListener mSensorEventListener = new SensorEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onSensorChanged(SensorEvent event) {
|
public void onSensorChanged(SensorEvent event) {
|
||||||
boolean below = event.values[0] < mThreshold;
|
boolean below = event.values[0] < mThreshold;
|
||||||
|
boolean above = event.values[0] > mThresholdLatch;
|
||||||
logDebug("Sensor value: " + event.values[0]);
|
logDebug("Sensor value: " + event.values[0]);
|
||||||
onSensorEvent(below, event.timestamp);
|
onSensorEvent(below, above, event.timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -60,10 +62,11 @@ class ThresholdSensorImpl implements ThresholdSensor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private ThresholdSensorImpl(AsyncSensorManager sensorManager,
|
private ThresholdSensorImpl(AsyncSensorManager sensorManager,
|
||||||
Sensor sensor, float threshold, int sensorDelay) {
|
Sensor sensor, float threshold, float thresholdLatch, int sensorDelay) {
|
||||||
mSensorManager = sensorManager;
|
mSensorManager = sensorManager;
|
||||||
mSensor = sensor;
|
mSensor = sensor;
|
||||||
mThreshold = threshold;
|
mThreshold = threshold;
|
||||||
|
mThresholdLatch = thresholdLatch;
|
||||||
mSensorDelay = sensorDelay;
|
mSensorDelay = sensorDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,13 +168,32 @@ class ThresholdSensorImpl implements ThresholdSensor {
|
|||||||
mLastBelow = null; // Forget what we know.
|
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();
|
Assert.isMainThread();
|
||||||
if (!mRegistered || mLastBelow != null && mLastBelow == below) {
|
if (!mRegistered) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mLastBelow = below;
|
if (mLastBelow != null) {
|
||||||
alertListenersInternal(below, timestampNs);
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -192,9 +214,11 @@ class ThresholdSensorImpl implements ThresholdSensor {
|
|||||||
private final AsyncSensorManager mSensorManager;
|
private final AsyncSensorManager mSensorManager;
|
||||||
private int mSensorDelay = SensorManager.SENSOR_DELAY_NORMAL;;
|
private int mSensorDelay = SensorManager.SENSOR_DELAY_NORMAL;;
|
||||||
private float mThresholdValue;
|
private float mThresholdValue;
|
||||||
|
private float mThresholdLatchValue;
|
||||||
private Sensor mSensor;
|
private Sensor mSensor;
|
||||||
private boolean mSensorSet;
|
private boolean mSensorSet;
|
||||||
private boolean mThresholdSet;
|
private boolean mThresholdSet;
|
||||||
|
private boolean mThresholdLatchValueSet;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
Builder(@Main Resources resources, AsyncSensorManager sensorManager) {
|
Builder(@Main Resources resources, AsyncSensorManager sensorManager) {
|
||||||
@@ -222,6 +246,15 @@ class ThresholdSensorImpl implements ThresholdSensor {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Builder setThresholdLatchResourceId(int thresholdLatchResourceId) {
|
||||||
|
try {
|
||||||
|
setThresholdLatchValue(mResources.getFloat(thresholdLatchResourceId));
|
||||||
|
} catch (Resources.NotFoundException e) {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
Builder setSensorType(String sensorType) {
|
Builder setSensorType(String sensorType) {
|
||||||
Sensor sensor = findSensorByType(sensorType);
|
Sensor sensor = findSensorByType(sensorType);
|
||||||
if (sensor != null) {
|
if (sensor != null) {
|
||||||
@@ -233,6 +266,15 @@ class ThresholdSensorImpl implements ThresholdSensor {
|
|||||||
Builder setThresholdValue(float thresholdValue) {
|
Builder setThresholdValue(float thresholdValue) {
|
||||||
mThresholdValue = thresholdValue;
|
mThresholdValue = thresholdValue;
|
||||||
mThresholdSet = true;
|
mThresholdSet = true;
|
||||||
|
if (!mThresholdLatchValueSet) {
|
||||||
|
mThresholdLatchValue = mThresholdValue;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder setThresholdLatchValue(float thresholdLatchValue) {
|
||||||
|
mThresholdLatchValue = thresholdLatchValue;
|
||||||
|
mThresholdLatchValueSet = true;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,8 +296,13 @@ class ThresholdSensorImpl implements ThresholdSensor {
|
|||||||
throw new IllegalStateException("A threshold was not successfully set.");
|
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(
|
return new ThresholdSensorImpl(
|
||||||
mSensorManager, mSensor, mThresholdValue, mSensorDelay);
|
mSensorManager, mSensor, mThresholdValue, mThresholdLatchValue, mSensorDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Sensor findSensorByType(String sensorType) {
|
private Sensor findSensorByType(String sensorType) {
|
||||||
|
|||||||
@@ -37,19 +37,21 @@ import org.junit.runner.RunWith;
|
|||||||
public class ThresholdSensorImplTest extends SysuiTestCase {
|
public class ThresholdSensorImplTest extends SysuiTestCase {
|
||||||
|
|
||||||
private ThresholdSensorImpl mThresholdSensor;
|
private ThresholdSensorImpl mThresholdSensor;
|
||||||
|
private FakeSensorManager mSensorManager;
|
||||||
|
private AsyncSensorManager mAsyncSensorManager;
|
||||||
private FakeSensorManager.FakeProximitySensor mFakeProximitySensor;
|
private FakeSensorManager.FakeProximitySensor mFakeProximitySensor;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
allowTestableLooperAsMainThread();
|
allowTestableLooperAsMainThread();
|
||||||
FakeSensorManager sensorManager = new FakeSensorManager(getContext());
|
mSensorManager = new FakeSensorManager(getContext());
|
||||||
|
|
||||||
AsyncSensorManager asyncSensorManager = new AsyncSensorManager(
|
mAsyncSensorManager = new AsyncSensorManager(
|
||||||
sensorManager, null, new Handler());
|
mSensorManager, null, new Handler());
|
||||||
|
|
||||||
mFakeProximitySensor = sensorManager.getFakeProximitySensor();
|
mFakeProximitySensor = mSensorManager.getFakeProximitySensor();
|
||||||
ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder(
|
ThresholdSensorImpl.Builder thresholdSensorBuilder = new ThresholdSensorImpl.Builder(
|
||||||
null, asyncSensorManager);
|
null, mAsyncSensorManager);
|
||||||
mThresholdSensor = (ThresholdSensorImpl) thresholdSensorBuilder
|
mThresholdSensor = (ThresholdSensorImpl) thresholdSensorBuilder
|
||||||
.setSensor(mFakeProximitySensor.getSensor())
|
.setSensor(mFakeProximitySensor.getSensor())
|
||||||
.setThresholdValue(mFakeProximitySensor.getSensor().getMaximumRange())
|
.setThresholdValue(mFakeProximitySensor.getSensor().getMaximumRange())
|
||||||
@@ -226,6 +228,54 @@ public class ThresholdSensorImplTest extends SysuiTestCase {
|
|||||||
waitForSensorManager();
|
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
|
@Test
|
||||||
public void testAlertAfterPause() {
|
public void testAlertAfterPause() {
|
||||||
TestableListener listener = new TestableListener();
|
TestableListener listener = new TestableListener();
|
||||||
|
|||||||
Reference in New Issue
Block a user