Skip to content

Commit

Permalink
Revert of Refactor DeviceMotionEventPump to use //device/generic_sens…
Browse files Browse the repository at this point in the history
…or instead of //device/sensors (patchset #13 id:240001 of https://codereview.chromium.org/2896583005/ )

Reason for revert:
Need to figure out some issues related to this CL on Android and Mac.

Original issue's description:
> Refactor DeviceMotionEventPump to use //device/generic_sensor instead of //device/sensors
>
> //device/generic_sensors already has all the sensors that can be used
> to implement the DeviceOrientation event:
> https://w3c.github.io/deviceorientation/spec-source-orientation.html
>
> Currently, //content/renderer/device_sensors uses sensors from
> //device/sensors as its backend, and this is one of the CLs that refactor
> //content/renderer/device_sensors to use sensors from
> //device/generic_sensor as the backend and removes //device/sensors.
>
> This CL refactors DeviceMotionEvent to use sensors from //device/generic_sensor.
>
> The issue page contains the design doc link for this change.
>
> BUG=721427
>
> Review-Url: https://codereview.chromium.org/2896583005
> Cr-Commit-Position: refs/heads/master@{#480934}
> Committed: https://chromium.googlesource.com/chromium/src/+/687e6a76c9d634404eb93643ab900596a77958fd

TBR=reillyg@chromium.org,timvolodine@chromium.org,jam@chromium.org,scheib@chromium.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=721427

Review-Url: https://codereview.chromium.org/2948253002
Cr-Commit-Position: refs/heads/master@{#481599}
  • Loading branch information
juncai authored and Commit Bot committed Jun 22, 2017
1 parent 002beb1 commit c7808a0
Show file tree
Hide file tree
Showing 15 changed files with 195 additions and 831 deletions.
287 changes: 73 additions & 214 deletions content/browser/device_sensors/device_sensor_browsertest.cc

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion content/renderer/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,6 @@ target(link_target_type, "renderer") {
"//device/base/synchronization",
"//device/gamepad/public/cpp:shared_with_blink",
"//device/gamepad/public/interfaces",
"//device/generic_sensor/public/cpp",
"//device/screen_orientation/public/interfaces",
"//device/sensors/public/cpp:full",
"//device/sensors/public/interfaces",
Expand Down
2 changes: 0 additions & 2 deletions content/renderer/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ include_rules = [
"+device/base/synchronization",
"+device/gamepad/public/cpp",
"+device/gamepad/public/interfaces",
"+device/generic_sensor/public/cpp",
"+device/generic_sensor/public/interfaces",
"+device/screen_orientation/public/interfaces",
"+device/sensors/public",
"+device/usb/public",
Expand Down
316 changes: 13 additions & 303 deletions content/renderer/device_sensors/device_motion_event_pump.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,328 +2,38 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/renderer/device_sensors/device_motion_event_pump.h"
#include "device_motion_event_pump.h"

#include "base/memory/ptr_util.h"
#include "content/public/common/service_names.mojom.h"
#include "content/public/renderer/render_thread.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "services/device/public/interfaces/constants.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
#include "third_party/WebKit/public/platform/modules/device_orientation/WebDeviceMotionListener.h"

namespace {

constexpr int kMaxReadAttemptsCount = 10;

// TODO(juncai): Extracting mojo::ScopedSharedBufferMapping reading
// functionality into a helper class.
// http://crbug.com/727788
bool TryReadFromBuffer(const device::SensorReadingSharedBuffer* buffer,
device::SensorReading* result) {
const device::OneWriterSeqLock& seqlock = buffer->seqlock.value();
auto version = seqlock.ReadBegin();
auto reading_data = buffer->reading;
if (seqlock.ReadRetry(version))
return false;
*result = reading_data;
return true;
}

// Updates sensor reading from shared buffer.
bool UpdateSensorReading(const device::SensorReadingSharedBuffer* buffer,
device::SensorReading* result) {
int read_attempts = 0;
while (!TryReadFromBuffer(buffer, result)) {
if (++read_attempts == kMaxReadAttemptsCount)
return false;
}

return true;
}

} // namespace

namespace content {

DeviceMotionEventPump::DeviceMotionEventPump(RenderThread* thread)
: PlatformEventObserver<blink::WebDeviceMotionListener>(thread),
accelerometer_(this, device::mojom::SensorType::ACCELEROMETER),
linear_acceleration_sensor_(
this,
device::mojom::SensorType::LINEAR_ACCELERATION),
gyroscope_(this, device::mojom::SensorType::GYROSCOPE),
state_(PumpState::STOPPED) {}
: DeviceSensorMojoClientMixin<
DeviceSensorEventPump<blink::WebDeviceMotionListener>,
device::mojom::MotionSensor>(thread) {}

DeviceMotionEventPump::~DeviceMotionEventPump() {
PlatformEventObserver<blink::WebDeviceMotionListener>::StopIfObserving();
}

void DeviceMotionEventPump::Start(blink::WebPlatformEventListener* listener) {
DVLOG(2) << "requested start";

if (state_ != PumpState::STOPPED)
return;

DCHECK(!timer_.IsRunning());

state_ = PumpState::PENDING_START;
PlatformEventObserver<blink::WebDeviceMotionListener>::Start(listener);
}

void DeviceMotionEventPump::Stop() {
DVLOG(2) << "requested stop";

if (state_ == PumpState::STOPPED)
return;

DCHECK((state_ == PumpState::PENDING_START && !timer_.IsRunning()) ||
(state_ == PumpState::RUNNING && timer_.IsRunning()));

if (timer_.IsRunning())
timer_.Stop();

PlatformEventObserver<blink::WebDeviceMotionListener>::Stop();
state_ = PumpState::STOPPED;
}

void DeviceMotionEventPump::SendStartMessage() {
auto request = mojo::MakeRequest(&sensor_provider_);

// When running layout tests, those observers should not listen to the
// actual hardware changes. In order to make that happen, don't connect
// the other end of the mojo pipe to anything.
if (!RenderThreadImpl::current() ||
RenderThreadImpl::current()->layout_test_mode()) {
return;
}

if (!accelerometer_.sensor && !linear_acceleration_sensor_.sensor &&
!gyroscope_.sensor) {
RenderThread::Get()->GetConnector()->BindInterface(
device::mojom::kServiceName, std::move(request));
sensor_provider_.set_connection_error_handler(
base::Bind(&DeviceMotionEventPump::HandleSensorProviderError,
base::Unretained(this)));
GetSensor(&accelerometer_);
GetSensor(&linear_acceleration_sensor_);
GetSensor(&gyroscope_);
} else {
if (accelerometer_.sensor)
accelerometer_.sensor->Resume();

if (linear_acceleration_sensor_.sensor)
linear_acceleration_sensor_.sensor->Resume();

if (gyroscope_.sensor)
gyroscope_.sensor->Resume();

DidStart();
}
void DeviceMotionEventPump::FireEvent() {
DCHECK(listener());
device::MotionData data;
if (reader_->GetLatestData(&data) && data.all_available_sensors_are_active)
listener()->DidChangeDeviceMotion(data);
}

void DeviceMotionEventPump::SendStopMessage() {
// SendStopMessage() gets called both when the page visibility changes and if
// all device motion event listeners are unregistered. Since removing the
// event listener is more rare than the page visibility changing,
// Sensor::Suspend() is used to optimize this case for not doing extra work.
if (accelerometer_.sensor)
accelerometer_.sensor->Suspend();

if (linear_acceleration_sensor_.sensor)
linear_acceleration_sensor_.sensor->Suspend();

if (gyroscope_.sensor)
gyroscope_.sensor->Suspend();
bool DeviceMotionEventPump::InitializeReader(base::SharedMemoryHandle handle) {
if (!reader_)
reader_.reset(new DeviceMotionSharedMemoryReader());
return reader_->Initialize(handle);
}

void DeviceMotionEventPump::SendFakeDataForTesting(void* fake_data) {
device::MotionData data = *static_cast<device::MotionData*>(fake_data);
listener()->DidChangeDeviceMotion(data);
}

DeviceMotionEventPump::SensorEntry::SensorEntry(
DeviceMotionEventPump* pump,
device::mojom::SensorType sensor_type)
: event_pump(pump), type(sensor_type), client_binding(this) {}

DeviceMotionEventPump::SensorEntry::~SensorEntry() {}

void DeviceMotionEventPump::SensorEntry::RaiseError() {
HandleSensorError();
}

void DeviceMotionEventPump::SensorEntry::SensorReadingChanged() {
// Since DeviceMotionEventPump::FireEvent is called in a certain
// frequency, the |shared_buffer| is read frequently, and
// PlatformSensorConfiguration::set_suppress_on_change_events()
// is set to true, so this method is not called and doesn't need
// to be implemented.
NOTREACHED();
}

void DeviceMotionEventPump::SensorEntry::OnSensorCreated(
device::mojom::SensorInitParamsPtr params,
device::mojom::SensorClientRequest client_request) {
if (!params) {
HandleSensorError();
if (event_pump->CanStart())
event_pump->DidStart();
return;
}

constexpr size_t kReadBufferSize = sizeof(device::SensorReadingSharedBuffer);

DCHECK_EQ(0u, params->buffer_offset % kReadBufferSize);

mode = params->mode;
default_config = params->default_configuration;

DCHECK(sensor.is_bound());
client_binding.Bind(std::move(client_request));

shared_buffer_handle = std::move(params->memory);
DCHECK(!shared_buffer);
shared_buffer =
shared_buffer_handle->MapAtOffset(kReadBufferSize, params->buffer_offset);

if (!shared_buffer) {
HandleSensorError();
if (event_pump->CanStart())
event_pump->DidStart();
return;
}

DCHECK_GT(params->minimum_frequency, 0.0);
DCHECK_GE(params->maximum_frequency, params->minimum_frequency);
DCHECK_GE(device::mojom::SensorConfiguration::kMaxAllowedFrequency,
params->maximum_frequency);

default_config.set_frequency(kDefaultPumpFrequencyHz);
default_config.set_suppress_on_change_events(true);

sensor->AddConfiguration(default_config,
base::Bind(&SensorEntry::OnSensorAddConfiguration,
base::Unretained(this)));
}

void DeviceMotionEventPump::SensorEntry::OnSensorAddConfiguration(
bool success) {
if (!success)
HandleSensorError();
if (event_pump->CanStart())
event_pump->DidStart();
}

void DeviceMotionEventPump::SensorEntry::HandleSensorError() {
sensor.reset();
shared_buffer_handle.reset();
shared_buffer.reset();
client_binding.Close();
}

bool DeviceMotionEventPump::SensorEntry::SensorReadingCouldBeRead() {
if (!sensor)
return false;

const device::SensorReadingSharedBuffer* buffer =
static_cast<const device::SensorReadingSharedBuffer*>(
shared_buffer.get());
if (!UpdateSensorReading(buffer, &reading)) {
HandleSensorError();
return false;
}

return true;
}

void DeviceMotionEventPump::FireEvent() {
device::MotionData data;
// The device orientation spec states that interval should be in milliseconds.
// https://w3c.github.io/deviceorientation/spec-source-orientation.html#devicemotion
data.interval = kDefaultPumpDelayMicroseconds / 1000;

DCHECK(listener());

GetDataFromSharedMemory(&data);
listener()->DidChangeDeviceMotion(data);
}

void DeviceMotionEventPump::DidStart() {
DVLOG(2) << "did start sensor event pump";

if (state_ != PumpState::PENDING_START)
return;

DCHECK(!timer_.IsRunning());

timer_.Start(FROM_HERE,
base::TimeDelta::FromMicroseconds(kDefaultPumpDelayMicroseconds),
this, &DeviceMotionEventPump::FireEvent);
state_ = PumpState::RUNNING;
}

bool DeviceMotionEventPump::CanStart() const {
if (accelerometer_.sensor && !accelerometer_.shared_buffer)
return false;

if (linear_acceleration_sensor_.sensor &&
!linear_acceleration_sensor_.shared_buffer) {
return false;
}

if (gyroscope_.sensor && !gyroscope_.shared_buffer)
return false;

return true;
}

void DeviceMotionEventPump::GetDataFromSharedMemory(device::MotionData* data) {
if (accelerometer_.SensorReadingCouldBeRead()) {
data->acceleration_including_gravity_x =
accelerometer_.reading.values[0].value();
data->acceleration_including_gravity_y =
accelerometer_.reading.values[1].value();
data->acceleration_including_gravity_z =
accelerometer_.reading.values[2].value();
data->has_acceleration_including_gravity_x = true;
data->has_acceleration_including_gravity_y = true;
data->has_acceleration_including_gravity_z = true;
}

if (linear_acceleration_sensor_.SensorReadingCouldBeRead()) {
data->acceleration_x =
linear_acceleration_sensor_.reading.values[0].value();
data->acceleration_y =
linear_acceleration_sensor_.reading.values[1].value();
data->acceleration_z =
linear_acceleration_sensor_.reading.values[2].value();
data->has_acceleration_x = true;
data->has_acceleration_y = true;
data->has_acceleration_z = true;
}

if (gyroscope_.SensorReadingCouldBeRead()) {
data->rotation_rate_alpha = gyroscope_.reading.values[0].value();
data->rotation_rate_beta = gyroscope_.reading.values[1].value();
data->rotation_rate_gamma = gyroscope_.reading.values[2].value();
data->has_rotation_rate_alpha = true;
data->has_rotation_rate_beta = true;
data->has_rotation_rate_gamma = true;
}
}

void DeviceMotionEventPump::GetSensor(SensorEntry* sensor_entry) {
auto request = mojo::MakeRequest(&sensor_entry->sensor);
sensor_provider_->GetSensor(sensor_entry->type, std::move(request),
base::Bind(&SensorEntry::OnSensorCreated,
base::Unretained(sensor_entry)));
sensor_entry->sensor.set_connection_error_handler(base::Bind(
&SensorEntry::HandleSensorError, base::Unretained(sensor_entry)));
}

void DeviceMotionEventPump::HandleSensorProviderError() {
sensor_provider_.reset();
}

} // namespace content
Loading

0 comments on commit c7808a0

Please sign in to comment.