Index: components/copresence/rpc/rpc_handler.cc |
diff --git a/components/copresence/rpc/rpc_handler.cc b/components/copresence/rpc/rpc_handler.cc |
index 91a09f457adc487cc1eb75d4f5c6279555b0e4b9..8d9eb00598e39cfa6eb01e10b5232ef7033fa111 100644 |
--- a/components/copresence/rpc/rpc_handler.cc |
+++ b/components/copresence/rpc/rpc_handler.cc |
@@ -61,8 +61,7 @@ const char kDefaultCopresenceServer[] = |
bool CopresenceErrorLogged(const Status& status) { |
if (status.code() != OK) { |
LOG(ERROR) << "Copresence error code " << status.code() |
- << (status.message().empty() ? std::string() : |
- ": " + status.message()); |
+ << (status.message().empty() ? "" : ": " + status.message()); |
} |
return status.code() != OK; |
} |
@@ -136,7 +135,7 @@ ClientVersion* CreateVersion(const std::string& client, |
return version; |
} |
-void AddTokenToRequest(ReportRequest* request, const AudioToken& token) { |
+void AddTokenToRequest(const AudioToken& token, ReportRequest* request) { |
TokenObservation* token_observation = |
request->mutable_update_signals_request()->add_token_observation(); |
token_observation->set_token_id(ToUrlSafe(token.token)); |
@@ -172,38 +171,66 @@ RpcHandler::~RpcHandler() { |
} |
} |
-void RpcHandler::Initialize(const SuccessCallback& init_done_callback) { |
+void RpcHandler::RegisterForToken(const std::string& auth_token, |
+ const SuccessCallback& init_done_callback) { |
+ if (IsRegisteredForToken(auth_token)) { |
+ LOG(WARNING) << "Attempted re-registration for the same auth token."; |
+ init_done_callback.Run(true); |
+ return; |
+ } |
scoped_ptr<RegisterDeviceRequest> request(new RegisterDeviceRequest); |
- DCHECK(device_id_.empty()); |
request->mutable_push_service()->set_service(PUSH_SERVICE_NONE); |
- Identity* identity = |
- request->mutable_device_identifiers()->mutable_registrant(); |
- identity->set_type(CHROME); |
- identity->set_chrome_id(base::GenerateGUID()); |
+ |
+ DVLOG(2) << "Sending " << (auth_token.empty() ? "anonymous" : "authenticated") |
+ << " registration to server."; |
+ |
+ // Only identify as a Chrome device if we're in anonymous mode. |
+ // Authenticated calls come from a "GAIA device". |
+ if (auth_token.empty()) { |
+ Identity* identity = |
+ request->mutable_device_identifiers()->mutable_registrant(); |
+ identity->set_type(CHROME); |
+ identity->set_chrome_id(base::GenerateGUID()); |
+ } |
+ |
SendServerRequest( |
kRegisterDeviceRpcName, |
- std::string(), |
+ std::string(), // device ID |
+ std::string(), // app ID |
+ auth_token, |
request.Pass(), |
base::Bind(&RpcHandler::RegisterResponseHandler, |
// On destruction, this request will be cancelled. |
base::Unretained(this), |
- init_done_callback)); |
+ init_done_callback, |
+ auth_token)); |
} |
-void RpcHandler::SendReportRequest(scoped_ptr<ReportRequest> request) { |
- SendReportRequest(request.Pass(), std::string(), StatusCallback()); |
+bool RpcHandler::IsRegisteredForToken(const std::string& auth_token) const { |
+ return device_id_by_auth_token_.find(auth_token) != |
+ device_id_by_auth_token_.end(); |
+} |
+ |
+void RpcHandler::SendReportRequest(scoped_ptr<ReportRequest> request, |
+ const std::string& auth_token) { |
+ SendReportRequest(request.Pass(), |
+ std::string(), |
+ auth_token, |
+ StatusCallback()); |
} |
void RpcHandler::SendReportRequest(scoped_ptr<ReportRequest> request, |
const std::string& app_id, |
+ const std::string& auth_token, |
const StatusCallback& status_callback) { |
DCHECK(request.get()); |
- DCHECK(!device_id_.empty()) |
- << "RpcHandler::Initialize() must complete successfully " |
- << "before other RpcHandler methods are called."; |
+ auto registration_entry = device_id_by_auth_token_.find(auth_token); |
+ DCHECK(registration_entry != device_id_by_auth_token_.end()) |
+ << "RegisterForToken() must complete successfully " |
+ << "for new tokens before calling SendReportRequest()."; |
- DVLOG(3) << "Sending report request to server."; |
+ DVLOG(3) << "Sending ReportRequest to server."; |
// If we are unpublishing or unsubscribing, we need to stop those publish or |
// subscribes right away, we don't need to wait for the server to tell us. |
@@ -215,7 +242,9 @@ void RpcHandler::SendReportRequest(scoped_ptr<ReportRequest> request, |
AddPlayingTokens(request.get()); |
SendServerRequest(kReportRequestRpcName, |
+ registration_entry->second, |
app_id, |
+ auth_token, |
request.Pass(), |
// On destruction, this request will be cancelled. |
base::Bind(&RpcHandler::ReportResponseHandler, |
@@ -226,17 +255,33 @@ void RpcHandler::SendReportRequest(scoped_ptr<ReportRequest> request, |
void RpcHandler::ReportTokens(const std::vector<AudioToken>& tokens) { |
DCHECK(!tokens.empty()); |
- scoped_ptr<ReportRequest> request(new ReportRequest); |
+ if (device_id_by_auth_token_.empty()) { |
+ VLOG(2) << "Skipping token reporting because no device IDs are registered"; |
+ return; |
+ } |
+ |
+ // Construct the ReportRequest. |
+ ReportRequest request; |
for (const AudioToken& token : tokens) { |
if (invalid_audio_token_cache_.HasKey(ToUrlSafe(token.token))) |
continue; |
- DVLOG(3) << "Sending token " << token.token << " to server."; |
- AddTokenToRequest(request.get(), token); |
+ DVLOG(3) << "Sending token " << token.token << " to server under " |
+ << device_id_by_auth_token_.size() << " device ID(s)"; |
+ AddTokenToRequest(token, &request); |
+ } |
+ |
+ // Report under all active tokens. |
+ for (const auto& registration : device_id_by_auth_token_) { |
+ SendReportRequest(make_scoped_ptr(new ReportRequest(request)), |
+ registration.first); |
} |
- SendReportRequest(request.Pass()); |
} |
void RpcHandler::ConnectToWhispernet() { |
+ // Check if we are already connected. |
+ if (directive_handler_) |
+ return; |
+ |
WhispernetClient* whispernet_client = delegate_->GetWhispernetClient(); |
// |directive_handler_| will be destructed with us, so unretained is safe. |
@@ -257,6 +302,7 @@ void RpcHandler::ConnectToWhispernet() { |
void RpcHandler::RegisterResponseHandler( |
const SuccessCallback& init_done_callback, |
+ const std::string& auth_token, |
HttpPost* completed_post, |
int http_status_code, |
const std::string& response_data) { |
@@ -278,11 +324,16 @@ void RpcHandler::RegisterResponseHandler( |
return; |
} |
- if (CopresenceErrorLogged(response.header().status())) |
+ if (CopresenceErrorLogged(response.header().status())) { |
+ init_done_callback.Run(false); |
return; |
- device_id_ = response.registered_device_id(); |
- DCHECK(!device_id_.empty()); |
- DVLOG(2) << "Device registration successful: id " << device_id_; |
+ } |
+ |
+ const std::string& device_id = response.registered_device_id(); |
+ DCHECK(!device_id.empty()); |
+ device_id_by_auth_token_[auth_token] = device_id; |
+ DVLOG(2) << (auth_token.empty() ? "Anonymous" : "Authenticated") |
+ << " device registration successful: id " << device_id; |
init_done_callback.Run(true); |
} |
@@ -391,9 +442,9 @@ void RpcHandler::AddPlayingTokens(ReportRequest* request) { |
directive_handler_->GetCurrentAudioToken(INAUDIBLE); |
if (!audible_token.empty()) |
- AddTokenToRequest(request, AudioToken(audible_token, true)); |
+ AddTokenToRequest(AudioToken(audible_token, true), request); |
if (!inaudible_token.empty()) |
- AddTokenToRequest(request, AudioToken(inaudible_token, false)); |
+ AddTokenToRequest(AudioToken(inaudible_token, false), request); |
} |
void RpcHandler::DispatchMessages( |
@@ -417,12 +468,13 @@ void RpcHandler::DispatchMessages( |
// it in here and get rid of the app id registry from the main API class. |
const std::string& subscription = map_entry.first; |
const std::vector<Message>& messages = map_entry.second; |
- delegate_->HandleMessages("", subscription, messages); |
+ delegate_->HandleMessages(std::string(), subscription, messages); |
} |
} |
RequestHeader* RpcHandler::CreateRequestHeader( |
- const std::string& client_name) const { |
+ const std::string& client_name, |
+ const std::string& device_id) const { |
RequestHeader* header = new RequestHeader; |
header->set_allocated_framework_version(CreateVersion( |
@@ -432,7 +484,7 @@ RequestHeader* RpcHandler::CreateRequestHeader( |
CreateVersion(client_name, std::string())); |
} |
header->set_current_time_millis(base::Time::Now().ToJsTime()); |
- header->set_registered_device_id(device_id_); |
+ header->set_registered_device_id(device_id); |
DeviceFingerprint* fingerprint = new DeviceFingerprint; |
fingerprint->set_platform_version(delegate_->GetPlatformVersionString()); |
@@ -445,18 +497,24 @@ RequestHeader* RpcHandler::CreateRequestHeader( |
template <class T> |
void RpcHandler::SendServerRequest( |
const std::string& rpc_name, |
+ const std::string& device_id, |
const std::string& app_id, |
+ const std::string& auth_token, |
scoped_ptr<T> request, |
const PostCleanupCallback& response_handler) { |
- request->set_allocated_header(CreateRequestHeader(app_id)); |
+ request->set_allocated_header(CreateRequestHeader(app_id, device_id)); |
server_post_callback_.Run(delegate_->GetRequestContext(), |
rpc_name, |
+ delegate_->GetAPIKey(app_id), |
+ auth_token, |
make_scoped_ptr<MessageLite>(request.release()), |
response_handler); |
} |
void RpcHandler::SendHttpPost(net::URLRequestContextGetter* url_context_getter, |
const std::string& rpc_name, |
+ const std::string& api_key, |
+ const std::string& auth_token, |
scoped_ptr<MessageLite> request_proto, |
const PostCleanupCallback& callback) { |
// Create the base URL to call. |
@@ -471,8 +529,9 @@ void RpcHandler::SendHttpPost(net::URLRequestContextGetter* url_context_getter, |
url_context_getter, |
copresence_server_host, |
rpc_name, |
+ api_key, |
+ auth_token, |
command_line->GetSwitchValueASCII(switches::kCopresenceTracingToken), |
- delegate_->GetAPIKey(), |
*request_proto); |
http_post->Start(base::Bind(callback, http_post)); |