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 20 namespace copresence { 21 22 class DirectiveHandler; 23 class ReportRequest; 24 class RequestHeader; 25 class SubscribedMessage; 26 27 // This class currently handles all communication with the copresence server. 28 class 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