• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~Source()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