Merge "fix [2931909] SensorManger breaks when using different SensorEventListener w/ the same sensors" into gingerbread

This commit is contained in:
Mathias Agopian
2010-09-16 17:54:42 -07:00
committed by Android (Google) Code Review

View File

@@ -24,6 +24,7 @@ import android.os.Message;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.util.Log; import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.view.IRotationWatcher; import android.view.IRotationWatcher;
import android.view.IWindowManager; import android.view.IWindowManager;
import android.view.Surface; import android.view.Surface;
@@ -487,7 +488,7 @@ public class SensorManager
private final ArrayList<Sensor> mSensorList = new ArrayList<Sensor>(); private final ArrayList<Sensor> mSensorList = new ArrayList<Sensor>();
private final Handler mHandler; private final Handler mHandler;
private SensorEvent mValuesPool; private SensorEvent mValuesPool;
public int mSensors; public SparseBooleanArray mSensors = new SparseBooleanArray();
ListenerDelegate(SensorEventListener listener, Sensor sensor, Handler handler) { ListenerDelegate(SensorEventListener listener, Sensor sensor, Handler handler) {
mSensorEventListener = listener; mSensorEventListener = listener;
@@ -541,18 +542,17 @@ public class SensorManager
return mSensorEventListener; return mSensorEventListener;
} }
int addSensor(Sensor sensor) { void addSensor(Sensor sensor) {
mSensors |= 1<<sensor.getHandle(); mSensors.put(sensor.getHandle(), true);
mSensorList.add(sensor); mSensorList.add(sensor);
return mSensors;
} }
int removeSensor(Sensor sensor) { int removeSensor(Sensor sensor) {
mSensors &= ~(1<<sensor.getHandle()); mSensors.delete(sensor.getHandle());
mSensorList.remove(sensor); mSensorList.remove(sensor);
return mSensors; return mSensors.size();
} }
boolean hasSensor(Sensor sensor) { boolean hasSensor(Sensor sensor) {
return ((mSensors & (1<<sensor.getHandle())) != 0); return mSensors.get(sensor.getHandle());
} }
List<Sensor> getSensors() { List<Sensor> getSensors() {
return mSensorList; return mSensorList;
@@ -971,6 +971,31 @@ public class SensorManager
return registerListener(listener, sensor, rate, null); return registerListener(listener, sensor, rate, null);
} }
private boolean enableSensorLocked(Sensor sensor, int delay) {
boolean result = false;
for (ListenerDelegate i : sListeners) {
if (i.hasSensor(sensor)) {
String name = sensor.getName();
int handle = sensor.getHandle();
result = sensors_enable_sensor(sQueue, name, handle, delay);
break;
}
}
return result;
}
private boolean disableSensorLocked(Sensor sensor) {
for (ListenerDelegate i : sListeners) {
if (i.hasSensor(sensor)) {
// not an error, it's just that this sensor is still in use
return true;
}
}
String name = sensor.getName();
int handle = sensor.getHandle();
return sensors_enable_sensor(sQueue, name, handle, SENSOR_DISABLE);
}
/** /**
* Registers a {@link android.hardware.SensorEventListener * Registers a {@link android.hardware.SensorEventListener
* SensorEventListener} for the given sensor. * SensorEventListener} for the given sensor.
@@ -1008,7 +1033,7 @@ public class SensorManager
if (listener == null || sensor == null) { if (listener == null || sensor == null) {
return false; return false;
} }
boolean result; boolean result = true;
int delay = -1; int delay = -1;
switch (rate) { switch (rate) {
case SENSOR_DELAY_FASTEST: case SENSOR_DELAY_FASTEST:
@@ -1029,6 +1054,7 @@ public class SensorManager
} }
synchronized (sListeners) { synchronized (sListeners) {
// look for this listener in our list
ListenerDelegate l = null; ListenerDelegate l = null;
for (ListenerDelegate i : sListeners) { for (ListenerDelegate i : sListeners) {
if (i.getListener() == listener) { if (i.getListener() == listener) {
@@ -1037,29 +1063,37 @@ public class SensorManager
} }
} }
String name = sensor.getName(); // if we don't find it, add it to the list
int handle = sensor.getHandle();
if (l == null) { if (l == null) {
result = false;
l = new ListenerDelegate(listener, sensor, handler); l = new ListenerDelegate(listener, sensor, handler);
sListeners.add(l); sListeners.add(l);
// if the list is not empty, start our main thread
if (!sListeners.isEmpty()) { if (!sListeners.isEmpty()) {
result = sSensorThread.startLocked(); if (sSensorThread.startLocked()) {
if (result) { if (!enableSensorLocked(sensor, delay)) {
result = sensors_enable_sensor(sQueue, name, handle, delay); // oops. there was an error
if (!result) {
// there was an error, remove the listeners
sListeners.remove(l); sListeners.remove(l);
result = false;
} }
} else {
// there was an error, remove the listener
sListeners.remove(l);
result = false;
} }
} else {
// weird, we couldn't add the listener
result = false;
} }
} else { } else {
result = sensors_enable_sensor(sQueue, name, handle, delay); l.addSensor(sensor);
if (result) { if (!enableSensorLocked(sensor, delay)) {
l.addSensor(sensor); // oops. there was an error
l.removeSensor(sensor);
result = false;
} }
} }
} }
return result; return result;
} }
@@ -1072,18 +1106,15 @@ public class SensorManager
for (int i=0 ; i<size ; i++) { for (int i=0 ; i<size ; i++) {
ListenerDelegate l = sListeners.get(i); ListenerDelegate l = sListeners.get(i);
if (l.getListener() == listener) { if (l.getListener() == listener) {
// disable these sensors
String name = sensor.getName();
int handle = sensor.getHandle();
sensors_enable_sensor(sQueue, name, handle, SENSOR_DISABLE);
// if we have no more sensors enabled on this listener,
// take it off the list.
if (l.removeSensor(sensor) == 0) { if (l.removeSensor(sensor) == 0) {
// if we have no more sensors enabled on this listener,
// take it off the list.
sListeners.remove(i); sListeners.remove(i);
} }
break; break;
} }
} }
disableSensorLocked(sensor);
} }
} }
@@ -1096,13 +1127,11 @@ public class SensorManager
for (int i=0 ; i<size ; i++) { for (int i=0 ; i<size ; i++) {
ListenerDelegate l = sListeners.get(i); ListenerDelegate l = sListeners.get(i);
if (l.getListener() == listener) { if (l.getListener() == listener) {
sListeners.remove(i);
// disable all sensors for this listener // disable all sensors for this listener
for (Sensor sensor : l.getSensors()) { for (Sensor sensor : l.getSensors()) {
String name = sensor.getName(); disableSensorLocked(sensor);
int handle = sensor.getHandle();
sensors_enable_sensor(sQueue, name, handle, SENSOR_DISABLE);
} }
sListeners.remove(i);
break; break;
} }
} }