From 497b56dbfb5346b399c40dc59fed2c8aecf55feb Mon Sep 17 00:00:00 2001 From: Jiaming Liu Date: Fri, 18 Nov 2022 00:02:07 +0000 Subject: [PATCH] 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 --- .../policy/DeviceStateProviderImpl.java | 4 +- .../policy/DeviceStateProviderImplTest.java | 51 ++++++++++++++++--- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java index 9b7d19a725d1f..1b7a07dcd5a7e 100644 --- a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java +++ b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java @@ -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; } diff --git a/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java b/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java index 90b19a450f483..6d2631ac3ad44 100644 --- a/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java +++ b/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java @@ -65,6 +65,7 @@ public final class DeviceStateProviderImplTest { private final ArgumentCaptor mDeviceStateArrayCaptor = ArgumentCaptor.forClass( DeviceState[].class); private final ArgumentCaptor 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 = "\n" + " \n" + " 1\n" @@ -310,14 +307,22 @@ public final class DeviceStateProviderImplTest { + " " + sensor.getName() + "\n" + " \n" + " 180\n" + + " " + MAX_HINGE_ANGLE_EXCLUSIVE + "\n" + " \n" + " \n" + " \n" + " \n" + "\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);