SensorManager.java revision 0871ee0c6f43a7201ce49a66211c1c850eabeb6b
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; 27ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopianimport android.util.SparseBooleanArray; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IRotationWatcher; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IWindowManager; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Surface; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 3843c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * <p> 3974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * SensorManager lets you access the device's {@link android.hardware.Sensor 4074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensors}. Get an instance of this class by calling 4174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.content.Context#getSystemService(java.lang.String) 4274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Context.getSystemService()} with the argument 4374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.content.Context#SENSOR_SERVICE}. 4443c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * </p> 4543c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * <p> 4643c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * Always make sure to disable sensors you don't need, especially when your 4743c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * activity is paused. Failing to do so can drain the battery in just a few 4843c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * hours. Note that the system will <i>not</i> disable sensors automatically when 4943c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * the screen turns off. 5043c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * </p> 510f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 520f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * <pre class="prettyprint"> 530f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * public class SensorActivity extends Activity, implements SensorEventListener { 540f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * private final SensorManager mSensorManager; 550f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * private final Sensor mAccelerometer; 560f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 570f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * public SensorActivity() { 580f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); 590f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 6043c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * } 6143c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * 6243c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * protected void onResume() { 6343c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * super.onResume(); 640f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); 650f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * } 660f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 6743c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * protected void onPause() { 6843c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * super.onPause(); 6943c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * mSensorManager.unregisterListener(this); 7043c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * } 7143c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * 720f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * public void onAccuracyChanged(Sensor sensor, int accuracy) { 730f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * } 740f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 7543c87e44fc0d7d7b37e039752c0dec093e227381Mathias Agopian * public void onSensorChanged(SensorEvent event) { 760f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * } 770f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * } 780f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * </pre> 790f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 800f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see SensorEventListener 810f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see SensorEvent 820f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see Sensor 830f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 85287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopianpublic class SensorManager 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "SensorManager"; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float[] mTempMatrix = new float[16]; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* NOTE: sensor IDs must be a power of 2 */ 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an orientation 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_ORIENTATION = 1 << 0; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an accelerometer. 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_ACCELEROMETER = 1 << 1; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a temperature 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_TEMPERATURE = 1 << 2; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a magnetic 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_MAGNETIC_FIELD = 1 << 3; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an ambient light sensor 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_LIGHT = 1 << 4; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a proximity 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_PROXIMITY = 1 << 5; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a Tricorder See 14874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1490f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_TRICORDER = 1 << 6; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an orientation sensor. See 15774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 1580f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ORIENTATION_RAW = 1 << 7; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 16574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant that includes all sensors 1660f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1674a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1684a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ALL = 0x7F; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 17374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Smallest sensor ID 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 SENSOR_MIN = SENSOR_ORIENTATION; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 18174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Largest sensor ID 1820f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 1834a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1844a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_MAX = ((SENSOR_ALL + 1)>>1); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 19074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the X 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_X = 0; 19774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 19874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 19974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the Y value 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 DATA_Y = 1; 20674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 20774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 20874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the Z 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 DATA_Z = 2; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 21774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Offset to the untransformed values 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_INDEX = 3; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 22674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the untransformed X 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_X = 3; 23374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 23474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 23574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the untransformed Y value in the array returned by 2364a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 2370f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 2384a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 2394a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_Y = 4; 24274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 24374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 24474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the untransformed Z value in the array returned by 2454a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 2460f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 2474a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 2484a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_Z = 5; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Standard gravity (g) on Earth. This value is equivalent to 1G */ 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float STANDARD_GRAVITY = 9.80665f; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Sun's gravity in SI units (m/s^2) */ 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_SUN = 275.0f; 25774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Mercury's gravity in SI units (m/s^2) */ 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MERCURY = 3.70f; 25974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Venus' gravity in SI units (m/s^2) */ 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_VENUS = 8.87f; 26174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Earth's gravity in SI units (m/s^2) */ 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_EARTH = 9.80665f; 26374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** The Moon's gravity in SI units (m/s^2) */ 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MOON = 1.6f; 26574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Mars' gravity in SI units (m/s^2) */ 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MARS = 3.71f; 26774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Jupiter's gravity in SI units (m/s^2) */ 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_JUPITER = 23.12f; 26974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Saturn's gravity in SI units (m/s^2) */ 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_SATURN = 8.96f; 27174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Uranus' gravity in SI units (m/s^2) */ 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_URANUS = 8.69f; 27374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Neptune's gravity in SI units (m/s^2) */ 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_NEPTUNE = 11.0f; 27574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Pluto's gravity in SI units (m/s^2) */ 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_PLUTO = 0.6f; 27774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Gravity (estimate) on the first Death Star in Empire units (m/s^2) */ 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_DEATH_STAR_I = 0.000000353036145f; 27974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Gravity on the island */ 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_THE_ISLAND = 4.815162342f; 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Maximum magnetic field on Earth's surface */ 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float MAGNETIC_FIELD_EARTH_MAX = 60.0f; 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Minimum magnetic field on Earth's surface */ 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float MAGNETIC_FIELD_EARTH_MIN = 30.0f; 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2880f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian 28904d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian /** Standard atmosphere, or average sea-level pressure in hPa (millibar) */ 29004d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian public static final float PRESSURE_STANDARD_ATMOSPHERE = 1013.25f; 29104d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian 29204d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian 29374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Maximum luminance of sunlight in lux */ 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNLIGHT_MAX = 120000.0f; 29574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance of sunlight in lux */ 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNLIGHT = 110000.0f; 29774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance in shade in lux */ 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SHADE = 20000.0f; 29974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance under an overcast sky in lux */ 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_OVERCAST = 10000.0f; 30174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance at sunrise in lux */ 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNRISE = 400.0f; 30374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance under a cloudy sky in lux */ 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_CLOUDY = 100.0f; 30574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance at night with full moon in lux */ 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_FULLMOON = 0.25f; 30774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance at night with no moon in lux*/ 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_NO_MOON = 0.001f; 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3100f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** get sensor data as fast as possible */ 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_FASTEST = 0; 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate suitable for games */ 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_GAME = 1; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate suitable for the user interface */ 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_UI = 2; 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate (default) suitable for screen orientation changes */ 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_NORMAL = 3; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 32274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The values returned by this sensor cannot be trusted, calibration is 32374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * needed or the environment doesn't allow readings 32474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian */ 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_UNRELIABLE = 0; 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 32874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * This sensor is reporting data with low accuracy, calibration with the 32974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * environment is needed 33074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian */ 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_LOW = 1; 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 33374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 33474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * This sensor is reporting data with an average level of accuracy, 33574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * calibration with the environment may improve the readings 33674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian */ 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_MEDIUM = 2; 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** This sensor is reporting data with maximum accuracy */ 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_HIGH = 3; 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_X = 1; 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_Y = 2; 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_Z = 3; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_X = AXIS_X | 0x80; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_Y = AXIS_Y | 0x80; 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_Z = AXIS_Z | 0x80; 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper mMainLooper; 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashMap<SensorListener, LegacyListener> mLegacyListenersMap = 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashMap<SensorListener, LegacyListener>(); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SENSOR_DISABLE = -1; 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean sSensorModuleInitialized = false; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static ArrayList<Sensor> sFullSensorsList = new ArrayList<Sensor>(); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static SparseArray<List<Sensor>> sSensorListByType = new SparseArray<List<Sensor>>(); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static IWindowManager sWindowManager; 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static int sRotation = Surface.ROTATION_0; 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* The thread and the sensor list are global to the process 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but the actual thread is spawned on demand */ 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static SensorThread sSensorThread; 3731bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian private static int sQueue; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Used within this module from outside SensorManager, don't make private 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static SparseArray<Sensor> sHandleToSensor = new SparseArray<Sensor>(); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final ArrayList<ListenerDelegate> sListeners = 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new ArrayList<ListenerDelegate>(); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static private class SensorThread { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Thread mThread; 385b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian boolean mSensorsReady; 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorThread() { 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() { 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // must be called with sListeners lock 3951bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian boolean startLocked() { 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mThread == null) { 3981bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian mSensorsReady = false; 3991bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian SensorThreadRunnable runnable = new SensorThreadRunnable(); 4001bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian Thread thread = new Thread(runnable, SensorThread.class.getName()); 4011bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian thread.start(); 4021bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian synchronized (runnable) { 4031bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian while (mSensorsReady == false) { 4041bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian runnable.wait(); 405b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } 406b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } 4071bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian mThread = thread; 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 409b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } catch (InterruptedException e) { 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 411b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian return mThread == null ? false : true; 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class SensorThreadRunnable implements Runnable { 4151bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian SensorThreadRunnable() { 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 417270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood 418270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood private boolean open() { 419b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian // NOTE: this cannot synchronize on sListeners, since 420b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian // it's held in the main thread at least until we 421b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian // return from here. 4221bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sQueue = sensors_create_queue(); 423270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood return true; 424270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood } 425270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.d(TAG, "entering main sensor thread"); 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float[] values = new float[3]; 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] status = new int[1]; 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long timestamp[] = new long[1]; 431e417158c06c81c8c4dc6794c5421b711e671c7e3Mathias Agopian Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 433270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood if (!open()) { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 437b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian synchronized (this) { 438b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian // we've open the driver, we're ready to open the sensors 439b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian mSensorsReady = true; 440b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian this.notify(); 441b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } 442b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) { 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // wait for an event 4451bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian final int sensor = sensors_data_poll(sQueue, values, status, timestamp); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int accuracy = status[0]; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sListeners) { 4496dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber if (sensor == -1 || sListeners.isEmpty()) { 4504d3cb63b9b9177b79c575ca1b21040cc42ee7879Mathias Agopian // we lost the connection to the event stream. this happens 4514d3cb63b9b9177b79c575ca1b21040cc42ee7879Mathias Agopian // when the last listener is removed or if there is an error 4524d3cb63b9b9177b79c575ca1b21040cc42ee7879Mathias Agopian if (sensor == -1 && !sListeners.isEmpty()) { 4534d3cb63b9b9177b79c575ca1b21040cc42ee7879Mathias Agopian // log a warning in case of abnormal termination 4544d3cb63b9b9177b79c575ca1b21040cc42ee7879Mathias Agopian Log.e(TAG, "_sensors_data_poll() failed, we bail out: sensors=" + sensor); 4556dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber } 4566dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber // we have no more listeners or polling failed, terminate the thread 4571bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sensors_destroy_queue(sQueue); 4581bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sQueue = 0; 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThread = null; 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Sensor sensorObject = sHandleToSensor.get(sensor); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sensorObject != null) { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // report the sensor event to all listeners that 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // care about it. 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int size = sListeners.size(); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<size ; i++) { 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ListenerDelegate listener = sListeners.get(i); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener.hasSensor(sensorObject)) { 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this is asynchronous (okay to call 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sListeners lock held). 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.onSensorChangedLocked(sensorObject, 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values, timestamp, accuracy); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.d(TAG, "exiting main sensor thread"); 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4861bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian private class ListenerDelegate { 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final SensorEventListener mSensorEventListener; 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Sensor> mSensorList = new ArrayList<Sensor>(); 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Handler mHandler; 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SensorEvent mValuesPool; 491ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian public SparseBooleanArray mSensors = new SparseBooleanArray(); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ListenerDelegate(SensorEventListener listener, Sensor sensor, Handler handler) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorEventListener = listener; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper looper = (handler != null) ? handler.getLooper() : mMainLooper; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // currently we create one Handler instance per listener, but we could 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // have one per looper (we'd need to pass the ListenerDelegate 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // instance to handleMessage and keep track of them separately). 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler = new Handler(looper) { 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorEvent t = (SensorEvent)msg.obj; 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.accuracy >= 0) { 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorEventListener.onAccuracyChanged(t.sensor, t.accuracy); 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorEventListener.onSensorChanged(t); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project returnToPool(t); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addSensor(sensor); 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected SensorEvent createSensorEvent() { 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // maximal size for all legacy events is 3 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new SensorEvent(3); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected SensorEvent getFromPool() { 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorEvent t = null; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // remove the array from the pool 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t = mValuesPool; 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mValuesPool = null; 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t == null) { 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the pool was empty, we need a new one 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t = createSensorEvent(); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return t; 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void returnToPool(SensorEvent t) { 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // put back the array into the pool 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mValuesPool == null) { 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mValuesPool = t; 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object getListener() { 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSensorEventListener; 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 545ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian void addSensor(Sensor sensor) { 546ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian mSensors.put(sensor.getHandle(), true); 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorList.add(sensor); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int removeSensor(Sensor sensor) { 550ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian mSensors.delete(sensor.getHandle()); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorList.remove(sensor); 552ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian return mSensors.size(); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hasSensor(Sensor sensor) { 555ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian return mSensors.get(sensor.getHandle()); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Sensor> getSensors() { 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSensorList; 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onSensorChangedLocked(Sensor sensor, float[] values, long[] timestamp, int accuracy) { 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorEvent t = getFromPool(); 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float[] v = t.values; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[0] = values[0]; 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[1] = values[1]; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[2] = values[2]; 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.timestamp = timestamp[0]; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.accuracy = accuracy; 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.sensor = sensor; 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = Message.obtain(); 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.what = 0; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.obj = t; 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendMessage(msg); 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SensorManager(Looper mainLooper) { 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMainLooper = mainLooper; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!sSensorModuleInitialized) { 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sSensorModuleInitialized = true; 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativeClassInit(); 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowManager = IWindowManager.Stub.asInterface( 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ServiceManager.getService("window")); 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sWindowManager != null) { 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if it's null we're running in the system process 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // which won't get the rotated values 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 596287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian sRotation = sWindowManager.watchRotation( 59704d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian new IRotationWatcher.Stub() { 59804d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian public void onRotationChanged(int rotation) { 59904d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian SensorManager.this.onRotationChanged(rotation); 60004d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian } 601287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian } 602287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian ); 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // initialize the sensor list 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensors_module_init(); 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<Sensor> fullList = sFullSensorsList; 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i = 0; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Sensor sensor = new Sensor(); 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = sensors_module_get_next_sensor(sensor, i); 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i>=0) { 616f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato //Log.d(TAG, "found sensor: " + sensor.getName() + 617f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato // ", handle=" + sensor.getHandle()); 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensor.setLegacyType(getLegacySensorType(sensor.getType())); 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fullList.add(sensor); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sHandleToSensor.append(sensor.getHandle(), sensor); 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (i>0); 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sSensorThread = new SensorThread(); 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int getLegacySensorType(int type) { 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (type) { 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ACCELEROMETER: 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_ACCELEROMETER; 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_MAGNETIC_FIELD: 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_MAGNETIC_FIELD; 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ORIENTATION: 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_ORIENTATION_RAW; 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_TEMPERATURE: 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_TEMPERATURE; 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 64374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 64474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return available sensors. 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 64674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#getSensorList(int)} instead 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getSensors() { 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = 0; 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<Sensor> fullList = sFullSensorsList; 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Sensor i : fullList) { 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (i.getType()) { 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ACCELEROMETER: 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_ACCELEROMETER; 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_MAGNETIC_FIELD: 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_MAGNETIC_FIELD; 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ORIENTATION: 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_ORIENTATION | 66204d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian SensorManager.SENSOR_ORIENTATION_RAW; 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 67074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Use this method to get the list of available sensors of a certain type. 67174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Make multiple calls to get sensors of different types or use 67274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor#TYPE_ALL Sensor.TYPE_ALL} to get all the 67374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensors. 6740f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 67574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param type 67674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * of sensors requested 6770f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a list of sensors matching the asked type. 6790f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 6800f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getDefaultSensor(int) 6810f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see Sensor 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<Sensor> getSensorList(int type) { 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cache the returned lists the first time 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Sensor> list; 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<Sensor> fullList = sFullSensorsList; 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(fullList) { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = sSensorListByType.get(type); 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (list == null) { 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == Sensor.TYPE_ALL) { 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = fullList; 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = new ArrayList<Sensor>(); 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Sensor i : fullList) { 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i.getType() == type) 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list.add(i); 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = Collections.unmodifiableList(list); 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sSensorListByType.append(type, list); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return list; 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 70774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Use this method to get the default sensor for a given type. Note that the 70874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * returned sensor could be a composite sensor, and its data could be 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * averaged or filtered. If you need to access the raw sensors use 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SensorManager#getSensorList(int) getSensorList}. 7110f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 71274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param type 71374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * of sensors requested 7140f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the default sensors matching the asked type. 7160f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 7170f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getSensorList(int) 7180f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see Sensor 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Sensor getDefaultSensor(int type) { 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: need to be smarter, for now, just return the 1st sensor 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Sensor> l = getSensorList(type); 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return l.isEmpty() ? null : l.get(0); 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Registers a listener 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 * @return <code>true</code> if the sensor is supported and successfully 74074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * enabled 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorListener listener, int sensors) { 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return registerListener(listener, sensors, SENSOR_DELAY_NORMAL); 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Registers a SensorListener for given sensors. 7490f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 75174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#registerListener(SensorEventListener, Sensor, int)} 75274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 7530f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 75474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 75574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensor listener object 7560f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 75774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensors 75874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a bit masks of the sensors to register to 7590f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 76074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param rate 76174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rate of events. This is only a hint to the system. events may be 76274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * received faster or slower than the specified rate. Usually events 76374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * are received faster. The value must be one of 76474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI}, 76574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}. 7660f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 76774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> if the sensor is supported and successfully 76874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * enabled 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorListener listener, int sensors, int rate) { 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 result = registerLegacyListener(SENSOR_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER, 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_MAGNETIC_FIELD, Sensor.TYPE_MAGNETIC_FIELD, 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_ORIENTATION_RAW, Sensor.TYPE_ORIENTATION, 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_ORIENTATION, Sensor.TYPE_ORIENTATION, 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_TEMPERATURE, Sensor.TYPE_TEMPERATURE, 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean registerLegacyListener(int legacyType, int type, 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorListener listener, int sensors, int rate) 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result = false; 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Are we activating this legacy sensor? 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((sensors & legacyType) != 0) { 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if so, find a suitable Sensor 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Sensor sensor = getDefaultSensor(type); 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sensor != null) { 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we don't already have one, create a LegacyListener 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to wrap this listener and process the events as 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // they are expected by legacy apps. 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LegacyListener legacyListener = null; 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLegacyListenersMap) { 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener = mLegacyListenersMap.get(listener); 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (legacyListener == null) { 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we didn't find a LegacyListener for this client, 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // create one, and put it in our list. 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener = new LegacyListener(listener); 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLegacyListenersMap.put(listener, legacyListener); 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // register this legacy sensor with this legacy listener 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener.registerSensor(legacyType); 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and finally, register the legacy listener with the new apis 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerListener(legacyListener, sensor, rate); 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for the sensors with which it is registered. 8260f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 82874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#unregisterListener(SensorEventListener, Sensor)} 82974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 8300f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 83174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 83274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorListener object 8330f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 83474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensors 83574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a bit masks of the sensors to unregister from 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorListener listener, int sensors) { 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER, 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_MAGNETIC_FIELD, Sensor.TYPE_MAGNETIC_FIELD, 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ORIENTATION_RAW, Sensor.TYPE_ORIENTATION, 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ORIENTATION, Sensor.TYPE_ORIENTATION, 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_TEMPERATURE, Sensor.TYPE_TEMPERATURE, 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void unregisterLegacyListener(int legacyType, int type, 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorListener listener, int sensors) 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // do we know about this listener? 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LegacyListener legacyListener = null; 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLegacyListenersMap) { 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener = mLegacyListenersMap.get(listener); 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (legacyListener != null) { 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Are we deactivating this legacy sensor? 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((sensors & legacyType) != 0) { 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if so, find the corresponding Sensor 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Sensor sensor = getDefaultSensor(type); 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sensor != null) { 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // unregister this legacy sensor and if we don't 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // need the corresponding Sensor, unregister it too 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (legacyListener.unregisterSensor(legacyType)) { 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // corresponding sensor not needed, unregister 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener(legacyListener, sensor); 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // finally check if we still need the legacyListener 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in our mapping, if not, get rid of it too. 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean found = false; 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ListenerDelegate i : sListeners) { 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i.getListener() == legacyListener) { 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project found = true; 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!found) { 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLegacyListenersMap) { 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLegacyListenersMap.remove(listener); 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for all sensors. 8980f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 90074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#unregisterListener(SensorEventListener)} 90174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 9020f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 90374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 90474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorListener object 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorListener listener) { 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener(listener, SENSOR_ALL | SENSOR_ORIENTATION_RAW); 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for the sensors with which it is registered. 9130f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 91474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 91574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorEventListener object 9160f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 91774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensor 91874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the sensor to unregister from 9190f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9200f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener) 9210f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #registerListener(SensorEventListener, Sensor, int) 9220f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorEventListener listener, Sensor sensor) { 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener((Object)listener, sensor); 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for all sensors. 9300f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 93174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 93274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorListener object 9330f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9340f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener, Sensor) 9350f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #registerListener(SensorEventListener, Sensor, int) 9360f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorEventListener listener) { 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener((Object)listener); 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 94374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Registers a {@link android.hardware.SensorEventListener 94474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * SensorEventListener} for the given sensor. 9450f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 94674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 94774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A {@link android.hardware.SensorEventListener SensorEventListener} 94874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * object. 9490f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 95074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensor 95174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The {@link android.hardware.Sensor Sensor} to register to. 9520f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 95374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param rate 95474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The rate {@link android.hardware.SensorEvent sensor events} are 95574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * delivered at. This is only a hint to the system. Events may be 95674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * received faster or slower than the specified rate. Usually events 95774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * are received faster. The value must be one of 95874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI}, 959050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST} 960050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian * or, the desired delay between events in microsecond. 9610f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 96274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> if the sensor is supported and successfully 96374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * enabled. 9640f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9650f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #registerListener(SensorEventListener, Sensor, int, Handler) 9660f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener) 9670f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener, Sensor) 9680f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) { 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return registerListener(listener, sensor, rate, null); 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 974ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian private boolean enableSensorLocked(Sensor sensor, int delay) { 975ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian boolean result = false; 976ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian for (ListenerDelegate i : sListeners) { 977ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian if (i.hasSensor(sensor)) { 978ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian String name = sensor.getName(); 979ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian int handle = sensor.getHandle(); 980ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian result = sensors_enable_sensor(sQueue, name, handle, delay); 981ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian break; 982ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian } 983ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian } 984ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian return result; 985ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian } 986ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian 987ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian private boolean disableSensorLocked(Sensor sensor) { 988ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian for (ListenerDelegate i : sListeners) { 989ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian if (i.hasSensor(sensor)) { 990ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian // not an error, it's just that this sensor is still in use 991ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian return true; 992ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian } 993ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian } 994ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian String name = sensor.getName(); 995ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian int handle = sensor.getHandle(); 996ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian return sensors_enable_sensor(sQueue, name, handle, SENSOR_DISABLE); 997ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian } 998ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 100074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Registers a {@link android.hardware.SensorEventListener 100174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * SensorEventListener} for the given sensor. 10020f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 100374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 100474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A {@link android.hardware.SensorEventListener SensorEventListener} 100574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * object. 10060f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 100774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensor 100874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The {@link android.hardware.Sensor Sensor} to register to. 10090f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 101074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param rate 101174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The rate {@link android.hardware.SensorEvent sensor events} are 101274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * delivered at. This is only a hint to the system. Events may be 101374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * received faster or slower than the specified rate. Usually events 101474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * are received faster. The value must be one of 101574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI}, 101674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}. 1017050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian * or, the desired delay between events in microsecond. 10180f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 101974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param handler 102074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The {@link android.os.Handler Handler} the 102174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent sensor events} will be 102274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * delivered to. 10230f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the sensor is supported and successfully enabled. 10250f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 10260f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #registerListener(SensorEventListener, Sensor, int) 10270f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener) 10280f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #unregisterListener(SensorEventListener, Sensor) 10290f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate, 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Handler handler) { 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null || sensor == null) { 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1036ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian boolean result = true; 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int delay = -1; 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (rate) { 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_FASTEST: 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delay = 0; 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_GAME: 1043050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian delay = 20000; 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_UI: 1046050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian delay = 60000; 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_NORMAL: 1049050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian delay = 200000; 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 1052050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian delay = rate; 1053050b56244ff46d43e4886018d7cd20f0b1dc02b9Mathias Agopian break; 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10561bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian synchronized (sListeners) { 1057ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian // look for this listener in our list 10581bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian ListenerDelegate l = null; 10591bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian for (ListenerDelegate i : sListeners) { 10601bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian if (i.getListener() == listener) { 10611bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian l = i; 10621bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian break; 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10641bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian } 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1066ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian // if we don't find it, add it to the list 10671bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian if (l == null) { 10681bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian l = new ListenerDelegate(listener, sensor, handler); 10691bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sListeners.add(l); 1070ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian // if the list is not empty, start our main thread 10711bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian if (!sListeners.isEmpty()) { 1072ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian if (sSensorThread.startLocked()) { 1073ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian if (!enableSensorLocked(sensor, delay)) { 1074ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian // oops. there was an error 10751bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sListeners.remove(l); 1076ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian result = false; 10771bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian } 1078ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian } else { 1079ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian // there was an error, remove the listener 1080ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian sListeners.remove(l); 1081ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian result = false; 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1083ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian } else { 1084ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian // weird, we couldn't add the listener 1085ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian result = false; 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10871bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian } else { 1088ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian l.addSensor(sensor); 1089ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian if (!enableSensorLocked(sensor, delay)) { 1090ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian // oops. there was an error 1091ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian l.removeSensor(sensor); 1092ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian result = false; 10931bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian } 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1096ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void unregisterListener(Object listener, Sensor sensor) { 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null || sensor == null) { 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11044d3cb63b9b9177b79c575ca1b21040cc42ee7879Mathias Agopian 11051bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian synchronized (sListeners) { 11061bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian final int size = sListeners.size(); 11071bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian for (int i=0 ; i<size ; i++) { 11081bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian ListenerDelegate l = sListeners.get(i); 11091bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian if (l.getListener() == listener) { 11101bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian if (l.removeSensor(sensor) == 0) { 1111ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian // if we have no more sensors enabled on this listener, 1112ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian // take it off the list. 11131bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian sListeners.remove(i); 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11151bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian break; 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1118ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian disableSensorLocked(sensor); 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void unregisterListener(Object listener) { 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11264d3cb63b9b9177b79c575ca1b21040cc42ee7879Mathias Agopian 11271bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian synchronized (sListeners) { 11281bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian final int size = sListeners.size(); 11291bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian for (int i=0 ; i<size ; i++) { 11301bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian ListenerDelegate l = sListeners.get(i); 11311bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian if (l.getListener() == listener) { 1132ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian sListeners.remove(i); 11331bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian // disable all sensors for this listener 11341bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian for (Sensor sensor : l.getSensors()) { 1135ec33b82c42f3dd996a72b80359c87524b51ffb2aMathias Agopian disableSensorLocked(sensor); 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11371bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian break; 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 114474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 114574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Computes the inclination matrix <b>I</b> as well as the rotation matrix 114674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>R</b> transforming a vector from the device coordinate system to the 114774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * world's coordinate system which is defined as a direct orthonormal basis, 114874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * where: 114974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 11500f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 115174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the ground at the device's current location and roughly points East).</li> 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Y is tangential to the ground at the device's current location and 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * points towards the magnetic North Pole.</li> 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Z points towards the sky and is perpendicular to the ground.</li> 115774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 11580f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 11590f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * <p> 11600f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * <center><img src="../../../images/axis_globe.png" 1161f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * alt="World coordinate-system diagram." border="0" /></center> 11620f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * </p> 11630f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 116674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 116774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * By definition: 116874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 116974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * [0 0 g] = <b>R</b> * <b>gravity</b> (g = magnitude of gravity) 117074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 117174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * [0 m 0] = <b>I</b> * <b>R</b> * <b>geomagnetic</b> (m = magnitude of 117274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * geomagnetic field) 117374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 117474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>R</b> is the identity matrix when the device is aligned with the 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * world's coordinate system, that is, when the device's X axis points 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * toward East, the Y axis points to the North Pole and the device is facing 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the sky. 11780f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 117974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 118074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>I</b> is a rotation matrix transforming the geomagnetic vector into 118174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the same coordinate space as gravity (the world's coordinate space). 118274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>I</b> is a simple rotation around the X axis. The inclination angle in 118374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * radians can be computed with {@link #getInclination}. 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 11850f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 118674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 118774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Each matrix is returned either as a 3x3 or 4x4 row-major matrix depending 118874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * on the length of the passed array: 118974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 119074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <u>If the array length is 16:</u> 11910f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] M[ 3] \ 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 4] M[ 5] M[ 6] M[ 7] | 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 8] M[ 9] M[10] M[11] | 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ M[12] M[13] M[14] M[15] / 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 11980f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 119974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * This matrix is ready to be used by OpenGL ES's 120074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link javax.microedition.khronos.opengles.GL10#glLoadMatrixf(float[], int) 120174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * glLoadMatrixf(float[], int)}. 120274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 120374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Note that because OpenGL matrices are column-major matrices you must 120474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * transpose the matrix before using it. However, since the matrix is a 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rotation matrix, its transpose is also its inverse, conveniently, it is 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * often the inverse of the rotation that is needed for rendering; it can 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * therefore be used with OpenGL ES directly. 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Also note that the returned matrices always have this form: 12100f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] 0 \ 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 4] M[ 5] M[ 6] 0 | 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 8] M[ 9] M[10] 0 | 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ 0 0 0 1 / 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 12170f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 121874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 121974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <u>If the array length is 9:</u> 12200f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] \ 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 3] M[ 4] M[ 5] | 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ M[ 6] M[ 7] M[ 8] / 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 12260f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 122874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 122974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The inverse of each matrix can be computed easily by taking its 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * transpose. 12310f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 123274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 123374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The matrices returned by this function are meaningful only when the 123474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * device is not free-falling and it is not close to the magnetic north. If 123574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the device is accelerating, or placed into a strong magnetic field, the 123674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * returned matrices may be inaccurate. 12370f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 123874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param R 123974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 9 floats holding the rotation matrix <b>R</b> when 124074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * this function returns. R can be null. 124174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 12420f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 124374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param I 124474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 9 floats holding the rotation matrix <b>I</b> when 124574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * this function returns. I can be null. 124674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 12470f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 124874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param gravity 124974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 3 floats containing the gravity vector expressed in 125074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the device's coordinate. You can simply use the 125174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent#values values} returned by a 125274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent SensorEvent} of a 125374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor Sensor} of type 125474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor#TYPE_ACCELEROMETER 125574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * TYPE_ACCELEROMETER}. 125674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 12570f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 125874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param geomagnetic 125974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 3 floats containing the geomagnetic vector 126074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * expressed in the device's coordinate. You can simply use the 126174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent#values values} returned by a 126274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent SensorEvent} of a 126374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor Sensor} of type 126474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD 126574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * TYPE_MAGNETIC_FIELD}. 12660f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 126774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> on success, <code>false</code> on failure (for 126874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instance, if the device is in free fall). On failure the output 126974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * matrices are not modified. 12700f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 12710f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getInclination(float[]) 12720f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getOrientation(float[], float[]) 12730f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #remapCoordinateSystem(float[], int, int, float[]) 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean getRotationMatrix(float[] R, float[] I, 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] gravity, float[] geomagnetic) { 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: move this to native code for efficiency 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Ax = gravity[0]; 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Ay = gravity[1]; 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Az = gravity[2]; 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ex = geomagnetic[0]; 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ey = geomagnetic[1]; 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ez = geomagnetic[2]; 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hx = Ey*Az - Ez*Ay; 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hy = Ez*Ax - Ex*Az; 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hz = Ex*Ay - Ey*Ax; 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz); 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (normH < 0.1f) { 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // device is close to free fall (or in space?), or close to 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // magnetic north pole. Typical values are > 100. 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invH = 1.0f / normH; 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hx *= invH; 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hy *= invH; 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hz *= invH; 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invA = 1.0f / (float)Math.sqrt(Ax*Ax + Ay*Ay + Az*Az); 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Ax *= invA; 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Ay *= invA; 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Az *= invA; 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Mx = Ay*Hz - Az*Hy; 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float My = Az*Hx - Ax*Hz; 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Mz = Ax*Hy - Ay*Hx; 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R != null) { 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R.length == 9) { 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[0] = Hx; R[1] = Hy; R[2] = Hz; 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[3] = Mx; R[4] = My; R[5] = Mz; 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[6] = Ax; R[7] = Ay; R[8] = Az; 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (R.length == 16) { 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[0] = Hx; R[1] = Hy; R[2] = Hz; R[3] = 0; 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[4] = Mx; R[5] = My; R[6] = Mz; R[7] = 0; 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[8] = Ax; R[9] = Ay; R[10] = Az; R[11] = 0; 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[12] = 0; R[13] = 0; R[14] = 0; R[15] = 1; 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I != null) { 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute the inclination matrix by projecting the geomagnetic 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // vector onto the Z (gravity) and X (horizontal component 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // of geomagnetic vector) axes. 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invE = 1.0f / (float)Math.sqrt(Ex*Ex + Ey*Ey + Ez*Ez); 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float c = (Ex*Mx + Ey*My + Ez*Mz) * invE; 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float s = (Ex*Ax + Ey*Ay + Ez*Az) * invE; 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I.length == 9) { 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[0] = 1; I[1] = 0; I[2] = 0; 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[3] = 0; I[4] = c; I[5] = s; 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[6] = 0; I[7] =-s; I[8] = c; 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (I.length == 16) { 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[0] = 1; I[1] = 0; I[2] = 0; 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[4] = 0; I[5] = c; I[6] = s; 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[8] = 0; I[9] =-s; I[10]= c; 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[3] = I[7] = I[11] = I[12] = I[13] = I[14] = 0; 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[15] = 1; 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes the geomagnetic inclination angle in radians from the 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * inclination matrix <b>I</b> returned by {@link #getRotationMatrix}. 13420f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 134374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param I 134474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * inclination matrix see {@link #getRotationMatrix}. 13450f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The geomagnetic inclination angle in radians. 13470f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 13480f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getRotationMatrix(float[], float[], float[], float[]) 13490f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getOrientation(float[], float[]) 13500f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see GeomagneticField 13510f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static float getInclination(float[] I) { 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I.length == 9) { 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (float)Math.atan2(I[5], I[4]); 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13570f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian return (float)Math.atan2(I[6], I[5]); 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 136274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 136374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Rotates the supplied rotation matrix so it is expressed in a different 136474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * coordinate system. This is typically used when an application needs to 136574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * compute the three orientation angles of the device (see 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #getOrientation}) in a different coordinate system. 136774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 13680f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 136974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 137074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * When the rotation matrix is used for drawing (for instance with OpenGL 137174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * ES), it usually <b>doesn't need</b> to be transformed by this function, 137274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * unless the screen is physically rotated, in which case you can use 137374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.view.Display#getRotation() Display.getRotation()} to 137474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * retrieve the current rotation of the screen. Note that because the user 137574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is generally free to rotate their screen, you often should consider the 137674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rotation in deciding the parameters to use here. 137774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 13780f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 137974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 138074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <u>Examples:</u> 138174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 13820f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 138374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 138474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <li>Using the camera (Y axis along the camera's axis) for an augmented 138574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * reality application where the rotation angles are needed:</li> 13860f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 138774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 138874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 138974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <code>remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);</code> 139074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 139174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 13920f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 13935cb70b54156fb305d579a1cc167424c8705bfdf7Dianne Hackborn * <li>Using the device as a mechanical compass when rotation is 139474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.view.Surface#ROTATION_90 Surface.ROTATION_90}:</li> 13950f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 139674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 139774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 139874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <code>remapCoordinateSystem(inR, AXIS_Y, AXIS_MINUS_X, outR);</code> 139974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 140074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 14010f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 140274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Beware of the above example. This call is needed only to account for a 140374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rotation from its natural orientation when calculating the rotation 140474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * angles (see {@link #getOrientation}). If the rotation matrix is also used 140574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * for rendering, it may not need to be transformed, for instance if your 140674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.app.Activity Activity} is running in landscape mode. 140774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 14080f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 140974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 141074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Since the resulting coordinate system is orthonormal, only two axes need 141174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * to be specified. 14120f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 141374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param inR 141474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the rotation matrix to be transformed. Usually it is the matrix 141574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * returned by {@link #getRotationMatrix}. 14160f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 141774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param X 141874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * defines on which world axis and direction the X axis of the device 141974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is mapped. 14200f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 142174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param Y 142274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * defines on which world axis and direction the Y axis of the device 142374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is mapped. 14240f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 142574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param outR 142674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the transformed rotation matrix. inR and outR can be the same 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * array, but it is not recommended for performance reason. 14280f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 142974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> on success. <code>false</code> if the input 143074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * parameters are incorrect, for instance if X and Y define the same 143174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * axis. Or if inR and outR don't have the same length. 14320f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 14330f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getRotationMatrix(float[], float[], float[], float[]) 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean remapCoordinateSystem(float[] inR, int X, int Y, 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] outR) 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inR == outR) { 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float[] temp = mTempMatrix; 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(temp) { 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we don't expect to have a lot of contention 14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (remapCoordinateSystemImpl(inR, X, Y, temp)) { 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int size = outR.length; 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<size ; i++) 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[i] = temp[i]; 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return remapCoordinateSystemImpl(inR, X, Y, outR); 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean remapCoordinateSystemImpl(float[] inR, int X, int Y, 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] outR) 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * X and Y define a rotation matrix 'r': 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * r[0] ^ r[1] 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * where the 3rd line is the vector product of the first 2 lines 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int length = outR.length; 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inR.length != length) 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // invalid parameter 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((X & 0x7C)!=0 || (Y & 0x7C)!=0) 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // invalid parameter 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((X & 0x3)==0) || ((Y & 0x3)==0)) 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // no axis specified 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((X & 0x3) == (Y & 0x3)) 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // same axis specified 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Z is "the other" axis, its sign is either +/- sign(X)*sign(Y) 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this can be calculated by exclusive-or'ing X and Y; except for 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the sign inversion (+/-) which is calculated below. 14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int Z = X ^ Y; 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // extract the axis (remove the sign), offset in the range 0 to 2. 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int x = (X & 0x3)-1; 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int y = (Y & 0x3)-1; 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int z = (Z & 0x3)-1; 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute the sign of Z (whether it needs to be inverted) 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int axis_y = (z+1)%3; 14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int axis_z = (z+2)%3; 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((x^axis_y)|(y^axis_z)) != 0) 14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Z ^= 0x80; 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sx = (X>=0x80); 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sy = (Y>=0x80); 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sz = (Z>=0x80); 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Perform R * r, in avoiding actual muls and adds. 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int rowLength = ((length==16)?4:3); 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j=0 ; j<3 ; j++) { 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int offset = j*rowLength; 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<3 ; i++) { 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x==i) outR[offset+i] = sx ? -inR[offset+0] : inR[offset+0]; 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (y==i) outR[offset+i] = sy ? -inR[offset+1] : inR[offset+1]; 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (z==i) outR[offset+i] = sz ? -inR[offset+2] : inR[offset+2]; 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (length == 16) { 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[3] = outR[7] = outR[11] = outR[12] = outR[13] = outR[14] = 0; 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[15] = 1; 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes the device's orientation based on the rotation matrix. 151774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 151874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * When it returns, the array values is filled with the result: 151974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[0]: <i>azimuth</i>, rotation around the Z axis.</li> 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[1]: <i>pitch</i>, rotation around the X axis.</li> 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[2]: <i>roll</i>, rotation around the Y axis.</li> 152374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 1524f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * <p>The reference coordinate-system used is different from the world 1525f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * coordinate-system defined for the rotation matrix:</p> 1526f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * <ul> 1527f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to 1528f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * the ground at the device's current location and roughly points West).</li> 1529f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * <li>Y is tangential to the ground at the device's current location and 1530f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * points towards the magnetic North Pole.</li> 1531f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * <li>Z points towards the center of the Earth and is perpendicular to the ground.</li> 1532f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * </ul> 1533f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 15350871ee0c6f43a7201ce49a66211c1c850eabeb6bDirk Dougherty * <center><img src="../../../images/axis_globe_inverted.png" 1536f71384cd6141c50f589178d309db3ceeb848fb30Mathias Agopian * alt="Inverted world coordinate-system diagram." border="0" /></center> 15370f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * </p> 15380f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * <p> 1539210fc914db37b3cf77ebb3bf75b0b509a1ecb07cMathias Agopian * All three angles above are in <b>radians</b> and <b>positive</b> in the 1540210fc914db37b3cf77ebb3bf75b0b509a1ecb07cMathias Agopian * <b>counter-clockwise</b> direction. 154174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 154274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param R 154374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rotation matrix see {@link #getRotationMatrix}. 15440f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 154574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param values 154674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * an array of 3 floats to hold the result. 15470f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The array values passed as argument. 15490f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 15500f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see #getRotationMatrix(float[], float[], float[], float[]) 15510f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * @see GeomagneticField 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 155304d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian public static float[] getOrientation(float[] R, float values[]) { 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4x4 (length=16) case: 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / R[ 0] R[ 1] R[ 2] 0 \ 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 4] R[ 5] R[ 6] 0 | 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 8] R[ 9] R[10] 0 | 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ 0 0 0 1 / 15600f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3x3 (length=9) case: 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / R[ 0] R[ 1] R[ 2] \ 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 3] R[ 4] R[ 5] | 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ R[ 6] R[ 7] R[ 8] / 15650f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian * 15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R.length == 9) { 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = (float)Math.atan2(R[1], R[4]); 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = (float)Math.asin(-R[7]); 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = (float)Math.atan2(-R[6], R[8]); 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = (float)Math.atan2(R[1], R[5]); 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = (float)Math.asin(-R[9]); 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = (float)Math.atan2(-R[8], R[10]); 15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return values; 15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 158004d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * Computes the Altitude in meters from the atmospheric pressure and the 158104d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * pressure at sea level. 158204d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * <p> 158304d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * Typically the atmospheric pressure is read from a 158404d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * {@link Sensor#TYPE_PRESSURE} sensor. The pressure at sea level must be 158504d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * known, usually it can be retrieved from airport databases in the 1586a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * vicinity. If unknown, you can use {@link #PRESSURE_STANDARD_ATMOSPHERE} 1587a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * as an approximation, but absolute altitudes won't be accurate. 1588a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * </p> 1589a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * <p> 1590a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * To calculate altitude differences, you must calculate the difference 1591a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * between the altitudes at both points. If you don't know the altitude 1592a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * as sea level, you can use {@link #PRESSURE_STANDARD_ATMOSPHERE} instead, 1593a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * which will give good results considering the range of pressure typically 1594a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * involved. 1595a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * </p> 1596a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * <p> 1597a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * <code><ul> 1598a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * float altitude_difference = 1599a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, pressure_at_point2) 1600a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * - getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE, pressure_at_point1); 1601a6704d39b31417dc674d3866f43dad4ce3f850b1Mathias Agopian * </ul></code> 160204d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * </p> 160304d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * 160404d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * @param p0 pressure at sea level 160504d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * @param p atmospheric pressure 160604d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian * @return Altitude in meters 160704d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian */ 160804d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian public static float getAltitude(float p0, float p) { 160904d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian final float coef = 1.0f / 5.255f; 161004d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian return 44330.0f * (1.0f - (float)Math.pow(p/p0, coef)); 161104d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian } 161204d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian 161304d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian 161404d7e83e65e246e154b5b346e3eb0081b741ae88Mathias Agopian /** 16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onRotationChanged(int rotation) { 16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sRotation = rotation; 16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int getRotation() { 16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sRotation; 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class LegacyListener implements SensorEventListener { 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mValues[] = new float[6]; 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SensorListener mTarget; 16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSensors; 16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final LmsFilter mYawfilter = new LmsFilter(); 16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LegacyListener(SensorListener target) { 16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget = target; 16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors = 0; 16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void registerSensor(int legacyType) { 16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors |= legacyType; 16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean unregisterSensor(int legacyType) { 16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors &= ~legacyType; 16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mask = SENSOR_ORIENTATION|SENSOR_ORIENTATION_RAW; 16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((legacyType&mask)!=0) && ((mSensors&mask)!=0)) { 16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onAccuracyChanged(Sensor sensor, int accuracy) { 16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onAccuracyChanged(sensor.getLegacyType(), accuracy); 16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (AbstractMethodError e) { 16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // old app that doesn't implement this method 16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // just ignore it. 16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onSensorChanged(SensorEvent event) { 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float v[] = mValues; 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[0] = event.values[0]; 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[1] = event.values[1]; 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[2] = event.values[2]; 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int legacyType = event.sensor.getLegacyType(); 16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mapSensorDataToWindow(legacyType, v, SensorManager.getRotation()); 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) { 16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mSensors & SENSOR_ORIENTATION_RAW)!=0) { 16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(SENSOR_ORIENTATION_RAW, v); 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mSensors & SENSOR_ORIENTATION)!=0) { 16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[0] = mYawfilter.filter(event.timestamp, v[0]); 16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(SENSOR_ORIENTATION, v); 16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(legacyType, v); 16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Helper function to convert the specified sensor's data to the windows's 16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * coordinate space from the device's coordinate space. 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * output: 3,4,5: values in the old API format 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 0,1,2: transformed values in the old API format 16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void mapSensorDataToWindow(int sensor, 16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] values, int orientation) { 16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x = values[0]; 16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = values[1]; 16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float z = values[2]; 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (sensor) { 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ORIENTATION: 17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ORIENTATION_RAW: 17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z = -z; 17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ACCELEROMETER: 17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x = -x; 17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y = -y; 17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z = -z; 17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_MAGNETIC_FIELD: 17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x = -x; 17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y = -y; 17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = x; 17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = y; 17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = z; 17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[3] = x; 17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[4] = y; 17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[5] = z; 17217895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian 17227895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian if ((orientation & Surface.ROTATION_90) != 0) { 17237895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian // handles 90 and 270 rotation 17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (sensor) { 17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ACCELEROMETER: 17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_MAGNETIC_FIELD: 17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] =-y; 17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = x; 17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = z; 17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ORIENTATION: 17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ORIENTATION_RAW: 17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = x + ((x < 270) ? 90 : -270); 17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = z; 17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = y; 17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17397895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian if ((orientation & Surface.ROTATION_180) != 0) { 17407895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian x = values[0]; 17417895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian y = values[1]; 17427895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian z = values[2]; 17437895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian // handles 180 (flip) and 270 (flip + 90) rotation 17447895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian switch (sensor) { 17457895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_ACCELEROMETER: 17467895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_MAGNETIC_FIELD: 17477895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[0] =-x; 17487895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[1] =-y; 17497895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[2] = z; 17507895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian break; 17517895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_ORIENTATION: 17527895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_ORIENTATION_RAW: 17537895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[0] = (x >= 180) ? (x - 180) : (x + 180); 17547895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[1] =-y; 17557895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[2] =-z; 17567895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian break; 17577895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian } 17587895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian } 17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17610f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian 17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class LmsFilter { 17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SENSORS_RATE_MS = 20; 17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int COUNT = 12; 17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float PREDICTION_RATIO = 1.0f/3.0f; 17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float PREDICTION_TIME = (SENSORS_RATE_MS*COUNT/1000.0f)*PREDICTION_RATIO; 17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mV[] = new float[COUNT*2]; 17689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mT[] = new float[COUNT*2]; 17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mIndex; 17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LmsFilter() { 17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex = COUNT; 17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float filter(long time, float in) { 17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float v = in; 17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float ns = 1.0f / 1000000000.0f; 17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float t = time*ns; 17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float v1 = mV[mIndex]; 17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((v-v1) > 180) { 17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v -= 360; 17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((v1-v) > 180) { 17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v += 360; 17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Manage the circular buffer, we write the data twice spaced 17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by COUNT values, so that we don't have to copy the array 17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when it's full 17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex++; 17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIndex >= COUNT*2) 17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex = COUNT; 17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mV[mIndex] = v; 17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mT[mIndex] = t; 17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mV[mIndex-COUNT] = v; 17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mT[mIndex-COUNT] = t; 17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float A, B, C, D, E; 17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float a, b; 17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A = B = C = D = E = 0; 18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0 ; i<COUNT-1 ; i++) { 18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int j = mIndex - 1 - i; 18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Z = mV[j]; 18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float T = 0.5f*(mT[j] + mT[j+1]) - t; 18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float dT = mT[j] - mT[j+1]; 18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dT *= dT; 18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A += Z*dT; 18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project B += T*(T*dT); 18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project C += (T*dT); 18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project D += Z*(T*dT); 18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project E += dT; 18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = (A*B + C*D) / (E*B + C*C); 18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = (E*b - A) / C; 18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float f = b + PREDICTION_TIME*a; 18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Normalize 18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f *= (1.0f / 360.0f); 18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((f>=0)?f:-f) >= 0.5f) 18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f = f - (float)Math.ceil(f + 0.5f) + 1.0f; 18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f < 0) 18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f += 1.0f; 18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f *= 360.0f; 18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return f; 18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18290f791a799dc81d93935fd2597297cf7ac2c0a044Mathias Agopian 18307a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell /** Helper function to compute the angle change between two rotation matrices. 18317a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * Given a current rotation matrix (R) and a previous rotation matrix 18327a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * (prevR) computes the rotation around the x,y, and z axes which 18337a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * transforms prevR to R. 18347a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * outputs a 3 element vector containing the x,y, and z angle 18357a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * change at indexes 0, 1, and 2 respectively. 18367a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * <p> Each input matrix is either as a 3x3 or 4x4 row-major matrix 18377a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * depending on the length of the passed array: 18387a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * <p>If the array length is 9, then the array elements represent this matrix 18397a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * <pre> 18407a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * / R[ 0] R[ 1] R[ 2] \ 18417a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * | R[ 3] R[ 4] R[ 5] | 18427a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * \ R[ 6] R[ 7] R[ 8] / 18437a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell *</pre> 18447a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * <p>If the array length is 16, then the array elements represent this matrix 18457a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * <pre> 18467a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * / R[ 0] R[ 1] R[ 2] R[ 3] \ 18477a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * | R[ 4] R[ 5] R[ 6] R[ 7] | 18487a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * | R[ 8] R[ 9] R[10] R[11] | 18497a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * \ R[12] R[13] R[14] R[15] / 18507a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell *</pre> 18517a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * @param R current rotation matrix 18527a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * @param prevR previous rotation matrix 18537a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * @param angleChange an array of floats in which the angle change is stored 18547a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell */ 18557a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 18567a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell public static void getAngleChange( float[] angleChange, float[] R, float[] prevR) { 18577a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float rd1=0,rd4=0, rd6=0,rd7=0, rd8=0; 18587a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float ri0=0,ri1=0,ri2=0,ri3=0,ri4=0,ri5=0,ri6=0,ri7=0,ri8=0; 18597a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float pri0=0, pri1=0, pri2=0, pri3=0, pri4=0, pri5=0, pri6=0, pri7=0, pri8=0; 18607a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell int i, j, k; 18617a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 18627a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell if(R.length == 9) { 18637a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri0 = R[0]; 18647a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri1 = R[1]; 18657a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri2 = R[2]; 18667a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri3 = R[3]; 18677a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri4 = R[4]; 18687a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri5 = R[5]; 18697a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri6 = R[6]; 18707a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri7 = R[7]; 18717a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri8 = R[8]; 18727a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell } else if(R.length == 16) { 18737a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri0 = R[0]; 18747a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri1 = R[1]; 18757a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri2 = R[2]; 18767a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri3 = R[4]; 18777a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri4 = R[5]; 18787a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri5 = R[6]; 18797a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri6 = R[8]; 18807a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri7 = R[9]; 18817a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell ri8 = R[10]; 18827a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell } 18837a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 18847a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell if(prevR.length == 9) { 188534884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri0 = prevR[0]; 188634884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri1 = prevR[1]; 188734884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri2 = prevR[2]; 188834884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri3 = prevR[3]; 188934884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri4 = prevR[4]; 189034884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri5 = prevR[5]; 189134884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri6 = prevR[6]; 189234884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri7 = prevR[7]; 189334884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri8 = prevR[8]; 18947a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell } else if(prevR.length == 16) { 189534884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri0 = prevR[0]; 189634884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri1 = prevR[1]; 189734884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri2 = prevR[2]; 189834884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri3 = prevR[4]; 189934884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri4 = prevR[5]; 190034884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri5 = prevR[6]; 190134884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri6 = prevR[8]; 190234884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri7 = prevR[9]; 190334884b409e24c1183b6be4f0611b8ea22e62dc10Kevin Powell pri8 = prevR[10]; 19047a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell } 19057a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 19067a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell // calculate the parts of the rotation difference matrix we need 19077a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell // rd[i][j] = pri[0][i] * ri[0][j] + pri[1][i] * ri[1][j] + pri[2][i] * ri[2][j]; 19087a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 19097a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell rd1 = pri0 * ri1 + pri3 * ri4 + pri6 * ri7; //rd[0][1] 19107a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell rd4 = pri1 * ri1 + pri4 * ri4 + pri7 * ri7; //rd[1][1] 19117a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell rd6 = pri2 * ri0 + pri5 * ri3 + pri8 * ri6; //rd[2][0] 19127a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell rd7 = pri2 * ri1 + pri5 * ri4 + pri8 * ri7; //rd[2][1] 19137a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell rd8 = pri2 * ri2 + pri5 * ri5 + pri8 * ri8; //rd[2][2] 19147a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 19157a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell angleChange[0] = (float)Math.atan2(rd1, rd4); 19167a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell angleChange[1] = (float)Math.asin(-rd7); 19177a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell angleChange[2] = (float)Math.atan2(-rd6, rd8); 19187a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 19197a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell } 19207a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 19217a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell /** Helper function to convert a rotation vector to a rotation matrix. 19227a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * Given a rotation vector (presumably from a ROTATION_VECTOR sensor), returns a 19237a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * 9 or 16 element rotation matrix in the array R. R must have length 9 or 16. 19247a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * If R.length == 9, the following matrix is returned: 19257a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * <pre> 19267a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * / R[ 0] R[ 1] R[ 2] \ 19277a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * | R[ 3] R[ 4] R[ 5] | 19287a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * \ R[ 6] R[ 7] R[ 8] / 19297a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell *</pre> 19307a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * If R.length == 16, the following matrix is returned: 19317a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * <pre> 19327a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * / R[ 0] R[ 1] R[ 2] 0 \ 19337a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * | R[ 4] R[ 5] R[ 6] 0 | 19347a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * | R[ 8] R[ 9] R[10] 0 | 19357a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * \ 0 0 0 1 / 19367a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell *</pre> 19377a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * @param rotationVector the rotation vector to convert 19387a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * @param R an array of floats in which to store the rotation matrix 19397a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell */ 19407a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell public static void getRotationMatrixFromVector(float[] R, float[] rotationVector) { 19417badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian 19427badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian float q0; 19437a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float q1 = rotationVector[0]; 19447a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float q2 = rotationVector[1]; 19457a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float q3 = rotationVector[2]; 19467a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 19477badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian if (rotationVector.length == 4) { 19487badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian q0 = rotationVector[3]; 19497badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian } else { 19507badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian q0 = (float)Math.sqrt(1 - q1*q1 - q2*q2 - q3*q3); 19517badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian } 19527badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian 19537a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float sq_q1 = 2 * q1 * q1; 19547a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float sq_q2 = 2 * q2 * q2; 19557a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float sq_q3 = 2 * q3 * q3; 19567a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float q1_q2 = 2 * q1 * q2; 19577a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float q3_q0 = 2 * q3 * q0; 19587a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float q1_q3 = 2 * q1 * q3; 19597a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float q2_q0 = 2 * q2 * q0; 19607a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float q2_q3 = 2 * q2 * q3; 19617a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell float q1_q0 = 2 * q1 * q0; 19627a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 19637a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell if(R.length == 9) { 19647a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[0] = 1 - sq_q2 - sq_q3; 19657a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[1] = q1_q2 - q3_q0; 19667a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[2] = q1_q3 + q2_q0; 19677a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 19687a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[3] = q1_q2 + q3_q0; 19697a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[4] = 1 - sq_q1 - sq_q3; 19707a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[5] = q2_q3 - q1_q0; 19717a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 19727a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[6] = q1_q3 - q2_q0; 19737a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[7] = q2_q3 + q1_q0; 19747a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[8] = 1 - sq_q1 - sq_q2; 19757a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell } else if (R.length == 16) { 19767a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[0] = 1 - sq_q2 - sq_q3; 19777a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[1] = q1_q2 - q3_q0; 19787a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[2] = q1_q3 + q2_q0; 19797a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[3] = 0.0f; 19807a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 19817a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[4] = q1_q2 + q3_q0; 19827a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[5] = 1 - sq_q1 - sq_q3; 19837a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[6] = q2_q3 - q1_q0; 19847a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[7] = 0.0f; 19857a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 19867a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[8] = q1_q3 - q2_q0; 19877a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[9] = q2_q3 + q1_q0; 19887a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[10] = 1 - sq_q1 - sq_q2; 19897a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[11] = 0.0f; 19907a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 19917a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[12] = R[13] = R[14] = 0.0f; 19927a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell R[15] = 1.0f; 19937a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell } 19947a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell } 19957a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 19967a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell /** Helper function to convert a rotation vector to a normalized quaternion. 19977a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * Given a rotation vector (presumably from a ROTATION_VECTOR sensor), returns a normalized 19987a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * quaternion in the array Q. The quaternion is stored as [w, x, y, z] 19997a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * @param rv the rotation vector to convert 20007a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell * @param Q an array of floats in which to store the computed quaternion 20017a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell */ 20027a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell public static void getQuaternionFromVector(float[] Q, float[] rv) { 20037badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian if (rv.length == 4) { 20047badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian Q[0] = rv[3]; 20057badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian } else { 20067badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian //In this case, the w component of the quaternion is known to be a positive number 20077badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian Q[0] = (float)Math.sqrt(1 - rv[0]*rv[0] - rv[1]*rv[1] - rv[2]*rv[2]); 20087badd2c402f9e8e9fd13f6915ad2e32301f9f305Mathias Agopian } 20097a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell Q[1] = rv[0]; 20107a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell Q[2] = rv[1]; 20117a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell Q[3] = rv[2]; 20127a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell } 20137a0541d6b803da02b8724b1d140d6ccaaec23a36Kevin Powell 20149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void nativeClassInit(); 20159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native int sensors_module_init(); 20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native int sensors_module_get_next_sensor(Sensor sensor, int next); 20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Used within this module from outside SensorManager, don't make private 20201bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian static native int sensors_create_queue(); 20211bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian static native void sensors_destroy_queue(int queue); 20221bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian static native boolean sensors_enable_sensor(int queue, String name, int sensor, int enable); 20231bf797857e025e8a71db86fb9e79765a767ec1ebMathias Agopian static native int sensors_data_poll(int queue, float[] values, int[] status, long[] timestamp); 20249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2025