OLD | NEW |
| (Empty) |
1 // Copyright 2015 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 <map> | |
9 #include <memory> | |
10 #include <set> | |
11 #include <string> | |
12 #include <vector> | |
13 | |
14 #include "base/callback_forward.h" | |
15 #include "base/memory/scoped_vector.h" | |
16 #include "components/audio_modem/public/audio_modem_types.h" | |
17 #include "components/copresence/proto/enums.pb.h" | |
18 #include "components/copresence/public/copresence_constants.h" | |
19 #include "components/copresence/public/copresence_delegate.h" | |
20 #include "components/copresence/timed_map.h" | |
21 | |
22 namespace copresence { | |
23 | |
24 class CopresenceDelegate; | |
25 class CopresenceStateImpl; | |
26 class DirectiveHandler; | |
27 class GCMHandler; | |
28 class HttpPost; | |
29 class ReportRequest; | |
30 class RequestHeader; | |
31 class SubscribedMessage; | |
32 | |
33 // This class handles all communication with the copresence server. | |
34 // Clients provide a ReportRequest proto containing publishes, subscribes, | |
35 // and token observations they want to send to the server. The RpcHandler | |
36 // will fill in details like the RequestHeader and DeviceCapabilities, | |
37 // and dispatch the results of the server call to the appropriate parts | |
38 // of the system. | |
39 // | |
40 // To create an RpcHandler, clients will need to provide a few other classes | |
41 // that support its functionality. Notable among them is the CopresenceDelegate, | |
42 // an interface clients must implement to provide settings and functionality | |
43 // that may depend on the environment. See the definition in | |
44 // //components/copresence/public/copresence_delegate.h. | |
45 // | |
46 // Here is an example of creating and using an RpcHandler. | |
47 // The GCMHandler and CopresenceStateImpl are optional. | |
48 // | |
49 // MyDelegate delegate(...); | |
50 // copresence::DirectiveHandlerImpl directive_handler; | |
51 // | |
52 // RpcHandler handler(&delegate, | |
53 // &directive_handler, | |
54 // nullptr, | |
55 // nullptr, | |
56 // base::Bind(&HandleMessages)); | |
57 // | |
58 // std::unique_ptr<ReportRequest> request(new ReportRequest); | |
59 // (Fill in ReportRequest.) | |
60 // | |
61 // handler.SendReportRequest(std::move(request), | |
62 // "my_app_id", | |
63 // "", | |
64 // base::Bind(&HandleStatus)); | |
65 // | |
66 // The server will respond with directives, which get passed to the | |
67 // DirectiveHandlerImpl. | |
68 // | |
69 // Tokens from the audio modem should also be forwarded | |
70 // via ReportTokens() so that messages get delivered properly. | |
71 class RpcHandler final { | |
72 public: | |
73 // An HttpPost::ResponseCallback along with an HttpPost object to be deleted. | |
74 // Arguments: | |
75 // HttpPost*: The handler should take ownership of (i.e. delete) this object. | |
76 // int: The HTTP status code of the response. | |
77 // string: The contents of the response. | |
78 using PostCleanupCallback = base::Callback<void(HttpPost*, | |
79 int, | |
80 const std::string&)>; | |
81 | |
82 // Callback to allow tests to stub out HTTP POST behavior. | |
83 // Arguments: | |
84 // URLRequestContextGetter: Context for the HTTP POST request. | |
85 // string: Name of the rpc to invoke. URL format: server.google.com/rpc_name | |
86 // string: The API key to pass in the request. | |
87 // string: The auth token to pass with the request. | |
88 // MessageLite: Contents of POST request to be sent. This needs to be | |
89 // a (scoped) pointer to ease handling of the abstract MessageLite class. | |
90 // PostCleanupCallback: Receives the response to the request. | |
91 using PostCallback = | |
92 base::Callback<void(net::URLRequestContextGetter*, | |
93 const std::string&, | |
94 const std::string&, | |
95 const std::string&, | |
96 std::unique_ptr<google::protobuf::MessageLite>, | |
97 const PostCleanupCallback&)>; | |
98 | |
99 // Report rpc name to send to Apiary. | |
100 static const char kReportRequestRpcName[]; | |
101 | |
102 // Constructor. The CopresenceStateImpl and GCMHandler may be null. | |
103 // The first four parameters are owned by the caller and (if not null) | |
104 // must outlive the RpcHandler. | |
105 RpcHandler(CopresenceDelegate* delegate, | |
106 DirectiveHandler* directive_handler, | |
107 CopresenceStateImpl* state, | |
108 GCMHandler* gcm_handler, | |
109 const MessagesCallback& new_messages_callback, | |
110 const PostCallback& server_post_callback = PostCallback()); | |
111 | |
112 // Not copyable. | |
113 RpcHandler(const RpcHandler&) = delete; | |
114 void operator=(const RpcHandler&) = delete; | |
115 | |
116 ~RpcHandler(); | |
117 | |
118 // Sends a ReportRequest from a specific app, and get notified of completion. | |
119 void SendReportRequest(std::unique_ptr<ReportRequest> request, | |
120 const std::string& app_id, | |
121 const std::string& auth_token, | |
122 const StatusCallback& callback); | |
123 | |
124 // Reports a set of tokens to the server for a given medium. | |
125 // Uses all active auth tokens (if any). | |
126 void ReportTokens(const std::vector<audio_modem::AudioToken>& tokens); | |
127 | |
128 private: | |
129 // A queued ReportRequest along with its metadata. | |
130 struct PendingRequest { | |
131 PendingRequest(std::unique_ptr<ReportRequest> report, | |
132 const std::string& app_id, | |
133 bool authenticated, | |
134 const StatusCallback& callback); | |
135 ~PendingRequest(); | |
136 | |
137 std::unique_ptr<ReportRequest> report; | |
138 const std::string app_id; | |
139 const bool authenticated; | |
140 const StatusCallback callback; | |
141 }; | |
142 | |
143 friend class RpcHandlerTest; | |
144 | |
145 // Before accepting any other calls, the server requires registration, | |
146 // which is tied to the auth token (or lack thereof) used to call Report. | |
147 void RegisterDevice(bool authenticated); | |
148 | |
149 // Device registration has completed. Send the requests that it was blocking. | |
150 void ProcessQueuedRequests(bool authenticated); | |
151 | |
152 // Sends a ReportRequest from Chrome itself, i.e. no app id. | |
153 void ReportOnAllDevices(std::unique_ptr<ReportRequest> request); | |
154 | |
155 // Stores a GCM ID and send it to the server if needed. | |
156 void RegisterGcmId(const std::string& gcm_id); | |
157 | |
158 // Server call response handlers. | |
159 void RegisterResponseHandler(bool authenticated, | |
160 bool gcm_pending, | |
161 HttpPost* completed_post, | |
162 int http_status_code, | |
163 const std::string& response_data); | |
164 void ReportResponseHandler(const StatusCallback& status_callback, | |
165 HttpPost* completed_post, | |
166 int http_status_code, | |
167 const std::string& response_data); | |
168 | |
169 // Removes unpublished or unsubscribed operations from the directive handlers. | |
170 void ProcessRemovedOperations(const ReportRequest& request); | |
171 | |
172 // Adds all currently playing tokens to the update signals in this report | |
173 // request. This ensures that the server doesn't keep issueing new tokens to | |
174 // us when we're already playing valid tokens. | |
175 void AddPlayingTokens(ReportRequest* request); | |
176 | |
177 void DispatchMessages( | |
178 const google::protobuf::RepeatedPtrField<SubscribedMessage>& | |
179 subscribed_messages); | |
180 | |
181 RequestHeader* CreateRequestHeader(const std::string& app_id, | |
182 const std::string& device_id) const; | |
183 | |
184 // Wrapper for the http post constructor. This is the default way | |
185 // to contact the server, but it can be overridden for testing. | |
186 void SendHttpPost( | |
187 net::URLRequestContextGetter* url_context_getter, | |
188 const std::string& rpc_name, | |
189 const std::string& api_key, | |
190 const std::string& auth_token, | |
191 std::unique_ptr<google::protobuf::MessageLite> request_proto, | |
192 const PostCleanupCallback& callback); | |
193 | |
194 // These belong to the caller. | |
195 CopresenceDelegate* const delegate_; | |
196 DirectiveHandler* const directive_handler_; | |
197 CopresenceStateImpl* state_; | |
198 GCMHandler* const gcm_handler_; | |
199 | |
200 MessagesCallback new_messages_callback_; | |
201 PostCallback server_post_callback_; | |
202 | |
203 ScopedVector<PendingRequest> pending_requests_queue_; | |
204 TimedMap<std::string, bool> invalid_audio_token_cache_; | |
205 std::set<HttpPost*> pending_posts_; | |
206 std::set<bool> pending_registrations_; | |
207 std::string auth_token_; | |
208 std::string gcm_id_; | |
209 }; | |
210 | |
211 } // namespace copresence | |
212 | |
213 #endif // COMPONENTS_COPRESENCE_RPC_RPC_HANDLER_H_ | |
OLD | NEW |