| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef EXTENSIONS_RENDERER_REQUEST_SENDER_H_ |
| #define EXTENSIONS_RENDERER_REQUEST_SENDER_H_ |
| |
| #include <map> |
| #include <string> |
| |
| #include "base/memory/linked_ptr.h" |
| #include "v8/include/v8.h" |
| |
| namespace base { |
| class ListValue; |
| } |
| |
| namespace extensions { |
| class Dispatcher; |
| class ScriptContext; |
| |
| struct PendingRequest; |
| |
| // Responsible for sending requests for named extension API functions to the |
| // extension host and routing the responses back to the caller. |
| class RequestSender { |
| public: |
| // Source represents a user of RequestSender. Every request is associated with |
| // a Source object, which will be notified when the corresponding response |
| // arrives. When a Source object is going away and there are pending requests, |
| // it should call InvalidateSource() to make sure no notifications are sent to |
| // it later. |
| class Source { |
| public: |
| virtual ~Source() {} |
| |
| virtual ScriptContext* GetContext() = 0; |
| virtual void OnResponseReceived(const std::string& name, |
| int request_id, |
| bool success, |
| const base::ListValue& response, |
| const std::string& error) = 0; |
| }; |
| |
| // Helper class to (re)set the |source_tab_id_| below. |
| class ScopedTabID { |
| public: |
| ScopedTabID(RequestSender* request_sender, int tab_id); |
| ~ScopedTabID(); |
| |
| private: |
| RequestSender* const request_sender_; |
| const int tab_id_; |
| const int previous_tab_id_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ScopedTabID); |
| }; |
| |
| explicit RequestSender(Dispatcher* dispatcher); |
| ~RequestSender(); |
| |
| // In order to avoid collision, all |request_id|s passed into StartRequest() |
| // should be generated by this method. |
| int GetNextRequestId() const; |
| |
| // Makes a call to the API function |name| that is to be handled by the |
| // extension host. The response to this request will be received in |
| // HandleResponse(). |
| // TODO(koz): Remove |request_id| and generate that internally. |
| // There are multiple of these per render view though, so we'll |
| // need to vend the IDs centrally. |
| void StartRequest(Source* source, |
| const std::string& name, |
| int request_id, |
| bool has_callback, |
| bool for_io_thread, |
| base::ListValue* value_args); |
| |
| // Handles responses from the extension host to calls made by StartRequest(). |
| void HandleResponse(int request_id, |
| bool success, |
| const base::ListValue& response, |
| const std::string& error); |
| |
| // Notifies this that a request source is no longer valid. |
| // TODO(kalman): Do this in a generic/safe way. |
| void InvalidateSource(Source* source); |
| |
| private: |
| friend class ScopedTabID; |
| typedef std::map<int, linked_ptr<PendingRequest> > PendingRequestMap; |
| |
| void InsertRequest(int request_id, PendingRequest* pending_request); |
| linked_ptr<PendingRequest> RemoveRequest(int request_id); |
| |
| Dispatcher* dispatcher_; |
| PendingRequestMap pending_requests_; |
| |
| int source_tab_id_; // Id of the tab sending the request, or -1 if no tab. |
| |
| DISALLOW_COPY_AND_ASSIGN(RequestSender); |
| }; |
| |
| } // namespace extensions |
| |
| #endif // EXTENSIONS_RENDERER_REQUEST_SENDER_H_ |