1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#ifndef EXTENSIONS_RENDERER_REQUEST_SENDER_H_
6a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#define EXTENSIONS_RENDERER_REQUEST_SENDER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
9a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "v8/include/v8.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ListValue;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Dispatcher;
20a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass ScriptContext;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PendingRequest;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Responsible for sending requests for named extension API functions to the
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// extension host and routing the responses back to the caller.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RequestSender {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Source represents a user of RequestSender. Every request is associated with
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // a Source object, which will be notified when the corresponding response
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // arrives. When a Source object is going away and there are pending requests,
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // it should call InvalidateSource() to make sure no notifications are sent to
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // it later.
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  class Source {
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   public:
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    virtual ~Source() {}
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    virtual ScriptContext* GetContext() = 0;
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    virtual void OnResponseReceived(const std::string& name,
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    int request_id,
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    bool success,
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    const base::ListValue& response,
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    const std::string& error) = 0;
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Helper class to (re)set the |source_tab_id_| below.
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  class ScopedTabID {
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   public:
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ScopedTabID(RequestSender* request_sender, int tab_id);
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ~ScopedTabID();
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)   private:
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RequestSender* const request_sender_;
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const int tab_id_;
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const int previous_tab_id_;
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DISALLOW_COPY_AND_ASSIGN(ScopedTabID);
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit RequestSender(Dispatcher* dispatcher);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~RequestSender();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // In order to avoid collision, all |request_id|s passed into StartRequest()
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // should be generated by this method.
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int GetNextRequestId() const;
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Makes a call to the API function |name| that is to be handled by the
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // extension host. The response to this request will be received in
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HandleResponse().
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(koz): Remove |request_id| and generate that internally.
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //            There are multiple of these per render view though, so we'll
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //            need to vend the IDs centrally.
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void StartRequest(Source* source,
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    const std::string& name,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    int request_id,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    bool has_callback,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    bool for_io_thread,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    base::ListValue* value_args);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles responses from the extension host to calls made by StartRequest().
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleResponse(int request_id,
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      bool success,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const base::ListValue& response,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const std::string& error);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Notifies this that a request source is no longer valid.
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(kalman): Do this in a generic/safe way.
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void InvalidateSource(Source* source);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  friend class ScopedTabID;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<int, linked_ptr<PendingRequest> > PendingRequestMap;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InsertRequest(int request_id, PendingRequest* pending_request);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  linked_ptr<PendingRequest> RemoveRequest(int request_id);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Dispatcher* dispatcher_;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingRequestMap pending_requests_;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int source_tab_id_;  // Id of the tab sending the request, or -1 if no tab.
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RequestSender);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif  // EXTENSIONS_RENDERER_REQUEST_SENDER_H_
107