| Index: content/browser/device_orientation/device_motion_provider.cc
|
| diff --git a/content/browser/device_orientation/device_motion_provider.cc b/content/browser/device_orientation/device_motion_provider.cc
|
| index 84f65cabd1108b6da4bec2a79ff06275a13788a1..e88d5af83f4173e97fe97aaa3077ac828de702c9 100644
|
| --- a/content/browser/device_orientation/device_motion_provider.cc
|
| +++ b/content/browser/device_orientation/device_motion_provider.cc
|
| @@ -4,14 +4,95 @@
|
|
|
| #include "content/browser/device_orientation/device_motion_provider.h"
|
|
|
| +#include "base/bind.h"
|
| #include "base/logging.h"
|
| +#include "base/threading/thread.h"
|
| +#include "base/timer/timer.h"
|
| #include "content/browser/device_orientation/data_fetcher_shared_memory.h"
|
| #include "content/common/device_motion_hardware_buffer.h"
|
|
|
| namespace content {
|
|
|
| +namespace {
|
| +const int kPeriodInMilliseconds = 100;
|
| +}
|
| +
|
| +class DeviceMotionProvider::PollingThread : public base::Thread {
|
| + public:
|
| + explicit PollingThread(const char* name);
|
| + virtual ~PollingThread();
|
| +
|
| + void StartPolling(DataFetcherSharedMemory* fetcher,
|
| + DeviceMotionHardwareBuffer* buffer);
|
| + void StopPolling();
|
| +
|
| + private:
|
| + void DoPoll();
|
| +
|
| + scoped_ptr<base::RepeatingTimer<PollingThread> > timer_;
|
| + DataFetcherSharedMemory* fetcher_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PollingThread);
|
| +};
|
| +
|
| +// ---- PollingThread methods
|
| +
|
| +DeviceMotionProvider::PollingThread::PollingThread(const char* name)
|
| + : base::Thread(name) {
|
| +}
|
| +
|
| +DeviceMotionProvider::PollingThread::~PollingThread() {
|
| +}
|
| +
|
| +void DeviceMotionProvider::PollingThread::StartPolling(
|
| + DataFetcherSharedMemory* fetcher, DeviceMotionHardwareBuffer* buffer) {
|
| + DCHECK(base::MessageLoop::current() == message_loop());
|
| + DCHECK(!timer_);
|
| +
|
| + fetcher_ = fetcher;
|
| + fetcher_->StartFetchingDeviceMotionData(buffer);
|
| + timer_.reset(new base::RepeatingTimer<PollingThread>());
|
| + timer_->Start(FROM_HERE,
|
| + base::TimeDelta::FromMilliseconds(kPeriodInMilliseconds),
|
| + this, &PollingThread::DoPoll);
|
| +}
|
| +
|
| +void DeviceMotionProvider::PollingThread::StopPolling() {
|
| + DCHECK(base::MessageLoop::current() == message_loop());
|
| + DCHECK(fetcher_);
|
| + // this will also stop the timer before killing it.
|
| + timer_.reset();
|
| + fetcher_->StopFetchingDeviceMotionData();
|
| +}
|
| +
|
| +void DeviceMotionProvider::PollingThread::DoPoll() {
|
| + DCHECK(base::MessageLoop::current() == message_loop());
|
| + fetcher_->FetchDeviceMotionDataIntoBuffer();
|
| +}
|
| +
|
| +// ---- end PollingThread methods
|
| +
|
| DeviceMotionProvider::DeviceMotionProvider()
|
| : is_started_(false) {
|
| + Initialize();
|
| +}
|
| +
|
| +DeviceMotionProvider::DeviceMotionProvider(
|
| + scoped_ptr<DataFetcherSharedMemory> fetcher)
|
| + : is_started_(false) {
|
| + data_fetcher_ = fetcher.Pass();
|
| + Initialize();
|
| +}
|
| +
|
| +DeviceMotionProvider::~DeviceMotionProvider() {
|
| + StopFetchingDeviceMotionData();
|
| + // make sure polling thread stops before data_fetcher_ gets deleted.
|
| + if (polling_thread_)
|
| + polling_thread_->Stop();
|
| + data_fetcher_.reset();
|
| +}
|
| +
|
| +void DeviceMotionProvider::Initialize() {
|
| size_t data_size = sizeof(DeviceMotionHardwareBuffer);
|
| bool res = device_motion_shared_memory_.CreateAndMapAnonymous(data_size);
|
| // TODO(timvolodine): consider not crashing the browser if the check fails.
|
| @@ -20,9 +101,6 @@ DeviceMotionProvider::DeviceMotionProvider()
|
| memset(hwbuf, 0, sizeof(DeviceMotionHardwareBuffer));
|
| }
|
|
|
| -DeviceMotionProvider::~DeviceMotionProvider() {
|
| -}
|
| -
|
| base::SharedMemoryHandle DeviceMotionProvider::GetSharedMemoryHandleForProcess(
|
| base::ProcessHandle process) {
|
| base::SharedMemoryHandle renderer_handle;
|
| @@ -33,20 +111,59 @@ base::SharedMemoryHandle DeviceMotionProvider::GetSharedMemoryHandleForProcess(
|
| void DeviceMotionProvider::StartFetchingDeviceMotionData() {
|
| if (is_started_)
|
| return;
|
| +
|
| if (!data_fetcher_)
|
| data_fetcher_.reset(new DataFetcherSharedMemory);
|
| - data_fetcher_->StartFetchingDeviceMotionData(SharedMemoryAsHardwareBuffer());
|
| +
|
| + if (data_fetcher_->NeedsPolling()) {
|
| + if (!polling_thread_)
|
| + CreateAndStartPollingThread();
|
| +
|
| + polling_thread_->message_loop()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&PollingThread::StartPolling,
|
| + base::Unretained(polling_thread_.get()),
|
| + data_fetcher_.get(),
|
| + SharedMemoryAsHardwareBuffer()));
|
| + } else {
|
| + data_fetcher_->StartFetchingDeviceMotionData(
|
| + SharedMemoryAsHardwareBuffer());
|
| + }
|
| +
|
| is_started_ = true;
|
| }
|
|
|
| +void DeviceMotionProvider::CreateAndStartPollingThread() {
|
| + polling_thread_.reset(
|
| + new PollingThread("Device Motion poller"));
|
| +
|
| + if (!polling_thread_->Start()) {
|
| + LOG(ERROR) << "Failed to start Device Motion data polling thread";
|
| + return;
|
| + }
|
| +}
|
| +
|
| void DeviceMotionProvider::StopFetchingDeviceMotionData() {
|
| - if (data_fetcher_)
|
| + if (!is_started_)
|
| + return;
|
| +
|
| + DCHECK(data_fetcher_);
|
| +
|
| + if (data_fetcher_->NeedsPolling()) {
|
| + DCHECK(polling_thread_);
|
| + polling_thread_->message_loop()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&PollingThread::StopPolling,
|
| + base::Unretained(polling_thread_.get())));
|
| + } else {
|
| data_fetcher_->StopFetchingDeviceMotionData();
|
| + }
|
| +
|
| is_started_ = false;
|
| }
|
|
|
| -DeviceMotionHardwareBuffer* DeviceMotionProvider::
|
| - SharedMemoryAsHardwareBuffer() {
|
| +DeviceMotionHardwareBuffer*
|
| +DeviceMotionProvider::SharedMemoryAsHardwareBuffer() {
|
| void* mem = device_motion_shared_memory_.memory();
|
| CHECK(mem);
|
| return static_cast<DeviceMotionHardwareBuffer*>(mem);
|
|
|