Commit a6725f19 authored by jonross's avatar jonross Committed by Commit bot

Reland Device Orientation API on Chrome OS

This reverts commit cc6a8bfe.
From review: https://codereview.chromium.org/899973002/

Original issue's description:
> Device Orientation API on Chrome OS
>
> Implement DataFetcherSharedMemory on Chrome OS to provide Device Orientation support. Create SensorManagerChromeOS to observe accelerometer events, and to generate updates to the Device Orientation API.
>
> This is a follow up to: https://codereview.chromium.org/680383007/
>
> With the accelerometer on Chrome OS now exposed to content/ from chromeos/accelerometer, no ash/ implementation is required. No public api in content/public/browser is needed either.
>
> TEST=SensorManagerTest.OrientationBuffer, SensorManagerTest.NeutralOrientation, SensorManagerTest.UpsideDown, SensorManagerTest.BeforeUpsideDownBoundary, SensorManagerTest.LeftEdge, SensorManagerTest.RightEdge, SensorManagerTest.BeforeRightEdgeBoundary
> BUG=342908

TBR=timvolodine@chromium.org,jam@chromium.org
BUG=342908

Review URL: https://codereview.chromium.org/880083005

Cr-Commit-Position: refs/heads/master@{#314692}
parent 597a8517
...@@ -350,6 +350,7 @@ source_set("browser") { ...@@ -350,6 +350,7 @@ source_set("browser") {
} }
if (is_chromeos) { if (is_chromeos) {
sources -= [ "device_sensors/data_fetcher_shared_memory_default.cc" ]
deps += [ deps += [
"//chromeos", "//chromeos",
"//chromeos:power_manager_proto", "//chromeos:power_manager_proto",
......
...@@ -22,7 +22,9 @@ class SuddenMotionSensor; ...@@ -22,7 +22,9 @@ class SuddenMotionSensor;
namespace content { namespace content {
#if defined(OS_MACOSX) #if defined(OS_CHROMEOS)
class SensorManagerChromeOS;
#elif defined(OS_MACOSX)
class AmbientLightSensor; class AmbientLightSensor;
#endif #endif
...@@ -42,7 +44,10 @@ class CONTENT_EXPORT DataFetcherSharedMemory ...@@ -42,7 +44,10 @@ class CONTENT_EXPORT DataFetcherSharedMemory
DeviceOrientationHardwareBuffer* orientation_buffer_; DeviceOrientationHardwareBuffer* orientation_buffer_;
DeviceLightHardwareBuffer* light_buffer_; DeviceLightHardwareBuffer* light_buffer_;
#endif #endif
#if defined(OS_MACOSX)
#if defined(OS_CHROMEOS)
scoped_ptr<SensorManagerChromeOS> sensor_manager_;
#elif defined(OS_MACOSX)
void Fetch(unsigned consumer_bitmask) override; void Fetch(unsigned consumer_bitmask) override;
FetcherType GetType() const override; FetcherType GetType() const override;
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/device_sensors/data_fetcher_shared_memory.h"
#include "content/browser/device_sensors/sensor_manager_chromeos.h"
namespace content {
DataFetcherSharedMemory::DataFetcherSharedMemory() {
}
DataFetcherSharedMemory::~DataFetcherSharedMemory() {
}
bool DataFetcherSharedMemory::Start(ConsumerType consumer_type, void* buffer) {
DCHECK(buffer);
if (!sensor_manager_)
sensor_manager_.reset(new SensorManagerChromeOS);
switch (consumer_type) {
case CONSUMER_TYPE_MOTION:
// TODO(jonross): Implement Device Motion API. (crbug.com/427662)
NOTIMPLEMENTED();
return false;
case CONSUMER_TYPE_ORIENTATION:
return sensor_manager_->StartFetchingDeviceOrientationData(
static_cast<DeviceOrientationHardwareBuffer*>(buffer));
case CONSUMER_TYPE_LIGHT:
NOTIMPLEMENTED();
return false;
}
NOTREACHED();
return false;
}
bool DataFetcherSharedMemory::Stop(ConsumerType consumer_type) {
switch (consumer_type) {
case CONSUMER_TYPE_MOTION:
NOTIMPLEMENTED();
return false;
case CONSUMER_TYPE_ORIENTATION:
return sensor_manager_->StopFetchingDeviceOrientationData();
case CONSUMER_TYPE_LIGHT:
NOTIMPLEMENTED();
return false;
}
NOTREACHED();
return false;
}
} // namespace content
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/device_sensors/sensor_manager_chromeos.h"
#include <math.h>
#include "base/logging.h"
#include "chromeos/accelerometer/accelerometer_reader.h"
#include "chromeos/accelerometer/accelerometer_types.h"
#include "ui/gfx/geometry/vector3d_f.h"
namespace {
// Conversion ratio from radians to degrees.
const double kRad2deg = 180.0 / M_PI;
}
namespace content {
SensorManagerChromeOS::SensorManagerChromeOS() : orientation_buffer_(nullptr) {
}
SensorManagerChromeOS::~SensorManagerChromeOS() {
}
bool SensorManagerChromeOS::StartFetchingDeviceOrientationData(
DeviceOrientationHardwareBuffer* buffer) {
DCHECK(buffer);
{
base::AutoLock autolock(orientation_buffer_lock_);
if (orientation_buffer_)
return false;
orientation_buffer_ = buffer;
// No compass information, so we cannot provide absolute orientation.
orientation_buffer_->seqlock.WriteBegin();
orientation_buffer_->data.absolute = false;
orientation_buffer_->data.hasAbsolute = true;
orientation_buffer_->seqlock.WriteEnd();
}
StartObservingAccelerometer();
return true;
}
bool SensorManagerChromeOS::StopFetchingDeviceOrientationData() {
{
base::AutoLock autolock(orientation_buffer_lock_);
if (!orientation_buffer_)
return false;
// Make sure to indicate that the sensor data is no longer available.
orientation_buffer_->seqlock.WriteBegin();
orientation_buffer_->data.allAvailableSensorsAreActive = false;
orientation_buffer_->seqlock.WriteEnd();
orientation_buffer_ = nullptr;
}
StopObservingAccelerometer();
return true;
}
void SensorManagerChromeOS::OnAccelerometerUpdated(
const chromeos::AccelerometerUpdate& update) {
base::AutoLock autolock(orientation_buffer_lock_);
if (!orientation_buffer_)
return;
chromeos::AccelerometerSource source;
if (update.has(chromeos::ACCELEROMETER_SOURCE_SCREEN)) {
source = chromeos::ACCELEROMETER_SOURCE_SCREEN;
} else if (update.has(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD)) {
source = chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD;
} else {
return;
}
double x = update.get(source).x;
double y = update.get(source).y;
double z = update.get(source).z;
// Create a unit vector for trigonometry
// TODO(jonross): Stop reversing signs for vector components once
// accelerometer values have been fixed. crbug.com/431391
// Ternaries are to remove -0.0f which gives incorrect trigonometrical
// results.
gfx::Vector3dF data(x, y ? -y : 0.0f, z ? -z : 0.0f);
data.Scale(1.0f / data.Length());
// Transform accelerometer to W3C angles, using the Z-X-Y Eulerangles matrix.
// x = sin(gamma)
// y = -cos(gamma) * sin(beta)
// z = cos(beta) * cos(gamma)
// With only accelerometer alpha cannot be provided.
double beta = kRad2deg * atan2(data.y(), data.z());
double gamma = kRad2deg * asin(data.x());
// Convert beta and gamma to fit the intervals in the specification. Beta is
// [-180, 180) and gamma is [-90, 90).
if (beta >= 180.0f)
beta = -180.0f;
if (gamma >= 90.0f)
gamma = -90.0f;
orientation_buffer_->seqlock.WriteBegin();
orientation_buffer_->data.beta = beta;
orientation_buffer_->data.hasBeta = true;
orientation_buffer_->data.gamma = gamma;
orientation_buffer_->data.hasGamma = true;
orientation_buffer_->data.allAvailableSensorsAreActive = true;
orientation_buffer_->seqlock.WriteEnd();
}
void SensorManagerChromeOS::StartObservingAccelerometer() {
chromeos::AccelerometerReader::GetInstance()->AddObserver(this);
}
void SensorManagerChromeOS::StopObservingAccelerometer() {
chromeos::AccelerometerReader::GetInstance()->RemoveObserver(this);
}
} // namespace content
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_DEVICE_SENSORS_SENSOR_MANAGER_CHROMEOS_H_
#define CONTENT_BROWSER_DEVICE_SENSORS_SENSOR_MANAGER_CHROMEOS_H_
#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "chromeos/accelerometer/accelerometer_reader.h"
#include "chromeos/accelerometer/accelerometer_types.h"
#include "content/common/content_export.h"
#include "content/common/device_sensors/device_orientation_hardware_buffer.h"
namespace content {
// Observes Chrome OS accelerometer sensors, and provides updated device
// orientation information.
class CONTENT_EXPORT SensorManagerChromeOS
: public chromeos::AccelerometerReader::Observer {
public:
SensorManagerChromeOS();
~SensorManagerChromeOS() override;
// Begins monitoring of orientation events, the shared memory of |buffer| will
// be updated upon subsequent events.
bool StartFetchingDeviceOrientationData(
DeviceOrientationHardwareBuffer* buffer);
// Stops monitoring orientation events. Returns true if there is an active
// |orientation_buffer_| and fetching stops. Otherwise returns false.
bool StopFetchingDeviceOrientationData();
// chromeos::AccelerometerReader::Observer:
void OnAccelerometerUpdated(
const chromeos::AccelerometerUpdate& update) override;
protected:
// Begins/ends the observation of accelerometer events.
virtual void StartObservingAccelerometer();
virtual void StopObservingAccelerometer();
private:
// Shared memory to update.
DeviceOrientationHardwareBuffer* orientation_buffer_;
// Synchronize orientation_buffer_ across threads.
base::Lock orientation_buffer_lock_;
DISALLOW_COPY_AND_ASSIGN(SensorManagerChromeOS);
};
} // namespace content
#endif // CONTENT_BROWSER_DEVICE_SENSORS_SENSOR_MANAGER_CHROMEOS_H_
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/device_sensors/sensor_manager_chromeos.h"
#include "base/memory/scoped_ptr.h"
#include "chromeos/accelerometer/accelerometer_types.h"
#include "content/common/device_sensors/device_orientation_hardware_buffer.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
const double kMeanGravity = 9.80665;
// Isolated content::SensorManagerChromeOS from the active
// chromeos::AccelerometerReader. This allows for direct control over which
// accelerometer events are provided to the sensor manager.
class TestSensorManagerChromeOS : public content::SensorManagerChromeOS {
public:
TestSensorManagerChromeOS() {}
~TestSensorManagerChromeOS() override {};
protected:
void StartObservingAccelerometer() override {}
void StopObservingAccelerometer() override {}
private:
DISALLOW_COPY_AND_ASSIGN(TestSensorManagerChromeOS);
};
} // namespace
namespace content {
class SensorManagerChromeOSTest : public testing::Test {
public:
SensorManagerChromeOSTest() {
orientation_buffer_.reset(new DeviceOrientationHardwareBuffer);
}
~SensorManagerChromeOSTest() override {}
void OnAccelerationIncludingGravity(double x, double y, double z) {
chromeos::AccelerometerUpdate update;
update.Set(chromeos::ACCELEROMETER_SOURCE_SCREEN, x, y, z);
sensor_manager_->OnAccelerometerUpdated(update);
}
DeviceOrientationHardwareBuffer* orientation_buffer() {
return orientation_buffer_.get();
}
SensorManagerChromeOS* sensor_manager() { return sensor_manager_.get(); }
// testing::Test:
void SetUp() override {
testing::Test::SetUp();
sensor_manager_.reset(new TestSensorManagerChromeOS);
sensor_manager_->StartFetchingDeviceOrientationData(
orientation_buffer_.get());
}
void TearDown() override {
sensor_manager_->StopFetchingDeviceOrientationData();
testing::Test::TearDown();
}
private:
scoped_ptr<TestSensorManagerChromeOS> sensor_manager_;
scoped_ptr<DeviceOrientationHardwareBuffer> orientation_buffer_;
DISALLOW_COPY_AND_ASSIGN(SensorManagerChromeOSTest);
};
// Tests that starting to process orientation data will update the associated
// buffer.
TEST_F(SensorManagerChromeOSTest, OrientationBuffer) {
DeviceOrientationHardwareBuffer* buffer = orientation_buffer();
EXPECT_TRUE(buffer->data.hasAbsolute);
EXPECT_FALSE(buffer->data.hasAlpha);
EXPECT_FALSE(buffer->data.hasBeta);
EXPECT_FALSE(buffer->data.hasGamma);
EXPECT_FALSE(buffer->data.allAvailableSensorsAreActive);
OnAccelerationIncludingGravity(0.0f, 0.0f, 1.0f);
EXPECT_FLOAT_EQ(0.0f, buffer->data.alpha);
EXPECT_FALSE(buffer->data.hasAlpha);
EXPECT_TRUE(buffer->data.hasBeta);
EXPECT_TRUE(buffer->data.hasGamma);
EXPECT_TRUE(buffer->data.allAvailableSensorsAreActive);
sensor_manager()->StopFetchingDeviceOrientationData();
EXPECT_FALSE(buffer->data.allAvailableSensorsAreActive);
}
// Tests a device resting flat.
TEST_F(SensorManagerChromeOSTest, NeutralOrientation) {
OnAccelerationIncludingGravity(0.0f, 0.0f, -kMeanGravity);
DeviceOrientationHardwareBuffer* buffer = orientation_buffer();
EXPECT_FLOAT_EQ(0.0f, buffer->data.beta);
EXPECT_FLOAT_EQ(0.0f, buffer->data.gamma);
}
// Tests an upside-down device, such that the W3C boundary [-180,180) causes the
// beta value to become negative.
TEST_F(SensorManagerChromeOSTest, UpsideDown) {
OnAccelerationIncludingGravity(0.0f, 0.0f, kMeanGravity);
DeviceOrientationHardwareBuffer* buffer = orientation_buffer();
EXPECT_FLOAT_EQ(-180.0f, buffer->data.beta);
EXPECT_FLOAT_EQ(0.0f, buffer->data.gamma);
}
// Tests for positive beta value before the device is completely upside-down
TEST_F(SensorManagerChromeOSTest, BeforeUpsideDownBoundary) {
OnAccelerationIncludingGravity(0.0f, -kMeanGravity / 2.0f,
kMeanGravity / 2.0f);
DeviceOrientationHardwareBuffer* buffer = orientation_buffer();
EXPECT_FLOAT_EQ(135.0f, buffer->data.beta);
EXPECT_FLOAT_EQ(0.0f, buffer->data.gamma);
}
// Tests a device lying on its left-edge.
TEST_F(SensorManagerChromeOSTest, LeftEdge) {
OnAccelerationIncludingGravity(-kMeanGravity, 0.0f, 0.0f);
DeviceOrientationHardwareBuffer* buffer = orientation_buffer();
EXPECT_FLOAT_EQ(0.0f, buffer->data.beta);
EXPECT_FLOAT_EQ(-90.0f, buffer->data.gamma);
}
// Tests a device lying on its right-edge, such that the W3C boundary [-90,90)
// causes the gamma value to become negative.
TEST_F(SensorManagerChromeOSTest, RightEdge) {
OnAccelerationIncludingGravity(kMeanGravity, 0.0f, 0.0f);
DeviceOrientationHardwareBuffer* buffer = orientation_buffer();
EXPECT_FLOAT_EQ(0.0f, buffer->data.beta);
EXPECT_FLOAT_EQ(-90.0f, buffer->data.gamma);
}
// Tests for positive gamma value before the device is completely on its right
// side.
TEST_F(SensorManagerChromeOSTest, BeforeRightEdgeBoundary) {
OnAccelerationIncludingGravity(kMeanGravity / 2.0f, 0.0f,
-kMeanGravity / 2.0f);
DeviceOrientationHardwareBuffer* buffer = orientation_buffer();
EXPECT_FLOAT_EQ(0.0f, buffer->data.beta);
EXPECT_FLOAT_EQ(45.0f, buffer->data.gamma);
}
} // namespace content
...@@ -514,6 +514,7 @@ ...@@ -514,6 +514,7 @@
'browser/device_sensors/data_fetcher_shared_memory_android.cc', 'browser/device_sensors/data_fetcher_shared_memory_android.cc',
'browser/device_sensors/data_fetcher_shared_memory_base.cc', 'browser/device_sensors/data_fetcher_shared_memory_base.cc',
'browser/device_sensors/data_fetcher_shared_memory_base.h', 'browser/device_sensors/data_fetcher_shared_memory_base.h',
'browser/device_sensors/data_fetcher_shared_memory_chromeos.cc',
'browser/device_sensors/data_fetcher_shared_memory_default.cc', 'browser/device_sensors/data_fetcher_shared_memory_default.cc',
'browser/device_sensors/data_fetcher_shared_memory_mac.cc', 'browser/device_sensors/data_fetcher_shared_memory_mac.cc',
'browser/device_sensors/data_fetcher_shared_memory_win.cc', 'browser/device_sensors/data_fetcher_shared_memory_win.cc',
...@@ -528,6 +529,8 @@ ...@@ -528,6 +529,8 @@
'browser/device_sensors/inertial_sensor_consts.h', 'browser/device_sensors/inertial_sensor_consts.h',
'browser/device_sensors/sensor_manager_android.cc', 'browser/device_sensors/sensor_manager_android.cc',
'browser/device_sensors/sensor_manager_android.h', 'browser/device_sensors/sensor_manager_android.h',
'browser/device_sensors/sensor_manager_chromeos.cc',
'browser/device_sensors/sensor_manager_chromeos.h',
'browser/dom_storage/dom_storage_area.cc', 'browser/dom_storage/dom_storage_area.cc',
'browser/dom_storage/dom_storage_area.h', 'browser/dom_storage/dom_storage_area.h',
'browser/dom_storage/dom_storage_context_impl.cc', 'browser/dom_storage/dom_storage_context_impl.cc',
...@@ -1891,6 +1894,7 @@ ...@@ -1891,6 +1894,7 @@
'../chromeos/chromeos.gyp:power_manager_proto', '../chromeos/chromeos.gyp:power_manager_proto',
], ],
'sources!': [ 'sources!': [
'browser/device_sensors/data_fetcher_shared_memory_default.cc',
'browser/geolocation/wifi_data_provider_linux.cc', 'browser/geolocation/wifi_data_provider_linux.cc',
'browser/power_save_blocker_ozone.cc', 'browser/power_save_blocker_ozone.cc',
'browser/power_save_blocker_x11.cc', 'browser/power_save_blocker_x11.cc',
......
...@@ -345,6 +345,7 @@ ...@@ -345,6 +345,7 @@
'browser/database_util_unittest.cc', 'browser/database_util_unittest.cc',
'browser/device_sensors/data_fetcher_shared_memory_base_unittest.cc', 'browser/device_sensors/data_fetcher_shared_memory_base_unittest.cc',
'browser/device_sensors/sensor_manager_android_unittest.cc', 'browser/device_sensors/sensor_manager_android_unittest.cc',
'browser/device_sensors/sensor_manager_chromeos_unittest.cc',
'browser/devtools/devtools_http_handler_unittest.cc', 'browser/devtools/devtools_http_handler_unittest.cc',
'browser/devtools/devtools_manager_unittest.cc', 'browser/devtools/devtools_manager_unittest.cc',
'browser/devtools/shared_worker_devtools_manager_unittest.cc', 'browser/devtools/shared_worker_devtools_manager_unittest.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment