| 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 scoped_ptr<AudioDirectiveHandler> audio_handler) | 18 scoped_ptr<AudioDirectiveHandler> audio_handler) |
| 19 : audio_handler_(audio_handler.Pass()), | 19 : audio_handler_(audio_handler.Pass()), is_started_(false) { |
| 20 whispernet_client_(nullptr) {} | 20 } |
| 21 | 21 |
| 22 DirectiveHandler::~DirectiveHandler() {} | 22 DirectiveHandler::~DirectiveHandler() {} |
| 23 | 23 |
| 24 void DirectiveHandler::Start(WhispernetClient* whispernet_client) { | 24 void DirectiveHandler::Start(WhispernetClient* whispernet_client, |
| 25 DCHECK(whispernet_client); | 25 const TokensCallback& tokens_cb) { |
| 26 whispernet_client_ = whispernet_client; | 26 audio_handler_->Initialize(whispernet_client, tokens_cb); |
| 27 | 27 |
| 28 // TODO(ckehoe): Just pass Whispernet all the way down to the AudioManager. | 28 is_started_ = true; |
| 29 // We shouldn't be concerned with these details here. | |
| 30 audio_handler_->Initialize( | |
| 31 base::Bind(&WhispernetClient::DecodeSamples, | |
| 32 base::Unretained(whispernet_client_)), | |
| 33 base::Bind(&DirectiveHandler::EncodeToken, | |
| 34 base::Unretained(this))); | |
| 35 | 29 |
| 36 // Run all the queued directives. | 30 // Run all the queued directives. |
| 37 for (const auto& op_id : pending_directives_) { | 31 for (const auto& op_id : pending_directives_) { |
| 38 for (const Directive& directive : op_id.second) { | 32 for (const Directive& directive : op_id.second) |
| 39 StartDirective(op_id.first, directive); | 33 StartDirective(op_id.first, directive); |
| 40 } | |
| 41 } | 34 } |
| 42 pending_directives_.clear(); | 35 pending_directives_.clear(); |
| 43 } | 36 } |
| 44 | 37 |
| 45 void DirectiveHandler::AddDirective(const Directive& directive) { | 38 void DirectiveHandler::AddDirective(const Directive& directive) { |
| 46 // We only handle transmit and receive directives. | 39 // We only handle transmit and receive directives. |
| 47 // WiFi and BLE scans aren't implemented. | 40 // WiFi and BLE scans aren't implemented. |
| 48 DCHECK_EQ(directive.instruction_type(), TOKEN); | 41 DCHECK_EQ(directive.instruction_type(), TOKEN); |
| 49 | 42 |
| 50 std::string op_id = directive.published_message_id(); | 43 std::string op_id = directive.published_message_id(); |
| 51 if (op_id.empty()) | 44 if (op_id.empty()) |
| 52 op_id = directive.subscription_id(); | 45 op_id = directive.subscription_id(); |
| 53 if (op_id.empty()) { | 46 if (op_id.empty()) { |
| 54 NOTREACHED() << "No operation associated with directive!"; | 47 NOTREACHED() << "No operation associated with directive!"; |
| 55 return; | 48 return; |
| 56 } | 49 } |
| 57 | 50 |
| 58 if (!whispernet_client_) { | 51 if (!is_started_) { |
| 59 pending_directives_[op_id].push_back(directive); | 52 pending_directives_[op_id].push_back(directive); |
| 60 } else { | 53 } else { |
| 61 StartDirective(op_id, directive); | 54 StartDirective(op_id, directive); |
| 62 } | 55 } |
| 63 } | 56 } |
| 64 | 57 |
| 65 void DirectiveHandler::RemoveDirectives(const std::string& op_id) { | 58 void DirectiveHandler::RemoveDirectives(const std::string& op_id) { |
| 66 // If whispernet_client_ is null, audio_handler_ hasn't been Initialized. | 59 // If whispernet_client_ is null, audio_handler_ hasn't been Initialized. |
| 67 if (whispernet_client_) { | 60 if (is_started_) { |
| 68 audio_handler_->RemoveInstructions(op_id); | 61 audio_handler_->RemoveInstructions(op_id); |
| 69 } else { | 62 } else { |
| 70 pending_directives_.erase(op_id); | 63 pending_directives_.erase(op_id); |
| 71 } | 64 } |
| 72 } | 65 } |
| 73 | 66 |
| 74 const std::string DirectiveHandler::GetCurrentAudioToken(AudioType type) const { | 67 const std::string DirectiveHandler::GetCurrentAudioToken(AudioType type) const { |
| 75 // If whispernet_client_ is null, audio_handler_ hasn't been Initialized. | 68 // If whispernet_client_ is null, audio_handler_ hasn't been Initialized. |
| 76 return whispernet_client_ ? audio_handler_->PlayingToken(type) : ""; | 69 return is_started_ ? audio_handler_->PlayingToken(type) : ""; |
| 77 } | 70 } |
| 78 | 71 |
| 72 bool DirectiveHandler::IsAudioTokenHeard(AudioType type) const { |
| 73 return is_started_ ? audio_handler_->IsPlayingTokenHeard(type) : false; |
| 74 } |
| 79 | 75 |
| 80 // Private functions | 76 // Private functions |
| 81 | 77 |
| 82 void DirectiveHandler::StartDirective(const std::string& op_id, | 78 void DirectiveHandler::StartDirective(const std::string& op_id, |
| 83 const Directive& directive) { | 79 const Directive& directive) { |
| 84 DCHECK(whispernet_client_); | 80 DCHECK(is_started_); |
| 85 const TokenInstruction& ti = directive.token_instruction(); | 81 const TokenInstruction& ti = directive.token_instruction(); |
| 86 if (ti.medium() == AUDIO_ULTRASOUND_PASSBAND || | 82 if (ti.medium() == AUDIO_ULTRASOUND_PASSBAND || |
| 87 ti.medium() == AUDIO_AUDIBLE_DTMF) { | 83 ti.medium() == AUDIO_AUDIBLE_DTMF) { |
| 88 audio_handler_->AddInstruction( | 84 audio_handler_->AddInstruction( |
| 89 ti, op_id, base::TimeDelta::FromMilliseconds(directive.ttl_millis())); | 85 ti, op_id, base::TimeDelta::FromMilliseconds(directive.ttl_millis())); |
| 90 } else { | 86 } else { |
| 91 // We should only get audio directives. | 87 // We should only get audio directives. |
| 92 NOTREACHED() << "Received directive for unimplemented medium " | 88 NOTREACHED() << "Received directive for unimplemented medium " |
| 93 << ti.medium(); | 89 << ti.medium(); |
| 94 } | 90 } |
| 95 } | 91 } |
| 96 | 92 |
| 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 | 93 } // namespace copresence |
| OLD | NEW |