SensorManager.java revision 74cde2cee9e53006a710f4e80700cd560c2d0e4d
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; 21270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwoodimport android.os.Bundle; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper; 23270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwoodimport android.os.Parcelable; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Process; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseArray; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IRotationWatcher; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IWindowManager; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Surface; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Collections; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 4474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * SensorManager lets you access the device's {@link android.hardware.Sensor 4574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensors}. Get an instance of this class by calling 4674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.content.Context#getSystemService(java.lang.String) 4774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Context.getSystemService()} with the argument 4874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.content.Context#SENSOR_SERVICE}. 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 50287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopianpublic class SensorManager 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "SensorManager"; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float[] mTempMatrix = new float[16]; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* NOTE: sensor IDs must be a power of 2 */ 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an orientation sensor. See 5974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 6074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ORIENTATION = 1 << 0; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an accelerometer. See 6874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 6974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ACCELEROMETER = 1 << 1; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a temperature sensor See 7774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 7874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_TEMPERATURE = 1 << 2; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a magnetic sensor See 8674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 8774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 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_MAGNETIC_FIELD = 1 << 3; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an ambient light sensor See 9574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 9674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_LIGHT = 1 << 4; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a proximity sensor See 10474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 10574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_PROXIMITY = 1 << 5; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing a Tricorder See 11374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 11474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_TRICORDER = 1 << 6; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant describing an orientation sensor. See 12274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorListener SensorListener} for more details. 12374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ORIENTATION_RAW = 1 << 7; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 13074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A constant that includes all sensors 13174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 1324a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1334a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_ALL = 0x7F; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 13874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Smallest sensor ID 13974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 1404a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1414a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_MIN = SENSOR_ORIENTATION; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 14674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Largest sensor ID 14774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 1484a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1494a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_MAX = ((SENSOR_ALL + 1)>>1); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 15574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the X value in the array returned by 1564a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 15774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 1584a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1594a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATA_X = 0; 16274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 16374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 16474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the Y value in the array returned by 1654a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 16674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 1674a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1684a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATA_Y = 1; 17174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 17274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 17374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the Z value in the array returned by 1744a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 17574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 1764a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1774a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int DATA_Z = 2; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 18274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Offset to the untransformed values in the array returned by 1834a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 18474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 1854a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1864a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_INDEX = 3; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 19174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the untransformed X value in the array returned by 1924a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 19374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 1944a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 1954a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_X = 3; 19874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 19974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 20074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the untransformed Y value in the array returned by 2014a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 20274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 2034a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 2044a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_Y = 4; 20774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 20874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 20974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Index of the untransformed Z value in the array returned by 2104a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * {@link android.hardware.SensorListener#onSensorChanged} 21174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 2124a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn * @deprecated use {@link android.hardware.Sensor Sensor} instead. 2134a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn */ 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int RAW_DATA_Z = 5; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Standard gravity (g) on Earth. This value is equivalent to 1G */ 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float STANDARD_GRAVITY = 9.80665f; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Sun's gravity in SI units (m/s^2) */ 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_SUN = 275.0f; 22274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Mercury's gravity in SI units (m/s^2) */ 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MERCURY = 3.70f; 22474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Venus' gravity in SI units (m/s^2) */ 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_VENUS = 8.87f; 22674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Earth's gravity in SI units (m/s^2) */ 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_EARTH = 9.80665f; 22874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** The Moon's gravity in SI units (m/s^2) */ 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MOON = 1.6f; 23074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Mars' gravity in SI units (m/s^2) */ 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_MARS = 3.71f; 23274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Jupiter's gravity in SI units (m/s^2) */ 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_JUPITER = 23.12f; 23474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Saturn's gravity in SI units (m/s^2) */ 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_SATURN = 8.96f; 23674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Uranus' gravity in SI units (m/s^2) */ 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_URANUS = 8.69f; 23874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Neptune's gravity in SI units (m/s^2) */ 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_NEPTUNE = 11.0f; 24074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Pluto's gravity in SI units (m/s^2) */ 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_PLUTO = 0.6f; 24274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Gravity (estimate) on the first Death Star in Empire units (m/s^2) */ 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_DEATH_STAR_I = 0.000000353036145f; 24474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Gravity on the island */ 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float GRAVITY_THE_ISLAND = 4.815162342f; 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Maximum magnetic field on Earth's surface */ 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float MAGNETIC_FIELD_EARTH_MAX = 60.0f; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Minimum magnetic field on Earth's surface */ 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float MAGNETIC_FIELD_EARTH_MIN = 30.0f; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 25474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** Maximum luminance of sunlight in lux */ 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNLIGHT_MAX = 120000.0f; 25674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance of sunlight in lux */ 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNLIGHT = 110000.0f; 25874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance in shade in lux */ 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SHADE = 20000.0f; 26074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance under an overcast sky in lux */ 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_OVERCAST = 10000.0f; 26274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance at sunrise in lux */ 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_SUNRISE = 400.0f; 26474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance under a cloudy sky in lux */ 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_CLOUDY = 100.0f; 26674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance at night with full moon in lux */ 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_FULLMOON = 0.25f; 26874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** luminance at night with no moon in lux*/ 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final float LIGHT_NO_MOON = 0.001f; 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** get sensor data as fast as possible */ 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_FASTEST = 0; 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate suitable for games */ 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_GAME = 1; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate suitable for the user interface */ 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_UI = 2; 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** rate (default) suitable for screen orientation changes */ 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_DELAY_NORMAL = 3; 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 28374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The values returned by this sensor cannot be trusted, calibration is 28474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * needed or the environment doesn't allow readings 28574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian */ 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_UNRELIABLE = 0; 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 28974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * This sensor is reporting data with low accuracy, calibration with the 29074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * environment is needed 29174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian */ 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_LOW = 1; 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 29574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * This sensor is reporting data with an average level of accuracy, 29674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * calibration with the environment may improve the readings 29774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian */ 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_MEDIUM = 2; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** This sensor is reporting data with maximum accuracy */ 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SENSOR_STATUS_ACCURACY_HIGH = 3; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_X = 1; 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_Y = 2; 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_Z = 3; 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_X = AXIS_X | 0x80; 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_Y = AXIS_Y | 0x80; 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** see {@link #remapCoordinateSystem} */ 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AXIS_MINUS_Z = AXIS_Z | 0x80; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ISensorService mSensorService; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper mMainLooper; 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashMap<SensorListener, LegacyListener> mLegacyListenersMap = 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashMap<SensorListener, LegacyListener>(); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SENSOR_DISABLE = -1; 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean sSensorModuleInitialized = false; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static ArrayList<Sensor> sFullSensorsList = new ArrayList<Sensor>(); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static SparseArray<List<Sensor>> sSensorListByType = new SparseArray<List<Sensor>>(); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static IWindowManager sWindowManager; 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static int sRotation = Surface.ROTATION_0; 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* The thread and the sensor list are global to the process 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but the actual thread is spawned on demand */ 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static SensorThread sSensorThread; 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Used within this module from outside SensorManager, don't make private 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static SparseArray<Sensor> sHandleToSensor = new SparseArray<Sensor>(); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final ArrayList<ListenerDelegate> sListeners = 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new ArrayList<ListenerDelegate>(); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static private class SensorThread { 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Thread mThread; 346b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian boolean mSensorsReady; 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorThread() { 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this gets to the sensor module. We can have only one per process. 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensors_data_init(); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() { 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensors_data_uninit(); 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // must be called with sListeners lock 359b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian boolean startLocked(ISensorService service) { 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mThread == null) { 362270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood Bundle dataChannel = service.getDataChannel(); 363b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian if (dataChannel != null) { 364b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian mSensorsReady = false; 365b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian SensorThreadRunnable runnable = new SensorThreadRunnable(dataChannel); 366b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian Thread thread = new Thread(runnable, SensorThread.class.getName()); 367b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian thread.start(); 368b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian synchronized (runnable) { 369b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian while (mSensorsReady == false) { 370b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian runnable.wait(); 371b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } 372b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } 373b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian mThread = thread; 374b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "RemoteException in startLocked: ", e); 378b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } catch (InterruptedException e) { 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 380b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian return mThread == null ? false : true; 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class SensorThreadRunnable implements Runnable { 384270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood private Bundle mDataChannel; 385270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood SensorThreadRunnable(Bundle dataChannel) { 386270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood mDataChannel = dataChannel; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 388270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood 389270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood private boolean open() { 390b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian // NOTE: this cannot synchronize on sListeners, since 391b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian // it's held in the main thread at least until we 392b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian // return from here. 393270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood 394270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood // this thread is guaranteed to be unique 395270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood Parcelable[] pfds = mDataChannel.getParcelableArray("fds"); 396270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood FileDescriptor[] fds; 397270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood if (pfds != null) { 398270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood int length = pfds.length; 399270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood fds = new FileDescriptor[length]; 400270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood for (int i = 0; i < length; i++) { 401270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood ParcelFileDescriptor pfd = (ParcelFileDescriptor)pfds[i]; 402270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood fds[i] = pfd.getFileDescriptor(); 403270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood } 404270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood } else { 405270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood fds = null; 406270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood } 407270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood int[] ints = mDataChannel.getIntArray("ints"); 408270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood sensors_data_open(fds, ints); 409270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood if (pfds != null) { 410270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood try { 411270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood // close our copies of the file descriptors, 412270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood // since we are just passing these to the JNI code and not using them here. 413270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood for (int i = pfds.length - 1; i >= 0; i--) { 414270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood ParcelFileDescriptor pfd = (ParcelFileDescriptor)pfds[i]; 415270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood pfd.close(); 416270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood } 417270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood } catch (IOException e) { 418270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood // *shrug* 419270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood Log.e(TAG, "IOException: ", e); 420270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood } 421270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood } 422270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood mDataChannel = null; 423270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood return true; 424270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood } 425270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.d(TAG, "entering main sensor thread"); 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float[] values = new float[3]; 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] status = new int[1]; 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long timestamp[] = new long[1]; 431e417158c06c81c8c4dc6794c5421b711e671c7e3Mathias Agopian Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 433270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood if (!open()) { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 437b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian synchronized (this) { 438b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian // we've open the driver, we're ready to open the sensors 439b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian mSensorsReady = true; 440b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian this.notify(); 441b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } 442b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) { 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // wait for an event 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int sensor = sensors_data_poll(values, status, timestamp); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int accuracy = status[0]; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sListeners) { 4496dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber if (sensor == -1 || sListeners.isEmpty()) { 4506dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber if (sensor == -1) { 4516dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber // we lost the connection to the event stream. this happens 4526dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber // when the last listener is removed. 4536dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber Log.d(TAG, "_sensors_data_poll() failed, we bail out."); 4546dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber } 4556dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber 4566dee6243bf5ecb96291e62ece7d736c5aee1e505Andreas Huber // we have no more listeners or polling failed, terminate the thread 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensors_data_close(); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mThread = null; 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Sensor sensorObject = sHandleToSensor.get(sensor); 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sensorObject != null) { 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // report the sensor event to all listeners that 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // care about it. 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int size = sListeners.size(); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<size ; i++) { 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ListenerDelegate listener = sListeners.get(i); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener.hasSensor(sensorObject)) { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this is asynchronous (okay to call 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sListeners lock held). 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.onSensorChangedLocked(sensorObject, 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values, timestamp, accuracy); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.d(TAG, "exiting main sensor thread"); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /*-----------------------------------------------------------------------*/ 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class ListenerDelegate extends Binder { 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final SensorEventListener mSensorEventListener; 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final ArrayList<Sensor> mSensorList = new ArrayList<Sensor>(); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Handler mHandler; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SensorEvent mValuesPool; 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int mSensors; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ListenerDelegate(SensorEventListener listener, Sensor sensor, Handler handler) { 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorEventListener = listener; 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Looper looper = (handler != null) ? handler.getLooper() : mMainLooper; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // currently we create one Handler instance per listener, but we could 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // have one per looper (we'd need to pass the ListenerDelegate 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // instance to handleMessage and keep track of them separately). 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler = new Handler(looper) { 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorEvent t = (SensorEvent)msg.obj; 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t.accuracy >= 0) { 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorEventListener.onAccuracyChanged(t.sensor, t.accuracy); 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorEventListener.onSensorChanged(t); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project returnToPool(t); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addSensor(sensor); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected SensorEvent createSensorEvent() { 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // maximal size for all legacy events is 3 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new SensorEvent(3); 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected SensorEvent getFromPool() { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorEvent t = null; 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // remove the array from the pool 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t = mValuesPool; 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mValuesPool = null; 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (t == null) { 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the pool was empty, we need a new one 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t = createSensorEvent(); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return t; 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void returnToPool(SensorEvent t) { 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // put back the array into the pool 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mValuesPool == null) { 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mValuesPool = t; 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object getListener() { 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSensorEventListener; 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int addSensor(Sensor sensor) { 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors |= 1<<sensor.getHandle(); 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorList.add(sensor); 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSensors; 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int removeSensor(Sensor sensor) { 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors &= ~(1<<sensor.getHandle()); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorList.remove(sensor); 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSensors; 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hasSensor(Sensor sensor) { 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ((mSensors & (1<<sensor.getHandle())) != 0); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Sensor> getSensors() { 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSensorList; 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onSensorChangedLocked(Sensor sensor, float[] values, long[] timestamp, int accuracy) { 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorEvent t = getFromPool(); 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float[] v = t.values; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[0] = values[0]; 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[1] = values[1]; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[2] = values[2]; 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.timestamp = timestamp[0]; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.accuracy = accuracy; 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project t.sensor = sensor; 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Message msg = Message.obtain(); 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.what = 0; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.obj = t; 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler.sendMessage(msg); 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SensorManager(Looper mainLooper) { 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorService = ISensorService.Stub.asInterface( 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ServiceManager.getService(Context.SENSOR_SERVICE)); 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMainLooper = mainLooper; 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!sSensorModuleInitialized) { 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sSensorModuleInitialized = true; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nativeClassInit(); 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWindowManager = IWindowManager.Stub.asInterface( 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ServiceManager.getService("window")); 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sWindowManager != null) { 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if it's null we're running in the system process 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // which won't get the rotated values 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 598287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian sRotation = sWindowManager.watchRotation( 599287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian new IRotationWatcher.Stub() { 600287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian public void onRotationChanged(int rotation) { 601287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian SensorManager.this.onRotationChanged(rotation); 602287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian } 603287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian } 604287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian ); 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // initialize the sensor list 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensors_module_init(); 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<Sensor> fullList = sFullSensorsList; 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i = 0; 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Sensor sensor = new Sensor(); 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = sensors_module_get_next_sensor(sensor, i); 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i>=0) { 618f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato //Log.d(TAG, "found sensor: " + sensor.getName() + 619f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato // ", handle=" + sensor.getHandle()); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sensor.setLegacyType(getLegacySensorType(sensor.getType())); 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fullList.add(sensor); 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sHandleToSensor.append(sensor.getHandle(), sensor); 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (i>0); 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sSensorThread = new SensorThread(); 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int getLegacySensorType(int type) { 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (type) { 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ACCELEROMETER: 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_ACCELEROMETER; 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_MAGNETIC_FIELD: 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_MAGNETIC_FIELD; 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ORIENTATION: 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_ORIENTATION_RAW; 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_TEMPERATURE: 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SENSOR_TEMPERATURE; 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 64574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian /** 64674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return available sensors. 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 64874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#getSensorList(int)} instead 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getSensors() { 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result = 0; 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<Sensor> fullList = sFullSensorsList; 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Sensor i : fullList) { 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (i.getType()) { 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ACCELEROMETER: 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_ACCELEROMETER; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_MAGNETIC_FIELD: 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_MAGNETIC_FIELD; 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Sensor.TYPE_ORIENTATION: 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result |= SensorManager.SENSOR_ORIENTATION | 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorManager.SENSOR_ORIENTATION_RAW; 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 67274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Use this method to get the list of available sensors of a certain type. 67374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Make multiple calls to get sensors of different types or use 67474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor#TYPE_ALL Sensor.TYPE_ALL} to get all the 67574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensors. 67674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 67774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param type 67874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * of sensors requested 67974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a list of sensors matching the asked type. 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<Sensor> getSensorList(int type) { 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // cache the returned lists the first time 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Sensor> list; 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ArrayList<Sensor> fullList = sFullSensorsList; 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(fullList) { 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = sSensorListByType.get(type); 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (list == null) { 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type == Sensor.TYPE_ALL) { 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = fullList; 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = new ArrayList<Sensor>(); 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Sensor i : fullList) { 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i.getType() == type) 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list.add(i); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list = Collections.unmodifiableList(list); 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sSensorListByType.append(type, list); 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return list; 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 70674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Use this method to get the default sensor for a given type. Note that the 70774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * returned sensor could be a composite sensor, and its data could be 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * averaged or filtered. If you need to access the raw sensors use 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link SensorManager#getSensorList(int) getSensorList}. 71074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 71174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param type 71274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * of sensors requested 71374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the default sensors matching the asked type. 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Sensor getDefaultSensor(int type) { 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: need to be smarter, for now, just return the 1st sensor 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<Sensor> l = getSensorList(type); 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return l.isEmpty() ? null : l.get(0); 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Registers a listener for given sensors. 72474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 72674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#registerListener(SensorEventListener, Sensor, int)} 72774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 72874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 72974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 73074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensor listener object 73174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 73274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensors 73374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a bit masks of the sensors to register to 73474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 73574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> if the sensor is supported and successfully 73674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * enabled 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorListener listener, int sensors) { 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return registerListener(listener, sensors, SENSOR_DELAY_NORMAL); 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Registers a SensorListener for given sensors. 74574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 74774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#registerListener(SensorEventListener, Sensor, int)} 74874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 74974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 75074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 75174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * sensor listener object 75274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 75374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensors 75474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a bit masks of the sensors to register to 75574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 75674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param rate 75774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rate of events. This is only a hint to the system. events may be 75874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * received faster or slower than the specified rate. Usually events 75974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * are received faster. The value must be one of 76074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI}, 76174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}. 76274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 76374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> if the sensor is supported and successfully 76474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * enabled 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorListener listener, int sensors, int rate) { 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result = false; 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER, 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_MAGNETIC_FIELD, Sensor.TYPE_MAGNETIC_FIELD, 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_ORIENTATION_RAW, Sensor.TYPE_ORIENTATION, 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_ORIENTATION, Sensor.TYPE_ORIENTATION, 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerLegacyListener(SENSOR_TEMPERATURE, Sensor.TYPE_TEMPERATURE, 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors, rate) || result; 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean registerLegacyListener(int legacyType, int type, 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorListener listener, int sensors, int rate) 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result = false; 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Are we activating this legacy sensor? 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((sensors & legacyType) != 0) { 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if so, find a suitable Sensor 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Sensor sensor = getDefaultSensor(type); 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sensor != null) { 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we don't already have one, create a LegacyListener 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to wrap this listener and process the events as 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // they are expected by legacy apps. 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LegacyListener legacyListener = null; 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLegacyListenersMap) { 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener = mLegacyListenersMap.get(listener); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (legacyListener == null) { 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we didn't find a LegacyListener for this client, 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // create one, and put it in our list. 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener = new LegacyListener(listener); 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLegacyListenersMap.put(listener, legacyListener); 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // register this legacy sensor with this legacy listener 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener.registerSensor(legacyType); 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and finally, register the legacy listener with the new apis 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = registerListener(legacyListener, sensor, rate); 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for the sensors with which it is registered. 82274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 82474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#unregisterListener(SensorEventListener, Sensor)} 82574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 82674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 82774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 82874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorListener object 82974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 83074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensors 83174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a bit masks of the sensors to unregister from 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorListener listener, int sensors) { 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ACCELEROMETER, Sensor.TYPE_ACCELEROMETER, 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_MAGNETIC_FIELD, Sensor.TYPE_MAGNETIC_FIELD, 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ORIENTATION_RAW, Sensor.TYPE_ORIENTATION, 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_ORIENTATION, Sensor.TYPE_ORIENTATION, 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterLegacyListener(SENSOR_TEMPERATURE, Sensor.TYPE_TEMPERATURE, 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener, sensors); 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void unregisterLegacyListener(int legacyType, int type, 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SensorListener listener, int sensors) 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // do we know about this listener? 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LegacyListener legacyListener = null; 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLegacyListenersMap) { 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project legacyListener = mLegacyListenersMap.get(listener); 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (legacyListener != null) { 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Are we deactivating this legacy sensor? 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((sensors & legacyType) != 0) { 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if so, find the corresponding Sensor 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Sensor sensor = getDefaultSensor(type); 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sensor != null) { 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // unregister this legacy sensor and if we don't 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // need the corresponding Sensor, unregister it too 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (legacyListener.unregisterSensor(legacyType)) { 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // corresponding sensor not needed, unregister 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener(legacyListener, sensor); 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // finally check if we still need the legacyListener 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // in our mapping, if not, get rid of it too. 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean found = false; 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ListenerDelegate i : sListeners) { 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i.getListener() == legacyListener) { 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project found = true; 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!found) { 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLegacyListenersMap) { 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLegacyListenersMap.remove(listener); 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for all sensors. 89474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @deprecated This method is deprecated, use 89674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link SensorManager#unregisterListener(SensorEventListener)} 89774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instead. 89874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 89974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 90074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorListener object 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Deprecated 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorListener listener) { 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener(listener, SENSOR_ALL | SENSOR_ORIENTATION_RAW); 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for the sensors with which it is registered. 90974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 91074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 91174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorEventListener object 91274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensor 91374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the sensor to unregister from 91474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorEventListener listener, Sensor sensor) { 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener((Object)listener, sensor); 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a listener for all sensors. 92274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 92374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 92474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * a SensorListener object 92574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void unregisterListener(SensorEventListener listener) { 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unregisterListener((Object)listener); 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 93274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Registers a {@link android.hardware.SensorEventListener 93374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * SensorEventListener} for the given sensor. 93474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 93574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 93674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A {@link android.hardware.SensorEventListener SensorEventListener} 93774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * object. 93874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 93974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensor 94074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The {@link android.hardware.Sensor Sensor} to register to. 94174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 94274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param rate 94374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The rate {@link android.hardware.SensorEvent sensor events} are 94474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * delivered at. This is only a hint to the system. Events may be 94574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * received faster or slower than the specified rate. Usually events 94674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * are received faster. The value must be one of 94774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI}, 94874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}. 94974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 95074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> if the sensor is supported and successfully 95174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * enabled. 95274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) { 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return registerListener(listener, sensor, rate, null); 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 95974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Registers a {@link android.hardware.SensorEventListener 96074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * SensorEventListener} for the given sensor. 96174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 96274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param listener 96374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * A {@link android.hardware.SensorEventListener SensorEventListener} 96474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * object. 96574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 96674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param sensor 96774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The {@link android.hardware.Sensor Sensor} to register to. 96874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 96974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param rate 97074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The rate {@link android.hardware.SensorEvent sensor events} are 97174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * delivered at. This is only a hint to the system. Events may be 97274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * received faster or slower than the specified rate. Usually events 97374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * are received faster. The value must be one of 97474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI}, 97574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}. 97674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 97774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param handler 97874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The {@link android.os.Handler Handler} the 97974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent sensor events} will be 98074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * delivered to. 98174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the sensor is supported and successfully enabled. 98374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate, 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Handler handler) { 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null || sensor == null) { 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean result; 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int delay = -1; 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (rate) { 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_FASTEST: 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delay = 0; 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_GAME: 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delay = 20; 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_UI: 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delay = 60; 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_DELAY_NORMAL: 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delay = 200; 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sListeners) { 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ListenerDelegate l = null; 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ListenerDelegate i : sListeners) { 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i.getListener() == listener) { 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project l = i; 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = sensor.getName(); 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int handle = sensor.getHandle(); 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (l == null) { 1022b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian result = false; 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project l = new ListenerDelegate(listener, sensor, handler); 1024b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian sListeners.add(l); 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!sListeners.isEmpty()) { 1026b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian result = sSensorThread.startLocked(mSensorService); 1027b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian if (result) { 1028b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian result = mSensorService.enableSensor(l, name, handle, delay); 1029b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian if (!result) { 1030b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian // there was an error, remove the listeners 1031b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian sListeners.remove(l); 1032b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } 1033b3dc5eb4e4143b119491a05e89b186763979ef75Mathias Agopian } 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = mSensorService.enableSensor(l, name, handle, delay); 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result) { 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project l.addSensor(sensor); 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "RemoteException in registerListener: ", e); 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = false; 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void unregisterListener(Object listener, Sensor sensor) { 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null || sensor == null) { 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sListeners) { 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int size = sListeners.size(); 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<size ; i++) { 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ListenerDelegate l = sListeners.get(i); 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (l.getListener() == listener) { 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // disable these sensors 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = sensor.getName(); 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int handle = sensor.getHandle(); 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorService.enableSensor(l, name, handle, SENSOR_DISABLE); 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if we have no more sensors enabled on this listener, 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // take it off the list. 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (l.removeSensor(sensor) == 0) { 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sListeners.remove(i); 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "RemoteException in unregisterListener: ", e); 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void unregisterListener(Object listener) { 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) { 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sListeners) { 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int size = sListeners.size(); 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<size ; i++) { 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ListenerDelegate l = sListeners.get(i); 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (l.getListener() == listener) { 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // disable all sensors for this listener 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Sensor sensor : l.getSensors()) { 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = sensor.getName(); 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int handle = sensor.getHandle(); 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensorService.enableSensor(l, name, handle, SENSOR_DISABLE); 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sListeners.remove(i); 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "RemoteException in unregisterListener: ", e); 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 110474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 110574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Computes the inclination matrix <b>I</b> as well as the rotation matrix 110674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>R</b> transforming a vector from the device coordinate system to the 110774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * world's coordinate system which is defined as a direct orthonormal basis, 110874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * where: 110974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 111174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>X is defined as the vector product <b>Y.Z</b> (It is tangential to 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the ground at the device's current location and roughly points East).</li> 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Y is tangential to the ground at the device's current location and 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * points towards the magnetic North Pole.</li> 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Z points towards the sky and is perpendicular to the ground.</li> 111774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 112074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 112174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * By definition: 112274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 112374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * [0 0 g] = <b>R</b> * <b>gravity</b> (g = magnitude of gravity) 112474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 112574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * [0 m 0] = <b>I</b> * <b>R</b> * <b>geomagnetic</b> (m = magnitude of 112674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * geomagnetic field) 112774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 112874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>R</b> is the identity matrix when the device is aligned with the 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * world's coordinate system, that is, when the device's X axis points 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * toward East, the Y axis points to the North Pole and the device is facing 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the sky. 113274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 113374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 113474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>I</b> is a rotation matrix transforming the geomagnetic vector into 113574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the same coordinate space as gravity (the world's coordinate space). 113674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <b>I</b> is a simple rotation around the X axis. The inclination angle in 113774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * radians can be computed with {@link #getInclination}. 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 114074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 114174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Each matrix is returned either as a 3x3 or 4x4 row-major matrix depending 114274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * on the length of the passed array: 114374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 114474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <u>If the array length is 16:</u> 114574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] M[ 3] \ 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 4] M[ 5] M[ 6] M[ 7] | 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 8] M[ 9] M[10] M[11] | 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ M[12] M[13] M[14] M[15] / 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 115274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 115374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * This matrix is ready to be used by OpenGL ES's 115474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link javax.microedition.khronos.opengles.GL10#glLoadMatrixf(float[], int) 115574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * glLoadMatrixf(float[], int)}. 115674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 115774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Note that because OpenGL matrices are column-major matrices you must 115874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * transpose the matrix before using it. However, since the matrix is a 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * rotation matrix, its transpose is also its inverse, conveniently, it is 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * often the inverse of the rotation that is needed for rendering; it can 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * therefore be used with OpenGL ES directly. 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Also note that the returned matrices always have this form: 116474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] 0 \ 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 4] M[ 5] M[ 6] 0 | 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 8] M[ 9] M[10] 0 | 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ 0 0 0 1 / 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 117174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 117274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 117374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <u>If the array length is 9:</u> 117474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / M[ 0] M[ 1] M[ 2] \ 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | M[ 3] M[ 4] M[ 5] | 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ M[ 6] M[ 7] M[ 8] / 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *</pre> 118074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <hr> 118274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 118374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The inverse of each matrix can be computed easily by taking its 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * transpose. 118574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 118674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 118774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * The matrices returned by this function are meaningful only when the 118874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * device is not free-falling and it is not close to the magnetic north. If 118974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the device is accelerating, or placed into a strong magnetic field, the 119074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * returned matrices may be inaccurate. 119174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 119274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param R 119374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 9 floats holding the rotation matrix <b>R</b> when 119474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * this function returns. R can be null. 119574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 119674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 119774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param I 119874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 9 floats holding the rotation matrix <b>I</b> when 119974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * this function returns. I can be null. 120074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 120174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 120274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param gravity 120374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 3 floats containing the gravity vector expressed in 120474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the device's coordinate. You can simply use the 120574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent#values values} returned by a 120674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent SensorEvent} of a 120774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor Sensor} of type 120874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor#TYPE_ACCELEROMETER 120974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * TYPE_ACCELEROMETER}. 121074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 121174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 121274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param geomagnetic 121374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is an array of 3 floats containing the geomagnetic vector 121474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * expressed in the device's coordinate. You can simply use the 121574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent#values values} returned by a 121674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.SensorEvent SensorEvent} of a 121774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor Sensor} of type 121874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD 121974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * TYPE_MAGNETIC_FIELD}. 122074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 122174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> on success, <code>false</code> on failure (for 122274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * instance, if the device is in free fall). On failure the output 122374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * matrices are not modified. 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean getRotationMatrix(float[] R, float[] I, 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] gravity, float[] geomagnetic) { 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: move this to native code for efficiency 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Ax = gravity[0]; 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Ay = gravity[1]; 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Az = gravity[2]; 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ex = geomagnetic[0]; 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ey = geomagnetic[1]; 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Ez = geomagnetic[2]; 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hx = Ey*Az - Ez*Ay; 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hy = Ez*Ax - Ex*Az; 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float Hz = Ex*Ay - Ey*Ax; 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float normH = (float)Math.sqrt(Hx*Hx + Hy*Hy + Hz*Hz); 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (normH < 0.1f) { 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // device is close to free fall (or in space?), or close to 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // magnetic north pole. Typical values are > 100. 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invH = 1.0f / normH; 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hx *= invH; 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hy *= invH; 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Hz *= invH; 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invA = 1.0f / (float)Math.sqrt(Ax*Ax + Ay*Ay + Az*Az); 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Ax *= invA; 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Ay *= invA; 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Az *= invA; 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Mx = Ay*Hz - Az*Hy; 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float My = Az*Hx - Ax*Hz; 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Mz = Ax*Hy - Ay*Hx; 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R != null) { 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R.length == 9) { 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[0] = Hx; R[1] = Hy; R[2] = Hz; 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[3] = Mx; R[4] = My; R[5] = Mz; 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[6] = Ax; R[7] = Ay; R[8] = Az; 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (R.length == 16) { 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[0] = Hx; R[1] = Hy; R[2] = Hz; R[3] = 0; 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[4] = Mx; R[5] = My; R[6] = Mz; R[7] = 0; 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[8] = Ax; R[9] = Ay; R[10] = Az; R[11] = 0; 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project R[12] = 0; R[13] = 0; R[14] = 0; R[15] = 1; 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I != null) { 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute the inclination matrix by projecting the geomagnetic 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // vector onto the Z (gravity) and X (horizontal component 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // of geomagnetic vector) axes. 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float invE = 1.0f / (float)Math.sqrt(Ex*Ex + Ey*Ey + Ez*Ez); 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float c = (Ex*Mx + Ey*My + Ez*Mz) * invE; 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float s = (Ex*Ax + Ey*Ay + Ez*Az) * invE; 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I.length == 9) { 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[0] = 1; I[1] = 0; I[2] = 0; 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[3] = 0; I[4] = c; I[5] = s; 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[6] = 0; I[7] =-s; I[8] = c; 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (I.length == 16) { 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[0] = 1; I[1] = 0; I[2] = 0; 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[4] = 0; I[5] = c; I[6] = s; 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[8] = 0; I[9] =-s; I[10]= c; 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[3] = I[7] = I[11] = I[12] = I[13] = I[14] = 0; 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project I[15] = 1; 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes the geomagnetic inclination angle in radians from the 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * inclination matrix <b>I</b> returned by {@link #getRotationMatrix}. 129274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 129374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param I 129474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * inclination matrix see {@link #getRotationMatrix}. 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The geomagnetic inclination angle in radians. 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static float getInclination(float[] I) { 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (I.length == 9) { 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (float)Math.atan2(I[5], I[4]); 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (float)Math.atan2(I[6], I[5]); 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 130674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 130774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Rotates the supplied rotation matrix so it is expressed in a different 130874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * coordinate system. This is typically used when an application needs to 130974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * compute the three orientation angles of the device (see 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #getOrientation}) in a different coordinate system. 131174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 131274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 131374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 131474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * When the rotation matrix is used for drawing (for instance with OpenGL 131574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * ES), it usually <b>doesn't need</b> to be transformed by this function, 131674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * unless the screen is physically rotated, in which case you can use 131774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.view.Display#getRotation() Display.getRotation()} to 131874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * retrieve the current rotation of the screen. Note that because the user 131974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is generally free to rotate their screen, you often should consider the 132074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rotation in deciding the parameters to use here. 132174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 132274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 132374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 132474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <u>Examples:</u> 132574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 132674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 132774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 132874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <li>Using the camera (Y axis along the camera's axis) for an augmented 132974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * reality application where the rotation angles are needed:</li> 133074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 133174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 133274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 133374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <code>remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR);</code> 133474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 133574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13375cb70b54156fb305d579a1cc167424c8705bfdf7Dianne Hackborn * <li>Using the device as a mechanical compass when rotation is 133874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.view.Surface#ROTATION_90 Surface.ROTATION_90}:</li> 133974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 134074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 134174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 134274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <code>remapCoordinateSystem(inR, AXIS_Y, AXIS_MINUS_X, outR);</code> 134374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 134474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </p> 134574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 134674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Beware of the above example. This call is needed only to account for a 134774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rotation from its natural orientation when calculating the rotation 134874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * angles (see {@link #getOrientation}). If the rotation matrix is also used 134974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * for rendering, it may not need to be transformed, for instance if your 135074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * {@link android.app.Activity Activity} is running in landscape mode. 135174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 135274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 135374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 135474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * Since the resulting coordinate system is orthonormal, only two axes need 135574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * to be specified. 135674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 135774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param inR 135874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the rotation matrix to be transformed. Usually it is the matrix 135974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * returned by {@link #getRotationMatrix}. 136074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 136174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param X 136274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * defines on which world axis and direction the X axis of the device 136374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is mapped. 136474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 136574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param Y 136674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * defines on which world axis and direction the Y axis of the device 136774cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * is mapped. 136874cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 136974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param outR 137074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * the transformed rotation matrix. inR and outR can be the same 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * array, but it is not recommended for performance reason. 137274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 137374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @return <code>true</code> on success. <code>false</code> if the input 137474cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * parameters are incorrect, for instance if X and Y define the same 137574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * axis. Or if inR and outR don't have the same length. 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean remapCoordinateSystem(float[] inR, int X, int Y, 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] outR) 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inR == outR) { 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float[] temp = mTempMatrix; 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(temp) { 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we don't expect to have a lot of contention 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (remapCoordinateSystemImpl(inR, X, Y, temp)) { 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int size = outR.length; 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<size ; i++) 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[i] = temp[i]; 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return remapCoordinateSystemImpl(inR, X, Y, outR); 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean remapCoordinateSystemImpl(float[] inR, int X, int Y, 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] outR) 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * X and Y define a rotation matrix 'r': 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The 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 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * r[0] ^ r[1] 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * where the 3rd line is the vector product of the first 2 lines 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int length = outR.length; 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inR.length != length) 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // invalid parameter 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((X & 0x7C)!=0 || (Y & 0x7C)!=0) 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // invalid parameter 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((X & 0x3)==0) || ((Y & 0x3)==0)) 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // no axis specified 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((X & 0x3) == (Y & 0x3)) 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; // same axis specified 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Z is "the other" axis, its sign is either +/- sign(X)*sign(Y) 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this can be calculated by exclusive-or'ing X and Y; except for 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the sign inversion (+/-) which is calculated below. 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int Z = X ^ Y; 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // extract the axis (remove the sign), offset in the range 0 to 2. 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int x = (X & 0x3)-1; 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int y = (Y & 0x3)-1; 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int z = (Z & 0x3)-1; 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // compute the sign of Z (whether it needs to be inverted) 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int axis_y = (z+1)%3; 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int axis_z = (z+2)%3; 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((x^axis_y)|(y^axis_z)) != 0) 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Z ^= 0x80; 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sx = (X>=0x80); 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sy = (Y>=0x80); 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean sz = (Z>=0x80); 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Perform R * r, in avoiding actual muls and adds. 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int rowLength = ((length==16)?4:3); 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j=0 ; j<3 ; j++) { 14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int offset = j*rowLength; 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<3 ; i++) { 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x==i) outR[offset+i] = sx ? -inR[offset+0] : inR[offset+0]; 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (y==i) outR[offset+i] = sy ? -inR[offset+1] : inR[offset+1]; 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (z==i) outR[offset+i] = sz ? -inR[offset+2] : inR[offset+2]; 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (length == 16) { 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[3] = outR[7] = outR[11] = outR[12] = outR[13] = outR[14] = 0; 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project outR[15] = 1; 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Computes the device's orientation based on the rotation matrix. 145974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <p> 146074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * When it returns, the array values is filled with the result: 146174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * <ul> 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[0]: <i>azimuth</i>, rotation around the Z axis.</li> 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[1]: <i>pitch</i>, rotation around the X axis.</li> 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>values[2]: <i>roll</i>, rotation around the Y axis.</li> 146574cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * </ul> 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 1467210fc914db37b3cf77ebb3bf75b0b509a1ecb07cMathias Agopian * All three angles above are in <b>radians</b> and <b>positive</b> in the 1468210fc914db37b3cf77ebb3bf75b0b509a1ecb07cMathias Agopian * <b>counter-clockwise</b> direction. 146974cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * 147074cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param R 147174cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * rotation matrix see {@link #getRotationMatrix}. 147274cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * @param values 147374cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian * an array of 3 floats to hold the result. 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The array values passed as argument. 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 147674cde2cee9e53006a710f4e80700cd560c2d0e4dMathias Agopian public static float[] getOrientation(float[] R, float values[]) { 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4x4 (length=16) case: 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / R[ 0] R[ 1] R[ 2] 0 \ 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 4] R[ 5] R[ 6] 0 | 14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 8] R[ 9] R[10] 0 | 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ 0 0 0 1 / 14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3x3 (length=9) case: 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * / R[ 0] R[ 1] R[ 2] \ 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * | R[ 3] R[ 4] R[ 5] | 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * \ R[ 6] R[ 7] R[ 8] / 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (R.length == 9) { 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = (float)Math.atan2(R[1], R[4]); 14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = (float)Math.asin(-R[7]); 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = (float)Math.atan2(-R[6], R[8]); 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = (float)Math.atan2(R[1], R[5]); 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = (float)Math.asin(-R[9]); 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = (float)Math.atan2(-R[8], R[10]); 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return values; 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onRotationChanged(int rotation) { 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sRotation = rotation; 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int getRotation() { 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(sListeners) { 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sRotation; 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class LegacyListener implements SensorEventListener { 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mValues[] = new float[6]; 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SensorListener mTarget; 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSensors; 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final LmsFilter mYawfilter = new LmsFilter(); 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LegacyListener(SensorListener target) { 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget = target; 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors = 0; 15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void registerSensor(int legacyType) { 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors |= legacyType; 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean unregisterSensor(int legacyType) { 15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSensors &= ~legacyType; 15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mask = SENSOR_ORIENTATION|SENSOR_ORIENTATION_RAW; 15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((legacyType&mask)!=0) && ((mSensors&mask)!=0)) { 15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onAccuracyChanged(Sensor sensor, int accuracy) { 15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onAccuracyChanged(sensor.getLegacyType(), accuracy); 15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (AbstractMethodError e) { 15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // old app that doesn't implement this method 15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // just ignore it. 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("deprecation") 15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onSensorChanged(SensorEvent event) { 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float v[] = mValues; 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[0] = event.values[0]; 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[1] = event.values[1]; 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[2] = event.values[2]; 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int legacyType = event.sensor.getLegacyType(); 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mapSensorDataToWindow(legacyType, v, SensorManager.getRotation()); 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) { 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mSensors & SENSOR_ORIENTATION_RAW)!=0) { 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(SENSOR_ORIENTATION_RAW, v); 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mSensors & SENSOR_ORIENTATION)!=0) { 15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v[0] = mYawfilter.filter(event.timestamp, v[0]); 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(SENSOR_ORIENTATION, v); 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTarget.onSensorChanged(legacyType, v); 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Helper function to convert the specified sensor's data to the windows's 15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * coordinate space from the device's coordinate space. 15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * output: 3,4,5: values in the old API format 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 0,1,2: transformed values in the old API format 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void mapSensorDataToWindow(int sensor, 15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] values, int orientation) { 15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x = values[0]; 15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float y = values[1]; 15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float z = values[2]; 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (sensor) { 15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ORIENTATION: 15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ORIENTATION_RAW: 15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z = -z; 15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_ACCELEROMETER: 15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x = -x; 15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y = -y; 15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project z = -z; 15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SensorManager.SENSOR_MAGNETIC_FIELD: 16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x = -x; 16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y = -y; 16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = x; 16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = y; 16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = z; 16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[3] = x; 16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[4] = y; 16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[5] = z; 16107895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian 16117895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian if ((orientation & Surface.ROTATION_90) != 0) { 16127895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian // handles 90 and 270 rotation 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (sensor) { 16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ACCELEROMETER: 16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_MAGNETIC_FIELD: 16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] =-y; 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = x; 16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = z; 16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ORIENTATION: 16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SENSOR_ORIENTATION_RAW: 16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[0] = x + ((x < 270) ? 90 : -270); 16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[1] = z; 16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[2] = y; 16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16287895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian if ((orientation & Surface.ROTATION_180) != 0) { 16297895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian x = values[0]; 16307895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian y = values[1]; 16317895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian z = values[2]; 16327895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian // handles 180 (flip) and 270 (flip + 90) rotation 16337895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian switch (sensor) { 16347895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_ACCELEROMETER: 16357895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_MAGNETIC_FIELD: 16367895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[0] =-x; 16377895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[1] =-y; 16387895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[2] = z; 16397895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian break; 16407895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_ORIENTATION: 16417895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian case SENSOR_ORIENTATION_RAW: 16427895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[0] = (x >= 180) ? (x - 180) : (x + 180); 16437895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[1] =-y; 16447895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian values[2] =-z; 16457895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian break; 16467895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian } 16477895da44e32e9c76e07663aae7084f11cbacbbdbMathias Agopian } 16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1650287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian 16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class LmsFilter { 16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int SENSORS_RATE_MS = 20; 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int COUNT = 12; 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float PREDICTION_RATIO = 1.0f/3.0f; 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float PREDICTION_TIME = (SENSORS_RATE_MS*COUNT/1000.0f)*PREDICTION_RATIO; 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mV[] = new float[COUNT*2]; 16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mT[] = new float[COUNT*2]; 16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mIndex; 16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LmsFilter() { 16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex = COUNT; 16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public float filter(long time, float in) { 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float v = in; 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float ns = 1.0f / 1000000000.0f; 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float t = time*ns; 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float v1 = mV[mIndex]; 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((v-v1) > 180) { 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v -= 360; 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((v1-v) > 180) { 16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v += 360; 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Manage the circular buffer, we write the data twice spaced 16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by COUNT values, so that we don't have to copy the array 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when it's full 16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex++; 16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIndex >= COUNT*2) 16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIndex = COUNT; 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mV[mIndex] = v; 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mT[mIndex] = t; 16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mV[mIndex-COUNT] = v; 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mT[mIndex-COUNT] = t; 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float A, B, C, D, E; 16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float a, b; 16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int i; 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A = B = C = D = E = 0; 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i=0 ; i<COUNT-1 ; i++) { 16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int j = mIndex - 1 - i; 16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float Z = mV[j]; 16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float T = 0.5f*(mT[j] + mT[j+1]) - t; 16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float dT = mT[j] - mT[j+1]; 16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dT *= dT; 16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A += Z*dT; 16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project B += T*(T*dT); 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project C += (T*dT); 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project D += Z*(T*dT); 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project E += dT; 17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b = (A*B + C*D) / (E*B + C*C); 17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = (E*b - A) / C; 17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float f = b + PREDICTION_TIME*a; 17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Normalize 17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f *= (1.0f / 360.0f); 17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (((f>=0)?f:-f) >= 0.5f) 17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f = f - (float)Math.ceil(f + 0.5f) + 1.0f; 17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (f < 0) 17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f += 1.0f; 17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project f *= 360.0f; 17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return f; 17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1718287b30920102b5466efa53a2f17ed69f2c776c16Mathias Agopian 17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void nativeClassInit(); 17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native int sensors_module_init(); 17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native int sensors_module_get_next_sensor(Sensor sensor, int next); 17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Used within this module from outside SensorManager, don't make private 17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static native int sensors_data_init(); 17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static native int sensors_data_uninit(); 1727270e87f71abc2edf446dbec20c725c823e8c7f37Mike Lockwood static native int sensors_data_open(FileDescriptor[] fds, int[] ints); 17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static native int sensors_data_close(); 17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static native int sensors_data_poll(float[] values, int[] status, long[] timestamp); 17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1731