Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: content/browser/device_sensors/data_fetcher_shared_memory_base.cc

Issue 2646093002: Move //content/browser/device_sensor/ into device/sensors (Closed)
Patch Set: gn format & code rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/device_sensors/data_fetcher_shared_memory_base.h"
6
7 #include <stddef.h>
8 #include <string.h>
9
10 #include "base/bind.h"
11 #include "base/location.h"
12 #include "base/logging.h"
13 #include "base/macros.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/stl_util.h"
16 #include "base/threading/thread.h"
17 #include "base/timer/timer.h"
18 #include "device/sensors/public/cpp/device_light_hardware_buffer.h"
19 #include "device/sensors/public/cpp/device_motion_hardware_buffer.h"
20 #include "device/sensors/public/cpp/device_orientation_hardware_buffer.h"
21
22 namespace content {
23
24 namespace {
25
26 size_t GetConsumerSharedMemoryBufferSize(ConsumerType consumer_type) {
27 switch (consumer_type) {
28 case CONSUMER_TYPE_MOTION:
29 return sizeof(DeviceMotionHardwareBuffer);
30 case CONSUMER_TYPE_ORIENTATION:
31 case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
32 return sizeof(DeviceOrientationHardwareBuffer);
33 case CONSUMER_TYPE_LIGHT:
34 return sizeof(DeviceLightHardwareBuffer);
35 default:
36 NOTREACHED();
37 }
38 return 0;
39 }
40
41 } // namespace
42
43 class DataFetcherSharedMemoryBase::PollingThread : public base::Thread {
44 public:
45 PollingThread(const char* name, DataFetcherSharedMemoryBase* fetcher);
46 ~PollingThread() override;
47
48 void AddConsumer(ConsumerType consumer_type, void* buffer);
49 void RemoveConsumer(ConsumerType consumer_type);
50
51 unsigned GetConsumersBitmask() const { return consumers_bitmask_; }
52 bool IsTimerRunning() const { return timer_ ? timer_->IsRunning() : false; }
53
54 private:
55 void DoPoll();
56
57 unsigned consumers_bitmask_;
58 DataFetcherSharedMemoryBase* fetcher_;
59 std::unique_ptr<base::RepeatingTimer> timer_;
60
61 DISALLOW_COPY_AND_ASSIGN(PollingThread);
62 };
63
64 // --- PollingThread methods
65
66 DataFetcherSharedMemoryBase::PollingThread::PollingThread(
67 const char* name, DataFetcherSharedMemoryBase* fetcher)
68 : base::Thread(name),
69 consumers_bitmask_(0),
70 fetcher_(fetcher) {
71 }
72
73 DataFetcherSharedMemoryBase::PollingThread::~PollingThread() {
74 }
75
76 void DataFetcherSharedMemoryBase::PollingThread::AddConsumer(
77 ConsumerType consumer_type, void* buffer) {
78 DCHECK(fetcher_);
79 if (!fetcher_->Start(consumer_type, buffer))
80 return;
81
82 consumers_bitmask_ |= consumer_type;
83
84 if (!timer_ && fetcher_->GetType() == FETCHER_TYPE_POLLING_CALLBACK) {
85 timer_.reset(new base::RepeatingTimer());
86 timer_->Start(FROM_HERE,
87 fetcher_->GetInterval(),
88 this, &PollingThread::DoPoll);
89 }
90 }
91
92 void DataFetcherSharedMemoryBase::PollingThread::RemoveConsumer(
93 ConsumerType consumer_type) {
94 DCHECK(fetcher_);
95 if (!fetcher_->Stop(consumer_type))
96 return;
97
98 consumers_bitmask_ &= ~consumer_type;
99
100 if (!consumers_bitmask_)
101 timer_.reset(); // will also stop the timer.
102 }
103
104 void DataFetcherSharedMemoryBase::PollingThread::DoPoll() {
105 DCHECK(fetcher_);
106 DCHECK(consumers_bitmask_);
107 fetcher_->Fetch(consumers_bitmask_);
108 }
109
110 // --- end of PollingThread methods
111
112 DataFetcherSharedMemoryBase::DataFetcherSharedMemoryBase()
113 : started_consumers_(0) {
114 }
115
116 DataFetcherSharedMemoryBase::~DataFetcherSharedMemoryBase() {
117 DCHECK_EQ(0u, started_consumers_);
118
119 // make sure polling thread stops asap.
120 if (polling_thread_)
121 polling_thread_->Stop();
122 }
123
124 bool DataFetcherSharedMemoryBase::StartFetchingDeviceData(
125 ConsumerType consumer_type) {
126 if (started_consumers_ & consumer_type)
127 return true;
128
129 void* buffer = GetSharedMemoryBuffer(consumer_type);
130 if (!buffer)
131 return false;
132
133 size_t buffer_size = GetConsumerSharedMemoryBufferSize(consumer_type);
134 // buffer size should be strictly positive because buffer is non-zero.
135 DCHECK(buffer_size > 0);
136 // make sure to clear any potentially stale values in the memory buffer.
137 memset(buffer, 0, buffer_size);
138
139 if (GetType() != FETCHER_TYPE_DEFAULT) {
140 if (!InitAndStartPollingThreadIfNecessary())
141 return false;
142 polling_thread_->task_runner()->PostTask(
143 FROM_HERE, base::Bind(&PollingThread::AddConsumer,
144 base::Unretained(polling_thread_.get()),
145 consumer_type, buffer));
146 } else {
147 if (!Start(consumer_type, buffer))
148 return false;
149 }
150
151 started_consumers_ |= consumer_type;
152
153 return true;
154 }
155
156 bool DataFetcherSharedMemoryBase::StopFetchingDeviceData(
157 ConsumerType consumer_type) {
158 if (!(started_consumers_ & consumer_type))
159 return true;
160
161 if (GetType() != FETCHER_TYPE_DEFAULT) {
162 polling_thread_->task_runner()->PostTask(
163 FROM_HERE,
164 base::Bind(&PollingThread::RemoveConsumer,
165 base::Unretained(polling_thread_.get()), consumer_type));
166 } else {
167 if (!Stop(consumer_type))
168 return false;
169 }
170
171 started_consumers_ ^= consumer_type;
172
173 return true;
174 }
175
176 void DataFetcherSharedMemoryBase::Shutdown() {
177 StopFetchingDeviceData(CONSUMER_TYPE_MOTION);
178 StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION);
179 StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
180 StopFetchingDeviceData(CONSUMER_TYPE_LIGHT);
181 }
182
183 mojo::ScopedSharedBufferHandle
184 DataFetcherSharedMemoryBase::GetSharedMemoryHandle(ConsumerType consumer_type) {
185 auto it = shared_memory_map_.find(consumer_type);
186 DCHECK(it != shared_memory_map_.end());
187 return it->second.first->Clone();
188 }
189
190 bool DataFetcherSharedMemoryBase::InitAndStartPollingThreadIfNecessary() {
191 if (polling_thread_)
192 return true;
193
194 polling_thread_.reset(new PollingThread("Device Sensor poller", this));
195
196 if (!polling_thread_->Start()) {
197 LOG(ERROR) << "Failed to start sensor data polling thread";
198 return false;
199 }
200 return true;
201 }
202
203 void DataFetcherSharedMemoryBase::Fetch(unsigned consumer_bitmask) {
204 NOTIMPLEMENTED();
205 }
206
207 DataFetcherSharedMemoryBase::FetcherType
208 DataFetcherSharedMemoryBase::GetType() const {
209 return FETCHER_TYPE_DEFAULT;
210 }
211
212 base::TimeDelta DataFetcherSharedMemoryBase::GetInterval() const {
213 return base::TimeDelta::FromMicroseconds(kDeviceSensorIntervalMicroseconds);
214 }
215
216 void* DataFetcherSharedMemoryBase::GetSharedMemoryBuffer(
217 ConsumerType consumer_type) {
218 auto it = shared_memory_map_.find(consumer_type);
219 if (it != shared_memory_map_.end())
220 return it->second.second.get();
221
222 size_t buffer_size = GetConsumerSharedMemoryBufferSize(consumer_type);
223 if (buffer_size == 0)
224 return nullptr;
225
226 mojo::ScopedSharedBufferHandle buffer =
227 mojo::SharedBufferHandle::Create(buffer_size);
228 mojo::ScopedSharedBufferMapping mapping = buffer->Map(buffer_size);
229 if (!mapping)
230 return nullptr;
231 void* mem = mapping.get();
232 memset(mem, 0, buffer_size);
233 shared_memory_map_[consumer_type] =
234 std::make_pair(std::move(buffer), std::move(mapping));
235 return mem;
236 }
237
238 base::MessageLoop* DataFetcherSharedMemoryBase::GetPollingMessageLoop() const {
239 return polling_thread_ ? polling_thread_->message_loop() : nullptr;
240 }
241
242 bool DataFetcherSharedMemoryBase::IsPollingTimerRunningForTesting() const {
243 return polling_thread_ ? polling_thread_->IsTimerRunning() : false;
244 }
245
246 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698