1// Copyright (c) 2012 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 CHROME_RENDERER_EXTENSIONS_REQUEST_SENDER_H_
6#define CHROME_RENDERER_EXTENSIONS_REQUEST_SENDER_H_
7
8#include <string>
9#include <map>
10
11#include "base/memory/linked_ptr.h"
12#include "v8/include/v8.h"
13
14namespace base {
15class ListValue;
16}
17
18namespace extensions {
19class ChromeV8Context;
20class Dispatcher;
21
22struct 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.
26class 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 ChromeV8Context* 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  explicit RequestSender(Dispatcher* dispatcher);
46  ~RequestSender();
47
48  // In order to avoid collision, all |request_id|s passed into StartRequest()
49  // should be generated by this method.
50  int GetNextRequestId() const;
51
52  // Makes a call to the API function |name| that is to be handled by the
53  // extension host. The response to this request will be received in
54  // HandleResponse().
55  // TODO(koz): Remove |request_id| and generate that internally.
56  //            There are multiple of these per render view though, so we'll
57  //            need to vend the IDs centrally.
58  void StartRequest(Source* source,
59                    const std::string& name,
60                    int request_id,
61                    bool has_callback,
62                    bool for_io_thread,
63                    base::ListValue* value_args);
64
65  // Handles responses from the extension host to calls made by StartRequest().
66  void HandleResponse(int request_id,
67                      bool success,
68                      const base::ListValue& response,
69                      const std::string& error);
70
71  // Notifies this that a request source is no longer valid.
72  // TODO(kalman): Do this in a generic/safe way.
73  void InvalidateSource(Source* source);
74
75 private:
76  typedef std::map<int, linked_ptr<PendingRequest> > PendingRequestMap;
77
78  void InsertRequest(int request_id, PendingRequest* pending_request);
79  linked_ptr<PendingRequest> RemoveRequest(int request_id);
80
81  Dispatcher* dispatcher_;
82  PendingRequestMap pending_requests_;
83
84  DISALLOW_COPY_AND_ASSIGN(RequestSender);
85};
86
87}  // namespace extensions
88
89#endif  // CHROME_RENDERER_EXTENSIONS_REQUEST_SENDER_H_
90