Home | History | Annotate | Download | only in renderer
      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.
      4 
      5 #ifndef EXTENSIONS_RENDERER_REQUEST_SENDER_H_
      6 #define EXTENSIONS_RENDERER_REQUEST_SENDER_H_
      7 
      8 #include <map>
      9 #include <string>
     10 
     11 #include "base/memory/linked_ptr.h"
     12 #include "v8/include/v8.h"
     13 
     14 namespace base {
     15 class ListValue;
     16 }
     17 
     18 namespace extensions {
     19 class Dispatcher;
     20 class ScriptContext;
     21 
     22 struct PendingRequest;
     23 
     24 // Responsible for sending requests for named extension API functions to the
     25 // extension host and routing the responses back to the caller.
     26 class RequestSender {
     27  public:
     28   // Source represents a user of RequestSender. Every request is associated with
     29   // a Source object, which will be notified when the corresponding response
     30   // arrives. When a Source object is going away and there are pending requests,
     31   // it should call InvalidateSource() to make sure no notifications are sent to
     32   // it later.
     33   class Source {
     34    public:
     35     virtual ~Source() {}
     36 
     37     virtual ScriptContext* GetContext() = 0;
     38     virtual void OnResponseReceived(const std::string& name,
     39                                     int request_id,
     40                                     bool success,
     41                                     const base::ListValue& response,
     42                                     const std::string& error) = 0;
     43   };
     44 
     45   // Helper class to (re)set the |source_tab_id_| below.
     46   class ScopedTabID {
     47    public:
     48     ScopedTabID(RequestSender* request_sender, int tab_id);
     49     ~ScopedTabID();
     50 
     51    private:
     52     RequestSender* const request_sender_;
     53     const int tab_id_;
     54     const int previous_tab_id_;
     55 
     56     DISALLOW_COPY_AND_ASSIGN(ScopedTabID);
     57   };
     58 
     59   explicit RequestSender(Dispatcher* dispatcher);
     60   ~RequestSender();
     61 
     62   // In order to avoid collision, all |request_id|s passed into StartRequest()
     63   // should be generated by this method.
     64   int GetNextRequestId() const;
     65 
     66   // Makes a call to the API function |name| that is to be handled by the
     67   // extension host. The response to this request will be received in
     68   // HandleResponse().
     69   // TODO(koz): Remove |request_id| and generate that internally.
     70   //            There are multiple of these per render view though, so we'll
     71   //            need to vend the IDs centrally.
     72   void StartRequest(Source* source,
     73                     const std::string& name,
     74                     int request_id,
     75                     bool has_callback,
     76                     bool for_io_thread,
     77                     base::ListValue* value_args);
     78 
     79   // Handles responses from the extension host to calls made by StartRequest().
     80   void HandleResponse(int request_id,
     81                       bool success,
     82                       const base::ListValue& response,
     83                       const std::string& error);
     84 
     85   // Notifies this that a request source is no longer valid.
     86   // TODO(kalman): Do this in a generic/safe way.
     87   void InvalidateSource(Source* source);
     88 
     89  private:
     90   friend class ScopedTabID;
     91   typedef std::map<int, linked_ptr<PendingRequest> > PendingRequestMap;
     92 
     93   void InsertRequest(int request_id, PendingRequest* pending_request);
     94   linked_ptr<PendingRequest> RemoveRequest(int request_id);
     95 
     96   Dispatcher* dispatcher_;
     97   PendingRequestMap pending_requests_;
     98 
     99   int source_tab_id_;  // Id of the tab sending the request, or -1 if no tab.
    100 
    101   DISALLOW_COPY_AND_ASSIGN(RequestSender);
    102 };
    103 
    104 }  // namespace extensions
    105 
    106 #endif  // EXTENSIONS_RENDERER_REQUEST_SENDER_H_
    107