OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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/hid/hid_service_linux.h" | 5 #include "device/hid/hid_service_linux.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 |
9 #include <limits> | 10 #include <limits> |
| 11 #include <memory> |
10 #include <string> | 12 #include <string> |
11 #include <utility> | 13 #include <utility> |
12 | 14 |
13 #include "base/bind.h" | 15 #include "base/bind.h" |
14 #include "base/files/file.h" | 16 #include "base/files/file.h" |
15 #include "base/files/file_path.h" | 17 #include "base/files/file_path.h" |
16 #include "base/files/file_util.h" | 18 #include "base/files/file_util.h" |
17 #include "base/location.h" | 19 #include "base/location.h" |
18 #include "base/macros.h" | 20 #include "base/macros.h" |
19 #include "base/scoped_observer.h" | 21 #include "base/scoped_observer.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 public: | 72 public: |
71 FileThreadHelper(base::WeakPtr<HidServiceLinux> service, | 73 FileThreadHelper(base::WeakPtr<HidServiceLinux> service, |
72 scoped_refptr<base::SingleThreadTaskRunner> task_runner) | 74 scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
73 : observer_(this), service_(service), task_runner_(task_runner) {} | 75 : observer_(this), service_(service), task_runner_(task_runner) {} |
74 | 76 |
75 ~FileThreadHelper() override { | 77 ~FileThreadHelper() override { |
76 DCHECK(thread_checker_.CalledOnValidThread()); | 78 DCHECK(thread_checker_.CalledOnValidThread()); |
77 base::MessageLoop::current()->RemoveDestructionObserver(this); | 79 base::MessageLoop::current()->RemoveDestructionObserver(this); |
78 } | 80 } |
79 | 81 |
80 static void Start(scoped_ptr<FileThreadHelper> self) { | 82 static void Start(std::unique_ptr<FileThreadHelper> self) { |
81 base::ThreadRestrictions::AssertIOAllowed(); | 83 base::ThreadRestrictions::AssertIOAllowed(); |
82 self->thread_checker_.DetachFromThread(); | 84 self->thread_checker_.DetachFromThread(); |
83 // |self| must be added as a destruction observer first so that it will be | 85 // |self| must be added as a destruction observer first so that it will be |
84 // notified before DeviceMonitorLinux. | 86 // notified before DeviceMonitorLinux. |
85 base::MessageLoop::current()->AddDestructionObserver(self.get()); | 87 base::MessageLoop::current()->AddDestructionObserver(self.get()); |
86 | 88 |
87 DeviceMonitorLinux* monitor = DeviceMonitorLinux::GetInstance(); | 89 DeviceMonitorLinux* monitor = DeviceMonitorLinux::GetInstance(); |
88 self->observer_.Add(monitor); | 90 self->observer_.Add(monitor); |
89 monitor->Enumerate(base::Bind(&FileThreadHelper::OnDeviceAdded, | 91 monitor->Enumerate(base::Bind(&FileThreadHelper::OnDeviceAdded, |
90 base::Unretained(self.get()))); | 92 base::Unretained(self.get()))); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 base::WeakPtr<HidServiceLinux> service_; | 206 base::WeakPtr<HidServiceLinux> service_; |
205 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 207 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
206 | 208 |
207 DISALLOW_COPY_AND_ASSIGN(FileThreadHelper); | 209 DISALLOW_COPY_AND_ASSIGN(FileThreadHelper); |
208 }; | 210 }; |
209 | 211 |
210 HidServiceLinux::HidServiceLinux( | 212 HidServiceLinux::HidServiceLinux( |
211 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) | 213 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) |
212 : file_task_runner_(file_task_runner), weak_factory_(this) { | 214 : file_task_runner_(file_task_runner), weak_factory_(this) { |
213 task_runner_ = base::ThreadTaskRunnerHandle::Get(); | 215 task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
214 scoped_ptr<FileThreadHelper> helper( | 216 std::unique_ptr<FileThreadHelper> helper( |
215 new FileThreadHelper(weak_factory_.GetWeakPtr(), task_runner_)); | 217 new FileThreadHelper(weak_factory_.GetWeakPtr(), task_runner_)); |
216 helper_ = helper.get(); | 218 helper_ = helper.get(); |
217 file_task_runner_->PostTask( | 219 file_task_runner_->PostTask( |
218 FROM_HERE, base::Bind(&FileThreadHelper::Start, base::Passed(&helper))); | 220 FROM_HERE, base::Bind(&FileThreadHelper::Start, base::Passed(&helper))); |
219 } | 221 } |
220 | 222 |
221 HidServiceLinux::~HidServiceLinux() { | 223 HidServiceLinux::~HidServiceLinux() { |
222 file_task_runner_->DeleteSoon(FROM_HERE, helper_); | 224 file_task_runner_->DeleteSoon(FROM_HERE, helper_); |
223 } | 225 } |
224 | 226 |
225 void HidServiceLinux::Connect(const HidDeviceId& device_id, | 227 void HidServiceLinux::Connect(const HidDeviceId& device_id, |
226 const ConnectCallback& callback) { | 228 const ConnectCallback& callback) { |
227 DCHECK(thread_checker_.CalledOnValidThread()); | 229 DCHECK(thread_checker_.CalledOnValidThread()); |
228 | 230 |
229 const auto& map_entry = devices().find(device_id); | 231 const auto& map_entry = devices().find(device_id); |
230 if (map_entry == devices().end()) { | 232 if (map_entry == devices().end()) { |
231 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); | 233 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr)); |
232 return; | 234 return; |
233 } | 235 } |
234 scoped_refptr<HidDeviceInfoLinux> device_info = | 236 scoped_refptr<HidDeviceInfoLinux> device_info = |
235 static_cast<HidDeviceInfoLinux*>(map_entry->second.get()); | 237 static_cast<HidDeviceInfoLinux*>(map_entry->second.get()); |
236 | 238 |
237 scoped_ptr<ConnectParams> params(new ConnectParams( | 239 std::unique_ptr<ConnectParams> params(new ConnectParams( |
238 device_info, callback, task_runner_, file_task_runner_)); | 240 device_info, callback, task_runner_, file_task_runner_)); |
239 | 241 |
240 #if defined(OS_CHROMEOS) | 242 #if defined(OS_CHROMEOS) |
241 chromeos::PermissionBrokerClient* client = | 243 chromeos::PermissionBrokerClient* client = |
242 chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient(); | 244 chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient(); |
243 DCHECK(client) << "Could not get permission broker client."; | 245 DCHECK(client) << "Could not get permission broker client."; |
244 chromeos::PermissionBrokerClient::ErrorCallback error_callback = | 246 chromeos::PermissionBrokerClient::ErrorCallback error_callback = |
245 base::Bind(&HidServiceLinux::OnPathOpenError, | 247 base::Bind(&HidServiceLinux::OnPathOpenError, |
246 params->device_info->device_node(), params->callback); | 248 params->device_info->device_node(), params->callback); |
247 client->OpenPath( | 249 client->OpenPath( |
248 device_info->device_node(), | 250 device_info->device_node(), |
249 base::Bind(&HidServiceLinux::OnPathOpenComplete, base::Passed(¶ms)), | 251 base::Bind(&HidServiceLinux::OnPathOpenComplete, base::Passed(¶ms)), |
250 error_callback); | 252 error_callback); |
251 #else | 253 #else |
252 file_task_runner_->PostTask(FROM_HERE, | 254 file_task_runner_->PostTask(FROM_HERE, |
253 base::Bind(&HidServiceLinux::OpenOnBlockingThread, | 255 base::Bind(&HidServiceLinux::OpenOnBlockingThread, |
254 base::Passed(¶ms))); | 256 base::Passed(¶ms))); |
255 #endif // defined(OS_CHROMEOS) | 257 #endif // defined(OS_CHROMEOS) |
256 } | 258 } |
257 | 259 |
258 #if defined(OS_CHROMEOS) | 260 #if defined(OS_CHROMEOS) |
259 | 261 |
260 // static | 262 // static |
261 void HidServiceLinux::OnPathOpenComplete(scoped_ptr<ConnectParams> params, | 263 void HidServiceLinux::OnPathOpenComplete(std::unique_ptr<ConnectParams> params, |
262 dbus::FileDescriptor fd) { | 264 dbus::FileDescriptor fd) { |
263 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner = | 265 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner = |
264 params->file_task_runner; | 266 params->file_task_runner; |
265 file_task_runner->PostTask( | 267 file_task_runner->PostTask( |
266 FROM_HERE, base::Bind(&HidServiceLinux::ValidateFdOnBlockingThread, | 268 FROM_HERE, base::Bind(&HidServiceLinux::ValidateFdOnBlockingThread, |
267 base::Passed(¶ms), base::Passed(&fd))); | 269 base::Passed(¶ms), base::Passed(&fd))); |
268 } | 270 } |
269 | 271 |
270 // static | 272 // static |
271 void HidServiceLinux::OnPathOpenError(const std::string& device_path, | 273 void HidServiceLinux::OnPathOpenError(const std::string& device_path, |
272 const ConnectCallback& callback, | 274 const ConnectCallback& callback, |
273 const std::string& error_name, | 275 const std::string& error_name, |
274 const std::string& error_message) { | 276 const std::string& error_message) { |
275 HID_LOG(EVENT) << "Permission broker failed to open '" << device_path | 277 HID_LOG(EVENT) << "Permission broker failed to open '" << device_path |
276 << "': " << error_name << ": " << error_message; | 278 << "': " << error_name << ": " << error_message; |
277 callback.Run(nullptr); | 279 callback.Run(nullptr); |
278 } | 280 } |
279 | 281 |
280 // static | 282 // static |
281 void HidServiceLinux::ValidateFdOnBlockingThread( | 283 void HidServiceLinux::ValidateFdOnBlockingThread( |
282 scoped_ptr<ConnectParams> params, | 284 std::unique_ptr<ConnectParams> params, |
283 dbus::FileDescriptor fd) { | 285 dbus::FileDescriptor fd) { |
284 base::ThreadRestrictions::AssertIOAllowed(); | 286 base::ThreadRestrictions::AssertIOAllowed(); |
285 fd.CheckValidity(); | 287 fd.CheckValidity(); |
286 DCHECK(fd.is_valid()); | 288 DCHECK(fd.is_valid()); |
287 params->device_file = base::File(fd.TakeValue()); | 289 params->device_file = base::File(fd.TakeValue()); |
288 FinishOpen(std::move(params)); | 290 FinishOpen(std::move(params)); |
289 } | 291 } |
290 | 292 |
291 #else | 293 #else |
292 | 294 |
293 // static | 295 // static |
294 void HidServiceLinux::OpenOnBlockingThread(scoped_ptr<ConnectParams> params) { | 296 void HidServiceLinux::OpenOnBlockingThread( |
| 297 std::unique_ptr<ConnectParams> params) { |
295 base::ThreadRestrictions::AssertIOAllowed(); | 298 base::ThreadRestrictions::AssertIOAllowed(); |
296 scoped_refptr<base::SingleThreadTaskRunner> task_runner = params->task_runner; | 299 scoped_refptr<base::SingleThreadTaskRunner> task_runner = params->task_runner; |
297 | 300 |
298 base::FilePath device_path(params->device_info->device_node()); | 301 base::FilePath device_path(params->device_info->device_node()); |
299 base::File& device_file = params->device_file; | 302 base::File& device_file = params->device_file; |
300 int flags = | 303 int flags = |
301 base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE; | 304 base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE; |
302 device_file.Initialize(device_path, flags); | 305 device_file.Initialize(device_path, flags); |
303 if (!device_file.IsValid()) { | 306 if (!device_file.IsValid()) { |
304 base::File::Error file_error = device_file.error_details(); | 307 base::File::Error file_error = device_file.error_details(); |
(...skipping 12 matching lines...) Expand all Loading... |
317 task_runner->PostTask(FROM_HERE, base::Bind(params->callback, nullptr)); | 320 task_runner->PostTask(FROM_HERE, base::Bind(params->callback, nullptr)); |
318 return; | 321 return; |
319 } | 322 } |
320 | 323 |
321 FinishOpen(std::move(params)); | 324 FinishOpen(std::move(params)); |
322 } | 325 } |
323 | 326 |
324 #endif // defined(OS_CHROMEOS) | 327 #endif // defined(OS_CHROMEOS) |
325 | 328 |
326 // static | 329 // static |
327 void HidServiceLinux::FinishOpen(scoped_ptr<ConnectParams> params) { | 330 void HidServiceLinux::FinishOpen(std::unique_ptr<ConnectParams> params) { |
328 base::ThreadRestrictions::AssertIOAllowed(); | 331 base::ThreadRestrictions::AssertIOAllowed(); |
329 scoped_refptr<base::SingleThreadTaskRunner> task_runner = params->task_runner; | 332 scoped_refptr<base::SingleThreadTaskRunner> task_runner = params->task_runner; |
330 | 333 |
331 if (!base::SetNonBlocking(params->device_file.GetPlatformFile())) { | 334 if (!base::SetNonBlocking(params->device_file.GetPlatformFile())) { |
332 HID_PLOG(ERROR) << "Failed to set the non-blocking flag on the device fd"; | 335 HID_PLOG(ERROR) << "Failed to set the non-blocking flag on the device fd"; |
333 task_runner->PostTask(FROM_HERE, base::Bind(params->callback, nullptr)); | 336 task_runner->PostTask(FROM_HERE, base::Bind(params->callback, nullptr)); |
334 return; | 337 return; |
335 } | 338 } |
336 | 339 |
337 task_runner->PostTask( | 340 task_runner->PostTask( |
338 FROM_HERE, | 341 FROM_HERE, |
339 base::Bind(&HidServiceLinux::CreateConnection, base::Passed(¶ms))); | 342 base::Bind(&HidServiceLinux::CreateConnection, base::Passed(¶ms))); |
340 } | 343 } |
341 | 344 |
342 // static | 345 // static |
343 void HidServiceLinux::CreateConnection(scoped_ptr<ConnectParams> params) { | 346 void HidServiceLinux::CreateConnection(std::unique_ptr<ConnectParams> params) { |
344 DCHECK(params->device_file.IsValid()); | 347 DCHECK(params->device_file.IsValid()); |
345 params->callback.Run(make_scoped_refptr(new HidConnectionLinux( | 348 params->callback.Run(make_scoped_refptr(new HidConnectionLinux( |
346 params->device_info, std::move(params->device_file), | 349 params->device_info, std::move(params->device_file), |
347 params->file_task_runner))); | 350 params->file_task_runner))); |
348 } | 351 } |
349 | 352 |
350 } // namespace device | 353 } // namespace device |
OLD | NEW |