blob: 88fa339a53cbb85957952f2d6b63b6a6f001419d [file] [log] [blame]
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -07001 /*
Jeff Brown25157e42012-04-16 12:13:05 -07002 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.hardware;
18
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -070019import android.content.Context;
Jeff Brown25157e42012-04-16 12:13:05 -070020import android.os.Handler;
Mathias Agopiandb772d82013-01-31 19:31:12 -080021import android.os.Looper;
22import android.os.MessageQueue;
Jaikumar Ganesh2e900892013-04-11 10:40:33 -070023import android.util.Log;
Jeff Brown25157e42012-04-16 12:13:05 -070024import android.util.SparseArray;
25import android.util.SparseBooleanArray;
26import android.util.SparseIntArray;
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -080027import dalvik.system.CloseGuard;
28
29import java.util.ArrayList;
30import java.util.HashMap;
31import java.util.List;
Jeff Brown25157e42012-04-16 12:13:05 -070032
Jeff Brown25157e42012-04-16 12:13:05 -070033/**
34 * Sensor manager implementation that communicates with the built-in
35 * system sensors.
36 *
37 * @hide
38 */
39public class SystemSensorManager extends SensorManager {
Mathias Agopiandb772d82013-01-31 19:31:12 -080040 private static native void nativeClassInit();
41 private static native int nativeGetNextSensor(Sensor sensor, int next);
Jeff Brown25157e42012-04-16 12:13:05 -070042
Mathias Agopiandb772d82013-01-31 19:31:12 -080043 private static boolean sSensorModuleInitialized = false;
44 private static final Object sSensorModuleLock = new Object();
45 private static final ArrayList<Sensor> sFullSensorsList = new ArrayList<Sensor>();
46 private static final SparseArray<Sensor> sHandleToSensor = new SparseArray<Sensor>();
47
48 // Listener list
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -080049 private final HashMap<SensorEventListener, SensorEventQueue> mSensorListeners =
50 new HashMap<SensorEventListener, SensorEventQueue>();
51 private final HashMap<TriggerEventListener, TriggerEventQueue> mTriggerListeners =
52 new HashMap<TriggerEventListener, TriggerEventQueue>();
Jeff Brown25157e42012-04-16 12:13:05 -070053
Jeff Brown4481d9c2012-04-16 16:14:44 -070054 // Looper associated with the context in which this instance was created.
Mathias Agopiandb772d82013-01-31 19:31:12 -080055 private final Looper mMainLooper;
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -070056 private final int mTargetSdkLevel;
Aravind Akella88445992015-02-26 17:05:28 -080057 private final String mPackageName;
Jeff Brown25157e42012-04-16 12:13:05 -070058
Mathias Agopiandb772d82013-01-31 19:31:12 -080059 /** {@hide} */
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -070060 public SystemSensorManager(Context context, Looper mainLooper) {
Jeff Brown25157e42012-04-16 12:13:05 -070061 mMainLooper = mainLooper;
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -070062 mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;
Aravind Akella88445992015-02-26 17:05:28 -080063 mPackageName = context.getPackageName();
Mathias Agopiandb772d82013-01-31 19:31:12 -080064 synchronized(sSensorModuleLock) {
Jeff Brown25157e42012-04-16 12:13:05 -070065 if (!sSensorModuleInitialized) {
66 sSensorModuleInitialized = true;
67
68 nativeClassInit();
69
70 // initialize the sensor list
Jeff Brown25157e42012-04-16 12:13:05 -070071 final ArrayList<Sensor> fullList = sFullSensorsList;
72 int i = 0;
73 do {
74 Sensor sensor = new Sensor();
Mathias Agopiandb772d82013-01-31 19:31:12 -080075 i = nativeGetNextSensor(sensor, i);
Jeff Brown25157e42012-04-16 12:13:05 -070076 if (i>=0) {
77 //Log.d(TAG, "found sensor: " + sensor.getName() +
78 // ", handle=" + sensor.getHandle());
79 fullList.add(sensor);
80 sHandleToSensor.append(sensor.getHandle(), sensor);
81 }
82 } while (i>0);
Jeff Brown25157e42012-04-16 12:13:05 -070083 }
84 }
85 }
86
Mathias Agopiandb772d82013-01-31 19:31:12 -080087
Jeff Brown25157e42012-04-16 12:13:05 -070088 /** @hide */
89 @Override
90 protected List<Sensor> getFullSensorList() {
91 return sFullSensorsList;
92 }
93
Jeff Brown25157e42012-04-16 12:13:05 -070094
95 /** @hide */
Jeff Brown4481d9c2012-04-16 16:14:44 -070096 @Override
Jeff Brown25157e42012-04-16 12:13:05 -070097 protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
Aravind Akella4bdc37d2013-10-01 17:58:35 -070098 int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
99 if (listener == null || sensor == null) {
100 Log.e(TAG, "sensor or listener is null");
101 return false;
102 }
Aravind Akellab4c76b12013-06-27 12:04:16 -0700103 // Trigger Sensors should use the requestTriggerSensor call.
Aravind Akella27900352014-06-03 19:20:42 -0700104 if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
Aravind Akella4bdc37d2013-10-01 17:58:35 -0700105 Log.e(TAG, "Trigger Sensors should use the requestTriggerSensor.");
106 return false;
107 }
108 if (maxBatchReportLatencyUs < 0 || delayUs < 0) {
109 Log.e(TAG, "maxBatchReportLatencyUs and delayUs should be non-negative");
110 return false;
111 }
Aravind Akellab4c76b12013-06-27 12:04:16 -0700112
Mathias Agopiandb772d82013-01-31 19:31:12 -0800113 // Invariants to preserve:
114 // - one Looper per SensorEventListener
115 // - one Looper per SensorEventQueue
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800116 // We map SensorEventListener to a SensorEventQueue, which holds the looper
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800117 synchronized (mSensorListeners) {
118 SensorEventQueue queue = mSensorListeners.get(listener);
119 if (queue == null) {
Jaikumar Ganesh1aab1db2013-03-13 15:00:21 -0700120 Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
Aravind Akella4bdc37d2013-10-01 17:58:35 -0700121 queue = new SensorEventQueue(listener, looper, this);
Aravind Akella88445992015-02-26 17:05:28 -0800122 if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
Jaikumar Ganesh1aab1db2013-03-13 15:00:21 -0700123 queue.dispose();
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800124 return false;
Jaikumar Ganesh1aab1db2013-03-13 15:00:21 -0700125 }
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800126 mSensorListeners.put(listener, queue);
127 return true;
128 } else {
Aravind Akella88445992015-02-26 17:05:28 -0800129 return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
Jeff Brown25157e42012-04-16 12:13:05 -0700130 }
131 }
Jeff Brown25157e42012-04-16 12:13:05 -0700132 }
133
134 /** @hide */
135 @Override
136 protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800137 // Trigger Sensors should use the cancelTriggerSensor call.
Aravind Akella27900352014-06-03 19:20:42 -0700138 if (sensor != null && sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800139 return;
140 }
Mathias Agopiandb772d82013-01-31 19:31:12 -0800141
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800142 synchronized (mSensorListeners) {
143 SensorEventQueue queue = mSensorListeners.get(listener);
Jaikumar Ganesh1aab1db2013-03-13 15:00:21 -0700144 if (queue != null) {
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800145 boolean result;
146 if (sensor == null) {
147 result = queue.removeAllSensors();
Jaikumar Ganesh1aab1db2013-03-13 15:00:21 -0700148 } else {
Jaikumar Ganesh2e900892013-04-11 10:40:33 -0700149 result = queue.removeSensor(sensor, true);
Jaikumar Ganesh1aab1db2013-03-13 15:00:21 -0700150 }
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800151 if (result && !queue.hasSensors()) {
152 mSensorListeners.remove(listener);
Mathias Agopiandb772d82013-01-31 19:31:12 -0800153 queue.dispose();
Jeff Brown25157e42012-04-16 12:13:05 -0700154 }
155 }
156 }
157 }
158
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800159 /** @hide */
160 @Override
161 protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
162 if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
Jeff Brown25157e42012-04-16 12:13:05 -0700163
Aravind Akella27900352014-06-03 19:20:42 -0700164 if (sensor.getReportingMode() != Sensor.REPORTING_MODE_ONE_SHOT) return false;
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800165
166 synchronized (mTriggerListeners) {
167 TriggerEventQueue queue = mTriggerListeners.get(listener);
168 if (queue == null) {
169 queue = new TriggerEventQueue(listener, mMainLooper, this);
Aravind Akella88445992015-02-26 17:05:28 -0800170 if (!queue.addSensor(sensor, 0, 0)) {
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800171 queue.dispose();
172 return false;
173 }
174 mTriggerListeners.put(listener, queue);
175 return true;
Mathias Agopiandb772d82013-01-31 19:31:12 -0800176 } else {
Aravind Akella88445992015-02-26 17:05:28 -0800177 return queue.addSensor(sensor, 0, 0);
Mathias Agopiandb772d82013-01-31 19:31:12 -0800178 }
179 }
180 }
Jeff Brown25157e42012-04-16 12:13:05 -0700181
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800182 /** @hide */
183 @Override
Jaikumar Ganesh2e900892013-04-11 10:40:33 -0700184 protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor,
185 boolean disable) {
Aravind Akella27900352014-06-03 19:20:42 -0700186 if (sensor != null && sensor.getReportingMode() != Sensor.REPORTING_MODE_ONE_SHOT) {
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800187 return false;
188 }
189 synchronized (mTriggerListeners) {
190 TriggerEventQueue queue = mTriggerListeners.get(listener);
191 if (queue != null) {
192 boolean result;
193 if (sensor == null) {
194 result = queue.removeAllSensors();
195 } else {
Jaikumar Ganesh2e900892013-04-11 10:40:33 -0700196 result = queue.removeSensor(sensor, disable);
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800197 }
198 if (result && !queue.hasSensors()) {
199 mTriggerListeners.remove(listener);
200 queue.dispose();
201 }
202 return result;
203 }
204 return false;
205 }
206 }
207
Aravind Akella4bdc37d2013-10-01 17:58:35 -0700208 protected boolean flushImpl(SensorEventListener listener) {
209 if (listener == null) throw new IllegalArgumentException("listener cannot be null");
Aravind Akellab4c76b12013-06-27 12:04:16 -0700210
Aravind Akella4bdc37d2013-10-01 17:58:35 -0700211 synchronized (mSensorListeners) {
212 SensorEventQueue queue = mSensorListeners.get(listener);
213 if (queue == null) {
214 return false;
215 } else {
216 return (queue.flush() == 0);
217 }
Aravind Akellab4c76b12013-06-27 12:04:16 -0700218 }
Aravind Akellab4c76b12013-06-27 12:04:16 -0700219 }
220
Mathias Agopiandb772d82013-01-31 19:31:12 -0800221 /*
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800222 * BaseEventQueue is the communication channel with the sensor service,
223 * SensorEventQueue, TriggerEventQueue are subclases and there is one-to-one mapping between
224 * the queues and the listeners.
Mathias Agopiandb772d82013-01-31 19:31:12 -0800225 */
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800226 private static abstract class BaseEventQueue {
Ashok Bhat4838e332014-01-03 14:37:19 +0000227 private native long nativeInitBaseEventQueue(BaseEventQueue eventQ, MessageQueue msgQ,
Aravind Akella88445992015-02-26 17:05:28 -0800228 float[] scratch, String packageName);
Ashok Bhat4838e332014-01-03 14:37:19 +0000229 private static native int nativeEnableSensor(long eventQ, int handle, int rateUs,
Aravind Akella88445992015-02-26 17:05:28 -0800230 int maxBatchReportLatencyUs);
Ashok Bhat4838e332014-01-03 14:37:19 +0000231 private static native int nativeDisableSensor(long eventQ, int handle);
232 private static native void nativeDestroySensorEventQueue(long eventQ);
233 private static native int nativeFlushSensor(long eventQ);
234 private long nSensorEventQueue;
Mathias Agopiandb772d82013-01-31 19:31:12 -0800235 private final SparseBooleanArray mActiveSensors = new SparseBooleanArray();
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800236 protected final SparseIntArray mSensorAccuracies = new SparseIntArray();
237 protected final SparseBooleanArray mFirstEvent = new SparseBooleanArray();
Mathias Agopiandb772d82013-01-31 19:31:12 -0800238 private final CloseGuard mCloseGuard = CloseGuard.get();
239 private final float[] mScratch = new float[16];
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700240 protected final SystemSensorManager mManager;
Mathias Agopiandb772d82013-01-31 19:31:12 -0800241
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700242 BaseEventQueue(Looper looper, SystemSensorManager manager) {
Aravind Akella88445992015-02-26 17:05:28 -0800243 nSensorEventQueue = nativeInitBaseEventQueue(this, looper.getQueue(), mScratch,
244 manager.mPackageName);
Mathias Agopiandb772d82013-01-31 19:31:12 -0800245 mCloseGuard.open("dispose");
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700246 mManager = manager;
Mathias Agopiandb772d82013-01-31 19:31:12 -0800247 }
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800248
Mathias Agopiandb772d82013-01-31 19:31:12 -0800249 public void dispose() {
250 dispose(false);
251 }
252
Aravind Akellab4c76b12013-06-27 12:04:16 -0700253 public boolean addSensor(
Aravind Akella88445992015-02-26 17:05:28 -0800254 Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800255 // Check if already present.
Jaikumar Ganesh2e900892013-04-11 10:40:33 -0700256 int handle = sensor.getHandle();
257 if (mActiveSensors.get(handle)) return false;
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800258
Jaikumar Ganesh2e900892013-04-11 10:40:33 -0700259 // Get ready to receive events before calling enable.
260 mActiveSensors.put(handle, true);
261 addSensorEvent(sensor);
Aravind Akella88445992015-02-26 17:05:28 -0800262 if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) {
Aravind Akellab4c76b12013-06-27 12:04:16 -0700263 // Try continuous mode if batching fails.
264 if (maxBatchReportLatencyUs == 0 ||
Aravind Akella88445992015-02-26 17:05:28 -0800265 maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
Aravind Akellab4c76b12013-06-27 12:04:16 -0700266 removeSensor(sensor, false);
267 return false;
268 }
Mathias Agopiandb772d82013-01-31 19:31:12 -0800269 }
Jaikumar Ganesh2e900892013-04-11 10:40:33 -0700270 return true;
Mathias Agopiandb772d82013-01-31 19:31:12 -0800271 }
272
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800273 public boolean removeAllSensors() {
Mathias Agopiandb772d82013-01-31 19:31:12 -0800274 for (int i=0 ; i<mActiveSensors.size(); i++) {
275 if (mActiveSensors.valueAt(i) == true) {
276 int handle = mActiveSensors.keyAt(i);
277 Sensor sensor = sHandleToSensor.get(handle);
278 if (sensor != null) {
279 disableSensor(sensor);
280 mActiveSensors.put(handle, false);
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700281 removeSensorEvent(sensor);
Mathias Agopiandb772d82013-01-31 19:31:12 -0800282 } else {
283 // it should never happen -- just ignore.
284 }
285 }
286 }
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800287 return true;
Mathias Agopiandb772d82013-01-31 19:31:12 -0800288 }
289
Jaikumar Ganesh2e900892013-04-11 10:40:33 -0700290 public boolean removeSensor(Sensor sensor, boolean disable) {
Mathias Agopiandb772d82013-01-31 19:31:12 -0800291 final int handle = sensor.getHandle();
292 if (mActiveSensors.get(handle)) {
Jaikumar Ganesh2e900892013-04-11 10:40:33 -0700293 if (disable) disableSensor(sensor);
Mathias Agopiandb772d82013-01-31 19:31:12 -0800294 mActiveSensors.put(sensor.getHandle(), false);
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700295 removeSensorEvent(sensor);
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800296 return true;
Mathias Agopiandb772d82013-01-31 19:31:12 -0800297 }
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800298 return false;
Mathias Agopiandb772d82013-01-31 19:31:12 -0800299 }
300
Aravind Akella4bdc37d2013-10-01 17:58:35 -0700301 public int flush() {
Aravind Akellab4c76b12013-06-27 12:04:16 -0700302 if (nSensorEventQueue == 0) throw new NullPointerException();
Aravind Akella4bdc37d2013-10-01 17:58:35 -0700303 return nativeFlushSensor(nSensorEventQueue);
Aravind Akellab4c76b12013-06-27 12:04:16 -0700304 }
305
Mathias Agopiandb772d82013-01-31 19:31:12 -0800306 public boolean hasSensors() {
307 // no more sensors are set
308 return mActiveSensors.indexOfValue(true) >= 0;
309 }
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800310
Mathias Agopiandb772d82013-01-31 19:31:12 -0800311 @Override
312 protected void finalize() throws Throwable {
313 try {
314 dispose(true);
315 } finally {
316 super.finalize();
317 }
318 }
319
320 private void dispose(boolean finalized) {
321 if (mCloseGuard != null) {
322 if (finalized) {
323 mCloseGuard.warnIfOpen();
324 }
325 mCloseGuard.close();
326 }
327 if (nSensorEventQueue != 0) {
328 nativeDestroySensorEventQueue(nSensorEventQueue);
329 nSensorEventQueue = 0;
330 }
331 }
332
Aravind Akellab4c76b12013-06-27 12:04:16 -0700333 private int enableSensor(
Aravind Akella88445992015-02-26 17:05:28 -0800334 Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
Mathias Agopiandb772d82013-01-31 19:31:12 -0800335 if (nSensorEventQueue == 0) throw new NullPointerException();
336 if (sensor == null) throw new NullPointerException();
Aravind Akellab4c76b12013-06-27 12:04:16 -0700337 return nativeEnableSensor(nSensorEventQueue, sensor.getHandle(), rateUs,
Aravind Akella88445992015-02-26 17:05:28 -0800338 maxBatchReportLatencyUs);
Mathias Agopiandb772d82013-01-31 19:31:12 -0800339 }
Aravind Akellab4c76b12013-06-27 12:04:16 -0700340
Mathias Agopiandb772d82013-01-31 19:31:12 -0800341 private int disableSensor(Sensor sensor) {
342 if (nSensorEventQueue == 0) throw new NullPointerException();
343 if (sensor == null) throw new NullPointerException();
344 return nativeDisableSensor(nSensorEventQueue, sensor.getHandle());
345 }
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800346 protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy,
347 long timestamp);
Aravind Akellab4c76b12013-06-27 12:04:16 -0700348 protected abstract void dispatchFlushCompleteEvent(int handle);
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700349
350 protected abstract void addSensorEvent(Sensor sensor);
351 protected abstract void removeSensorEvent(Sensor sensor);
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800352 }
353
354 static final class SensorEventQueue extends BaseEventQueue {
355 private final SensorEventListener mListener;
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700356 private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800357
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700358 public SensorEventQueue(SensorEventListener listener, Looper looper,
Aravind Akella4bdc37d2013-10-01 17:58:35 -0700359 SystemSensorManager manager) {
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700360 super(looper, manager);
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800361 mListener = listener;
362 }
Mathias Agopiandb772d82013-01-31 19:31:12 -0800363
Aravind Akella31d14ce2013-10-22 20:04:22 -0700364 @Override
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700365 public void addSensorEvent(Sensor sensor) {
366 SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor,
367 mManager.mTargetSdkLevel));
Aravind Akella31d14ce2013-10-22 20:04:22 -0700368 synchronized (mSensorsEvents) {
369 mSensorsEvents.put(sensor.getHandle(), t);
370 }
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700371 }
372
Aravind Akella31d14ce2013-10-22 20:04:22 -0700373 @Override
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700374 public void removeSensorEvent(Sensor sensor) {
Aravind Akella31d14ce2013-10-22 20:04:22 -0700375 synchronized (mSensorsEvents) {
376 mSensorsEvents.delete(sensor.getHandle());
377 }
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700378 }
379
Mathias Agopiandb772d82013-01-31 19:31:12 -0800380 // Called from native code.
381 @SuppressWarnings("unused")
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800382 @Override
383 protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
384 long timestamp) {
385 final Sensor sensor = sHandleToSensor.get(handle);
Aravind Akella31d14ce2013-10-22 20:04:22 -0700386 SensorEvent t = null;
387 synchronized (mSensorsEvents) {
388 t = mSensorsEvents.get(handle);
389 }
390
Jaikumar Ganesh2e900892013-04-11 10:40:33 -0700391 if (t == null) {
Aravind Akella31d14ce2013-10-22 20:04:22 -0700392 // This may happen if the client has unregistered and there are pending events in
393 // the queue waiting to be delivered. Ignore.
Jaikumar Ganesh2e900892013-04-11 10:40:33 -0700394 return;
395 }
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700396 // Copy from the values array.
397 System.arraycopy(values, 0, t.values, 0, t.values.length);
398 t.timestamp = timestamp;
399 t.accuracy = inAccuracy;
400 t.sensor = sensor;
Etienne Le Grandaf805102014-05-16 12:21:41 -0700401
402 // call onAccuracyChanged() only if the value changes
403 final int accuracy = mSensorAccuracies.get(handle);
404 if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
405 mSensorAccuracies.put(handle, t.accuracy);
406 mListener.onAccuracyChanged(t.sensor, t.accuracy);
Mathias Agopiandb772d82013-01-31 19:31:12 -0800407 }
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700408 mListener.onSensorChanged(t);
Mathias Agopiandb772d82013-01-31 19:31:12 -0800409 }
Aravind Akellab4c76b12013-06-27 12:04:16 -0700410
411 @SuppressWarnings("unused")
412 protected void dispatchFlushCompleteEvent(int handle) {
Aravind Akella4bdc37d2013-10-01 17:58:35 -0700413 if (mListener instanceof SensorEventListener2) {
414 final Sensor sensor = sHandleToSensor.get(handle);
415 ((SensorEventListener2)mListener).onFlushCompleted(sensor);
Aravind Akellab4c76b12013-06-27 12:04:16 -0700416 }
417 return;
418 }
Mathias Agopiandb772d82013-01-31 19:31:12 -0800419 }
420
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800421 static final class TriggerEventQueue extends BaseEventQueue {
422 private final TriggerEventListener mListener;
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700423 private final SparseArray<TriggerEvent> mTriggerEvents = new SparseArray<TriggerEvent>();
Mathias Agopiandb772d82013-01-31 19:31:12 -0800424
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800425 public TriggerEventQueue(TriggerEventListener listener, Looper looper,
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700426 SystemSensorManager manager) {
427 super(looper, manager);
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800428 mListener = listener;
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700429 }
430
Aravind Akella31d14ce2013-10-22 20:04:22 -0700431 @Override
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700432 public void addSensorEvent(Sensor sensor) {
433 TriggerEvent t = new TriggerEvent(Sensor.getMaxLengthValuesArray(sensor,
434 mManager.mTargetSdkLevel));
Aravind Akella31d14ce2013-10-22 20:04:22 -0700435 synchronized (mTriggerEvents) {
436 mTriggerEvents.put(sensor.getHandle(), t);
437 }
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700438 }
439
Aravind Akella31d14ce2013-10-22 20:04:22 -0700440 @Override
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700441 public void removeSensorEvent(Sensor sensor) {
Aravind Akella31d14ce2013-10-22 20:04:22 -0700442 synchronized (mTriggerEvents) {
443 mTriggerEvents.delete(sensor.getHandle());
444 }
Mathias Agopiandb772d82013-01-31 19:31:12 -0800445 }
446
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800447 // Called from native code.
448 @SuppressWarnings("unused")
449 @Override
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700450 protected void dispatchSensorEvent(int handle, float[] values, int accuracy,
451 long timestamp) {
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800452 final Sensor sensor = sHandleToSensor.get(handle);
Aravind Akella31d14ce2013-10-22 20:04:22 -0700453 TriggerEvent t = null;
454 synchronized (mTriggerEvents) {
455 t = mTriggerEvents.get(handle);
456 }
Jaikumar Ganesh2e900892013-04-11 10:40:33 -0700457 if (t == null) {
458 Log.e(TAG, "Error: Trigger Event is null for Sensor: " + sensor);
459 return;
460 }
Mathias Agopiandb772d82013-01-31 19:31:12 -0800461
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700462 // Copy from the values array.
463 System.arraycopy(values, 0, t.values, 0, t.values.length);
464 t.timestamp = timestamp;
465 t.sensor = sensor;
Mathias Agopiandb772d82013-01-31 19:31:12 -0800466
Jaikumar Ganesh2e900892013-04-11 10:40:33 -0700467 // A trigger sensor is auto disabled. So just clean up and don't call native
468 // disable.
469 mManager.cancelTriggerSensorImpl(mListener, sensor, false);
Jaikumar Ganesh9a8df4d2013-02-12 16:31:32 -0800470
Jaikumar Ganesh6d0c1d782013-03-27 17:41:33 -0700471 mListener.onTrigger(t);
Mathias Agopiandb772d82013-01-31 19:31:12 -0800472 }
Aravind Akellab4c76b12013-06-27 12:04:16 -0700473
474 @SuppressWarnings("unused")
475 protected void dispatchFlushCompleteEvent(int handle) {
476 }
477 }
Jeff Brown25157e42012-04-16 12:13:05 -0700478}