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 |