16d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh /* 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 196d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganeshimport android.content.Context; 2025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownimport android.os.Handler; 21db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianimport android.os.Looper; 22db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopianimport android.os.MessageQueue; 232e90089766c047687662d402819018b308e83d15Jaikumar Ganeshimport android.util.Log; 2425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownimport android.util.SparseArray; 2525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownimport android.util.SparseBooleanArray; 2625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownimport android.util.SparseIntArray; 279a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganeshimport dalvik.system.CloseGuard; 289a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh 299a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganeshimport java.util.ArrayList; 309a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganeshimport java.util.HashMap; 319a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganeshimport java.util.List; 3225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 3325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown/** 3425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * Sensor manager implementation that communicates with the built-in 3525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * system sensors. 3625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * 3725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown * @hide 3825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown */ 3925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brownpublic class SystemSensorManager extends SensorManager { 40db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian private static native void nativeClassInit(); 41db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian private static native int nativeGetNextSensor(Sensor sensor, int next); 42db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 4325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown private static boolean sSensorModuleInitialized = false; 44db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian private static final Object sSensorModuleLock = new Object(); 45db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian private static final ArrayList<Sensor> sFullSensorsList = new ArrayList<Sensor>(); 46db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian private static final SparseArray<Sensor> sHandleToSensor = new SparseArray<Sensor>(); 4725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 48db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian // Listener list 499a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh private final HashMap<SensorEventListener, SensorEventQueue> mSensorListeners = 509a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh new HashMap<SensorEventListener, SensorEventQueue>(); 519a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh private final HashMap<TriggerEventListener, TriggerEventQueue> mTriggerListeners = 529a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh new HashMap<TriggerEventListener, TriggerEventQueue>(); 5325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 544481d9c10ceaf3b886fb5cab1d20941932af5b0fJeff Brown // Looper associated with the context in which this instance was created. 55db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian private final Looper mMainLooper; 566d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh private final int mTargetSdkLevel; 5725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 58db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian /** {@hide} */ 596d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh public SystemSensorManager(Context context, Looper mainLooper) { 6025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown mMainLooper = mainLooper; 616d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion; 62db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian synchronized(sSensorModuleLock) { 6325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (!sSensorModuleInitialized) { 6425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sSensorModuleInitialized = true; 6525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 6625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown nativeClassInit(); 6725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 6825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // initialize the sensor list 6925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown final ArrayList<Sensor> fullList = sFullSensorsList; 7025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown int i = 0; 7125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown do { 7225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown Sensor sensor = new Sensor(); 73db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian i = nativeGetNextSensor(sensor, i); 7425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown if (i>=0) { 7525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown //Log.d(TAG, "found sensor: " + sensor.getName() + 7625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown // ", handle=" + sensor.getHandle()); 7725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown fullList.add(sensor); 7825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown sHandleToSensor.append(sensor.getHandle(), sensor); 7925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 8025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } while (i>0); 8125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 8225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 8325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 8425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 85db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 8625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /** @hide */ 8725157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown @Override 8825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown protected List<Sensor> getFullSensorList() { 8925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown return sFullSensorsList; 9025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 9125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 92db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 93db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian /** @hide */ 94db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian @Override 95db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, 964bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) { 974bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella if (listener == null || sensor == null) { 984bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella Log.e(TAG, "sensor or listener is null"); 994bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella return false; 1004bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella } 101b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella // Trigger Sensors should use the requestTriggerSensor call. 1024bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) { 1034bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella Log.e(TAG, "Trigger Sensors should use the requestTriggerSensor."); 1044bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella return false; 1054bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella } 1064bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella if (maxBatchReportLatencyUs < 0 || delayUs < 0) { 1074bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella Log.e(TAG, "maxBatchReportLatencyUs and delayUs should be non-negative"); 1084bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella return false; 1094bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella } 110b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 111db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian // Invariants to preserve: 112db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian // - one Looper per SensorEventListener 113db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian // - one Looper per SensorEventQueue 1149a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh // We map SensorEventListener to a SensorEventQueue, which holds the looper 1159a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh synchronized (mSensorListeners) { 1169a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh SensorEventQueue queue = mSensorListeners.get(listener); 1179a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh if (queue == null) { 118db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian Looper looper = (handler != null) ? handler.getLooper() : mMainLooper; 1194bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella queue = new SensorEventQueue(listener, looper, this); 120b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags)) { 121db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian queue.dispose(); 1229a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh return false; 123db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 1249a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh mSensorListeners.put(listener, queue); 1259a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh return true; 1269a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh } else { 127b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags); 12825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 12925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 13025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 13125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 13225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown /** @hide */ 1334481d9c10ceaf3b886fb5cab1d20941932af5b0fJeff Brown @Override 134db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) { 1359a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh // Trigger Sensors should use the cancelTriggerSensor call. 1369a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh if (sensor != null && Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) { 1379a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh return; 1389a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh } 13925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 1409a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh synchronized (mSensorListeners) { 1419a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh SensorEventQueue queue = mSensorListeners.get(listener); 142db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (queue != null) { 1439a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh boolean result; 1449a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh if (sensor == null) { 1459a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh result = queue.removeAllSensors(); 14625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } else { 1472e90089766c047687662d402819018b308e83d15Jaikumar Ganesh result = queue.removeSensor(sensor, true); 14825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 1499a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh if (result && !queue.hasSensors()) { 1509a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh mSensorListeners.remove(listener); 151db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian queue.dispose(); 15225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 15325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 15425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 155db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 15625157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 1579a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh /** @hide */ 1589a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh @Override 1599a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) { 1609a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh if (sensor == null) throw new IllegalArgumentException("sensor cannot be null"); 1619a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh 1629a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh if (Sensor.getReportingMode(sensor) != Sensor.REPORTING_MODE_ONE_SHOT) return false; 163db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 1649a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh synchronized (mTriggerListeners) { 1659a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh TriggerEventQueue queue = mTriggerListeners.get(listener); 1669a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh if (queue == null) { 1679a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh queue = new TriggerEventQueue(listener, mMainLooper, this); 168b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella if (!queue.addSensor(sensor, 0, 0, 0)) { 1699a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh queue.dispose(); 1709a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh return false; 1719a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh } 1729a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh mTriggerListeners.put(listener, queue); 1739a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh return true; 1741aab1dbca5cf7386797ce609c768249247233186Jaikumar Ganesh } else { 175b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella return queue.addSensor(sensor, 0, 0, 0); 1769a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh } 1779a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh } 1789a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh } 1799a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh 1809a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh /** @hide */ 1819a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh @Override 1822e90089766c047687662d402819018b308e83d15Jaikumar Ganesh protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor, 1832e90089766c047687662d402819018b308e83d15Jaikumar Ganesh boolean disable) { 1849a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh if (sensor != null && Sensor.getReportingMode(sensor) != Sensor.REPORTING_MODE_ONE_SHOT) { 1859a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh return false; 1869a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh } 1879a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh synchronized (mTriggerListeners) { 1889a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh TriggerEventQueue queue = mTriggerListeners.get(listener); 1899a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh if (queue != null) { 1909a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh boolean result; 1919a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh if (sensor == null) { 1929a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh result = queue.removeAllSensors(); 1939a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh } else { 1942e90089766c047687662d402819018b308e83d15Jaikumar Ganesh result = queue.removeSensor(sensor, disable); 1959a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh } 1969a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh if (result && !queue.hasSensors()) { 1979a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh mTriggerListeners.remove(listener); 1989a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh queue.dispose(); 1999a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh } 2009a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh return result; 201db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 2029a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh return false; 203db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 20425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 20525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 2064bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella protected boolean flushImpl(SensorEventListener listener) { 2074bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella if (listener == null) throw new IllegalArgumentException("listener cannot be null"); 208b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 2094bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella synchronized (mSensorListeners) { 2104bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella SensorEventQueue queue = mSensorListeners.get(listener); 2114bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella if (queue == null) { 2124bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella return false; 2134bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella } else { 2144bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella return (queue.flush() == 0); 2154bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella } 216b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella } 217b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella } 218b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 219db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian /* 2209a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh * BaseEventQueue is the communication channel with the sensor service, 2219a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh * SensorEventQueue, TriggerEventQueue are subclases and there is one-to-one mapping between 2229a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh * the queues and the listeners. 223db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian */ 2249a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh private static abstract class BaseEventQueue { 2259a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh private native int nativeInitBaseEventQueue(BaseEventQueue eventQ, MessageQueue msgQ, 2269a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh float[] scratch); 227b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella private static native int nativeEnableSensor(int eventQ, int handle, int rateUs, 228b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella int maxBatchReportLatencyUs, int reservedFlags); 229db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian private static native int nativeDisableSensor(int eventQ, int handle); 230db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian private static native void nativeDestroySensorEventQueue(int eventQ); 2314bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella private static native int nativeFlushSensor(int eventQ); 232db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian private int nSensorEventQueue; 233db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian private final SparseBooleanArray mActiveSensors = new SparseBooleanArray(); 2349a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh protected final SparseIntArray mSensorAccuracies = new SparseIntArray(); 2359a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh protected final SparseBooleanArray mFirstEvent = new SparseBooleanArray(); 236db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian private final CloseGuard mCloseGuard = CloseGuard.get(); 237db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian private final float[] mScratch = new float[16]; 2386d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh protected final SystemSensorManager mManager; 239db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 2406d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh BaseEventQueue(Looper looper, SystemSensorManager manager) { 2419a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh nSensorEventQueue = nativeInitBaseEventQueue(this, looper.getQueue(), mScratch); 242db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mCloseGuard.open("dispose"); 2436d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh mManager = manager; 244db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 2459a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh 246db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian public void dispose() { 247db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian dispose(false); 248db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 249db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 250b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella public boolean addSensor( 251b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella Sensor sensor, int delayUs, int maxBatchReportLatencyUs, int reservedFlags) { 2529a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh // Check if already present. 2532e90089766c047687662d402819018b308e83d15Jaikumar Ganesh int handle = sensor.getHandle(); 2542e90089766c047687662d402819018b308e83d15Jaikumar Ganesh if (mActiveSensors.get(handle)) return false; 2552e90089766c047687662d402819018b308e83d15Jaikumar Ganesh 2562e90089766c047687662d402819018b308e83d15Jaikumar Ganesh // Get ready to receive events before calling enable. 2572e90089766c047687662d402819018b308e83d15Jaikumar Ganesh mActiveSensors.put(handle, true); 2582e90089766c047687662d402819018b308e83d15Jaikumar Ganesh addSensorEvent(sensor); 259b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags) != 0) { 260b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella // Try continuous mode if batching fails. 261b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella if (maxBatchReportLatencyUs == 0 || 262b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0, 0) != 0) { 263b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella removeSensor(sensor, false); 264b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella return false; 265b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella } 266db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 2672e90089766c047687662d402819018b308e83d15Jaikumar Ganesh return true; 268db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 269db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 2709a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh public boolean removeAllSensors() { 271db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian for (int i=0 ; i<mActiveSensors.size(); i++) { 272db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (mActiveSensors.valueAt(i) == true) { 273db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian int handle = mActiveSensors.keyAt(i); 274db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian Sensor sensor = sHandleToSensor.get(handle); 275db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (sensor != null) { 276db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian disableSensor(sensor); 277db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mActiveSensors.put(handle, false); 2786d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh removeSensorEvent(sensor); 279db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } else { 280db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian // it should never happen -- just ignore. 28125157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 28225157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 28325157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 2849a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh return true; 28525157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 286db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 2872e90089766c047687662d402819018b308e83d15Jaikumar Ganesh public boolean removeSensor(Sensor sensor, boolean disable) { 288db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian final int handle = sensor.getHandle(); 289db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (mActiveSensors.get(handle)) { 2902e90089766c047687662d402819018b308e83d15Jaikumar Ganesh if (disable) disableSensor(sensor); 291db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mActiveSensors.put(sensor.getHandle(), false); 2926d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh removeSensorEvent(sensor); 2939a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh return true; 294db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 2959a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh return false; 296db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 297db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 2984bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella public int flush() { 299b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella if (nSensorEventQueue == 0) throw new NullPointerException(); 3004bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella return nativeFlushSensor(nSensorEventQueue); 301b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella } 302b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 303db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian public boolean hasSensors() { 304db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian // no more sensors are set 305db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return mActiveSensors.indexOfValue(true) >= 0; 306db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 3079a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh 308db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian @Override 309db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian protected void finalize() throws Throwable { 310db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian try { 311db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian dispose(true); 312db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } finally { 313db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian super.finalize(); 314db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 315db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 316db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 317db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian private void dispose(boolean finalized) { 318db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (mCloseGuard != null) { 319db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (finalized) { 320db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mCloseGuard.warnIfOpen(); 321db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 322db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian mCloseGuard.close(); 323db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 324db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (nSensorEventQueue != 0) { 325db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian nativeDestroySensorEventQueue(nSensorEventQueue); 326db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian nSensorEventQueue = 0; 327db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 328db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 329db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 330b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella private int enableSensor( 331b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella Sensor sensor, int rateUs, int maxBatchReportLatencyUs, int reservedFlags) { 332db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (nSensorEventQueue == 0) throw new NullPointerException(); 333db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (sensor == null) throw new NullPointerException(); 334b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella return nativeEnableSensor(nSensorEventQueue, sensor.getHandle(), rateUs, 335b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella maxBatchReportLatencyUs, reservedFlags); 336db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 337b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 338db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian private int disableSensor(Sensor sensor) { 339db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (nSensorEventQueue == 0) throw new NullPointerException(); 340db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian if (sensor == null) throw new NullPointerException(); 341db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian return nativeDisableSensor(nSensorEventQueue, sensor.getHandle()); 342db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 3439a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy, 3449a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh long timestamp); 345b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella protected abstract void dispatchFlushCompleteEvent(int handle); 3466d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh 3476d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh protected abstract void addSensorEvent(Sensor sensor); 3486d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh protected abstract void removeSensorEvent(Sensor sensor); 3499a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh } 3509a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh 3519a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh static final class SensorEventQueue extends BaseEventQueue { 3529a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh private final SensorEventListener mListener; 3536d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>(); 3549a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh 3556d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh public SensorEventQueue(SensorEventListener listener, Looper looper, 3564bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella SystemSensorManager manager) { 3576d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh super(looper, manager); 3589a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh mListener = listener; 3599a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh } 360db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian 36131d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella @Override 3626d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh public void addSensorEvent(Sensor sensor) { 3636d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor, 3646d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh mManager.mTargetSdkLevel)); 36531d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella synchronized (mSensorsEvents) { 36631d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella mSensorsEvents.put(sensor.getHandle(), t); 36731d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella } 3686d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh } 3696d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh 37031d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella @Override 3716d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh public void removeSensorEvent(Sensor sensor) { 37231d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella synchronized (mSensorsEvents) { 37331d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella mSensorsEvents.delete(sensor.getHandle()); 37431d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella } 3756d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh } 3766d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh 377db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian // Called from native code. 378db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian @SuppressWarnings("unused") 3799a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh @Override 3809a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy, 3819a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh long timestamp) { 3829a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh final Sensor sensor = sHandleToSensor.get(handle); 38331d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella SensorEvent t = null; 38431d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella synchronized (mSensorsEvents) { 38531d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella t = mSensorsEvents.get(handle); 38631d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella } 38731d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella 3882e90089766c047687662d402819018b308e83d15Jaikumar Ganesh if (t == null) { 38931d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella // This may happen if the client has unregistered and there are pending events in 39031d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella // the queue waiting to be delivered. Ignore. 3912e90089766c047687662d402819018b308e83d15Jaikumar Ganesh return; 3922e90089766c047687662d402819018b308e83d15Jaikumar Ganesh } 3936d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh // Copy from the values array. 3946d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh System.arraycopy(values, 0, t.values, 0, t.values.length); 3956d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh t.timestamp = timestamp; 3966d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh t.accuracy = inAccuracy; 3976d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh t.sensor = sensor; 3986d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh switch (t.sensor.getType()) { 3996d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh // Only report accuracy for sensors that support it. 4006d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh case Sensor.TYPE_MAGNETIC_FIELD: 4016d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh case Sensor.TYPE_ORIENTATION: 4026d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh // call onAccuracyChanged() only if the value changes 4036d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh final int accuracy = mSensorAccuracies.get(handle); 4046d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh if ((t.accuracy >= 0) && (accuracy != t.accuracy)) { 4056d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh mSensorAccuracies.put(handle, t.accuracy); 4066d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh mListener.onAccuracyChanged(t.sensor, t.accuracy); 4076d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh } 4086d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh break; 4096d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh default: 4106d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh // For other sensors, just report the accuracy once 4116d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh if (mFirstEvent.get(handle) == false) { 4126d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh mFirstEvent.put(handle, true); 4136d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh mListener.onAccuracyChanged( 4146d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh t.sensor, SENSOR_STATUS_ACCURACY_HIGH); 4156d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh } 4166d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh break; 417db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 4186d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh mListener.onSensorChanged(t); 419db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 420b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 421b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella @SuppressWarnings("unused") 422b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella protected void dispatchFlushCompleteEvent(int handle) { 4234bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella if (mListener instanceof SensorEventListener2) { 4244bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella final Sensor sensor = sHandleToSensor.get(handle); 4254bdc37d315a6dbdcf2425e70423ec43d7b74e102Aravind Akella ((SensorEventListener2)mListener).onFlushCompleted(sensor); 426b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella } 427b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella return; 428b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella } 42925157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown } 43025157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 4319a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh static final class TriggerEventQueue extends BaseEventQueue { 4329a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh private final TriggerEventListener mListener; 4336d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh private final SparseArray<TriggerEvent> mTriggerEvents = new SparseArray<TriggerEvent>(); 43425157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown 4359a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh public TriggerEventQueue(TriggerEventListener listener, Looper looper, 4366d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh SystemSensorManager manager) { 4376d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh super(looper, manager); 4389a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh mListener = listener; 4396d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh } 4406d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh 44131d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella @Override 4426d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh public void addSensorEvent(Sensor sensor) { 4436d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh TriggerEvent t = new TriggerEvent(Sensor.getMaxLengthValuesArray(sensor, 4446d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh mManager.mTargetSdkLevel)); 44531d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella synchronized (mTriggerEvents) { 44631d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella mTriggerEvents.put(sensor.getHandle(), t); 44731d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella } 4486d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh } 4496d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh 45031d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella @Override 4516d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh public void removeSensorEvent(Sensor sensor) { 45231d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella synchronized (mTriggerEvents) { 45331d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella mTriggerEvents.delete(sensor.getHandle()); 45431d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella } 4551aab1dbca5cf7386797ce609c768249247233186Jaikumar Ganesh } 456bc03a348d78326dee779a8ecc325799c9fceac98Jaikumar Ganesh 4579a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh // Called from native code. 4589a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh @SuppressWarnings("unused") 4599a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh @Override 4606d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh protected void dispatchSensorEvent(int handle, float[] values, int accuracy, 4616d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh long timestamp) { 4629a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh final Sensor sensor = sHandleToSensor.get(handle); 46331d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella TriggerEvent t = null; 46431d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella synchronized (mTriggerEvents) { 46531d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella t = mTriggerEvents.get(handle); 46631d14ce57ca230588d8ffe991ee827b12d8ed17eAravind Akella } 4672e90089766c047687662d402819018b308e83d15Jaikumar Ganesh if (t == null) { 4682e90089766c047687662d402819018b308e83d15Jaikumar Ganesh Log.e(TAG, "Error: Trigger Event is null for Sensor: " + sensor); 4692e90089766c047687662d402819018b308e83d15Jaikumar Ganesh return; 4702e90089766c047687662d402819018b308e83d15Jaikumar Ganesh } 471bc03a348d78326dee779a8ecc325799c9fceac98Jaikumar Ganesh 4726d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh // Copy from the values array. 4736d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh System.arraycopy(values, 0, t.values, 0, t.values.length); 4746d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh t.timestamp = timestamp; 4756d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh t.sensor = sensor; 4769a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh 4772e90089766c047687662d402819018b308e83d15Jaikumar Ganesh // A trigger sensor is auto disabled. So just clean up and don't call native 4782e90089766c047687662d402819018b308e83d15Jaikumar Ganesh // disable. 4792e90089766c047687662d402819018b308e83d15Jaikumar Ganesh mManager.cancelTriggerSensorImpl(mListener, sensor, false); 4809a8df4dcf9f83c1cf0cd8dedeb51d1ff8a52a2b5Jaikumar Ganesh 4816d0c1d78f121d4f1b72973740e8b120c7def1dc0Jaikumar Ganesh mListener.onTrigger(t); 482db772d813492517dce2bd7e6e9fbc88e42b30c02Mathias Agopian } 483b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella 484b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella @SuppressWarnings("unused") 485b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella protected void dispatchFlushCompleteEvent(int handle) { 486b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella } 487b4c76b18a369d940f448bcc55d7245b6b30084ddAravind Akella } 48825157e458d6e10b027d1ba6b78b0487156c9f57aJeff Brown} 489