Chromium Code Reviews| Index: chrome/browser/extensions/api/api_resource_controller.cc |
| diff --git a/chrome/browser/extensions/api/api_resource_controller.cc b/chrome/browser/extensions/api/api_resource_controller.cc |
| index 28d7e7443ed8694973af3429f96c0a2e3a9dac6d..ed7677b610b362886cb18ce33a2bd3eb93bc542e 100644 |
| --- a/chrome/browser/extensions/api/api_resource_controller.cc |
| +++ b/chrome/browser/extensions/api/api_resource_controller.cc |
| @@ -6,26 +6,60 @@ |
| #include "chrome/browser/extensions/api/serial/serial_connection.h" |
| #include "chrome/browser/extensions/api/socket/socket.h" |
| #include "chrome/browser/extensions/api/usb/usb_device_resource.h" |
| +#include "content/public/browser/browser_thread.h" |
| -namespace extensions { |
| +using content::BrowserThread; |
| -APIResourceController::APIResourceController() : next_api_resource_id_(1) {} |
| +namespace extensions { |
| -APIResourceController::~APIResourceController() {} |
| +APIResourceController::APIResourceController() |
| + : next_api_resource_id_(1), |
| + socket_resource_map_(new APIResourceMap), |
| + serial_connection_resource_map_(new APIResourceMap), |
| + usb_device_resource_map_(new APIResourceMap) {} |
| + |
| +APIResourceController::~APIResourceController() { |
| + // If this check failed, then a unit test was using an APIResource but |
| + // didn't provide the IO/FILE thread message loops needed for those resources |
| + // to do their job (including destroying themselves at shutdown). |
| + DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::IO)); |
| + DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::FILE)); |
| + |
| + BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, |
| + socket_resource_map_); |
| + BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, |
| + serial_connection_resource_map_); |
| + BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, |
| + usb_device_resource_map_); |
| +} |
| -APIResource* APIResourceController::GetAPIResource(int api_resource_id) const { |
| - // TODO(miket): verify that the extension asking for the APIResource is the |
| - // same one that created it. |
| - APIResourceMap::const_iterator i = api_resource_map_.find(api_resource_id); |
| - if (i != api_resource_map_.end()) |
| - return i->second.get(); |
| - return NULL; |
| +APIResourceController::APIResourceMap* |
| +APIResourceController::GetResourceMapForType( |
| + APIResource::APIResourceType api_resource_type) const { |
| + switch (api_resource_type) { |
| + case APIResource::SocketResource: |
| + return socket_resource_map_; |
| + case APIResource::SerialConnectionResource: |
| + return serial_connection_resource_map_; |
| + case APIResource::UsbDeviceResource: |
| + return usb_device_resource_map_; |
| + default: |
| + NOTREACHED(); |
| + return NULL; |
| + } |
| } |
| APIResource* APIResourceController::GetAPIResource( |
| APIResource::APIResourceType api_resource_type, |
| int api_resource_id) const { |
| - APIResource* resource = GetAPIResource(api_resource_id); |
| + // TODO(miket): verify that the extension asking for the APIResource is the |
| + // same one that created it. |
|
asargent_no_longer_on_chrome
2012/05/24 22:43:03
Please create a bug for this so we don't forget to
miket_OOO
2012/05/24 23:44:43
https://code.google.com/p/chromium/issues/detail?i
|
| + APIResourceMap* map = GetResourceMapForType(api_resource_type); |
| + APIResourceMap::const_iterator i = map->find(api_resource_id); |
| + if (i == map->end()) |
| + return NULL; |
| + |
| + APIResource* resource = i->second.get(); |
| // This DCHECK is going to catch some legitimate application-developer |
| // errors, where someone asks for resource of Type A with the wrong ID that |
| @@ -43,45 +77,64 @@ APIResource* APIResourceController::GetAPIResource( |
| } |
| int APIResourceController::AddAPIResource(APIResource* api_resource) { |
|
asargent_no_longer_on_chrome
2012/05/24 22:43:03
Since the Get* functions must be called on particu
miket_OOO
2012/05/24 23:44:43
Done.
|
| + APIResourceMap* map = GetResourceMapForType( |
| + api_resource->api_resource_type()); |
| int id = GenerateAPIResourceId(); |
| if (id > 0) { |
| linked_ptr<APIResource> resource_ptr(api_resource); |
| - api_resource_map_[id] = resource_ptr; |
| + (*map)[id] = resource_ptr; |
| return id; |
| } |
| return 0; |
| } |
| -bool APIResourceController::RemoveAPIResource(int api_resource_id) { |
| - APIResource* api_resource = GetAPIResource(api_resource_id); |
| +bool APIResourceController::RemoveAPIResource( |
| + APIResource::APIResourceType api_resource_type, int api_resource_id) { |
| + APIResource* api_resource = GetAPIResource(api_resource_type, |
| + api_resource_id); |
| if (!api_resource) |
| return false; |
| - api_resource_map_.erase(api_resource_id); |
| + APIResourceMap* map = GetResourceMapForType( |
| + api_resource->api_resource_type()); |
| + map->erase(api_resource_id); |
| return true; |
| } |
| +bool APIResourceController::RemoveSocket(int api_resource_id) { |
| + return RemoveAPIResource(APIResource::SocketResource, api_resource_id); |
| +} |
| + |
| +bool APIResourceController::RemoveSerialConnection(int api_resource_id) { |
| + return RemoveAPIResource(APIResource::SerialConnectionResource, |
| + api_resource_id); |
| +} |
| + |
| +bool APIResourceController::RemoveUsbDeviceResource(int api_resource_id) { |
| + return RemoveAPIResource(APIResource::UsbDeviceResource, api_resource_id); |
| +} |
| + |
| // TODO(miket): consider partitioning the ID space by extension ID |
| // to make it harder for extensions to peek into each others' resources. |
| int APIResourceController::GenerateAPIResourceId() { |
| - while (next_api_resource_id_ > 0 && |
| - api_resource_map_.count(next_api_resource_id_) > 0) |
| - ++next_api_resource_id_; |
| return next_api_resource_id_++; |
| } |
| Socket* APIResourceController::GetSocket(int api_resource_id) const { |
| + CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| return static_cast<Socket*>(GetAPIResource(APIResource::SocketResource, |
| api_resource_id)); |
| } |
| SerialConnection* APIResourceController::GetSerialConnection( |
| int api_resource_id) const { |
| + CHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| return static_cast<SerialConnection*>( |
| GetAPIResource(APIResource::SerialConnectionResource, api_resource_id)); |
| } |
| UsbDeviceResource* APIResourceController::GetUsbDeviceResource( |
| int api_resource_id) const { |
| + CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| return static_cast<UsbDeviceResource*>(GetAPIResource( |
| APIResource::UsbDeviceResource, api_resource_id)); |
| } |