Index: extensions/browser/api/device_permissions_prompt.cc |
diff --git a/extensions/browser/api/device_permissions_prompt.cc b/extensions/browser/api/device_permissions_prompt.cc |
index 09751b36cc84fe14e1814a71352d745fe9cbfa04..6e630456747cdadf7f98677b59d5f2cf24b95c06 100644 |
--- a/extensions/browser/api/device_permissions_prompt.cc |
+++ b/extensions/browser/api/device_permissions_prompt.cc |
@@ -4,10 +4,9 @@ |
#include "extensions/browser/api/device_permissions_prompt.h" |
-#include "base/barrier_closure.h" |
+#include "base/scoped_observer.h" |
#include "base/strings/stringprintf.h" |
#include "base/strings/utf_string_conversions.h" |
-#include "content/public/browser/browser_thread.h" |
#include "device/core/device_client.h" |
#include "device/usb/usb_device.h" |
#include "device/usb/usb_device_filter.h" |
@@ -18,49 +17,167 @@ |
#include "extensions/strings/grit/extensions_strings.h" |
#include "ui/base/l10n/l10n_util.h" |
-using content::BrowserThread; |
using device::UsbDevice; |
using device::UsbDeviceFilter; |
using device::UsbService; |
namespace extensions { |
-DevicePermissionsPrompt::Delegate::~Delegate() { |
-} |
+namespace { |
+ |
+class UsbDeviceInfo : public DevicePermissionsPrompt::Prompt::DeviceInfo { |
+ public: |
+ UsbDeviceInfo(scoped_refptr<UsbDevice> device) : device_(device) { |
+ base::string16 manufacturer_string = device->manufacturer_string(); |
+ if (manufacturer_string.empty()) { |
+ const char* vendor_name = |
+ device::UsbIds::GetVendorName(device->vendor_id()); |
+ if (vendor_name) { |
+ manufacturer_string = base::UTF8ToUTF16(vendor_name); |
+ } else { |
+ base::string16 vendor_id = base::ASCIIToUTF16( |
+ base::StringPrintf("0x%04x", device->vendor_id())); |
+ manufacturer_string = |
+ l10n_util::GetStringFUTF16(IDS_DEVICE_UNKNOWN_VENDOR, vendor_id); |
+ } |
+ } |
+ |
+ base::string16 product_string = device->product_string(); |
+ if (product_string.empty()) { |
+ const char* product_name = device::UsbIds::GetProductName( |
+ device->vendor_id(), device->product_id()); |
+ if (product_name) { |
+ product_string = base::UTF8ToUTF16(product_name); |
+ } else { |
+ base::string16 product_id = base::ASCIIToUTF16( |
+ base::StringPrintf("0x%04x", device->product_id())); |
+ product_string = |
+ l10n_util::GetStringFUTF16(IDS_DEVICE_UNKNOWN_PRODUCT, product_id); |
+ } |
+ } |
+ |
+ name_ = l10n_util::GetStringFUTF16(IDS_DEVICE_PERMISSIONS_DEVICE_NAME, |
+ product_string, manufacturer_string); |
+ serial_number_ = device->serial_number(); |
+ } |
+ |
+ ~UsbDeviceInfo() override {} |
+ |
+ const scoped_refptr<UsbDevice>& device() const { return device_; } |
+ |
+ private: |
+ // TODO(reillyg): Convert this to a weak reference when UsbDevice has a |
+ // connected flag. |
+ scoped_refptr<UsbDevice> device_; |
+}; |
+ |
+class UsbDevicePermissionsPrompt : public DevicePermissionsPrompt::Prompt, |
+ public device::UsbService::Observer { |
+ public: |
+ UsbDevicePermissionsPrompt( |
+ const Extension* extension, |
+ content::BrowserContext* context, |
+ bool multiple, |
+ const std::vector<device::UsbDeviceFilter>& filters, |
+ const DevicePermissionsPrompt::UsbDevicesCallback& callback) |
+ : Prompt(extension, context, multiple), |
+ filters_(filters), |
+ callback_(callback), |
+ service_observer_(this) {} |
+ |
+ private: |
+ ~UsbDevicePermissionsPrompt() override {} |
+ |
+ // DevicePermissionsPrompt::Prompt implementation: |
+ void SetObserver( |
+ DevicePermissionsPrompt::Prompt::Observer* observer) override { |
+ DevicePermissionsPrompt::Prompt::SetObserver(observer); |
+ |
+ if (observer) { |
+ UsbService* service = device::DeviceClient::Get()->GetUsbService(); |
+ if (service && !service_observer_.IsObserving(service)) { |
+ service->GetDevices( |
+ base::Bind(&UsbDevicePermissionsPrompt::OnDevicesEnumerated, this)); |
+ service_observer_.Add(service); |
+ } |
+ } |
+ } |
+ |
+ base::string16 GetHeading() const override { |
+ return l10n_util::GetStringUTF16( |
+ multiple() ? IDS_USB_DEVICE_PERMISSIONS_PROMPT_TITLE_MULTIPLE |
+ : IDS_USB_DEVICE_PERMISSIONS_PROMPT_TITLE_SINGLE); |
+ } |
+ |
+ void Dismissed() override { |
+ DevicePermissionsManager* permissions_manager = |
+ DevicePermissionsManager::Get(browser_context()); |
+ std::vector<scoped_refptr<UsbDevice>> devices; |
+ for (const DeviceInfo* device : devices_) { |
+ if (device->granted()) { |
+ const UsbDeviceInfo* usb_device = |
+ static_cast<const UsbDeviceInfo*>(device); |
+ devices.push_back(usb_device->device()); |
+ if (permissions_manager) { |
+ permissions_manager->AllowUsbDevice(extension()->id(), |
+ usb_device->device()); |
+ } |
+ } |
+ } |
+ DCHECK(multiple() || devices.size() <= 1); |
+ callback_.Run(devices); |
+ callback_.Reset(); |
+ } |
+ |
+ // device::UsbService::Observer implementation: |
+ void OnDeviceAdded(scoped_refptr<UsbDevice> device) override { |
+ if (!(filters_.empty() || UsbDeviceFilter::MatchesAny(device, filters_))) { |
+ return; |
+ } |
+ |
+ device->CheckUsbAccess(base::Bind( |
+ &UsbDevicePermissionsPrompt::AddCheckedDevice, this, device)); |
+ } |
-DevicePermissionsPrompt::Prompt::DeviceInfo::DeviceInfo( |
- scoped_refptr<UsbDevice> device) |
- : device(device) { |
- base::string16 manufacturer_string = device->manufacturer_string(); |
- if (manufacturer_string.empty()) { |
- const char* vendor_name = |
- device::UsbIds::GetVendorName(device->vendor_id()); |
- if (vendor_name) { |
- manufacturer_string = base::UTF8ToUTF16(vendor_name); |
- } else { |
- base::string16 vendor_id = |
- base::ASCIIToUTF16(base::StringPrintf("0x%04x", device->vendor_id())); |
- manufacturer_string = |
- l10n_util::GetStringFUTF16(IDS_DEVICE_UNKNOWN_VENDOR, vendor_id); |
+ void OnDeviceRemoved(scoped_refptr<UsbDevice> device) override { |
+ for (auto it = devices_.begin(); it != devices_.end(); ++it) { |
+ const UsbDeviceInfo* entry = static_cast<const UsbDeviceInfo*>(*it); |
+ if (entry->device() == device) { |
+ devices_.erase(it); |
+ if (observer()) { |
+ observer()->OnDevicesChanged(); |
+ } |
+ return; |
+ } |
} |
} |
- base::string16 product_string = device->product_string(); |
- if (product_string.empty()) { |
- const char* product_name = device::UsbIds::GetProductName( |
- device->vendor_id(), device->product_id()); |
- if (product_name) { |
- product_string = base::UTF8ToUTF16(product_name); |
- } else { |
- base::string16 product_id = base::ASCIIToUTF16( |
- base::StringPrintf("0x%04x", device->product_id())); |
- product_string = |
- l10n_util::GetStringFUTF16(IDS_DEVICE_UNKNOWN_PRODUCT, product_id); |
+ void OnDevicesEnumerated( |
+ const std::vector<scoped_refptr<UsbDevice>>& devices) { |
+ for (const auto& device : devices) { |
+ OnDeviceAdded(device); |
} |
} |
- name = l10n_util::GetStringFUTF16(IDS_DEVICE_PERMISSIONS_DEVICE_NAME, |
- product_string, manufacturer_string); |
+ void AddCheckedDevice(scoped_refptr<UsbDevice> device, bool allowed) { |
+ if (allowed) { |
+ // TODO(reillyg): This method could be called after OnDeviceRemoved. We |
+ // should check that the device is still connected. |
+ devices_.push_back(new UsbDeviceInfo(device)); |
+ if (observer()) { |
+ observer()->OnDevicesChanged(); |
+ } |
+ } |
+ } |
+ |
+ std::vector<UsbDeviceFilter> filters_; |
+ DevicePermissionsPrompt::UsbDevicesCallback callback_; |
+ ScopedObserver<UsbService, UsbService::Observer> service_observer_; |
+}; |
+ |
+} // namespace |
+ |
+DevicePermissionsPrompt::Prompt::DeviceInfo::DeviceInfo() { |
} |
DevicePermissionsPrompt::Prompt::DeviceInfo::~DeviceInfo() { |
@@ -69,32 +186,14 @@ DevicePermissionsPrompt::Prompt::DeviceInfo::~DeviceInfo() { |
DevicePermissionsPrompt::Prompt::Observer::~Observer() { |
} |
-DevicePermissionsPrompt::Prompt::Prompt(Delegate* delegate, |
- const Extension* extension, |
- content::BrowserContext* context) |
- : extension_(extension), |
- browser_context_(context), |
- delegate_(delegate), |
- usb_service_observer_(this) { |
+DevicePermissionsPrompt::Prompt::Prompt(const Extension* extension, |
+ content::BrowserContext* context, |
+ bool multiple) |
+ : extension_(extension), browser_context_(context), multiple_(multiple) { |
} |
void DevicePermissionsPrompt::Prompt::SetObserver(Observer* observer) { |
observer_ = observer; |
- |
- if (observer_) { |
- UsbService* service = device::DeviceClient::Get()->GetUsbService(); |
- if (service && !usb_service_observer_.IsObserving(service)) { |
- service->GetDevices(base::Bind( |
- &DevicePermissionsPrompt::Prompt::OnDevicesEnumerated, this)); |
- usb_service_observer_.Add(service); |
- } |
- } |
-} |
- |
-base::string16 DevicePermissionsPrompt::Prompt::GetHeading() const { |
- return l10n_util::GetStringUTF16( |
- multiple_ ? IDS_DEVICE_PERMISSIONS_PROMPT_TITLE_MULTIPLE |
- : IDS_DEVICE_PERMISSIONS_PROMPT_TITLE_SINGLE); |
} |
base::string16 DevicePermissionsPrompt::Prompt::GetPromptMessage() const { |
@@ -107,90 +206,23 @@ base::string16 DevicePermissionsPrompt::Prompt::GetPromptMessage() const { |
base::string16 DevicePermissionsPrompt::Prompt::GetDeviceName( |
size_t index) const { |
DCHECK_LT(index, devices_.size()); |
- return devices_[index].name; |
+ return devices_[index]->name(); |
} |
base::string16 DevicePermissionsPrompt::Prompt::GetDeviceSerialNumber( |
size_t index) const { |
DCHECK_LT(index, devices_.size()); |
- return devices_[index].device->serial_number(); |
+ return devices_[index]->serial_number(); |
} |
void DevicePermissionsPrompt::Prompt::GrantDevicePermission(size_t index) { |
DCHECK_LT(index, devices_.size()); |
- devices_[index].granted = true; |
-} |
- |
-void DevicePermissionsPrompt::Prompt::Dismissed() { |
- DevicePermissionsManager* permissions_manager = |
- DevicePermissionsManager::Get(browser_context_); |
- std::vector<scoped_refptr<UsbDevice>> devices; |
- for (const DeviceInfo& device : devices_) { |
- if (device.granted) { |
- devices.push_back(device.device); |
- if (permissions_manager) { |
- permissions_manager->AllowUsbDevice(extension_->id(), device.device); |
- } |
- } |
- } |
- delegate_->OnUsbDevicesChosen(devices); |
-} |
- |
-void DevicePermissionsPrompt::Prompt::set_filters( |
- const std::vector<UsbDeviceFilter>& filters) { |
- filters_ = filters; |
+ devices_[index]->set_granted(); |
} |
DevicePermissionsPrompt::Prompt::~Prompt() { |
} |
-void DevicePermissionsPrompt::Prompt::OnDeviceAdded( |
- scoped_refptr<UsbDevice> device) { |
- if (!(filters_.empty() || UsbDeviceFilter::MatchesAny(device, filters_))) { |
- return; |
- } |
- |
- device->CheckUsbAccess(base::Bind( |
- &DevicePermissionsPrompt::Prompt::AddCheckedUsbDevice, this, device)); |
-} |
- |
-void DevicePermissionsPrompt::Prompt::OnDeviceRemoved( |
- scoped_refptr<UsbDevice> device) { |
- bool removed_entry = false; |
- for (std::vector<DeviceInfo>::iterator it = devices_.begin(); |
- it != devices_.end(); ++it) { |
- if (it->device == device) { |
- devices_.erase(it); |
- removed_entry = true; |
- break; |
- } |
- } |
- if (observer_ && removed_entry) { |
- observer_->OnDevicesChanged(); |
- } |
-} |
- |
-void DevicePermissionsPrompt::Prompt::OnDevicesEnumerated( |
- const std::vector<scoped_refptr<UsbDevice>>& devices) { |
- for (const auto& device : devices) { |
- if (filters_.empty() || UsbDeviceFilter::MatchesAny(device, filters_)) { |
- device->CheckUsbAccess(base::Bind( |
- &DevicePermissionsPrompt::Prompt::AddCheckedUsbDevice, this, device)); |
- } |
- } |
-} |
- |
-void DevicePermissionsPrompt::Prompt::AddCheckedUsbDevice( |
- scoped_refptr<UsbDevice> device, |
- bool allowed) { |
- if (allowed) { |
- devices_.push_back(DeviceInfo(device)); |
- if (observer_) { |
- observer_->OnDevicesChanged(); |
- } |
- } |
-} |
- |
DevicePermissionsPrompt::DevicePermissionsPrompt( |
content::WebContents* web_contents) |
: web_contents_(web_contents) { |
@@ -200,15 +232,13 @@ DevicePermissionsPrompt::~DevicePermissionsPrompt() { |
} |
void DevicePermissionsPrompt::AskForUsbDevices( |
- Delegate* delegate, |
const Extension* extension, |
content::BrowserContext* context, |
bool multiple, |
- const std::vector<UsbDeviceFilter>& filters) { |
- prompt_ = new Prompt(delegate, extension, context); |
- prompt_->set_multiple(multiple); |
- prompt_->set_filters(filters); |
- |
+ const std::vector<UsbDeviceFilter>& filters, |
+ const UsbDevicesCallback& callback) { |
+ prompt_ = new UsbDevicePermissionsPrompt(extension, context, multiple, |
+ filters, callback); |
ShowDialog(); |
} |