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

Side by Side Diff: chrome/browser/usb/usb_chooser_controller.cc

Issue 2746313002: Remove RenderFrameHost pointer from ChooserController. (Closed)
Patch Set: Created 3 years, 9 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 "chrome/browser/usb/usb_chooser_controller.h" 5 #include "chrome/browser/usb/usb_chooser_controller.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/net/referrer.h" 13 #include "chrome/browser/net/referrer.h"
14 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/profiles/profile_manager.h" 15 #include "chrome/browser/profiles/profile_manager.h"
16 #include "chrome/browser/ui/browser.h" 16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" 17 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
18 #include "chrome/browser/usb/usb_blocklist.h" 18 #include "chrome/browser/usb/usb_blocklist.h"
19 #include "chrome/browser/usb/usb_chooser_context.h" 19 #include "chrome/browser/usb/usb_chooser_context.h"
20 #include "chrome/browser/usb/usb_chooser_context_factory.h" 20 #include "chrome/browser/usb/usb_chooser_context_factory.h"
21 #include "chrome/browser/usb/web_usb_histograms.h" 21 #include "chrome/browser/usb/web_usb_histograms.h"
22 #include "chrome/browser/usb/web_usb_permission_provider.h"
23 #include "chrome/common/url_constants.h" 22 #include "chrome/common/url_constants.h"
24 #include "chrome/grit/generated_resources.h" 23 #include "chrome/grit/generated_resources.h"
25 #include "content/public/browser/render_frame_host.h" 24 #include "content/public/browser/render_frame_host.h"
26 #include "content/public/browser/web_contents.h" 25 #include "content/public/browser/web_contents.h"
27 #include "device/base/device_client.h" 26 #include "device/base/device_client.h"
28 #include "device/usb/mojo/type_converters.h" 27 #include "device/usb/mojo/type_converters.h"
29 #include "device/usb/usb_device.h" 28 #include "device/usb/usb_device.h"
30 #include "device/usb/usb_device_filter.h" 29 #include "device/usb/usb_device_filter.h"
31 #include "device/usb/usb_ids.h" 30 #include "device/usb/usb_ids.h"
32 #include "device/usb/webusb_descriptors.h" 31 #include "device/usb/webusb_descriptors.h"
33 #include "ui/base/l10n/l10n_util.h" 32 #include "ui/base/l10n/l10n_util.h"
34 #include "url/gurl.h" 33 #include "url/gurl.h"
35 34
36 using content::RenderFrameHost; 35 using content::RenderFrameHost;
37 using content::WebContents; 36 using content::WebContents;
37 using device::UsbDevice;
38 using device::UsbDeviceFilter;
38 39
39 namespace { 40 namespace {
40 41
41 Browser* GetBrowser() { 42 Browser* GetBrowser() {
42 chrome::ScopedTabbedBrowserDisplayer browser_displayer( 43 chrome::ScopedTabbedBrowserDisplayer browser_displayer(
43 ProfileManager::GetActiveUserProfile()); 44 ProfileManager::GetActiveUserProfile());
44 DCHECK(browser_displayer.browser()); 45 DCHECK(browser_displayer.browser());
45 return browser_displayer.browser(); 46 return browser_displayer.browser();
46 } 47 }
47 48
48 base::string16 GetDeviceName(scoped_refptr<device::UsbDevice> device) { 49 base::string16 GetDeviceName(scoped_refptr<UsbDevice> device) {
49 base::string16 device_name = device->product_string(); 50 base::string16 device_name = device->product_string();
50 if (device_name.empty()) { 51 if (device_name.empty()) {
51 uint16_t vendor_id = device->vendor_id(); 52 uint16_t vendor_id = device->vendor_id();
52 uint16_t product_id = device->product_id(); 53 uint16_t product_id = device->product_id();
53 if (const char* product_name = 54 if (const char* product_name =
54 device::UsbIds::GetProductName(vendor_id, product_id)) { 55 device::UsbIds::GetProductName(vendor_id, product_id)) {
55 device_name = base::UTF8ToUTF16(product_name); 56 device_name = base::UTF8ToUTF16(product_name);
56 } else if (const char* vendor_name = 57 } else if (const char* vendor_name =
57 device::UsbIds::GetVendorName(vendor_id)) { 58 device::UsbIds::GetVendorName(vendor_id)) {
58 device_name = l10n_util::GetStringFUTF16( 59 device_name = l10n_util::GetStringFUTF16(
59 IDS_DEVICE_CHOOSER_DEVICE_NAME_UNKNOWN_DEVICE_WITH_VENDOR_NAME, 60 IDS_DEVICE_CHOOSER_DEVICE_NAME_UNKNOWN_DEVICE_WITH_VENDOR_NAME,
60 base::UTF8ToUTF16(vendor_name)); 61 base::UTF8ToUTF16(vendor_name));
61 } else { 62 } else {
62 device_name = l10n_util::GetStringFUTF16( 63 device_name = l10n_util::GetStringFUTF16(
63 IDS_DEVICE_CHOOSER_DEVICE_NAME_UNKNOWN_DEVICE_WITH_VENDOR_ID_AND_PRODU CT_ID, 64 IDS_DEVICE_CHOOSER_DEVICE_NAME_UNKNOWN_DEVICE_WITH_VENDOR_ID_AND_PRODU CT_ID,
64 base::ASCIIToUTF16(base::StringPrintf("%04x", vendor_id)), 65 base::ASCIIToUTF16(base::StringPrintf("%04x", vendor_id)),
65 base::ASCIIToUTF16(base::StringPrintf("%04x", product_id))); 66 base::ASCIIToUTF16(base::StringPrintf("%04x", product_id)));
66 } 67 }
67 } 68 }
68 69
69 return device_name; 70 return device_name;
70 } 71 }
71 72
72 } // namespace 73 } // namespace
73 74
74 UsbChooserController::UsbChooserController( 75 UsbChooserController::UsbChooserController(
75 RenderFrameHost* render_frame_host, 76 RenderFrameHost* render_frame_host,
76 const std::vector<device::UsbDeviceFilter>& device_filters, 77 const std::vector<UsbDeviceFilter>& device_filters,
77 const device::usb::ChooserService::GetPermissionCallback& callback) 78 const device::usb::ChooserService::GetPermissionCallback& callback)
78 : ChooserController(render_frame_host, 79 : ChooserController(render_frame_host,
79 IDS_USB_DEVICE_CHOOSER_PROMPT_ORIGIN, 80 IDS_USB_DEVICE_CHOOSER_PROMPT_ORIGIN,
80 IDS_USB_DEVICE_CHOOSER_PROMPT_EXTENSION_NAME), 81 IDS_USB_DEVICE_CHOOSER_PROMPT_EXTENSION_NAME),
81 render_frame_host_(render_frame_host), 82 filters_(device_filters),
82 callback_(callback), 83 callback_(callback),
83 usb_service_observer_(this), 84 usb_service_observer_(this),
84 filters_(device_filters),
85 weak_factory_(this) { 85 weak_factory_(this) {
86 device::UsbService* usb_service = 86 device::UsbService* usb_service =
87 device::DeviceClient::Get()->GetUsbService(); 87 device::DeviceClient::Get()->GetUsbService();
88 if (!usb_service) 88 if (usb_service) {
89 return; 89 usb_service_observer_.Add(usb_service);
90 usb_service->GetDevices(base::Bind(&UsbChooserController::GotUsbDeviceList,
91 weak_factory_.GetWeakPtr()));
92 }
90 93
91 if (!usb_service_observer_.IsObserving(usb_service)) 94 WebContents* web_contents =
juncai 2017/03/14 00:10:48 question: this if condition is removed, any reason
Reilly Grant (use Gerrit) 2017/03/14 20:44:11 usb_service_observer_.Add is only called here in t
92 usb_service_observer_.Add(usb_service); 95 WebContents::FromRenderFrameHost(render_frame_host);
93 96 RenderFrameHost* main_frame = web_contents->GetMainFrame();
94 usb_service->GetDevices(base::Bind(&UsbChooserController::GotUsbDeviceList, 97 requesting_origin_ = render_frame_host->GetLastCommittedURL().GetOrigin();
95 weak_factory_.GetWeakPtr())); 98 embedding_origin_ = main_frame->GetLastCommittedURL().GetOrigin();
99 embedded_frame_ = render_frame_host != main_frame;
100 Profile* profile =
101 Profile::FromBrowserContext(web_contents->GetBrowserContext());
102 chooser_context_ =
103 UsbChooserContextFactory::GetForProfile(profile)->AsWeakPtr();
96 } 104 }
97 105
98 UsbChooserController::~UsbChooserController() { 106 UsbChooserController::~UsbChooserController() {
99 if (!callback_.is_null()) 107 if (!callback_.is_null())
100 callback_.Run(nullptr); 108 callback_.Run(nullptr);
101 } 109 }
102 110
103 base::string16 UsbChooserController::GetNoOptionsText() const { 111 base::string16 UsbChooserController::GetNoOptionsText() const {
104 return l10n_util::GetStringUTF16(IDS_DEVICE_CHOOSER_NO_DEVICES_FOUND_PROMPT); 112 return l10n_util::GetStringUTF16(IDS_DEVICE_CHOOSER_NO_DEVICES_FOUND_PROMPT);
105 } 113 }
(...skipping 11 matching lines...) Expand all
117 const base::string16& device_name = devices_[index].second; 125 const base::string16& device_name = devices_[index].second;
118 const auto& it = device_name_map_.find(device_name); 126 const auto& it = device_name_map_.find(device_name);
119 DCHECK(it != device_name_map_.end()); 127 DCHECK(it != device_name_map_.end());
120 return it->second == 1 128 return it->second == 1
121 ? device_name 129 ? device_name
122 : l10n_util::GetStringFUTF16( 130 : l10n_util::GetStringFUTF16(
123 IDS_DEVICE_CHOOSER_DEVICE_NAME_WITH_ID, device_name, 131 IDS_DEVICE_CHOOSER_DEVICE_NAME_WITH_ID, device_name,
124 devices_[index].first->serial_number()); 132 devices_[index].first->serial_number());
125 } 133 }
126 134
127 bool UsbChooserController::IsPaired(size_t index) const { 135 bool UsbChooserController::IsPaired(size_t index) const {
msw 2017/03/13 23:48:51 This isn't really a blocker, but it would be nice
Reilly Grant (use Gerrit) 2017/03/14 20:44:11 Done. It is safe for WebUSBPermissionProvider to c
128 return WebUSBPermissionProvider::HasDevicePermission(render_frame_host_, 136 scoped_refptr<UsbDevice> device = devices_[index].first;
129 devices_[index].first); 137
138 if (UsbBlocklist::Get().IsExcluded(device))
139 return false;
140
141 if (!chooser_context_)
142 return false;
143
144 if (!chooser_context_->HasDevicePermission(requesting_origin_,
145 embedding_origin_, device)) {
146 return false;
147 }
148
149 // On Android it is not possible to read the WebUSB descriptors until Chrome
150 // has been granted permission to open it. Instead we grant provisional access
151 // to the device and perform the allowed origins check when the client tries
152 // to open it.
153 if (!device->permission_granted())
154 return true;
155
156 // Embedded frames must have their origin in the list provided by the device.
157 if (embedded_frame_) {
158 return device::FindInWebUsbAllowedOrigins(device->webusb_allowed_origins(),
msw 2017/03/13 23:48:51 aside: too bad FindInWebUsbAllowedOrigins and Find
Reilly Grant (use Gerrit) 2017/03/14 20:44:11 Done.
159 requesting_origin_);
160 }
161
162 return true;
130 } 163 }
131 164
132 void UsbChooserController::RefreshOptions() {} 165 void UsbChooserController::RefreshOptions() {}
133 166
134 base::string16 UsbChooserController::GetStatus() const { 167 base::string16 UsbChooserController::GetStatus() const {
135 return base::string16(); 168 return base::string16();
136 } 169 }
137 170
138 void UsbChooserController::Select(const std::vector<size_t>& indices) { 171 void UsbChooserController::Select(const std::vector<size_t>& indices) {
139 DCHECK_EQ(1u, indices.size()); 172 DCHECK_EQ(1u, indices.size());
140 size_t index = indices[0]; 173 size_t index = indices[0];
141 DCHECK_LT(index, devices_.size()); 174 DCHECK_LT(index, devices_.size());
142 WebContents* web_contents = 175
143 WebContents::FromRenderFrameHost(render_frame_host_); 176 if (chooser_context_) {
144 GURL embedding_origin = 177 chooser_context_->GrantDevicePermission(
145 web_contents->GetMainFrame()->GetLastCommittedURL().GetOrigin(); 178 requesting_origin_, embedding_origin_, devices_[index].first->guid());
146 Profile* profile = 179 }
147 Profile::FromBrowserContext(web_contents->GetBrowserContext());
148 UsbChooserContext* chooser_context =
149 UsbChooserContextFactory::GetForProfile(profile);
150 chooser_context->GrantDevicePermission(
151 render_frame_host_->GetLastCommittedURL().GetOrigin(), embedding_origin,
152 devices_[index].first->guid());
153 180
154 device::usb::DeviceInfoPtr device_info_ptr = 181 device::usb::DeviceInfoPtr device_info_ptr =
155 device::usb::DeviceInfo::From(*devices_[index].first); 182 device::usb::DeviceInfo::From(*devices_[index].first);
156 callback_.Run(std::move(device_info_ptr)); 183 callback_.Run(std::move(device_info_ptr));
157 callback_.Reset(); // Reset |callback_| so that it is only run once. 184 callback_.Reset(); // Reset |callback_| so that it is only run once.
158 185
159 RecordWebUsbChooserClosure( 186 RecordWebUsbChooserClosure(
160 devices_[index].first->serial_number().empty() 187 devices_[index].first->serial_number().empty()
161 ? WEBUSB_CHOOSER_CLOSED_EPHEMERAL_PERMISSION_GRANTED 188 ? WEBUSB_CHOOSER_CLOSED_EPHEMERAL_PERMISSION_GRANTED
162 : WEBUSB_CHOOSER_CLOSED_PERMISSION_GRANTED); 189 : WEBUSB_CHOOSER_CLOSED_PERMISSION_GRANTED);
163 } 190 }
164 191
165 void UsbChooserController::Cancel() { 192 void UsbChooserController::Cancel() {
166 RecordWebUsbChooserClosure(devices_.size() == 0 193 RecordWebUsbChooserClosure(devices_.size() == 0
167 ? WEBUSB_CHOOSER_CLOSED_CANCELLED_NO_DEVICES 194 ? WEBUSB_CHOOSER_CLOSED_CANCELLED_NO_DEVICES
168 : WEBUSB_CHOOSER_CLOSED_CANCELLED); 195 : WEBUSB_CHOOSER_CLOSED_CANCELLED);
169 } 196 }
170 197
171 void UsbChooserController::Close() {} 198 void UsbChooserController::Close() {}
172 199
173 void UsbChooserController::OpenHelpCenterUrl() const { 200 void UsbChooserController::OpenHelpCenterUrl() const {
174 GetBrowser()->OpenURL(content::OpenURLParams( 201 GetBrowser()->OpenURL(content::OpenURLParams(
175 GURL(chrome::kChooserUsbOverviewURL), content::Referrer(), 202 GURL(chrome::kChooserUsbOverviewURL), content::Referrer(),
176 WindowOpenDisposition::NEW_FOREGROUND_TAB, 203 WindowOpenDisposition::NEW_FOREGROUND_TAB,
177 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false /* is_renderer_initialized */)); 204 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false /* is_renderer_initialized */));
178 } 205 }
179 206
180 void UsbChooserController::OnDeviceAdded( 207 void UsbChooserController::OnDeviceAdded(scoped_refptr<UsbDevice> device) {
181 scoped_refptr<device::UsbDevice> device) {
182 if (DisplayDevice(device)) { 208 if (DisplayDevice(device)) {
183 base::string16 device_name = GetDeviceName(device); 209 base::string16 device_name = GetDeviceName(device);
184 devices_.push_back(std::make_pair(device, device_name)); 210 devices_.push_back(std::make_pair(device, device_name));
185 ++device_name_map_[device_name]; 211 ++device_name_map_[device_name];
186 if (view()) 212 if (view())
187 view()->OnOptionAdded(devices_.size() - 1); 213 view()->OnOptionAdded(devices_.size() - 1);
188 } 214 }
189 } 215 }
190 216
191 void UsbChooserController::OnDeviceRemoved( 217 void UsbChooserController::OnDeviceRemoved(scoped_refptr<UsbDevice> device) {
192 scoped_refptr<device::UsbDevice> device) {
193 for (auto it = devices_.begin(); it != devices_.end(); ++it) { 218 for (auto it = devices_.begin(); it != devices_.end(); ++it) {
194 if (it->first == device) { 219 if (it->first == device) {
195 size_t index = it - devices_.begin(); 220 size_t index = it - devices_.begin();
196 DCHECK_GT(device_name_map_[it->second], 0); 221 DCHECK_GT(device_name_map_[it->second], 0);
197 if (--device_name_map_[it->second] == 0) 222 if (--device_name_map_[it->second] == 0)
198 device_name_map_.erase(it->second); 223 device_name_map_.erase(it->second);
199 devices_.erase(it); 224 devices_.erase(it);
200 if (view()) 225 if (view())
201 view()->OnOptionRemoved(index); 226 view()->OnOptionRemoved(index);
202 return; 227 return;
203 } 228 }
204 } 229 }
205 } 230 }
206 231
207 // Get a list of devices that can be shown in the chooser bubble UI for 232 // Get a list of devices that can be shown in the chooser bubble UI for
208 // user to grant permsssion. 233 // user to grant permsssion.
209 void UsbChooserController::GotUsbDeviceList( 234 void UsbChooserController::GotUsbDeviceList(
210 const std::vector<scoped_refptr<device::UsbDevice>>& devices) { 235 const std::vector<scoped_refptr<UsbDevice>>& devices) {
211 for (const auto& device : devices) { 236 for (const auto& device : devices) {
212 if (DisplayDevice(device)) { 237 if (DisplayDevice(device)) {
213 base::string16 device_name = GetDeviceName(device); 238 base::string16 device_name = GetDeviceName(device);
214 devices_.push_back(std::make_pair(device, device_name)); 239 devices_.push_back(std::make_pair(device, device_name));
215 ++device_name_map_[device_name]; 240 ++device_name_map_[device_name];
216 } 241 }
217 } 242 }
218 if (view()) 243 if (view())
219 view()->OnOptionsInitialized(); 244 view()->OnOptionsInitialized();
220 } 245 }
221 246
222 bool UsbChooserController::DisplayDevice( 247 bool UsbChooserController::DisplayDevice(
223 scoped_refptr<device::UsbDevice> device) const { 248 scoped_refptr<UsbDevice> device) const {
224 if (!device::UsbDeviceFilter::MatchesAny(device, filters_)) 249 if (!UsbDeviceFilter::MatchesAny(device, filters_))
225 return false; 250 return false;
226 251
227 if (UsbBlocklist::Get().IsExcluded(device)) 252 if (UsbBlocklist::Get().IsExcluded(device))
228 return false; 253 return false;
229 254
230 // Embedded frames must have their origin in the list provided by the device. 255 // Embedded frames must have their origin in the list provided by the device.
231 RenderFrameHost* main_frame = 256 if (embedded_frame_) {
232 WebContents::FromRenderFrameHost(render_frame_host_)->GetMainFrame(); 257 return device::FindInWebUsbAllowedOrigins(device->webusb_allowed_origins(),
233 if (render_frame_host_ != main_frame) { 258 requesting_origin_);
234 return device::FindInWebUsbAllowedOrigins(
235 device->webusb_allowed_origins(),
236 render_frame_host_->GetLastCommittedURL().GetOrigin());
237 } 259 }
238 260
239 return true; 261 return true;
240 } 262 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698