diff options
Diffstat (limited to 'chrome/browser/extensions/api/socket')
-rw-r--r-- | chrome/browser/extensions/api/socket/socket_api.cc | 29 | ||||
-rw-r--r-- | chrome/browser/extensions/api/socket/socket_api.h | 68 | ||||
-rw-r--r-- | chrome/browser/extensions/api/socket/udp_socket.cc | 41 | ||||
-rw-r--r-- | chrome/browser/extensions/api/socket/udp_socket.h | 27 |
4 files changed, 154 insertions, 11 deletions
diff --git a/chrome/browser/extensions/api/socket/socket_api.cc b/chrome/browser/extensions/api/socket/socket_api.cc index 83f1e4e..8c1a55b 100644 --- a/chrome/browser/extensions/api/socket/socket_api.cc +++ b/chrome/browser/extensions/api/socket/socket_api.cc @@ -47,30 +47,39 @@ const char kMulticastSocketTypeError[] = const char kWildcardAddress[] = "*"; const int kWildcardPort = 0; -SocketAsyncApiFunction::SocketAsyncApiFunction() - : manager_(NULL) { +SocketAsyncApiFunction::SocketAsyncApiFunction() { } SocketAsyncApiFunction::~SocketAsyncApiFunction() { } bool SocketAsyncApiFunction::PrePrepare() { - manager_ = ApiResourceManager<Socket>::Get(profile()); - DCHECK(manager_) << "There is no socket manager. " - "If this assertion is failing during a test, then it is likely that " - "TestExtensionSystem is failing to provide an instance of " - "ApiResourceManager<Socket>."; - return manager_ != NULL; + manager_ = CreateSocketResourceManager(); + return manager_->SetProfile(profile()); } bool SocketAsyncApiFunction::Respond() { return error_.empty(); } +scoped_ptr<SocketResourceManagerInterface> + SocketAsyncApiFunction::CreateSocketResourceManager() { + return scoped_ptr<SocketResourceManagerInterface>( + new SocketResourceManager<Socket>()).Pass(); +} + +int SocketAsyncApiFunction::AddSocket(Socket* socket) { + return manager_->Add(socket); +} + Socket* SocketAsyncApiFunction::GetSocket(int api_resource_id) { return manager_->Get(extension_->id(), api_resource_id); } +base::hash_set<int>* SocketAsyncApiFunction::GetSocketIds() { + return manager_->GetResourceIds(extension_->id()); +} + void SocketAsyncApiFunction::RemoveSocket(int api_resource_id) { manager_->Remove(extension_->id(), api_resource_id); } @@ -152,7 +161,7 @@ void SocketCreateFunction::Work() { DCHECK(socket); base::DictionaryValue* result = new base::DictionaryValue(); - result->SetInteger(kSocketIdKey, manager_->Add(socket)); + result->SetInteger(kSocketIdKey, AddSocket(socket)); SetResult(result); } @@ -352,7 +361,7 @@ void SocketAcceptFunction::OnAccept(int result_code, result->SetInteger(kResultCodeKey, result_code); if (socket) { Socket *client_socket = new TCPSocket(socket, extension_id(), true); - result->SetInteger(kSocketIdKey, manager_->Add(client_socket)); + result->SetInteger(kSocketIdKey, AddSocket(client_socket)); } SetResult(result); diff --git a/chrome/browser/extensions/api/socket/socket_api.h b/chrome/browser/extensions/api/socket/socket_api.h index 4e68c58..396ddc6 100644 --- a/chrome/browser/extensions/api/socket/socket_api.h +++ b/chrome/browser/extensions/api/socket/socket_api.h @@ -27,6 +27,66 @@ namespace extensions { class Socket; +// A simple interface to ApiResourceManager<Socket> or derived class. The goal +// of this interface is to allow Socket API functions to use distinct instances +// of ApiResourceManager<> depending on the type of socket (old version in +// "socket" namespace vs new version in "socket.xxx" namespaces). +class SocketResourceManagerInterface { + public: + virtual ~SocketResourceManagerInterface() {} + + virtual bool SetProfile(Profile* profile) = 0; + virtual int Add(Socket *socket) = 0; + virtual Socket* Get(const std::string& extension_id, + int api_resource_id) = 0; + virtual void Remove(const std::string& extension_id, + int api_resource_id) = 0; + virtual base::hash_set<int>* GetResourceIds( + const std::string& extension_id) = 0; +}; + +// Implementation of SocketResourceManagerInterface using an +// ApiResourceManager<T> instance (where T derives from Socket). +template<typename T> +class SocketResourceManager : public SocketResourceManagerInterface { + public: + SocketResourceManager() + : manager_(NULL) { + } + + virtual bool SetProfile(Profile* profile) OVERRIDE { + manager_ = ApiResourceManager<T>::Get(profile); + DCHECK(manager_) << "There is no socket manager. " + "If this assertion is failing during a test, then it is likely that " + "TestExtensionSystem is failing to provide an instance of " + "ApiResourceManager<Socket>."; + return manager_ != NULL; + } + + virtual int Add(Socket *socket) OVERRIDE { + // Note: Cast needed here, because "T" may be a subclass of "Socket". + return manager_->Add(static_cast<T*>(socket)); + } + + virtual Socket* Get(const std::string& extension_id, + int api_resource_id) OVERRIDE { + return manager_->Get(extension_id, api_resource_id); + } + + virtual void Remove(const std::string& extension_id, + int api_resource_id) OVERRIDE { + manager_->Remove(extension_id, api_resource_id); + } + + virtual base::hash_set<int>* GetResourceIds( + const std::string& extension_id) OVERRIDE { + return manager_->GetResourceIds(extension_id); + } + + private: + ApiResourceManager<T>* manager_; +}; + class SocketAsyncApiFunction : public AsyncApiFunction { public: SocketAsyncApiFunction(); @@ -38,10 +98,16 @@ class SocketAsyncApiFunction : public AsyncApiFunction { virtual bool PrePrepare() OVERRIDE; virtual bool Respond() OVERRIDE; + virtual scoped_ptr<SocketResourceManagerInterface> + CreateSocketResourceManager(); + + int AddSocket(Socket* socket); Socket* GetSocket(int api_resource_id); void RemoveSocket(int api_resource_id); + base::hash_set<int>* GetSocketIds(); - ApiResourceManager<Socket>* manager_; + private: + scoped_ptr<SocketResourceManagerInterface> manager_; }; class SocketExtensionWithDnsLookupFunction : public SocketAsyncApiFunction { diff --git a/chrome/browser/extensions/api/socket/udp_socket.cc b/chrome/browser/extensions/api/socket/udp_socket.cc index 4a77aea..7d36ffc 100644 --- a/chrome/browser/extensions/api/socket/udp_socket.cc +++ b/chrome/browser/extensions/api/socket/udp_socket.cc @@ -14,6 +14,17 @@ namespace extensions { +static base::LazyInstance<ProfileKeyedAPIFactory< + ApiResourceManager<ResumableUDPSocket> > > + g_factory = LAZY_INSTANCE_INITIALIZER; + +// static +template <> +ProfileKeyedAPIFactory<ApiResourceManager<ResumableUDPSocket> >* +ApiResourceManager<ResumableUDPSocket>::GetFactoryInstance() { + return &g_factory.Get(); +} + UDPSocket::UDPSocket(const std::string& owner_extension_id) : Socket(owner_extension_id), socket_(net::DatagramSocket::DEFAULT_BIND, @@ -278,4 +289,34 @@ const std::vector<std::string>& UDPSocket::GetJoinedGroups() const { return multicast_groups_; } +ResumableUDPSocket::ResumableUDPSocket(const std::string& owner_extension_id) + : UDPSocket(owner_extension_id), + persistent_(false), + buffer_size_(0) { +} + +const std::string& ResumableUDPSocket::name() const { + return name_; +} + +void ResumableUDPSocket::set_name(const std::string& name) { + name_ = name; +} + +bool ResumableUDPSocket::persistent() const { + return persistent_; +} + +void ResumableUDPSocket::set_persistent(bool persistent) { + persistent_ = persistent; +} + +int ResumableUDPSocket::buffer_size() const { + return buffer_size_; +} + +void ResumableUDPSocket::set_buffer_size(int buffer_size) { + buffer_size_ = buffer_size; +} + } // namespace extensions diff --git a/chrome/browser/extensions/api/socket/udp_socket.h b/chrome/browser/extensions/api/socket/udp_socket.h index b301cb2..4989e27 100644 --- a/chrome/browser/extensions/api/socket/udp_socket.h +++ b/chrome/browser/extensions/api/socket/udp_socket.h @@ -74,6 +74,33 @@ class UDPSocket : public Socket { std::vector<std::string> multicast_groups_; }; +// UDP Socket instances from the "sockets.udp" namespace. These are regular +// socket objects with additional properties related to the behavior defined in +// the "sockets.udp" namespace. +class ResumableUDPSocket : public UDPSocket { + public: + explicit ResumableUDPSocket(const std::string& owner_extension_id); + + const std::string& name() const; + void set_name(const std::string& name); + + virtual bool persistent() const OVERRIDE; + void set_persistent(bool persistent); + + int buffer_size() const; + void set_buffer_size(int buffer_size); + + private: + friend class ApiResourceManager<ResumableUDPSocket>; + static const char* service_name() { + return "ResumableUDPSocketManager"; + } + + std::string name_; + bool persistent_; + int buffer_size_; +}; + } // namespace extensions #endif // CHROME_BROWSER_EXTENSIONS_API_SOCKET_UDP_SOCKET_H_ |