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 |