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

Side by Side Diff: device/generic_sensor/platform_sensor_provider_linux.cc

Issue 2533793002: [sensors](CrOS/Linux) Implement Sensor device manager for sensors (Closed)
Patch Set: construct manager Created 4 years 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "device/generic_sensor/platform_sensor_provider_linux.h" 5 #include "device/generic_sensor/platform_sensor_provider_linux.h"
6 6
7 #include "base/memory/singleton.h" 7 #include "base/memory/singleton.h"
8 #include "base/task_runner_util.h"
9 #include "base/threading/thread.h" 8 #include "base/threading/thread.h"
10 #include "device/generic_sensor/linux/platform_sensor_utils_linux.h"
11 #include "device/generic_sensor/linux/sensor_data_linux.h" 9 #include "device/generic_sensor/linux/sensor_data_linux.h"
12 #include "device/generic_sensor/platform_sensor_linux.h" 10 #include "device/generic_sensor/platform_sensor_linux.h"
13 11
14 namespace device { 12 namespace device {
15 13
16 // static 14 // static
17 PlatformSensorProviderLinux* PlatformSensorProviderLinux::GetInstance() { 15 PlatformSensorProviderLinux* PlatformSensorProviderLinux::GetInstance() {
18 return base::Singleton< 16 return base::Singleton<
19 PlatformSensorProviderLinux, 17 PlatformSensorProviderLinux,
20 base::LeakySingletonTraits<PlatformSensorProviderLinux>>::get(); 18 base::LeakySingletonTraits<PlatformSensorProviderLinux>>::get();
21 } 19 }
22 20
23 PlatformSensorProviderLinux::PlatformSensorProviderLinux() = default; 21 PlatformSensorProviderLinux::PlatformSensorProviderLinux()
22 : sensor_nodes_enumerated_(false),
23 sensor_nodes_enumeration_started_(false),
24 sensor_device_manager_(nullptr) {}
24 25
25 PlatformSensorProviderLinux::~PlatformSensorProviderLinux() = default; 26 PlatformSensorProviderLinux::~PlatformSensorProviderLinux() {
27 DCHECK(!sensor_device_manager_);
28 }
26 29
27 void PlatformSensorProviderLinux::CreateSensorInternal( 30 void PlatformSensorProviderLinux::CreateSensorInternal(
28 mojom::SensorType type, 31 mojom::SensorType type,
29 mojo::ScopedSharedBufferMapping mapping, 32 mojo::ScopedSharedBufferMapping mapping,
30 const CreateSensorCallback& callback) { 33 const CreateSensorCallback& callback) {
31 SensorDataLinux data; 34 if (!sensor_device_manager_)
32 if (!InitSensorData(type, &data)) { 35 sensor_device_manager_.reset(new SensorDeviceManager());
33 callback.Run(nullptr); 36
37 if (!sensor_nodes_enumerated_) {
38 if (!sensor_nodes_enumeration_started_) {
39 sensor_nodes_enumeration_started_ = file_task_runner_->PostTask(
40 FROM_HERE,
41 base::Bind(&SensorDeviceManager::Start,
42 base::Unretained(sensor_device_manager_.get()), this));
43 }
34 return; 44 return;
35 } 45 }
36 46
37 if (!polling_thread_) 47 SensorInfoLinux* sensor_device = GetSensorDevice(type);
38 polling_thread_.reset(new base::Thread("Sensor polling thread")); 48 if (!sensor_device) {
39
40 if (!polling_thread_->IsRunning()) {
41 if (!polling_thread_->StartWithOptions(
42 base::Thread::Options(base::MessageLoop::TYPE_IO, 0))) {
43 callback.Run(nullptr);
44 return;
45 }
46 polling_thread_task_runner_ = polling_thread_->task_runner();
47 }
48
49 base::PostTaskAndReplyWithResult(
50 polling_thread_task_runner_.get(), FROM_HERE,
51 base::Bind(SensorReader::Create, data),
52 base::Bind(&PlatformSensorProviderLinux::SensorReaderFound,
53 base::Unretained(this), type, base::Passed(&mapping), callback,
54 data));
55 }
56
57 void PlatformSensorProviderLinux::SensorReaderFound(
58 mojom::SensorType type,
59 mojo::ScopedSharedBufferMapping mapping,
60 const PlatformSensorProviderBase::CreateSensorCallback& callback,
61 const SensorDataLinux& data,
62 std::unique_ptr<SensorReader> sensor_reader) {
63 DCHECK(CalledOnValidThread());
64
65 if (!sensor_reader) {
66 // If there are no sensors, stop polling thread. 49 // If there are no sensors, stop polling thread.
67 if (!HasSensors()) 50 if (!HasSensors())
68 AllSensorsRemoved(); 51 AllSensorsRemoved();
69 callback.Run(nullptr); 52 callback.Run(nullptr);
70 return; 53 return;
71 } 54 }
55 SensorDeviceFound(type, std::move(mapping), callback, sensor_device);
56 }
72 57
73 callback.Run(new PlatformSensorLinux(type, std::move(mapping), this, data, 58 void PlatformSensorProviderLinux::SensorDeviceFound(
74 std::move(sensor_reader), 59 mojom::SensorType type,
75 polling_thread_task_runner_)); 60 mojo::ScopedSharedBufferMapping mapping,
61 const PlatformSensorProviderBase::CreateSensorCallback& callback,
62 SensorInfoLinux* sensor_device) {
63 DCHECK(CalledOnValidThread());
64
65 if (!StartPollingThread()) {
66 callback.Run(nullptr);
67 return;
68 }
69
70 scoped_refptr<PlatformSensorLinux> sensor =
71 new PlatformSensorLinux(type, std::move(mapping), this, sensor_device,
72 polling_thread_->task_runner());
73 callback.Run(sensor);
76 } 74 }
77 75
78 void PlatformSensorProviderLinux::SetFileTaskRunner( 76 void PlatformSensorProviderLinux::SetFileTaskRunner(
79 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) { 77 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) {
80 DCHECK(CalledOnValidThread()); 78 DCHECK(CalledOnValidThread());
81 if (!file_task_runner_) 79 if (!file_task_runner_)
82 file_task_runner_ = file_task_runner; 80 file_task_runner_ = file_task_runner;
83 } 81 }
84 82
85 void PlatformSensorProviderLinux::AllSensorsRemoved() { 83 void PlatformSensorProviderLinux::AllSensorsRemoved() {
86 DCHECK(CalledOnValidThread()); 84 DCHECK(CalledOnValidThread());
87 DCHECK(file_task_runner_); 85 DCHECK(file_task_runner_);
86 Shutdown();
88 // When there are no sensors left, the polling thread must be stopped. 87 // When there are no sensors left, the polling thread must be stopped.
89 // Stop() can only be called on a different thread that allows io. 88 // Stop() can only be called on a different thread that allows I/O.
90 // Thus, browser's file thread is used for this purpose. 89 // Thus, browser's file thread is used for this purpose.
91 file_task_runner_->PostTask( 90 file_task_runner_->PostTask(
92 FROM_HERE, base::Bind(&PlatformSensorProviderLinux::StopPollingThread, 91 FROM_HERE, base::Bind(&PlatformSensorProviderLinux::StopPollingThread,
93 base::Unretained(this))); 92 base::Unretained(this)));
94 } 93 }
95 94
95 bool PlatformSensorProviderLinux::StartPollingThread() {
96 if (!polling_thread_)
97 polling_thread_.reset(new base::Thread("Sensor polling thread"));
98
99 if (!polling_thread_->IsRunning()) {
100 return polling_thread_->StartWithOptions(
101 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
102 }
103 return true;
104 }
105
96 void PlatformSensorProviderLinux::StopPollingThread() { 106 void PlatformSensorProviderLinux::StopPollingThread() {
97 DCHECK(file_task_runner_); 107 DCHECK(file_task_runner_);
98 DCHECK(file_task_runner_->BelongsToCurrentThread()); 108 DCHECK(file_task_runner_->BelongsToCurrentThread());
99 polling_thread_->Stop(); 109 if (polling_thread_ && polling_thread_->IsRunning())
110 polling_thread_->Stop();
111 }
112
113 void PlatformSensorProviderLinux::Shutdown() {
114 DCHECK(CalledOnValidThread());
115 const bool did_post_task = file_task_runner_->DeleteSoon(
116 FROM_HERE, sensor_device_manager_.release());
117 DCHECK(did_post_task);
118 sensor_nodes_enumerated_ = false;
119 sensor_nodes_enumeration_started_ = false;
120 sensor_devices_by_type_.clear();
121 }
122
123 SensorInfoLinux* PlatformSensorProviderLinux::GetSensorDevice(
124 mojom::SensorType type) {
125 DCHECK(CalledOnValidThread());
126 auto sensor = sensor_devices_by_type_.find(type);
127 if (sensor == sensor_devices_by_type_.end())
128 return nullptr;
129 return sensor->second.get();
130 }
131
132 void PlatformSensorProviderLinux::GetAllSensorDevices() {
133 DCHECK(CalledOnValidThread());
134 // TODO(maksims): implement this method once we have discovery API.
135 NOTIMPLEMENTED();
136 }
137
138 void PlatformSensorProviderLinux::SetSensorDeviceManagerForTesting(
139 std::unique_ptr<SensorDeviceManager> sensor_device_manager) {
140 DCHECK(CalledOnValidThread());
141 Shutdown();
142 sensor_device_manager_ = std::move(sensor_device_manager);
143 }
144
145 void PlatformSensorProviderLinux::SetFileTaskRunnerForTesting(
146 scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
147 DCHECK(CalledOnValidThread());
148 file_task_runner_ = std::move(task_runner);
149 }
150
151 void PlatformSensorProviderLinux::ProcessStoredRequests() {
152 DCHECK(CalledOnValidThread());
153 std::vector<mojom::SensorType> request_types = GetPendingRequestTypes();
154 if (request_types.empty())
155 return;
156
157 for (auto const& type : request_types) {
158 SensorInfoLinux* device = nullptr;
159 auto device_entry = sensor_devices_by_type_.find(type);
160 if (device_entry != sensor_devices_by_type_.end())
161 device = device_entry->second.get();
162 CreateSensorAndNotify(type, device);
163 }
164 }
165
166 void PlatformSensorProviderLinux::CreateSensorAndNotify(
167 mojom::SensorType type,
168 SensorInfoLinux* sensor_device) {
169 DCHECK(CalledOnValidThread());
170 scoped_refptr<PlatformSensorLinux> sensor;
171 mojo::ScopedSharedBufferMapping mapping = MapSharedBufferForType(type);
172 if (sensor_device && mapping && StartPollingThread()) {
173 sensor =
174 new PlatformSensorLinux(type, std::move(mapping), this, sensor_device,
175 polling_thread_->task_runner());
176 }
177 NotifySensorCreated(type, sensor);
178 }
179
180 void PlatformSensorProviderLinux::OnSensorNodesEnumerated() {
181 DCHECK(CalledOnValidThread());
182 DCHECK(!sensor_nodes_enumerated_);
183 sensor_nodes_enumerated_ = true;
184 ProcessStoredRequests();
185 }
186
187 void PlatformSensorProviderLinux::OnDeviceAdded(
188 mojom::SensorType type,
189 std::unique_ptr<SensorInfoLinux> sensor_device) {
190 DCHECK(CalledOnValidThread());
191 // At the moment, we support only one device per type.
192 if (base::ContainsKey(sensor_devices_by_type_, type)) {
193 DVLOG(1) << "Sensor ignored. Type " << type
194 << ". Node: " << sensor_device->device_node;
195 return;
196 }
197 sensor_devices_by_type_[type] = std::move(sensor_device);
198 }
199
200 void PlatformSensorProviderLinux::OnDeviceRemoved(
201 mojom::SensorType type,
202 const std::string& device_node) {
203 DCHECK(CalledOnValidThread());
204 auto it = sensor_devices_by_type_.find(type);
205 if (it == sensor_devices_by_type_.end() &&
Reilly Grant (use Gerrit) 2016/12/09 18:54:19 it != sensor_devices_by_type_.end()
206 it->second->device_node == device_node)
207 sensor_devices_by_type_.erase(it);
100 } 208 }
101 209
102 } // namespace device 210 } // namespace device
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698