Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / content / browser / device_sensors / data_fetcher_shared_memory_base.cc
blobf2b2d40c6431a251c34b5015dc01f3b5def37211
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.
5 #include "content/browser/device_sensors/data_fetcher_shared_memory_base.h"
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/stl_util.h"
10 #include "base/threading/thread.h"
11 #include "base/timer/timer.h"
12 #include "content/common/device_sensors/device_light_hardware_buffer.h"
13 #include "content/common/device_sensors/device_motion_hardware_buffer.h"
14 #include "content/common/device_sensors/device_orientation_hardware_buffer.h"
16 namespace content {
18 namespace {
20 size_t GetConsumerSharedMemoryBufferSize(ConsumerType consumer_type) {
21 switch (consumer_type) {
22 case CONSUMER_TYPE_MOTION:
23 return sizeof(DeviceMotionHardwareBuffer);
24 case CONSUMER_TYPE_ORIENTATION:
25 return sizeof(DeviceOrientationHardwareBuffer);
26 case CONSUMER_TYPE_LIGHT:
27 return sizeof(DeviceLightHardwareBuffer);
28 default:
29 NOTREACHED();
31 return 0;
34 } // namespace
36 class DataFetcherSharedMemoryBase::PollingThread : public base::Thread {
37 public:
38 PollingThread(const char* name, DataFetcherSharedMemoryBase* fetcher);
39 ~PollingThread() override;
41 void AddConsumer(ConsumerType consumer_type, void* buffer);
42 void RemoveConsumer(ConsumerType consumer_type);
44 unsigned GetConsumersBitmask() const { return consumers_bitmask_; }
45 bool IsTimerRunning() const { return timer_ ? timer_->IsRunning() : false; }
47 private:
48 void DoPoll();
50 unsigned consumers_bitmask_;
51 DataFetcherSharedMemoryBase* fetcher_;
52 scoped_ptr<base::RepeatingTimer<PollingThread> > timer_;
54 DISALLOW_COPY_AND_ASSIGN(PollingThread);
57 // --- PollingThread methods
59 DataFetcherSharedMemoryBase::PollingThread::PollingThread(
60 const char* name, DataFetcherSharedMemoryBase* fetcher)
61 : base::Thread(name),
62 consumers_bitmask_(0),
63 fetcher_(fetcher) {
66 DataFetcherSharedMemoryBase::PollingThread::~PollingThread() {
69 void DataFetcherSharedMemoryBase::PollingThread::AddConsumer(
70 ConsumerType consumer_type, void* buffer) {
71 DCHECK(fetcher_);
72 if (!fetcher_->Start(consumer_type, buffer))
73 return;
75 consumers_bitmask_ |= consumer_type;
77 if (!timer_ && fetcher_->GetType() == FETCHER_TYPE_POLLING_CALLBACK) {
78 timer_.reset(new base::RepeatingTimer<PollingThread>());
79 timer_->Start(FROM_HERE,
80 fetcher_->GetInterval(),
81 this, &PollingThread::DoPoll);
85 void DataFetcherSharedMemoryBase::PollingThread::RemoveConsumer(
86 ConsumerType consumer_type) {
87 DCHECK(fetcher_);
88 if (!fetcher_->Stop(consumer_type))
89 return;
91 consumers_bitmask_ ^= consumer_type;
93 if (!consumers_bitmask_)
94 timer_.reset(); // will also stop the timer.
97 void DataFetcherSharedMemoryBase::PollingThread::DoPoll() {
98 DCHECK(fetcher_);
99 DCHECK(consumers_bitmask_);
100 fetcher_->Fetch(consumers_bitmask_);
103 // --- end of PollingThread methods
105 DataFetcherSharedMemoryBase::DataFetcherSharedMemoryBase()
106 : started_consumers_(0) {
109 DataFetcherSharedMemoryBase::~DataFetcherSharedMemoryBase() {
110 DCHECK_EQ(0u, started_consumers_);
112 // make sure polling thread stops asap.
113 if (polling_thread_)
114 polling_thread_->Stop();
116 STLDeleteContainerPairSecondPointers(shared_memory_map_.begin(),
117 shared_memory_map_.end());
120 bool DataFetcherSharedMemoryBase::StartFetchingDeviceData(
121 ConsumerType consumer_type) {
122 if (started_consumers_ & consumer_type)
123 return true;
125 void* buffer = GetSharedMemoryBuffer(consumer_type);
126 if (!buffer)
127 return false;
129 if (GetType() != FETCHER_TYPE_DEFAULT) {
130 if (!InitAndStartPollingThreadIfNecessary())
131 return false;
132 polling_thread_->message_loop()->PostTask(
133 FROM_HERE,
134 base::Bind(&PollingThread::AddConsumer,
135 base::Unretained(polling_thread_.get()),
136 consumer_type, buffer));
137 } else {
138 if (!Start(consumer_type, buffer))
139 return false;
142 started_consumers_ |= consumer_type;
144 return true;
147 bool DataFetcherSharedMemoryBase::StopFetchingDeviceData(
148 ConsumerType consumer_type) {
149 if (!(started_consumers_ & consumer_type))
150 return true;
152 if (GetType() != FETCHER_TYPE_DEFAULT) {
153 polling_thread_->message_loop()->PostTask(
154 FROM_HERE,
155 base::Bind(&PollingThread::RemoveConsumer,
156 base::Unretained(polling_thread_.get()),
157 consumer_type));
158 } else {
159 if (!Stop(consumer_type))
160 return false;
163 started_consumers_ ^= consumer_type;
165 return true;
168 void DataFetcherSharedMemoryBase::Shutdown() {
169 StopFetchingDeviceData(CONSUMER_TYPE_MOTION);
170 StopFetchingDeviceData(CONSUMER_TYPE_ORIENTATION);
171 StopFetchingDeviceData(CONSUMER_TYPE_LIGHT);
174 base::SharedMemoryHandle
175 DataFetcherSharedMemoryBase::GetSharedMemoryHandleForProcess(
176 ConsumerType consumer_type, base::ProcessHandle process) {
177 SharedMemoryMap::const_iterator it = shared_memory_map_.find(consumer_type);
178 if (it == shared_memory_map_.end())
179 return base::SharedMemory::NULLHandle();
181 base::SharedMemoryHandle renderer_handle;
182 it->second->ShareToProcess(process, &renderer_handle);
183 return renderer_handle;
186 bool DataFetcherSharedMemoryBase::InitAndStartPollingThreadIfNecessary() {
187 if (polling_thread_)
188 return true;
190 polling_thread_.reset(
191 new PollingThread("Inertial Device Sensor poller", this));
193 if (!polling_thread_->Start()) {
194 LOG(ERROR) << "Failed to start inertial sensor data polling thread";
195 return false;
197 return true;
200 void DataFetcherSharedMemoryBase::Fetch(unsigned consumer_bitmask) {
201 NOTIMPLEMENTED();
204 DataFetcherSharedMemoryBase::FetcherType
205 DataFetcherSharedMemoryBase::GetType() const {
206 return FETCHER_TYPE_DEFAULT;
209 base::TimeDelta DataFetcherSharedMemoryBase::GetInterval() const {
210 return base::TimeDelta::FromMicroseconds(kInertialSensorIntervalMicroseconds);
213 base::SharedMemory* DataFetcherSharedMemoryBase::GetSharedMemory(
214 ConsumerType consumer_type) {
215 SharedMemoryMap::const_iterator it = shared_memory_map_.find(consumer_type);
216 if (it != shared_memory_map_.end())
217 return it->second;
219 size_t buffer_size = GetConsumerSharedMemoryBufferSize(consumer_type);
220 if (buffer_size == 0)
221 return nullptr;
223 scoped_ptr<base::SharedMemory> new_shared_mem(new base::SharedMemory);
224 if (new_shared_mem->CreateAndMapAnonymous(buffer_size)) {
225 if (void* mem = new_shared_mem->memory()) {
226 memset(mem, 0, buffer_size);
227 base::SharedMemory* shared_mem = new_shared_mem.release();
228 shared_memory_map_[consumer_type] = shared_mem;
229 return shared_mem;
232 LOG(ERROR) << "Failed to initialize shared memory";
233 return nullptr;
236 void* DataFetcherSharedMemoryBase::GetSharedMemoryBuffer(
237 ConsumerType consumer_type) {
238 if (base::SharedMemory* shared_memory = GetSharedMemory(consumer_type))
239 return shared_memory->memory();
240 return nullptr;
243 base::MessageLoop* DataFetcherSharedMemoryBase::GetPollingMessageLoop() const {
244 return polling_thread_ ? polling_thread_->message_loop() : nullptr;
247 bool DataFetcherSharedMemoryBase::IsPollingTimerRunningForTesting() const {
248 return polling_thread_ ? polling_thread_->IsTimerRunning() : false;
251 } // namespace content