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
3 // found in the LICENSE file.
5 #include "extensions/browser/api/device_permissions_prompt.h"
7 #include "base/strings/stringprintf.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "device/core/device_client.h"
11 #include "device/usb/usb_device.h"
12 #include "device/usb/usb_device_filter.h"
13 #include "device/usb/usb_ids.h"
14 #include "device/usb/usb_service.h"
15 #include "extensions/browser/api/device_permissions_manager.h"
16 #include "extensions/common/extension.h"
17 #include "extensions/strings/grit/extensions_strings.h"
18 #include "ui/base/l10n/l10n_util.h"
20 namespace extensions
{
22 using device::UsbDevice
;
23 using device::UsbDeviceFilter
;
24 using device::UsbService
;
26 DevicePermissionsPrompt::Prompt::DeviceInfo::DeviceInfo(
27 scoped_refptr
<UsbDevice
> device
,
28 const base::string16
& name
,
29 const base::string16
& product_string
,
30 const base::string16
& manufacturer_string
,
31 const base::string16
& serial_number
)
34 product_string(product_string
),
35 manufacturer_string(manufacturer_string
),
36 serial_number(serial_number
) {
39 DevicePermissionsPrompt::Prompt::DeviceInfo::~DeviceInfo() {
42 DevicePermissionsPrompt::Prompt::Prompt()
43 : extension_(nullptr),
44 browser_context_(nullptr),
49 void DevicePermissionsPrompt::Prompt::SetObserver(Observer
* observer
) {
52 content::BrowserThread::PostTask(
53 content::BrowserThread::FILE,
55 base::Bind(&DevicePermissionsPrompt::Prompt::DoDeviceQuery
, this));
58 base::string16
DevicePermissionsPrompt::Prompt::GetHeading() const {
59 return l10n_util::GetStringUTF16(
60 multiple_
? IDS_DEVICE_PERMISSIONS_PROMPT_TITLE_MULTIPLE
61 : IDS_DEVICE_PERMISSIONS_PROMPT_TITLE_SINGLE
);
64 base::string16
DevicePermissionsPrompt::Prompt::GetPromptMessage() const {
65 return l10n_util::GetStringFUTF16(multiple_
66 ? IDS_DEVICE_PERMISSIONS_PROMPT_MULTIPLE
67 : IDS_DEVICE_PERMISSIONS_PROMPT_SINGLE
,
68 base::UTF8ToUTF16(extension_
->name()));
71 scoped_refptr
<UsbDevice
> DevicePermissionsPrompt::Prompt::GetDevice(
73 DCHECK_LT(index
, devices_
.size());
74 return devices_
[index
].device
;
77 void DevicePermissionsPrompt::Prompt::GrantDevicePermission(
79 DCHECK_LT(index
, devices_
.size());
80 DevicePermissionsManager
* permissions_manager
=
81 DevicePermissionsManager::Get(browser_context_
);
82 if (permissions_manager
) {
83 const DeviceInfo
& device
= devices_
[index
];
84 permissions_manager
->AllowUsbDevice(extension_
->id(),
86 device
.product_string
,
87 device
.manufacturer_string
,
88 device
.serial_number
);
92 void DevicePermissionsPrompt::Prompt::set_filters(
93 const std::vector
<UsbDeviceFilter
>& filters
) {
97 DevicePermissionsPrompt::Prompt::~Prompt() {
100 void DevicePermissionsPrompt::Prompt::DoDeviceQuery() {
101 UsbService
* service
= device::DeviceClient::Get()->GetUsbService();
106 std::vector
<scoped_refptr
<UsbDevice
>> devices
;
107 service
->GetDevices(&devices
);
109 std::vector
<DeviceInfo
> device_info
;
110 for (const auto& device
: devices
) {
111 if (!(filters_
.empty() || UsbDeviceFilter::MatchesAny(device
, filters_
))) {
115 base::string16 manufacturer_string
;
116 base::string16 original_manufacturer_string
;
117 if (device
->GetManufacturer(&original_manufacturer_string
)) {
118 manufacturer_string
= original_manufacturer_string
;
120 const char* vendor_name
=
121 device::UsbIds::GetVendorName(device
->vendor_id());
123 manufacturer_string
= base::UTF8ToUTF16(vendor_name
);
125 base::string16 vendor_id
= base::ASCIIToUTF16(
126 base::StringPrintf("0x%04x", device
->vendor_id()));
127 manufacturer_string
=
128 l10n_util::GetStringFUTF16(IDS_DEVICE_UNKNOWN_VENDOR
, vendor_id
);
132 base::string16 product_string
;
133 base::string16 original_product_string
;
134 if (device
->GetProduct(&original_product_string
)) {
135 product_string
= original_product_string
;
137 const char* product_name
= device::UsbIds::GetProductName(
138 device
->vendor_id(), device
->product_id());
140 product_string
= base::UTF8ToUTF16(product_name
);
142 base::string16 product_id
= base::ASCIIToUTF16(
143 base::StringPrintf("0x%04x", device
->product_id()));
145 l10n_util::GetStringFUTF16(IDS_DEVICE_UNKNOWN_PRODUCT
, product_id
);
149 base::string16 serial_number
;
150 if (!device
->GetSerialNumber(&serial_number
)) {
151 serial_number
.clear();
154 device_info
.push_back(DeviceInfo(
156 l10n_util::GetStringFUTF16(IDS_DEVICE_PERMISSIONS_DEVICE_NAME
,
158 manufacturer_string
),
159 original_product_string
,
160 original_manufacturer_string
,
164 content::BrowserThread::PostTask(
165 content::BrowserThread::UI
,
168 &DevicePermissionsPrompt::Prompt::SetDevices
, this, device_info
));
171 void DevicePermissionsPrompt::Prompt::SetDevices(
172 const std::vector
<DeviceInfo
>& devices
) {
175 observer_
->OnDevicesChanged();
179 DevicePermissionsPrompt::DevicePermissionsPrompt(
180 content::WebContents
* web_contents
)
181 : web_contents_(web_contents
), delegate_(nullptr) {
184 DevicePermissionsPrompt::~DevicePermissionsPrompt() {
187 void DevicePermissionsPrompt::AskForUsbDevices(
189 const Extension
* extension
,
190 content::BrowserContext
* context
,
192 const std::vector
<UsbDeviceFilter
>& filters
) {
193 prompt_
= new Prompt();
194 prompt_
->set_extension(extension
);
195 prompt_
->set_browser_context(context
);
196 prompt_
->set_multiple(multiple
);
197 prompt_
->set_filters(filters
);
198 delegate_
= delegate
;
203 } // namespace extensions