Fix race condition and disable call.
1. A dispatch event can happen as soon you call enabled,
and we won't be ready to receive it. Also add error checks
and not crash if such a thing happens.
2. Java layer shouldn't call disable on the native layer
for trigger sensors. Native layer will clean up on its own.
b/8165631
Change-Id: Icbe76bd1f50632c0bcb0b3b04975b2c2f20ff36b
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 37cbe04..30118f9 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -1387,14 +1387,14 @@
* @throws IllegalArgumentException when sensor is a trigger sensor.
*/
public boolean cancelTriggerSensor(TriggerEventListener listener, Sensor sensor) {
- return cancelTriggerSensorImpl(listener, sensor);
+ return cancelTriggerSensorImpl(listener, sensor, true);
}
/**
* @hide
*/
protected abstract boolean cancelTriggerSensorImpl(TriggerEventListener listener,
- Sensor sensor);
+ Sensor sensor, boolean disable);
private LegacySensorManager getLegacySensorManager() {
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index c6c999b..852cf4a 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -20,6 +20,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.MessageQueue;
+import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
@@ -135,7 +136,7 @@
if (sensor == null) {
result = queue.removeAllSensors();
} else {
- result = queue.removeSensor(sensor);
+ result = queue.removeSensor(sensor, true);
}
if (result && !queue.hasSensors()) {
mSensorListeners.remove(listener);
@@ -170,7 +171,8 @@
/** @hide */
@Override
- protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
+ protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor,
+ boolean disable) {
if (sensor != null && Sensor.getReportingMode(sensor) != Sensor.REPORTING_MODE_ONE_SHOT) {
return false;
}
@@ -181,7 +183,7 @@
if (sensor == null) {
result = queue.removeAllSensors();
} else {
- result = queue.removeSensor(sensor);
+ result = queue.removeSensor(sensor, disable);
}
if (result && !queue.hasSensors()) {
mTriggerListeners.remove(listener);
@@ -225,14 +227,17 @@
public boolean addSensor(Sensor sensor, int delay) {
// Check if already present.
- if (mActiveSensors.get(sensor.getHandle())) return false;
+ int handle = sensor.getHandle();
+ if (mActiveSensors.get(handle)) return false;
- if (enableSensor(sensor, delay) == 0) {
- mActiveSensors.put(sensor.getHandle(), true);
- addSensorEvent(sensor);
- return true;
+ // Get ready to receive events before calling enable.
+ mActiveSensors.put(handle, true);
+ addSensorEvent(sensor);
+ if (enableSensor(sensor, delay) != 0) {
+ removeSensor(sensor, false);
+ return false;
}
- return false;
+ return true;
}
public boolean removeAllSensors() {
@@ -252,10 +257,10 @@
return true;
}
- public boolean removeSensor(Sensor sensor) {
+ public boolean removeSensor(Sensor sensor, boolean disable) {
final int handle = sensor.getHandle();
if (mActiveSensors.get(handle)) {
- disableSensor(sensor);
+ if (disable) disableSensor(sensor);
mActiveSensors.put(sensor.getHandle(), false);
removeSensorEvent(sensor);
return true;
@@ -334,6 +339,10 @@
long timestamp) {
final Sensor sensor = sHandleToSensor.get(handle);
SensorEvent t = mSensorsEvents.get(handle);
+ if (t == null) {
+ Log.e(TAG, "Error: Sensor Event is null for Sensor: " + sensor);
+ return;
+ }
// Copy from the values array.
System.arraycopy(values, 0, t.values, 0, t.values.length);
t.timestamp = timestamp;
@@ -390,14 +399,19 @@
long timestamp) {
final Sensor sensor = sHandleToSensor.get(handle);
TriggerEvent t = mTriggerEvents.get(handle);
+ if (t == null) {
+ Log.e(TAG, "Error: Trigger Event is null for Sensor: " + sensor);
+ return;
+ }
// Copy from the values array.
System.arraycopy(values, 0, t.values, 0, t.values.length);
t.timestamp = timestamp;
t.sensor = sensor;
- // A trigger sensor should be auto disabled.
- mManager.cancelTriggerSensorImpl(mListener, sensor);
+ // A trigger sensor is auto disabled. So just clean up and don't call native
+ // disable.
+ mManager.cancelTriggerSensorImpl(mListener, sensor, false);
mListener.onTrigger(t);
}