Index: components/copresence/copresence_manager_impl.cc |
diff --git a/components/copresence/copresence_manager_impl.cc b/components/copresence/copresence_manager_impl.cc |
deleted file mode 100644 |
index 956391f39c68193ca256e7dddf4b6d9d4c34ec0d..0000000000000000000000000000000000000000 |
--- a/components/copresence/copresence_manager_impl.cc |
+++ /dev/null |
@@ -1,270 +0,0 @@ |
-// Copyright 2014 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "components/copresence/copresence_manager_impl.h" |
- |
-#include <map> |
-#include <utility> |
-#include <vector> |
- |
-#include "base/bind.h" |
-#include "base/strings/stringprintf.h" |
-#include "base/time/time.h" |
-#include "base/timer/timer.h" |
-#include "components/audio_modem/public/whispernet_client.h" |
-#include "components/copresence/copresence_state_impl.h" |
-#include "components/copresence/handlers/directive_handler_impl.h" |
-#include "components/copresence/handlers/gcm_handler_impl.h" |
-#include "components/copresence/proto/rpcs.pb.h" |
-#include "components/copresence/rpc/rpc_handler.h" |
- |
-using google::protobuf::RepeatedPtrField; |
- |
-using audio_modem::AUDIBLE; |
-using audio_modem::AudioToken; |
-using audio_modem::INAUDIBLE; |
- |
-namespace { |
- |
-const int kPollTimerIntervalMs = 3000; // milliseconds. |
-const int kAudioCheckIntervalMs = 1000; // milliseconds. |
- |
-const int kQueuedMessageTimeout = 10; // seconds. |
-const int kMaxQueuedMessages = 1000; |
- |
-} // namespace |
- |
-namespace copresence { |
- |
-bool SupportedTokenMedium(const TokenObservation& token) { |
- for (const TokenSignals& signals : token.signals()) { |
- if (signals.medium() == AUDIO_ULTRASOUND_PASSBAND || |
- signals.medium() == AUDIO_AUDIBLE_DTMF) |
- return true; |
- } |
- return false; |
-} |
- |
- |
-// Public functions. |
- |
-CopresenceManagerImpl::CopresenceManagerImpl(CopresenceDelegate* delegate) |
- : delegate_(delegate), |
- whispernet_init_callback_( |
- base::Bind(&CopresenceManagerImpl::WhispernetInitComplete, |
- // This callback gets cancelled when we are destroyed. |
- base::Unretained(this))), |
- init_failed_(false), |
- state_(new CopresenceStateImpl), |
- directive_handler_(new DirectiveHandlerImpl( |
- // The directive handler and its descendants |
- // will be destructed before the CopresenceState instance. |
- base::Bind(&CopresenceStateImpl::UpdateDirectives, |
- base::Unretained(state_.get())))), |
- poll_timer_(new base::RepeatingTimer), |
- audio_check_timer_(new base::RepeatingTimer), |
- queued_messages_by_token_( |
- base::TimeDelta::FromSeconds(kQueuedMessageTimeout), |
- kMaxQueuedMessages) { |
- DCHECK(delegate_); |
- DCHECK(delegate_->GetWhispernetClient()); |
- // TODO(ckehoe): Handle whispernet initialization in the whispernet component. |
- delegate_->GetWhispernetClient()->Initialize( |
- whispernet_init_callback_.callback()); |
- |
- MessagesCallback messages_callback = base::Bind( |
- &CopresenceManagerImpl::DispatchMessages, |
- // This will only be passed to objects that we own. |
- base::Unretained(this)); |
- |
- if (delegate->GetGCMDriver()) |
- gcm_handler_.reset(new GCMHandlerImpl(delegate->GetGCMDriver(), |
- directive_handler_.get(), |
- messages_callback)); |
- |
- rpc_handler_.reset(new RpcHandler(delegate, |
- directive_handler_.get(), |
- state_.get(), |
- gcm_handler_.get(), |
- messages_callback)); |
- |
- directive_handler_->Start(delegate_->GetWhispernetClient(), |
- base::Bind(&CopresenceManagerImpl::ReceivedTokens, |
- base::Unretained(this))); |
-} |
- |
-CopresenceManagerImpl::~CopresenceManagerImpl() { |
- whispernet_init_callback_.Cancel(); |
-} |
- |
-CopresenceState* CopresenceManagerImpl::state() { |
- return state_.get(); |
-} |
- |
-// Returns false if any operations were malformed. |
-void CopresenceManagerImpl::ExecuteReportRequest( |
- const ReportRequest& request, |
- const std::string& app_id, |
- const std::string& auth_token, |
- const StatusCallback& callback) { |
- // If initialization has failed, reject all requests. |
- if (init_failed_) { |
- callback.Run(FAIL); |
- return; |
- } |
- |
- // We'll need to modify the ReportRequest, so we make our own copy to send. |
- std::unique_ptr<ReportRequest> request_copy(new ReportRequest(request)); |
- rpc_handler_->SendReportRequest(std::move(request_copy), app_id, auth_token, |
- callback); |
-} |
- |
- |
-// Private functions. |
- |
-void CopresenceManagerImpl::WhispernetInitComplete(bool success) { |
- if (success) { |
- DVLOG(3) << "Whispernet initialized successfully."; |
- poll_timer_->Start(FROM_HERE, |
- base::TimeDelta::FromMilliseconds(kPollTimerIntervalMs), |
- base::Bind(&CopresenceManagerImpl::PollForMessages, |
- base::Unretained(this))); |
- audio_check_timer_->Start( |
- FROM_HERE, base::TimeDelta::FromMilliseconds(kAudioCheckIntervalMs), |
- base::Bind(&CopresenceManagerImpl::AudioCheck, base::Unretained(this))); |
- } else { |
- LOG(ERROR) << "Whispernet initialization failed!"; |
- init_failed_ = true; |
- } |
-} |
- |
-void CopresenceManagerImpl::ReceivedTokens( |
- const std::vector<AudioToken>& tokens) { |
- rpc_handler_->ReportTokens(tokens); |
- |
- for (const AudioToken audio_token : tokens) { |
- const std::string& token_id = audio_token.token; |
- DVLOG(3) << "Heard token: " << token_id; |
- |
- // Update the CopresenceState. |
- ReceivedToken token( |
- token_id, |
- audio_token.audible ? AUDIO_AUDIBLE_DTMF : AUDIO_ULTRASOUND_PASSBAND, |
- base::Time::Now()); |
- state_->UpdateReceivedToken(token); |
- |
- // Deliver messages that were pre-sent on this token. |
- if (queued_messages_by_token_.HasKey(token_id)) { |
- // Not const because we have to remove the required tokens for delivery. |
- // We're going to delete this whole vector at the end anyway. |
- RepeatedPtrField<SubscribedMessage>* messages = |
- queued_messages_by_token_.GetMutableValue(token_id); |
- DCHECK_GT(messages->size(), 0) |
- << "Empty entry in queued_messages_by_token_"; |
- |
- // These messages still have their required tokens stored, and |
- // DispatchMessages() will still check for them. If we don't remove |
- // the tokens before delivery, we'll just end up re-queuing the message. |
- for (SubscribedMessage& message : *messages) |
- message.mutable_required_token()->Clear(); |
- |
- DVLOG(3) << "Delivering " << messages->size() |
- << " message(s) pre-sent on token " << token_id; |
- DispatchMessages(*messages); |
- |
- // The messages have been delivered, so we don't need to keep them |
- // in the queue. Note that the token will still be reported |
- // to the server (above), so we'll keep getting the message. |
- // But we can now drop our local copy of it. |
- int erase_count = queued_messages_by_token_.Erase(token_id); |
- DCHECK_GT(erase_count, 0); |
- } |
- } |
-} |
- |
-void CopresenceManagerImpl::AudioCheck() { |
- if (!directive_handler_->GetCurrentAudioToken(AUDIBLE).empty() && |
- !directive_handler_->IsAudioTokenHeard(AUDIBLE)) { |
- delegate_->HandleStatusUpdate(AUDIO_FAIL); |
- } else if (!directive_handler_->GetCurrentAudioToken(INAUDIBLE).empty() && |
- !directive_handler_->IsAudioTokenHeard(INAUDIBLE)) { |
- delegate_->HandleStatusUpdate(AUDIO_FAIL); |
- } |
-} |
- |
-// Report our currently playing tokens to the server. |
-void CopresenceManagerImpl::PollForMessages() { |
- const std::string& audible_token = |
- directive_handler_->GetCurrentAudioToken(AUDIBLE); |
- const std::string& inaudible_token = |
- directive_handler_->GetCurrentAudioToken(INAUDIBLE); |
- |
- std::vector<AudioToken> tokens; |
- if (!audible_token.empty()) |
- tokens.push_back(AudioToken(audible_token, true)); |
- if (!inaudible_token.empty()) |
- tokens.push_back(AudioToken(inaudible_token, false)); |
- |
- if (!tokens.empty()) |
- rpc_handler_->ReportTokens(tokens); |
-} |
- |
-void CopresenceManagerImpl::DispatchMessages( |
- const RepeatedPtrField<SubscribedMessage>& messages) { |
- if (messages.size() == 0) |
- return; |
- |
- // Index the messages by subscription id. |
- std::map<std::string, std::vector<Message>> messages_by_subscription; |
- DVLOG(3) << "Processing " << messages.size() << " received message(s)."; |
- int immediate_message_count = 0; |
- for (const SubscribedMessage& message : messages) { |
- // If tokens are required for this message, queue it. |
- // Otherwise stage it for delivery. |
- if (message.required_token_size() > 0) { |
- int supported_token_count = 0; |
- for (const TokenObservation& token : message.required_token()) { |
- if (SupportedTokenMedium(token)) { |
- if (!queued_messages_by_token_.HasKey(token.token_id())) { |
- queued_messages_by_token_.Add( |
- token.token_id(), RepeatedPtrField<SubscribedMessage>()); |
- } |
- RepeatedPtrField<SubscribedMessage>* queued_messages = |
- queued_messages_by_token_.GetMutableValue(token.token_id()); |
- DCHECK(queued_messages); |
- queued_messages->Add()->CopyFrom(message); |
- supported_token_count++; |
- } |
- } |
- |
- if (supported_token_count > 0) { |
- DVLOG(3) << "Queued message under " << supported_token_count |
- << "token(s)."; |
- } else { |
- VLOG(2) << "Discarded message that requires one of " |
- << message.required_token_size() |
- << " token(s), all on unsupported mediums."; |
- } |
- } else { |
- immediate_message_count++; |
- for (const std::string& subscription_id : message.subscription_id()) { |
- messages_by_subscription[subscription_id].push_back( |
- message.published_message()); |
- } |
- } |
- } |
- |
- // Send the messages for each subscription. |
- DVLOG(3) << "Dispatching " << immediate_message_count << "message(s) for " |
- << messages_by_subscription.size() << " subscription(s)."; |
- for (const auto& map_entry : messages_by_subscription) { |
- // TODO(ckehoe): Once we have the app ID from the server, we need to pass |
- // 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(std::string(), subscription, messages); |
- } |
-} |
- |
-} // namespace copresence |