Move legacy sensor support to a new class.
Bug: 6339552
Change-Id: I2067b754348ac76b1e1f71608031be2c80fc31d2
diff --git a/core/java/android/hardware/LegacySensorManager.java b/core/java/android/hardware/LegacySensorManager.java
new file mode 100644
index 0000000..62c194f
--- /dev/null
+++ b/core/java/android/hardware/LegacySensorManager.java
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware;
+
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.view.IRotationWatcher;
+import android.view.IWindowManager;
+import android.view.Surface;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Helper class for implementing the legacy sensor manager API.
+ * @hide
+ */
+@SuppressWarnings("deprecation")
+final class LegacySensorManager {
+ private static boolean sInitialized;
+ private static IWindowManager sWindowManager;
+ private static int sRotation = Surface.ROTATION_0;
+
+ private final SensorManager mSensorManager;
+
+ // List of legacy listeners. Guarded by mLegacyListenersMap.
+ private final HashMap<SensorListener, LegacyListener> mLegacyListenersMap =
+ new HashMap<SensorListener, LegacyListener>();
+
+ public LegacySensorManager(SensorManager sensorManager) {
+ mSensorManager = sensorManager;
+
+ synchronized (SensorManager.class) {
+ if (!sInitialized) {
+ sWindowManager = IWindowManager.Stub.asInterface(
+ ServiceManager.getService("window"));
+ if (sWindowManager != null) {
+ // if it's null we're running in the system process
+ // which won't get the rotated values
+ try {
+ sRotation = sWindowManager.watchRotation(
+ new IRotationWatcher.Stub() {
+ public void onRotationChanged(int rotation) {
+ LegacySensorManager.onRotationChanged(rotation);
+ }
+ }
+ );
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ }
+ }
+
+ public int getSensors() {
+ int result = 0;
+ final List<Sensor> fullList = mSensorManager.getFullSensorList();
+ for (Sensor i : fullList) {
+ switch (i.getType()) {
+ case Sensor.TYPE_ACCELEROMETER:
+ result |= SensorManager.SENSOR_ACCELEROMETER;
+ break;
+ case Sensor.TYPE_MAGNETIC_FIELD:
+ result |= SensorManager.SENSOR_MAGNETIC_FIELD;
+ break;
+ case Sensor.TYPE_ORIENTATION:
+ result |= SensorManager.SENSOR_ORIENTATION
+ | SensorManager.SENSOR_ORIENTATION_RAW;
+ break;
+ }
+ }
+ return result;
+ }
+
+ public boolean registerListener(SensorListener listener, int sensors, int rate) {
+ if (listener == null) {
+ return false;
+ }
+ boolean result = false;
+ result = registerLegacyListener(SensorManager.SENSOR_ACCELEROMETER,
+ Sensor.TYPE_ACCELEROMETER, listener, sensors, rate) || result;
+ result = registerLegacyListener(SensorManager.SENSOR_MAGNETIC_FIELD,
+ Sensor.TYPE_MAGNETIC_FIELD, listener, sensors, rate) || result;
+ result = registerLegacyListener(SensorManager.SENSOR_ORIENTATION_RAW,
+ Sensor.TYPE_ORIENTATION, listener, sensors, rate) || result;
+ result = registerLegacyListener(SensorManager.SENSOR_ORIENTATION,
+ Sensor.TYPE_ORIENTATION, listener, sensors, rate) || result;
+ result = registerLegacyListener(SensorManager.SENSOR_TEMPERATURE,
+ Sensor.TYPE_TEMPERATURE, listener, sensors, rate) || result;
+ return result;
+ }
+
+ private boolean registerLegacyListener(int legacyType, int type,
+ SensorListener listener, int sensors, int rate) {
+ boolean result = false;
+ // Are we activating this legacy sensor?
+ if ((sensors & legacyType) != 0) {
+ // if so, find a suitable Sensor
+ Sensor sensor = mSensorManager.getDefaultSensor(type);
+ if (sensor != null) {
+ // We do all of this work holding the legacy listener lock to ensure
+ // that the invariants around listeners are maintained. This is safe
+ // because neither registerLegacyListener nor unregisterLegacyListener
+ // are called reentrantly while sensors are being registered or unregistered.
+ synchronized (mLegacyListenersMap) {
+ // If we don't already have one, create a LegacyListener
+ // to wrap this listener and process the events as
+ // they are expected by legacy apps.
+ LegacyListener legacyListener = mLegacyListenersMap.get(listener);
+ if (legacyListener == null) {
+ // we didn't find a LegacyListener for this client,
+ // create one, and put it in our list.
+ legacyListener = new LegacyListener(listener);
+ mLegacyListenersMap.put(listener, legacyListener);
+ }
+
+ // register this legacy sensor with this legacy listener
+ if (legacyListener.registerSensor(legacyType)) {
+ // and finally, register the legacy listener with the new apis
+ result = mSensorManager.registerListener(legacyListener, sensor, rate);
+ } else {
+ result = true; // sensor already enabled
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ public void unregisterListener(SensorListener listener, int sensors) {
+ if (listener == null) {
+ return;
+ }
+ unregisterLegacyListener(SensorManager.SENSOR_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER,
+ listener, sensors);
+ unregisterLegacyListener(SensorManager.SENSOR_MAGNETIC_FIELD, Sensor.TYPE_MAGNETIC_FIELD,
+ listener, sensors);
+ unregisterLegacyListener(SensorManager.SENSOR_ORIENTATION_RAW, Sensor.TYPE_ORIENTATION,
+ listener, sensors);
+ unregisterLegacyListener(SensorManager.SENSOR_ORIENTATION, Sensor.TYPE_ORIENTATION,
+ listener, sensors);
+ unregisterLegacyListener(SensorManager.SENSOR_TEMPERATURE, Sensor.TYPE_TEMPERATURE,
+ listener, sensors);
+ }
+
+ private void unregisterLegacyListener(int legacyType, int type,
+ SensorListener listener, int sensors) {
+ // Are we deactivating this legacy sensor?
+ if ((sensors & legacyType) != 0) {
+ // if so, find the corresponding Sensor
+ Sensor sensor = mSensorManager.getDefaultSensor(type);
+ if (sensor != null) {
+ // We do all of this work holding the legacy listener lock to ensure
+ // that the invariants around listeners are maintained. This is safe
+ // because neither registerLegacyListener nor unregisterLegacyListener
+ // are called re-entrantly while sensors are being registered or unregistered.
+ synchronized (mLegacyListenersMap) {
+ // do we know about this listener?
+ LegacyListener legacyListener = mLegacyListenersMap.get(listener);
+ if (legacyListener != null) {
+ // unregister this legacy sensor and if we don't
+ // need the corresponding Sensor, unregister it too
+ if (legacyListener.unregisterSensor(legacyType)) {
+ // corresponding sensor not needed, unregister
+ mSensorManager.unregisterListener(legacyListener, sensor);
+
+ // finally check if we still need the legacyListener
+ // in our mapping, if not, get rid of it too.
+ if (!legacyListener.hasSensors()) {
+ mLegacyListenersMap.remove(listener);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ static void onRotationChanged(int rotation) {
+ synchronized (SensorManager.class) {
+ sRotation = rotation;
+ }
+ }
+
+ static int getRotation() {
+ synchronized (SensorManager.class) {
+ return sRotation;
+ }
+ }
+
+ private static final class LegacyListener implements SensorEventListener {
+ private float mValues[] = new float[6];
+ private SensorListener mTarget;
+ private int mSensors;
+ private final LmsFilter mYawfilter = new LmsFilter();
+
+ LegacyListener(SensorListener target) {
+ mTarget = target;
+ mSensors = 0;
+ }
+
+ boolean registerSensor(int legacyType) {
+ if ((mSensors & legacyType) != 0) {
+ return false;
+ }
+ boolean alreadyHasOrientationSensor = hasOrientationSensor(mSensors);
+ mSensors |= legacyType;
+ if (alreadyHasOrientationSensor && hasOrientationSensor(legacyType)) {
+ return false; // don't need to re-register the orientation sensor
+ }
+ return true;
+ }
+
+ boolean unregisterSensor(int legacyType) {
+ if ((mSensors & legacyType) == 0) {
+ return false;
+ }
+ mSensors &= ~legacyType;
+ if (hasOrientationSensor(legacyType) && hasOrientationSensor(mSensors)) {
+ return false; // can't unregister the orientation sensor just yet
+ }
+ return true;
+ }
+
+ boolean hasSensors() {
+ return mSensors != 0;
+ }
+
+ private static boolean hasOrientationSensor(int sensors) {
+ return (sensors & (SensorManager.SENSOR_ORIENTATION
+ | SensorManager.SENSOR_ORIENTATION_RAW)) != 0;
+ }
+
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ try {
+ mTarget.onAccuracyChanged(getLegacySensorType(sensor.getType()), accuracy);
+ } catch (AbstractMethodError e) {
+ // old app that doesn't implement this method
+ // just ignore it.
+ }
+ }
+
+ public void onSensorChanged(SensorEvent event) {
+ final float v[] = mValues;
+ v[0] = event.values[0];
+ v[1] = event.values[1];
+ v[2] = event.values[2];
+ int type = event.sensor.getType();
+ int legacyType = getLegacySensorType(type);
+ mapSensorDataToWindow(legacyType, v, LegacySensorManager.getRotation());
+ if (type == Sensor.TYPE_ORIENTATION) {
+ if ((mSensors & SensorManager.SENSOR_ORIENTATION_RAW)!=0) {
+ mTarget.onSensorChanged(SensorManager.SENSOR_ORIENTATION_RAW, v);
+ }
+ if ((mSensors & SensorManager.SENSOR_ORIENTATION)!=0) {
+ v[0] = mYawfilter.filter(event.timestamp, v[0]);
+ mTarget.onSensorChanged(SensorManager.SENSOR_ORIENTATION, v);
+ }
+ } else {
+ mTarget.onSensorChanged(legacyType, v);
+ }
+ }
+
+ /*
+ * Helper function to convert the specified sensor's data to the windows's
+ * coordinate space from the device's coordinate space.
+ *
+ * output: 3,4,5: values in the old API format
+ * 0,1,2: transformed values in the old API format
+ *
+ */
+ private void mapSensorDataToWindow(int sensor,
+ float[] values, int orientation) {
+ float x = values[0];
+ float y = values[1];
+ float z = values[2];
+
+ switch (sensor) {
+ case SensorManager.SENSOR_ORIENTATION:
+ case SensorManager.SENSOR_ORIENTATION_RAW:
+ z = -z;
+ break;
+ case SensorManager.SENSOR_ACCELEROMETER:
+ x = -x;
+ y = -y;
+ z = -z;
+ break;
+ case SensorManager.SENSOR_MAGNETIC_FIELD:
+ x = -x;
+ y = -y;
+ break;
+ }
+ values[0] = x;
+ values[1] = y;
+ values[2] = z;
+ values[3] = x;
+ values[4] = y;
+ values[5] = z;
+
+ if ((orientation & Surface.ROTATION_90) != 0) {
+ // handles 90 and 270 rotation
+ switch (sensor) {
+ case SensorManager.SENSOR_ACCELEROMETER:
+ case SensorManager.SENSOR_MAGNETIC_FIELD:
+ values[0] =-y;
+ values[1] = x;
+ values[2] = z;
+ break;
+ case SensorManager.SENSOR_ORIENTATION:
+ case SensorManager.SENSOR_ORIENTATION_RAW:
+ values[0] = x + ((x < 270) ? 90 : -270);
+ values[1] = z;
+ values[2] = y;
+ break;
+ }
+ }
+ if ((orientation & Surface.ROTATION_180) != 0) {
+ x = values[0];
+ y = values[1];
+ z = values[2];
+ // handles 180 (flip) and 270 (flip + 90) rotation
+ switch (sensor) {
+ case SensorManager.SENSOR_ACCELEROMETER:
+ case SensorManager.SENSOR_MAGNETIC_FIELD:
+ values[0] =-x;
+ values[1] =-y;
+ values[2] = z;
+ break;
+ case SensorManager.SENSOR_ORIENTATION:
+ case SensorManager.SENSOR_ORIENTATION_RAW:
+ values[0] = (x >= 180) ? (x - 180) : (x + 180);
+ values[1] =-y;
+ values[2] =-z;
+ break;
+ }
+ }
+ }
+
+ private static int getLegacySensorType(int type) {
+ switch (type) {
+ case Sensor.TYPE_ACCELEROMETER:
+ return SensorManager.SENSOR_ACCELEROMETER;
+ case Sensor.TYPE_MAGNETIC_FIELD:
+ return SensorManager.SENSOR_MAGNETIC_FIELD;
+ case Sensor.TYPE_ORIENTATION:
+ return SensorManager.SENSOR_ORIENTATION_RAW;
+ case Sensor.TYPE_TEMPERATURE:
+ return SensorManager.SENSOR_TEMPERATURE;
+ }
+ return 0;
+ }
+ }
+
+ private static final class LmsFilter {
+ private static final int SENSORS_RATE_MS = 20;
+ private static final int COUNT = 12;
+ private static final float PREDICTION_RATIO = 1.0f/3.0f;
+ private static final float PREDICTION_TIME = (SENSORS_RATE_MS*COUNT/1000.0f)*PREDICTION_RATIO;
+ private float mV[] = new float[COUNT*2];
+ private float mT[] = new float[COUNT*2];
+ private int mIndex;
+
+ public LmsFilter() {
+ mIndex = COUNT;
+ }
+
+ public float filter(long time, float in) {
+ float v = in;
+ final float ns = 1.0f / 1000000000.0f;
+ final float t = time*ns;
+ float v1 = mV[mIndex];
+ if ((v-v1) > 180) {
+ v -= 360;
+ } else if ((v1-v) > 180) {
+ v += 360;
+ }
+ /* Manage the circular buffer, we write the data twice spaced
+ * by COUNT values, so that we don't have to copy the array
+ * when it's full
+ */
+ mIndex++;
+ if (mIndex >= COUNT*2)
+ mIndex = COUNT;
+ mV[mIndex] = v;
+ mT[mIndex] = t;
+ mV[mIndex-COUNT] = v;
+ mT[mIndex-COUNT] = t;
+
+ float A, B, C, D, E;
+ float a, b;
+ int i;
+
+ A = B = C = D = E = 0;
+ for (i=0 ; i<COUNT-1 ; i++) {
+ final int j = mIndex - 1 - i;
+ final float Z = mV[j];
+ final float T = 0.5f*(mT[j] + mT[j+1]) - t;
+ float dT = mT[j] - mT[j+1];
+ dT *= dT;
+ A += Z*dT;
+ B += T*(T*dT);
+ C += (T*dT);
+ D += Z*(T*dT);
+ E += dT;
+ }
+ b = (A*B + C*D) / (E*B + C*C);
+ a = (E*b - A) / C;
+ float f = b + PREDICTION_TIME*a;
+
+ // Normalize
+ f *= (1.0f / 360.0f);
+ if (((f>=0)?f:-f) >= 0.5f)
+ f = f - (float)Math.ceil(f + 0.5f) + 1.0f;
+ if (f < 0)
+ f += 1.0f;
+ f *= 360.0f;
+ return f;
+ }
+ }
+}
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index d783db7..aeb46cf 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -16,17 +16,12 @@
package android.hardware;
-import android.os.RemoteException;
import android.os.Handler;
-import android.os.ServiceManager;
+import android.util.Log;
import android.util.SparseArray;
-import android.view.IRotationWatcher;
-import android.view.IWindowManager;
-import android.view.Surface;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
/**
@@ -78,20 +73,18 @@
*
*/
public abstract class SensorManager {
+ /** @hide */
+ protected static final String TAG = "SensorManager";
+
private static final float[] mTempMatrix = new float[16];
- private static boolean sInitialized;
- private static IWindowManager sWindowManager;
- private static int sRotation = Surface.ROTATION_0;
-
- // List of legacy listeners. Guarded by mLegacyListenersMap.
- private final HashMap<SensorListener, LegacyListener> mLegacyListenersMap =
- new HashMap<SensorListener, LegacyListener>();
-
// Cached lists of sensors by type. Guarded by mSensorListByType.
private final SparseArray<List<Sensor>> mSensorListByType =
new SparseArray<List<Sensor>>();
+ // Legacy sensor manager implementation. Guarded by mSensorListByType during initialization.
+ private LegacySensorManager mLegacySensorManager;
+
/* NOTE: sensor IDs must be a power of 2 */
/**
@@ -362,26 +355,6 @@
* {@hide}
*/
public SensorManager() {
- synchronized (SensorManager.class) {
- if (!sInitialized) {
- sWindowManager = IWindowManager.Stub.asInterface(
- ServiceManager.getService("window"));
- if (sWindowManager != null) {
- // if it's null we're running in the system process
- // which won't get the rotated values
- try {
- sRotation = sWindowManager.watchRotation(
- new IRotationWatcher.Stub() {
- public void onRotationChanged(int rotation) {
- SensorManager.this.onRotationChanged(rotation);
- }
- }
- );
- } catch (RemoteException e) {
- }
- }
- }
- }
}
/**
@@ -397,23 +370,7 @@
*/
@Deprecated
public int getSensors() {
- int result = 0;
- final List<Sensor> fullList = getFullSensorList();
- for (Sensor i : fullList) {
- switch (i.getType()) {
- case Sensor.TYPE_ACCELEROMETER:
- result |= SensorManager.SENSOR_ACCELEROMETER;
- break;
- case Sensor.TYPE_MAGNETIC_FIELD:
- result |= SensorManager.SENSOR_MAGNETIC_FIELD;
- break;
- case Sensor.TYPE_ORIENTATION:
- result |= SensorManager.SENSOR_ORIENTATION |
- SensorManager.SENSOR_ORIENTATION_RAW;
- break;
- }
- }
- return result;
+ return getLegacySensorManager().getSensors();
}
/**
@@ -519,89 +476,7 @@
*/
@Deprecated
public boolean registerListener(SensorListener listener, int sensors, int rate) {
- if (listener == null) {
- return false;
- }
- boolean result = false;
- result = registerLegacyListener(SENSOR_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER,
- listener, sensors, rate) || result;
- result = registerLegacyListener(SENSOR_MAGNETIC_FIELD, Sensor.TYPE_MAGNETIC_FIELD,
- listener, sensors, rate) || result;
- result = registerLegacyListener(SENSOR_ORIENTATION_RAW, Sensor.TYPE_ORIENTATION,
- listener, sensors, rate) || result;
- result = registerLegacyListener(SENSOR_ORIENTATION, Sensor.TYPE_ORIENTATION,
- listener, sensors, rate) || result;
- result = registerLegacyListener(SENSOR_TEMPERATURE, Sensor.TYPE_TEMPERATURE,
- listener, sensors, rate) || result;
- return result;
- }
-
- @SuppressWarnings("deprecation")
- private boolean registerLegacyListener(int legacyType, int type,
- SensorListener listener, int sensors, int rate) {
- boolean result = false;
- // Are we activating this legacy sensor?
- if ((sensors & legacyType) != 0) {
- // if so, find a suitable Sensor
- Sensor sensor = getDefaultSensor(type);
- if (sensor != null) {
- // We do all of this work holding the legacy listener lock to ensure
- // that the invariants around listeners are maintained. This is safe
- // because neither registerLegacyListener nor unregisterLegacyListener
- // are called reentrantly while sensors are being registered or unregistered.
- synchronized (mLegacyListenersMap) {
- // If we don't already have one, create a LegacyListener
- // to wrap this listener and process the events as
- // they are expected by legacy apps.
- LegacyListener legacyListener = mLegacyListenersMap.get(listener);
- if (legacyListener == null) {
- // we didn't find a LegacyListener for this client,
- // create one, and put it in our list.
- legacyListener = new LegacyListener(listener);
- mLegacyListenersMap.put(listener, legacyListener);
- }
-
- // register this legacy sensor with this legacy listener
- if (legacyListener.registerSensor(legacyType)) {
- // and finally, register the legacy listener with the new apis
- result = registerListener(legacyListener, sensor, rate);
- } else {
- result = true; // sensor already enabled
- }
- }
- }
- }
- return result;
- }
-
- /**
- * Unregisters a listener for the sensors with which it is registered.
- *
- * @deprecated This method is deprecated, use
- * {@link SensorManager#unregisterListener(SensorEventListener, Sensor)}
- * instead.
- *
- * @param listener
- * a SensorListener object
- *
- * @param sensors
- * a bit masks of the sensors to unregister from
- */
- @Deprecated
- public void unregisterListener(SensorListener listener, int sensors) {
- if (listener == null) {
- return;
- }
- unregisterLegacyListener(SENSOR_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER,
- listener, sensors);
- unregisterLegacyListener(SENSOR_MAGNETIC_FIELD, Sensor.TYPE_MAGNETIC_FIELD,
- listener, sensors);
- unregisterLegacyListener(SENSOR_ORIENTATION_RAW, Sensor.TYPE_ORIENTATION,
- listener, sensors);
- unregisterLegacyListener(SENSOR_ORIENTATION, Sensor.TYPE_ORIENTATION,
- listener, sensors);
- unregisterLegacyListener(SENSOR_TEMPERATURE, Sensor.TYPE_TEMPERATURE,
- listener, sensors);
+ return getLegacySensorManager().registerListener(listener, sensors, rate);
}
/**
@@ -619,38 +494,22 @@
unregisterListener(listener, SENSOR_ALL | SENSOR_ORIENTATION_RAW);
}
- @SuppressWarnings("deprecation")
- private void unregisterLegacyListener(int legacyType, int type,
- SensorListener listener, int sensors) {
- // Are we deactivating this legacy sensor?
- if ((sensors & legacyType) != 0) {
- // if so, find the corresponding Sensor
- Sensor sensor = getDefaultSensor(type);
- if (sensor != null) {
- // We do all of this work holding the legacy listener lock to ensure
- // that the invariants around listeners are maintained. This is safe
- // because neither registerLegacyListener nor unregisterLegacyListener
- // are called re-entrantly while sensors are being registered or unregistered.
- synchronized (mLegacyListenersMap) {
- // do we know about this listener?
- LegacyListener legacyListener = mLegacyListenersMap.get(listener);
- if (legacyListener != null) {
- // unregister this legacy sensor and if we don't
- // need the corresponding Sensor, unregister it too
- if (legacyListener.unregisterSensor(legacyType)) {
- // corresponding sensor not needed, unregister
- unregisterListener(legacyListener, sensor);
-
- // finally check if we still need the legacyListener
- // in our mapping, if not, get rid of it too.
- if (!legacyListener.hasSensors()) {
- mLegacyListenersMap.remove(listener);
- }
- }
- }
- }
- }
- }
+ /**
+ * Unregisters a listener for the sensors with which it is registered.
+ *
+ * @deprecated This method is deprecated, use
+ * {@link SensorManager#unregisterListener(SensorEventListener, Sensor)}
+ * instead.
+ *
+ * @param listener
+ * a SensorListener object
+ *
+ * @param sensors
+ * a bit masks of the sensors to unregister from
+ */
+ @Deprecated
+ public void unregisterListener(SensorListener listener, int sensors) {
+ getLegacySensorManager().unregisterListener(listener, sensors);
}
/**
@@ -1446,248 +1305,14 @@
Q[3] = rv[2];
}
- static void onRotationChanged(int rotation) {
- synchronized (SensorManager.class) {
- sRotation = rotation;
- }
- }
-
- static int getRotation() {
- synchronized (SensorManager.class) {
- return sRotation;
- }
- }
-
- private static final class LegacyListener implements SensorEventListener {
- private float mValues[] = new float[6];
- @SuppressWarnings("deprecation")
- private SensorListener mTarget;
- private int mSensors;
- private final LmsFilter mYawfilter = new LmsFilter();
-
- @SuppressWarnings("deprecation")
- LegacyListener(SensorListener target) {
- mTarget = target;
- mSensors = 0;
- }
-
- boolean registerSensor(int legacyType) {
- if ((mSensors & legacyType) != 0) {
- return false;
+ private LegacySensorManager getLegacySensorManager() {
+ synchronized (mSensorListByType) {
+ if (mLegacySensorManager == null) {
+ Log.i(TAG, "This application is using deprecated SensorManager API which will "
+ + "be removed someday. Please consider switching to the new API.");
+ mLegacySensorManager = new LegacySensorManager(this);
}
- boolean alreadyHasOrientationSensor = hasOrientationSensor(mSensors);
- mSensors |= legacyType;
- if (alreadyHasOrientationSensor && hasOrientationSensor(legacyType)) {
- return false; // don't need to re-register the orientation sensor
- }
- return true;
- }
-
- boolean unregisterSensor(int legacyType) {
- if ((mSensors & legacyType) == 0) {
- return false;
- }
- mSensors &= ~legacyType;
- if (hasOrientationSensor(legacyType) && hasOrientationSensor(mSensors)) {
- return false; // can't unregister the orientation sensor just yet
- }
- return true;
- }
-
- boolean hasSensors() {
- return mSensors != 0;
- }
-
- private static boolean hasOrientationSensor(int sensors) {
- return (sensors & (SENSOR_ORIENTATION | SENSOR_ORIENTATION_RAW)) != 0;
- }
-
- @SuppressWarnings("deprecation")
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- try {
- mTarget.onAccuracyChanged(getLegacySensorType(sensor.getType()), accuracy);
- } catch (AbstractMethodError e) {
- // old app that doesn't implement this method
- // just ignore it.
- }
- }
-
- @SuppressWarnings("deprecation")
- public void onSensorChanged(SensorEvent event) {
- final float v[] = mValues;
- v[0] = event.values[0];
- v[1] = event.values[1];
- v[2] = event.values[2];
- int type = event.sensor.getType();
- int legacyType = getLegacySensorType(type);
- mapSensorDataToWindow(legacyType, v, SensorManager.getRotation());
- if (type == Sensor.TYPE_ORIENTATION) {
- if ((mSensors & SENSOR_ORIENTATION_RAW)!=0) {
- mTarget.onSensorChanged(SENSOR_ORIENTATION_RAW, v);
- }
- if ((mSensors & SENSOR_ORIENTATION)!=0) {
- v[0] = mYawfilter.filter(event.timestamp, v[0]);
- mTarget.onSensorChanged(SENSOR_ORIENTATION, v);
- }
- } else {
- mTarget.onSensorChanged(legacyType, v);
- }
- }
-
- /*
- * Helper function to convert the specified sensor's data to the windows's
- * coordinate space from the device's coordinate space.
- *
- * output: 3,4,5: values in the old API format
- * 0,1,2: transformed values in the old API format
- *
- */
- private void mapSensorDataToWindow(int sensor,
- float[] values, int orientation) {
- float x = values[0];
- float y = values[1];
- float z = values[2];
-
- switch (sensor) {
- case SensorManager.SENSOR_ORIENTATION:
- case SensorManager.SENSOR_ORIENTATION_RAW:
- z = -z;
- break;
- case SensorManager.SENSOR_ACCELEROMETER:
- x = -x;
- y = -y;
- z = -z;
- break;
- case SensorManager.SENSOR_MAGNETIC_FIELD:
- x = -x;
- y = -y;
- break;
- }
- values[0] = x;
- values[1] = y;
- values[2] = z;
- values[3] = x;
- values[4] = y;
- values[5] = z;
-
- if ((orientation & Surface.ROTATION_90) != 0) {
- // handles 90 and 270 rotation
- switch (sensor) {
- case SENSOR_ACCELEROMETER:
- case SENSOR_MAGNETIC_FIELD:
- values[0] =-y;
- values[1] = x;
- values[2] = z;
- break;
- case SENSOR_ORIENTATION:
- case SENSOR_ORIENTATION_RAW:
- values[0] = x + ((x < 270) ? 90 : -270);
- values[1] = z;
- values[2] = y;
- break;
- }
- }
- if ((orientation & Surface.ROTATION_180) != 0) {
- x = values[0];
- y = values[1];
- z = values[2];
- // handles 180 (flip) and 270 (flip + 90) rotation
- switch (sensor) {
- case SENSOR_ACCELEROMETER:
- case SENSOR_MAGNETIC_FIELD:
- values[0] =-x;
- values[1] =-y;
- values[2] = z;
- break;
- case SENSOR_ORIENTATION:
- case SENSOR_ORIENTATION_RAW:
- values[0] = (x >= 180) ? (x - 180) : (x + 180);
- values[1] =-y;
- values[2] =-z;
- break;
- }
- }
- }
-
- private static int getLegacySensorType(int type) {
- switch (type) {
- case Sensor.TYPE_ACCELEROMETER:
- return SENSOR_ACCELEROMETER;
- case Sensor.TYPE_MAGNETIC_FIELD:
- return SENSOR_MAGNETIC_FIELD;
- case Sensor.TYPE_ORIENTATION:
- return SENSOR_ORIENTATION_RAW;
- case Sensor.TYPE_TEMPERATURE:
- return SENSOR_TEMPERATURE;
- }
- return 0;
- }
- }
-
- private static final class LmsFilter {
- private static final int SENSORS_RATE_MS = 20;
- private static final int COUNT = 12;
- private static final float PREDICTION_RATIO = 1.0f/3.0f;
- private static final float PREDICTION_TIME = (SENSORS_RATE_MS*COUNT/1000.0f)*PREDICTION_RATIO;
- private float mV[] = new float[COUNT*2];
- private float mT[] = new float[COUNT*2];
- private int mIndex;
-
- public LmsFilter() {
- mIndex = COUNT;
- }
-
- public float filter(long time, float in) {
- float v = in;
- final float ns = 1.0f / 1000000000.0f;
- final float t = time*ns;
- float v1 = mV[mIndex];
- if ((v-v1) > 180) {
- v -= 360;
- } else if ((v1-v) > 180) {
- v += 360;
- }
- /* Manage the circular buffer, we write the data twice spaced
- * by COUNT values, so that we don't have to copy the array
- * when it's full
- */
- mIndex++;
- if (mIndex >= COUNT*2)
- mIndex = COUNT;
- mV[mIndex] = v;
- mT[mIndex] = t;
- mV[mIndex-COUNT] = v;
- mT[mIndex-COUNT] = t;
-
- float A, B, C, D, E;
- float a, b;
- int i;
-
- A = B = C = D = E = 0;
- for (i=0 ; i<COUNT-1 ; i++) {
- final int j = mIndex - 1 - i;
- final float Z = mV[j];
- final float T = 0.5f*(mT[j] + mT[j+1]) - t;
- float dT = mT[j] - mT[j+1];
- dT *= dT;
- A += Z*dT;
- B += T*(T*dT);
- C += (T*dT);
- D += Z*(T*dT);
- E += dT;
- }
- b = (A*B + C*D) / (E*B + C*C);
- a = (E*b - A) / C;
- float f = b + PREDICTION_TIME*a;
-
- // Normalize
- f *= (1.0f / 360.0f);
- if (((f>=0)?f:-f) >= 0.5f)
- f = f - (float)Math.ceil(f + 0.5f) + 1.0f;
- if (f < 0)
- f += 1.0f;
- f *= 360.0f;
- return f;
+ return mLegacySensorManager;
}
}
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 7763405..0204e94 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -35,14 +35,6 @@
* @hide
*/
public class SystemSensorManager extends SensorManager {
- private static final String TAG = "SensorManager";
-
- /*-----------------------------------------------------------------------*/
-
- final Looper mMainLooper;
-
- /*-----------------------------------------------------------------------*/
-
private static final int SENSOR_DISABLE = -1;
private static boolean sSensorModuleInitialized = false;
private static ArrayList<Sensor> sFullSensorsList = new ArrayList<Sensor>();
@@ -56,9 +48,11 @@
static final ArrayList<ListenerDelegate> sListeners =
new ArrayList<ListenerDelegate>();
- /*-----------------------------------------------------------------------*/
+ // Common pool of sensor events.
+ static SensorEventPool sPool;
- private static SensorEventPool sPool;
+ // Looper associated with the context in which this instance was created.
+ final Looper mMainLooper;
/*-----------------------------------------------------------------------*/
@@ -317,6 +311,7 @@
}
/** @hide */
+ @Override
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
int delay, Handler handler) {
boolean result = true;