Revert "Add new sensor types."
This reverts commit bc03a348d78326dee779a8ecc325799c9fceac98.
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 3c231e5..9591631 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -16,19 +16,18 @@
package android.hardware;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+import dalvik.system.CloseGuard;
+
import android.os.Handler;
import android.os.Looper;
import android.os.MessageQueue;
-import android.util.Log;
-import android.util.Pools;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
-import dalvik.system.CloseGuard;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
/**
* Sensor manager implementation that communicates with the built-in
@@ -46,21 +45,22 @@
private static final SparseArray<Sensor> sHandleToSensor = new SparseArray<Sensor>();
// Listener list
- private final HashMap<SensorEventListener, SensorEventQueue> mSensorListeners =
- new HashMap<SensorEventListener, SensorEventQueue>();
- private final HashMap<TriggerEventListener, TriggerEventQueue> mTriggerListeners =
- new HashMap<TriggerEventListener, TriggerEventQueue>();
+ private final ArrayList<SensorEventListenerSensorPair> mListenerDelegates = new ArrayList<SensorEventListenerSensorPair>();
- private static final int MAX_EVENTS = 16;
- private static Pools.SynchronizedPool<SensorEvent> sSensorEventPool;
- private static Pools.SynchronizedPool<TriggerEvent> sTriggerEventPool;
+ // Common pool of sensor events.
+ private static SensorEventPool sPool;
// Looper associated with the context in which this instance was created.
private final Looper mMainLooper;
+ // maps a SensorEventListener to a SensorEventQueue
+ private final Hashtable<SensorEventListener, SensorEventQueue> mSensorEventQueueMap;
+
/** {@hide} */
public SystemSensorManager(Looper mainLooper) {
mMainLooper = mainLooper;
+ mSensorEventQueueMap = new Hashtable<SensorEventListener, SensorEventQueue>();
+
synchronized(sSensorModuleLock) {
if (!sSensorModuleInitialized) {
sSensorModuleInitialized = true;
@@ -81,10 +81,7 @@
}
} while (i>0);
- sSensorEventPool = new Pools.SynchronizedPool<SensorEvent>(
- sFullSensorsList.size()*2);
- sTriggerEventPool = new Pools.SynchronizedPool<TriggerEvent>(
- sFullSensorsList.size()*2);
+ sPool = new SensorEventPool( sFullSensorsList.size()*2 );
}
}
}
@@ -105,133 +102,128 @@
// Invariants to preserve:
// - one Looper per SensorEventListener
// - one Looper per SensorEventQueue
- // We map SensorEventListener to a SensorEventQueue, which holds the looper
- if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
+ // We map SensorEventListeners to a SensorEventQueue, which holds the looper
- // Trigger Sensors should use the requestTriggerSensor call.
- if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) return false;
+ if (sensor == null) throw new NullPointerException("sensor cannot be null");
- synchronized (mSensorListeners) {
- SensorEventQueue queue = mSensorListeners.get(listener);
- if (queue == null) {
- Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
- queue = new SensorEventQueue(listener, looper);
- if (!queue.addSensor(sensor, delay)) {
- queue.dispose();
- return false;
+ boolean result;
+ synchronized (mSensorEventQueueMap) {
+ // check if we already have this SensorEventListener, Sensor pair
+ // registered -- if so, we ignore the register. This is not ideal
+ // but this is what the implementation has always been doing.
+ for (SensorEventListenerSensorPair l : mListenerDelegates) {
+ if (l.isSameListenerSensorPair(listener, sensor)) {
+ // already added, just return silently.
+ return true;
}
- mSensorListeners.put(listener, queue);
- return true;
+ }
+
+ // now find the SensorEventQueue associated to this listener
+ SensorEventQueue queue = mSensorEventQueueMap.get(listener);
+ if (queue != null) {
+ result = queue.addSensor(sensor, delay);
+ if (result) {
+ // create a new ListenerDelegate for this pair
+ mListenerDelegates.add(new SensorEventListenerSensorPair(listener, sensor));
+ }
} else {
- return queue.addSensor(sensor, delay);
+ Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
+ queue = new SensorEventQueue(listener, looper.getQueue());
+ result = queue.addSensor(sensor, delay);
+ if (result) {
+ // create a new ListenerDelegate for this pair
+ mListenerDelegates.add(new SensorEventListenerSensorPair(listener, sensor));
+ mSensorEventQueueMap.put(listener, queue);
+ } else {
+ queue.dispose();
+ }
}
}
+ return result;
}
/** @hide */
@Override
protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
- // Trigger Sensors should use the cancelTriggerSensor call.
- if (sensor != null && Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) {
- return;
- }
+ synchronized (mSensorEventQueueMap) {
- synchronized (mSensorListeners) {
- SensorEventQueue queue = mSensorListeners.get(listener);
- if (queue != null) {
- boolean result;
- if (sensor == null) {
- result = queue.removeAllSensors();
- } else {
- result = queue.removeSensor(sensor);
+ // remove this listener/sensor from our list
+ final ArrayList<SensorEventListenerSensorPair> copy =
+ new ArrayList<SensorEventListenerSensorPair>(mListenerDelegates);
+ int lastIndex = copy.size()-1;
+ for (int i=lastIndex ; i>= 0 ; i--) {
+ if (copy.get(i).isSameListenerSensorPair(listener, sensor)) {
+ mListenerDelegates.remove(i);
}
- if (result && !queue.hasSensors()) {
- mSensorListeners.remove(listener);
+ }
+
+ // find the SensorEventQueue associated to this SensorEventListener
+ SensorEventQueue queue = mSensorEventQueueMap.get(listener);
+ if (queue != null) {
+ if (sensor != null) {
+ queue.removeSensor(sensor);
+ } else {
+ queue.removeAllSensors();
+ }
+ if (!queue.hasSensors()) {
+ mSensorEventQueueMap.remove(listener);
queue.dispose();
}
}
}
}
- /** @hide */
- @Override
- protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
- if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
- if (Sensor.getReportingMode(sensor) != Sensor.REPORTING_MODE_ONE_SHOT) return false;
-
- synchronized (mTriggerListeners) {
- TriggerEventQueue queue = mTriggerListeners.get(listener);
- if (queue == null) {
- queue = new TriggerEventQueue(listener, mMainLooper, this);
- if (!queue.addSensor(sensor, 0)) {
- queue.dispose();
- return false;
- }
- mTriggerListeners.put(listener, queue);
- return true;
+ /*
+ * ListenerDelegate is essentially a SensorEventListener, Sensor pair
+ * and is associated with a single SensorEventQueue.
+ */
+ private static final class SensorEventListenerSensorPair {
+ private final SensorEventListener mSensorEventListener;
+ private final Sensor mSensor;
+ public SensorEventListenerSensorPair(SensorEventListener listener, Sensor sensor) {
+ mSensorEventListener = listener;
+ mSensor = sensor;
+ }
+ public boolean isSameListenerSensorPair(SensorEventListener listener, Sensor sensor) {
+ // if sensor is null, we match only on the listener
+ if (sensor != null) {
+ return (listener == mSensorEventListener) &&
+ (sensor.getHandle() == mSensor.getHandle());
} else {
- return queue.addSensor(sensor, 0);
+ return (listener == mSensorEventListener);
}
}
}
- /** @hide */
- @Override
- protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
- if (sensor != null && Sensor.getReportingMode(sensor) != Sensor.REPORTING_MODE_ONE_SHOT) {
- return false;
- }
- synchronized (mTriggerListeners) {
- TriggerEventQueue queue = mTriggerListeners.get(listener);
- if (queue != null) {
- boolean result;
- if (sensor == null) {
- result = queue.removeAllSensors();
- } else {
- result = queue.removeSensor(sensor);
- }
- if (result && !queue.hasSensors()) {
- mTriggerListeners.remove(listener);
- queue.dispose();
- }
- return result;
- }
- return false;
- }
- }
-
/*
- * BaseEventQueue is the communication channel with the sensor service,
- * SensorEventQueue, TriggerEventQueue are subclases and there is one-to-one mapping between
- * the queues and the listeners.
+ * SensorEventQueue is the communication channel with the sensor service,
+ * there is a one-to-one mapping between SensorEventQueue and
+ * SensorEventListener.
*/
- private static abstract class BaseEventQueue {
- private native int nativeInitBaseEventQueue(BaseEventQueue eventQ, MessageQueue msgQ,
- float[] scratch);
+ private static final class SensorEventQueue {
+ private static native int nativeInitSensorEventQueue(SensorEventQueue eventQ, MessageQueue msgQ, float[] scratch);
private static native int nativeEnableSensor(int eventQ, int handle, int us);
private static native int nativeDisableSensor(int eventQ, int handle);
private static native void nativeDestroySensorEventQueue(int eventQ);
private int nSensorEventQueue;
+ private final SensorEventListener mListener;
private final SparseBooleanArray mActiveSensors = new SparseBooleanArray();
- protected final SparseIntArray mSensorAccuracies = new SparseIntArray();
- protected final SparseBooleanArray mFirstEvent = new SparseBooleanArray();
+ private final SparseIntArray mSensorAccuracies = new SparseIntArray();
+ private final SparseBooleanArray mFirstEvent = new SparseBooleanArray();
private final CloseGuard mCloseGuard = CloseGuard.get();
private final float[] mScratch = new float[16];
- BaseEventQueue(Looper looper) {
- nSensorEventQueue = nativeInitBaseEventQueue(this, looper.getQueue(), mScratch);
+ public SensorEventQueue(SensorEventListener listener, MessageQueue msgQ) {
+ nSensorEventQueue = nativeInitSensorEventQueue(this, msgQ, mScratch);
+ mListener = listener;
mCloseGuard.open("dispose");
}
-
public void dispose() {
dispose(false);
}
public boolean addSensor(Sensor sensor, int delay) {
- // Check if already present.
- if (mActiveSensors.get(sensor.getHandle())) return false;
-
if (enableSensor(sensor, delay) == 0) {
mActiveSensors.put(sensor.getHandle(), true);
return true;
@@ -239,7 +231,7 @@
return false;
}
- public boolean removeAllSensors() {
+ public void removeAllSensors() {
for (int i=0 ; i<mActiveSensors.size(); i++) {
if (mActiveSensors.valueAt(i) == true) {
int handle = mActiveSensors.keyAt(i);
@@ -252,24 +244,21 @@
}
}
}
- return true;
}
- public boolean removeSensor(Sensor sensor) {
+ public void removeSensor(Sensor sensor) {
final int handle = sensor.getHandle();
if (mActiveSensors.get(handle)) {
disableSensor(sensor);
mActiveSensors.put(sensor.getHandle(), false);
- return true;
}
- return false;
}
public boolean hasSensors() {
// no more sensors are set
return mActiveSensors.indexOfValue(true) >= 0;
}
-
+
@Override
protected void finalize() throws Throwable {
try {
@@ -302,30 +291,17 @@
if (sensor == null) throw new NullPointerException();
return nativeDisableSensor(nSensorEventQueue, sensor.getHandle());
}
- protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy,
- long timestamp);
- }
-
- static final class SensorEventQueue extends BaseEventQueue {
- private final SensorEventListener mListener;
-
- public SensorEventQueue(SensorEventListener listener, Looper looper) {
- super(looper);
- mListener = listener;
- }
// Called from native code.
@SuppressWarnings("unused")
- @Override
- protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
- long timestamp) {
- final Sensor sensor = sHandleToSensor.get(handle);
- SensorEvent t = sSensorEventPool.acquire();
- if (t == null) t = new SensorEvent(MAX_EVENTS);
+ private void dispatchSensorEvent(int handle, float[] values, int inAccuracy, long timestamp) {
+ // this is always called on the same thread.
+ final SensorEvent t = sPool.getFromPool();
try {
- // Copy the entire values array.
- // Any changes in length will be handled at the native layer.
- System.arraycopy(values, 0, t.values, 0, t.values.length);
+ final Sensor sensor = sHandleToSensor.get(handle);
+ final SensorEventListener listener = mListener;
+ // FIXME: handle more than 3 values
+ System.arraycopy(values, 0, t.values, 0, 3);
t.timestamp = timestamp;
t.accuracy = inAccuracy;
t.sensor = sensor;
@@ -337,57 +313,72 @@
final int accuracy = mSensorAccuracies.get(handle);
if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
mSensorAccuracies.put(handle, t.accuracy);
- mListener.onAccuracyChanged(t.sensor, t.accuracy);
+ listener.onAccuracyChanged(t.sensor, t.accuracy);
}
break;
default:
// For other sensors, just report the accuracy once
if (mFirstEvent.get(handle) == false) {
mFirstEvent.put(handle, true);
- mListener.onAccuracyChanged(
+ listener.onAccuracyChanged(
t.sensor, SENSOR_STATUS_ACCURACY_HIGH);
}
break;
}
- mListener.onSensorChanged(t);
+ listener.onSensorChanged(t);
} finally {
- sSensorEventPool.release(t);
+ sPool.returnToPool(t);
}
}
}
- static final class TriggerEventQueue extends BaseEventQueue {
- private final TriggerEventListener mListener;
- private SensorManager mManager;
+ /*
+ * A dumb pool of SensorEvent
+ */
+ private static final class SensorEventPool {
+ private final int mPoolSize;
+ private final SensorEvent mPool[];
+ private int mNumItemsInPool;
- public TriggerEventQueue(TriggerEventListener listener, Looper looper,
- SensorManager manager) {
- super(looper);
- mListener = listener;
- mManager = manager;
+ private SensorEvent createSensorEvent() {
+ // maximal size for all legacy events is 3
+ return new SensorEvent(3);
}
- // Called from native code.
- @SuppressWarnings("unused")
- @Override
- protected void dispatchSensorEvent(int handle, float[] values, int accuracy, long timestamp) {
- final Sensor sensor = sHandleToSensor.get(handle);
- TriggerEvent t = sTriggerEventPool.acquire();
- if (t == null) t = new TriggerEvent(MAX_EVENTS);
+ SensorEventPool(int poolSize) {
+ mPoolSize = poolSize;
+ mNumItemsInPool = poolSize;
+ mPool = new SensorEvent[poolSize];
+ }
- try {
- // Copy the entire values array.
- // Any changes in length will be handled at the native layer.
- System.arraycopy(values, 0, t.values, 0, t.values.length);
- t.timestamp = timestamp;
- t.sensor = sensor;
+ SensorEvent getFromPool() {
+ SensorEvent t = null;
+ synchronized (this) {
+ if (mNumItemsInPool > 0) {
+ // remove the "top" item from the pool
+ final int index = mPoolSize - mNumItemsInPool;
+ t = mPool[index];
+ mPool[index] = null;
+ mNumItemsInPool--;
+ }
+ }
+ if (t == null) {
+ // the pool was empty or this item was removed from the pool for
+ // the first time. In any case, we need to create a new item.
+ t = createSensorEvent();
+ }
+ return t;
+ }
- // A trigger sensor should be auto disabled.
- mManager.cancelTriggerSensorImpl(mListener, sensor);
-
- mListener.onTrigger(t);
- } finally {
- sTriggerEventPool.release(t);
+ void returnToPool(SensorEvent t) {
+ synchronized (this) {
+ // is there space left in the pool?
+ if (mNumItemsInPool < mPoolSize) {
+ // if so, return the item to the pool
+ mNumItemsInPool++;
+ final int index = mPoolSize - mNumItemsInPool;
+ mPool[index] = t;
+ }
}
}
}