Fix crash on app list start page contents not existing.
[chromium-blink-merge.git] / components / copresence / rpc / rpc_handler.h
blob2e6f8838d2670b6e5601c5a064f495e9e432363b
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.
5 #ifndef COMPONENTS_COPRESENCE_RPC_RPC_HANDLER_H_
6 #define COMPONENTS_COPRESENCE_RPC_RPC_HANDLER_H_
8 #include <map>
9 #include <set>
10 #include <string>
11 #include <vector>
13 #include "base/callback_forward.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/scoped_vector.h"
16 #include "components/copresence/proto/enums.pb.h"
17 #include "components/copresence/public/copresence_constants.h"
18 #include "components/copresence/public/copresence_delegate.h"
19 #include "components/copresence/timed_map.h"
21 namespace audio_modem {
22 struct AudioToken;
25 namespace copresence {
27 class CopresenceDelegate;
28 class CopresenceStateImpl;
29 class DirectiveHandler;
30 class GCMHandler;
31 class HttpPost;
32 class ReportRequest;
33 class RequestHeader;
34 class SubscribedMessage;
36 // This class currently handles all communication with the copresence server.
37 class RpcHandler {
38 public:
39 // A callback to indicate whether handler initialization succeeded.
40 using SuccessCallback = base::Callback<void(bool)>;
42 // An HttpPost::ResponseCallback along with an HttpPost object to be deleted.
43 // Arguments:
44 // HttpPost*: The handler should take ownership of (i.e. delete) this object.
45 // int: The HTTP status code of the response.
46 // string: The contents of the response.
47 using PostCleanupCallback = base::Callback<void(HttpPost*,
48 int,
49 const std::string&)>;
51 // Callback to allow tests to stub out HTTP POST behavior.
52 // Arguments:
53 // URLRequestContextGetter: Context for the HTTP POST request.
54 // string: Name of the rpc to invoke. URL format: server.google.com/rpc_name
55 // string: The API key to pass in the request.
56 // string: The auth token to pass with the request.
57 // MessageLite: Contents of POST request to be sent. This needs to be
58 // a (scoped) pointer to ease handling of the abstract MessageLite class.
59 // PostCleanupCallback: Receives the response to the request.
60 using PostCallback = base::Callback<void(
61 net::URLRequestContextGetter*,
62 const std::string&,
63 const std::string&,
64 const std::string&,
65 scoped_ptr<google::protobuf::MessageLite>,
66 const PostCleanupCallback&)>;
68 // Report rpc name to send to Apiary.
69 static const char kReportRequestRpcName[];
71 // Constructor. |delegate| and |directive_handler|
72 // are owned by the caller and must outlive the RpcHandler.
73 // |server_post_callback| should be set only by tests.
74 RpcHandler(CopresenceDelegate* delegate,
75 CopresenceStateImpl* state,
76 DirectiveHandler* directive_handler,
77 GCMHandler* gcm_handler,
78 const MessagesCallback& new_messages_callback,
79 const PostCallback& server_post_callback = PostCallback());
81 virtual ~RpcHandler();
83 // Send a ReportRequest from a specific app, and get notified of completion.
84 void SendReportRequest(scoped_ptr<ReportRequest> request,
85 const std::string& app_id,
86 const std::string& auth_token,
87 const StatusCallback& callback);
89 // Report a set of tokens to the server for a given medium.
90 // Uses all active auth tokens (if any).
91 void ReportTokens(const std::vector<audio_modem::AudioToken>& tokens);
93 private:
94 // A queued ReportRequest along with its metadata.
95 struct PendingRequest {
96 PendingRequest(scoped_ptr<ReportRequest> report,
97 const std::string& app_id,
98 bool authenticated,
99 const StatusCallback& callback);
100 ~PendingRequest();
102 scoped_ptr<ReportRequest> report;
103 const std::string app_id;
104 const bool authenticated;
105 const StatusCallback callback;
108 friend class RpcHandlerTest;
110 // Before accepting any other calls, the server requires registration,
111 // which is tied to the auth token (or lack thereof) used to call Report.
112 void RegisterDevice(bool authenticated);
114 // Device registration has completed. Send the requests that it was blocking.
115 void ProcessQueuedRequests(bool authenticated);
117 // Send a ReportRequest from Chrome itself, i.e. no app id.
118 void ReportOnAllDevices(scoped_ptr<ReportRequest> request);
120 // Store a GCM ID and send it to the server if needed.
121 void RegisterGcmId(const std::string& gcm_id);
123 // Server call response handlers.
124 void RegisterResponseHandler(bool authenticated,
125 bool gcm_pending,
126 HttpPost* completed_post,
127 int http_status_code,
128 const std::string& response_data);
129 void ReportResponseHandler(const StatusCallback& status_callback,
130 HttpPost* completed_post,
131 int http_status_code,
132 const std::string& response_data);
134 // If the request has any unpublish or unsubscribe operations, it removes
135 // them from our directive handlers.
136 void ProcessRemovedOperations(const ReportRequest& request);
138 // Add all currently playing tokens to the update signals in this report
139 // request. This ensures that the server doesn't keep issueing new tokens to
140 // us when we're already playing valid tokens.
141 void AddPlayingTokens(ReportRequest* request);
143 void DispatchMessages(
144 const google::protobuf::RepeatedPtrField<SubscribedMessage>&
145 subscribed_messages);
147 RequestHeader* CreateRequestHeader(const std::string& app_id,
148 const std::string& device_id) const;
150 // Post a request to the server. The request should be in proto format.
151 template <class T>
152 void SendServerRequest(const std::string& rpc_name,
153 const std::string& device_id,
154 const std::string& app_id,
155 bool authenticated,
156 scoped_ptr<T> request,
157 const PostCleanupCallback& response_handler);
159 // Wrapper for the http post constructor. This is the default way
160 // to contact the server, but it can be overridden for testing.
161 void SendHttpPost(net::URLRequestContextGetter* url_context_getter,
162 const std::string& rpc_name,
163 const std::string& api_key,
164 const std::string& auth_token,
165 scoped_ptr<google::protobuf::MessageLite> request_proto,
166 const PostCleanupCallback& callback);
168 // These belong to the caller.
169 CopresenceDelegate* const delegate_;
170 CopresenceStateImpl* state_;
171 DirectiveHandler* const directive_handler_;
172 GCMHandler* const gcm_handler_;
174 MessagesCallback new_messages_callback_;
175 PostCallback server_post_callback_;
177 ScopedVector<PendingRequest> pending_requests_queue_;
178 TimedMap<std::string, bool> invalid_audio_token_cache_;
179 std::set<HttpPost*> pending_posts_;
180 std::set<bool> pending_registrations_;
181 std::string auth_token_;
182 std::string gcm_id_;
184 DISALLOW_COPY_AND_ASSIGN(RpcHandler);
187 } // namespace copresence
189 #endif // COMPONENTS_COPRESENCE_RPC_RPC_HANDLER_H_