| 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/handlers/directive_handler.h" | 5 #include "components/copresence/handlers/directive_handler.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
| 10 #include "components/copresence/handlers/audio/audio_directive_handler_impl.h" | 10 #include "components/copresence/handlers/audio/audio_directive_handler_impl.h" |
| 11 #include "components/copresence/proto/data.pb.h" | 11 #include "components/copresence/proto/data.pb.h" |
| 12 | 12 |
| 13 namespace copresence { | 13 namespace copresence { |
| 14 | 14 |
| 15 // Public functions | 15 // Public functions |
| 16 | 16 |
| 17 DirectiveHandler::DirectiveHandler() | 17 DirectiveHandler::DirectiveHandler() |
| 18 : audio_handler_(new AudioDirectiveHandlerImpl), | 18 : audio_handler_(new AudioDirectiveHandlerImpl), is_started_(false) { |
| 19 whispernet_client_(nullptr) {} | 19 } |
| 20 | 20 |
| 21 DirectiveHandler::~DirectiveHandler() {} | 21 DirectiveHandler::~DirectiveHandler() {} |
| 22 | 22 |
| 23 void DirectiveHandler::Start(WhispernetClient* whispernet_client) { | 23 void DirectiveHandler::Start(WhispernetClient* whispernet_client, |
| 24 const TokensCallback& tokens_cb) { |
| 24 DCHECK(whispernet_client); | 25 DCHECK(whispernet_client); |
| 25 whispernet_client_ = whispernet_client; | 26 audio_handler_->Initialize(whispernet_client, tokens_cb); |
| 26 | 27 |
| 27 // TODO(ckehoe): Just pass Whispernet all the way down to the AudioManager. | 28 is_started_ = true; |
| 28 // We shouldn't be concerned with these details here. | |
| 29 audio_handler_->Initialize( | |
| 30 base::Bind(&WhispernetClient::DecodeSamples, | |
| 31 base::Unretained(whispernet_client_)), | |
| 32 base::Bind(&DirectiveHandler::EncodeToken, | |
| 33 base::Unretained(this))); | |
| 34 | 29 |
| 35 // Run all the queued directives. | 30 // Run all the queued directives. |
| 36 for (const auto& op_id : pending_directives_) { | 31 for (const auto& op_id : pending_directives_) { |
| 37 for (const Directive& directive : op_id.second) { | 32 for (const Directive& directive : op_id.second) |
| 38 StartDirective(op_id.first, directive); | 33 StartDirective(op_id.first, directive); |
| 39 } | |
| 40 } | 34 } |
| 41 pending_directives_.clear(); | 35 pending_directives_.clear(); |
| 42 } | 36 } |
| 43 | 37 |
| 44 void DirectiveHandler::AddDirective(const Directive& directive) { | 38 void DirectiveHandler::AddDirective(const Directive& directive) { |
| 45 // We only handle transmit and receive directives. | 39 // We only handle transmit and receive directives. |
| 46 // WiFi and BLE scans aren't implemented. | 40 // WiFi and BLE scans aren't implemented. |
| 47 DCHECK_EQ(directive.instruction_type(), TOKEN); | 41 DCHECK_EQ(directive.instruction_type(), TOKEN); |
| 48 | 42 |
| 49 std::string op_id; | 43 std::string op_id; |
| 50 if (directive.has_published_message_id()) { | 44 if (directive.has_published_message_id()) { |
| 51 op_id = directive.published_message_id(); | 45 op_id = directive.published_message_id(); |
| 52 } else if (directive.has_subscription_id()) { | 46 } else if (directive.has_subscription_id()) { |
| 53 op_id = directive.subscription_id(); | 47 op_id = directive.subscription_id(); |
| 54 } else { | 48 } else { |
| 55 NOTREACHED() << "No operation associated with directive!"; | 49 NOTREACHED() << "No operation associated with directive!"; |
| 56 return; | 50 return; |
| 57 } | 51 } |
| 58 | 52 |
| 59 if (!whispernet_client_) { | 53 if (!is_started_) { |
| 60 pending_directives_[op_id].push_back(directive); | 54 pending_directives_[op_id].push_back(directive); |
| 61 } else { | 55 } else { |
| 62 StartDirective(op_id, directive); | 56 StartDirective(op_id, directive); |
| 63 } | 57 } |
| 64 } | 58 } |
| 65 | 59 |
| 66 void DirectiveHandler::RemoveDirectives(const std::string& op_id) { | 60 void DirectiveHandler::RemoveDirectives(const std::string& op_id) { |
| 67 // If whispernet_client_ is null, audio_handler_ hasn't been Initialized. | 61 // If whispernet_client_ is null, audio_handler_ hasn't been Initialized. |
| 68 if (whispernet_client_) { | 62 if (is_started_) { |
| 69 audio_handler_->RemoveInstructions(op_id); | 63 audio_handler_->RemoveInstructions(op_id); |
| 70 } else { | 64 } else { |
| 71 pending_directives_.erase(op_id); | 65 pending_directives_.erase(op_id); |
| 72 } | 66 } |
| 73 } | 67 } |
| 74 | 68 |
| 75 const std::string DirectiveHandler::GetCurrentAudioToken(AudioType type) const { | 69 const std::string DirectiveHandler::GetCurrentAudioToken(AudioType type) const { |
| 76 // If whispernet_client_ is null, audio_handler_ hasn't been Initialized. | 70 // If whispernet_client_ is null, audio_handler_ hasn't been Initialized. |
| 77 return whispernet_client_ ? audio_handler_->PlayingToken(type) : ""; | 71 return is_started_ ? audio_handler_->PlayingToken(type) : ""; |
| 78 } | 72 } |
| 79 | 73 |
| 74 bool DirectiveHandler::IsAudioTokenHeard(AudioType type) const { |
| 75 return is_started_ ? audio_handler_->IsPlayingTokenHeard(type) : false; |
| 76 } |
| 80 | 77 |
| 81 // Private functions | 78 // Private functions |
| 82 | 79 |
| 83 void DirectiveHandler::StartDirective(const std::string& op_id, | 80 void DirectiveHandler::StartDirective(const std::string& op_id, |
| 84 const Directive& directive) { | 81 const Directive& directive) { |
| 85 const TokenInstruction& ti = directive.token_instruction(); | 82 const TokenInstruction& ti = directive.token_instruction(); |
| 86 if (ti.medium() == AUDIO_ULTRASOUND_PASSBAND || | 83 if (ti.medium() == AUDIO_ULTRASOUND_PASSBAND || |
| 87 ti.medium() == AUDIO_AUDIBLE_DTMF) { | 84 ti.medium() == AUDIO_AUDIBLE_DTMF) { |
| 88 audio_handler_->AddInstruction( | 85 audio_handler_->AddInstruction( |
| 89 ti, op_id, base::TimeDelta::FromMilliseconds(directive.ttl_millis())); | 86 ti, op_id, base::TimeDelta::FromMilliseconds(directive.ttl_millis())); |
| 90 } else { | 87 } else { |
| 91 // We should only get audio directives. | 88 // We should only get audio directives. |
| 92 NOTREACHED() << "Received directive for unimplemented medium " | 89 NOTREACHED() << "Received directive for unimplemented medium " |
| 93 << ti.medium(); | 90 << ti.medium(); |
| 94 } | 91 } |
| 95 } | 92 } |
| 96 | 93 |
| 97 // TODO(ckehoe): We don't need to re-register the samples callback | |
| 98 // every time. Which means this whole function is unnecessary. | |
| 99 void DirectiveHandler::EncodeToken( | |
| 100 const std::string& token, | |
| 101 AudioType type, | |
| 102 const WhispernetClient::SamplesCallback& samples_callback) { | |
| 103 DCHECK(type == AUDIBLE || type == INAUDIBLE); | |
| 104 // TODO(ckehoe): This null check shouldn't be necessary. | |
| 105 // It's only here for tests. | |
| 106 if (whispernet_client_) { | |
| 107 whispernet_client_->RegisterSamplesCallback(samples_callback); | |
| 108 whispernet_client_->EncodeToken(token, type); | |
| 109 } | |
| 110 } | |
| 111 | |
| 112 } // namespace copresence | 94 } // namespace copresence |
| OLD | NEW |