Do not report state change when receiving invalid sensor values
Currently we report the default state when none of the declared states matches the sensor values. This causes the device to switch to the CLOSED state when we receive invalid sensor values. We should instead make it a noop when receiving bad sensor data. Fix: 258990181 Test: atest com.android.server.policy.DeviceStateProviderImplTest#create_sensor Change-Id: I56c4513b7056911d5147f96223a410fe4332af3c
This commit is contained in:
@@ -358,7 +358,7 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
||||
return;
|
||||
}
|
||||
|
||||
int newState = mOrderedStates[0].getIdentifier();
|
||||
int newState = INVALID_DEVICE_STATE;
|
||||
for (int i = 0; i < mOrderedStates.length; i++) {
|
||||
int state = mOrderedStates[i].getIdentifier();
|
||||
if (DEBUG) {
|
||||
@@ -387,7 +387,7 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
||||
}
|
||||
}
|
||||
|
||||
if (newState != mLastReportedState) {
|
||||
if (newState != INVALID_DEVICE_STATE && newState != mLastReportedState) {
|
||||
mLastReportedState = newState;
|
||||
stateToReport = newState;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ public final class DeviceStateProviderImplTest {
|
||||
private final ArgumentCaptor<DeviceState[]> mDeviceStateArrayCaptor = ArgumentCaptor.forClass(
|
||||
DeviceState[].class);
|
||||
private final ArgumentCaptor<Integer> mIntegerCaptor = ArgumentCaptor.forClass(Integer.class);
|
||||
private static final int MAX_HINGE_ANGLE_EXCLUSIVE = 360;
|
||||
|
||||
private Context mContext;
|
||||
private SensorManager mSensorManager;
|
||||
@@ -268,11 +269,7 @@ public final class DeviceStateProviderImplTest {
|
||||
assertEquals(1, mIntegerCaptor.getValue().intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void create_sensor() throws Exception {
|
||||
Sensor sensor = newSensor("sensor", Sensor.STRING_TYPE_HINGE_ANGLE);
|
||||
when(mSensorManager.getSensorList(anyInt())).thenReturn(List.of(sensor));
|
||||
|
||||
private DeviceStateProviderImpl create_sensorBasedProvider(Sensor sensor) {
|
||||
String configString = "<device-state-config>\n"
|
||||
+ " <device-state>\n"
|
||||
+ " <identifier>1</identifier>\n"
|
||||
@@ -310,14 +307,22 @@ public final class DeviceStateProviderImplTest {
|
||||
+ " <name>" + sensor.getName() + "</name>\n"
|
||||
+ " <value>\n"
|
||||
+ " <min-inclusive>180</min-inclusive>\n"
|
||||
+ " <max>" + MAX_HINGE_ANGLE_EXCLUSIVE + "</max>\n"
|
||||
+ " </value>\n"
|
||||
+ " </sensor>\n"
|
||||
+ " </conditions>\n"
|
||||
+ " </device-state>\n"
|
||||
+ "</device-state-config>\n";
|
||||
DeviceStateProviderImpl.ReadableConfig config = new TestReadableConfig(configString);
|
||||
DeviceStateProviderImpl provider = DeviceStateProviderImpl.createFromConfig(mContext,
|
||||
return DeviceStateProviderImpl.createFromConfig(mContext,
|
||||
config);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void create_sensor() throws Exception {
|
||||
Sensor sensor = newSensor("sensor", Sensor.STRING_TYPE_HINGE_ANGLE);
|
||||
when(mSensorManager.getSensorList(anyInt())).thenReturn(List.of(sensor));
|
||||
DeviceStateProviderImpl provider = create_sensorBasedProvider(sensor);
|
||||
|
||||
DeviceStateProvider.Listener listener = mock(DeviceStateProvider.Listener.class);
|
||||
provider.setListener(listener);
|
||||
@@ -370,6 +375,40 @@ public final class DeviceStateProviderImplTest {
|
||||
assertEquals(1, mIntegerCaptor.getValue().intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_invalidSensorValues() throws Exception {
|
||||
// onStateChanged() should not be triggered by invalid sensor values.
|
||||
|
||||
Sensor sensor = newSensor("sensor", Sensor.STRING_TYPE_HINGE_ANGLE);
|
||||
when(mSensorManager.getSensorList(anyInt())).thenReturn(List.of(sensor));
|
||||
DeviceStateProviderImpl provider = create_sensorBasedProvider(sensor);
|
||||
|
||||
DeviceStateProvider.Listener listener = mock(DeviceStateProvider.Listener.class);
|
||||
provider.setListener(listener);
|
||||
Mockito.clearInvocations(listener);
|
||||
|
||||
// First, switch to a non-default state.
|
||||
SensorEvent event1 = mock(SensorEvent.class);
|
||||
event1.sensor = sensor;
|
||||
FieldSetter.setField(event1, event1.getClass().getField("values"), new float[]{90});
|
||||
provider.onSensorChanged(event1);
|
||||
verify(listener).onStateChanged(mIntegerCaptor.capture());
|
||||
assertEquals(2, mIntegerCaptor.getValue().intValue());
|
||||
|
||||
Mockito.clearInvocations(listener);
|
||||
|
||||
// Then, send an invalid sensor event, verify that onStateChanged() is not triggered.
|
||||
SensorEvent event2 = mock(SensorEvent.class);
|
||||
event2.sensor = sensor;
|
||||
FieldSetter.setField(event2, event2.getClass().getField("values"),
|
||||
new float[]{MAX_HINGE_ANGLE_EXCLUSIVE});
|
||||
|
||||
provider.onSensorChanged(event2);
|
||||
|
||||
verify(listener, never()).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
||||
verify(listener, never()).onStateChanged(mIntegerCaptor.capture());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void create_invalidSensor() throws Exception {
|
||||
Sensor sensor = newSensor("sensor", Sensor.STRING_TYPE_HINGE_ANGLE);
|
||||
|
||||
Reference in New Issue
Block a user