Atomic: Notify Watcher to observe device fd
[chromium-blink-merge.git] / extensions / common / permissions / usb_device_permission.cc
blob59b28d564f40f53aa52a54485a0b550b573e0f49
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/common/permissions/usb_device_permission.h"
7 #include <set>
8 #include <string>
10 #include "base/logging.h"
11 #include "base/strings/string16.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "device/usb/usb_ids.h"
16 #include "extensions/common/permissions/permissions_info.h"
17 #include "grit/extensions_strings.h"
18 #include "ui/base/l10n/l10n_util.h"
20 namespace extensions {
22 namespace {
24 // Adds the permissions from the |data_set| to the permission lists that are
25 // not NULL. If NULL, that list is ignored.
26 void AddPermissionsToLists(const std::set<UsbDevicePermissionData>& data_set,
27 PermissionIDSet* ids,
28 PermissionMessages* messages) {
29 // TODO(sashab): Once GetMessages() is deprecated, move this logic back into
30 // GetPermissions().
31 // TODO(sashab, reillyg): Once GetMessages() is deprecated, rework the
32 // permission message logic for USB devices to generate more meaningful
33 // messages and better fit the current rules system.
34 if (data_set.size() == 1) {
35 const UsbDevicePermissionData& data = *data_set.begin();
37 const char* vendor = device::UsbIds::GetVendorName(data.vendor_id());
38 if (vendor) {
39 const char* product =
40 device::UsbIds::GetProductName(data.vendor_id(), data.product_id());
41 if (product) {
42 base::string16 product_name_and_vendor = l10n_util::GetStringFUTF16(
43 IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_PRODUCT_NAME_AND_VENDOR,
44 base::UTF8ToUTF16(product), base::UTF8ToUTF16(vendor));
46 if (messages) {
47 messages->push_back(
48 PermissionMessage(PermissionMessage::kUsbDevice,
49 l10n_util::GetStringFUTF16(
50 IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE,
51 product_name_and_vendor)));
53 if (ids)
54 ids->insert(APIPermission::kUsbDevice, product_name_and_vendor);
55 } else {
56 if (messages) {
57 messages->push_back(PermissionMessage(
58 PermissionMessage::kUsbDevice,
59 l10n_util::GetStringFUTF16(
60 IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_UNKNOWN_PRODUCT,
61 base::UTF8ToUTF16(vendor))));
63 if (ids) {
64 ids->insert(APIPermission::kUsbDeviceUnknownProduct,
65 base::UTF8ToUTF16(vendor));
68 } else {
69 if (messages) {
70 messages->push_back(PermissionMessage(
71 PermissionMessage::kUsbDevice,
72 l10n_util::GetStringUTF16(
73 IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_UNKNOWN_VENDOR)));
75 if (ids) {
76 ids->insert(APIPermission::kUsbDeviceUnknownVendor);
79 } else if (data_set.size() > 1) {
80 std::vector<base::string16> details;
81 std::set<uint16> unknown_product_vendors;
82 bool found_unknown_vendor = false;
84 for (const UsbDevicePermissionData& data : data_set) {
85 const char* vendor = device::UsbIds::GetVendorName(data.vendor_id());
86 if (vendor) {
87 const char* product =
88 device::UsbIds::GetProductName(data.vendor_id(), data.product_id());
89 if (product) {
90 base::string16 product_name_and_vendor = l10n_util::GetStringFUTF16(
91 IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_PRODUCT_NAME_AND_VENDOR,
92 base::UTF8ToUTF16(product), base::UTF8ToUTF16(vendor));
93 details.push_back(l10n_util::GetStringFUTF16(
94 IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_LIST_ITEM,
95 product_name_and_vendor));
96 } else {
97 unknown_product_vendors.insert(data.vendor_id());
99 } else {
100 found_unknown_vendor = true;
104 // List generic "devices from this vendor" entries after specific devices.
105 for (const uint16& vendor_id : unknown_product_vendors) {
106 const char* vendor = device::UsbIds::GetVendorName(vendor_id);
107 DCHECK(vendor);
108 details.push_back(l10n_util::GetStringFUTF16(
109 IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_LIST_ITEM_UNKNOWN_PRODUCT,
110 base::UTF8ToUTF16(vendor)));
113 // Display the catch all "device from an unknown vendor" last.
114 if (found_unknown_vendor) {
115 details.push_back(l10n_util::GetStringUTF16(
116 IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_LIST_ITEM_UNKNOWN_VENDOR));
119 if (messages) {
120 messages->push_back(PermissionMessage(
121 PermissionMessage::kUsbDevice,
122 l10n_util::GetStringUTF16(
123 IDS_EXTENSION_PROMPT_WARNING_USB_DEVICE_LIST),
124 base::JoinString(details, base::ASCIIToUTF16("\n"))));
126 if (ids) {
127 for (const auto& detail : details)
128 ids->insert(APIPermission::kUsbDeviceList, detail);
133 } // namespace
135 UsbDevicePermission::UsbDevicePermission(const APIPermissionInfo* info)
136 : SetDisjunctionPermission<UsbDevicePermissionData, UsbDevicePermission>(
137 info) {
140 UsbDevicePermission::~UsbDevicePermission() {
143 PermissionIDSet UsbDevicePermission::GetPermissions() const {
144 PermissionIDSet ids;
145 AddPermissionsToLists(data_set_, &ids, NULL);
146 return ids;
149 PermissionMessages UsbDevicePermission::GetMessages() const {
150 DCHECK(HasMessages());
151 PermissionMessages messages;
152 AddPermissionsToLists(data_set_, NULL, &messages);
153 return messages;
156 } // namespace extensions