SensorManager.java revision 050b56244ff46d43e4886018d7cd20f0b1dc02b9
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.Looper; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Process; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IRotationWatcher; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IWindowManager; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Surface; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 3774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * SensorManager lets you access the device's {@link android.hardware.Sensor 3874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensors}. Get an instance of this class by calling 3974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.content.Context#getSystemService(java.lang.String) 4074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Context.getSystemService()} with the argument 4174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.content.Context#SENSOR_SERVICE}. 420f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 430f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * <pre class="prettyprint"> 440f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * public class SensorActivity extends Activity, implements SensorEventListener { 450f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * private final SensorManager mSensorManager; 460f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * private final Sensor mAccelerometer; 470f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 480f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * public SensorActivity() { 490f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); 500f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 510f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); 520f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * } 530f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 540f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * public void onAccuracyChanged(Sensor sensor, int accuracy) { 550f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * } 560f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 570f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * public abstract void onSensorChanged(SensorEvent event) { 580f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * } 590f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * } 600f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * </pre> 610f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 620f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see SensorEventListener 630f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see SensorEvent 640f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see Sensor 650f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 67287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopianpublic class SensorManager 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "SensorManager"; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float[] mTempMatrix = new float[16]; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* NOTE: sensor IDs must be a power of 2 */ 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an orientation sensor. See 7674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 770f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ORIENTATION = 1 << 0; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an accelerometer. See 8574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 860f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ACCELEROMETER = 1 << 1; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a temperature sensor See 9474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 950f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_TEMPERATURE = 1 << 2; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a magnetic sensor See 10374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1040f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_MAGNETIC_FIELD = 1 << 3; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an ambient light sensor See 11274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1130f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_LIGHT = 1 << 4; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a proximity sensor See 12174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1220f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_PROXIMITY = 1 << 5; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a Tricorder See 13074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1310f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_TRICORDER = 1 << 6; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an orientation sensor. See 13974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1400f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ORIENTATION_RAW = 1 << 7; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 14774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant that includes all sensors 1480f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1494a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1504a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ALL = 0x7F; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 15574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Smallest sensor ID 1560f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1574a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1584a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_MIN = SENSOR_ORIENTATION; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 16374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Largest sensor ID 1640f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1654a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1664a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_MAX = ((SENSOR_ALL + 1)>>1); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 17274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the X value in the array returned by 1734a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 1740f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1754a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1764a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATA_X = 0; 17974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 18074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 18174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the Y value in the array returned by 1824a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 1830f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1844a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1854a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATA_Y = 1; 18874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 18974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 19074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the Z value in the array returned by 1914a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 1920f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1934a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1944a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATA_Z = 2; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 19974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Offset to the untransformed values in the array returned by 2004a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 2010f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 2024a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 2034a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_INDEX = 3; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 20874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the untransformed X value in the array returned by 2094a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 2100f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 2114a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 2124a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_X = 3; 21574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 21674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 21774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the untransformed Y value in the array returned by 2184a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 2190f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 2204a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 2214a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_Y = 4; 22474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 22574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 22674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the untransformed Z value in the array returned by 2274a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 2280f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 2294a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 2304a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_Z = 5; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Standard gravity (g) on Earth. This value is equivalent to 1G */ 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float STANDARD_GRAVITY = 9.80665f; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Sun's gravity in SI units (m/s^2) */ 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_SUN = 275.0f; 23974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Mercury's gravity in SI units (m/s^2) */ 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MERCURY = 3.70f; 24174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Venus' gravity in SI units (m/s^2) */ 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_VENUS = 8.87f; 24374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Earth's gravity in SI units (m/s^2) */ 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_EARTH = 9.80665f; 24574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** The Moon's gravity in SI units (m/s^2) */ 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MOON = 1.6f; 24774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Mars' gravity in SI units (m/s^2) */ 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MARS = 3.71f; 24974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Jupiter's gravity in SI units (m/s^2) */ 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_JUPITER = 23.12f; 25174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Saturn's gravity in SI units (m/s^2) */ 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_SATURN = 8.96f; 25374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Uranus' gravity in SI units (m/s^2) */ 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_URANUS = 8.69f; 25574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Neptune's gravity in SI units (m/s^2) */ 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_NEPTUNE = 11.0f; 25774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Pluto's gravity in SI units (m/s^2) */ 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_PLUTO = 0.6f; 25974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Gravity (estimate) on the first Death Star in Empire units (m/s^2) */ 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_DEATH_STAR_I = 0.000000353036145f; 26174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Gravity on the island */ 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_THE_ISLAND = 4.815162342f; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Maximum magnetic field on Earth's surface */ 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float MAGNETIC_FIELD_EARTH_MAX = 60.0f; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Minimum magnetic field on Earth's surface */ 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float MAGNETIC_FIELD_EARTH_MIN = 30.0f; 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2700f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian 27174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Maximum luminance of sunlight in lux */ 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNLIGHT_MAX = 120000.0f; 27374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance of sunlight in lux */ 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNLIGHT = 110000.0f; 27574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance in shade in lux */ 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SHADE = 20000.0f; 27774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance under an overcast sky in lux */ 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_OVERCAST = 10000.0f; 27974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance at sunrise in lux */ 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNRISE = 400.0f; 28174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance under a cloudy sky in lux */ 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_CLOUDY = 100.0f; 28374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance at night with full moon in lux */ 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_FULLMOON = 0.25f; 28574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance at night with no moon in lux*/ 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_NO_MOON = 0.001f; 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2880f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** get sensor data as fast as possible */ 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_FASTEST = 0; 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate suitable for games */ 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_GAME = 1; 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate suitable for the user interface */ 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_UI = 2; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate (default) suitable for screen orientation changes */ 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_NORMAL = 3; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 30074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The values returned by this sensor cannot be trusted, calibration is 30174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * needed or the environment doesn't allow readings 30274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian */ 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_UNRELIABLE = 0; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 30574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 30674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * This sensor is reporting data with low accuracy, calibration with the 30774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * environment is needed 30874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian */ 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_LOW = 1; 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 31274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * This sensor is reporting data with an average level of accuracy, 31374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * calibration with the environment may improve the readings 31474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian */ 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_MEDIUM = 2; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** This sensor is reporting data with maximum accuracy */ 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_HIGH = 3; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_X = 1; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_Y = 2; 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_Z = 3; 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_X = AXIS_X | 0x80; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_Y = AXIS_Y | 0x80; 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_Z = AXIS_Z | 0x80; 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper mMainLooper; 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashMap<SensorListener, LegacyListener> mLegacyListenersMap = 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashMap<SensorListener, LegacyListener>(); 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SENSOR_DISABLE = -1; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean sSensorModuleInitialized = false; 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static ArrayList<Sensor> sFullSensorsList = new ArrayList<Sensor>(); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static SparseArray<List<Sensor>> sSensorListByType = new SparseArray<List<Sensor>>(); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static IWindowManager sWindowManager; 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static int sRotation = Surface.ROTATION_0; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* The thread and the sensor list are global to the process 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but the actual thread is spawned on demand */ 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static SensorThread sSensorThread; 3511bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian private static int sQueue; 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Used within this module from outside SensorManager, don't make private 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static SparseArray<Sensor> sHandleToSensor = new SparseArray<Sensor>(); 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final ArrayList<ListenerDelegate> sListeners = 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new ArrayList<ListenerDelegate>(); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static private class SensorThread { 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Thread mThread; 363b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian boolean mSensorsReady; 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorThread() { 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() { 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // must be called with sListeners lock 3731bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian boolean startLocked() { 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mThread == null) { 3761bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian mSensorsReady = false; 3771bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian SensorThreadRunnable runnable = new SensorThreadRunnable(); 3781bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian Thread thread = new Thread(runnable, SensorThread.class.getName()); 3791bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian thread.start(); 3801bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian synchronized (runnable) { 3811bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian while (mSensorsReady == false) { 3821bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian runnable.wait(); 383b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } 384b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } 3851bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian mThread = thread; 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 387b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } catch (InterruptedException e) { 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 389b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian return mThread == null ? false : true; 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class SensorThreadRunnable implements Runnable { 3931bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian SensorThreadRunnable() { 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 395270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood 396270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood private boolean open() { 397b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian // NOTE: this cannot synchronize on sListeners, since 398b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian // it's held in the main thread at least until we 399b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian // return from here. 4001bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sQueue = sensors_create_queue(); 401270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood return true; 402270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood } 403270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.d(TAG, "entering main sensor thread"); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float[] values = new float[3]; 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] status = new int[1]; 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long timestamp[] = new long[1]; 409e417158c06c81c8c4dc6794c5421b711e671c7e3Mathias Agopian Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY); 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 411270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood if (!open()) { 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 415b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian synchronized (this) { 416b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian // we've open the driver, we're ready to open the sensors 417b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian mSensorsReady = true; 418b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian this.notify(); 419b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } 420b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) { 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // wait for an event 4231bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian final int sensor = sensors_data_poll(sQueue, values, status, timestamp); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int accuracy = status[0]; 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sListeners) { 4276dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber if (sensor == -1 || sListeners.isEmpty()) { 4286dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber if (sensor == -1) { 4296dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber // we lost the connection to the event stream. this happens 4306dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber // when the last listener is removed. 4316dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber Log.d(TAG, "_sensors_data_poll() failed, we bail out."); 4326dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber } 4336dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber 4346dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber // we have no more listeners or polling failed, terminate the thread 4351bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sensors_destroy_queue(sQueue); 4361bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sQueue = 0; 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThread = null; 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Sensor sensorObject = sHandleToSensor.get(sensor); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sensorObject != null) { 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // report the sensor event to all listeners that 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // care about it. 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int size = sListeners.size(); 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<size ; i++) { 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ListenerDelegate listener = sListeners.get(i); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener.hasSensor(sensorObject)) { 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this is asynchronous (okay to call 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sListeners lock held). 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.onSensorChangedLocked(sensorObject, 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values, timestamp, accuracy); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.d(TAG, "exiting main sensor thread"); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4641bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian private class ListenerDelegate { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final SensorEventListener mSensorEventListener; 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Sensor> mSensorList = new ArrayList<Sensor>(); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Handler mHandler; 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SensorEvent mValuesPool; 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int mSensors; 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ListenerDelegate(SensorEventListener listener, Sensor sensor, Handler handler) { 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorEventListener = listener; 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper looper = (handler != null) ? handler.getLooper() : mMainLooper; 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // currently we create one Handler instance per listener, but we could 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // have one per looper (we'd need to pass the ListenerDelegate 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // instance to handleMessage and keep track of them separately). 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler = new Handler(looper) { 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorEvent t = (SensorEvent)msg.obj; 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.accuracy >= 0) { 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorEventListener.onAccuracyChanged(t.sensor, t.accuracy); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorEventListener.onSensorChanged(t); 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project returnToPool(t); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addSensor(sensor); 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected SensorEvent createSensorEvent() { 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // maximal size for all legacy events is 3 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new SensorEvent(3); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected SensorEvent getFromPool() { 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorEvent t = null; 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // remove the array from the pool 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t = mValuesPool; 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mValuesPool = null; 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t == null) { 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the pool was empty, we need a new one 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t = createSensorEvent(); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return t; 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void returnToPool(SensorEvent t) { 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // put back the array into the pool 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mValuesPool == null) { 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mValuesPool = t; 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object getListener() { 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSensorEventListener; 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int addSensor(Sensor sensor) { 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors |= 1<<sensor.getHandle(); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorList.add(sensor); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSensors; 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int removeSensor(Sensor sensor) { 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors &= ~(1<<sensor.getHandle()); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorList.remove(sensor); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSensors; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hasSensor(Sensor sensor) { 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ((mSensors & (1<<sensor.getHandle())) != 0); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Sensor> getSensors() { 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSensorList; 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onSensorChangedLocked(Sensor sensor, float[] values, long[] timestamp, int accuracy) { 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorEvent t = getFromPool(); 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float[] v = t.values; 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[0] = values[0]; 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[1] = values[1]; 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[2] = values[2]; 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.timestamp = timestamp[0]; 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.accuracy = accuracy; 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.sensor = sensor; 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = Message.obtain(); 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.what = 0; 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.obj = t; 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendMessage(msg); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SensorManager(Looper mainLooper) { 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMainLooper = mainLooper; 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!sSensorModuleInitialized) { 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sSensorModuleInitialized = true; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativeClassInit(); 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowManager = IWindowManager.Stub.asInterface( 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ServiceManager.getService("window")); 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sWindowManager != null) { 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if it's null we're running in the system process 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // which won't get the rotated values 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 575287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian sRotation = sWindowManager.watchRotation( 576287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian new IRotationWatcher.Stub() { 577287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian public void onRotationChanged(int rotation) { 578287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian SensorManager.this.onRotationChanged(rotation); 579287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian } 580287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian } 581287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian ); 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // initialize the sensor list 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensors_module_init(); 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<Sensor> fullList = sFullSensorsList; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i = 0; 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Sensor sensor = new Sensor(); 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = sensors_module_get_next_sensor(sensor, i); 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i>=0) { 595f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato //Log.d(TAG, "found sensor: " + sensor.getName() + 596f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato // ", handle=" + sensor.getHandle()); 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensor.setLegacyType(getLegacySensorType(sensor.getType())); 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fullList.add(sensor); 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sHandleToSensor.append(sensor.getHandle(), sensor); 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (i>0); 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sSensorThread = new SensorThread(); 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int getLegacySensorType(int type) { 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (type) { 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ACCELEROMETER: 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_ACCELEROMETER; 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_MAGNETIC_FIELD: 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_MAGNETIC_FIELD; 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ORIENTATION: 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_ORIENTATION_RAW; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_TEMPERATURE: 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_TEMPERATURE; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 62274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 62374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return available sensors. 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 62574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#getSensorList(int)} instead 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getSensors() { 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = 0; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<Sensor> fullList = sFullSensorsList; 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Sensor i : fullList) { 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (i.getType()) { 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ACCELEROMETER: 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_ACCELEROMETER; 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_MAGNETIC_FIELD: 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_MAGNETIC_FIELD; 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ORIENTATION: 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_ORIENTATION | 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorManager.SENSOR_ORIENTATION_RAW; 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 64974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Use this method to get the list of available sensors of a certain type. 65074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Make multiple calls to get sensors of different types or use 65174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor#TYPE_ALL Sensor.TYPE_ALL} to get all the 65274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensors. 6530f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 65474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param type 65574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * of sensors requested 6560f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a list of sensors matching the asked type. 6580f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 6590f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getDefaultSensor(int) 6600f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see Sensor 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<Sensor> getSensorList(int type) { 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cache the returned lists the first time 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Sensor> list; 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<Sensor> fullList = sFullSensorsList; 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(fullList) { 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = sSensorListByType.get(type); 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (list == null) { 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == Sensor.TYPE_ALL) { 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = fullList; 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = new ArrayList<Sensor>(); 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Sensor i : fullList) { 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i.getType() == type) 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list.add(i); 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = Collections.unmodifiableList(list); 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sSensorListByType.append(type, list); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return list; 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 68674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Use this method to get the default sensor for a given type. Note that the 68774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * returned sensor could be a composite sensor, and its data could be 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * averaged or filtered. If you need to access the raw sensors use 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SensorManager#getSensorList(int) getSensorList}. 6900f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 69174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param type 69274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * of sensors requested 6930f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the default sensors matching the asked type. 6950f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 6960f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getSensorList(int) 6970f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see Sensor 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Sensor getDefaultSensor(int type) { 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: need to be smarter, for now, just return the 1st sensor 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Sensor> l = getSensorList(type); 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return l.isEmpty() ? null : l.get(0); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Registers a listener for given sensors. 7070f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 70974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#registerListener(SensorEventListener, Sensor, int)} 71074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 7110f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 71274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 71374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensor listener object 7140f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 71574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensors 71674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a bit masks of the sensors to register to 7170f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 71874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> if the sensor is supported and successfully 71974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * enabled 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorListener listener, int sensors) { 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return registerListener(listener, sensors, SENSOR_DELAY_NORMAL); 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Registers a SensorListener for given sensors. 7280f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 73074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#registerListener(SensorEventListener, Sensor, int)} 73174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 7320f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 73374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 73474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensor listener object 7350f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 73674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensors 73774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a bit masks of the sensors to register to 7380f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 73974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param rate 74074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rate of events. This is only a hint to the system. events may be 74174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * received faster or slower than the specified rate. Usually events 74274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * are received faster. The value must be one of 74374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI}, 74474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}. 7450f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 74674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> if the sensor is supported and successfully 74774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * enabled 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorListener listener, int sensors, int rate) { 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result = false; 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER, 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_MAGNETIC_FIELD, Sensor.TYPE_MAGNETIC_FIELD, 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_ORIENTATION_RAW, Sensor.TYPE_ORIENTATION, 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_ORIENTATION, Sensor.TYPE_ORIENTATION, 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_TEMPERATURE, Sensor.TYPE_TEMPERATURE, 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean registerLegacyListener(int legacyType, int type, 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorListener listener, int sensors, int rate) 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result = false; 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Are we activating this legacy sensor? 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((sensors & legacyType) != 0) { 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if so, find a suitable Sensor 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Sensor sensor = getDefaultSensor(type); 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sensor != null) { 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we don't already have one, create a LegacyListener 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to wrap this listener and process the events as 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // they are expected by legacy apps. 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LegacyListener legacyListener = null; 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLegacyListenersMap) { 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener = mLegacyListenersMap.get(listener); 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (legacyListener == null) { 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we didn't find a LegacyListener for this client, 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // create one, and put it in our list. 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener = new LegacyListener(listener); 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLegacyListenersMap.put(listener, legacyListener); 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // register this legacy sensor with this legacy listener 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener.registerSensor(legacyType); 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and finally, register the legacy listener with the new apis 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerListener(legacyListener, sensor, rate); 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for the sensors with which it is registered. 8050f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 80774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#unregisterListener(SensorEventListener, Sensor)} 80874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 8090f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 81074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 81174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorListener object 8120f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 81374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensors 81474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a bit masks of the sensors to unregister from 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorListener listener, int sensors) { 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER, 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_MAGNETIC_FIELD, Sensor.TYPE_MAGNETIC_FIELD, 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ORIENTATION_RAW, Sensor.TYPE_ORIENTATION, 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ORIENTATION, Sensor.TYPE_ORIENTATION, 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_TEMPERATURE, Sensor.TYPE_TEMPERATURE, 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void unregisterLegacyListener(int legacyType, int type, 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorListener listener, int sensors) 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // do we know about this listener? 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LegacyListener legacyListener = null; 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLegacyListenersMap) { 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener = mLegacyListenersMap.get(listener); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (legacyListener != null) { 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Are we deactivating this legacy sensor? 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((sensors & legacyType) != 0) { 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if so, find the corresponding Sensor 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Sensor sensor = getDefaultSensor(type); 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sensor != null) { 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // unregister this legacy sensor and if we don't 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // need the corresponding Sensor, unregister it too 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (legacyListener.unregisterSensor(legacyType)) { 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // corresponding sensor not needed, unregister 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener(legacyListener, sensor); 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // finally check if we still need the legacyListener 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in our mapping, if not, get rid of it too. 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean found = false; 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ListenerDelegate i : sListeners) { 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i.getListener() == legacyListener) { 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project found = true; 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!found) { 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLegacyListenersMap) { 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLegacyListenersMap.remove(listener); 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for all sensors. 8770f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 87974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#unregisterListener(SensorEventListener)} 88074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 8810f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 88274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 88374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorListener object 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorListener listener) { 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener(listener, SENSOR_ALL | SENSOR_ORIENTATION_RAW); 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for the sensors with which it is registered. 8920f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 89374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 89474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorEventListener object 8950f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 89674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensor 89774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the sensor to unregister from 8980f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 8990f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener) 9000f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #registerListener(SensorEventListener, Sensor, int) 9010f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorEventListener listener, Sensor sensor) { 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener((Object)listener, sensor); 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for all sensors. 9090f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 91074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 91174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorListener object 9120f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9130f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener, Sensor) 9140f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #registerListener(SensorEventListener, Sensor, int) 9150f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorEventListener listener) { 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener((Object)listener); 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 92274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Registers a {@link android.hardware.SensorEventListener 92374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * SensorEventListener} for the given sensor. 9240f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 92574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 92674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A {@link android.hardware.SensorEventListener SensorEventListener} 92774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * object. 9280f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 92974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensor 93074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The {@link android.hardware.Sensor Sensor} to register to. 9310f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 93274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param rate 93374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The rate {@link android.hardware.SensorEvent sensor events} are 93474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * delivered at. This is only a hint to the system. Events may be 93574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * received faster or slower than the specified rate. Usually events 93674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * are received faster. The value must be one of 93774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI}, 938050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST} 939050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian * or, the desired delay between events in microsecond. 9400f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 94174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> if the sensor is supported and successfully 94274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * enabled. 9430f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9440f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #registerListener(SensorEventListener, Sensor, int, Handler) 9450f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener) 9460f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener, Sensor) 9470f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) { 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return registerListener(listener, sensor, rate, null); 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 95474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Registers a {@link android.hardware.SensorEventListener 95574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * SensorEventListener} for the given sensor. 9560f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 95774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 95874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A {@link android.hardware.SensorEventListener SensorEventListener} 95974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * object. 9600f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 96174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensor 96274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The {@link android.hardware.Sensor Sensor} to register to. 9630f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 96474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param rate 96574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The rate {@link android.hardware.SensorEvent sensor events} are 96674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * delivered at. This is only a hint to the system. Events may be 96774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * received faster or slower than the specified rate. Usually events 96874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * are received faster. The value must be one of 96974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI}, 97074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}. 971050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian * or, the desired delay between events in microsecond. 9720f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 97374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param handler 97474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The {@link android.os.Handler Handler} the 97574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent sensor events} will be 97674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * delivered to. 9770f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the sensor is supported and successfully enabled. 9790f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9800f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #registerListener(SensorEventListener, Sensor, int) 9810f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener) 9820f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener, Sensor) 9830f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate, 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Handler handler) { 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null || sensor == null) { 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result; 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int delay = -1; 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (rate) { 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_FASTEST: 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delay = 0; 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_GAME: 997050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian delay = 20000; 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_UI: 1000050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian delay = 60000; 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_NORMAL: 1003050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian delay = 200000; 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 1006050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian delay = rate; 1007050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian break; 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10101bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian synchronized (sListeners) { 10111bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian ListenerDelegate l = null; 10121bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian for (ListenerDelegate i : sListeners) { 10131bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian if (i.getListener() == listener) { 10141bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian l = i; 10151bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian break; 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10171bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian } 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10191bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian String name = sensor.getName(); 10201bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian int handle = sensor.getHandle(); 10211bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian if (l == null) { 10221bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian result = false; 10231bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian l = new ListenerDelegate(listener, sensor, handler); 10241bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sListeners.add(l); 10251bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian if (!sListeners.isEmpty()) { 10261bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian result = sSensorThread.startLocked(); 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result) { 10281bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian result = sensors_enable_sensor(sQueue, name, handle, delay); 10291bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian if (!result) { 10301bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian // there was an error, remove the listeners 10311bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sListeners.remove(l); 10321bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian } 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10351bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian } else { 10361bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian result = sensors_enable_sensor(sQueue, name, handle, delay); 10371bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian if (result) { 10381bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian l.addSensor(sensor); 10391bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian } 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void unregisterListener(Object listener, Sensor sensor) { 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null || sensor == null) { 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10491bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian synchronized (sListeners) { 10501bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian final int size = sListeners.size(); 10511bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian for (int i=0 ; i<size ; i++) { 10521bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian ListenerDelegate l = sListeners.get(i); 10531bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian if (l.getListener() == listener) { 10541bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian // disable these sensors 10551bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian String name = sensor.getName(); 10561bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian int handle = sensor.getHandle(); 10571bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sensors_enable_sensor(sQueue, name, handle, SENSOR_DISABLE); 10581bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian // if we have no more sensors enabled on this listener, 10591bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian // take it off the list. 10601bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian if (l.removeSensor(sensor) == 0) { 10611bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sListeners.remove(i); 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10631bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian break; 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void unregisterListener(Object listener) { 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10731bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian synchronized (sListeners) { 10741bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian final int size = sListeners.size(); 10751bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian for (int i=0 ; i<size ; i++) { 10761bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian ListenerDelegate l = sListeners.get(i); 10771bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian if (l.getListener() == listener) { 10781bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian // disable all sensors for this listener 10791bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian for (Sensor sensor : l.getSensors()) { 10801bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian String name = sensor.getName(); 10811bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian int handle = sensor.getHandle(); 10821bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sensors_enable_sensor(sQueue, name, handle, SENSOR_DISABLE); 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10841bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sListeners.remove(i); 10851bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian break; 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 109274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 109374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Computes the inclination matrix <b>I</b> as well as the rotation matrix 109474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>R</b> transforming a vector from the device coordinate system to the 109574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * world's coordinate system which is defined as a direct orthonormal basis, 109674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * where: 109774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 10980f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 109974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the ground at the device's current location and roughly points East).</li> 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Y is tangential to the ground at the device's current location and 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * points towards the magnetic North Pole.</li> 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Z points towards the sky and is perpendicular to the ground.</li> 110574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 11060f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 11070f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * <p> 11080f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * <center><img src="../../../images/axis_globe.png" 11090f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * alt="Sensors coordinate-system diagram." border="0" /></center> 11100f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * </p> 11110f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 111474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 111574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * By definition: 111674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 111774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * [0 0 g] = <b>R</b> * <b>gravity</b> (g = magnitude of gravity) 111874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 111974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * [0 m 0] = <b>I</b> * <b>R</b> * <b>geomagnetic</b> (m = magnitude of 112074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * geomagnetic field) 112174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 112274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>R</b> is the identity matrix when the device is aligned with the 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * world's coordinate system, that is, when the device's X axis points 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * toward East, the Y axis points to the North Pole and the device is facing 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the sky. 11260f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 112774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 112874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>I</b> is a rotation matrix transforming the geomagnetic vector into 112974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the same coordinate space as gravity (the world's coordinate space). 113074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>I</b> is a simple rotation around the X axis. The inclination angle in 113174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * radians can be computed with {@link #getInclination}. 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 11330f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 113474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 113574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Each matrix is returned either as a 3x3 or 4x4 row-major matrix depending 113674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * on the length of the passed array: 113774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 113874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <u>If the array length is 16:</u> 11390f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] M[ 3] \ 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 4] M[ 5] M[ 6] M[ 7] | 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 8] M[ 9] M[10] M[11] | 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ M[12] M[13] M[14] M[15] / 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 11460f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 114774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * This matrix is ready to be used by OpenGL ES's 114874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link javax.microedition.khronos.opengles.GL10#glLoadMatrixf(float[], int) 114974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * glLoadMatrixf(float[], int)}. 115074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 115174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Note that because OpenGL matrices are column-major matrices you must 115274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * transpose the matrix before using it. However, since the matrix is a 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rotation matrix, its transpose is also its inverse, conveniently, it is 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * often the inverse of the rotation that is needed for rendering; it can 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * therefore be used with OpenGL ES directly. 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Also note that the returned matrices always have this form: 11580f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] 0 \ 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 4] M[ 5] M[ 6] 0 | 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 8] M[ 9] M[10] 0 | 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ 0 0 0 1 / 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 11650f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 116674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 116774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <u>If the array length is 9:</u> 11680f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] \ 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 3] M[ 4] M[ 5] | 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ M[ 6] M[ 7] M[ 8] / 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 11740f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 117674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 117774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The inverse of each matrix can be computed easily by taking its 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * transpose. 11790f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 118074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 118174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The matrices returned by this function are meaningful only when the 118274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * device is not free-falling and it is not close to the magnetic north. If 118374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the device is accelerating, or placed into a strong magnetic field, the 118474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * returned matrices may be inaccurate. 11850f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 118674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param R 118774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 9 floats holding the rotation matrix <b>R</b> when 118874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * this function returns. R can be null. 118974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 11900f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 119174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param I 119274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 9 floats holding the rotation matrix <b>I</b> when 119374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * this function returns. I can be null. 119474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 11950f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 119674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param gravity 119774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 3 floats containing the gravity vector expressed in 119874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the device's coordinate. You can simply use the 119974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent#values values} returned by a 120074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent SensorEvent} of a 120174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor Sensor} of type 120274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor#TYPE_ACCELEROMETER 120374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * TYPE_ACCELEROMETER}. 120474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 12050f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 120674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param geomagnetic 120774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 3 floats containing the geomagnetic vector 120874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * expressed in the device's coordinate. You can simply use the 120974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent#values values} returned by a 121074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent SensorEvent} of a 121174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor Sensor} of type 121274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD 121374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * TYPE_MAGNETIC_FIELD}. 12140f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 121574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> on success, <code>false</code> on failure (for 121674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instance, if the device is in free fall). On failure the output 121774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * matrices are not modified. 12180f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 12190f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getInclination(float[]) 12200f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getOrientation(float[], float[]) 12210f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #remapCoordinateSystem(float[], int, int, float[]) 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean getRotationMatrix(float[] R, float[] I, 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] gravity, float[] geomagnetic) { 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: move this to native code for efficiency 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Ax = gravity[0]; 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Ay = gravity[1]; 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Az = gravity[2]; 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ex = geomagnetic[0]; 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ey = geomagnetic[1]; 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ez = geomagnetic[2]; 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hx = Ey*Az - Ez*Ay; 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hy = Ez*Ax - Ex*Az; 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hz = Ex*Ay - Ey*Ax; 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz); 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (normH < 0.1f) { 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // device is close to free fall (or in space?), or close to 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // magnetic north pole. Typical values are > 100. 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invH = 1.0f / normH; 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hx *= invH; 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hy *= invH; 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hz *= invH; 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invA = 1.0f / (float)Math.sqrt(Ax*Ax + Ay*Ay + Az*Az); 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Ax *= invA; 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Ay *= invA; 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Az *= invA; 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Mx = Ay*Hz - Az*Hy; 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float My = Az*Hx - Ax*Hz; 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Mz = Ax*Hy - Ay*Hx; 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R != null) { 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R.length == 9) { 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[0] = Hx; R[1] = Hy; R[2] = Hz; 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[3] = Mx; R[4] = My; R[5] = Mz; 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[6] = Ax; R[7] = Ay; R[8] = Az; 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (R.length == 16) { 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[0] = Hx; R[1] = Hy; R[2] = Hz; R[3] = 0; 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[4] = Mx; R[5] = My; R[6] = Mz; R[7] = 0; 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[8] = Ax; R[9] = Ay; R[10] = Az; R[11] = 0; 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[12] = 0; R[13] = 0; R[14] = 0; R[15] = 1; 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I != null) { 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute the inclination matrix by projecting the geomagnetic 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // vector onto the Z (gravity) and X (horizontal component 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // of geomagnetic vector) axes. 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invE = 1.0f / (float)Math.sqrt(Ex*Ex + Ey*Ey + Ez*Ez); 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float c = (Ex*Mx + Ey*My + Ez*Mz) * invE; 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float s = (Ex*Ax + Ey*Ay + Ez*Az) * invE; 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I.length == 9) { 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[0] = 1; I[1] = 0; I[2] = 0; 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[3] = 0; I[4] = c; I[5] = s; 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[6] = 0; I[7] =-s; I[8] = c; 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (I.length == 16) { 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[0] = 1; I[1] = 0; I[2] = 0; 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[4] = 0; I[5] = c; I[6] = s; 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[8] = 0; I[9] =-s; I[10]= c; 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[3] = I[7] = I[11] = I[12] = I[13] = I[14] = 0; 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[15] = 1; 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes the geomagnetic inclination angle in radians from the 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * inclination matrix <b>I</b> returned by {@link #getRotationMatrix}. 12900f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 129174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param I 129274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * inclination matrix see {@link #getRotationMatrix}. 12930f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The geomagnetic inclination angle in radians. 12950f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 12960f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getRotationMatrix(float[], float[], float[], float[]) 12970f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getOrientation(float[], float[]) 12980f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see GeomagneticField 12990f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static float getInclination(float[] I) { 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I.length == 9) { 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (float)Math.atan2(I[5], I[4]); 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13050f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian return (float)Math.atan2(I[6], I[5]); 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 131074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 131174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Rotates the supplied rotation matrix so it is expressed in a different 131274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * coordinate system. This is typically used when an application needs to 131374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * compute the three orientation angles of the device (see 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #getOrientation}) in a different coordinate system. 131574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 13160f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 131774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 131874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * When the rotation matrix is used for drawing (for instance with OpenGL 131974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * ES), it usually <b>doesn't need</b> to be transformed by this function, 132074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * unless the screen is physically rotated, in which case you can use 132174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.view.Display#getRotation() Display.getRotation()} to 132274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * retrieve the current rotation of the screen. Note that because the user 132374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is generally free to rotate their screen, you often should consider the 132474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rotation in deciding the parameters to use here. 132574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 13260f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 132774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 132874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <u>Examples:</u> 132974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 13300f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 133174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 133274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <li>Using the camera (Y axis along the camera's axis) for an augmented 133374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * reality application where the rotation angles are needed:</li> 13340f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 133574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 133674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 133774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <code>remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);</code> 133874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 133974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 13400f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 13415cb70b54156fb305d579a1cc167424c8705bfdf7Dianne Hackborn * <li>Using the device as a mechanical compass when rotation is 134274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.view.Surface#ROTATION_90 Surface.ROTATION_90}:</li> 13430f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 134474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 134574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 134674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <code>remapCoordinateSystem(inR, AXIS_Y, AXIS_MINUS_X, outR);</code> 134774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 134874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 13490f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 135074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Beware of the above example. This call is needed only to account for a 135174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rotation from its natural orientation when calculating the rotation 135274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * angles (see {@link #getOrientation}). If the rotation matrix is also used 135374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * for rendering, it may not need to be transformed, for instance if your 135474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.app.Activity Activity} is running in landscape mode. 135574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 13560f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 135774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 135874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Since the resulting coordinate system is orthonormal, only two axes need 135974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * to be specified. 13600f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 136174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param inR 136274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the rotation matrix to be transformed. Usually it is the matrix 136374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * returned by {@link #getRotationMatrix}. 13640f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 136574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param X 136674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * defines on which world axis and direction the X axis of the device 136774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is mapped. 13680f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 136974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param Y 137074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * defines on which world axis and direction the Y axis of the device 137174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is mapped. 13720f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 137374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param outR 137474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the transformed rotation matrix. inR and outR can be the same 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * array, but it is not recommended for performance reason. 13760f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 137774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> on success. <code>false</code> if the input 137874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * parameters are incorrect, for instance if X and Y define the same 137974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * axis. Or if inR and outR don't have the same length. 13800f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 13810f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getRotationMatrix(float[], float[], float[], float[]) 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean remapCoordinateSystem(float[] inR, int X, int Y, 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] outR) 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inR == outR) { 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float[] temp = mTempMatrix; 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(temp) { 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we don't expect to have a lot of contention 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (remapCoordinateSystemImpl(inR, X, Y, temp)) { 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int size = outR.length; 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<size ; i++) 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[i] = temp[i]; 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return remapCoordinateSystemImpl(inR, X, Y, outR); 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean remapCoordinateSystemImpl(float[] inR, int X, int Y, 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] outR) 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * X and Y define a rotation matrix 'r': 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * r[0] ^ r[1] 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * where the 3rd line is the vector product of the first 2 lines 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int length = outR.length; 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inR.length != length) 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // invalid parameter 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((X & 0x7C)!=0 || (Y & 0x7C)!=0) 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // invalid parameter 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((X & 0x3)==0) || ((Y & 0x3)==0)) 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // no axis specified 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((X & 0x3) == (Y & 0x3)) 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // same axis specified 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Z is "the other" axis, its sign is either +/- sign(X)*sign(Y) 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this can be calculated by exclusive-or'ing X and Y; except for 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the sign inversion (+/-) which is calculated below. 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int Z = X ^ Y; 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // extract the axis (remove the sign), offset in the range 0 to 2. 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int x = (X & 0x3)-1; 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int y = (Y & 0x3)-1; 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int z = (Z & 0x3)-1; 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute the sign of Z (whether it needs to be inverted) 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int axis_y = (z+1)%3; 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int axis_z = (z+2)%3; 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((x^axis_y)|(y^axis_z)) != 0) 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Z ^= 0x80; 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sx = (X>=0x80); 14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sy = (Y>=0x80); 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sz = (Z>=0x80); 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Perform R * r, in avoiding actual muls and adds. 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int rowLength = ((length==16)?4:3); 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j=0 ; j<3 ; j++) { 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int offset = j*rowLength; 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<3 ; i++) { 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x==i) outR[offset+i] = sx ? -inR[offset+0] : inR[offset+0]; 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (y==i) outR[offset+i] = sy ? -inR[offset+1] : inR[offset+1]; 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (z==i) outR[offset+i] = sz ? -inR[offset+2] : inR[offset+2]; 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (length == 16) { 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[3] = outR[7] = outR[11] = outR[12] = outR[13] = outR[14] = 0; 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[15] = 1; 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes the device's orientation based on the rotation matrix. 146574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 146674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * When it returns, the array values is filled with the result: 146774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[0]: <i>azimuth</i>, rotation around the Z axis.</li> 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[1]: <i>pitch</i>, rotation around the X axis.</li> 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[2]: <i>roll</i>, rotation around the Y axis.</li> 147174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 14730f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * <center><img src="../../../images/axis_device.png" 14740f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * alt="Sensors coordinate-system diagram." border="0" /></center> 14750f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * </p> 14760f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * <p> 1477210fc914db37b3cf77ebb3bf75b0b509a1ecb07cMathias Agopian * All three angles above are in <b>radians</b> and <b>positive</b> in the 1478210fc914db37b3cf77ebb3bf75b0b509a1ecb07cMathias Agopian * <b>counter-clockwise</b> direction. 147974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 148074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param R 148174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rotation matrix see {@link #getRotationMatrix}. 14820f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 148374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param values 148474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * an array of 3 floats to hold the result. 14850f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The array values passed as argument. 14870f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 14880f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getRotationMatrix(float[], float[], float[], float[]) 14890f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see GeomagneticField 14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 149174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian public static float[] getOrientation(float[] R, float values[]) { 14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4x4 (length=16) case: 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / R[ 0] R[ 1] R[ 2] 0 \ 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 4] R[ 5] R[ 6] 0 | 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 8] R[ 9] R[10] 0 | 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ 0 0 0 1 / 14980f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3x3 (length=9) case: 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / R[ 0] R[ 1] R[ 2] \ 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 3] R[ 4] R[ 5] | 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ R[ 6] R[ 7] R[ 8] / 15030f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R.length == 9) { 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = (float)Math.atan2(R[1], R[4]); 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = (float)Math.asin(-R[7]); 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = (float)Math.atan2(-R[6], R[8]); 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = (float)Math.atan2(R[1], R[5]); 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = (float)Math.asin(-R[9]); 15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = (float)Math.atan2(-R[8], R[10]); 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return values; 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onRotationChanged(int rotation) { 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sRotation = rotation; 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int getRotation() { 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sRotation; 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class LegacyListener implements SensorEventListener { 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mValues[] = new float[6]; 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SensorListener mTarget; 15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSensors; 15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final LmsFilter mYawfilter = new LmsFilter(); 15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LegacyListener(SensorListener target) { 15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget = target; 15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors = 0; 15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void registerSensor(int legacyType) { 15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors |= legacyType; 15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean unregisterSensor(int legacyType) { 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors &= ~legacyType; 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mask = SENSOR_ORIENTATION|SENSOR_ORIENTATION_RAW; 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((legacyType&mask)!=0) && ((mSensors&mask)!=0)) { 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onAccuracyChanged(Sensor sensor, int accuracy) { 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onAccuracyChanged(sensor.getLegacyType(), accuracy); 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (AbstractMethodError e) { 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // old app that doesn't implement this method 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // just ignore it. 15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onSensorChanged(SensorEvent event) { 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float v[] = mValues; 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[0] = event.values[0]; 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[1] = event.values[1]; 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[2] = event.values[2]; 15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int legacyType = event.sensor.getLegacyType(); 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mapSensorDataToWindow(legacyType, v, SensorManager.getRotation()); 15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) { 15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mSensors & SENSOR_ORIENTATION_RAW)!=0) { 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(SENSOR_ORIENTATION_RAW, v); 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mSensors & SENSOR_ORIENTATION)!=0) { 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[0] = mYawfilter.filter(event.timestamp, v[0]); 15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(SENSOR_ORIENTATION, v); 15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(legacyType, v); 15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Helper function to convert the specified sensor's data to the windows's 15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * coordinate space from the device's coordinate space. 15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * output: 3,4,5: values in the old API format 15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 0,1,2: transformed values in the old API format 15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void mapSensorDataToWindow(int sensor, 15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] values, int orientation) { 16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x = values[0]; 16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = values[1]; 16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float z = values[2]; 16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (sensor) { 16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ORIENTATION: 16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ORIENTATION_RAW: 16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z = -z; 16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ACCELEROMETER: 16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x = -x; 16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y = -y; 16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z = -z; 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_MAGNETIC_FIELD: 16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x = -x; 16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y = -y; 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = x; 16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = y; 16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = z; 16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[3] = x; 16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[4] = y; 16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[5] = z; 16257895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian 16267895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian if ((orientation & Surface.ROTATION_90) != 0) { 16277895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian // handles 90 and 270 rotation 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (sensor) { 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ACCELEROMETER: 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_MAGNETIC_FIELD: 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] =-y; 16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = x; 16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = z; 16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ORIENTATION: 16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ORIENTATION_RAW: 16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = x + ((x < 270) ? 90 : -270); 16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = z; 16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = y; 16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16437895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian if ((orientation & Surface.ROTATION_180) != 0) { 16447895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian x = values[0]; 16457895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian y = values[1]; 16467895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian z = values[2]; 16477895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian // handles 180 (flip) and 270 (flip + 90) rotation 16487895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian switch (sensor) { 16497895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_ACCELEROMETER: 16507895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_MAGNETIC_FIELD: 16517895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[0] =-x; 16527895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[1] =-y; 16537895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[2] = z; 16547895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian break; 16557895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_ORIENTATION: 16567895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_ORIENTATION_RAW: 16577895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[0] = (x >= 180) ? (x - 180) : (x + 180); 16587895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[1] =-y; 16597895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[2] =-z; 16607895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian break; 16617895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian } 16627895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian } 16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16650f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class LmsFilter { 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SENSORS_RATE_MS = 20; 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int COUNT = 12; 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float PREDICTION_RATIO = 1.0f/3.0f; 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float PREDICTION_TIME = (SENSORS_RATE_MS*COUNT/1000.0f)*PREDICTION_RATIO; 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mV[] = new float[COUNT*2]; 16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mT[] = new float[COUNT*2]; 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mIndex; 16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LmsFilter() { 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex = COUNT; 16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float filter(long time, float in) { 16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float v = in; 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float ns = 1.0f / 1000000000.0f; 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float t = time*ns; 16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float v1 = mV[mIndex]; 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((v-v1) > 180) { 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v -= 360; 16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((v1-v) > 180) { 16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v += 360; 16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Manage the circular buffer, we write the data twice spaced 16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by COUNT values, so that we don't have to copy the array 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when it's full 16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex++; 16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIndex >= COUNT*2) 16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex = COUNT; 16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mV[mIndex] = v; 16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mT[mIndex] = t; 16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mV[mIndex-COUNT] = v; 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mT[mIndex-COUNT] = t; 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float A, B, C, D, E; 17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float a, b; 17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A = B = C = D = E = 0; 17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0 ; i<COUNT-1 ; i++) { 17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int j = mIndex - 1 - i; 17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Z = mV[j]; 17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float T = 0.5f*(mT[j] + mT[j+1]) - t; 17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float dT = mT[j] - mT[j+1]; 17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dT *= dT; 17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A += Z*dT; 17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project B += T*(T*dT); 17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project C += (T*dT); 17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project D += Z*(T*dT); 17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project E += dT; 17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = (A*B + C*D) / (E*B + C*C); 17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = (E*b - A) / C; 17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float f = b + PREDICTION_TIME*a; 17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Normalize 17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f *= (1.0f / 360.0f); 17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((f>=0)?f:-f) >= 0.5f) 17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f = f - (float)Math.ceil(f + 0.5f) + 1.0f; 17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f < 0) 17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f += 1.0f; 17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f *= 360.0f; 17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return f; 17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17330f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian 17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void nativeClassInit(); 17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native int sensors_module_init(); 17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native int sensors_module_get_next_sensor(Sensor sensor, int next); 17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Used within this module from outside SensorManager, don't make private 17401bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian static native int sensors_create_queue(); 17411bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian static native void sensors_destroy_queue(int queue); 17421bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian static native boolean sensors_enable_sensor(int queue, String name, int sensor, int enable); 17431bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian static native int sensors_data_poll(int queue, float[] values, int[] status, long[] timestamp); 17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1745