| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/copresence/rpc/rpc_handler.h" | 5 #include "components/copresence/rpc/rpc_handler.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/guid.h" | 11 #include "base/guid.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 14 | 14 |
| 15 // TODO(ckehoe): time.h includes windows.h, which #defines DeviceCapabilities | 15 // TODO(ckehoe): time.h includes windows.h, which #defines DeviceCapabilities |
| 16 // to DeviceCapabilitiesW. This breaks the pb.h headers below. For now, | 16 // to DeviceCapabilitiesW. This breaks the pb.h headers below. For now, |
| 17 // we fix this with an #undef. | 17 // we fix this with an #undef. |
| 18 #include "base/time/time.h" | 18 #include "base/time/time.h" |
| 19 #if defined(OS_WIN) | 19 #if defined(OS_WIN) |
| 20 #undef DeviceCapabilities | 20 #undef DeviceCapabilities |
| 21 #endif | 21 #endif |
| 22 | 22 |
| 23 #include "components/copresence/copresence_switches.h" | 23 #include "components/copresence/copresence_switches.h" |
| 24 #include "components/copresence/handlers/directive_handler.h" | 24 #include "components/copresence/handlers/directive_handler.h" |
| 25 #include "components/copresence/proto/codes.pb.h" | 25 #include "components/copresence/proto/codes.pb.h" |
| 26 #include "components/copresence/proto/data.pb.h" | 26 #include "components/copresence/proto/data.pb.h" |
| 27 #include "components/copresence/proto/rpcs.pb.h" | 27 #include "components/copresence/proto/rpcs.pb.h" |
| 28 #include "components/copresence/public/copresence_constants.h" | 28 #include "components/copresence/public/copresence_constants.h" |
| 29 #include "components/copresence/public/copresence_delegate.h" | 29 #include "components/copresence/public/copresence_delegate.h" |
| 30 #include "components/copresence/public/whispernet_client.h" |
| 31 #include "components/copresence/rpc/http_post.h" |
| 30 #include "net/http/http_status_code.h" | 32 #include "net/http/http_status_code.h" |
| 31 | 33 |
| 32 // TODO(ckehoe): Return error messages for bad requests. | 34 // TODO(ckehoe): Return error messages for bad requests. |
| 33 | 35 |
| 34 namespace copresence { | 36 namespace copresence { |
| 35 | 37 |
| 36 using google::protobuf::MessageLite; | 38 using google::protobuf::MessageLite; |
| 37 using google::protobuf::RepeatedPtrField; | 39 using google::protobuf::RepeatedPtrField; |
| 38 | 40 |
| 39 const char RpcHandler::kReportRequestRpcName[] = "report"; | 41 const char RpcHandler::kReportRequestRpcName[] = "report"; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 TokenSignals* signals = token_observation->add_signals(); | 145 TokenSignals* signals = token_observation->add_signals(); |
| 144 signals->set_medium(token.audible ? AUDIO_AUDIBLE_DTMF | 146 signals->set_medium(token.audible ? AUDIO_AUDIBLE_DTMF |
| 145 : AUDIO_ULTRASOUND_PASSBAND); | 147 : AUDIO_ULTRASOUND_PASSBAND); |
| 146 signals->set_observed_time_millis(base::Time::Now().ToJsTime()); | 148 signals->set_observed_time_millis(base::Time::Now().ToJsTime()); |
| 147 } | 149 } |
| 148 | 150 |
| 149 } // namespace | 151 } // namespace |
| 150 | 152 |
| 151 // Public methods | 153 // Public methods |
| 152 | 154 |
| 153 RpcHandler::RpcHandler(CopresenceDelegate* delegate) | 155 RpcHandler::RpcHandler(CopresenceDelegate* delegate, |
| 156 DirectiveHandler* directive_handler) |
| 154 : delegate_(delegate), | 157 : delegate_(delegate), |
| 158 directive_handler_(directive_handler), |
| 155 invalid_audio_token_cache_( | 159 invalid_audio_token_cache_( |
| 156 base::TimeDelta::FromMilliseconds(kInvalidTokenExpiryTimeMs), | 160 base::TimeDelta::FromMilliseconds(kInvalidTokenExpiryTimeMs), |
| 157 kMaxInvalidTokens), | 161 kMaxInvalidTokens), |
| 158 server_post_callback_(base::Bind(&RpcHandler::SendHttpPost, | 162 server_post_callback_(base::Bind(&RpcHandler::SendHttpPost, |
| 159 base::Unretained(this))) {} | 163 base::Unretained(this))) { |
| 164 DCHECK(delegate_); |
| 165 DCHECK(directive_handler_); |
| 166 } |
| 160 | 167 |
| 161 RpcHandler::~RpcHandler() { | 168 RpcHandler::~RpcHandler() { |
| 162 for (HttpPost* post : pending_posts_) { | 169 for (HttpPost* post : pending_posts_) { |
| 163 delete post; | 170 delete post; |
| 164 } | 171 } |
| 165 | 172 |
| 166 if (delegate_ && delegate_->GetWhispernetClient()) { | 173 if (delegate_->GetWhispernetClient()) { |
| 174 // TODO(ckehoe): Use CancelableCallbacks instead. |
| 167 delegate_->GetWhispernetClient()->RegisterTokensCallback( | 175 delegate_->GetWhispernetClient()->RegisterTokensCallback( |
| 168 WhispernetClient::TokensCallback()); | 176 WhispernetClient::TokensCallback()); |
| 169 delegate_->GetWhispernetClient()->RegisterSamplesCallback( | 177 delegate_->GetWhispernetClient()->RegisterSamplesCallback( |
| 170 WhispernetClient::SamplesCallback()); | 178 WhispernetClient::SamplesCallback()); |
| 171 } | 179 } |
| 172 } | 180 } |
| 173 | 181 |
| 174 void RpcHandler::RegisterForToken(const std::string& auth_token, | 182 void RpcHandler::RegisterForToken(const std::string& auth_token, |
| 175 const SuccessCallback& init_done_callback) { | 183 const SuccessCallback& init_done_callback) { |
| 176 if (IsRegisteredForToken(auth_token)) { | 184 if (IsRegisteredForToken(auth_token)) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 AddTokenToRequest(token, &request); | 278 AddTokenToRequest(token, &request); |
| 271 } | 279 } |
| 272 | 280 |
| 273 // Report under all active tokens. | 281 // Report under all active tokens. |
| 274 for (const auto& registration : device_id_by_auth_token_) { | 282 for (const auto& registration : device_id_by_auth_token_) { |
| 275 SendReportRequest(make_scoped_ptr(new ReportRequest(request)), | 283 SendReportRequest(make_scoped_ptr(new ReportRequest(request)), |
| 276 registration.first); | 284 registration.first); |
| 277 } | 285 } |
| 278 } | 286 } |
| 279 | 287 |
| 280 void RpcHandler::ConnectToWhispernet() { | |
| 281 // Check if we are already connected. | |
| 282 if (directive_handler_) | |
| 283 return; | |
| 284 | |
| 285 WhispernetClient* whispernet_client = delegate_->GetWhispernetClient(); | |
| 286 | |
| 287 // |directive_handler_| will be destructed with us, so unretained is safe. | |
| 288 directive_handler_.reset(new DirectiveHandler); | |
| 289 directive_handler_->Initialize( | |
| 290 base::Bind(&WhispernetClient::DecodeSamples, | |
| 291 base::Unretained(whispernet_client)), | |
| 292 base::Bind(&RpcHandler::AudioDirectiveListToWhispernetConnector, | |
| 293 base::Unretained(this))); | |
| 294 | |
| 295 whispernet_client->RegisterTokensCallback( | |
| 296 base::Bind(&RpcHandler::ReportTokens, | |
| 297 // On destruction, this callback will be disconnected. | |
| 298 base::Unretained(this))); | |
| 299 } | |
| 300 | |
| 301 // Private methods | 288 // Private methods |
| 302 | 289 |
| 303 void RpcHandler::RegisterResponseHandler( | 290 void RpcHandler::RegisterResponseHandler( |
| 304 const SuccessCallback& init_done_callback, | 291 const SuccessCallback& init_done_callback, |
| 305 const std::string& auth_token, | 292 const std::string& auth_token, |
| 306 HttpPost* completed_post, | 293 HttpPost* completed_post, |
| 307 int http_status_code, | 294 int http_status_code, |
| 308 const std::string& response_data) { | 295 const std::string& response_data) { |
| 309 if (completed_post) { | 296 if (completed_post) { |
| 310 int elements_erased = pending_posts_.erase(completed_post); | 297 int elements_erased = pending_posts_.erase(completed_post); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 for (const SubscriptionResult& result : | 363 for (const SubscriptionResult& result : |
| 377 response.manage_subscriptions_response().subscription_result()) { | 364 response.manage_subscriptions_response().subscription_result()) { |
| 378 DVLOG(2) << "Created subscription with id " << result.subscription_id(); | 365 DVLOG(2) << "Created subscription with id " << result.subscription_id(); |
| 379 } | 366 } |
| 380 | 367 |
| 381 if (response.has_update_signals_response()) { | 368 if (response.has_update_signals_response()) { |
| 382 const UpdateSignalsResponse& update_response = | 369 const UpdateSignalsResponse& update_response = |
| 383 response.update_signals_response(); | 370 response.update_signals_response(); |
| 384 DispatchMessages(update_response.message()); | 371 DispatchMessages(update_response.message()); |
| 385 | 372 |
| 386 if (directive_handler_.get()) { | 373 for (const Directive& directive : update_response.directive()) |
| 387 for (const Directive& directive : update_response.directive()) | 374 directive_handler_->AddDirective(directive); |
| 388 directive_handler_->AddDirective(directive); | |
| 389 } else { | |
| 390 DVLOG(1) << "No directive handler."; | |
| 391 } | |
| 392 | 375 |
| 393 for (const Token& token : update_response.token()) { | 376 for (const Token& token : update_response.token()) { |
| 394 switch (token.status()) { | 377 switch (token.status()) { |
| 395 case VALID: | 378 case VALID: |
| 396 // TODO(rkc/ckehoe): Store the token in a |valid_token_cache_| with a | 379 // TODO(rkc/ckehoe): Store the token in a |valid_token_cache_| with a |
| 397 // short TTL (like 10s) and send it up with every report request. | 380 // short TTL (like 10s) and send it up with every report request. |
| 398 // Then we'll still get messages while we're waiting to hear it again. | 381 // Then we'll still get messages while we're waiting to hear it again. |
| 399 VLOG(1) << "Got valid token " << token.id(); | 382 VLOG(1) << "Got valid token " << token.id(); |
| 400 break; | 383 break; |
| 401 case INVALID: | 384 case INVALID: |
| (...skipping 24 matching lines...) Expand all Loading... |
| 426 // Remove unsubscribes. | 409 // Remove unsubscribes. |
| 427 if (request.has_manage_subscriptions_request()) { | 410 if (request.has_manage_subscriptions_request()) { |
| 428 for (const std::string& unsubscribe : | 411 for (const std::string& unsubscribe : |
| 429 request.manage_subscriptions_request().id_to_unsubscribe()) { | 412 request.manage_subscriptions_request().id_to_unsubscribe()) { |
| 430 directive_handler_->RemoveDirectives(unsubscribe); | 413 directive_handler_->RemoveDirectives(unsubscribe); |
| 431 } | 414 } |
| 432 } | 415 } |
| 433 } | 416 } |
| 434 | 417 |
| 435 void RpcHandler::AddPlayingTokens(ReportRequest* request) { | 418 void RpcHandler::AddPlayingTokens(ReportRequest* request) { |
| 436 if (!directive_handler_) | |
| 437 return; | |
| 438 | |
| 439 const std::string& audible_token = | 419 const std::string& audible_token = |
| 440 directive_handler_->GetCurrentAudioToken(AUDIBLE); | 420 directive_handler_->GetCurrentAudioToken(AUDIBLE); |
| 441 const std::string& inaudible_token = | 421 const std::string& inaudible_token = |
| 442 directive_handler_->GetCurrentAudioToken(INAUDIBLE); | 422 directive_handler_->GetCurrentAudioToken(INAUDIBLE); |
| 443 | 423 |
| 444 if (!audible_token.empty()) | 424 if (!audible_token.empty()) |
| 445 AddTokenToRequest(AudioToken(audible_token, true), request); | 425 AddTokenToRequest(AudioToken(audible_token, true), request); |
| 446 if (!inaudible_token.empty()) | 426 if (!inaudible_token.empty()) |
| 447 AddTokenToRequest(AudioToken(inaudible_token, false), request); | 427 AddTokenToRequest(AudioToken(inaudible_token, false), request); |
| 448 } | 428 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 465 // Send the messages for each subscription. | 445 // Send the messages for each subscription. |
| 466 for (const auto& map_entry : messages_by_subscription) { | 446 for (const auto& map_entry : messages_by_subscription) { |
| 467 // TODO(ckehoe): Once we have the app ID from the server, we need to pass | 447 // TODO(ckehoe): Once we have the app ID from the server, we need to pass |
| 468 // it in here and get rid of the app id registry from the main API class. | 448 // it in here and get rid of the app id registry from the main API class. |
| 469 const std::string& subscription = map_entry.first; | 449 const std::string& subscription = map_entry.first; |
| 470 const std::vector<Message>& messages = map_entry.second; | 450 const std::vector<Message>& messages = map_entry.second; |
| 471 delegate_->HandleMessages(std::string(), subscription, messages); | 451 delegate_->HandleMessages(std::string(), subscription, messages); |
| 472 } | 452 } |
| 473 } | 453 } |
| 474 | 454 |
| 455 // TODO(ckehoe): Pass in the version string and |
| 456 // group this with the local functions up top. |
| 475 RequestHeader* RpcHandler::CreateRequestHeader( | 457 RequestHeader* RpcHandler::CreateRequestHeader( |
| 476 const std::string& client_name, | 458 const std::string& client_name, |
| 477 const std::string& device_id) const { | 459 const std::string& device_id) const { |
| 478 RequestHeader* header = new RequestHeader; | 460 RequestHeader* header = new RequestHeader; |
| 479 | 461 |
| 480 header->set_allocated_framework_version(CreateVersion( | 462 header->set_allocated_framework_version(CreateVersion( |
| 481 "Chrome", delegate_->GetPlatformVersionString())); | 463 "Chrome", delegate_->GetPlatformVersionString())); |
| 482 if (!client_name.empty()) { | 464 if (!client_name.empty()) { |
| 483 header->set_allocated_client_version( | 465 header->set_allocated_client_version( |
| 484 CreateVersion(client_name, std::string())); | 466 CreateVersion(client_name, std::string())); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 rpc_name, | 513 rpc_name, |
| 532 api_key, | 514 api_key, |
| 533 auth_token, | 515 auth_token, |
| 534 command_line->GetSwitchValueASCII(switches::kCopresenceTracingToken), | 516 command_line->GetSwitchValueASCII(switches::kCopresenceTracingToken), |
| 535 *request_proto); | 517 *request_proto); |
| 536 | 518 |
| 537 http_post->Start(base::Bind(callback, http_post)); | 519 http_post->Start(base::Bind(callback, http_post)); |
| 538 pending_posts_.insert(http_post); | 520 pending_posts_.insert(http_post); |
| 539 } | 521 } |
| 540 | 522 |
| 541 void RpcHandler::AudioDirectiveListToWhispernetConnector( | |
| 542 const std::string& token, | |
| 543 AudioType type, | |
| 544 const WhispernetClient::SamplesCallback& samples_callback) { | |
| 545 DCHECK(type == AUDIBLE || type == INAUDIBLE); | |
| 546 WhispernetClient* whispernet_client = delegate_->GetWhispernetClient(); | |
| 547 if (whispernet_client) { | |
| 548 whispernet_client->RegisterSamplesCallback(samples_callback); | |
| 549 whispernet_client->EncodeToken(token, type); | |
| 550 } | |
| 551 } | |
| 552 | |
| 553 } // namespace copresence | 523 } // namespace copresence |
| OLD | NEW |