OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/device_orientation/device_motion_provider.h" | 5 #include "content/browser/device_orientation/device_motion_provider.h" |
6 | 6 |
7 #include "base/bind.h" | |
7 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/threading/thread.h" | |
10 #include "base/timer/timer.h" | |
8 #include "content/browser/device_orientation/data_fetcher_shared_memory.h" | 11 #include "content/browser/device_orientation/data_fetcher_shared_memory.h" |
9 #include "content/common/device_motion_hardware_buffer.h" | 12 #include "content/common/device_motion_hardware_buffer.h" |
10 | 13 |
11 namespace content { | 14 namespace content { |
12 | 15 |
16 namespace { | |
17 const int kPeriodInMilliseconds = 100; | |
18 } | |
19 | |
20 class DeviceMotionProvider::PollingThread : public base::Thread { | |
21 public: | |
22 PollingThread(const char* name); | |
bulach
2013/07/24 14:33:27
nit: explicit
timvolodine
2013/07/25 16:46:41
Done.
| |
23 virtual ~PollingThread(); | |
24 | |
25 void StartPolling(DataFetcherSharedMemory* fetcher, | |
26 DeviceMotionHardwareBuffer* buffer); | |
bulach
2013/07/24 14:33:27
nit: left align with the open parens
timvolodine
2013/07/25 16:46:41
Done.
| |
27 void StopPolling(); | |
28 | |
29 private: | |
30 void DoPoll(); | |
bulach
2013/07/24 14:33:27
nit: add a \n
timvolodine
2013/07/25 16:46:41
Done.
| |
31 scoped_ptr<base::RepeatingTimer<PollingThread> > timer_; | |
32 DataFetcherSharedMemory* fetcher_; | |
bulach
2013/07/24 14:33:27
nit:
\n
DISALLOW_COPY_AND_ASSIGN(DeviceMotionProvi
timvolodine
2013/07/25 16:46:41
Done.
| |
33 }; | |
34 | |
35 | |
13 DeviceMotionProvider::DeviceMotionProvider() | 36 DeviceMotionProvider::DeviceMotionProvider() |
14 : is_started_(false) { | 37 : is_stopped_or_stopping_(true) { |
38 Initialize(); | |
39 } | |
40 | |
41 DeviceMotionProvider::DeviceMotionProvider( | |
42 scoped_ptr<DataFetcherSharedMemory> fetcher) | |
43 : is_stopped_or_stopping_(true) { | |
44 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
| |
45 Initialize(); | |
46 } | |
47 | |
48 DeviceMotionProvider::~DeviceMotionProvider() { | |
49 // make sure polling thread stops before data_fetcher_ gets deleted. | |
50 if (polling_thread_) | |
51 polling_thread_->Stop(); | |
52 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
| |
53 } | |
54 | |
55 void DeviceMotionProvider::Initialize() { | |
15 size_t data_size = sizeof(DeviceMotionHardwareBuffer); | 56 size_t data_size = sizeof(DeviceMotionHardwareBuffer); |
16 bool res = device_motion_shared_memory_.CreateAndMapAnonymous(data_size); | 57 bool res = device_motion_shared_memory_.CreateAndMapAnonymous(data_size); |
17 // TODO(timvolodine): consider not crashing the browser if the check fails. | 58 // TODO(timvolodine): consider not crashing the browser if the check fails. |
18 CHECK(res); | 59 CHECK(res); |
19 DeviceMotionHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer(); | 60 DeviceMotionHardwareBuffer* hwbuf = SharedMemoryAsHardwareBuffer(); |
20 memset(hwbuf, 0, sizeof(DeviceMotionHardwareBuffer)); | 61 memset(hwbuf, 0, sizeof(DeviceMotionHardwareBuffer)); |
21 } | 62 } |
22 | 63 |
23 DeviceMotionProvider::~DeviceMotionProvider() { | |
24 } | |
25 | |
26 base::SharedMemoryHandle DeviceMotionProvider::GetSharedMemoryHandleForProcess( | 64 base::SharedMemoryHandle DeviceMotionProvider::GetSharedMemoryHandleForProcess( |
27 base::ProcessHandle process) { | 65 base::ProcessHandle process) { |
28 base::SharedMemoryHandle renderer_handle; | 66 base::SharedMemoryHandle renderer_handle; |
29 device_motion_shared_memory_.ShareToProcess(process, &renderer_handle); | 67 device_motion_shared_memory_.ShareToProcess(process, &renderer_handle); |
30 return renderer_handle; | 68 return renderer_handle; |
31 } | 69 } |
32 | 70 |
33 void DeviceMotionProvider::StartFetchingDeviceMotionData() { | 71 void DeviceMotionProvider::StartFetchingDeviceMotionData() { |
34 if (is_started_) | 72 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.
| |
35 return; | 73 return; |
74 | |
36 if (!data_fetcher_) | 75 if (!data_fetcher_) |
37 data_fetcher_.reset(new DataFetcherSharedMemory); | 76 data_fetcher_.reset(new DataFetcherSharedMemory); |
38 data_fetcher_->StartFetchingDeviceMotionData(SharedMemoryAsHardwareBuffer()); | 77 |
39 is_started_ = true; | 78 if (data_fetcher_->NeedsPolling()) { |
79 if (!polling_thread_) | |
80 CreateAndStartPollingThread(); | |
81 | |
82 polling_thread_->message_loop()->PostTask( | |
83 FROM_HERE, | |
84 base::Bind(&PollingThread::StartPolling, | |
85 base::Unretained(polling_thread_.get()), | |
86 data_fetcher_.get(), | |
87 SharedMemoryAsHardwareBuffer())); | |
88 } else { | |
89 data_fetcher_->StartFetchingDeviceMotionData( | |
90 SharedMemoryAsHardwareBuffer()); | |
91 } | |
92 | |
93 is_stopped_or_stopping_ = false; | |
94 } | |
95 | |
96 void DeviceMotionProvider::CreateAndStartPollingThread() { | |
97 polling_thread_.reset( | |
98 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.
| |
99 | |
100 if (!polling_thread_->Start()) { | |
101 LOG(ERROR) << "Failed to start Device Motion data polling thread"; | |
102 return; | |
103 } | |
40 } | 104 } |
41 | 105 |
42 void DeviceMotionProvider::StopFetchingDeviceMotionData() { | 106 void DeviceMotionProvider::StopFetchingDeviceMotionData() { |
43 if (data_fetcher_) | 107 if (is_stopped_or_stopping_) |
108 return; | |
109 | |
110 DCHECK(data_fetcher_); | |
111 | |
112 if (data_fetcher_->NeedsPolling()) { | |
113 DCHECK(polling_thread_); | |
114 polling_thread_->message_loop()->PostTask( | |
115 FROM_HERE, | |
116 base::Bind(&PollingThread::StopPolling, | |
117 base::Unretained(polling_thread_.get()))); | |
118 } else { | |
44 data_fetcher_->StopFetchingDeviceMotionData(); | 119 data_fetcher_->StopFetchingDeviceMotionData(); |
45 is_started_ = false; | 120 } |
121 | |
122 is_stopped_or_stopping_ = true; | |
46 } | 123 } |
47 | 124 |
48 DeviceMotionHardwareBuffer* DeviceMotionProvider:: | 125 DeviceMotionHardwareBuffer* |
49 SharedMemoryAsHardwareBuffer() { | 126 DeviceMotionProvider::SharedMemoryAsHardwareBuffer() { |
50 void* mem = device_motion_shared_memory_.memory(); | 127 void* mem = device_motion_shared_memory_.memory(); |
51 CHECK(mem); | 128 CHECK(mem); |
52 return static_cast<DeviceMotionHardwareBuffer*>(mem); | 129 return static_cast<DeviceMotionHardwareBuffer*>(mem); |
53 } | 130 } |
54 | 131 |
132 // ---- 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.
| |
133 | |
134 DeviceMotionProvider::PollingThread::PollingThread(const char* name) | |
135 : base::Thread(name) { | |
136 } | |
137 | |
138 DeviceMotionProvider::PollingThread::~PollingThread() { | |
139 } | |
140 | |
141 void DeviceMotionProvider::PollingThread::StartPolling( | |
142 DataFetcherSharedMemory* fetcher, DeviceMotionHardwareBuffer* buffer) { | |
143 DCHECK(base::MessageLoop::current() == message_loop()); | |
144 DCHECK(!timer_); | |
145 | |
146 fetcher_ = fetcher; | |
147 fetcher_->StartFetchingDeviceMotionData(buffer); | |
148 timer_.reset(new base::RepeatingTimer<PollingThread>()); | |
149 timer_->Start(FROM_HERE, | |
150 base::TimeDelta::FromMilliseconds(kPeriodInMilliseconds), | |
151 this, &PollingThread::DoPoll); | |
152 } | |
153 | |
154 void DeviceMotionProvider::PollingThread::StopPolling() { | |
155 DCHECK(base::MessageLoop::current() == message_loop()); | |
156 // this will also stop the timer before killing it. | |
157 timer_.reset(); | |
158 fetcher_->StopFetchingDeviceMotionData(); | |
159 } | |
160 | |
161 void DeviceMotionProvider::PollingThread::DoPoll() { | |
162 DCHECK(base::MessageLoop::current() == message_loop()); | |
163 fetcher_->FetchDeviceMotionDataIntoBuffer(); | |
164 } | |
165 | |
55 } // namespace content | 166 } // namespace content |
OLD | NEW |