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(IDS_DEVICE_PERMISSIONS_PROMPT_HEADING
);
62 base::string16
DevicePermissionsPrompt::Prompt::GetPromptMessage() const {
63 return l10n_util::GetStringFUTF16(multiple_
64 ? IDS_DEVICE_PERMISSIONS_PROMPT_MULTIPLE
65 : IDS_DEVICE_PERMISSIONS_PROMPT_SINGLE
,
66 base::UTF8ToUTF16(extension_
->name()));
69 scoped_refptr
<UsbDevice
> DevicePermissionsPrompt::Prompt::GetDevice(
71 DCHECK_LT(index
, devices_
.size());
72 return devices_
[index
].device
;
75 void DevicePermissionsPrompt::Prompt::GrantDevicePermission(
77 DCHECK_LT(index
, devices_
.size());
78 DevicePermissionsManager
* permissions_manager
=
79 DevicePermissionsManager::Get(browser_context_
);
80 if (permissions_manager
) {
81 const DeviceInfo
& device
= devices_
[index
];
82 permissions_manager
->AllowUsbDevice(extension_
->id(),
84 device
.product_string
,
85 device
.manufacturer_string
,
86 device
.serial_number
);
90 void DevicePermissionsPrompt::Prompt::set_filters(
91 const std::vector
<UsbDeviceFilter
>& filters
) {
95 DevicePermissionsPrompt::Prompt::~Prompt() {
98 void DevicePermissionsPrompt::Prompt::DoDeviceQuery() {
99 UsbService
* service
= device::DeviceClient::Get()->GetUsbService();
104 std::vector
<scoped_refptr
<UsbDevice
>> devices
;
105 service
->GetDevices(&devices
);
107 std::vector
<DeviceInfo
> device_info
;
108 for (const auto& device
: devices
) {
109 if (!(filters_
.empty() || UsbDeviceFilter::MatchesAny(device
, filters_
))) {
113 base::string16 manufacturer_string
;
114 base::string16 original_manufacturer_string
;
115 if (device
->GetManufacturer(&original_manufacturer_string
)) {
116 manufacturer_string
= original_manufacturer_string
;
118 const char* vendor_name
=
119 device::UsbIds::GetVendorName(device
->vendor_id());
121 manufacturer_string
= base::UTF8ToUTF16(vendor_name
);
123 base::string16 vendor_id
= base::ASCIIToUTF16(
124 base::StringPrintf("0x%04x", device
->vendor_id()));
125 manufacturer_string
=
126 l10n_util::GetStringFUTF16(IDS_DEVICE_UNKNOWN_VENDOR
, vendor_id
);
130 base::string16 product_string
;
131 base::string16 original_product_string
;
132 if (device
->GetProduct(&original_product_string
)) {
133 product_string
= original_product_string
;
135 const char* product_name
= device::UsbIds::GetProductName(
136 device
->vendor_id(), device
->product_id());
138 product_string
= base::UTF8ToUTF16(product_name
);
140 base::string16 product_id
= base::ASCIIToUTF16(
141 base::StringPrintf("0x%04x", device
->product_id()));
143 l10n_util::GetStringFUTF16(IDS_DEVICE_UNKNOWN_PRODUCT
, product_id
);
147 base::string16 serial_number
;
148 if (!device
->GetSerialNumber(&serial_number
)) {
149 serial_number
.clear();
152 device_info
.push_back(DeviceInfo(
154 l10n_util::GetStringFUTF16(IDS_DEVICE_PERMISSIONS_DEVICE_NAME
,
156 manufacturer_string
),
157 original_product_string
,
158 original_manufacturer_string
,
162 content::BrowserThread::PostTask(
163 content::BrowserThread::UI
,
166 &DevicePermissionsPrompt::Prompt::SetDevices
, this, device_info
));
169 void DevicePermissionsPrompt::Prompt::SetDevices(
170 const std::vector
<DeviceInfo
>& devices
) {
173 observer_
->OnDevicesChanged();
177 DevicePermissionsPrompt::DevicePermissionsPrompt(
178 content::WebContents
* web_contents
)
179 : web_contents_(web_contents
), delegate_(nullptr) {
182 DevicePermissionsPrompt::~DevicePermissionsPrompt() {
185 void DevicePermissionsPrompt::AskForUsbDevices(
187 const Extension
* extension
,
188 content::BrowserContext
* context
,
190 const std::vector
<UsbDeviceFilter
>& filters
) {
191 prompt_
= new Prompt();
192 prompt_
->set_extension(extension
);
193 prompt_
->set_browser_context(context
);
194 prompt_
->set_multiple(multiple
);
195 prompt_
->set_filters(filters
);
196 delegate_
= delegate
;
201 } // namespace extensions