| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/devices_app/usb/device_manager_impl.h" | 5 #include "device/devices_app/usb/device_manager_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/message_loop/message_loop.h" | |
| 11 #include "base/scoped_observer.h" | |
| 12 #include "base/sequenced_task_runner.h" | |
| 13 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| 14 #include "base/thread_task_runner_handle.h" | |
| 15 #include "device/core/device_client.h" | 11 #include "device/core/device_client.h" |
| 16 #include "device/devices_app/usb/device_impl.h" | 12 #include "device/devices_app/usb/device_impl.h" |
| 17 #include "device/devices_app/usb/public/interfaces/device.mojom.h" | 13 #include "device/devices_app/usb/public/interfaces/device.mojom.h" |
| 18 #include "device/devices_app/usb/type_converters.h" | 14 #include "device/devices_app/usb/type_converters.h" |
| 19 #include "device/usb/usb_device.h" | 15 #include "device/usb/usb_device.h" |
| 20 #include "device/usb/usb_device_filter.h" | 16 #include "device/usb/usb_device_filter.h" |
| 21 #include "device/usb/usb_service.h" | 17 #include "device/usb/usb_service.h" |
| 22 #include "third_party/mojo/src/mojo/public/cpp/bindings/array.h" | 18 #include "third_party/mojo/src/mojo/public/cpp/bindings/array.h" |
| 23 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h" | 19 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h" |
| 24 | 20 |
| 25 namespace device { | 21 namespace device { |
| 26 namespace usb { | 22 namespace usb { |
| 27 | 23 |
| 28 namespace { | 24 namespace { |
| 29 | 25 |
| 30 using DeviceList = DeviceManagerImpl::DeviceList; | 26 using DeviceList = DeviceManagerImpl::DeviceList; |
| 31 using DeviceMap = DeviceManagerImpl::DeviceMap; | 27 using DeviceMap = DeviceManagerImpl::DeviceMap; |
| 32 | 28 |
| 33 void OnGetDevicesOnServiceThread( | |
| 34 const base::Callback<void(const DeviceList&)>& callback, | |
| 35 scoped_refptr<base::TaskRunner> callback_task_runner, | |
| 36 const DeviceList& devices) { | |
| 37 callback_task_runner->PostTask(FROM_HERE, base::Bind(callback, devices)); | |
| 38 } | |
| 39 | |
| 40 void GetDevicesOnServiceThread( | |
| 41 const base::Callback<void(const DeviceList&)>& callback, | |
| 42 scoped_refptr<base::TaskRunner> callback_task_runner) { | |
| 43 DCHECK(DeviceClient::Get()); | |
| 44 UsbService* usb_service = DeviceClient::Get()->GetUsbService(); | |
| 45 if (usb_service) { | |
| 46 usb_service->GetDevices(base::Bind(&OnGetDevicesOnServiceThread, callback, | |
| 47 callback_task_runner)); | |
| 48 } else { | |
| 49 callback_task_runner->PostTask(FROM_HERE, | |
| 50 base::Bind(callback, DeviceList())); | |
| 51 } | |
| 52 } | |
| 53 | |
| 54 void GetDeviceOnServiceThread( | |
| 55 const mojo::String& guid, | |
| 56 const base::Callback<void(scoped_refptr<UsbDevice>)>& callback, | |
| 57 scoped_refptr<base::TaskRunner> callback_task_runner) { | |
| 58 DCHECK(DeviceClient::Get()); | |
| 59 scoped_refptr<UsbDevice> device; | |
| 60 UsbService* usb_service = DeviceClient::Get()->GetUsbService(); | |
| 61 if (usb_service) | |
| 62 device = usb_service->GetDevice(guid); | |
| 63 callback_task_runner->PostTask(FROM_HERE, base::Bind(callback, device)); | |
| 64 } | |
| 65 | |
| 66 void FilterAndConvertDevicesAndThen( | 29 void FilterAndConvertDevicesAndThen( |
| 67 const DeviceMap& devices, | 30 const DeviceMap& devices, |
| 68 const DeviceManagerImpl::GetDevicesCallback& callback, | 31 const DeviceManagerImpl::GetDevicesCallback& callback, |
| 69 mojo::Array<mojo::String> allowed_guids) { | 32 mojo::Array<mojo::String> allowed_guids) { |
| 70 mojo::Array<DeviceInfoPtr> allowed_devices(allowed_guids.size()); | 33 mojo::Array<DeviceInfoPtr> allowed_devices(allowed_guids.size()); |
| 71 for (size_t i = 0; i < allowed_guids.size(); ++i) { | 34 for (size_t i = 0; i < allowed_guids.size(); ++i) { |
| 72 const auto it = devices.find(allowed_guids[i]); | 35 const auto it = devices.find(allowed_guids[i]); |
| 73 DCHECK(it != devices.end()); | 36 DCHECK(it != devices.end()); |
| 74 allowed_devices[i] = DeviceInfo::From(*it->second); | 37 allowed_devices[i] = DeviceInfo::From(*it->second); |
| 75 } | 38 } |
| 76 | 39 |
| 77 callback.Run(allowed_devices.Pass()); | 40 callback.Run(allowed_devices.Pass()); |
| 78 } | 41 } |
| 79 | 42 |
| 80 } // namespace | 43 } // namespace |
| 81 | 44 |
| 82 class DeviceManagerImpl::ServiceThreadHelper | 45 // static |
| 83 : public UsbService::Observer, | 46 void DeviceManagerImpl::Create(PermissionProviderPtr permission_provider, |
| 84 public base::MessageLoop::DestructionObserver { | 47 mojo::InterfaceRequest<DeviceManager> request) { |
| 85 public: | 48 // The created object is owned by its binding. |
| 86 ServiceThreadHelper(base::WeakPtr<DeviceManagerImpl> manager, | 49 new DeviceManagerImpl(permission_provider.Pass(), request.Pass()); |
| 87 scoped_refptr<base::TaskRunner> task_runner) | 50 } |
| 88 : observer_(this), manager_(manager), task_runner_(task_runner) {} | |
| 89 | |
| 90 ~ServiceThreadHelper() override { | |
| 91 base::MessageLoop::current()->RemoveDestructionObserver(this); | |
| 92 } | |
| 93 | |
| 94 static void Start(scoped_ptr<ServiceThreadHelper> self) { | |
| 95 UsbService* usb_service = DeviceClient::Get()->GetUsbService(); | |
| 96 if (usb_service) | |
| 97 self->observer_.Add(usb_service); | |
| 98 | |
| 99 // |self| now owned by the current message loop. | |
| 100 base::MessageLoop::current()->AddDestructionObserver(self.release()); | |
| 101 } | |
| 102 | |
| 103 private: | |
| 104 // UsbService::Observer | |
| 105 void OnDeviceAdded(scoped_refptr<UsbDevice> device) override { | |
| 106 task_runner_->PostTask( | |
| 107 FROM_HERE, | |
| 108 base::Bind(&DeviceManagerImpl::OnDeviceAdded, manager_, device)); | |
| 109 } | |
| 110 | |
| 111 void OnDeviceRemoved(scoped_refptr<UsbDevice> device) override { | |
| 112 task_runner_->PostTask( | |
| 113 FROM_HERE, | |
| 114 base::Bind(&DeviceManagerImpl::OnDeviceRemoved, manager_, device)); | |
| 115 } | |
| 116 | |
| 117 void WillDestroyUsbService() override { observer_.RemoveAll(); } | |
| 118 | |
| 119 // base::MessageLoop::DestructionObserver | |
| 120 void WillDestroyCurrentMessageLoop() override { delete this; } | |
| 121 | |
| 122 ScopedObserver<UsbService, UsbService::Observer> observer_; | |
| 123 base::WeakPtr<DeviceManagerImpl> manager_; | |
| 124 scoped_refptr<base::TaskRunner> task_runner_; | |
| 125 }; | |
| 126 | 51 |
| 127 DeviceManagerImpl::DeviceManagerImpl( | 52 DeviceManagerImpl::DeviceManagerImpl( |
| 128 mojo::InterfaceRequest<DeviceManager> request, | |
| 129 PermissionProviderPtr permission_provider, | 53 PermissionProviderPtr permission_provider, |
| 130 scoped_refptr<base::SequencedTaskRunner> service_task_runner) | 54 mojo::InterfaceRequest<DeviceManager> request) |
| 131 : permission_provider_(permission_provider.Pass()), | 55 : permission_provider_(permission_provider.Pass()), |
| 132 service_task_runner_(service_task_runner), | 56 observer_(this), |
| 133 binding_(this, request.Pass()), | 57 binding_(this, request.Pass()), |
| 134 weak_factory_(this) { | 58 weak_factory_(this) { |
| 135 // This object owns itself and will be destroyed if either the message pipe | 59 // This object owns itself and will be destroyed if either the message pipe |
| 136 // it is bound to is closed or the PermissionProvider it depends on is | 60 // it is bound to is closed or the PermissionProvider it depends on is |
| 137 // unavailable. | 61 // unavailable. |
| 138 binding_.set_connection_error_handler([this]() { delete this; }); | 62 binding_.set_connection_error_handler([this]() { delete this; }); |
| 139 permission_provider_.set_connection_error_handler([this]() { delete this; }); | 63 permission_provider_.set_connection_error_handler([this]() { delete this; }); |
| 140 | 64 |
| 141 scoped_ptr<ServiceThreadHelper> helper(new ServiceThreadHelper( | 65 DCHECK(DeviceClient::Get()); |
| 142 weak_factory_.GetWeakPtr(), base::ThreadTaskRunnerHandle::Get())); | 66 usb_service_ = DeviceClient::Get()->GetUsbService(); |
| 143 helper_ = helper.get(); | 67 if (usb_service_) |
| 144 service_task_runner_->PostTask( | 68 observer_.Add(usb_service_); |
| 145 FROM_HERE, | |
| 146 base::Bind(&ServiceThreadHelper::Start, base::Passed(&helper))); | |
| 147 } | 69 } |
| 148 | 70 |
| 149 DeviceManagerImpl::~DeviceManagerImpl() { | 71 DeviceManagerImpl::~DeviceManagerImpl() { |
| 150 // It is safe to call this if |helper_| was already destroyed when | |
| 151 // |service_task_runner_| exited as the task will never execute. | |
| 152 service_task_runner_->DeleteSoon(FROM_HERE, helper_); | |
| 153 connection_error_handler_.Run(); | 72 connection_error_handler_.Run(); |
| 154 } | 73 } |
| 155 | 74 |
| 156 void DeviceManagerImpl::GetDevices(EnumerationOptionsPtr options, | 75 void DeviceManagerImpl::GetDevices(EnumerationOptionsPtr options, |
| 157 const GetDevicesCallback& callback) { | 76 const GetDevicesCallback& callback) { |
| 158 auto get_devices_callback = | 77 if (!usb_service_) { |
| 159 base::Bind(&DeviceManagerImpl::OnGetDevices, weak_factory_.GetWeakPtr(), | 78 mojo::Array<DeviceInfoPtr> no_devices; |
| 160 base::Passed(&options), callback); | 79 callback.Run(no_devices.Pass()); |
| 161 service_task_runner_->PostTask( | 80 return; |
| 162 FROM_HERE, base::Bind(&GetDevicesOnServiceThread, get_devices_callback, | 81 } |
| 163 base::ThreadTaskRunnerHandle::Get())); | 82 |
| 83 usb_service_->GetDevices(base::Bind(&DeviceManagerImpl::OnGetDevices, |
| 84 weak_factory_.GetWeakPtr(), |
| 85 base::Passed(&options), callback)); |
| 164 } | 86 } |
| 165 | 87 |
| 166 void DeviceManagerImpl::GetDeviceChanges( | 88 void DeviceManagerImpl::GetDeviceChanges( |
| 167 const GetDeviceChangesCallback& callback) { | 89 const GetDeviceChangesCallback& callback) { |
| 168 device_change_callbacks_.push(callback); | 90 device_change_callbacks_.push(callback); |
| 169 MaybeRunDeviceChangesCallback(); | 91 MaybeRunDeviceChangesCallback(); |
| 170 } | 92 } |
| 171 | 93 |
| 172 void DeviceManagerImpl::GetDevice( | 94 void DeviceManagerImpl::GetDevice( |
| 173 const mojo::String& guid, | 95 const mojo::String& guid, |
| 174 mojo::InterfaceRequest<Device> device_request) { | 96 mojo::InterfaceRequest<Device> device_request) { |
| 175 auto get_device_callback = | 97 if (!usb_service_) |
| 176 base::Bind(&DeviceManagerImpl::OnGetDevice, weak_factory_.GetWeakPtr(), | 98 return; |
| 177 base::Passed(&device_request)); | |
| 178 service_task_runner_->PostTask( | |
| 179 FROM_HERE, | |
| 180 base::Bind(&GetDeviceOnServiceThread, guid, get_device_callback, | |
| 181 base::ThreadTaskRunnerHandle::Get())); | |
| 182 } | |
| 183 | 99 |
| 184 void DeviceManagerImpl::OnGetDevice( | 100 scoped_refptr<UsbDevice> device = usb_service_->GetDevice(guid); |
| 185 mojo::InterfaceRequest<Device> device_request, | |
| 186 scoped_refptr<UsbDevice> device) { | |
| 187 if (!device) | 101 if (!device) |
| 188 return; | 102 return; |
| 189 | 103 |
| 190 mojo::Array<DeviceInfoPtr> requested_devices(1); | 104 mojo::Array<DeviceInfoPtr> requested_devices(1); |
| 191 requested_devices[0] = DeviceInfo::From(*device); | 105 requested_devices[0] = DeviceInfo::From(*device); |
| 192 permission_provider_->HasDevicePermission( | 106 permission_provider_->HasDevicePermission( |
| 193 requested_devices.Pass(), | 107 requested_devices.Pass(), |
| 194 base::Bind(&DeviceManagerImpl::OnGetDevicePermissionCheckComplete, | 108 base::Bind(&DeviceManagerImpl::OnGetDevicePermissionCheckComplete, |
| 195 base::Unretained(this), device, | 109 base::Unretained(this), device, |
| 196 base::Passed(&device_request))); | 110 base::Passed(&device_request))); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 devices_added_[device->guid()] = device; | 149 devices_added_[device->guid()] = device; |
| 236 MaybeRunDeviceChangesCallback(); | 150 MaybeRunDeviceChangesCallback(); |
| 237 } | 151 } |
| 238 | 152 |
| 239 void DeviceManagerImpl::OnDeviceRemoved(scoped_refptr<UsbDevice> device) { | 153 void DeviceManagerImpl::OnDeviceRemoved(scoped_refptr<UsbDevice> device) { |
| 240 if (devices_added_.erase(device->guid()) == 0) | 154 if (devices_added_.erase(device->guid()) == 0) |
| 241 devices_removed_[device->guid()] = device; | 155 devices_removed_[device->guid()] = device; |
| 242 MaybeRunDeviceChangesCallback(); | 156 MaybeRunDeviceChangesCallback(); |
| 243 } | 157 } |
| 244 | 158 |
| 159 void DeviceManagerImpl::WillDestroyUsbService() { |
| 160 observer_.RemoveAll(); |
| 161 usb_service_ = nullptr; |
| 162 } |
| 163 |
| 245 void DeviceManagerImpl::MaybeRunDeviceChangesCallback() { | 164 void DeviceManagerImpl::MaybeRunDeviceChangesCallback() { |
| 246 if (!permission_request_pending_ && !device_change_callbacks_.empty()) { | 165 if (!permission_request_pending_ && !device_change_callbacks_.empty()) { |
| 247 DeviceMap devices_added; | 166 DeviceMap devices_added; |
| 248 devices_added.swap(devices_added_); | 167 devices_added.swap(devices_added_); |
| 249 DeviceMap devices_removed; | 168 DeviceMap devices_removed; |
| 250 devices_removed.swap(devices_removed_); | 169 devices_removed.swap(devices_removed_); |
| 251 | 170 |
| 252 mojo::Array<DeviceInfoPtr> requested_devices(devices_added.size() + | 171 mojo::Array<DeviceInfoPtr> requested_devices(devices_added.size() + |
| 253 devices_removed.size()); | 172 devices_removed.size()); |
| 254 { | 173 { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 callback.Run(notification.Pass()); | 215 callback.Run(notification.Pass()); |
| 297 device_change_callbacks_.pop(); | 216 device_change_callbacks_.pop(); |
| 298 } | 217 } |
| 299 | 218 |
| 300 if (devices_added_.size() > 0 || !devices_removed_.empty()) | 219 if (devices_added_.size() > 0 || !devices_removed_.empty()) |
| 301 MaybeRunDeviceChangesCallback(); | 220 MaybeRunDeviceChangesCallback(); |
| 302 } | 221 } |
| 303 | 222 |
| 304 } // namespace usb | 223 } // namespace usb |
| 305 } // namespace device | 224 } // namespace device |
| OLD | NEW |