Track if sensor is active
Keep track of if a sensor has been activated within the Sensor Device.
This prevents a possible race-condition if the Sensors NDK API is used
incorrectly by calling setEventRate prior to enabling a sensor causing
the SensorDevice and SensorService to become out of sync with each
other. In such a situation, the Sensor Device could end up with two
sets of batch parameters for a sensor before activating the sensor.
Previously, if there is more than one set of batch parameters, the
SensorDevice assumes that the device has been activated and will not
activate the sensor. This patch modifies that logic to check if the
sensor is actually activated, and the sensor will be activated if it
is not. This prevents the SensorService and SensorDevice from becoming
out of sync.
Bug: 113594036
Test: CTS SensorOperationTests pass
Test: Created an NDK client that calls setEventRate then waits to call
enableSensor. During the wait, launched second instance of
client. Verified that events are not received by the clients
without this patch, and the SensorService and SensorDevice
became out-of-sync. With this patch, the SensorService and
SensorDevice remained in sync, the sensor was activated, and the
clients received events.
Change-Id: Ifa8281de63d5de7c4a8bbf825982ce28613b3d2c
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index a6ed75f..6570704 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -579,10 +579,9 @@
}
if (info.batchParams.indexOfKey(ident) >= 0) {
- if (info.numActiveClients() == 1) {
- // This is the first connection, we need to activate the underlying h/w sensor.
- actuateHardware = true;
- }
+ if (info.numActiveClients() > 0 && !info.isActive) {
+ actuateHardware = true;
+ }
} else {
// Log error. Every activate call should be preceded by a batch() call.
ALOGE("\t >>>ERROR: activate called without batch");
@@ -631,6 +630,11 @@
if (err != NO_ERROR && enabled) {
// Failure when enabling the sensor. Clean up on failure.
info.removeBatchParamsForIdent(ident);
+ } else {
+ // Update the isActive flag if there is no error. If there is an error when disabling a
+ // sensor, still set the flag to false since the batch parameters have already been
+ // removed. This ensures that everything remains in-sync.
+ info.isActive = enabled;
}
}