Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: device/sensors/android/java/src/org/chromium/device/sensors/SensorBase.java

Issue 2051083002: WIP : Generic Sensor API implementation Base URL: https://chromium.googlesource.com/chromium/src.git@lkgr
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.device.sensors;
6
7 import android.hardware.Sensor;
8 import android.hardware.SensorEvent;
9 import android.hardware.SensorEventListener;
10 import android.hardware.SensorManager;
11 import android.os.Build;
12 import android.os.Handler;
13
14 import org.chromium.mojo.system.SharedBufferHandle;
15 import org.chromium.mojom.device.sensors.SensorConfiguration;
16 import org.chromium.mojom.device.sensors.ReportingMode;
17
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21
22 import java.nio.ByteBuffer;
23 import java.nio.ByteOrder;
24 import java.nio.BufferOverflowException;
25
26 /**
27 * Base interface for Sensors
28 */
29 public abstract class SensorBase implements SensorEventListener {
30 private static final double MICROSECONDS_PER_SECOND = 1000000;
31 private final Sensor mSensor;
32 private final SensorManager mSensorManager;
33 private final SensorStateObserver mSensorStateObserver;
34 private final Map<SensorProxy, Boolean> mSensorProxies = new HashMap<SensorP roxy, Boolean>();
35 private final SharedBufferHandle mSharedBufferHandle;
36 private final Handler mHandler;
37 private final long mSize;
38 private final long mOffset;
39 private final int mMinDelay;
40 private SensorConfiguration mCurrentConfiguration;
41 private ByteBuffer mSharedBuffer;
42 private ByteBuffer mSensorReadingData;
43
44 protected SensorBase(int sensorType, SensorManager manager, Handler handler,
45 SharedBufferHandle handle, long offset, long size, SensorStateObserv er observer)
46 throws SensorException {
47 if (handle == null || !handle.isValid()) throw new SensorException();
48 mSensorManager = manager;
49 mHandler = handler;
50 mSensorStateObserver = observer;
51 mSharedBufferHandle = handle;
52 mSize = size;
53 mOffset = offset;
54 List<Sensor> sensors = mSensorManager.getSensorList(sensorType);
55 if (sensors.isEmpty()) throw new SensorException();
56 mSensor = sensors.get(0);
57 mMinDelay = mSensor.getMinDelay();
58 }
59
60 public int reportingMode() {
61 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
62 return mSensor.getReportingMode() == Sensor.REPORTING_MODE_CONTINUOU S ?
63 ReportingMode.CONTINUOUS : ReportingMode.ON_CHANGE;
64 }
65 return ReportingMode.CONTINUOUS;
66 }
67
68 public abstract int getType();
69 protected abstract void fillSensorReadingData(SensorEvent event, ByteBuffer buffer)
70 throws SensorException;
71
72 public boolean startListening(SensorProxy proxy) {
73 if (proxy == null) return false;
74
75 if (!mapSharedBuffer()) {
76 return false;
77 }
78
79 setSensorListening(proxy);
80 SensorConfiguration configuration = optimalConfiguration();
81 return restartIfNeeded(configuration);
82 }
83
84 private SensorConfiguration optimalConfiguration() {
85 SensorConfigurations configurations = new SensorConfigurations();
86 for (Map.Entry<SensorProxy, Boolean> entry : mSensorProxies.entrySet()) {
87 if (entry.getValue() == true) {
88 configurations.add(entry.getKey().getCurrentConfiguration());
89 }
90 }
91 if (!configurations.isEmpty())
92 return configurations.get(0);
93 return null;
94 }
95
96 public boolean stopListening(SensorProxy proxy) {
97 if (proxy == null) return false;
98
99 SensorConfiguration configuration = optimalConfiguration();
100 setSensorNotListening(proxy);
101
102 if (hasListeners()) {
103 return restartIfNeeded(configuration);
104 } else {
105 stopListening();
106 }
107
108 return true;
109 }
110
111 public boolean configuratoinUpdated() {
112 return restartIfNeeded(optimalConfiguration());
113 }
114
115 public boolean restartIfNeeded(SensorConfiguration configuration) {
116 boolean restarted = true;
117 if (configuration != null && configuration != mCurrentConfiguration) {
118 SensorConfiguration oldConfiguration = mCurrentConfiguration;
119 mCurrentConfiguration = configuration;
120 stopListening();
121 restarted = startListening();
122 if (!restarted) {
123 mCurrentConfiguration = oldConfiguration;
124 startListening();
125 }
126 }
127 return restarted;
128 }
129
130 private boolean startListening() {
131 int samplingFrequency = getSamplingFrequency();
132 if (samplingFrequency < mMinDelay) return false;
133 return mSensorManager.registerListener(this, mSensor, samplingFrequency, mHandler);
134 }
135
136 private void stopListening() {
137 mSensorManager.unregisterListener(this);
138 }
139
140 public void addSensorProxy(SensorProxy proxy) {
141 mSensorProxies.put(proxy, false);
142 }
143
144 public void removeSensorProxy(SensorProxy proxy) {
145 mSensorProxies.remove(proxy);
146 if (mSensorProxies.isEmpty()) {
147 stopListening();
148 mSensorStateObserver.onSensorNotInUse(this);
149 }
150 }
151
152 private int getSamplingFrequency() {
153 if (mCurrentConfiguration == null)
154 return getDefaultSamplingFrequency();
155
156 if (mCurrentConfiguration.frequency > 0) {
157 return (int)((1 / mCurrentConfiguration.frequency) * MICROSECONDS_PE R_SECOND);
158 } else {
159 return getDefaultSamplingFrequency();
160 }
161 }
162
163 private int getDefaultSamplingFrequency() {
164 return SensorManager.SENSOR_DELAY_NORMAL;
165 }
166
167 private void setSensorListening(SensorProxy proxy) {
168 setSensorFlag(proxy, true);
169 }
170
171 private void setSensorNotListening(SensorProxy proxy) {
172 setSensorFlag(proxy, false);
173 }
174
175 private void setSensorFlag(SensorProxy proxy, boolean listening) {
176 if (mSensorProxies.containsKey(proxy)) {
177 mSensorProxies.put(proxy, listening);
178 }
179 }
180
181 protected boolean hasListeners() {
182 for (Map.Entry<SensorProxy, Boolean> entry : mSensorProxies.entrySet()) {
183 if (entry.getValue() == true) return true;
184 }
185 return false;
186 }
187
188 private boolean isValidConfiguration(SensorConfiguration configuration) {
189 return true;
190 }
191
192 private boolean mapSharedBuffer() {
193 if (mSharedBuffer == null) {
194 mSharedBuffer = mSharedBufferHandle.map(mOffset, mSize, SharedBuffer Handle.MapFlags.none());
195 mSensorReadingData = ByteBuffer.allocate(mSharedBuffer.capacity());
196 mSensorReadingData.order(ByteOrder.nativeOrder());
197 }
198
199 return mSharedBuffer != null;
200 }
201
202 @Override
203 public void onAccuracyChanged(Sensor sensor, int accuracy) { }
204
205 @Override
206 public void onSensorChanged(SensorEvent event) {
207 try {
208 mSensorReadingData.mark();
209 // Timestamp in milliseconds
210 mSensorReadingData.putDouble(event.timestamp * 0.000001d);
211 fillSensorReadingData(event, mSensorReadingData);
212
213 mSensorReadingData.reset();
214
215 mSharedBuffer.mark();
216 mSharedBuffer.put(mSensorReadingData);
217 mSensorReadingData.reset();
218 mSharedBuffer.reset();
219
220 if (reportingMode() == ReportingMode.ON_CHANGE) {
221 for (Map.Entry<SensorProxy, Boolean> entry : mSensorProxies.entr ySet()) {
222 if (entry.getValue() == true) {
223 entry.getKey().reportSensorReadingChaned();
224 }
225 }
226 }
227 } catch (BufferOverflowException | SensorException e) {
228 for (SensorProxy proxy : mSensorProxies.keySet()) {
229 proxy.reportError();
230 }
231 }
232 }
233 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698