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 |