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

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

Powered by Google App Engine
This is Rietveld 408576698