Chromium Code Reviews| 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..2defc892d662b54cd6aade2ce1dc55320fcebb1e 100644 |
| --- a/content/browser/device_orientation/device_motion_provider.cc |
| +++ b/content/browser/device_orientation/device_motion_provider.cc |
| @@ -4,14 +4,55 @@ |
| #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: |
| + PollingThread(const char* name); |
|
bulach
2013/07/24 14:33:27
nit: explicit
timvolodine
2013/07/25 16:46:41
Done.
|
| + virtual ~PollingThread(); |
| + |
| + void StartPolling(DataFetcherSharedMemory* fetcher, |
| + DeviceMotionHardwareBuffer* buffer); |
|
bulach
2013/07/24 14:33:27
nit: left align with the open parens
timvolodine
2013/07/25 16:46:41
Done.
|
| + void StopPolling(); |
| + |
| + private: |
| + void DoPoll(); |
|
bulach
2013/07/24 14:33:27
nit: add a \n
timvolodine
2013/07/25 16:46:41
Done.
|
| + scoped_ptr<base::RepeatingTimer<PollingThread> > timer_; |
| + DataFetcherSharedMemory* fetcher_; |
|
bulach
2013/07/24 14:33:27
nit:
\n
DISALLOW_COPY_AND_ASSIGN(DeviceMotionProvi
timvolodine
2013/07/25 16:46:41
Done.
|
| +}; |
| + |
| + |
| DeviceMotionProvider::DeviceMotionProvider() |
| - : is_started_(false) { |
| + : is_stopped_or_stopping_(true) { |
| + Initialize(); |
| +} |
| + |
| +DeviceMotionProvider::DeviceMotionProvider( |
| + scoped_ptr<DataFetcherSharedMemory> fetcher) |
| + : is_stopped_or_stopping_(true) { |
| + data_fetcher_.reset(fetcher.release()); |
|
bulach
2013/07/24 14:33:27
I think it's possible to:
data_fetcher_ = fetcher;
timvolodine
2013/07/25 16:46:41
that doesn't seem to work because '=' is private a
|
| + Initialize(); |
| +} |
| + |
| +DeviceMotionProvider::~DeviceMotionProvider() { |
| + // make sure polling thread stops before data_fetcher_ gets deleted. |
| + if (polling_thread_) |
| + polling_thread_->Stop(); |
| + data_fetcher_.reset(); |
|
bulach
2013/07/24 14:33:27
reset would be called automatically, no?
timvolodine
2013/07/25 16:46:41
yes, but this is a small kind of optimization to m
|
| +} |
| + |
| +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 +61,6 @@ DeviceMotionProvider::DeviceMotionProvider() |
| memset(hwbuf, 0, sizeof(DeviceMotionHardwareBuffer)); |
| } |
| -DeviceMotionProvider::~DeviceMotionProvider() { |
| -} |
| - |
| base::SharedMemoryHandle DeviceMotionProvider::GetSharedMemoryHandleForProcess( |
| base::ProcessHandle process) { |
| base::SharedMemoryHandle renderer_handle; |
| @@ -31,25 +69,98 @@ base::SharedMemoryHandle DeviceMotionProvider::GetSharedMemoryHandleForProcess( |
| } |
| void DeviceMotionProvider::StartFetchingDeviceMotionData() { |
| - if (is_started_) |
| + if (!is_stopped_or_stopping_) |
|
bulach
2013/07/24 14:33:27
would "is_started" be clearer?
timvolodine
2013/07/25 16:46:41
Done.
|
| return; |
| + |
| if (!data_fetcher_) |
| data_fetcher_.reset(new DataFetcherSharedMemory); |
| - data_fetcher_->StartFetchingDeviceMotionData(SharedMemoryAsHardwareBuffer()); |
| - is_started_ = true; |
| + |
| + 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_stopped_or_stopping_ = false; |
| +} |
| + |
| +void DeviceMotionProvider::CreateAndStartPollingThread() { |
| + polling_thread_.reset( |
| + new PollingThread("Device Motion data polling thread")); |
|
bulach
2013/07/24 14:33:27
nit: perhaps just "DeviceMotion poller" would be e
timvolodine
2013/07/25 16:46:41
Done.
|
| + |
| + if (!polling_thread_->Start()) { |
| + LOG(ERROR) << "Failed to start Device Motion data polling thread"; |
| + return; |
| + } |
| } |
| void DeviceMotionProvider::StopFetchingDeviceMotionData() { |
| - if (data_fetcher_) |
| + if (is_stopped_or_stopping_) |
| + 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; |
| + } |
| + |
| + is_stopped_or_stopping_ = true; |
| } |
| -DeviceMotionHardwareBuffer* DeviceMotionProvider:: |
| - SharedMemoryAsHardwareBuffer() { |
| +DeviceMotionHardwareBuffer* |
| +DeviceMotionProvider::SharedMemoryAsHardwareBuffer() { |
| void* mem = device_motion_shared_memory_.memory(); |
| CHECK(mem); |
| return static_cast<DeviceMotionHardwareBuffer*>(mem); |
| } |
| +// ---- Polling thread methods |
|
bulach
2013/07/24 14:33:27
nit: probably best to keep this higher up, closer
timvolodine
2013/07/25 16:46:41
Done.
|
| + |
| +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()); |
| + // 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(); |
| +} |
| + |
| } // namespace content |