SensorManager.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
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.content.Context; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Process; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IRotationWatcher; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IWindowManager; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Surface; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Class that lets you access the device's sensors. Get an instance of this 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * class by calling {@link android.content.Context#getSystemService(java.lang.String) 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Context.getSystemService()} with an argument of {@link android.content.Context#SENSOR_SERVICE}. 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SensorManager extends IRotationWatcher.Stub 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "SensorManager"; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float[] mTempMatrix = new float[16]; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* NOTE: sensor IDs must be a power of 2 */ 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A constant describing an orientation sensor. 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link android.hardware.SensorListener SensorListener} for more details. 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ORIENTATION = 1 << 0; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A constant describing an accelerometer. 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link android.hardware.SensorListener SensorListener} for more details. 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ACCELEROMETER = 1 << 1; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A constant describing a temperature sensor 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link android.hardware.SensorListener SensorListener} for more details. 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_TEMPERATURE = 1 << 2; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A constant describing a magnetic sensor 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link android.hardware.SensorListener SensorListener} for more details. 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_MAGNETIC_FIELD = 1 << 3; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A constant describing an ambient light sensor 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link android.hardware.SensorListener SensorListener} for more details. 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_LIGHT = 1 << 4; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A constant describing a proximity sensor 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link android.hardware.SensorListener SensorListener} for more details. 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_PROXIMITY = 1 << 5; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A constant describing a Tricorder 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link android.hardware.SensorListener SensorListener} for more details. 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_TRICORDER = 1 << 6; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A constant describing an orientation sensor. 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link android.hardware.SensorListener SensorListener} for more details. 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ORIENTATION_RAW = 1 << 7; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** A constant that includes all sensors */ 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ALL = 0x7F; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Smallest sensor ID */ 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_MIN = SENSOR_ORIENTATION; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Largest sensor ID */ 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_MAX = ((SENSOR_ALL + 1)>>1); 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Index of the X value in the array returned by 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.SensorListener#onSensorChanged} */ 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATA_X = 0; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Index of the Y value in the array returned by 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.SensorListener#onSensorChanged} */ 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATA_Y = 1; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Index of the Z value in the array returned by 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.SensorListener#onSensorChanged} */ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATA_Z = 2; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Offset to the untransformed values in the array returned by 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.SensorListener#onSensorChanged} */ 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_INDEX = 3; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Index of the untransformed X value in the array returned by 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.SensorListener#onSensorChanged} */ 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_X = 3; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Index of the untransformed Y value in the array returned by 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.SensorListener#onSensorChanged} */ 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_Y = 4; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Index of the untransformed Z value in the array returned by 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.SensorListener#onSensorChanged} */ 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_Z = 5; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Standard gravity (g) on Earth. This value is equivalent to 1G */ 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float STANDARD_GRAVITY = 9.80665f; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** values returned by the accelerometer in various locations in the universe. 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * all values are in SI units (m/s^2) */ 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_SUN = 275.0f; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MERCURY = 3.70f; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_VENUS = 8.87f; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_EARTH = 9.80665f; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MOON = 1.6f; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MARS = 3.71f; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_JUPITER = 23.12f; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_SATURN = 8.96f; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_URANUS = 8.69f; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_NEPTUNE = 11.0f; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_PLUTO = 0.6f; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_DEATH_STAR_I = 0.000000353036145f; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_THE_ISLAND = 4.815162342f; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Maximum magnetic field on Earth's surface */ 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float MAGNETIC_FIELD_EARTH_MAX = 60.0f; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Minimum magnetic field on Earth's surface */ 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float MAGNETIC_FIELD_EARTH_MIN = 30.0f; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Various luminance values during the day (lux) */ 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNLIGHT_MAX = 120000.0f; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNLIGHT = 110000.0f; 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SHADE = 20000.0f; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_OVERCAST = 10000.0f; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNRISE = 400.0f; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_CLOUDY = 100.0f; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Various luminance values during the night (lux) */ 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_FULLMOON = 0.25f; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_NO_MOON = 0.001f; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** get sensor data as fast as possible */ 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_FASTEST = 0; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate suitable for games */ 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_GAME = 1; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate suitable for the user interface */ 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_UI = 2; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate (default) suitable for screen orientation changes */ 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_NORMAL = 3; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The values returned by this sensor cannot be trusted, calibration 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is needed or the environment doesn't allow readings */ 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_UNRELIABLE = 0; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** This sensor is reporting data with low accuracy, calibration with the 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * environment is needed */ 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_LOW = 1; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** This sensor is reporting data with an average level of accuracy, 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * calibration with the environment may improve the readings */ 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_MEDIUM = 2; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** This sensor is reporting data with maximum accuracy */ 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_HIGH = 3; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_X = 1; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_Y = 2; 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_Z = 3; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_X = AXIS_X | 0x80; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_Y = AXIS_Y | 0x80; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_Z = AXIS_Z | 0x80; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ISensorService mSensorService; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper mMainLooper; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashMap<SensorListener, LegacyListener> mLegacyListenersMap = 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashMap<SensorListener, LegacyListener>(); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SENSOR_DISABLE = -1; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean sSensorModuleInitialized = false; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static ArrayList<Sensor> sFullSensorsList = new ArrayList<Sensor>(); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static SparseArray<List<Sensor>> sSensorListByType = new SparseArray<List<Sensor>>(); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static IWindowManager sWindowManager; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static int sRotation = Surface.ROTATION_0; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* The thread and the sensor list are global to the process 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but the actual thread is spawned on demand */ 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static SensorThread sSensorThread; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Used within this module from outside SensorManager, don't make private 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static SparseArray<Sensor> sHandleToSensor = new SparseArray<Sensor>(); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final ArrayList<ListenerDelegate> sListeners = 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new ArrayList<ListenerDelegate>(); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static private class SensorThread { 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Thread mThread; 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorThread() { 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this gets to the sensor module. We can have only one per process. 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensors_data_init(); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() { 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensors_data_uninit(); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // must be called with sListeners lock 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void startLocked(ISensorService service) { 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mThread == null) { 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor fd = service.getDataChanel(); 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThread = new Thread(new SensorThreadRunnable(fd), 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorThread.class.getName()); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThread.start(); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "RemoteException in startLocked: ", e); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class SensorThreadRunnable implements Runnable { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ParcelFileDescriptor mSensorDataFd; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorThreadRunnable(ParcelFileDescriptor fd) { 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorDataFd = fd; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.d(TAG, "entering main sensor thread"); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float[] values = new float[3]; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] status = new int[1]; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long timestamp[] = new long[1]; 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY); 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSensorDataFd == null) { 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "mSensorDataFd == NULL, exiting"); 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this thread is guaranteed to be unique 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensors_data_open(mSensorDataFd.getFileDescriptor()); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorDataFd.close(); 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // *shrug* 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "IOException: ", e); 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorDataFd = null; 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) { 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // wait for an event 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int sensor = sensors_data_poll(values, status, timestamp); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sensor == -1) { 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we lost the connection to the event stream. this happens 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // when the last listener is removed. 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "_sensors_data_poll() failed, we bail out."); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int accuracy = status[0]; 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sListeners) { 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sListeners.isEmpty()) { 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we have no more listeners, terminate the thread 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensors_data_close(); 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThread = null; 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Sensor sensorObject = sHandleToSensor.get(sensor); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sensorObject != null) { 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // report the sensor event to all listeners that 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // care about it. 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int size = sListeners.size(); 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<size ; i++) { 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ListenerDelegate listener = sListeners.get(i); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener.hasSensor(sensorObject)) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this is asynchronous (okay to call 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sListeners lock held). 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.onSensorChangedLocked(sensorObject, 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values, timestamp, accuracy); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.d(TAG, "exiting main sensor thread"); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class ListenerDelegate extends Binder { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final SensorEventListener mSensorEventListener; 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Sensor> mSensorList = new ArrayList<Sensor>(); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Handler mHandler; 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SensorEvent mValuesPool; 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int mSensors; 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ListenerDelegate(SensorEventListener listener, Sensor sensor, Handler handler) { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorEventListener = listener; 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper looper = (handler != null) ? handler.getLooper() : mMainLooper; 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // currently we create one Handler instance per listener, but we could 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // have one per looper (we'd need to pass the ListenerDelegate 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // instance to handleMessage and keep track of them separately). 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler = new Handler(looper) { 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorEvent t = (SensorEvent)msg.obj; 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.accuracy >= 0) { 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorEventListener.onAccuracyChanged(t.sensor, t.accuracy); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorEventListener.onSensorChanged(t); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project returnToPool(t); 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addSensor(sensor); 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected SensorEvent createSensorEvent() { 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // maximal size for all legacy events is 3 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new SensorEvent(3); 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected SensorEvent getFromPool() { 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorEvent t = null; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // remove the array from the pool 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t = mValuesPool; 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mValuesPool = null; 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t == null) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the pool was empty, we need a new one 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t = createSensorEvent(); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return t; 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void returnToPool(SensorEvent t) { 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // put back the array into the pool 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mValuesPool == null) { 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mValuesPool = t; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object getListener() { 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSensorEventListener; 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int addSensor(Sensor sensor) { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors |= 1<<sensor.getHandle(); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorList.add(sensor); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSensors; 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int removeSensor(Sensor sensor) { 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors &= ~(1<<sensor.getHandle()); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorList.remove(sensor); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSensors; 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hasSensor(Sensor sensor) { 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ((mSensors & (1<<sensor.getHandle())) != 0); 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Sensor> getSensors() { 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSensorList; 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onSensorChangedLocked(Sensor sensor, float[] values, long[] timestamp, int accuracy) { 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorEvent t = getFromPool(); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float[] v = t.values; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[0] = values[0]; 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[1] = values[1]; 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[2] = values[2]; 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.timestamp = timestamp[0]; 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.accuracy = accuracy; 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.sensor = sensor; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = Message.obtain(); 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.what = 0; 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.obj = t; 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendMessage(msg); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SensorManager(Looper mainLooper) { 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorService = ISensorService.Stub.asInterface( 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ServiceManager.getService(Context.SENSOR_SERVICE)); 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMainLooper = mainLooper; 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!sSensorModuleInitialized) { 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sSensorModuleInitialized = true; 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativeClassInit(); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowManager = IWindowManager.Stub.asInterface( 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ServiceManager.getService("window")); 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sWindowManager != null) { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if it's null we're running in the system process 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // which won't get the rotated values 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sRotation = sWindowManager.watchRotation(this); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // initialize the sensor list 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensors_module_init(); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<Sensor> fullList = sFullSensorsList; 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i = 0; 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Sensor sensor = new Sensor(); 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = sensors_module_get_next_sensor(sensor, i); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i>=0) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "found sensor: " + sensor.getName() + 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ", handle=" + sensor.getHandle()); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensor.setLegacyType(getLegacySensorType(sensor.getType())); 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fullList.add(sensor); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sHandleToSensor.append(sensor.getHandle(), sensor); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (i>0); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sSensorThread = new SensorThread(); 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int getLegacySensorType(int type) { 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (type) { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ACCELEROMETER: 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_ACCELEROMETER; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_MAGNETIC_FIELD: 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_MAGNETIC_FIELD; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ORIENTATION: 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_ORIENTATION_RAW; 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_TEMPERATURE: 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_TEMPERATURE; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @return available sensors. 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SensorManager#getSensorList(int)} instead 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getSensors() { 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = 0; 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<Sensor> fullList = sFullSensorsList; 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Sensor i : fullList) { 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (i.getType()) { 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ACCELEROMETER: 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_ACCELEROMETER; 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_MAGNETIC_FIELD: 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_MAGNETIC_FIELD; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ORIENTATION: 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_ORIENTATION | 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorManager.SENSOR_ORIENTATION_RAW; 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Use this method to get the list of available sensors of a certain 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * type. Make multiple calls to get sensors of different types or use 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.Sensor#TYPE_ALL Sensor.TYPE_ALL} to get all 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the sensors. 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param type of sensors requested 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a list of sensors matching the asked type. 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<Sensor> getSensorList(int type) { 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cache the returned lists the first time 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Sensor> list; 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<Sensor> fullList = sFullSensorsList; 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(fullList) { 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = sSensorListByType.get(type); 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (list == null) { 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == Sensor.TYPE_ALL) { 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = fullList; 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = new ArrayList<Sensor>(); 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Sensor i : fullList) { 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i.getType() == type) 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list.add(i); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = Collections.unmodifiableList(list); 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sSensorListByType.append(type, list); 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return list; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Use this method to get the default sensor for a given type. Note that 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the returned sensor could be a composite sensor, and its data could be 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * averaged or filtered. If you need to access the raw sensors use 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SensorManager#getSensorList(int) getSensorList}. 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param type of sensors requested 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the default sensors matching the asked type. 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Sensor getDefaultSensor(int type) { 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: need to be smarter, for now, just return the 1st sensor 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Sensor> l = getSensorList(type); 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return l.isEmpty() ? null : l.get(0); 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Registers a listener for given sensors. 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SensorManager#registerListener(SensorEventListener, Sensor, int)} 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instead. 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener sensor listener object 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sensors a bit masks of the sensors to register to 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the sensor is supported and successfully enabled 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorListener listener, int sensors) { 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return registerListener(listener, sensors, SENSOR_DELAY_NORMAL); 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Registers a SensorListener for given sensors. 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SensorManager#registerListener(SensorEventListener, Sensor, int)} 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instead. 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener sensor listener object 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sensors a bit masks of the sensors to register to 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rate rate of events. This is only a hint to the system. events 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * may be received faster or slower than the specified rate. Usually events 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * are received faster. 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the sensor is supported and successfully enabled 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorListener listener, int sensors, int rate) { 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result = false; 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER, 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_MAGNETIC_FIELD, Sensor.TYPE_MAGNETIC_FIELD, 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_ORIENTATION_RAW, Sensor.TYPE_ORIENTATION, 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_ORIENTATION, Sensor.TYPE_ORIENTATION, 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_TEMPERATURE, Sensor.TYPE_TEMPERATURE, 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean registerLegacyListener(int legacyType, int type, 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorListener listener, int sensors, int rate) 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result = false; 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Are we activating this legacy sensor? 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((sensors & legacyType) != 0) { 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if so, find a suitable Sensor 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Sensor sensor = getDefaultSensor(type); 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sensor != null) { 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we don't already have one, create a LegacyListener 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to wrap this listener and process the events as 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // they are expected by legacy apps. 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LegacyListener legacyListener = null; 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLegacyListenersMap) { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener = mLegacyListenersMap.get(listener); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (legacyListener == null) { 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we didn't find a LegacyListener for this client, 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // create one, and put it in our list. 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener = new LegacyListener(listener); 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLegacyListenersMap.put(listener, legacyListener); 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // register this legacy sensor with this legacy listener 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener.registerSensor(legacyType); 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and finally, register the legacy listener with the new apis 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerListener(legacyListener, sensor, rate); 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for the sensors with which it is registered. 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SensorManager#unregisterListener(SensorEventListener, Sensor)} 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instead. 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener a SensorListener object 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sensors a bit masks of the sensors to unregister from 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorListener listener, int sensors) { 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER, 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_MAGNETIC_FIELD, Sensor.TYPE_MAGNETIC_FIELD, 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ORIENTATION_RAW, Sensor.TYPE_ORIENTATION, 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ORIENTATION, Sensor.TYPE_ORIENTATION, 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_TEMPERATURE, Sensor.TYPE_TEMPERATURE, 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void unregisterLegacyListener(int legacyType, int type, 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorListener listener, int sensors) 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // do we know about this listener? 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LegacyListener legacyListener = null; 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLegacyListenersMap) { 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener = mLegacyListenersMap.get(listener); 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (legacyListener != null) { 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Are we deactivating this legacy sensor? 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((sensors & legacyType) != 0) { 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if so, find the corresponding Sensor 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Sensor sensor = getDefaultSensor(type); 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sensor != null) { 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // unregister this legacy sensor and if we don't 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // need the corresponding Sensor, unregister it too 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (legacyListener.unregisterSensor(legacyType)) { 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // corresponding sensor not needed, unregister 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener(legacyListener, sensor); 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // finally check if we still need the legacyListener 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in our mapping, if not, get rid of it too. 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean found = false; 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ListenerDelegate i : sListeners) { 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i.getListener() == legacyListener) { 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project found = true; 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!found) { 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLegacyListenersMap) { 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLegacyListenersMap.remove(listener); 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for all sensors. 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SensorManager#unregisterListener(SensorEventListener)} 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instead. 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener a SensorListener object 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorListener listener) { 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener(listener, SENSOR_ALL | SENSOR_ORIENTATION_RAW); 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for the sensors with which it is registered. 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener a SensorEventListener object 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sensor the sensor to unregister from 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorEventListener listener, Sensor sensor) { 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener((Object)listener, sensor); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for all sensors. 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener a SensorListener object 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorEventListener listener) { 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener((Object)listener); 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Registers a {@link android.hardware.SensorEventListener SensorEventListener} 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for the given sensor. 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object. 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sensor The {@link android.hardware.Sensor Sensor} to register to. 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rate The rate {@link android.hardware.SensorEvent sensor events} are delivered at. 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is only a hint to the system. Events may be received faster or 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * slower than the specified rate. Usually events are received faster. 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the sensor is supported and successfully enabled. 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) { 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return registerListener(listener, sensor, rate, null); 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Registers a {@link android.hardware.SensorEventListener SensorEventListener} 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for the given sensor. 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object. 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sensor The {@link android.hardware.Sensor Sensor} to register to. 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rate The rate {@link android.hardware.SensorEvent sensor events} are delivered at. 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is only a hint to the system. Events may be received faster or 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * slower than the specified rate. Usually events are received faster. 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param handler The {@link android.os.Handler Handler} the 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.SensorEvent sensor events} will be delivered to. 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the sensor is supported and successfully enabled. 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate, 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Handler handler) { 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null || sensor == null) { 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result; 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int delay = -1; 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (rate) { 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_FASTEST: 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delay = 0; 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_GAME: 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delay = 20; 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_UI: 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delay = 60; 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_NORMAL: 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delay = 200; 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sListeners) { 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ListenerDelegate l = null; 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ListenerDelegate i : sListeners) { 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i.getListener() == listener) { 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project l = i; 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = sensor.getName(); 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int handle = sensor.getHandle(); 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (l == null) { 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project l = new ListenerDelegate(listener, sensor, handler); 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = mSensorService.enableSensor(l, name, handle, delay); 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result) { 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sListeners.add(l); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sListeners.notify(); 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!sListeners.isEmpty()) { 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sSensorThread.startLocked(mSensorService); 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = mSensorService.enableSensor(l, name, handle, delay); 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result) { 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project l.addSensor(sensor); 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "RemoteException in registerListener: ", e); 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = false; 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void unregisterListener(Object listener, Sensor sensor) { 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null || sensor == null) { 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sListeners) { 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int size = sListeners.size(); 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<size ; i++) { 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ListenerDelegate l = sListeners.get(i); 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (l.getListener() == listener) { 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // disable these sensors 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = sensor.getName(); 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int handle = sensor.getHandle(); 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorService.enableSensor(l, name, handle, SENSOR_DISABLE); 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if we have no more sensors enabled on this listener, 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // take it off the list. 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (l.removeSensor(sensor) == 0) { 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sListeners.remove(i); 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "RemoteException in unregisterListener: ", e); 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void unregisterListener(Object listener) { 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sListeners) { 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int size = sListeners.size(); 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<size ; i++) { 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ListenerDelegate l = sListeners.get(i); 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (l.getListener() == listener) { 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // disable all sensors for this listener 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Sensor sensor : l.getSensors()) { 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = sensor.getName(); 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int handle = sensor.getHandle(); 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorService.enableSensor(l, name, handle, SENSOR_DISABLE); 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sListeners.remove(i); 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "RemoteException in unregisterListener: ", e); 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes the inclination matrix <b>I</b> as well as the rotation 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * matrix <b>R</b> transforming a vector from the 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * device coordinate system to the world's coordinate system which is 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * defined as a direct orthonormal basis, where: 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the ground at the device's current location and roughly points East).</li> 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Y is tangential to the ground at the device's current location and 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * points towards the magnetic North Pole.</li> 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Z points towards the sky and is perpendicular to the ground.</li> 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>By definition: 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>[0 0 g] = <b>R</b> * <b>gravity</b> (g = magnitude of gravity) 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>[0 m 0] = <b>I</b> * <b>R</b> * <b>geomagnetic</b> 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (m = magnitude of geomagnetic field) 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p><b>R</b> is the identity matrix when the device is aligned with the 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * world's coordinate system, that is, when the device's X axis points 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * toward East, the Y axis points to the North Pole and the device is facing 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the sky. 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p><b>I</b> is a rotation matrix transforming the geomagnetic 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * vector into the same coordinate space as gravity (the world's coordinate 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * space). <b>I</b> is a simple rotation around the X axis. 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The inclination angle in radians can be computed with 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #getInclination}. 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> Each matrix is returned either as a 3x3 or 4x4 row-major matrix 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * depending on the length of the passed array: 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p><u>If the array length is 16:</u> 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] M[ 3] \ 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 4] M[ 5] M[ 6] M[ 7] | 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 8] M[ 9] M[10] M[11] | 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ M[12] M[13] M[14] M[15] / 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This matrix is ready to be used by OpenGL ES's 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link javax.microedition.khronos.opengles.GL10#glLoadMatrixf(float[], int) 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * glLoadMatrixf(float[], int)}. 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Note that because OpenGL matrices are column-major matrices you must 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * transpose the matrix before using it. However, since the matrix is a 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rotation matrix, its transpose is also its inverse, conveniently, it is 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * often the inverse of the rotation that is needed for rendering; it can 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * therefore be used with OpenGL ES directly. 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Also note that the returned matrices always have this form: 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] 0 \ 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 4] M[ 5] M[ 6] 0 | 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 8] M[ 9] M[10] 0 | 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ 0 0 0 1 / 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p><u>If the array length is 9:</u> 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] \ 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 3] M[ 4] M[ 5] | 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ M[ 6] M[ 7] M[ 8] / 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The inverse of each matrix can be computed easily by taking its 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * transpose. 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The matrices returned by this function are meaningful only when the 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * device is not free-falling and it is not close to the magnetic north. 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the device is accelerating, or placed into a strong magnetic field, 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the returned matrices may be inaccurate. 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param R is an array of 9 floats holding the rotation matrix <b>R</b> 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when this function returns. R can be null.<p> 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param I is an array of 9 floats holding the rotation matrix <b>I</b> 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when this function returns. I can be null.<p> 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gravity is an array of 3 floats containing the gravity vector 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * expressed in the device's coordinate. You can simply use the 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.SensorEvent#values values} 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returned by a {@link android.hardware.SensorEvent SensorEvent} of a 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.Sensor Sensor} of type 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.Sensor#TYPE_ACCELEROMETER TYPE_ACCELEROMETER}.<p> 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param geomagnetic is an array of 3 floats containing the geomagnetic 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * vector expressed in the device's coordinate. You can simply use the 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.SensorEvent#values values} 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returned by a {@link android.hardware.SensorEvent SensorEvent} of a 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.Sensor Sensor} of type 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD TYPE_MAGNETIC_FIELD}. 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * true on success<p> 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * false on failure (for instance, if the device is in free fall). 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * On failure the output matrices are not modified. 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean getRotationMatrix(float[] R, float[] I, 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] gravity, float[] geomagnetic) { 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: move this to native code for efficiency 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Ax = gravity[0]; 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Ay = gravity[1]; 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Az = gravity[2]; 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ex = geomagnetic[0]; 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ey = geomagnetic[1]; 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ez = geomagnetic[2]; 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hx = Ey*Az - Ez*Ay; 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hy = Ez*Ax - Ex*Az; 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hz = Ex*Ay - Ey*Ax; 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz); 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (normH < 0.1f) { 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // device is close to free fall (or in space?), or close to 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // magnetic north pole. Typical values are > 100. 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invH = 1.0f / normH; 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hx *= invH; 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hy *= invH; 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hz *= invH; 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invA = 1.0f / (float)Math.sqrt(Ax*Ax + Ay*Ay + Az*Az); 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Ax *= invA; 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Ay *= invA; 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Az *= invA; 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Mx = Ay*Hz - Az*Hy; 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float My = Az*Hx - Ax*Hz; 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Mz = Ax*Hy - Ay*Hx; 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R != null) { 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R.length == 9) { 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[0] = Hx; R[1] = Hy; R[2] = Hz; 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[3] = Mx; R[4] = My; R[5] = Mz; 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[6] = Ax; R[7] = Ay; R[8] = Az; 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (R.length == 16) { 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[0] = Hx; R[1] = Hy; R[2] = Hz; R[3] = 0; 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[4] = Mx; R[5] = My; R[6] = Mz; R[7] = 0; 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[8] = Ax; R[9] = Ay; R[10] = Az; R[11] = 0; 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[12] = 0; R[13] = 0; R[14] = 0; R[15] = 1; 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I != null) { 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute the inclination matrix by projecting the geomagnetic 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // vector onto the Z (gravity) and X (horizontal component 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // of geomagnetic vector) axes. 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invE = 1.0f / (float)Math.sqrt(Ex*Ex + Ey*Ey + Ez*Ez); 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float c = (Ex*Mx + Ey*My + Ez*Mz) * invE; 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float s = (Ex*Ax + Ey*Ay + Ez*Az) * invE; 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I.length == 9) { 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[0] = 1; I[1] = 0; I[2] = 0; 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[3] = 0; I[4] = c; I[5] = s; 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[6] = 0; I[7] =-s; I[8] = c; 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (I.length == 16) { 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[0] = 1; I[1] = 0; I[2] = 0; 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[4] = 0; I[5] = c; I[6] = s; 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[8] = 0; I[9] =-s; I[10]= c; 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[3] = I[7] = I[11] = I[12] = I[13] = I[14] = 0; 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[15] = 1; 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes the geomagnetic inclination angle in radians from the 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * inclination matrix <b>I</b> returned by {@link #getRotationMatrix}. 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param I inclination matrix see {@link #getRotationMatrix}. 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The geomagnetic inclination angle in radians. 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static float getInclination(float[] I) { 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I.length == 9) { 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (float)Math.atan2(I[5], I[4]); 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (float)Math.atan2(I[6], I[5]); 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Rotates the supplied rotation matrix so it is expressed in a 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * different coordinate system. This is typically used when an application 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * needs to compute the three orientation angles of the device (see 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #getOrientation}) in a different coordinate system. 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>When the rotation matrix is used for drawing (for instance with 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * OpenGL ES), it usually <b>doesn't need</b> to be transformed by this 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * function, unless the screen is physically rotated, such as when used 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in landscape mode. 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p><u>Examples:</u><p> 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Using the camera (Y axis along the camera's axis) for an augmented 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * reality application where the rotation angles are needed :</li><p> 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);</code><p> 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Using the device as a mechanical compass in landscape mode:</li><p> 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>remapCoordinateSystem(inR, AXIS_Y, AXIS_MINUS_X, outR);</code><p> 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Beware of the above example. This call is needed only if the device is 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * physically used in landscape mode to calculate the rotation angles (see 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #getOrientation}). 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the rotation matrix is also used for rendering, it may not need to 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be transformed, for instance if your {@link android.app.Activity 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Activity} is running in landscape mode. 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Since the resulting coordinate system is orthonormal, only two axes 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * need to be specified. 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param inR the rotation matrix to be transformed. Usually it is the 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * matrix returned by {@link #getRotationMatrix}. 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param X defines on which world axis and direction the X axis of the 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * device is mapped. 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param Y defines on which world axis and direction the Y axis of the 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * device is mapped. 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param outR the transformed rotation matrix. inR and outR can be the same 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * array, but it is not recommended for performance reason. 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true on success. false if the input parameters are incorrect, for 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instance if X and Y define the same axis. Or if inR and outR don't have 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the same length. 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean remapCoordinateSystem(float[] inR, int X, int Y, 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] outR) 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inR == outR) { 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float[] temp = mTempMatrix; 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(temp) { 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we don't expect to have a lot of contention 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (remapCoordinateSystemImpl(inR, X, Y, temp)) { 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int size = outR.length; 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<size ; i++) 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[i] = temp[i]; 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return remapCoordinateSystemImpl(inR, X, Y, outR); 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean remapCoordinateSystemImpl(float[] inR, int X, int Y, 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] outR) 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * X and Y define a rotation matrix 'r': 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * r[0] ^ r[1] 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * where the 3rd line is the vector product of the first 2 lines 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int length = outR.length; 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inR.length != length) 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // invalid parameter 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((X & 0x7C)!=0 || (Y & 0x7C)!=0) 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // invalid parameter 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((X & 0x3)==0) || ((Y & 0x3)==0)) 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // no axis specified 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((X & 0x3) == (Y & 0x3)) 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // same axis specified 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Z is "the other" axis, its sign is either +/- sign(X)*sign(Y) 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this can be calculated by exclusive-or'ing X and Y; except for 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the sign inversion (+/-) which is calculated below. 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int Z = X ^ Y; 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // extract the axis (remove the sign), offset in the range 0 to 2. 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int x = (X & 0x3)-1; 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int y = (Y & 0x3)-1; 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int z = (Z & 0x3)-1; 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute the sign of Z (whether it needs to be inverted) 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int axis_y = (z+1)%3; 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int axis_z = (z+2)%3; 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((x^axis_y)|(y^axis_z)) != 0) 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Z ^= 0x80; 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sx = (X>=0x80); 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sy = (Y>=0x80); 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sz = (Z>=0x80); 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Perform R * r, in avoiding actual muls and adds. 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int rowLength = ((length==16)?4:3); 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j=0 ; j<3 ; j++) { 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int offset = j*rowLength; 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<3 ; i++) { 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x==i) outR[offset+i] = sx ? -inR[offset+0] : inR[offset+0]; 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (y==i) outR[offset+i] = sy ? -inR[offset+1] : inR[offset+1]; 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (z==i) outR[offset+i] = sz ? -inR[offset+2] : inR[offset+2]; 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (length == 16) { 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[3] = outR[7] = outR[11] = outR[12] = outR[13] = outR[14] = 0; 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[15] = 1; 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes the device's orientation based on the rotation matrix. 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> When it returns, the array values is filled with the result: 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[0]: <i>azimuth</i>, rotation around the Z axis.</li> 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[1]: <i>pitch</i>, rotation around the X axis.</li> 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[2]: <i>roll</i>, rotation around the Y axis.</li> 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param R rotation matrix see {@link #getRotationMatrix}. 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values an array of 3 floats to hold the result. 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The array values passed as argument. 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static float[] getOrientation(float[] R, float values[]) { 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4x4 (length=16) case: 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / R[ 0] R[ 1] R[ 2] 0 \ 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 4] R[ 5] R[ 6] 0 | 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 8] R[ 9] R[10] 0 | 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ 0 0 0 1 / 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3x3 (length=9) case: 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / R[ 0] R[ 1] R[ 2] \ 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 3] R[ 4] R[ 5] | 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ R[ 6] R[ 7] R[ 8] / 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R.length == 9) { 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = (float)Math.atan2(R[1], R[4]); 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = (float)Math.asin(-R[7]); 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = (float)Math.atan2(-R[6], R[8]); 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = (float)Math.atan2(R[1], R[5]); 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = (float)Math.asin(-R[9]); 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = (float)Math.atan2(-R[8], R[10]); 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return values; 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onRotationChanged(int rotation) { 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sRotation = rotation; 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int getRotation() { 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sRotation; 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class LegacyListener implements SensorEventListener { 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mValues[] = new float[6]; 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SensorListener mTarget; 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSensors; 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final LmsFilter mYawfilter = new LmsFilter(); 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LegacyListener(SensorListener target) { 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget = target; 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors = 0; 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void registerSensor(int legacyType) { 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors |= legacyType; 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean unregisterSensor(int legacyType) { 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors &= ~legacyType; 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mask = SENSOR_ORIENTATION|SENSOR_ORIENTATION_RAW; 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((legacyType&mask)!=0) && ((mSensors&mask)!=0)) { 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onAccuracyChanged(Sensor sensor, int accuracy) { 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onAccuracyChanged(sensor.getLegacyType(), accuracy); 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (AbstractMethodError e) { 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // old app that doesn't implement this method 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // just ignore it. 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onSensorChanged(SensorEvent event) { 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float v[] = mValues; 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[0] = event.values[0]; 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[1] = event.values[1]; 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[2] = event.values[2]; 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int legacyType = event.sensor.getLegacyType(); 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mapSensorDataToWindow(legacyType, v, SensorManager.getRotation()); 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) { 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mSensors & SENSOR_ORIENTATION_RAW)!=0) { 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(SENSOR_ORIENTATION_RAW, v); 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mSensors & SENSOR_ORIENTATION)!=0) { 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[0] = mYawfilter.filter(event.timestamp, v[0]); 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(SENSOR_ORIENTATION, v); 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(legacyType, v); 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Helper function to convert the specified sensor's data to the windows's 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * coordinate space from the device's coordinate space. 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * output: 3,4,5: values in the old API format 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 0,1,2: transformed values in the old API format 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void mapSensorDataToWindow(int sensor, 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] values, int orientation) { 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x = values[0]; 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = values[1]; 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float z = values[2]; 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (sensor) { 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ORIENTATION: 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ORIENTATION_RAW: 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z = -z; 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ACCELEROMETER: 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x = -x; 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y = -y; 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z = -z; 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_MAGNETIC_FIELD: 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x = -x; 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y = -y; 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = x; 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = y; 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = z; 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[3] = x; 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[4] = y; 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[5] = z; 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: add support for 180 and 270 orientations 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (orientation == Surface.ROTATION_90) { 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (sensor) { 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ACCELEROMETER: 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_MAGNETIC_FIELD: 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] =-y; 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = x; 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = z; 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ORIENTATION: 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ORIENTATION_RAW: 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = x + ((x < 270) ? 90 : -270); 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = z; 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = y; 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class LmsFilter { 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SENSORS_RATE_MS = 20; 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int COUNT = 12; 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float PREDICTION_RATIO = 1.0f/3.0f; 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float PREDICTION_TIME = (SENSORS_RATE_MS*COUNT/1000.0f)*PREDICTION_RATIO; 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mV[] = new float[COUNT*2]; 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mT[] = new float[COUNT*2]; 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mIndex; 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LmsFilter() { 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex = COUNT; 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float filter(long time, float in) { 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float v = in; 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float ns = 1.0f / 1000000000.0f; 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float t = time*ns; 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float v1 = mV[mIndex]; 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((v-v1) > 180) { 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v -= 360; 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((v1-v) > 180) { 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v += 360; 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Manage the circular buffer, we write the data twice spaced 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by COUNT values, so that we don't have to copy the array 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when it's full 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex++; 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIndex >= COUNT*2) 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex = COUNT; 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mV[mIndex] = v; 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mT[mIndex] = t; 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mV[mIndex-COUNT] = v; 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mT[mIndex-COUNT] = t; 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float A, B, C, D, E; 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float a, b; 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A = B = C = D = E = 0; 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0 ; i<COUNT-1 ; i++) { 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int j = mIndex - 1 - i; 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Z = mV[j]; 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float T = 0.5f*(mT[j] + mT[j+1]) - t; 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float dT = mT[j] - mT[j+1]; 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dT *= dT; 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A += Z*dT; 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project B += T*(T*dT); 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project C += (T*dT); 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project D += Z*(T*dT); 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project E += dT; 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = (A*B + C*D) / (E*B + C*C); 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = (E*b - A) / C; 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float f = b + PREDICTION_TIME*a; 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Normalize 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f *= (1.0f / 360.0f); 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((f>=0)?f:-f) >= 0.5f) 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f = f - (float)Math.ceil(f + 0.5f) + 1.0f; 14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f < 0) 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f += 1.0f; 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f *= 360.0f; 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return f; 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void nativeClassInit(); 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native int sensors_module_init(); 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native int sensors_module_get_next_sensor(Sensor sensor, int next); 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Used within this module from outside SensorManager, don't make private 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static native int sensors_data_init(); 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static native int sensors_data_uninit(); 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static native int sensors_data_open(FileDescriptor fd); 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static native int sensors_data_close(); 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static native int sensors_data_poll(float[] values, int[] status, long[] timestamp); 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1463