125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown/* 225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * Copyright (C) 2012 The Android Open Source Project 325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * 425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * you may not use this file except in compliance with the License. 625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * You may obtain a copy of the License at 725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * 825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * 1025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * Unless required by applicable law or agreed to in writing, software 1125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 1225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * See the License for the specific language governing permissions and 1425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * limitations under the License. 1525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown */ 1625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 1725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownpackage android.hardware; 1825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 1925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownimport android.os.Looper; 2025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownimport android.os.Process; 2125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownimport android.os.Handler; 2225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownimport android.os.Message; 2325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownimport android.util.Log; 2425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownimport android.util.SparseArray; 2525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownimport android.util.SparseBooleanArray; 2625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownimport android.util.SparseIntArray; 2725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 2825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownimport java.util.ArrayList; 2925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownimport java.util.List; 3025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 3125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown/** 3225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * Sensor manager implementation that communicates with the built-in 3325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * system sensors. 3425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * 3525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * @hide 3625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown */ 3725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownpublic class SystemSensorManager extends SensorManager { 3825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static final int SENSOR_DISABLE = -1; 3925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static boolean sSensorModuleInitialized = false; 4025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static ArrayList<Sensor> sFullSensorsList = new ArrayList<Sensor>(); 4125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /* The thread and the sensor list are global to the process 4225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * but the actual thread is spawned on demand */ 4325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static SensorThread sSensorThread; 4425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static int sQueue; 4525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 4625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // Used within this module from outside SensorManager, don't make private 4725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown static SparseArray<Sensor> sHandleToSensor = new SparseArray<Sensor>(); 4825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown static final ArrayList<ListenerDelegate> sListeners = 4925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown new ArrayList<ListenerDelegate>(); 5025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 514481d9c10ceaf3b886fb5cab1d20941932af5b0fJeff Brown // Common pool of sensor events. 524481d9c10ceaf3b886fb5cab1d20941932af5b0fJeff Brown static SensorEventPool sPool; 5325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 544481d9c10ceaf3b886fb5cab1d20941932af5b0fJeff Brown // Looper associated with the context in which this instance was created. 554481d9c10ceaf3b886fb5cab1d20941932af5b0fJeff Brown final Looper mMainLooper; 5625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 5725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /*-----------------------------------------------------------------------*/ 5825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 5925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown static private class SensorThread { 6025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 6125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Thread mThread; 6225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown boolean mSensorsReady; 6325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 6425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown SensorThread() { 6525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 6625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 6725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown @Override 6825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown protected void finalize() { 6925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 7025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 7125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // must be called with sListeners lock 7225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown boolean startLocked() { 7325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown try { 7425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (mThread == null) { 7525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mSensorsReady = false; 7625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown SensorThreadRunnable runnable = new SensorThreadRunnable(); 7725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Thread thread = new Thread(runnable, SensorThread.class.getName()); 7825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown thread.start(); 7925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown synchronized (runnable) { 8025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown while (mSensorsReady == false) { 8125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown runnable.wait(); 8225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 8325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 8425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mThread = thread; 8525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 8625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } catch (InterruptedException e) { 8725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 8825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return mThread == null ? false : true; 8925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 9025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 9125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private class SensorThreadRunnable implements Runnable { 9225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown SensorThreadRunnable() { 9325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 9425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 9525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private boolean open() { 9625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // NOTE: this cannot synchronize on sListeners, since 9725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // it's held in the main thread at least until we 9825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // return from here. 9925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sQueue = sensors_create_queue(); 10025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return true; 10125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 10225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 10325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown public void run() { 10425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown //Log.d(TAG, "entering main sensor thread"); 10525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final float[] values = new float[3]; 10625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final int[] status = new int[1]; 10725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final long timestamp[] = new long[1]; 10825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY); 10925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 11025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (!open()) { 11125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return; 11225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 11325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 11425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown synchronized (this) { 11525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // we've open the driver, we're ready to open the sensors 11625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mSensorsReady = true; 11725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown this.notify(); 11825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 11925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 12025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown while (true) { 12125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // wait for an event 12225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final int sensor = sensors_data_poll(sQueue, values, status, timestamp); 12325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 12425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown int accuracy = status[0]; 12525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown synchronized (sListeners) { 12625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (sensor == -1 || sListeners.isEmpty()) { 12725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // we lost the connection to the event stream. this happens 12825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // when the last listener is removed or if there is an error 12925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (sensor == -1 && !sListeners.isEmpty()) { 13025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // log a warning in case of abnormal termination 13125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Log.e(TAG, "_sensors_data_poll() failed, we bail out: sensors=" + sensor); 13225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 13325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // we have no more listeners or polling failed, terminate the thread 13425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sensors_destroy_queue(sQueue); 13525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sQueue = 0; 13625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mThread = null; 13725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown break; 13825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 13925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final Sensor sensorObject = sHandleToSensor.get(sensor); 14025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (sensorObject != null) { 14125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // report the sensor event to all listeners that 14225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // care about it. 14325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final int size = sListeners.size(); 14425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown for (int i=0 ; i<size ; i++) { 14525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ListenerDelegate listener = sListeners.get(i); 14625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (listener.hasSensor(sensorObject)) { 14725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // this is asynchronous (okay to call 14825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // with sListeners lock held). 14925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown listener.onSensorChangedLocked(sensorObject, 15025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown values, timestamp, accuracy); 15125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 15225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 15325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 15425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 15525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 15625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown //Log.d(TAG, "exiting main sensor thread"); 15725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 15825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 15925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 16025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 16125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /*-----------------------------------------------------------------------*/ 16225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 16325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private class ListenerDelegate { 16425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private final SensorEventListener mSensorEventListener; 16525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private final ArrayList<Sensor> mSensorList = new ArrayList<Sensor>(); 16625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private final Handler mHandler; 16725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown public SparseBooleanArray mSensors = new SparseBooleanArray(); 16825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown public SparseBooleanArray mFirstEvent = new SparseBooleanArray(); 16925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown public SparseIntArray mSensorAccuracies = new SparseIntArray(); 17025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 17125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ListenerDelegate(SensorEventListener listener, Sensor sensor, Handler handler) { 17225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mSensorEventListener = listener; 17325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Looper looper = (handler != null) ? handler.getLooper() : mMainLooper; 17425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // currently we create one Handler instance per listener, but we could 17525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // have one per looper (we'd need to pass the ListenerDelegate 17625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // instance to handleMessage and keep track of them separately). 17725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mHandler = new Handler(looper) { 17825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown @Override 17925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown public void handleMessage(Message msg) { 18025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final SensorEvent t = (SensorEvent)msg.obj; 18125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final int handle = t.sensor.getHandle(); 18225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 18325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown switch (t.sensor.getType()) { 18425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // Only report accuracy for sensors that support it. 18525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown case Sensor.TYPE_MAGNETIC_FIELD: 18625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown case Sensor.TYPE_ORIENTATION: 18725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // call onAccuracyChanged() only if the value changes 18825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final int accuracy = mSensorAccuracies.get(handle); 18925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if ((t.accuracy >= 0) && (accuracy != t.accuracy)) { 19025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mSensorAccuracies.put(handle, t.accuracy); 19125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mSensorEventListener.onAccuracyChanged(t.sensor, t.accuracy); 19225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 19325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown break; 19425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown default: 19525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // For other sensors, just report the accuracy once 19625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (mFirstEvent.get(handle) == false) { 19725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mFirstEvent.put(handle, true); 19825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mSensorEventListener.onAccuracyChanged( 19925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown t.sensor, SENSOR_STATUS_ACCURACY_HIGH); 20025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 20125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown break; 20225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 20325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 20425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mSensorEventListener.onSensorChanged(t); 20525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sPool.returnToPool(t); 20625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 20725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown }; 20825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown addSensor(sensor); 20925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 21025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 21125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Object getListener() { 21225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return mSensorEventListener; 21325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 21425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 21525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown void addSensor(Sensor sensor) { 21625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mSensors.put(sensor.getHandle(), true); 21725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mSensorList.add(sensor); 21825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 21925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown int removeSensor(Sensor sensor) { 22025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mSensors.delete(sensor.getHandle()); 22125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mSensorList.remove(sensor); 22225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return mSensors.size(); 22325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 22425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown boolean hasSensor(Sensor sensor) { 22525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return mSensors.get(sensor.getHandle()); 22625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 22725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown List<Sensor> getSensors() { 22825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return mSensorList; 22925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 23025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 23125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown void onSensorChangedLocked(Sensor sensor, float[] values, long[] timestamp, int accuracy) { 23225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown SensorEvent t = sPool.getFromPool(); 23325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final float[] v = t.values; 23425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown v[0] = values[0]; 23525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown v[1] = values[1]; 23625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown v[2] = values[2]; 23725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown t.timestamp = timestamp[0]; 23825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown t.accuracy = accuracy; 23925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown t.sensor = sensor; 24025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Message msg = Message.obtain(); 24125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown msg.what = 0; 24225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown msg.obj = t; 24325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown msg.setAsynchronous(true); 24425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mHandler.sendMessage(msg); 24525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 24625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 24725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 24825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /** 24925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * {@hide} 25025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown */ 25125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown public SystemSensorManager(Looper mainLooper) { 25225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mMainLooper = mainLooper; 25325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 25425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown synchronized(sListeners) { 25525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (!sSensorModuleInitialized) { 25625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sSensorModuleInitialized = true; 25725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 25825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown nativeClassInit(); 25925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 26025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // initialize the sensor list 26125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sensors_module_init(); 26225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final ArrayList<Sensor> fullList = sFullSensorsList; 26325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown int i = 0; 26425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown do { 26525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Sensor sensor = new Sensor(); 26625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown i = sensors_module_get_next_sensor(sensor, i); 26725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 26825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (i>=0) { 26925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown //Log.d(TAG, "found sensor: " + sensor.getName() + 27025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // ", handle=" + sensor.getHandle()); 27125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown fullList.add(sensor); 27225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sHandleToSensor.append(sensor.getHandle(), sensor); 27325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 27425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } while (i>0); 27525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 27625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sPool = new SensorEventPool( sFullSensorsList.size()*2 ); 27725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sSensorThread = new SensorThread(); 27825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 27925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 28025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 28125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 28225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /** @hide */ 28325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown @Override 28425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown protected List<Sensor> getFullSensorList() { 28525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return sFullSensorsList; 28625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 28725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 28825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private boolean enableSensorLocked(Sensor sensor, int delay) { 28925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown boolean result = false; 29025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown for (ListenerDelegate i : sListeners) { 29125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (i.hasSensor(sensor)) { 29225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown String name = sensor.getName(); 29325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown int handle = sensor.getHandle(); 29425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown result = sensors_enable_sensor(sQueue, name, handle, delay); 29525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown break; 29625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 29725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 29825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return result; 29925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 30025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 30125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private boolean disableSensorLocked(Sensor sensor) { 30225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown for (ListenerDelegate i : sListeners) { 30325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (i.hasSensor(sensor)) { 30425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // not an error, it's just that this sensor is still in use 30525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return true; 30625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 30725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 30825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown String name = sensor.getName(); 30925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown int handle = sensor.getHandle(); 31025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return sensors_enable_sensor(sQueue, name, handle, SENSOR_DISABLE); 31125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 31225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 31325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /** @hide */ 3144481d9c10ceaf3b886fb5cab1d20941932af5b0fJeff Brown @Override 31525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, 31625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown int delay, Handler handler) { 31725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown boolean result = true; 31825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown synchronized (sListeners) { 31925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // look for this listener in our list 32025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ListenerDelegate l = null; 32125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown for (ListenerDelegate i : sListeners) { 32225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (i.getListener() == listener) { 32325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown l = i; 32425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown break; 32525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 32625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 32725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 32825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // if we don't find it, add it to the list 32925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (l == null) { 33025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown l = new ListenerDelegate(listener, sensor, handler); 33125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sListeners.add(l); 33225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // if the list is not empty, start our main thread 33325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (!sListeners.isEmpty()) { 33425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (sSensorThread.startLocked()) { 33525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (!enableSensorLocked(sensor, delay)) { 33625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // oops. there was an error 33725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sListeners.remove(l); 33825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown result = false; 33925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 34025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } else { 34125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // there was an error, remove the listener 34225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sListeners.remove(l); 34325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown result = false; 34425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 34525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } else { 34625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // weird, we couldn't add the listener 34725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown result = false; 34825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 34925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } else if (!l.hasSensor(sensor)) { 35025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown l.addSensor(sensor); 35125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (!enableSensorLocked(sensor, delay)) { 35225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // oops. there was an error 35325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown l.removeSensor(sensor); 35425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown result = false; 35525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 35625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 35725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 35825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 35925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return result; 36025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 36125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 36225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /** @hide */ 36325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown @Override 36425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) { 36525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown synchronized (sListeners) { 36625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final int size = sListeners.size(); 36725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown for (int i=0 ; i<size ; i++) { 36825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown ListenerDelegate l = sListeners.get(i); 36925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (l.getListener() == listener) { 37025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (sensor == null) { 37125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sListeners.remove(i); 37225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // disable all sensors for this listener 37325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown for (Sensor s : l.getSensors()) { 37425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown disableSensorLocked(s); 37525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 37625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } else if (l.removeSensor(sensor) == 0) { 37725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // if we have no more sensors enabled on this listener, 37825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // take it off the list. 37925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sListeners.remove(i); 38025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown disableSensorLocked(sensor); 38125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 38225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown break; 38325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 38425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 38525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 38625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 38725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 38825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static native void nativeClassInit(); 38925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 39025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static native int sensors_module_init(); 39125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static native int sensors_module_get_next_sensor(Sensor sensor, int next); 39225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 39325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // Used within this module from outside SensorManager, don't make private 39425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown static native int sensors_create_queue(); 39525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown static native void sensors_destroy_queue(int queue); 39625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown static native boolean sensors_enable_sensor(int queue, String name, int sensor, int enable); 39725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown static native int sensors_data_poll(int queue, float[] values, int[] status, long[] timestamp); 39825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown} 399