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

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: nits 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 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 (!InitializeSenorDeviceManager()) {
32 if (!InitSensorData(type, &data)) {
33 callback.Run(nullptr); 35 callback.Run(nullptr);
34 return; 36 return;
35 } 37 }
36 38
37 if (!polling_thread_) 39 if (!sensor_nodes_enumerated_)
38 polling_thread_.reset(new base::Thread("Sensor polling thread")); 40 return;
39 41
Mikhail 2016/12/09 11:17:29 if (!sensor_nodes_enumerated_) { if (!sensor_nod
maksims (do not use this acc) 2016/12/09 13:03:07 Done.
40 if (!polling_thread_->IsRunning()) { 42 SensorInfoLinux* sensor_device = GetSensorDevice(type);
41 if (!polling_thread_->StartWithOptions( 43 if (!sensor_device) {
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. 44 // If there are no sensors, stop polling thread.
67 if (!HasSensors()) 45 if (!HasSensors())
68 AllSensorsRemoved(); 46 AllSensorsRemoved();
69 callback.Run(nullptr); 47 callback.Run(nullptr);
70 return; 48 return;
71 } 49 }
50 SensorDeviceFound(type, std::move(mapping), callback, sensor_device);
51 }
72 52
73 callback.Run(new PlatformSensorLinux(type, std::move(mapping), this, data, 53 void PlatformSensorProviderLinux::SensorDeviceFound(
74 std::move(sensor_reader), 54 mojom::SensorType type,
75 polling_thread_task_runner_)); 55 mojo::ScopedSharedBufferMapping mapping,
56 const PlatformSensorProviderBase::CreateSensorCallback& callback,
57 SensorInfoLinux* sensor_device) {
58 DCHECK(CalledOnValidThread());
59
60 if (!StartPollingThread()) {
61 callback.Run(nullptr);
62 return;
63 }
64
65 scoped_refptr<PlatformSensorLinux> sensor =
66 new PlatformSensorLinux(type, std::move(mapping), this, sensor_device,
67 polling_thread_->task_runner());
68 callback.Run(sensor);
76 } 69 }
77 70
78 void PlatformSensorProviderLinux::SetFileTaskRunner( 71 void PlatformSensorProviderLinux::SetFileTaskRunner(
79 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) { 72 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) {
80 DCHECK(CalledOnValidThread()); 73 DCHECK(CalledOnValidThread());
81 if (!file_task_runner_) 74 if (!file_task_runner_)
82 file_task_runner_ = file_task_runner; 75 file_task_runner_ = file_task_runner;
83 } 76 }
84 77
85 void PlatformSensorProviderLinux::AllSensorsRemoved() { 78 void PlatformSensorProviderLinux::AllSensorsRemoved() {
86 DCHECK(CalledOnValidThread()); 79 DCHECK(CalledOnValidThread());
87 DCHECK(file_task_runner_); 80 DCHECK(file_task_runner_);
81 Shutdown();
88 // When there are no sensors left, the polling thread must be stopped. 82 // 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. 83 // Stop() can only be called on a different thread that allows I/O.
90 // Thus, browser's file thread is used for this purpose. 84 // Thus, browser's file thread is used for this purpose.
91 file_task_runner_->PostTask( 85 file_task_runner_->PostTask(
92 FROM_HERE, base::Bind(&PlatformSensorProviderLinux::StopPollingThread, 86 FROM_HERE, base::Bind(&PlatformSensorProviderLinux::StopPollingThread,
93 base::Unretained(this))); 87 base::Unretained(this)));
94 } 88 }
95 89
90 bool PlatformSensorProviderLinux::StartPollingThread() {
91 if (!polling_thread_)
92 polling_thread_.reset(new base::Thread("Sensor polling thread"));
93
94 if (!polling_thread_->IsRunning()) {
95 return polling_thread_->StartWithOptions(
96 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
97 }
98 return true;
99 }
100
96 void PlatformSensorProviderLinux::StopPollingThread() { 101 void PlatformSensorProviderLinux::StopPollingThread() {
97 DCHECK(file_task_runner_); 102 DCHECK(file_task_runner_);
98 DCHECK(file_task_runner_->BelongsToCurrentThread()); 103 DCHECK(file_task_runner_->BelongsToCurrentThread());
99 polling_thread_->Stop(); 104 if (polling_thread_ && polling_thread_->IsRunning())
105 polling_thread_->Stop();
106 }
107
108 bool PlatformSensorProviderLinux::InitializeSenorDeviceManager() {
Mikhail 2016/12/09 11:17:29 we can drop this method (pls see comment above)
maksims (do not use this acc) 2016/12/09 13:03:07 Done.
109 if (!sensor_device_manager_)
110 sensor_device_manager_.reset(new SensorDeviceManager());
111
112 if (!enumeration_started_) {
113 enumeration_started_ = file_task_runner_->PostTask(
114 FROM_HERE,
115 base::Bind(&SensorDeviceManager::Start,
116 base::Unretained(sensor_device_manager_.get()), this));
117 }
118 return enumeration_started_;
Mikhail 2016/12/09 11:17:29 sensor_nodes_enumeration_started_
maksims (do not use this acc) 2016/12/09 13:03:07 Done.
119 }
120
121 void PlatformSensorProviderLinux::Shutdown() {
122 DCHECK(CalledOnValidThread());
123 const bool did_post_task = file_task_runner_->DeleteSoon(
124 FROM_HERE, sensor_device_manager_.release());
125 DCHECK(did_post_task);
126 sensor_nodes_enumerated_ = false;
127 enumeration_started_ = false;
128 sensor_devices_by_type_.clear();
129 }
130
131 SensorInfoLinux* PlatformSensorProviderLinux::GetSensorDevice(
132 mojom::SensorType type) {
133 DCHECK(CalledOnValidThread());
134 auto sensor = sensor_devices_by_type_.find(type);
135 if (sensor == sensor_devices_by_type_.end())
136 return nullptr;
137 return sensor->second.get();
138 }
139
140 void PlatformSensorProviderLinux::GetAllSensorDevices() {
141 DCHECK(CalledOnValidThread());
142 // TODO(maksims): implement this method once we have discovery API.
143 NOTIMPLEMENTED();
144 }
145
146 void PlatformSensorProviderLinux::SetSensorDeviceManagerForTesting(
147 std::unique_ptr<SensorDeviceManager> sensor_device_manager) {
148 DCHECK(CalledOnValidThread());
149 Shutdown();
150 sensor_device_manager_ = std::move(sensor_device_manager);
151 }
152
153 void PlatformSensorProviderLinux::SetFileTaskRunnerForTesting(
154 scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
155 DCHECK(CalledOnValidThread());
156 file_task_runner_ = std::move(task_runner);
157 }
158
159 void PlatformSensorProviderLinux::ProcessStoredRequests() {
160 DCHECK(CalledOnValidThread());
161 std::vector<mojom::SensorType> request_types = GetPendingRequestTypes();
162 if (request_types.empty())
163 return;
164
165 for (auto const& type : request_types) {
166 SensorInfoLinux* device = nullptr;
167 auto device_entry = sensor_devices_by_type_.find(type);
168 if (device_entry != sensor_devices_by_type_.end())
169 device = device_entry->second.get();
170 CreateSensorAndNotify(type, device);
171 }
172 }
173
174 void PlatformSensorProviderLinux::CreateSensorAndNotify(
175 mojom::SensorType type,
176 SensorInfoLinux* sensor_device) {
177 DCHECK(CalledOnValidThread());
178 scoped_refptr<PlatformSensorLinux> sensor;
179 mojo::ScopedSharedBufferMapping mapping = MapSharedBufferForType(type);
180 if (sensor_device && mapping && StartPollingThread()) {
181 sensor =
182 new PlatformSensorLinux(type, std::move(mapping), this, sensor_device,
183 polling_thread_->task_runner());
184 }
185 NotifySensorCreated(type, sensor);
186 }
187
188 void PlatformSensorProviderLinux::OnSensorNodesEnumerated() {
189 DCHECK(CalledOnValidThread());
190 DCHECK(!sensor_nodes_enumerated_);
191 sensor_nodes_enumerated_ = true;
192 ProcessStoredRequests();
193 }
194
195 void PlatformSensorProviderLinux::OnDeviceAdded(
196 mojom::SensorType type,
197 std::unique_ptr<SensorInfoLinux> sensor_device) {
198 DCHECK(CalledOnValidThread());
199 // At the moment, we support only one device per type.
200 if (base::ContainsKey(sensor_devices_by_type_, type)) {
201 DVLOG(1) << "Sensor ignored. Type " << type
202 << ". Node: " << sensor_device->device_node;
203 return;
204 }
205 sensor_devices_by_type_[type] = std::move(sensor_device);
206 }
207
208 void PlatformSensorProviderLinux::OnDeviceRemoved(
209 mojom::SensorType type,
210 const std::string& device_node) {
211 DCHECK(CalledOnValidThread());
212 auto it = sensor_devices_by_type_.find(type);
213 if (it == sensor_devices_by_type_.end() &&
214 it->second->device_node == device_node)
215 sensor_devices_by_type_.erase(it);
100 } 216 }
101 217
102 } // namespace device 218 } // namespace device
OLDNEW
« no previous file with comments | « device/generic_sensor/platform_sensor_provider_linux.h ('k') | device/generic_sensor/platform_sensor_reader_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698