| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "components/copresence/handlers/directive_handler_impl.h" | |
| 6 | |
| 7 #include <utility> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/guid.h" | |
| 11 #include "base/logging.h" | |
| 12 #include "base/memory/ptr_util.h" | |
| 13 #include "base/time/time.h" | |
| 14 #include "components/copresence/handlers/audio/audio_directive_handler_impl.h" | |
| 15 #include "components/copresence/proto/data.pb.h" | |
| 16 | |
| 17 namespace { | |
| 18 | |
| 19 const int kMaxUnlabeledDirectiveTtl = 60000; // 1 minute | |
| 20 | |
| 21 } // namespace | |
| 22 | |
| 23 namespace copresence { | |
| 24 | |
| 25 // Public functions. | |
| 26 | |
| 27 DirectiveHandlerImpl::DirectiveHandlerImpl() | |
| 28 : DirectiveHandlerImpl(base::WrapUnique( | |
| 29 new AudioDirectiveHandlerImpl(DirectivesCallback()))) {} | |
| 30 | |
| 31 DirectiveHandlerImpl::DirectiveHandlerImpl( | |
| 32 const DirectivesCallback& update_directives_callback) | |
| 33 : DirectiveHandlerImpl(base::WrapUnique( | |
| 34 new AudioDirectiveHandlerImpl(update_directives_callback))) {} | |
| 35 | |
| 36 DirectiveHandlerImpl::DirectiveHandlerImpl( | |
| 37 std::unique_ptr<AudioDirectiveHandler> audio_handler) | |
| 38 : audio_handler_(std::move(audio_handler)), is_started_(false) {} | |
| 39 | |
| 40 DirectiveHandlerImpl::~DirectiveHandlerImpl() {} | |
| 41 | |
| 42 void DirectiveHandlerImpl::Start( | |
| 43 audio_modem::WhispernetClient* whispernet_client, | |
| 44 const audio_modem::TokensCallback& tokens_cb) { | |
| 45 audio_handler_->Initialize(whispernet_client, tokens_cb); | |
| 46 DVLOG(2) << "Directive handler starting"; | |
| 47 | |
| 48 is_started_ = true; | |
| 49 | |
| 50 // Run all the queued directives. | |
| 51 for (const auto& op_id : pending_directives_) { | |
| 52 for (const Directive& directive : op_id.second) | |
| 53 StartDirective(op_id.first, directive); | |
| 54 } | |
| 55 pending_directives_.clear(); | |
| 56 } | |
| 57 | |
| 58 void DirectiveHandlerImpl::AddDirective(const Directive& original_directive) { | |
| 59 // We may need to modify the directive's TTL. | |
| 60 Directive directive(original_directive); | |
| 61 | |
| 62 // We only handle transmit and receive directives. | |
| 63 // WiFi and BLE scans aren't implemented. | |
| 64 DCHECK_EQ(directive.instruction_type(), TOKEN); | |
| 65 | |
| 66 std::string op_id = directive.published_message_id(); | |
| 67 if (op_id.empty()) | |
| 68 op_id = directive.subscription_id(); | |
| 69 | |
| 70 // GCM directives will not have a publish or subscribe ID populated. | |
| 71 if (op_id.empty()) { | |
| 72 op_id = base::GenerateGUID(); | |
| 73 DVLOG(3) << "No operation associated with directive. Setting op id to " | |
| 74 << op_id; | |
| 75 | |
| 76 // The app can't cancel these directives, so make sure they're not too long. | |
| 77 if (directive.ttl_millis() > kMaxUnlabeledDirectiveTtl) { | |
| 78 DVLOG(2) << "Cutting TTL of unlabeled directive from " | |
| 79 << directive.ttl_millis() << " down to " | |
| 80 << kMaxUnlabeledDirectiveTtl << " milliseconds"; | |
| 81 directive.set_ttl_millis(kMaxUnlabeledDirectiveTtl); | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 if (!is_started_) { | |
| 86 pending_directives_[op_id].push_back(directive); | |
| 87 } else { | |
| 88 StartDirective(op_id, directive); | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 void DirectiveHandlerImpl::RemoveDirectives(const std::string& op_id) { | |
| 93 // If whispernet_client_ is null, audio_handler_ hasn't been Initialized. | |
| 94 if (is_started_) { | |
| 95 audio_handler_->RemoveInstructions(op_id); | |
| 96 } else { | |
| 97 pending_directives_.erase(op_id); | |
| 98 } | |
| 99 } | |
| 100 | |
| 101 const std::string DirectiveHandlerImpl::GetCurrentAudioToken( | |
| 102 audio_modem::AudioType type) const { | |
| 103 // If whispernet_client_ is null, audio_handler_ hasn't been Initialized. | |
| 104 return is_started_ ? audio_handler_->PlayingToken(type) : ""; | |
| 105 } | |
| 106 | |
| 107 bool DirectiveHandlerImpl::IsAudioTokenHeard( | |
| 108 audio_modem::AudioType type) const { | |
| 109 return is_started_ ? audio_handler_->IsPlayingTokenHeard(type) : false; | |
| 110 } | |
| 111 | |
| 112 | |
| 113 // Private functions. | |
| 114 | |
| 115 void DirectiveHandlerImpl::StartDirective(const std::string& op_id, | |
| 116 const Directive& directive) { | |
| 117 DCHECK(is_started_); | |
| 118 DLOG_IF(WARNING, directive.delay_millis() > 0) | |
| 119 << "Ignoring " << directive.delay_millis() << " delay for directive"; | |
| 120 const TokenMedium& medium = directive.token_instruction().medium(); | |
| 121 DCHECK(medium == AUDIO_ULTRASOUND_PASSBAND || medium == AUDIO_AUDIBLE_DTMF) | |
| 122 << "Received directive for unimplemented medium " << medium; | |
| 123 audio_handler_->AddInstruction(directive, op_id); | |
| 124 } | |
| 125 | |
| 126 } // namespace copresence | |
| OLD | NEW |