sensor_manager_android.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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),
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      device_motion_buffer_(NULL),
30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      device_orientation_buffer_(NULL),
31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      is_motion_buffer_ready_(false),
32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      is_orientation_buffer_ready_(false) {
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  memset(received_motion_data_, 0, sizeof(received_motion_data_));
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  device_orientation_.Reset(
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      Java_DeviceSensors_getInstance(
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          AttachCurrentThread(),
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          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)
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SensorManagerAndroid::Start(EventType event_type) {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!device_orientation_.is_null());
1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return Java_DeviceSensors_start(
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AttachCurrentThread(), device_orientation_.obj(),
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      reinterpret_cast<intptr_t>(this), static_cast<jint>(event_type),
1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      kInertialSensorIntervalMillis);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::Stop(EventType event_type) {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!device_orientation_.is_null());
1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Java_DeviceSensors_stop(
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      AttachCurrentThread(), device_orientation_.obj(),
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      static_cast<jint>(event_type));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int SensorManagerAndroid::GetNumberActiveDeviceMotionSensors() {
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(!device_orientation_.is_null());
1570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return Java_DeviceSensors_getNumberActiveDeviceMotionSensors(
1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      AttachCurrentThread(), device_orientation_.obj());
1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// ----- Shared memory API methods
1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// --- Device Motion
165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SensorManagerAndroid::StartFetchingDeviceMotionData(
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DeviceMotionHardwareBuffer* buffer) {
168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(buffer);
1690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
1700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoLock autolock(motion_buffer_lock_);
1710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    device_motion_buffer_ = buffer;
1720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ClearInternalMotionBuffers();
1730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool success = Start(kTypeMotion);
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // If no motion data can ever be provided, the number of active device motion
1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // sensors will be zero. In that case flag the shared memory buffer
1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // as ready to read, as it will not change anyway.
1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  number_active_device_motion_sensors_ = GetNumberActiveDeviceMotionSensors();
1800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
1810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoLock autolock(motion_buffer_lock_);
1820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    CheckMotionBufferReadyToRead();
1830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return success;
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::StopFetchingDeviceMotionData() {
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Stop(kTypeMotion);
1890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
1900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoLock autolock(motion_buffer_lock_);
1910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (device_motion_buffer_) {
1920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      ClearInternalMotionBuffers();
1930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      device_motion_buffer_ = NULL;
1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::CheckMotionBufferReadyToRead() {
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION] +
2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION_INCL_GRAVITY] +
2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      received_motion_data_[RECEIVED_MOTION_DATA_ROTATION_RATE] ==
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      number_active_device_motion_sensors_) {
2039ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    device_motion_buffer_->seqlock.WriteBegin();
2048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    device_motion_buffer_->data.interval = kInertialSensorIntervalMillis;
2059ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    device_motion_buffer_->seqlock.WriteEnd();
206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    SetMotionBufferReadyStatus(true);
207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    UMA_HISTOGRAM_BOOLEAN("InertialSensor.AccelerometerAndroidAvailable",
209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION] > 0);
210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    UMA_HISTOGRAM_BOOLEAN(
211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        "InertialSensor.AccelerometerIncGravityAndroidAvailable",
212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        received_motion_data_[RECEIVED_MOTION_DATA_ACCELERATION_INCL_GRAVITY]
213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        > 0);
214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    UMA_HISTOGRAM_BOOLEAN("InertialSensor.GyroscopeAndroidAvailable",
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        received_motion_data_[RECEIVED_MOTION_DATA_ROTATION_RATE] > 0);
2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::SetMotionBufferReadyStatus(bool ready) {
2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->seqlock.WriteBegin();
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->data.allAvailableSensorsAreActive = ready;
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  device_motion_buffer_->seqlock.WriteEnd();
223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  is_motion_buffer_ready_ = ready;
2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::ClearInternalMotionBuffers() {
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  memset(received_motion_data_, 0, sizeof(received_motion_data_));
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  number_active_device_motion_sensors_ = 0;
229424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SetMotionBufferReadyStatus(false);
230424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
231424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
232424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// --- Device Orientation
233424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::SetOrientationBufferReadyStatus(bool ready) {
235424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  device_orientation_buffer_->seqlock.WriteBegin();
2361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  device_orientation_buffer_->data.absolute = ready;
2371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  device_orientation_buffer_->data.hasAbsolute = ready;
238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  device_orientation_buffer_->data.allAvailableSensorsAreActive = ready;
239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  device_orientation_buffer_->seqlock.WriteEnd();
240424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  is_orientation_buffer_ready_ = ready;
241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SensorManagerAndroid::StartFetchingDeviceOrientationData(
244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    DeviceOrientationHardwareBuffer* buffer) {
245424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(buffer);
2460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
2470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoLock autolock(orientation_buffer_lock_);
2480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    device_orientation_buffer_ = buffer;
2490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool success = Start(kTypeOrientation);
251424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
2530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoLock autolock(orientation_buffer_lock_);
2540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // If Start() was unsuccessful then set the buffer ready flag to true
2550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    // to start firing all-null events.
2560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    SetOrientationBufferReadyStatus(!success);
2570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!success)
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    updateRotationVectorHistogram(false);
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return success;
263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SensorManagerAndroid::StopFetchingDeviceOrientationData() {
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Stop(kTypeOrientation);
2670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  {
2680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    base::AutoLock autolock(orientation_buffer_lock_);
2690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    if (device_orientation_buffer_) {
2700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      SetOrientationBufferReadyStatus(false);
2710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      device_orientation_buffer_ = NULL;
2720f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
277