15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/browser/device_sensors/sensor_manager_android.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <string.h>
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_android.h"
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/memory/singleton.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/metrics/histogram.h"
120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/browser/device_sensors/inertial_sensor_consts.h"
130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "jni/DeviceSensors_jni.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::AttachCurrentThread;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static void updateRotationVectorHistogram(bool value) {
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  UMA_HISTOGRAM_BOOLEAN("InertialSensor.RotationVectorAndroidAvailable", value);
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SensorManagerAndroid::SensorManagerAndroid()
287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    : number_active_device_motion_sensors_(0),
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      device_light_buffer_(NULL),
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      device_motion_buffer_(NULL),
31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      device_orientation_buffer_(NULL),
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      is_light_buffer_ready_(false),
33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      is_motion_buffer_ready_(false),
34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      is_orientation_buffer_ready_(false) {
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  memset(received_motion_data_, 0, sizeof(received_motion_data_));
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device_sensors_.Reset(Java_DeviceSensors_getInstance(
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      AttachCurrentThread(), base::android::GetApplicationContext()));
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SensorManagerAndroid::~SensorManagerAndroid() {
417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SensorManagerAndroid::Register(JNIEnv* env) {
44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return RegisterNativesImpl(env);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SensorManagerAndroid* SensorManagerAndroid::GetInstance() {
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return Singleton<SensorManagerAndroid,
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   LeakySingletonTraits<SensorManagerAndroid> >::get();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::GotOrientation(
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv*, jobject, double alpha, double beta, double gamma) {
540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::AutoLock autolock(orientation_buffer_lock_);
550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!device_orientation_buffer_)
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  device_orientation_buffer_->seqlock.WriteBegin();
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  device_orientation_buffer_->data.alpha = alpha;
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  device_orientation_buffer_->data.hasAlpha = true;
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  device_orientation_buffer_->data.beta = beta;
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  device_orientation_buffer_->data.hasBeta = true;
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  device_orientation_buffer_->data.gamma = gamma;
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  device_orientation_buffer_->data.hasGamma = true;
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  device_orientation_buffer_->seqlock.WriteEnd();
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!is_orientation_buffer_ready_) {
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    SetOrientationBufferReadyStatus(true);
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    updateRotationVectorHistogram(true);
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::GotAcceleration(
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    JNIEnv*, jobject, double x, double y, double z) {
760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::AutoLock autolock(motion_buffer_lock_);
770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!device_motion_buffer_)
790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return;
800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->seqlock.WriteBegin();
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.accelerationX = x;
837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.hasAccelerationX = true;
847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.accelerationY = y;
857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.hasAccelerationY = true;
867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.accelerationZ = z;
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.hasAccelerationZ = true;
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->seqlock.WriteEnd();
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!is_motion_buffer_ready_) {
917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION] = 1;
92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    CheckMotionBufferReadyToRead();
937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::GotAccelerationIncludingGravity(
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    JNIEnv*, jobject, double x, double y, double z) {
980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::AutoLock autolock(motion_buffer_lock_);
990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!device_motion_buffer_)
1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return;
1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->seqlock.WriteBegin();
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.accelerationIncludingGravityX = x;
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.hasAccelerationIncludingGravityX = true;
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.accelerationIncludingGravityY = y;
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.hasAccelerationIncludingGravityY = true;
1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.accelerationIncludingGravityZ = z;
1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.hasAccelerationIncludingGravityZ = true;
1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->seqlock.WriteEnd();
1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
112424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!is_motion_buffer_ready_) {
1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION_INCL_GRAVITY] = 1;
114424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    CheckMotionBufferReadyToRead();
1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::GotRotationRate(
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    JNIEnv*, jobject, double alpha, double beta, double gamma) {
1200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::AutoLock autolock(motion_buffer_lock_);
1210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!device_motion_buffer_)
1230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return;
1240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->seqlock.WriteBegin();
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.rotationRateAlpha = alpha;
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.hasRotationRateAlpha = true;
1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.rotationRateBeta = beta;
1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.hasRotationRateBeta = true;
1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.rotationRateGamma = gamma;
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.hasRotationRateGamma = true;
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->seqlock.WriteEnd();
1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
134424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!is_motion_buffer_ready_) {
1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    received_motion_data_[RECEIVED_MOTION_DATA_ROTATION_RATE] = 1;
136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    CheckMotionBufferReadyToRead();
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SensorManagerAndroid::GotLight(JNIEnv*, jobject, double value) {
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::AutoLock autolock(light_buffer_lock_);
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!device_light_buffer_)
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device_light_buffer_->seqlock.WriteBegin();
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device_light_buffer_->data.value = value;
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device_light_buffer_->seqlock.WriteEnd();
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SensorManagerAndroid::Start(EventType event_type) {
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!device_sensors_.is_null());
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int rate_in_milliseconds = (event_type == kTypeLight)
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 ? kLightSensorIntervalMillis
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 : kInertialSensorIntervalMillis;
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return Java_DeviceSensors_start(AttachCurrentThread(),
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  device_sensors_.obj(),
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  reinterpret_cast<intptr_t>(this),
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  static_cast<jint>(event_type),
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  rate_in_milliseconds);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::Stop(EventType event_type) {
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!device_sensors_.is_null());
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Java_DeviceSensors_stop(AttachCurrentThread(),
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          device_sensors_.obj(),
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          static_cast<jint>(event_type));
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int SensorManagerAndroid::GetNumberActiveDeviceMotionSensors() {
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!device_sensors_.is_null());
1720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return Java_DeviceSensors_getNumberActiveDeviceMotionSensors(
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      AttachCurrentThread(), device_sensors_.obj());
1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// ----- Shared memory API methods
1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// --- Device Light
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool SensorManagerAndroid::StartFetchingDeviceLightData(
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DeviceLightHardwareBuffer* buffer) {
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(buffer);
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  {
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::AutoLock autolock(light_buffer_lock_);
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    device_light_buffer_ = buffer;
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SetLightBufferValue(-1);
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool success = Start(kTypeLight);
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!success) {
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::AutoLock autolock(light_buffer_lock_);
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SetLightBufferValue(std::numeric_limits<double>::infinity());
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return success;
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SensorManagerAndroid::StopFetchingDeviceLightData() {
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Stop(kTypeLight);
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  {
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::AutoLock autolock(light_buffer_lock_);
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (device_light_buffer_) {
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SetLightBufferValue(-1);
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      device_light_buffer_ = NULL;
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SensorManagerAndroid::SetLightBufferValue(double lux) {
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device_light_buffer_->seqlock.WriteBegin();
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device_light_buffer_->data.value = lux;
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  device_light_buffer_->seqlock.WriteEnd();
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
213424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// --- Device Motion
214424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SensorManagerAndroid::StartFetchingDeviceMotionData(
2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DeviceMotionHardwareBuffer* buffer) {
217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(buffer);
2180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
2190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoLock autolock(motion_buffer_lock_);
2200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    device_motion_buffer_ = buffer;
2210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ClearInternalMotionBuffers();
2220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool success = Start(kTypeMotion);
2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // If no motion data can ever be provided, the number of active device motion
2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // sensors will be zero. In that case flag the shared memory buffer
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // as ready to read, as it will not change anyway.
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  number_active_device_motion_sensors_ = GetNumberActiveDeviceMotionSensors();
2290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
2300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoLock autolock(motion_buffer_lock_);
2310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    CheckMotionBufferReadyToRead();
2320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return success;
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::StopFetchingDeviceMotionData() {
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Stop(kTypeMotion);
2380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
2390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoLock autolock(motion_buffer_lock_);
2400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (device_motion_buffer_) {
2410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      ClearInternalMotionBuffers();
2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      device_motion_buffer_ = NULL;
2430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::CheckMotionBufferReadyToRead() {
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION] +
2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION_INCL_GRAVITY] +
2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      received_motion_data_[RECEIVED_MOTION_DATA_ROTATION_RATE] ==
2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      number_active_device_motion_sensors_) {
2529ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    device_motion_buffer_->seqlock.WriteBegin();
2538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    device_motion_buffer_->data.interval = kInertialSensorIntervalMillis;
2549ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    device_motion_buffer_->seqlock.WriteEnd();
255424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    SetMotionBufferReadyStatus(true);
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    UMA_HISTOGRAM_BOOLEAN("InertialSensor.AccelerometerAndroidAvailable",
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION] > 0);
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    UMA_HISTOGRAM_BOOLEAN(
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        "InertialSensor.AccelerometerIncGravityAndroidAvailable",
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION_INCL_GRAVITY]
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        > 0);
263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    UMA_HISTOGRAM_BOOLEAN("InertialSensor.GyroscopeAndroidAvailable",
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        received_motion_data_[RECEIVED_MOTION_DATA_ROTATION_RATE] > 0);
2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::SetMotionBufferReadyStatus(bool ready) {
2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->seqlock.WriteBegin();
2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.allAvailableSensorsAreActive = ready;
2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->seqlock.WriteEnd();
272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  is_motion_buffer_ready_ = ready;
2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::ClearInternalMotionBuffers() {
2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  memset(received_motion_data_, 0, sizeof(received_motion_data_));
2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  number_active_device_motion_sensors_ = 0;
278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetMotionBufferReadyStatus(false);
279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// --- Device Orientation
282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::SetOrientationBufferReadyStatus(bool ready) {
284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  device_orientation_buffer_->seqlock.WriteBegin();
2851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  device_orientation_buffer_->data.absolute = ready;
2861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  device_orientation_buffer_->data.hasAbsolute = ready;
287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  device_orientation_buffer_->data.allAvailableSensorsAreActive = ready;
288424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  device_orientation_buffer_->seqlock.WriteEnd();
289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  is_orientation_buffer_ready_ = ready;
290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SensorManagerAndroid::StartFetchingDeviceOrientationData(
293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    DeviceOrientationHardwareBuffer* buffer) {
294424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(buffer);
2950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
2960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoLock autolock(orientation_buffer_lock_);
2970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    device_orientation_buffer_ = buffer;
2980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool success = Start(kTypeOrientation);
300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
3010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
3020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoLock autolock(orientation_buffer_lock_);
3030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // If Start() was unsuccessful then set the buffer ready flag to true
3040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // to start firing all-null events.
3050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    SetOrientationBufferReadyStatus(!success);
3060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!success)
309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    updateRotationVectorHistogram(false);
310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return success;
312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::StopFetchingDeviceOrientationData() {
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Stop(kTypeOrientation);
3160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
3170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoLock autolock(orientation_buffer_lock_);
3180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (device_orientation_buffer_) {
3190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      SetOrientationBufferReadyStatus(false);
3200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      device_orientation_buffer_ = NULL;
3210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
322424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
326