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

Side by Side Diff: device/devices_app/usb/device_manager_impl.cc

Issue 1316203006: Convert DeviceManagerDelegate to PermissionProvider mojo interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed rockot@'s comments. Created 5 years, 3 months 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 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" 10 #include "base/message_loop/message_loop.h"
11 #include "base/scoped_observer.h" 11 #include "base/scoped_observer.h"
12 #include "base/sequenced_task_runner.h" 12 #include "base/sequenced_task_runner.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/thread_task_runner_handle.h" 14 #include "base/thread_task_runner_handle.h"
15 #include "device/core/device_client.h" 15 #include "device/core/device_client.h"
16 #include "device/devices_app/usb/device_impl.h" 16 #include "device/devices_app/usb/device_impl.h"
17 #include "device/devices_app/usb/public/cpp/device_manager_delegate.h"
18 #include "device/devices_app/usb/public/interfaces/device.mojom.h" 17 #include "device/devices_app/usb/public/interfaces/device.mojom.h"
19 #include "device/devices_app/usb/type_converters.h" 18 #include "device/devices_app/usb/type_converters.h"
20 #include "device/usb/usb_device.h" 19 #include "device/usb/usb_device.h"
21 #include "device/usb/usb_device_filter.h" 20 #include "device/usb/usb_device_filter.h"
22 #include "device/usb/usb_service.h" 21 #include "device/usb/usb_service.h"
23 #include "third_party/mojo/src/mojo/public/cpp/bindings/array.h" 22 #include "third_party/mojo/src/mojo/public/cpp/bindings/array.h"
24 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h" 23 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
25 24
26 namespace device { 25 namespace device {
27 namespace usb { 26 namespace usb {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 callback_task_runner->PostTask(FROM_HERE, 100 callback_task_runner->PostTask(FROM_HERE,
102 base::Bind(&RunOpenDeviceCallback, callback, 101 base::Bind(&RunOpenDeviceCallback, callback,
103 OPEN_DEVICE_ERROR_NOT_FOUND)); 102 OPEN_DEVICE_ERROR_NOT_FOUND));
104 return; 103 return;
105 } 104 }
106 device->Open(base::Bind(&OnOpenDeviceOnServiceThread, 105 device->Open(base::Bind(&OnOpenDeviceOnServiceThread,
107 base::Passed(&device_request), callback, 106 base::Passed(&device_request), callback,
108 callback_task_runner)); 107 callback_task_runner));
109 } 108 }
110 109
110 void FilterDeviceListAndThen(
111 const DeviceManagerImpl::GetDevicesCallback& callback,
112 mojo::Array<DeviceInfoPtr> devices,
113 mojo::Array<mojo::String> allowed_guids) {
114 std::set<std::string> allowed_guid_set;
115 for (size_t i = 0; i < allowed_guids.size(); ++i)
116 allowed_guid_set.insert(allowed_guids[i]);
117
118 mojo::Array<DeviceInfoPtr> allowed_devices(0);
119 for (size_t i = 0; i < devices.size(); ++i) {
120 if (ContainsKey(allowed_guid_set, devices[i]->guid))
121 allowed_devices.push_back(devices[i].Pass());
122 }
123
124 callback.Run(allowed_devices.Pass());
125 }
126
111 } // namespace 127 } // namespace
112 128
113 class DeviceManagerImpl::ServiceThreadHelper 129 class DeviceManagerImpl::ServiceThreadHelper
114 : public UsbService::Observer, 130 : public UsbService::Observer,
115 public base::MessageLoop::DestructionObserver { 131 public base::MessageLoop::DestructionObserver {
116 public: 132 public:
117 ServiceThreadHelper(base::WeakPtr<DeviceManagerImpl> manager, 133 ServiceThreadHelper(base::WeakPtr<DeviceManagerImpl> manager,
118 scoped_refptr<base::TaskRunner> task_runner) 134 scoped_refptr<base::TaskRunner> task_runner)
119 : observer_(this), manager_(manager), task_runner_(task_runner) {} 135 : observer_(this), manager_(manager), task_runner_(task_runner) {}
120 136
121 ~ServiceThreadHelper() override { 137 ~ServiceThreadHelper() override {
122 base::MessageLoop::current()->RemoveDestructionObserver(this); 138 base::MessageLoop::current()->RemoveDestructionObserver(this);
123 } 139 }
124 140
125 static void Start( 141 static void Start(scoped_ptr<ServiceThreadHelper> self) {
126 scoped_ptr<ServiceThreadHelper> self,
127 const base::Callback<void(mojo::Array<DeviceInfoPtr>)>& callback) {
128 UsbService* usb_service = DeviceClient::Get()->GetUsbService(); 142 UsbService* usb_service = DeviceClient::Get()->GetUsbService();
129 if (usb_service) { 143 if (usb_service)
130 self->observer_.Add(usb_service); 144 self->observer_.Add(usb_service);
131 std::vector<UsbDeviceFilter> no_filters;
132 usb_service->GetDevices(base::Bind(&OnGetDevicesOnServiceThread,
133 no_filters, callback,
134 self->task_runner_));
135 }
136 145
137 // |self| now owned by the current message loop. 146 // |self| now owned by the current message loop.
138 base::MessageLoop::current()->AddDestructionObserver(self.release()); 147 base::MessageLoop::current()->AddDestructionObserver(self.release());
139 } 148 }
140 149
141 private: 150 private:
142 // UsbService::Observer 151 // UsbService::Observer
143 void OnDeviceAdded(scoped_refptr<UsbDevice> device) override { 152 void OnDeviceAdded(scoped_refptr<UsbDevice> device) override {
144 DeviceInfoPtr mojo_device(DeviceInfo::From(*device)); 153 DeviceInfoPtr mojo_device(DeviceInfo::From(*device));
145 task_runner_->PostTask( 154 task_runner_->PostTask(
(...skipping 10 matching lines...) Expand all
156 // base::MessageLoop::DestructionObserver 165 // base::MessageLoop::DestructionObserver
157 void WillDestroyCurrentMessageLoop() override { delete this; } 166 void WillDestroyCurrentMessageLoop() override { delete this; }
158 167
159 ScopedObserver<UsbService, UsbService::Observer> observer_; 168 ScopedObserver<UsbService, UsbService::Observer> observer_;
160 base::WeakPtr<DeviceManagerImpl> manager_; 169 base::WeakPtr<DeviceManagerImpl> manager_;
161 scoped_refptr<base::TaskRunner> task_runner_; 170 scoped_refptr<base::TaskRunner> task_runner_;
162 }; 171 };
163 172
164 DeviceManagerImpl::DeviceManagerImpl( 173 DeviceManagerImpl::DeviceManagerImpl(
165 mojo::InterfaceRequest<DeviceManager> request, 174 mojo::InterfaceRequest<DeviceManager> request,
166 scoped_ptr<DeviceManagerDelegate> delegate, 175 PermissionProviderPtr permission_provider,
167 scoped_refptr<base::SequencedTaskRunner> service_task_runner) 176 scoped_refptr<base::SequencedTaskRunner> service_task_runner)
168 : binding_(this, request.Pass()), 177 : permission_provider_(permission_provider.Pass()),
169 delegate_(delegate.Pass()),
170 service_task_runner_(service_task_runner), 178 service_task_runner_(service_task_runner),
179 binding_(this, request.Pass()),
171 weak_factory_(this) { 180 weak_factory_(this) {
181 // This object owns itself and will be destroyed if either the message pipe
182 // it is bound to is closed or the PermissionProvider it depends on is
183 // unavailable.
184 binding_.set_connection_error_handler([this]() { delete this; });
185 permission_provider_.set_connection_error_handler([this]() { delete this; });
186
187 scoped_ptr<ServiceThreadHelper> helper(new ServiceThreadHelper(
188 weak_factory_.GetWeakPtr(), base::ThreadTaskRunnerHandle::Get()));
189 helper_ = helper.get();
190 service_task_runner_->PostTask(
191 FROM_HERE,
192 base::Bind(&ServiceThreadHelper::Start, base::Passed(&helper)));
172 } 193 }
173 194
174 DeviceManagerImpl::~DeviceManagerImpl() { 195 DeviceManagerImpl::~DeviceManagerImpl() {
175 if (helper_) { 196 // It is safe to call this if |helper_| was already destroyed when
176 // It is safe to call this if |helper_| was already destroyed when 197 // |service_task_runner_| exited as the task will never execute.
177 // |service_task_runner_| exited as the task will never execute. 198 service_task_runner_->DeleteSoon(FROM_HERE, helper_);
178 service_task_runner_->DeleteSoon(FROM_HERE, helper_); 199 connection_error_handler_.Run();
179 }
180 }
181
182 void DeviceManagerImpl::set_connection_error_handler(
183 const mojo::Closure& error_handler) {
184 binding_.set_connection_error_handler(error_handler);
185 } 200 }
186 201
187 void DeviceManagerImpl::GetDevices(EnumerationOptionsPtr options, 202 void DeviceManagerImpl::GetDevices(EnumerationOptionsPtr options,
188 const GetDevicesCallback& callback) { 203 const GetDevicesCallback& callback) {
189 auto filters = options->filters.To<std::vector<UsbDeviceFilter>>(); 204 std::vector<UsbDeviceFilter> filters;
205 if (options)
206 filters = options->filters.To<std::vector<UsbDeviceFilter>>();
190 auto get_devices_callback = base::Bind(&DeviceManagerImpl::OnGetDevices, 207 auto get_devices_callback = base::Bind(&DeviceManagerImpl::OnGetDevices,
191 weak_factory_.GetWeakPtr(), callback); 208 weak_factory_.GetWeakPtr(), callback);
192 service_task_runner_->PostTask( 209 service_task_runner_->PostTask(
193 FROM_HERE, 210 FROM_HERE,
194 base::Bind(&GetDevicesOnServiceThread, filters, get_devices_callback, 211 base::Bind(&GetDevicesOnServiceThread, filters, get_devices_callback,
195 base::ThreadTaskRunnerHandle::Get())); 212 base::ThreadTaskRunnerHandle::Get()));
196 } 213 }
197 214
198 void DeviceManagerImpl::GetDeviceChanges( 215 void DeviceManagerImpl::GetDeviceChanges(
199 const GetDeviceChangesCallback& callback) { 216 const GetDeviceChangesCallback& callback) {
200 if (helper_) { 217 device_change_callbacks_.push(callback);
201 device_change_callbacks_.push(callback); 218 MaybeRunDeviceChangesCallback();
202 MaybeRunDeviceChangesCallback();
203 } else {
204 scoped_ptr<ServiceThreadHelper> helper(new ServiceThreadHelper(
205 weak_factory_.GetWeakPtr(), base::ThreadTaskRunnerHandle::Get()));
206 helper_ = helper.get();
207 auto get_devices_callback =
208 base::Bind(&DeviceManagerImpl::OnGetInitialDevices,
209 weak_factory_.GetWeakPtr(), callback);
210 service_task_runner_->PostTask(
211 FROM_HERE, base::Bind(&ServiceThreadHelper::Start,
212 base::Passed(&helper), get_devices_callback));
213 }
214 } 219 }
215 220
216 void DeviceManagerImpl::OpenDevice( 221 void DeviceManagerImpl::OpenDevice(
217 const mojo::String& guid, 222 const mojo::String& guid,
218 mojo::InterfaceRequest<Device> device_request, 223 mojo::InterfaceRequest<Device> device_request,
219 const OpenDeviceCallback& callback) { 224 const OpenDeviceCallback& callback) {
220 service_task_runner_->PostTask( 225 service_task_runner_->PostTask(
221 FROM_HERE, base::Bind(&OpenDeviceOnServiceThread, guid, 226 FROM_HERE, base::Bind(&OpenDeviceOnServiceThread, guid,
222 base::Passed(&device_request), callback, 227 base::Passed(&device_request), callback,
223 base::ThreadTaskRunnerHandle::Get())); 228 base::ThreadTaskRunnerHandle::Get()));
224 } 229 }
225 230
226 void DeviceManagerImpl::OnGetDevices(const GetDevicesCallback& callback, 231 void DeviceManagerImpl::OnGetDevices(const GetDevicesCallback& callback,
227 mojo::Array<DeviceInfoPtr> devices) { 232 mojo::Array<DeviceInfoPtr> devices) {
228 mojo::Array<DeviceInfoPtr> allowed_devices(0); 233 mojo::Array<mojo::String> requested_guids(devices.size());
229 for (size_t i = 0; i < devices.size(); ++i) { 234 for (size_t i = 0; i < devices.size(); ++i) {
Ken Rockot(use gerrit already) 2015/09/03 00:06:11 extra nitty nit: no {}
Reilly Grant (use Gerrit) 2015/09/03 00:09:28 Done.
230 if (delegate_->IsDeviceAllowed(*devices[i])) 235 requested_guids[i] = devices[i]->guid;
231 allowed_devices.push_back(devices[i].Pass());
232 } 236 }
233 callback.Run(allowed_devices.Pass()); 237 permission_provider_->HasDevicePermission(
234 } 238 requested_guids.Pass(),
235 239 base::Bind(&FilterDeviceListAndThen, callback, base::Passed(&devices)));
236 void DeviceManagerImpl::OnGetInitialDevices(
237 const GetDeviceChangesCallback& callback,
238 mojo::Array<DeviceInfoPtr> devices) {
239 DeviceChangeNotificationPtr notification = DeviceChangeNotification::New();
240 notification->devices_added = mojo::Array<DeviceInfoPtr>::New(0);
241 notification->devices_removed = mojo::Array<mojo::String>::New(0);
242 for (size_t i = 0; i < devices.size(); ++i) {
243 if (delegate_->IsDeviceAllowed(*devices[i]))
244 notification->devices_added.push_back(devices[i].Pass());
245 }
246 callback.Run(notification.Pass());
247 } 240 }
248 241
249 void DeviceManagerImpl::OnDeviceAdded(DeviceInfoPtr device) { 242 void DeviceManagerImpl::OnDeviceAdded(DeviceInfoPtr device) {
250 DCHECK(!ContainsKey(devices_removed_, device->guid)); 243 DCHECK(!ContainsKey(devices_removed_, device->guid));
251 devices_added_.push_back(device.Pass()); 244 devices_added_.push_back(device.Pass());
252 MaybeRunDeviceChangesCallback(); 245 MaybeRunDeviceChangesCallback();
253 } 246 }
254 247
255 void DeviceManagerImpl::OnDeviceRemoved(std::string device_guid) { 248 void DeviceManagerImpl::OnDeviceRemoved(std::string device_guid) {
256 bool found = false; 249 bool found = false;
257 mojo::Array<DeviceInfoPtr> devices_added; 250 mojo::Array<DeviceInfoPtr> devices_added;
258 for (size_t i = 0; i < devices_added_.size(); ++i) { 251 for (size_t i = 0; i < devices_added_.size(); ++i) {
259 if (devices_added_[i]->guid == device_guid) 252 if (devices_added_[i]->guid == device_guid)
260 found = true; 253 found = true;
261 else 254 else
262 devices_added.push_back(devices_added_[i].Pass()); 255 devices_added.push_back(devices_added_[i].Pass());
263 } 256 }
264 devices_added.Swap(&devices_added_); 257 devices_added.Swap(&devices_added_);
265 if (!found) 258 if (!found)
266 devices_removed_.insert(device_guid); 259 devices_removed_.insert(device_guid);
267 MaybeRunDeviceChangesCallback(); 260 MaybeRunDeviceChangesCallback();
268 } 261 }
269 262
270 void DeviceManagerImpl::MaybeRunDeviceChangesCallback() { 263 void DeviceManagerImpl::MaybeRunDeviceChangesCallback() {
271 if (!device_change_callbacks_.empty()) { 264 if (!permission_request_pending_ && !device_change_callbacks_.empty()) {
265 mojo::Array<DeviceInfoPtr> devices_added;
266 devices_added.Swap(&devices_added_);
267 std::set<std::string> devices_removed;
268 devices_removed.swap(devices_removed_);
269
270 mojo::Array<mojo::String> requested_guids(devices_added.size() +
271 devices_removed.size());
272 {
273 size_t i;
274 for (i = 0; i < devices_added.size(); ++i)
275 requested_guids[i] = devices_added[i]->guid;
276 for (const std::string& guid : devices_removed)
277 requested_guids[i++] = guid;
278 }
279
280 permission_request_pending_ = true;
281 permission_provider_->HasDevicePermission(
282 requested_guids.Pass(),
283 base::Bind(&DeviceManagerImpl::OnPermissionCheckComplete,
284 base::Unretained(this), base::Passed(&devices_added),
285 devices_removed));
286 }
287 }
288
289 void DeviceManagerImpl::OnPermissionCheckComplete(
290 mojo::Array<DeviceInfoPtr> devices_added,
291 const std::set<std::string>& devices_removed,
292 mojo::Array<mojo::String> allowed_guids) {
293 permission_request_pending_ = false;
294
295 if (allowed_guids.size() > 0) {
296 std::set<std::string> allowed_guid_set;
297 for (size_t i = 0; i < allowed_guids.size(); ++i)
298 allowed_guid_set.insert(allowed_guids[i]);
299
272 DeviceChangeNotificationPtr notification = DeviceChangeNotification::New(); 300 DeviceChangeNotificationPtr notification = DeviceChangeNotification::New();
273 notification->devices_added.Swap(&devices_added_); 301 notification->devices_added.resize(0);
302 for (size_t i = 0; i < devices_added.size(); ++i) {
303 if (ContainsKey(allowed_guid_set, devices_added[i]->guid))
304 notification->devices_added.push_back(devices_added[i].Pass());
305 }
306
274 notification->devices_removed.resize(0); 307 notification->devices_removed.resize(0);
275 for (const std::string& device : devices_removed_) 308 for (const std::string& guid : devices_removed) {
276 notification->devices_removed.push_back(device); 309 if (ContainsKey(allowed_guid_set, guid))
277 devices_removed_.clear(); 310 notification->devices_removed.push_back(guid);
311 }
278 312
313 DCHECK(!device_change_callbacks_.empty());
279 const GetDeviceChangesCallback& callback = device_change_callbacks_.front(); 314 const GetDeviceChangesCallback& callback = device_change_callbacks_.front();
280 callback.Run(notification.Pass()); 315 callback.Run(notification.Pass());
281 device_change_callbacks_.pop(); 316 device_change_callbacks_.pop();
282 } 317 }
318
319 if (devices_added_.size() > 0 || !devices_removed_.empty()) {
320 MaybeRunDeviceChangesCallback();
321 }
283 } 322 }
284 323
285 } // namespace usb 324 } // namespace usb
286 } // namespace device 325 } // namespace device
OLDNEW
« no previous file with comments | « device/devices_app/usb/device_manager_impl.h ('k') | device/devices_app/usb/device_manager_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698