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