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

Side by Side Diff: device/sensors/data_fetcher_shared_memory_base.cc

Issue 2885203004: Refactor content/renderer/device_sensors to use device/generic_sensor instead of device/sensors (Closed)
Patch Set: updated content/renderer/BUILD.gn Created 3 years, 7 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 "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_motion_hardware_buffer.h"
19 #include "device/sensors/public/cpp/device_orientation_hardware_buffer.h"
20
21 namespace device {
22
23 namespace {
24
25 size_t GetConsumerSharedMemoryBufferSize(ConsumerType consumer_type) {
26 switch (consumer_type) {
27 case CONSUMER_TYPE_MOTION:
28 return sizeof(DeviceMotionHardwareBuffer);
29 case CONSUMER_TYPE_ORIENTATION:
30 case CONSUMER_TYPE_ORIENTATION_ABSOLUTE:
31 return sizeof(DeviceOrientationHardwareBuffer);
32 default:
33 NOTREACHED();
34 }
35 return 0;
36 }
37
38 } // namespace
39
40 class DataFetcherSharedMemoryBase::PollingThread : public base::Thread {
41 public:
42 PollingThread(const char* name, DataFetcherSharedMemoryBase* fetcher);
43 ~PollingThread() override;
44
45 void AddConsumer(ConsumerType consumer_type, void* buffer);
46 void RemoveConsumer(ConsumerType consumer_type);
47
48 unsigned GetConsumersBitmask() const { return consumers_bitmask_; }
49 bool IsTimerRunning() const { return timer_ ? timer_->IsRunning() : false; }
50
51 private:
52 void DoPoll();
53
54 unsigned consumers_bitmask_;
55 DataFetcherSharedMemoryBase* fetcher_;
56 std::unique_ptr<base::RepeatingTimer> timer_;
57
58 DISALLOW_COPY_AND_ASSIGN(PollingThread);
59 };
60
61 // --- PollingThread methods
62
63 DataFetcherSharedMemoryBase::PollingThread::PollingThread(
64 const char* name,
65 DataFetcherSharedMemoryBase* fetcher)
66 : base::Thread(name), consumers_bitmask_(0), fetcher_(fetcher) {}
67
68 DataFetcherSharedMemoryBase::PollingThread::~PollingThread() {}
69
70 void DataFetcherSharedMemoryBase::PollingThread::AddConsumer(
71 ConsumerType consumer_type,
72 void* buffer) {
73 DCHECK(fetcher_);
74 if (!fetcher_->Start(consumer_type, buffer))
75 return;
76
77 consumers_bitmask_ |= consumer_type;
78
79 if (!timer_ && fetcher_->GetType() == FETCHER_TYPE_POLLING_CALLBACK) {
80 timer_.reset(new base::RepeatingTimer());
81 timer_->Start(FROM_HERE, fetcher_->GetInterval(), this,
82 &PollingThread::DoPoll);
83 }
84 }
85
86 void DataFetcherSharedMemoryBase::PollingThread::RemoveConsumer(
87 ConsumerType consumer_type) {
88 DCHECK(fetcher_);
89 if (!fetcher_->Stop(consumer_type))
90 return;
91
92 consumers_bitmask_ &= ~consumer_type;
93
94 if (!consumers_bitmask_)
95 timer_.reset(); // will also stop the timer.
96 }
97
98 void DataFetcherSharedMemoryBase::PollingThread::DoPoll() {
99 DCHECK(fetcher_);
100 DCHECK(consumers_bitmask_);
101 fetcher_->Fetch(consumers_bitmask_);
102 }
103
104 // --- end of PollingThread methods
105
106 DataFetcherSharedMemoryBase::DataFetcherSharedMemoryBase()
107 : started_consumers_(0) {}
108
109 DataFetcherSharedMemoryBase::~DataFetcherSharedMemoryBase() {
110 DCHECK_EQ(0u, started_consumers_);
111
112 // By this point the polling thread should have already been stopped (it's not
113 // safe for it to be running in this class's destructor as tasks are posted to
114 // it that call virtual methods of this class).
115 DCHECK(!polling_thread_ || !polling_thread_->IsRunning());
116 }
117
118 bool DataFetcherSharedMemoryBase::StartFetchingDeviceData(
119 ConsumerType consumer_type) {
120 if (started_consumers_ & consumer_type)
121 return true;
122
123 void* buffer = GetSharedMemoryBuffer(consumer_type);
124 if (!buffer)
125 return false;
126
127 size_t buffer_size = GetConsumerSharedMemoryBufferSize(consumer_type);
128 // buffer size should be strictly positive because buffer is non-zero.
129 DCHECK(buffer_size > 0);
130 // make sure to clear any potentially stale values in the memory buffer.
131 memset(buffer, 0, buffer_size);
132
133 if (GetType() != FETCHER_TYPE_DEFAULT) {
134 if (!InitAndStartPollingThreadIfNecessary())
135 return false;
136 polling_thread_->task_runner()->PostTask(
137 FROM_HERE, base::Bind(&PollingThread::AddConsumer,
138 base::Unretained(polling_thread_.get()),
139 consumer_type, buffer));
140 } else {
141 if (!Start(consumer_type, buffer))
142 return false;
143 }
144
145 started_consumers_ |= consumer_type;
146
147 return true;
148 }
149
150 bool DataFetcherSharedMemoryBase::StopFetchingDeviceData(
151 ConsumerType consumer_type) {
152 if (!(started_consumers_ & consumer_type))
153 return true;
154
155 if (GetType() != FETCHER_TYPE_DEFAULT) {
156 polling_thread_->task_runner()->PostTask(
157 FROM_HERE,
158 base::Bind(&PollingThread::RemoveConsumer,
159 base::Unretained(polling_thread_.get()), consumer_type));
160 } else {
161 if (!Stop(consumer_type))
162 return false;
163 }
164
165 started_consumers_ ^= consumer_type;
166
167 return true;
168 }
169
170 void DataFetcherSharedMemoryBase::Shutdown() {
171 StopFetchingDeviceData(CONSUMER_TYPE_MOTION);
172 StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION);
173 StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION_ABSOLUTE);
174
175 // Ensure that the polling thread stops before entering the destructor of the
176 // subclass, as the stopping of the polling thread causes tasks to execute
177 // that call virtual methods of this class, which can cause crashes if they
178 // execute while (or after) the subclass is being torn down.
179 if (polling_thread_)
180 polling_thread_->Stop();
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 DataFetcherSharedMemoryBase::GetType()
208 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 device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698