Merge "Don't throw exception if DeviceStateProviderImpl can't find required sensor." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
2dd3fdce69
@@ -83,6 +83,7 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
|||||||
private static final String TAG = "DeviceStateProviderImpl";
|
private static final String TAG = "DeviceStateProviderImpl";
|
||||||
|
|
||||||
private static final BooleanSupplier TRUE_BOOLEAN_SUPPLIER = () -> true;
|
private static final BooleanSupplier TRUE_BOOLEAN_SUPPLIER = () -> true;
|
||||||
|
private static final BooleanSupplier FALSE_BOOLEAN_SUPPLIER = () -> false;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState(MINIMUM_DEVICE_STATE,
|
static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState(MINIMUM_DEVICE_STATE,
|
||||||
@@ -152,7 +153,7 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
|||||||
private final DeviceState[] mOrderedStates;
|
private final DeviceState[] mOrderedStates;
|
||||||
// Map of state identifier to a boolean supplier that returns true when all required conditions
|
// Map of state identifier to a boolean supplier that returns true when all required conditions
|
||||||
// are met for the device to be in the state.
|
// are met for the device to be in the state.
|
||||||
private final SparseArray<BooleanSupplier> mStateConditions;
|
private final SparseArray<BooleanSupplier> mStateConditions = new SparseArray<>();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
@@ -177,6 +178,11 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
|||||||
Arrays.sort(orderedStates, Comparator.comparingInt(DeviceState::getIdentifier));
|
Arrays.sort(orderedStates, Comparator.comparingInt(DeviceState::getIdentifier));
|
||||||
mOrderedStates = orderedStates;
|
mOrderedStates = orderedStates;
|
||||||
|
|
||||||
|
setStateConditions(deviceStates, stateConditions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setStateConditions(@NonNull List<DeviceState> deviceStates,
|
||||||
|
@NonNull List<Conditions> stateConditions) {
|
||||||
// Whether or not this instance should register to receive lid switch notifications from
|
// Whether or not this instance should register to receive lid switch notifications from
|
||||||
// InputManagerInternal. If there are no device state conditions that are based on the lid
|
// InputManagerInternal. If there are no device state conditions that are based on the lid
|
||||||
// switch there is no need to register for a callback.
|
// switch there is no need to register for a callback.
|
||||||
@@ -185,7 +191,6 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
|||||||
// The set of Sensor(s) that this instance should register to receive SensorEvent(s) from.
|
// The set of Sensor(s) that this instance should register to receive SensorEvent(s) from.
|
||||||
final ArraySet<Sensor> sensorsToListenTo = new ArraySet<>();
|
final ArraySet<Sensor> sensorsToListenTo = new ArraySet<>();
|
||||||
|
|
||||||
mStateConditions = new SparseArray<>();
|
|
||||||
for (int i = 0; i < stateConditions.size(); i++) {
|
for (int i = 0; i < stateConditions.size(); i++) {
|
||||||
final int state = deviceStates.get(i).getIdentifier();
|
final int state = deviceStates.get(i).getIdentifier();
|
||||||
final Conditions conditions = stateConditions.get(i);
|
final Conditions conditions = stateConditions.get(i);
|
||||||
@@ -194,12 +199,20 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Whether or not all the required hardware components could be found that match the
|
||||||
|
// requirements from the config.
|
||||||
|
boolean allRequiredComponentsFound = true;
|
||||||
|
// Whether or not this condition requires the lid switch.
|
||||||
|
boolean lidSwitchRequired = false;
|
||||||
|
// Set of sensors required for this condition.
|
||||||
|
ArraySet<Sensor> sensorsRequired = new ArraySet<>();
|
||||||
|
|
||||||
List<BooleanSupplier> suppliers = new ArrayList<>();
|
List<BooleanSupplier> suppliers = new ArrayList<>();
|
||||||
|
|
||||||
LidSwitchCondition lidSwitchCondition = conditions.getLidSwitch();
|
LidSwitchCondition lidSwitchCondition = conditions.getLidSwitch();
|
||||||
if (lidSwitchCondition != null) {
|
if (lidSwitchCondition != null) {
|
||||||
suppliers.add(new LidSwitchBooleanSupplier(lidSwitchCondition.getOpen()));
|
suppliers.add(new LidSwitchBooleanSupplier(lidSwitchCondition.getOpen()));
|
||||||
shouldListenToLidSwitch = true;
|
lidSwitchRequired = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<SensorCondition> sensorConditions = conditions.getSensor();
|
List<SensorCondition> sensorConditions = conditions.getSensor();
|
||||||
@@ -210,22 +223,33 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
|||||||
|
|
||||||
final Sensor foundSensor = findSensor(expectedSensorType, expectedSensorName);
|
final Sensor foundSensor = findSensor(expectedSensorType, expectedSensorName);
|
||||||
if (foundSensor == null) {
|
if (foundSensor == null) {
|
||||||
throw new IllegalStateException("Failed to find Sensor with type: "
|
Slog.e(TAG, "Failed to find Sensor with type: " + expectedSensorType
|
||||||
+ expectedSensorType + " and name: " + expectedSensorName);
|
+ " and name: " + expectedSensorName);
|
||||||
|
allRequiredComponentsFound = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
suppliers.add(new SensorBooleanSupplier(foundSensor, sensorCondition.getValue()));
|
suppliers.add(new SensorBooleanSupplier(foundSensor, sensorCondition.getValue()));
|
||||||
sensorsToListenTo.add(foundSensor);
|
sensorsRequired.add(foundSensor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (suppliers.size() > 1) {
|
if (allRequiredComponentsFound) {
|
||||||
mStateConditions.put(state, new AndBooleanSupplier(suppliers));
|
shouldListenToLidSwitch |= lidSwitchRequired;
|
||||||
} else if (suppliers.size() > 0) {
|
sensorsToListenTo.addAll(sensorsRequired);
|
||||||
// No need to wrap with an AND supplier if there is only 1.
|
|
||||||
mStateConditions.put(state, suppliers.get(0));
|
if (suppliers.size() > 1) {
|
||||||
|
mStateConditions.put(state, new AndBooleanSupplier(suppliers));
|
||||||
|
} else if (suppliers.size() > 0) {
|
||||||
|
// No need to wrap with an AND supplier if there is only 1.
|
||||||
|
mStateConditions.put(state, suppliers.get(0));
|
||||||
|
} else {
|
||||||
|
// There are no conditions for this state. Default to always true.
|
||||||
|
mStateConditions.put(state, TRUE_BOOLEAN_SUPPLIER);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// There are no conditions for this state. Default to always true.
|
// Failed to setup this condition. This can happen if a sensor is missing. Default
|
||||||
mStateConditions.put(state, TRUE_BOOLEAN_SUPPLIER);
|
// this state to always false.
|
||||||
|
mStateConditions.put(state, FALSE_BOOLEAN_SUPPLIER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -307,6 +307,56 @@ public final class DeviceStateProviderImplTest {
|
|||||||
assertEquals(1, mIntegerCaptor.getValue().intValue());
|
assertEquals(1, mIntegerCaptor.getValue().intValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void create_invalidSensor() throws Exception {
|
||||||
|
Sensor sensor = newSensor("sensor", Sensor.STRING_TYPE_HINGE_ANGLE);
|
||||||
|
when(mSensorManager.getSensorList(anyInt())).thenReturn(List.of());
|
||||||
|
|
||||||
|
String configString = "<device-state-config>\n"
|
||||||
|
+ " <device-state>\n"
|
||||||
|
+ " <identifier>1</identifier>\n"
|
||||||
|
+ " <name>CLOSED</name>\n"
|
||||||
|
+ " <conditions>\n"
|
||||||
|
+ " <sensor>\n"
|
||||||
|
+ " <type>" + sensor.getStringType() + "</type>\n"
|
||||||
|
+ " <name>" + sensor.getName() + "</name>\n"
|
||||||
|
+ " <value>\n"
|
||||||
|
+ " <max>90</max>\n"
|
||||||
|
+ " </value>\n"
|
||||||
|
+ " </sensor>\n"
|
||||||
|
+ " </conditions>\n"
|
||||||
|
+ " </device-state>\n"
|
||||||
|
+ " <device-state>\n"
|
||||||
|
+ " <identifier>2</identifier>\n"
|
||||||
|
+ " <name>HALF_OPENED</name>\n"
|
||||||
|
+ " <conditions>\n"
|
||||||
|
+ " <sensor>\n"
|
||||||
|
+ " <type>" + sensor.getStringType() + "</type>\n"
|
||||||
|
+ " <name>" + sensor.getName() + "</name>\n"
|
||||||
|
+ " <value>\n"
|
||||||
|
+ " <min-inclusive>90</min-inclusive>\n"
|
||||||
|
+ " <max>180</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,
|
||||||
|
config);
|
||||||
|
|
||||||
|
DeviceStateProvider.Listener listener = mock(DeviceStateProvider.Listener.class);
|
||||||
|
provider.setListener(listener);
|
||||||
|
|
||||||
|
verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
||||||
|
assertArrayEquals(
|
||||||
|
new DeviceState[]{ new DeviceState(1, "CLOSED"), new DeviceState(2, "HALF_OPENED"),
|
||||||
|
}, mDeviceStateArrayCaptor.getValue());
|
||||||
|
// onStateChanged() should be called because the provider could not find the sensor.
|
||||||
|
verify(listener).onStateChanged(mIntegerCaptor.capture());
|
||||||
|
assertEquals(1, mIntegerCaptor.getValue().intValue());
|
||||||
|
}
|
||||||
|
|
||||||
private static Sensor newSensor(String name, String type) throws Exception {
|
private static Sensor newSensor(String name, String type) throws Exception {
|
||||||
Constructor<Sensor> constructor = Sensor.class.getDeclaredConstructor();
|
Constructor<Sensor> constructor = Sensor.class.getDeclaredConstructor();
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
|
|||||||
Reference in New Issue
Block a user