Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: components/copresence/handlers/audio/audio_directive_handler_impl.cc

Issue 690213004: Refactoring AudioDirectiveHandler to support testing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixing crash Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/audio/audio_directive_handler.h" 5 #include "components/copresence/handlers/audio/audio_directive_handler_impl.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/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/time/default_tick_clock.h" 10 #include "base/time/default_tick_clock.h"
11 #include "base/time/time.h" 11 #include "base/time/time.h"
12 #include "base/timer/timer.h" 12 #include "base/timer/timer.h"
13 #include "components/copresence/handlers/audio/audio_directive_list.h"
13 #include "components/copresence/handlers/audio/tick_clock_ref_counted.h" 14 #include "components/copresence/handlers/audio/tick_clock_ref_counted.h"
14 #include "components/copresence/mediums/audio/audio_manager_impl.h" 15 #include "components/copresence/mediums/audio/audio_manager_impl.h"
15 #include "components/copresence/proto/data.pb.h" 16 #include "components/copresence/proto/data.pb.h"
16 #include "components/copresence/public/copresence_constants.h" 17 #include "components/copresence/public/copresence_constants.h"
17 #include "media/base/audio_bus.h" 18 #include "media/base/audio_bus.h"
18 19
19 namespace copresence { 20 namespace copresence {
20 21
21 namespace { 22 namespace {
22 23
23 base::TimeTicks GetEarliestEventTime(AudioDirectiveList* list, 24 base::TimeTicks GetEarliestEventTime(AudioDirectiveList* list,
24 base::TimeTicks event_time) { 25 base::TimeTicks event_time) {
25 if (!list->GetActiveDirective()) 26 if (!list->GetActiveDirective())
26 return event_time; 27 return event_time;
27 28
28 if (event_time.is_null()) 29 return event_time.is_null() ?
29 return list->GetActiveDirective()->end_time; 30 list->GetActiveDirective()->end_time :
30 else 31 std::min(list->GetActiveDirective()->end_time, event_time);
31 return std::min(list->GetActiveDirective()->end_time, event_time);
32 } 32 }
33 33
34 } // namespace 34 } // namespace
35 35
36 // Public methods.
37 36
38 AudioDirectiveHandler::AudioDirectiveHandler() 37 // Public functions.
39 : audio_event_timer_(new base::OneShotTimer<AudioDirectiveHandler>), 38
40 clock_(new TickClockRefCounted( 39 AudioDirectiveHandlerImpl::AudioDirectiveHandlerImpl()
41 make_scoped_ptr(new base::DefaultTickClock))) { 40 : audio_manager_(new AudioManagerImpl),
41 audio_event_timer_(new base::OneShotTimer<AudioDirectiveHandler>),
42 clock_(new TickClockRefCounted(new base::DefaultTickClock)) {
43 transmits_lists_.push_back(new AudioDirectiveList(clock_));
44 transmits_lists_.push_back(new AudioDirectiveList(clock_));
45 receives_lists_.push_back(new AudioDirectiveList(clock_));
46 receives_lists_.push_back(new AudioDirectiveList(clock_));
42 } 47 }
43 48
44 AudioDirectiveHandler::~AudioDirectiveHandler() { 49 // TODO(ckehoe): Merge these two constructors when
50 // delegating constructors are allowed.
51 AudioDirectiveHandlerImpl::AudioDirectiveHandlerImpl(
52 scoped_ptr<AudioManager> audio_manager,
53 scoped_ptr<base::Timer> timer,
54 const scoped_refptr<TickClockRefCounted>& clock)
55 : audio_manager_(audio_manager.Pass()),
56 audio_event_timer_(timer.Pass()),
57 clock_(clock) {
58 transmits_lists_.push_back(new AudioDirectiveList(clock));
rkc 2014/11/03 20:14:43 Why aren't these in the Initialize function? Won't
Charlie 2014/11/03 22:45:13 Done.
59 transmits_lists_.push_back(new AudioDirectiveList(clock));
60 receives_lists_.push_back(new AudioDirectiveList(clock));
61 receives_lists_.push_back(new AudioDirectiveList(clock));
45 } 62 }
46 63
47 void AudioDirectiveHandler::Initialize( 64 AudioDirectiveHandlerImpl::~AudioDirectiveHandlerImpl() {}
65
66 void AudioDirectiveHandlerImpl::Initialize(
48 const AudioManager::DecodeSamplesCallback& decode_cb, 67 const AudioManager::DecodeSamplesCallback& decode_cb,
49 const AudioManager::EncodeTokenCallback& encode_cb) { 68 const AudioManager::EncodeTokenCallback& encode_cb) {
50 if (!audio_manager_) 69 if (!audio_manager_)
51 audio_manager_.reset(new AudioManagerImpl()); 70 audio_manager_.reset(new AudioManagerImpl());
52 audio_manager_->Initialize(decode_cb, encode_cb); 71 audio_manager_->Initialize(decode_cb, encode_cb);
53 } 72 }
54 73
55 void AudioDirectiveHandler::AddInstruction(const TokenInstruction& instruction, 74 void AudioDirectiveHandlerImpl::AddInstruction(
56 const std::string& op_id, 75 const TokenInstruction& instruction,
57 base::TimeDelta ttl) { 76 const std::string& op_id,
77 base::TimeDelta ttl) {
58 switch (instruction.token_instruction_type()) { 78 switch (instruction.token_instruction_type()) {
59 case TRANSMIT: 79 case TRANSMIT:
60 DVLOG(2) << "Audio Transmit Directive received. Token: " 80 DVLOG(2) << "Audio Transmit Directive received. Token: "
61 << instruction.token_id() 81 << instruction.token_id()
62 << " with medium=" << instruction.medium() 82 << " with medium=" << instruction.medium()
63 << " with TTL=" << ttl.InMilliseconds(); 83 << " with TTL=" << ttl.InMilliseconds();
64 switch (instruction.medium()) { 84 switch (instruction.medium()) {
65 case AUDIO_ULTRASOUND_PASSBAND: 85 case AUDIO_ULTRASOUND_PASSBAND:
rkc 2014/11/03 20:14:43 DCHECK(transmits_lists_[INAUDIBLE]); Then audible
Charlie 2014/11/03 22:45:13 I'm not sure this checks for the thing you want. I
rkc 2014/11/03 22:52:15 This is true. So lets DCHECK the vector size then.
Charlie 2014/11/03 23:08:58 The check inside of std::vector already does what
rkc 2014/11/04 00:37:22 I dislike depending on platform specific implement
Charlie 2014/11/04 01:07:46 In principle I agree, although since this is only
66 transmits_list_[INAUDIBLE].AddDirective(op_id, ttl); 86 transmits_lists_[INAUDIBLE]->AddDirective(op_id, ttl);
67 audio_manager_->SetToken(INAUDIBLE, instruction.token_id()); 87 audio_manager_->SetToken(INAUDIBLE, instruction.token_id());
68 break; 88 break;
69 case AUDIO_AUDIBLE_DTMF: 89 case AUDIO_AUDIBLE_DTMF:
70 transmits_list_[AUDIBLE].AddDirective(op_id, ttl); 90 transmits_lists_[AUDIBLE]->AddDirective(op_id, ttl);
71 audio_manager_->SetToken(AUDIBLE, instruction.token_id()); 91 audio_manager_->SetToken(AUDIBLE, instruction.token_id());
72 break; 92 break;
73 default: 93 default:
74 NOTREACHED(); 94 NOTREACHED();
75 } 95 }
76 break; 96 break;
77 case RECEIVE: 97 case RECEIVE:
78 DVLOG(2) << "Audio Receive Directive received." 98 DVLOG(2) << "Audio Receive Directive received."
79 << " with medium=" << instruction.medium() 99 << " with medium=" << instruction.medium()
80 << " with TTL=" << ttl.InMilliseconds(); 100 << " with TTL=" << ttl.InMilliseconds();
81 switch (instruction.medium()) { 101 switch (instruction.medium()) {
82 case AUDIO_ULTRASOUND_PASSBAND: 102 case AUDIO_ULTRASOUND_PASSBAND:
83 receives_list_[INAUDIBLE].AddDirective(op_id, ttl); 103 receives_lists_[INAUDIBLE]->AddDirective(op_id, ttl);
84 break; 104 break;
85 case AUDIO_AUDIBLE_DTMF: 105 case AUDIO_AUDIBLE_DTMF:
86 receives_list_[AUDIBLE].AddDirective(op_id, ttl); 106 receives_lists_[AUDIBLE]->AddDirective(op_id, ttl);
87 break; 107 break;
88 default: 108 default:
89 NOTREACHED(); 109 NOTREACHED();
90 } 110 }
91 break; 111 break;
92 case UNKNOWN_TOKEN_INSTRUCTION_TYPE: 112 case UNKNOWN_TOKEN_INSTRUCTION_TYPE:
93 default: 113 default:
94 LOG(WARNING) << "Unknown Audio Transmit Directive received. type = " 114 LOG(WARNING) << "Unknown Audio Transmit Directive received. type = "
95 << instruction.token_instruction_type(); 115 << instruction.token_instruction_type();
96 } 116 }
97 ProcessNextInstruction(); 117 ProcessNextInstruction();
98 } 118 }
99 119
100 void AudioDirectiveHandler::RemoveInstructions(const std::string& op_id) { 120 void AudioDirectiveHandlerImpl::RemoveInstructions(const std::string& op_id) {
101 transmits_list_[AUDIBLE].RemoveDirective(op_id); 121 transmits_lists_[AUDIBLE]->RemoveDirective(op_id);
102 transmits_list_[INAUDIBLE].RemoveDirective(op_id); 122 transmits_lists_[INAUDIBLE]->RemoveDirective(op_id);
103 receives_list_[AUDIBLE].RemoveDirective(op_id); 123 receives_lists_[AUDIBLE]->RemoveDirective(op_id);
104 receives_list_[INAUDIBLE].RemoveDirective(op_id); 124 receives_lists_[INAUDIBLE]->RemoveDirective(op_id);
105 125
106 ProcessNextInstruction(); 126 ProcessNextInstruction();
107 } 127 }
108 128
109 const std::string AudioDirectiveHandler::PlayingToken(AudioType type) const { 129 const std::string AudioDirectiveHandlerImpl::PlayingToken(
130 AudioType type) const {
110 return audio_manager_->GetToken(type); 131 return audio_manager_->GetToken(type);
111 } 132 }
112 133
113 void AudioDirectiveHandler::set_clock_for_testing(
114 const scoped_refptr<TickClockRefCounted>& clock) {
115 clock_ = clock;
116 134
117 transmits_list_[AUDIBLE].set_clock_for_testing(clock); 135 // Private functions.
118 transmits_list_[INAUDIBLE].set_clock_for_testing(clock);
119 receives_list_[AUDIBLE].set_clock_for_testing(clock);
120 receives_list_[INAUDIBLE].set_clock_for_testing(clock);
121 }
122 136
123 void AudioDirectiveHandler::set_timer_for_testing( 137 void AudioDirectiveHandlerImpl::ProcessNextInstruction() {
124 scoped_ptr<base::Timer> timer) {
125 audio_event_timer_.swap(timer);
126 }
127
128 // Private methods.
129
130 void AudioDirectiveHandler::ProcessNextInstruction() {
131 DCHECK(audio_event_timer_); 138 DCHECK(audio_event_timer_);
132 audio_event_timer_->Stop(); 139 audio_event_timer_->Stop();
133 140
134 // Change |audio_manager_| state for audible transmits. 141 // Change |audio_manager_| state for audible transmits.
135 if (transmits_list_[AUDIBLE].GetActiveDirective()) 142 if (transmits_lists_[AUDIBLE]->GetActiveDirective())
136 audio_manager_->StartPlaying(AUDIBLE); 143 audio_manager_->StartPlaying(AUDIBLE);
137 else 144 else
138 audio_manager_->StopPlaying(AUDIBLE); 145 audio_manager_->StopPlaying(AUDIBLE);
139 146
140 // Change audio_manager_ state for inaudible transmits. 147 // Change audio_manager_ state for inaudible transmits.
141 if (transmits_list_[INAUDIBLE].GetActiveDirective()) 148 if (transmits_lists_[INAUDIBLE]->GetActiveDirective())
142 audio_manager_->StartPlaying(INAUDIBLE); 149 audio_manager_->StartPlaying(INAUDIBLE);
143 else 150 else
144 audio_manager_->StopPlaying(INAUDIBLE); 151 audio_manager_->StopPlaying(INAUDIBLE);
145 152
146 // Change audio_manager_ state for audible receives. 153 // Change audio_manager_ state for audible receives.
147 if (receives_list_[AUDIBLE].GetActiveDirective()) 154 if (receives_lists_[AUDIBLE]->GetActiveDirective())
148 audio_manager_->StartRecording(AUDIBLE); 155 audio_manager_->StartRecording(AUDIBLE);
149 else 156 else
150 audio_manager_->StopRecording(AUDIBLE); 157 audio_manager_->StopRecording(AUDIBLE);
151 158
152 // Change audio_manager_ state for inaudible receives. 159 // Change audio_manager_ state for inaudible receives.
153 if (receives_list_[INAUDIBLE].GetActiveDirective()) 160 if (receives_lists_[INAUDIBLE]->GetActiveDirective())
154 audio_manager_->StartRecording(INAUDIBLE); 161 audio_manager_->StartRecording(INAUDIBLE);
155 else 162 else
156 audio_manager_->StopRecording(INAUDIBLE); 163 audio_manager_->StopRecording(INAUDIBLE);
157 164
158 base::TimeTicks next_event_time; 165 base::TimeTicks next_event_time;
159 if (GetNextInstructionExpiry(&next_event_time)) { 166 if (GetNextInstructionExpiry(&next_event_time)) {
160 audio_event_timer_->Start( 167 audio_event_timer_->Start(
161 FROM_HERE, 168 FROM_HERE,
162 next_event_time - clock_->NowTicks(), 169 next_event_time - clock_->NowTicks(),
163 base::Bind(&AudioDirectiveHandler::ProcessNextInstruction, 170 base::Bind(&AudioDirectiveHandlerImpl::ProcessNextInstruction,
164 base::Unretained(this))); 171 base::Unretained(this)));
165 } 172 }
166 } 173 }
167 174
168 bool AudioDirectiveHandler::GetNextInstructionExpiry(base::TimeTicks* expiry) { 175 bool AudioDirectiveHandlerImpl::GetNextInstructionExpiry(
176 base::TimeTicks* expiry) {
169 DCHECK(expiry); 177 DCHECK(expiry);
170 178
171 *expiry = GetEarliestEventTime(&transmits_list_[AUDIBLE], base::TimeTicks()); 179 *expiry = GetEarliestEventTime(transmits_lists_[AUDIBLE], base::TimeTicks());
172 *expiry = GetEarliestEventTime(&transmits_list_[INAUDIBLE], *expiry); 180 *expiry = GetEarliestEventTime(transmits_lists_[INAUDIBLE], *expiry);
173 *expiry = GetEarliestEventTime(&receives_list_[AUDIBLE], *expiry); 181 *expiry = GetEarliestEventTime(receives_lists_[AUDIBLE], *expiry);
174 *expiry = GetEarliestEventTime(&receives_list_[INAUDIBLE], *expiry); 182 *expiry = GetEarliestEventTime(receives_lists_[INAUDIBLE], *expiry);
175 183
176 return !expiry->is_null(); 184 return !expiry->is_null();
177 } 185 }
178 186
179 } // namespace copresence 187 } // namespace copresence
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698