SensorManager.java revision 25157e458d6e10b027d1ba6b78b0487156c9f57a
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.hardware; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IRotationWatcher; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IWindowManager; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Surface; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 3343c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * <p> 3474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * SensorManager lets you access the device's {@link android.hardware.Sensor 3574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensors}. Get an instance of this class by calling 3674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.content.Context#getSystemService(java.lang.String) 3774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Context.getSystemService()} with the argument 3874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.content.Context#SENSOR_SERVICE}. 3943c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * </p> 4043c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * <p> 4143c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * Always make sure to disable sensors you don't need, especially when your 4243c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * activity is paused. Failing to do so can drain the battery in just a few 4343c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * hours. Note that the system will <i>not</i> disable sensors automatically when 4443c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * the screen turns off. 4543c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * </p> 460f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 470f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * <pre class="prettyprint"> 480f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * public class SensorActivity extends Activity, implements SensorEventListener { 490f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * private final SensorManager mSensorManager; 500f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * private final Sensor mAccelerometer; 510f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 520f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * public SensorActivity() { 530f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); 540f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 5543c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * } 5643c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * 5743c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * protected void onResume() { 5843c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * super.onResume(); 590f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); 600f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * } 610f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 6243c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * protected void onPause() { 6343c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * super.onPause(); 6443c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * mSensorManager.unregisterListener(this); 6543c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * } 6643c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * 670f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * public void onAccuracyChanged(Sensor sensor, int accuracy) { 680f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * } 690f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 7043c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * public void onSensorChanged(SensorEvent event) { 710f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * } 720f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * } 730f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * </pre> 740f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 750f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see SensorEventListener 760f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see SensorEvent 770f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see Sensor 780f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownpublic abstract class SensorManager { 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float[] mTempMatrix = new float[16]; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static boolean sInitialized; 8425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static IWindowManager sWindowManager; 8525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static int sRotation = Surface.ROTATION_0; 8625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 8725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // List of legacy listeners. Guarded by mLegacyListenersMap. 8825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private final HashMap<SensorListener, LegacyListener> mLegacyListenersMap = 8925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown new HashMap<SensorListener, LegacyListener>(); 9025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 9125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // Cached lists of sensors by type. Guarded by mSensorListByType. 9225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private final SparseArray<List<Sensor>> mSensorListByType = 9325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown new SparseArray<List<Sensor>>(); 9425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* NOTE: sensor IDs must be a power of 2 */ 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an orientation sensor. See 9974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1000f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ORIENTATION = 1 << 0; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an accelerometer. See 10874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1090f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ACCELEROMETER = 1 << 1; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a temperature sensor See 11774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1180f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_TEMPERATURE = 1 << 2; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a magnetic sensor See 12674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1270f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_MAGNETIC_FIELD = 1 << 3; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an ambient light sensor See 13574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1360f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_LIGHT = 1 << 4; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a proximity sensor See 14474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1450f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_PROXIMITY = 1 << 5; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a Tricorder See 15374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1540f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_TRICORDER = 1 << 6; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an orientation sensor. See 16274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1630f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ORIENTATION_RAW = 1 << 7; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 17074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant that includes all sensors 1710f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1724a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1734a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ALL = 0x7F; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 17874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Smallest sensor ID 1790f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1804a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1814a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_MIN = SENSOR_ORIENTATION; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 18674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Largest sensor ID 1870f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1884a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1894a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_MAX = ((SENSOR_ALL + 1)>>1); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 19574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the X value in the array returned by 1964a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 1970f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1984a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1994a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATA_X = 0; 20274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 20374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 20474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the Y value in the array returned by 2054a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 2060f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 2074a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 2084a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATA_Y = 1; 21174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 21274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 21374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the Z value in the array returned by 2144a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 2150f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 2164a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 2174a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATA_Z = 2; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 22274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Offset to the untransformed values in the array returned by 2234a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 2240f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 2254a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 2264a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_INDEX = 3; 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 23174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the untransformed X value in the array returned by 2324a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 2330f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 2344a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 2354a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_X = 3; 23874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 23974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 24074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the untransformed Y value in the array returned by 2414a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 2420f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 2434a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 2444a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_Y = 4; 24774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 24874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 24974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the untransformed Z value in the array returned by 2504a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 2510f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 2524a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 2534a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_Z = 5; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Standard gravity (g) on Earth. This value is equivalent to 1G */ 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float STANDARD_GRAVITY = 9.80665f; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 26074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Sun's gravity in SI units (m/s^2) */ 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_SUN = 275.0f; 26274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Mercury's gravity in SI units (m/s^2) */ 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MERCURY = 3.70f; 26474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Venus' gravity in SI units (m/s^2) */ 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_VENUS = 8.87f; 26674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Earth's gravity in SI units (m/s^2) */ 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_EARTH = 9.80665f; 26874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** The Moon's gravity in SI units (m/s^2) */ 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MOON = 1.6f; 27074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Mars' gravity in SI units (m/s^2) */ 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MARS = 3.71f; 27274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Jupiter's gravity in SI units (m/s^2) */ 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_JUPITER = 23.12f; 27474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Saturn's gravity in SI units (m/s^2) */ 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_SATURN = 8.96f; 27674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Uranus' gravity in SI units (m/s^2) */ 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_URANUS = 8.69f; 27874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Neptune's gravity in SI units (m/s^2) */ 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_NEPTUNE = 11.0f; 28074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Pluto's gravity in SI units (m/s^2) */ 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_PLUTO = 0.6f; 28274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Gravity (estimate) on the first Death Star in Empire units (m/s^2) */ 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_DEATH_STAR_I = 0.000000353036145f; 28474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Gravity on the island */ 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_THE_ISLAND = 4.815162342f; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Maximum magnetic field on Earth's surface */ 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float MAGNETIC_FIELD_EARTH_MAX = 60.0f; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Minimum magnetic field on Earth's surface */ 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float MAGNETIC_FIELD_EARTH_MIN = 30.0f; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2930f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian 29404d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian /** Standard atmosphere, or average sea-level pressure in hPa (millibar) */ 29504d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian public static final float PRESSURE_STANDARD_ATMOSPHERE = 1013.25f; 29604d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian 29704d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian 29874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Maximum luminance of sunlight in lux */ 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNLIGHT_MAX = 120000.0f; 30074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance of sunlight in lux */ 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNLIGHT = 110000.0f; 30274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance in shade in lux */ 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SHADE = 20000.0f; 30474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance under an overcast sky in lux */ 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_OVERCAST = 10000.0f; 30674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance at sunrise in lux */ 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNRISE = 400.0f; 30874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance under a cloudy sky in lux */ 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_CLOUDY = 100.0f; 31074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance at night with full moon in lux */ 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_FULLMOON = 0.25f; 31274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance at night with no moon in lux*/ 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_NO_MOON = 0.001f; 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3150f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** get sensor data as fast as possible */ 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_FASTEST = 0; 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate suitable for games */ 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_GAME = 1; 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate suitable for the user interface */ 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_UI = 2; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate (default) suitable for screen orientation changes */ 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_NORMAL = 3; 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 32774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The values returned by this sensor cannot be trusted, calibration is 32874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * needed or the environment doesn't allow readings 32974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian */ 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_UNRELIABLE = 0; 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 33374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * This sensor is reporting data with low accuracy, calibration with the 33474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * environment is needed 33574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian */ 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_LOW = 1; 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 33974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * This sensor is reporting data with an average level of accuracy, 34074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * calibration with the environment may improve the readings 34174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian */ 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_MEDIUM = 2; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** This sensor is reporting data with maximum accuracy */ 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_HIGH = 3; 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_X = 1; 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_Y = 2; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_Z = 3; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_X = AXIS_X | 0x80; 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_Y = AXIS_Y | 0x80; 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_Z = AXIS_Z | 0x80; 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 36425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown public SensorManager() { 36525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown synchronized (SensorManager.class) { 36625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (!sInitialized) { 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowManager = IWindowManager.Stub.asInterface( 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ServiceManager.getService("window")); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sWindowManager != null) { 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if it's null we're running in the system process 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // which won't get the rotated values 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 373287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian sRotation = sWindowManager.watchRotation( 37404d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian new IRotationWatcher.Stub() { 37504d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian public void onRotationChanged(int rotation) { 37604d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian SensorManager.this.onRotationChanged(rotation); 37704d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian } 378287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian } 379287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian ); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /** 38825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * Gets the full list of sensors that are available. 38925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * @hide 39025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown */ 39125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown protected abstract List<Sensor> getFullSensorList(); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 39474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return available sensors. 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 39674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#getSensorList(int)} instead 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getSensors() { 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = 0; 40125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final List<Sensor> fullList = getFullSensorList(); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Sensor i : fullList) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (i.getType()) { 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ACCELEROMETER: 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_ACCELEROMETER; 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_MAGNETIC_FIELD: 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_MAGNETIC_FIELD; 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ORIENTATION: 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_ORIENTATION | 41204d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian SensorManager.SENSOR_ORIENTATION_RAW; 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 42074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Use this method to get the list of available sensors of a certain type. 42174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Make multiple calls to get sensors of different types or use 42274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor#TYPE_ALL Sensor.TYPE_ALL} to get all the 42374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensors. 4240f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 42574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param type 42674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * of sensors requested 4270f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a list of sensors matching the asked type. 4290f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 4300f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getDefaultSensor(int) 4310f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see Sensor 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<Sensor> getSensorList(int type) { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cache the returned lists the first time 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Sensor> list; 43625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final List<Sensor> fullList = getFullSensorList(); 43725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown synchronized (mSensorListByType) { 43825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown list = mSensorListByType.get(type); 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (list == null) { 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == Sensor.TYPE_ALL) { 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = fullList; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = new ArrayList<Sensor>(); 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Sensor i : fullList) { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i.getType() == type) 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list.add(i); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = Collections.unmodifiableList(list); 45025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mSensorListByType.append(type, list); 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return list; 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 45774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Use this method to get the default sensor for a given type. Note that the 45874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * returned sensor could be a composite sensor, and its data could be 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * averaged or filtered. If you need to access the raw sensors use 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SensorManager#getSensorList(int) getSensorList}. 4610f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 46274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param type 46374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * of sensors requested 4640f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the default sensors matching the asked type. 4660f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 4670f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getSensorList(int) 4680f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see Sensor 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Sensor getDefaultSensor(int type) { 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: need to be smarter, for now, just return the 1st sensor 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Sensor> l = getSensorList(type); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return l.isEmpty() ? null : l.get(0); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Registers a listener for given sensors. 4780f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 48074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#registerListener(SensorEventListener, Sensor, int)} 48174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 4820f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 48374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 48474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensor listener object 4850f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 48674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensors 48774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a bit masks of the sensors to register to 4880f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 48974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> if the sensor is supported and successfully 49074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * enabled 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorListener listener, int sensors) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return registerListener(listener, sensors, SENSOR_DELAY_NORMAL); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Registers a SensorListener for given sensors. 4990f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 50174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#registerListener(SensorEventListener, Sensor, int)} 50274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 5030f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 50474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 50574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensor listener object 5060f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 50774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensors 50874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a bit masks of the sensors to register to 5090f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 51074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param rate 51174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rate of events. This is only a hint to the system. events may be 51274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * received faster or slower than the specified rate. Usually events 51374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * are received faster. The value must be one of 51474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI}, 51574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}. 5160f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 51774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> if the sensor is supported and successfully 51874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * enabled 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorListener listener, int sensors, int rate) { 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result = false; 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER, 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_MAGNETIC_FIELD, Sensor.TYPE_MAGNETIC_FIELD, 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_ORIENTATION_RAW, Sensor.TYPE_ORIENTATION, 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_ORIENTATION, Sensor.TYPE_ORIENTATION, 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_TEMPERATURE, Sensor.TYPE_TEMPERATURE, 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean registerLegacyListener(int legacyType, int type, 54125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown SensorListener listener, int sensors, int rate) { 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result = false; 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Are we activating this legacy sensor? 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((sensors & legacyType) != 0) { 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if so, find a suitable Sensor 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Sensor sensor = getDefaultSensor(type); 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sensor != null) { 54825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // We do all of this work holding the legacy listener lock to ensure 54925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // that the invariants around listeners are maintained. This is safe 55025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // because neither registerLegacyListener nor unregisterLegacyListener 55125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // are called reentrantly while sensors are being registered or unregistered. 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLegacyListenersMap) { 55325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // If we don't already have one, create a LegacyListener 55425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // to wrap this listener and process the events as 55525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // they are expected by legacy apps. 55625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown LegacyListener legacyListener = mLegacyListenersMap.get(listener); 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (legacyListener == null) { 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we didn't find a LegacyListener for this client, 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // create one, and put it in our list. 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener = new LegacyListener(listener); 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLegacyListenersMap.put(listener, legacyListener); 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 56325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 56425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // register this legacy sensor with this legacy listener 56525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (legacyListener.registerSensor(legacyType)) { 56625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // and finally, register the legacy listener with the new apis 56725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown result = registerListener(legacyListener, sensor, rate); 56825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } else { 56925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown result = true; // sensor already enabled 57025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for the sensors with which it is registered. 5790f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 58174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#unregisterListener(SensorEventListener, Sensor)} 58274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 5830f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 58474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 58574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorListener object 5860f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 58774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensors 58874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a bit masks of the sensors to unregister from 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorListener listener, int sensors) { 59225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (listener == null) { 59325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return; 59425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER, 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_MAGNETIC_FIELD, Sensor.TYPE_MAGNETIC_FIELD, 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ORIENTATION_RAW, Sensor.TYPE_ORIENTATION, 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ORIENTATION, Sensor.TYPE_ORIENTATION, 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_TEMPERATURE, Sensor.TYPE_TEMPERATURE, 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for all sensors. 6090f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 61174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#unregisterListener(SensorEventListener)} 61274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 6130f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 61474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 61574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorListener object 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorListener listener) { 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener(listener, SENSOR_ALL | SENSOR_ORIENTATION_RAW); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 62225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown @SuppressWarnings("deprecation") 62325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private void unregisterLegacyListener(int legacyType, int type, 62425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown SensorListener listener, int sensors) { 62525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // Are we deactivating this legacy sensor? 62625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if ((sensors & legacyType) != 0) { 62725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // if so, find the corresponding Sensor 62825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Sensor sensor = getDefaultSensor(type); 62925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (sensor != null) { 63025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // We do all of this work holding the legacy listener lock to ensure 63125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // that the invariants around listeners are maintained. This is safe 63225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // because neither registerLegacyListener nor unregisterLegacyListener 63325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // are called re-entrantly while sensors are being registered or unregistered. 63425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown synchronized (mLegacyListenersMap) { 63525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // do we know about this listener? 63625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown LegacyListener legacyListener = mLegacyListenersMap.get(listener); 63725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (legacyListener != null) { 63825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // unregister this legacy sensor and if we don't 63925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // need the corresponding Sensor, unregister it too 64025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (legacyListener.unregisterSensor(legacyType)) { 64125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // corresponding sensor not needed, unregister 64225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown unregisterListener(legacyListener, sensor); 64325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 64425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // finally check if we still need the legacyListener 64525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // in our mapping, if not, get rid of it too. 64625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (!legacyListener.hasSensors()) { 64725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mLegacyListenersMap.remove(listener); 64825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 64925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 65025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 65125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 65225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 65325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 65425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 65525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for the sensors with which it is registered. 6580f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 65974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 66074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorEventListener object 6610f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 66274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensor 66374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the sensor to unregister from 6640f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 6650f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener) 6660f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #registerListener(SensorEventListener, Sensor, int) 6670f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorEventListener listener, Sensor sensor) { 67025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (listener == null || sensor == null) { 67125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return; 67225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 67325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 67425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown unregisterListenerImpl(listener, sensor); 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for all sensors. 6790f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 68074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 68174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorListener object 6820f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 6830f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener, Sensor) 6840f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #registerListener(SensorEventListener, Sensor, int) 6850f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorEventListener listener) { 68825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (listener == null) { 68925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return; 69025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 69125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 69225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown unregisterListenerImpl(listener, null); 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 69525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /** @hide */ 69625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown protected abstract void unregisterListenerImpl(SensorEventListener listener, Sensor sensor); 69725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 69974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Registers a {@link android.hardware.SensorEventListener 70074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * SensorEventListener} for the given sensor. 7010f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 70274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 70374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A {@link android.hardware.SensorEventListener SensorEventListener} 70474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * object. 7050f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 70674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensor 70774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The {@link android.hardware.Sensor Sensor} to register to. 7080f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 70974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param rate 71074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The rate {@link android.hardware.SensorEvent sensor events} are 71174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * delivered at. This is only a hint to the system. Events may be 71274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * received faster or slower than the specified rate. Usually events 71374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * are received faster. The value must be one of 71474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI}, 715050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST} 716050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian * or, the desired delay between events in microsecond. 7170f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 71874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> if the sensor is supported and successfully 71974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * enabled. 7200f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 7210f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #registerListener(SensorEventListener, Sensor, int, Handler) 7220f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener) 7230f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener, Sensor) 7240f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) { 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return registerListener(listener, sensor, rate, null); 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 73174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Registers a {@link android.hardware.SensorEventListener 73274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * SensorEventListener} for the given sensor. 7330f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 73474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 73574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A {@link android.hardware.SensorEventListener SensorEventListener} 73674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * object. 7370f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 73874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensor 73974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The {@link android.hardware.Sensor Sensor} to register to. 7400f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 74174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param rate 74274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The rate {@link android.hardware.SensorEvent sensor events} are 74374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * delivered at. This is only a hint to the system. Events may be 74474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * received faster or slower than the specified rate. Usually events 74574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * are received faster. The value must be one of 74674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI}, 74774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}. 748050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian * or, the desired delay between events in microsecond. 7490f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 75074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param handler 75174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The {@link android.os.Handler Handler} the 75274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent sensor events} will be 75374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * delivered to. 7540f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the sensor is supported and successfully enabled. 7560f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 7570f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #registerListener(SensorEventListener, Sensor, int) 7580f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener) 7590f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener, Sensor) 7600f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate, 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Handler handler) { 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null || sensor == null) { 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 76725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int delay = -1; 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (rate) { 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_FASTEST: 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delay = 0; 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_GAME: 774050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian delay = 20000; 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_UI: 7775263767cdae21f8f6968dfba974623b240746d6eMathias Agopian delay = 66667; 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_NORMAL: 780050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian delay = 200000; 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 783050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian delay = rate; 784050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian break; 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 78725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return registerListenerImpl(listener, sensor, delay, handler); 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 79025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /** @hide */ 79125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, 79225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown int delay, Handler handler); 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 79574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 79674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Computes the inclination matrix <b>I</b> as well as the rotation matrix 79774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>R</b> transforming a vector from the device coordinate system to the 79874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * world's coordinate system which is defined as a direct orthonormal basis, 79974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * where: 80074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 8010f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 80274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the ground at the device's current location and roughly points East).</li> 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Y is tangential to the ground at the device's current location and 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * points towards the magnetic North Pole.</li> 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Z points towards the sky and is perpendicular to the ground.</li> 80874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 8090f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 8100f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * <p> 8110f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * <center><img src="../../../images/axis_globe.png" 812f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * alt="World coordinate-system diagram." border="0" /></center> 8130f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * </p> 8140f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 81774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 81874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * By definition: 81974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 82074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * [0 0 g] = <b>R</b> * <b>gravity</b> (g = magnitude of gravity) 82174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 82274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * [0 m 0] = <b>I</b> * <b>R</b> * <b>geomagnetic</b> (m = magnitude of 82374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * geomagnetic field) 82474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 82574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>R</b> is the identity matrix when the device is aligned with the 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * world's coordinate system, that is, when the device's X axis points 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * toward East, the Y axis points to the North Pole and the device is facing 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the sky. 8290f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 83074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 83174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>I</b> is a rotation matrix transforming the geomagnetic vector into 83274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the same coordinate space as gravity (the world's coordinate space). 83374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>I</b> is a simple rotation around the X axis. The inclination angle in 83474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * radians can be computed with {@link #getInclination}. 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 8360f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 83774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 83874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Each matrix is returned either as a 3x3 or 4x4 row-major matrix depending 83974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * on the length of the passed array: 84074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 84174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <u>If the array length is 16:</u> 8420f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] M[ 3] \ 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 4] M[ 5] M[ 6] M[ 7] | 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 8] M[ 9] M[10] M[11] | 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ M[12] M[13] M[14] M[15] / 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 8490f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 85074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * This matrix is ready to be used by OpenGL ES's 85174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link javax.microedition.khronos.opengles.GL10#glLoadMatrixf(float[], int) 85274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * glLoadMatrixf(float[], int)}. 85374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 85474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Note that because OpenGL matrices are column-major matrices you must 85574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * transpose the matrix before using it. However, since the matrix is a 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rotation matrix, its transpose is also its inverse, conveniently, it is 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * often the inverse of the rotation that is needed for rendering; it can 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * therefore be used with OpenGL ES directly. 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Also note that the returned matrices always have this form: 8610f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] 0 \ 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 4] M[ 5] M[ 6] 0 | 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 8] M[ 9] M[10] 0 | 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ 0 0 0 1 / 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 8680f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 86974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 87074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <u>If the array length is 9:</u> 8710f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] \ 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 3] M[ 4] M[ 5] | 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ M[ 6] M[ 7] M[ 8] / 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 8770f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 87974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 88074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The inverse of each matrix can be computed easily by taking its 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * transpose. 8820f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 88374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 88474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The matrices returned by this function are meaningful only when the 88574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * device is not free-falling and it is not close to the magnetic north. If 88674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the device is accelerating, or placed into a strong magnetic field, the 88774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * returned matrices may be inaccurate. 8880f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 88974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param R 89074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 9 floats holding the rotation matrix <b>R</b> when 89174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * this function returns. R can be null. 89274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 8930f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 89474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param I 89574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 9 floats holding the rotation matrix <b>I</b> when 89674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * this function returns. I can be null. 89774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 8980f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 89974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param gravity 90074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 3 floats containing the gravity vector expressed in 90174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the device's coordinate. You can simply use the 90274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent#values values} returned by a 90374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent SensorEvent} of a 90474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor Sensor} of type 90574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor#TYPE_ACCELEROMETER 90674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * TYPE_ACCELEROMETER}. 90774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 9080f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 90974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param geomagnetic 91074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 3 floats containing the geomagnetic vector 91174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * expressed in the device's coordinate. You can simply use the 91274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent#values values} returned by a 91374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent SensorEvent} of a 91474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor Sensor} of type 91574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD 91674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * TYPE_MAGNETIC_FIELD}. 9170f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 91874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> on success, <code>false</code> on failure (for 91974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instance, if the device is in free fall). On failure the output 92074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * matrices are not modified. 9210f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9220f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getInclination(float[]) 9230f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getOrientation(float[], float[]) 9240f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #remapCoordinateSystem(float[], int, int, float[]) 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean getRotationMatrix(float[] R, float[] I, 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] gravity, float[] geomagnetic) { 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: move this to native code for efficiency 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Ax = gravity[0]; 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Ay = gravity[1]; 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Az = gravity[2]; 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ex = geomagnetic[0]; 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ey = geomagnetic[1]; 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ez = geomagnetic[2]; 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hx = Ey*Az - Ez*Ay; 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hy = Ez*Ax - Ex*Az; 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hz = Ex*Ay - Ey*Ax; 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz); 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (normH < 0.1f) { 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // device is close to free fall (or in space?), or close to 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // magnetic north pole. Typical values are > 100. 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invH = 1.0f / normH; 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hx *= invH; 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hy *= invH; 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hz *= invH; 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invA = 1.0f / (float)Math.sqrt(Ax*Ax + Ay*Ay + Az*Az); 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Ax *= invA; 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Ay *= invA; 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Az *= invA; 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Mx = Ay*Hz - Az*Hy; 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float My = Az*Hx - Ax*Hz; 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Mz = Ax*Hy - Ay*Hx; 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R != null) { 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R.length == 9) { 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[0] = Hx; R[1] = Hy; R[2] = Hz; 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[3] = Mx; R[4] = My; R[5] = Mz; 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[6] = Ax; R[7] = Ay; R[8] = Az; 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (R.length == 16) { 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[0] = Hx; R[1] = Hy; R[2] = Hz; R[3] = 0; 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[4] = Mx; R[5] = My; R[6] = Mz; R[7] = 0; 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[8] = Ax; R[9] = Ay; R[10] = Az; R[11] = 0; 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[12] = 0; R[13] = 0; R[14] = 0; R[15] = 1; 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I != null) { 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute the inclination matrix by projecting the geomagnetic 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // vector onto the Z (gravity) and X (horizontal component 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // of geomagnetic vector) axes. 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invE = 1.0f / (float)Math.sqrt(Ex*Ex + Ey*Ey + Ez*Ez); 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float c = (Ex*Mx + Ey*My + Ez*Mz) * invE; 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float s = (Ex*Ax + Ey*Ay + Ez*Az) * invE; 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I.length == 9) { 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[0] = 1; I[1] = 0; I[2] = 0; 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[3] = 0; I[4] = c; I[5] = s; 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[6] = 0; I[7] =-s; I[8] = c; 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (I.length == 16) { 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[0] = 1; I[1] = 0; I[2] = 0; 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[4] = 0; I[5] = c; I[6] = s; 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[8] = 0; I[9] =-s; I[10]= c; 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[3] = I[7] = I[11] = I[12] = I[13] = I[14] = 0; 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[15] = 1; 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes the geomagnetic inclination angle in radians from the 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * inclination matrix <b>I</b> returned by {@link #getRotationMatrix}. 9930f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 99474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param I 99574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * inclination matrix see {@link #getRotationMatrix}. 9960f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The geomagnetic inclination angle in radians. 9980f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9990f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getRotationMatrix(float[], float[], float[], float[]) 10000f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getOrientation(float[], float[]) 10010f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see GeomagneticField 10020f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static float getInclination(float[] I) { 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I.length == 9) { 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (float)Math.atan2(I[5], I[4]); 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10080f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian return (float)Math.atan2(I[6], I[5]); 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 101374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 101474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Rotates the supplied rotation matrix so it is expressed in a different 101574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * coordinate system. This is typically used when an application needs to 101674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * compute the three orientation angles of the device (see 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #getOrientation}) in a different coordinate system. 101874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 10190f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 102074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 102174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * When the rotation matrix is used for drawing (for instance with OpenGL 102274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * ES), it usually <b>doesn't need</b> to be transformed by this function, 102374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * unless the screen is physically rotated, in which case you can use 102474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.view.Display#getRotation() Display.getRotation()} to 102574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * retrieve the current rotation of the screen. Note that because the user 102674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is generally free to rotate their screen, you often should consider the 102774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rotation in deciding the parameters to use here. 102874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 10290f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 103074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 103174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <u>Examples:</u> 103274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 10330f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 103474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 103574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <li>Using the camera (Y axis along the camera's axis) for an augmented 103674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * reality application where the rotation angles are needed:</li> 10370f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 103874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 103974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 104074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <code>remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);</code> 104174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 104274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 10430f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 10445cb70b54156fb305d579a1cc167424c8705bfdf7Dianne Hackborn * <li>Using the device as a mechanical compass when rotation is 104574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.view.Surface#ROTATION_90 Surface.ROTATION_90}:</li> 10460f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 104774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 104874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 104974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <code>remapCoordinateSystem(inR, AXIS_Y, AXIS_MINUS_X, outR);</code> 105074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 105174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 10520f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 105374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Beware of the above example. This call is needed only to account for a 105474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rotation from its natural orientation when calculating the rotation 105574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * angles (see {@link #getOrientation}). If the rotation matrix is also used 105674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * for rendering, it may not need to be transformed, for instance if your 105774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.app.Activity Activity} is running in landscape mode. 105874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 10590f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 106074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 106174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Since the resulting coordinate system is orthonormal, only two axes need 106274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * to be specified. 10630f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 106474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param inR 106574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the rotation matrix to be transformed. Usually it is the matrix 106674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * returned by {@link #getRotationMatrix}. 10670f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 106874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param X 106974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * defines on which world axis and direction the X axis of the device 107074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is mapped. 10710f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 107274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param Y 107374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * defines on which world axis and direction the Y axis of the device 107474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is mapped. 10750f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 107674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param outR 107774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the transformed rotation matrix. inR and outR can be the same 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * array, but it is not recommended for performance reason. 10790f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 108074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> on success. <code>false</code> if the input 108174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * parameters are incorrect, for instance if X and Y define the same 108274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * axis. Or if inR and outR don't have the same length. 10830f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 10840f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getRotationMatrix(float[], float[], float[], float[]) 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean remapCoordinateSystem(float[] inR, int X, int Y, 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] outR) 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inR == outR) { 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float[] temp = mTempMatrix; 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(temp) { 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we don't expect to have a lot of contention 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (remapCoordinateSystemImpl(inR, X, Y, temp)) { 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int size = outR.length; 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<size ; i++) 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[i] = temp[i]; 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return remapCoordinateSystemImpl(inR, X, Y, outR); 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean remapCoordinateSystemImpl(float[] inR, int X, int Y, 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] outR) 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * X and Y define a rotation matrix 'r': 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (X==1)?((X&0x80)?-1:1):0 (X==2)?((X&0x80)?-1:1):0 (X==3)?((X&0x80)?-1:1):0 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (Y==1)?((Y&0x80)?-1:1):0 (Y==2)?((Y&0x80)?-1:1):0 (Y==3)?((X&0x80)?-1:1):0 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * r[0] ^ r[1] 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * where the 3rd line is the vector product of the first 2 lines 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int length = outR.length; 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inR.length != length) 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // invalid parameter 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((X & 0x7C)!=0 || (Y & 0x7C)!=0) 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // invalid parameter 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((X & 0x3)==0) || ((Y & 0x3)==0)) 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // no axis specified 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((X & 0x3) == (Y & 0x3)) 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // same axis specified 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Z is "the other" axis, its sign is either +/- sign(X)*sign(Y) 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this can be calculated by exclusive-or'ing X and Y; except for 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the sign inversion (+/-) which is calculated below. 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int Z = X ^ Y; 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // extract the axis (remove the sign), offset in the range 0 to 2. 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int x = (X & 0x3)-1; 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int y = (Y & 0x3)-1; 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int z = (Z & 0x3)-1; 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute the sign of Z (whether it needs to be inverted) 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int axis_y = (z+1)%3; 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int axis_z = (z+2)%3; 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((x^axis_y)|(y^axis_z)) != 0) 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Z ^= 0x80; 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sx = (X>=0x80); 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sy = (Y>=0x80); 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sz = (Z>=0x80); 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Perform R * r, in avoiding actual muls and adds. 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int rowLength = ((length==16)?4:3); 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j=0 ; j<3 ; j++) { 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int offset = j*rowLength; 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<3 ; i++) { 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x==i) outR[offset+i] = sx ? -inR[offset+0] : inR[offset+0]; 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (y==i) outR[offset+i] = sy ? -inR[offset+1] : inR[offset+1]; 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (z==i) outR[offset+i] = sz ? -inR[offset+2] : inR[offset+2]; 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (length == 16) { 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[3] = outR[7] = outR[11] = outR[12] = outR[13] = outR[14] = 0; 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[15] = 1; 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes the device's orientation based on the rotation matrix. 116874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 116974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * When it returns, the array values is filled with the result: 117074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[0]: <i>azimuth</i>, rotation around the Z axis.</li> 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[1]: <i>pitch</i>, rotation around the X axis.</li> 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[2]: <i>roll</i>, rotation around the Y axis.</li> 117474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 1175f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * <p>The reference coordinate-system used is different from the world 1176f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * coordinate-system defined for the rotation matrix:</p> 1177f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * <ul> 1178f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to 1179f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * the ground at the device's current location and roughly points West).</li> 1180f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * <li>Y is tangential to the ground at the device's current location and 1181f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * points towards the magnetic North Pole.</li> 1182f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * <li>Z points towards the center of the Earth and is perpendicular to the ground.</li> 1183f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * </ul> 1184f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 11860871ee0c6f43a7201ce49a66211c1c850eabeb6bDirk Dougherty * <center><img src="../../../images/axis_globe_inverted.png" 1187f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * alt="Inverted world coordinate-system diagram." border="0" /></center> 11880f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * </p> 11890f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * <p> 1190210fc914db37b3cf77ebb3bf75b0b509a1ecb07cMathias Agopian * All three angles above are in <b>radians</b> and <b>positive</b> in the 1191210fc914db37b3cf77ebb3bf75b0b509a1ecb07cMathias Agopian * <b>counter-clockwise</b> direction. 119274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 119374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param R 119474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rotation matrix see {@link #getRotationMatrix}. 11950f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 119674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param values 119774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * an array of 3 floats to hold the result. 11980f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The array values passed as argument. 12000f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 12010f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getRotationMatrix(float[], float[], float[], float[]) 12020f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see GeomagneticField 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 120404d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian public static float[] getOrientation(float[] R, float values[]) { 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4x4 (length=16) case: 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / R[ 0] R[ 1] R[ 2] 0 \ 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 4] R[ 5] R[ 6] 0 | 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 8] R[ 9] R[10] 0 | 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ 0 0 0 1 / 12110f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3x3 (length=9) case: 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / R[ 0] R[ 1] R[ 2] \ 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 3] R[ 4] R[ 5] | 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ R[ 6] R[ 7] R[ 8] / 12160f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R.length == 9) { 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = (float)Math.atan2(R[1], R[4]); 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = (float)Math.asin(-R[7]); 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = (float)Math.atan2(-R[6], R[8]); 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = (float)Math.atan2(R[1], R[5]); 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = (float)Math.asin(-R[9]); 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = (float)Math.atan2(-R[8], R[10]); 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return values; 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 123104d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * Computes the Altitude in meters from the atmospheric pressure and the 123204d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * pressure at sea level. 123304d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * <p> 123404d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * Typically the atmospheric pressure is read from a 123504d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * {@link Sensor#TYPE_PRESSURE} sensor. The pressure at sea level must be 123604d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * known, usually it can be retrieved from airport databases in the 1237a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * vicinity. If unknown, you can use {@link #PRESSURE_STANDARD_ATMOSPHERE} 1238a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * as an approximation, but absolute altitudes won't be accurate. 1239a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * </p> 1240a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * <p> 1241a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * To calculate altitude differences, you must calculate the difference 1242a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * between the altitudes at both points. If you don't know the altitude 1243a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * as sea level, you can use {@link #PRESSURE_STANDARD_ATMOSPHERE} instead, 1244a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * which will give good results considering the range of pressure typically 1245a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * involved. 1246a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * </p> 1247a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * <p> 1248a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * <code><ul> 1249a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * float altitude_difference = 1250a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, pressure_at_point2) 1251a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * - getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, pressure_at_point1); 1252a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * </ul></code> 125304d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * </p> 125404d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * 125504d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * @param p0 pressure at sea level 125604d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * @param p atmospheric pressure 125704d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * @return Altitude in meters 125804d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian */ 125925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown public static float getAltitude(float p0, float p) { 126004d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian final float coef = 1.0f / 5.255f; 126104d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian return 44330.0f * (1.0f - (float)Math.pow(p/p0, coef)); 126204d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian } 126304d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian 126425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /** Helper function to compute the angle change between two rotation matrices. 126525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * Given a current rotation matrix (R) and a previous rotation matrix 126625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * (prevR) computes the rotation around the x,y, and z axes which 126725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * transforms prevR to R. 126825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * outputs a 3 element vector containing the x,y, and z angle 126925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * change at indexes 0, 1, and 2 respectively. 127025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * <p> Each input matrix is either as a 3x3 or 4x4 row-major matrix 127125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * depending on the length of the passed array: 127225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * <p>If the array length is 9, then the array elements represent this matrix 127325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * <pre> 127425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * / R[ 0] R[ 1] R[ 2] \ 127525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * | R[ 3] R[ 4] R[ 5] | 127625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * \ R[ 6] R[ 7] R[ 8] / 127725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown *</pre> 127825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * <p>If the array length is 16, then the array elements represent this matrix 127925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * <pre> 128025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * / R[ 0] R[ 1] R[ 2] R[ 3] \ 128125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * | R[ 4] R[ 5] R[ 6] R[ 7] | 128225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * | R[ 8] R[ 9] R[10] R[11] | 128325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * \ R[12] R[13] R[14] R[15] / 128425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown *</pre> 128525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * @param R current rotation matrix 128625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * @param prevR previous rotation matrix 128725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * @param angleChange an array of floats in which the angle change is stored 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 129025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown public static void getAngleChange( float[] angleChange, float[] R, float[] prevR) { 129125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float rd1=0,rd4=0, rd6=0,rd7=0, rd8=0; 129225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float ri0=0,ri1=0,ri2=0,ri3=0,ri4=0,ri5=0,ri6=0,ri7=0,ri8=0; 129325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float pri0=0, pri1=0, pri2=0, pri3=0, pri4=0, pri5=0, pri6=0, pri7=0, pri8=0; 129425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown int i, j, k; 129525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 129625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if(R.length == 9) { 129725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri0 = R[0]; 129825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri1 = R[1]; 129925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri2 = R[2]; 130025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri3 = R[3]; 130125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri4 = R[4]; 130225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri5 = R[5]; 130325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri6 = R[6]; 130425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri7 = R[7]; 130525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri8 = R[8]; 130625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } else if(R.length == 16) { 130725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri0 = R[0]; 130825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri1 = R[1]; 130925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri2 = R[2]; 131025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri3 = R[4]; 131125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri4 = R[5]; 131225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri5 = R[6]; 131325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri6 = R[8]; 131425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri7 = R[9]; 131525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ri8 = R[10]; 131625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 131725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 131825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if(prevR.length == 9) { 131925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri0 = prevR[0]; 132025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri1 = prevR[1]; 132125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri2 = prevR[2]; 132225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri3 = prevR[3]; 132325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri4 = prevR[4]; 132425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri5 = prevR[5]; 132525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri6 = prevR[6]; 132625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri7 = prevR[7]; 132725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri8 = prevR[8]; 132825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } else if(prevR.length == 16) { 132925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri0 = prevR[0]; 133025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri1 = prevR[1]; 133125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri2 = prevR[2]; 133225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri3 = prevR[4]; 133325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri4 = prevR[5]; 133425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri5 = prevR[6]; 133525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri6 = prevR[8]; 133625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri7 = prevR[9]; 133725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown pri8 = prevR[10]; 133825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 133925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 134025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // calculate the parts of the rotation difference matrix we need 134125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // rd[i][j] = pri[0][i] * ri[0][j] + pri[1][i] * ri[1][j] + pri[2][i] * ri[2][j]; 134225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 134325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown rd1 = pri0 * ri1 + pri3 * ri4 + pri6 * ri7; //rd[0][1] 134425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown rd4 = pri1 * ri1 + pri4 * ri4 + pri7 * ri7; //rd[1][1] 134525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown rd6 = pri2 * ri0 + pri5 * ri3 + pri8 * ri6; //rd[2][0] 134625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown rd7 = pri2 * ri1 + pri5 * ri4 + pri8 * ri7; //rd[2][1] 134725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown rd8 = pri2 * ri2 + pri5 * ri5 + pri8 * ri8; //rd[2][2] 134825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 134925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown angleChange[0] = (float)Math.atan2(rd1, rd4); 135025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown angleChange[1] = (float)Math.asin(-rd7); 135125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown angleChange[2] = (float)Math.atan2(-rd6, rd8); 135225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 135325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 135425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 135525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /** Helper function to convert a rotation vector to a rotation matrix. 135625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * Given a rotation vector (presumably from a ROTATION_VECTOR sensor), returns a 135725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * 9 or 16 element rotation matrix in the array R. R must have length 9 or 16. 135825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * If R.length == 9, the following matrix is returned: 135925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * <pre> 136025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * / R[ 0] R[ 1] R[ 2] \ 136125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * | R[ 3] R[ 4] R[ 5] | 136225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * \ R[ 6] R[ 7] R[ 8] / 136325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown *</pre> 136425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * If R.length == 16, the following matrix is returned: 136525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * <pre> 136625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * / R[ 0] R[ 1] R[ 2] 0 \ 136725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * | R[ 4] R[ 5] R[ 6] 0 | 136825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * | R[ 8] R[ 9] R[10] 0 | 136925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * \ 0 0 0 1 / 137025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown *</pre> 137125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * @param rotationVector the rotation vector to convert 137225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * @param R an array of floats in which to store the rotation matrix 137325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown */ 137425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown public static void getRotationMatrixFromVector(float[] R, float[] rotationVector) { 137525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 137625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float q0; 137725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float q1 = rotationVector[0]; 137825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float q2 = rotationVector[1]; 137925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float q3 = rotationVector[2]; 138025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 138125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (rotationVector.length == 4) { 138225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown q0 = rotationVector[3]; 138325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } else { 138425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown q0 = 1 - q1*q1 - q2*q2 - q3*q3; 138525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown q0 = (q0 > 0) ? (float)Math.sqrt(q0) : 0; 138625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 138725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 138825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float sq_q1 = 2 * q1 * q1; 138925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float sq_q2 = 2 * q2 * q2; 139025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float sq_q3 = 2 * q3 * q3; 139125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float q1_q2 = 2 * q1 * q2; 139225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float q3_q0 = 2 * q3 * q0; 139325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float q1_q3 = 2 * q1 * q3; 139425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float q2_q0 = 2 * q2 * q0; 139525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float q2_q3 = 2 * q2 * q3; 139625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown float q1_q0 = 2 * q1 * q0; 139725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 139825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if(R.length == 9) { 139925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[0] = 1 - sq_q2 - sq_q3; 140025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[1] = q1_q2 - q3_q0; 140125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[2] = q1_q3 + q2_q0; 140225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 140325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[3] = q1_q2 + q3_q0; 140425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[4] = 1 - sq_q1 - sq_q3; 140525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[5] = q2_q3 - q1_q0; 140625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 140725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[6] = q1_q3 - q2_q0; 140825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[7] = q2_q3 + q1_q0; 140925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[8] = 1 - sq_q1 - sq_q2; 141025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } else if (R.length == 16) { 141125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[0] = 1 - sq_q2 - sq_q3; 141225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[1] = q1_q2 - q3_q0; 141325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[2] = q1_q3 + q2_q0; 141425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[3] = 0.0f; 141525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 141625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[4] = q1_q2 + q3_q0; 141725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[5] = 1 - sq_q1 - sq_q3; 141825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[6] = q2_q3 - q1_q0; 141925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[7] = 0.0f; 142025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 142125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[8] = q1_q3 - q2_q0; 142225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[9] = q2_q3 + q1_q0; 142325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[10] = 1 - sq_q1 - sq_q2; 142425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[11] = 0.0f; 142525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 142625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[12] = R[13] = R[14] = 0.0f; 142725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown R[15] = 1.0f; 142825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 142925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 143025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 143125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /** Helper function to convert a rotation vector to a normalized quaternion. 143225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * Given a rotation vector (presumably from a ROTATION_VECTOR sensor), returns a normalized 143325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * quaternion in the array Q. The quaternion is stored as [w, x, y, z] 143425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * @param rv the rotation vector to convert 143525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * @param Q an array of floats in which to store the computed quaternion 143625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown */ 143725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown public static void getQuaternionFromVector(float[] Q, float[] rv) { 143825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (rv.length == 4) { 143925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Q[0] = rv[3]; 144025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } else { 144125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Q[0] = 1 - rv[0]*rv[0] - rv[1]*rv[1] - rv[2]*rv[2]; 144225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Q[0] = (Q[0] > 0) ? (float)Math.sqrt(Q[0]) : 0; 144325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 144425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Q[1] = rv[0]; 144525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Q[2] = rv[1]; 144625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Q[3] = rv[2]; 144725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 144825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 144925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown static void onRotationChanged(int rotation) { 145025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown synchronized (SensorManager.class) { 145125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sRotation = rotation; 145225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 145325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 145425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 145525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown static int getRotation() { 145625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown synchronized (SensorManager.class) { 145725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return sRotation; 145825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 145925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 146025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 146125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static final class LegacyListener implements SensorEventListener { 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mValues[] = new float[6]; 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SensorListener mTarget; 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSensors; 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final LmsFilter mYawfilter = new LmsFilter(); 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LegacyListener(SensorListener target) { 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget = target; 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors = 0; 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 147425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown boolean registerSensor(int legacyType) { 147525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if ((mSensors & legacyType) != 0) { 147625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return false; 147725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 147825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown boolean alreadyHasOrientationSensor = hasOrientationSensor(mSensors); 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors |= legacyType; 148025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (alreadyHasOrientationSensor && hasOrientationSensor(legacyType)) { 148125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return false; // don't need to re-register the orientation sensor 148225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 148325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return true; 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean unregisterSensor(int legacyType) { 148725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if ((mSensors & legacyType) == 0) { 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 149025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mSensors &= ~legacyType; 149125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (hasOrientationSensor(legacyType) && hasOrientationSensor(mSensors)) { 149225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return false; // can't unregister the orientation sensor just yet 149325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 149725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown boolean hasSensors() { 149825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return mSensors != 0; 149925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 150025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 150125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static boolean hasOrientationSensor(int sensors) { 150225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return (sensors & (SENSOR_ORIENTATION | SENSOR_ORIENTATION_RAW)) != 0; 150325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 150425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onAccuracyChanged(Sensor sensor, int accuracy) { 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 150825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mTarget.onAccuracyChanged(getLegacySensorType(sensor.getType()), accuracy); 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (AbstractMethodError e) { 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // old app that doesn't implement this method 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // just ignore it. 15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onSensorChanged(SensorEvent event) { 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float v[] = mValues; 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[0] = event.values[0]; 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[1] = event.values[1]; 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[2] = event.values[2]; 152125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown int type = event.sensor.getType(); 152225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown int legacyType = getLegacySensorType(type); 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mapSensorDataToWindow(legacyType, v, SensorManager.getRotation()); 152425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (type == Sensor.TYPE_ORIENTATION) { 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mSensors & SENSOR_ORIENTATION_RAW)!=0) { 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(SENSOR_ORIENTATION_RAW, v); 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mSensors & SENSOR_ORIENTATION)!=0) { 15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[0] = mYawfilter.filter(event.timestamp, v[0]); 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(SENSOR_ORIENTATION, v); 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(legacyType, v); 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Helper function to convert the specified sensor's data to the windows's 15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * coordinate space from the device's coordinate space. 15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * output: 3,4,5: values in the old API format 15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 0,1,2: transformed values in the old API format 15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void mapSensorDataToWindow(int sensor, 15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] values, int orientation) { 15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x = values[0]; 15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = values[1]; 15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float z = values[2]; 15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (sensor) { 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ORIENTATION: 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ORIENTATION_RAW: 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z = -z; 15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ACCELEROMETER: 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x = -x; 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y = -y; 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z = -z; 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_MAGNETIC_FIELD: 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x = -x; 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y = -y; 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = x; 15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = y; 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = z; 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[3] = x; 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[4] = y; 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[5] = z; 15727895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian 15737895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian if ((orientation & Surface.ROTATION_90) != 0) { 15747895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian // handles 90 and 270 rotation 15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (sensor) { 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ACCELEROMETER: 15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_MAGNETIC_FIELD: 15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] =-y; 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = x; 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = z; 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ORIENTATION: 15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ORIENTATION_RAW: 15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = x + ((x < 270) ? 90 : -270); 15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = z; 15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = y; 15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15907895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian if ((orientation & Surface.ROTATION_180) != 0) { 15917895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian x = values[0]; 15927895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian y = values[1]; 15937895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian z = values[2]; 15947895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian // handles 180 (flip) and 270 (flip + 90) rotation 15957895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian switch (sensor) { 15967895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_ACCELEROMETER: 15977895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_MAGNETIC_FIELD: 15987895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[0] =-x; 15997895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[1] =-y; 16007895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[2] = z; 16017895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian break; 16027895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_ORIENTATION: 16037895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_ORIENTATION_RAW: 16047895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[0] = (x >= 180) ? (x - 180) : (x + 180); 16057895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[1] =-y; 16067895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[2] =-z; 16077895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian break; 16087895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian } 16097895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian } 16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 161125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 161225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static int getLegacySensorType(int type) { 161325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown switch (type) { 161425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown case Sensor.TYPE_ACCELEROMETER: 161525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return SENSOR_ACCELEROMETER; 161625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown case Sensor.TYPE_MAGNETIC_FIELD: 161725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return SENSOR_MAGNETIC_FIELD; 161825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown case Sensor.TYPE_ORIENTATION: 161925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return SENSOR_ORIENTATION_RAW; 162025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown case Sensor.TYPE_TEMPERATURE: 162125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return SENSOR_TEMPERATURE; 162225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 162325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return 0; 162425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16260f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian 162725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static final class LmsFilter { 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SENSORS_RATE_MS = 20; 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int COUNT = 12; 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float PREDICTION_RATIO = 1.0f/3.0f; 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float PREDICTION_TIME = (SENSORS_RATE_MS*COUNT/1000.0f)*PREDICTION_RATIO; 16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mV[] = new float[COUNT*2]; 16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mT[] = new float[COUNT*2]; 16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mIndex; 16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LmsFilter() { 16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex = COUNT; 16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float filter(long time, float in) { 16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float v = in; 16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float ns = 1.0f / 1000000000.0f; 16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float t = time*ns; 16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float v1 = mV[mIndex]; 16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((v-v1) > 180) { 16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v -= 360; 16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((v1-v) > 180) { 16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v += 360; 16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Manage the circular buffer, we write the data twice spaced 16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by COUNT values, so that we don't have to copy the array 16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when it's full 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex++; 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIndex >= COUNT*2) 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex = COUNT; 16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mV[mIndex] = v; 16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mT[mIndex] = t; 16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mV[mIndex-COUNT] = v; 16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mT[mIndex-COUNT] = t; 16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float A, B, C, D, E; 16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float a, b; 16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A = B = C = D = E = 0; 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0 ; i<COUNT-1 ; i++) { 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int j = mIndex - 1 - i; 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Z = mV[j]; 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float T = 0.5f*(mT[j] + mT[j+1]) - t; 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float dT = mT[j] - mT[j+1]; 16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dT *= dT; 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A += Z*dT; 16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project B += T*(T*dT); 16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project C += (T*dT); 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project D += Z*(T*dT); 16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project E += dT; 16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = (A*B + C*D) / (E*B + C*C); 16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = (E*b - A) / C; 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float f = b + PREDICTION_TIME*a; 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Normalize 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f *= (1.0f / 360.0f); 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((f>=0)?f:-f) >= 0.5f) 16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f = f - (float)Math.ceil(f + 0.5f) + 1.0f; 16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f < 0) 16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f += 1.0f; 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f *= 360.0f; 16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return f; 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 169425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /** 169525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * Sensor event pool implementation. 169625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * @hide 16977a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell */ 169825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown protected static final class SensorEventPool { 169925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private final int mPoolSize; 170025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private final SensorEvent mPool[]; 170125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private int mNumItemsInPool; 17027a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 170325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private SensorEvent createSensorEvent() { 170425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // maximal size for all legacy events is 3 170525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return new SensorEvent(3); 17067a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell } 17077a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 170825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown SensorEventPool(int poolSize) { 170925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mPoolSize = poolSize; 171025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mNumItemsInPool = poolSize; 171125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mPool = new SensorEvent[poolSize]; 17127badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian } 17137badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian 171425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown SensorEvent getFromPool() { 171525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown SensorEvent t = null; 171625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown synchronized (this) { 171725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (mNumItemsInPool > 0) { 171825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // remove the "top" item from the pool 171925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final int index = mPoolSize - mNumItemsInPool; 172025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown t = mPool[index]; 172125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mPool[index] = null; 172225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mNumItemsInPool--; 172325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 172425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 172525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (t == null) { 172625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // the pool was empty or this item was removed from the pool for 172725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // the first time. In any case, we need to create a new item. 172825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown t = createSensorEvent(); 172925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 173025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return t; 17317a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell } 17327a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 173325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown void returnToPool(SensorEvent t) { 173425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown synchronized (this) { 173525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // is there space left in the pool? 173625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (mNumItemsInPool < mPoolSize) { 173725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // if so, return the item to the pool 173825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mNumItemsInPool++; 173925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final int index = mPoolSize - mNumItemsInPool; 174025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mPool[index] = t; 174125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 174225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 17437badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian } 17447a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell } 17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1746