| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 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 "content/browser/device_sensors/sensor_manager_chromeos.h" | |
| 6 | |
| 7 #include <math.h> | |
| 8 | |
| 9 #include "chromeos/accelerometer/accelerometer_reader.h" | |
| 10 #include "chromeos/accelerometer/accelerometer_types.h" | |
| 11 #include "content/browser/device_sensors/device_sensors_consts.h" | |
| 12 #include "ui/gfx/geometry/vector3d_f.h" | |
| 13 | |
| 14 namespace { | |
| 15 // Conversion ratio from radians to degrees. | |
| 16 const double kRad2deg = 180.0 / M_PI; | |
| 17 } | |
| 18 | |
| 19 namespace content { | |
| 20 | |
| 21 SensorManagerChromeOS::SensorManagerChromeOS() | |
| 22 : motion_buffer_(nullptr), orientation_buffer_(nullptr) { | |
| 23 } | |
| 24 | |
| 25 SensorManagerChromeOS::~SensorManagerChromeOS() { | |
| 26 } | |
| 27 | |
| 28 void SensorManagerChromeOS::StartFetchingDeviceMotionData( | |
| 29 DeviceMotionHardwareBuffer* buffer) { | |
| 30 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 31 DCHECK(!motion_buffer_); | |
| 32 motion_buffer_ = buffer; | |
| 33 | |
| 34 motion_buffer_->seqlock.WriteBegin(); | |
| 35 // The interval between updates is the longer of the rate set on the buffer, | |
| 36 // and the rate at which AccelerometerReader polls the sensor. | |
| 37 motion_buffer_->data.interval = | |
| 38 std::max(kDeviceSensorIntervalMicroseconds / 1000, | |
| 39 chromeos::AccelerometerReader::kDelayBetweenReadsMs); | |
| 40 motion_buffer_->seqlock.WriteEnd(); | |
| 41 | |
| 42 if (!orientation_buffer_) | |
| 43 StartObservingAccelerometer(); | |
| 44 } | |
| 45 | |
| 46 bool SensorManagerChromeOS::StopFetchingDeviceMotionData() { | |
| 47 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 48 if (!motion_buffer_) | |
| 49 return false; | |
| 50 | |
| 51 // Make sure to indicate that the sensor data is no longer available. | |
| 52 motion_buffer_->seqlock.WriteBegin(); | |
| 53 motion_buffer_->data.allAvailableSensorsAreActive = false; | |
| 54 motion_buffer_->seqlock.WriteEnd(); | |
| 55 | |
| 56 motion_buffer_ = nullptr; | |
| 57 | |
| 58 if (!orientation_buffer_) | |
| 59 StopObservingAccelerometer(); | |
| 60 return true; | |
| 61 } | |
| 62 | |
| 63 void SensorManagerChromeOS::StartFetchingDeviceOrientationData( | |
| 64 DeviceOrientationHardwareBuffer* buffer) { | |
| 65 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 66 DCHECK(!orientation_buffer_); | |
| 67 orientation_buffer_ = buffer; | |
| 68 | |
| 69 // No compass information, so we cannot provide absolute orientation. | |
| 70 orientation_buffer_->seqlock.WriteBegin(); | |
| 71 orientation_buffer_->data.absolute = false; | |
| 72 orientation_buffer_->seqlock.WriteEnd(); | |
| 73 | |
| 74 if (!motion_buffer_) | |
| 75 StartObservingAccelerometer(); | |
| 76 } | |
| 77 | |
| 78 bool SensorManagerChromeOS::StopFetchingDeviceOrientationData() { | |
| 79 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 80 if (!orientation_buffer_) | |
| 81 return false; | |
| 82 // Make sure to indicate that the sensor data is no longer available. | |
| 83 orientation_buffer_->seqlock.WriteBegin(); | |
| 84 orientation_buffer_->data.allAvailableSensorsAreActive = false; | |
| 85 orientation_buffer_->seqlock.WriteEnd(); | |
| 86 orientation_buffer_ = nullptr; | |
| 87 | |
| 88 if (!motion_buffer_) | |
| 89 StopObservingAccelerometer(); | |
| 90 return true; | |
| 91 } | |
| 92 | |
| 93 void SensorManagerChromeOS::OnAccelerometerUpdated( | |
| 94 scoped_refptr<const chromeos::AccelerometerUpdate> update) { | |
| 95 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 96 chromeos::AccelerometerSource source; | |
| 97 if (update->has(chromeos::ACCELEROMETER_SOURCE_SCREEN)) | |
| 98 source = chromeos::ACCELEROMETER_SOURCE_SCREEN; | |
| 99 else if (update->has(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD)) | |
| 100 source = chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD; | |
| 101 else | |
| 102 return; | |
| 103 | |
| 104 double x = update->get(source).x; | |
| 105 double y = update->get(source).y; | |
| 106 double z = update->get(source).z; | |
| 107 | |
| 108 GenerateMotionEvent(x, y, z); | |
| 109 GenerateOrientationEvent(x, y, z); | |
| 110 } | |
| 111 | |
| 112 void SensorManagerChromeOS::StartObservingAccelerometer() { | |
| 113 chromeos::AccelerometerReader::GetInstance()->AddObserver(this); | |
| 114 } | |
| 115 | |
| 116 void SensorManagerChromeOS::StopObservingAccelerometer() { | |
| 117 chromeos::AccelerometerReader::GetInstance()->RemoveObserver(this); | |
| 118 } | |
| 119 | |
| 120 void SensorManagerChromeOS::GenerateMotionEvent(double x, double y, double z) { | |
| 121 if (!motion_buffer_) | |
| 122 return; | |
| 123 | |
| 124 motion_buffer_->seqlock.WriteBegin(); | |
| 125 motion_buffer_->data.accelerationIncludingGravityX = x; | |
| 126 motion_buffer_->data.hasAccelerationIncludingGravityX = true; | |
| 127 motion_buffer_->data.accelerationIncludingGravityY = y; | |
| 128 motion_buffer_->data.hasAccelerationIncludingGravityY = true; | |
| 129 motion_buffer_->data.accelerationIncludingGravityZ = z; | |
| 130 motion_buffer_->data.hasAccelerationIncludingGravityZ = true; | |
| 131 motion_buffer_->data.allAvailableSensorsAreActive = true; | |
| 132 motion_buffer_->seqlock.WriteEnd(); | |
| 133 } | |
| 134 | |
| 135 void SensorManagerChromeOS::GenerateOrientationEvent(double x, | |
| 136 double y, | |
| 137 double z) { | |
| 138 if (!orientation_buffer_) | |
| 139 return; | |
| 140 | |
| 141 // Create a unit vector for trigonometry | |
| 142 gfx::Vector3dF data(x, y, z); | |
| 143 data.Scale(1.0f / data.Length()); | |
| 144 | |
| 145 // Transform accelerometer to W3C angles, using the Z-X-Y Eulerangles matrix. | |
| 146 // x = sin(gamma) | |
| 147 // y = -cos(gamma) * sin(beta) | |
| 148 // z = cos(beta) * cos(gamma) | |
| 149 // With only accelerometer alpha cannot be provided. | |
| 150 double beta = kRad2deg * atan2(data.y(), data.z()); | |
| 151 double gamma = kRad2deg * asin(-data.x()); | |
| 152 | |
| 153 // Convert beta and gamma to fit the intervals in the specification. Beta is | |
| 154 // [-180, 180) and gamma is [-90, 90). | |
| 155 if (beta >= 180.0f) | |
| 156 beta = -180.0f; | |
| 157 if (gamma >= 90.0f) | |
| 158 gamma = -90.0f; | |
| 159 orientation_buffer_->seqlock.WriteBegin(); | |
| 160 orientation_buffer_->data.beta = beta; | |
| 161 orientation_buffer_->data.hasBeta = true; | |
| 162 orientation_buffer_->data.gamma = gamma; | |
| 163 orientation_buffer_->data.hasGamma = true; | |
| 164 orientation_buffer_->data.allAvailableSensorsAreActive = true; | |
| 165 orientation_buffer_->seqlock.WriteEnd(); | |
| 166 } | |
| 167 | |
| 168 } // namespace content | |
| OLD | NEW |