rpc_handler.h revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
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 COMPONENTS_COPRESENCE_RPC_RPC_HANDLER_H_
6#define COMPONENTS_COPRESENCE_RPC_RPC_HANDLER_H_
7
8#include <set>
9#include <string>
10#include <vector>
11
12#include "base/callback.h"
13#include "base/memory/scoped_ptr.h"
14#include "components/copresence/proto/enums.pb.h"
15#include "components/copresence/public/copresence_delegate.h"
16#include "components/copresence/public/whispernet_client.h"
17#include "components/copresence/rpc/http_post.h"
18#include "components/copresence/timed_map.h"
19
20namespace copresence {
21
22class DirectiveHandler;
23class ReportRequest;
24class RequestHeader;
25class SubscribedMessage;
26
27// This class currently handles all communication with the copresence server.
28class RpcHandler {
29 public:
30  // A callback to indicate whether handler initialization succeeded.
31  typedef base::Callback<void(bool)> SuccessCallback;
32
33  // Report rpc name to send to Apiary.
34  static const char kReportRequestRpcName[];
35
36  // Constructor. |delegate| is owned by the caller,
37  // and must be valid as long as the RpcHandler exists.
38  explicit RpcHandler(CopresenceDelegate* delegate);
39
40  virtual ~RpcHandler();
41
42  // Clients must call this and wait for |init_done_callback|
43  // to be called before invoking any other methods.
44  void Initialize(const SuccessCallback& init_done_callback);
45
46  // Send a report request.
47  void SendReportRequest(scoped_ptr<ReportRequest> request);
48  void SendReportRequest(scoped_ptr<ReportRequest> request,
49                         const std::string& app_id,
50                         const StatusCallback& callback);
51
52  // Report a set of tokens to the server for a given medium.
53  void ReportTokens(const std::vector<AudioToken>& tokens);
54
55  // Create the directive handler and connect it to
56  // the whispernet client specified by the delegate.
57  void ConnectToWhispernet();
58
59 private:
60  // An HttpPost::ResponseCallback prepended with an HttpPost object
61  // that needs to be deleted.
62  typedef base::Callback<void(HttpPost*, int, const std::string&)>
63      PostCleanupCallback;
64
65  // Callback to allow tests to stub out HTTP POST behavior.
66  // Arguments:
67  // URLRequestContextGetter: Context for the HTTP POST request.
68  // string: Name of the rpc to invoke. URL format: server.google.com/rpc_name
69  // MessageLite: Contents of POST request to be sent. This needs to be
70  //     a (scoped) pointer to ease handling of the abstract MessageLite class.
71  // ResponseCallback: Receives the response to the request.
72  typedef base::Callback<void(net::URLRequestContextGetter*,
73                              const std::string&,
74                              scoped_ptr<google::protobuf::MessageLite>,
75                              const PostCleanupCallback&)> PostCallback;
76
77  friend class RpcHandlerTest;
78
79  void RegisterResponseHandler(const SuccessCallback& init_done_callback,
80                               HttpPost* completed_post,
81                               int http_status_code,
82                               const std::string& response_data);
83  void ReportResponseHandler(const StatusCallback& status_callback,
84                             HttpPost* completed_post,
85                             int http_status_code,
86                             const std::string& response_data);
87
88  // If the request has any unpublish or unsubscribe operations, it removes
89  // them from our directive handlers.
90  void ProcessRemovedOperations(const ReportRequest& request);
91
92  // Add all currently playing tokens to the update signals in this report
93  // request. This ensures that the server doesn't keep issueing new tokens to
94  // us when we're already playing valid tokens.
95  void AddPlayingTokens(ReportRequest* request);
96
97  void DispatchMessages(
98      const google::protobuf::RepeatedPtrField<SubscribedMessage>&
99      subscribed_messages);
100
101  RequestHeader* CreateRequestHeader(const std::string& client_name) const;
102
103  template <class T>
104  void SendServerRequest(const std::string& rpc_name,
105                         const std::string& app_id,
106                         scoped_ptr<T> request,
107                         const PostCleanupCallback& response_handler);
108
109  // Wrapper for the http post constructor. This is the default way
110  // to contact the server, but it can be overridden for testing.
111  void SendHttpPost(net::URLRequestContextGetter* url_context_getter,
112                    const std::string& rpc_name,
113                    scoped_ptr<google::protobuf::MessageLite> request_proto,
114                    const PostCleanupCallback& callback);
115
116  // This method receives the request to encode a token and forwards it to
117  // whispernet, setting the samples return callback to samples_callback.
118  void AudioDirectiveListToWhispernetConnector(
119      const std::string& token,
120      bool audible,
121      const WhispernetClient::SamplesCallback& samples_callback);
122
123  CopresenceDelegate* delegate_;  // Belongs to the caller.
124  TimedMap<std::string, bool> invalid_audio_token_cache_;
125  PostCallback server_post_callback_;
126
127  std::string device_id_;
128  scoped_ptr<DirectiveHandler> directive_handler_;
129  std::set<HttpPost*> pending_posts_;
130
131  DISALLOW_COPY_AND_ASSIGN(RpcHandler);
132};
133
134}  // namespace copresence
135
136#endif  // COMPONENTS_COPRESENCE_RPC_RPC_HANDLER_H_
137