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

Side by Side Diff: device/sensors/sensor_manager_android.cc

Issue 2819273006: Move //device/sensor impl to be part of the internal implemenation of the Device Service. (Closed)
Patch Set: Move //device/sensor impl to be part of the internal implemenation of the Device Service Created 3 years, 8 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 2014 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 #include "device/sensors/sensor_manager_android.h"
6
7 #include <string.h>
8
9 #include "base/android/context_utils.h"
10 #include "base/android/jni_android.h"
11 #include "base/bind.h"
12 #include "base/memory/singleton.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/metrics/histogram_macros.h"
15 #include "jni/DeviceSensors_jni.h"
16
17 using base::android::AttachCurrentThread;
18 using base::android::JavaParamRef;
19
20 namespace {
21
22 void UpdateDeviceOrientationHistogram(
23 device::SensorManagerAndroid::OrientationSensorType type) {
24 UMA_HISTOGRAM_ENUMERATION(
25 "InertialSensor.DeviceOrientationSensorAndroid", type,
26 device::SensorManagerAndroid::ORIENTATION_SENSOR_MAX);
27 }
28
29 void SetOrientation(device::DeviceOrientationHardwareBuffer* buffer,
30 double alpha,
31 double beta,
32 double gamma) {
33 buffer->seqlock.WriteBegin();
34 buffer->data.alpha = alpha;
35 buffer->data.has_alpha = true;
36 buffer->data.beta = beta;
37 buffer->data.has_beta = true;
38 buffer->data.gamma = gamma;
39 buffer->data.has_gamma = true;
40 buffer->seqlock.WriteEnd();
41 }
42
43 void SetOrientationBufferStatus(device::DeviceOrientationHardwareBuffer* buffer,
44 bool ready,
45 bool absolute) {
46 buffer->seqlock.WriteBegin();
47 buffer->data.absolute = absolute;
48 buffer->data.all_available_sensors_are_active = ready;
49 buffer->seqlock.WriteEnd();
50 }
51
52 } // namespace
53
54 namespace device {
55
56 SensorManagerAndroid::SensorManagerAndroid()
57 : number_active_device_motion_sensors_(0),
58 device_light_buffer_(nullptr),
59 device_motion_buffer_(nullptr),
60 device_orientation_buffer_(nullptr),
61 motion_buffer_initialized_(false),
62 orientation_buffer_initialized_(false),
63 is_shutdown_(false) {
64 DCHECK(thread_checker_.CalledOnValidThread());
65 memset(received_motion_data_, 0, sizeof(received_motion_data_));
66 device_sensors_.Reset(Java_DeviceSensors_getInstance(
67 AttachCurrentThread(), base::android::GetApplicationContext()));
68 }
69
70 SensorManagerAndroid::~SensorManagerAndroid() {}
71
72 bool SensorManagerAndroid::Register(JNIEnv* env) {
73 return RegisterNativesImpl(env);
74 }
75
76 SensorManagerAndroid* SensorManagerAndroid::GetInstance() {
77 DCHECK(base::MessageLoopForUI::IsCurrent());
78 return base::Singleton<
79 SensorManagerAndroid,
80 base::LeakySingletonTraits<SensorManagerAndroid>>::get();
81 }
82
83 void SensorManagerAndroid::GotOrientation(JNIEnv*,
84 const JavaParamRef<jobject>&,
85 double alpha,
86 double beta,
87 double gamma) {
88 base::AutoLock autolock(orientation_buffer_lock_);
89
90 if (!device_orientation_buffer_)
91 return;
92
93 SetOrientation(device_orientation_buffer_, alpha, beta, gamma);
94
95 if (!orientation_buffer_initialized_) {
96 OrientationSensorType type =
97 static_cast<OrientationSensorType>(GetOrientationSensorTypeUsed());
98 SetOrientationBufferStatus(device_orientation_buffer_, true,
99 type != GAME_ROTATION_VECTOR);
100 orientation_buffer_initialized_ = true;
101 UpdateDeviceOrientationHistogram(type);
102 }
103 }
104
105 void SensorManagerAndroid::GotOrientationAbsolute(JNIEnv*,
106 const JavaParamRef<jobject>&,
107 double alpha,
108 double beta,
109 double gamma) {
110 base::AutoLock autolock(orientation_absolute_buffer_lock_);
111
112 if (!device_orientation_absolute_buffer_)
113 return;
114
115 SetOrientation(device_orientation_absolute_buffer_, alpha, beta, gamma);
116
117 if (!orientation_absolute_buffer_initialized_) {
118 SetOrientationBufferStatus(device_orientation_absolute_buffer_, true, true);
119 orientation_absolute_buffer_initialized_ = true;
120 // TODO(timvolodine): Add UMA.
121 }
122 }
123
124 void SensorManagerAndroid::GotAcceleration(JNIEnv*,
125 const JavaParamRef<jobject>&,
126 double x,
127 double y,
128 double z) {
129 base::AutoLock autolock(motion_buffer_lock_);
130
131 if (!device_motion_buffer_)
132 return;
133
134 device_motion_buffer_->seqlock.WriteBegin();
135 device_motion_buffer_->data.acceleration_x = x;
136 device_motion_buffer_->data.has_acceleration_x = true;
137 device_motion_buffer_->data.acceleration_y = y;
138 device_motion_buffer_->data.has_acceleration_y = true;
139 device_motion_buffer_->data.acceleration_z = z;
140 device_motion_buffer_->data.has_acceleration_z = true;
141 device_motion_buffer_->seqlock.WriteEnd();
142
143 if (!motion_buffer_initialized_) {
144 received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION] = 1;
145 CheckMotionBufferReadyToRead();
146 }
147 }
148
149 void SensorManagerAndroid::GotAccelerationIncludingGravity(
150 JNIEnv*,
151 const JavaParamRef<jobject>&,
152 double x,
153 double y,
154 double z) {
155 base::AutoLock autolock(motion_buffer_lock_);
156
157 if (!device_motion_buffer_)
158 return;
159
160 device_motion_buffer_->seqlock.WriteBegin();
161 device_motion_buffer_->data.acceleration_including_gravity_x = x;
162 device_motion_buffer_->data.has_acceleration_including_gravity_x = true;
163 device_motion_buffer_->data.acceleration_including_gravity_y = y;
164 device_motion_buffer_->data.has_acceleration_including_gravity_y = true;
165 device_motion_buffer_->data.acceleration_including_gravity_z = z;
166 device_motion_buffer_->data.has_acceleration_including_gravity_z = true;
167 device_motion_buffer_->seqlock.WriteEnd();
168
169 if (!motion_buffer_initialized_) {
170 received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION_INCL_GRAVITY] = 1;
171 CheckMotionBufferReadyToRead();
172 }
173 }
174
175 void SensorManagerAndroid::GotRotationRate(JNIEnv*,
176 const JavaParamRef<jobject>&,
177 double alpha,
178 double beta,
179 double gamma) {
180 base::AutoLock autolock(motion_buffer_lock_);
181
182 if (!device_motion_buffer_)
183 return;
184
185 device_motion_buffer_->seqlock.WriteBegin();
186 device_motion_buffer_->data.rotation_rate_alpha = alpha;
187 device_motion_buffer_->data.has_rotation_rate_alpha = true;
188 device_motion_buffer_->data.rotation_rate_beta = beta;
189 device_motion_buffer_->data.has_rotation_rate_beta = true;
190 device_motion_buffer_->data.rotation_rate_gamma = gamma;
191 device_motion_buffer_->data.has_rotation_rate_gamma = true;
192 device_motion_buffer_->seqlock.WriteEnd();
193
194 if (!motion_buffer_initialized_) {
195 received_motion_data_[RECEIVED_MOTION_DATA_ROTATION_RATE] = 1;
196 CheckMotionBufferReadyToRead();
197 }
198 }
199
200 void SensorManagerAndroid::GotLight(JNIEnv*,
201 const JavaParamRef<jobject>&,
202 double value) {
203 base::AutoLock autolock(light_buffer_lock_);
204
205 if (!device_light_buffer_)
206 return;
207
208 device_light_buffer_->seqlock.WriteBegin();
209 device_light_buffer_->data.value = value;
210 device_light_buffer_->seqlock.WriteEnd();
211 }
212
213 bool SensorManagerAndroid::Start(ConsumerType consumer_type) {
214 DCHECK(thread_checker_.CalledOnValidThread());
215 DCHECK(!device_sensors_.is_null());
216 int rate_in_microseconds = (consumer_type == CONSUMER_TYPE_LIGHT)
217 ? kLightSensorIntervalMicroseconds
218 : kDeviceSensorIntervalMicroseconds;
219 return Java_DeviceSensors_start(
220 AttachCurrentThread(), device_sensors_, reinterpret_cast<intptr_t>(this),
221 static_cast<jint>(consumer_type), rate_in_microseconds);
222 }
223
224 void SensorManagerAndroid::Stop(ConsumerType consumer_type) {
225 DCHECK(thread_checker_.CalledOnValidThread());
226 DCHECK(!device_sensors_.is_null());
227 Java_DeviceSensors_stop(AttachCurrentThread(), device_sensors_,
228 static_cast<jint>(consumer_type));
229 }
230
231 int SensorManagerAndroid::GetNumberActiveDeviceMotionSensors() {
232 DCHECK(thread_checker_.CalledOnValidThread());
233 DCHECK(!device_sensors_.is_null());
234 return Java_DeviceSensors_getNumberActiveDeviceMotionSensors(
235 AttachCurrentThread(), device_sensors_);
236 }
237
238 SensorManagerAndroid::OrientationSensorType
239 SensorManagerAndroid::GetOrientationSensorTypeUsed() {
240 DCHECK(!device_sensors_.is_null());
241 return static_cast<SensorManagerAndroid::OrientationSensorType>(
242 Java_DeviceSensors_getOrientationSensorTypeUsed(AttachCurrentThread(),
243 device_sensors_));
244 }
245
246 // ----- Shared memory API methods
247
248 // --- Device Light
249
250 void SensorManagerAndroid::StartFetchingDeviceLightData(
251 DeviceLightHardwareBuffer* buffer) {
252 DCHECK(thread_checker_.CalledOnValidThread());
253 DCHECK(buffer);
254 if (is_shutdown_)
255 return;
256
257 {
258 base::AutoLock autolock(light_buffer_lock_);
259 device_light_buffer_ = buffer;
260 SetLightBufferValue(-1);
261 }
262 bool success = Start(CONSUMER_TYPE_LIGHT);
263 if (!success) {
264 base::AutoLock autolock(light_buffer_lock_);
265 SetLightBufferValue(std::numeric_limits<double>::infinity());
266 }
267 }
268
269 void SensorManagerAndroid::StopFetchingDeviceLightData() {
270 DCHECK(thread_checker_.CalledOnValidThread());
271 if (is_shutdown_)
272 return;
273
274 Stop(CONSUMER_TYPE_LIGHT);
275 {
276 base::AutoLock autolock(light_buffer_lock_);
277 if (device_light_buffer_) {
278 SetLightBufferValue(-1);
279 device_light_buffer_ = nullptr;
280 }
281 }
282 }
283
284 void SensorManagerAndroid::SetLightBufferValue(double lux) {
285 device_light_buffer_->seqlock.WriteBegin();
286 device_light_buffer_->data.value = lux;
287 device_light_buffer_->seqlock.WriteEnd();
288 }
289
290 // --- Device Motion
291
292 void SensorManagerAndroid::StartFetchingDeviceMotionData(
293 DeviceMotionHardwareBuffer* buffer) {
294 DCHECK(thread_checker_.CalledOnValidThread());
295 DCHECK(buffer);
296 if (is_shutdown_)
297 return;
298
299 {
300 base::AutoLock autolock(motion_buffer_lock_);
301 device_motion_buffer_ = buffer;
302 ClearInternalMotionBuffers();
303 }
304 Start(CONSUMER_TYPE_MOTION);
305
306 // If no motion data can ever be provided, the number of active device motion
307 // sensors will be zero. In that case flag the shared memory buffer
308 // as ready to read, as it will not change anyway.
309 number_active_device_motion_sensors_ = GetNumberActiveDeviceMotionSensors();
310 {
311 base::AutoLock autolock(motion_buffer_lock_);
312 CheckMotionBufferReadyToRead();
313 }
314 }
315
316 void SensorManagerAndroid::StopFetchingDeviceMotionData() {
317 DCHECK(thread_checker_.CalledOnValidThread());
318 if (is_shutdown_)
319 return;
320
321 Stop(CONSUMER_TYPE_MOTION);
322 {
323 base::AutoLock autolock(motion_buffer_lock_);
324 if (device_motion_buffer_) {
325 ClearInternalMotionBuffers();
326 device_motion_buffer_ = nullptr;
327 }
328 }
329 }
330
331 void SensorManagerAndroid::CheckMotionBufferReadyToRead() {
332 if (received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION] +
333 received_motion_data_
334 [RECEIVED_MOTION_DATA_ACCELERATION_INCL_GRAVITY] +
335 received_motion_data_[RECEIVED_MOTION_DATA_ROTATION_RATE] ==
336 number_active_device_motion_sensors_) {
337 device_motion_buffer_->seqlock.WriteBegin();
338 device_motion_buffer_->data.interval =
339 kDeviceSensorIntervalMicroseconds / 1000.;
340 device_motion_buffer_->seqlock.WriteEnd();
341 SetMotionBufferReadyStatus(true);
342
343 UMA_HISTOGRAM_BOOLEAN(
344 "InertialSensor.AccelerometerAndroidAvailable",
345 received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION] > 0);
346 UMA_HISTOGRAM_BOOLEAN(
347 "InertialSensor.AccelerometerIncGravityAndroidAvailable",
348 received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION_INCL_GRAVITY] >
349 0);
350 UMA_HISTOGRAM_BOOLEAN(
351 "InertialSensor.GyroscopeAndroidAvailable",
352 received_motion_data_[RECEIVED_MOTION_DATA_ROTATION_RATE] > 0);
353 }
354 }
355
356 void SensorManagerAndroid::SetMotionBufferReadyStatus(bool ready) {
357 device_motion_buffer_->seqlock.WriteBegin();
358 device_motion_buffer_->data.all_available_sensors_are_active = ready;
359 device_motion_buffer_->seqlock.WriteEnd();
360 motion_buffer_initialized_ = ready;
361 }
362
363 void SensorManagerAndroid::ClearInternalMotionBuffers() {
364 memset(received_motion_data_, 0, sizeof(received_motion_data_));
365 number_active_device_motion_sensors_ = 0;
366 SetMotionBufferReadyStatus(false);
367 }
368
369 // --- Device Orientation
370
371 void SensorManagerAndroid::StartFetchingDeviceOrientationData(
372 DeviceOrientationHardwareBuffer* buffer) {
373 DCHECK(thread_checker_.CalledOnValidThread());
374 DCHECK(buffer);
375 if (is_shutdown_)
376 return;
377
378 {
379 base::AutoLock autolock(orientation_buffer_lock_);
380 device_orientation_buffer_ = buffer;
381 }
382 bool success = Start(CONSUMER_TYPE_ORIENTATION);
383
384 {
385 base::AutoLock autolock(orientation_buffer_lock_);
386 // If Start() was unsuccessful then set the buffer ready flag to true
387 // to start firing all-null events.
388 SetOrientationBufferStatus(buffer, !success /* ready */,
389 false /* absolute */);
390 orientation_buffer_initialized_ = !success;
391 }
392
393 if (!success)
394 UpdateDeviceOrientationHistogram(NOT_AVAILABLE);
395 }
396
397 void SensorManagerAndroid::StopFetchingDeviceOrientationData() {
398 DCHECK(thread_checker_.CalledOnValidThread());
399 if (is_shutdown_)
400 return;
401
402 Stop(CONSUMER_TYPE_ORIENTATION);
403 {
404 base::AutoLock autolock(orientation_buffer_lock_);
405 if (device_orientation_buffer_) {
406 SetOrientationBufferStatus(device_orientation_buffer_, false, false);
407 orientation_buffer_initialized_ = false;
408 device_orientation_buffer_ = nullptr;
409 }
410 }
411 }
412
413 void SensorManagerAndroid::StartFetchingDeviceOrientationAbsoluteData(
414 DeviceOrientationHardwareBuffer* buffer) {
415 DCHECK(thread_checker_.CalledOnValidThread());
416 DCHECK(buffer);
417 if (is_shutdown_)
418 return;
419
420 {
421 base::AutoLock autolock(orientation_absolute_buffer_lock_);
422 device_orientation_absolute_buffer_ = buffer;
423 }
424 bool success = Start(CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
425
426 {
427 base::AutoLock autolock(orientation_absolute_buffer_lock_);
428 // If Start() was unsuccessful then set the buffer ready flag to true
429 // to start firing all-null events.
430 SetOrientationBufferStatus(buffer, !success /* ready */,
431 false /* absolute */);
432 orientation_absolute_buffer_initialized_ = !success;
433 }
434 }
435
436 void SensorManagerAndroid::StopFetchingDeviceOrientationAbsoluteData() {
437 DCHECK(thread_checker_.CalledOnValidThread());
438 if (is_shutdown_)
439 return;
440
441 Stop(CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
442 {
443 base::AutoLock autolock(orientation_absolute_buffer_lock_);
444 if (device_orientation_absolute_buffer_) {
445 SetOrientationBufferStatus(device_orientation_absolute_buffer_, false,
446 false);
447 orientation_absolute_buffer_initialized_ = false;
448 device_orientation_absolute_buffer_ = nullptr;
449 }
450 }
451 }
452
453 void SensorManagerAndroid::Shutdown() {
454 DCHECK(thread_checker_.CalledOnValidThread());
455 is_shutdown_ = true;
456 }
457
458 } // namespace device
OLDNEW
« no previous file with comments | « device/sensors/sensor_manager_android.h ('k') | device/sensors/sensor_manager_android_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698