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 <string> |
| 6 #include <vector> |
| 7 |
5 #include "base/bind.h" | 8 #include "base/bind.h" |
6 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
7 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
8 #include "base/test/simple_test_tick_clock.h" | 11 #include "base/test/simple_test_tick_clock.h" |
9 #include "base/timer/mock_timer.h" | 12 #include "base/timer/mock_timer.h" |
10 #include "components/copresence/handlers/audio/audio_directive_handler_impl.h" | 13 #include "components/copresence/handlers/audio/audio_directive_handler_impl.h" |
11 #include "components/copresence/handlers/audio/tick_clock_ref_counted.h" | 14 #include "components/copresence/handlers/audio/tick_clock_ref_counted.h" |
12 #include "components/copresence/mediums/audio/audio_manager.h" | 15 #include "components/copresence/mediums/audio/audio_manager.h" |
13 #include "components/copresence/proto/data.pb.h" | 16 #include "components/copresence/proto/data.pb.h" |
14 #include "components/copresence/test/audio_test_support.h" | 17 #include "components/copresence/test/audio_test_support.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
16 | 19 |
17 namespace copresence { | 20 namespace copresence { |
18 | 21 |
| 22 namespace { |
| 23 |
| 24 const Directive CreateDirective(TokenInstructionType type, |
| 25 bool audible, |
| 26 int64 ttl) { |
| 27 Directive directive; |
| 28 directive.mutable_token_instruction()->set_token_instruction_type(type); |
| 29 directive.mutable_token_instruction()->set_token_id("token"); |
| 30 directive.mutable_token_instruction()->set_medium(audible ? |
| 31 AUDIO_AUDIBLE_DTMF : AUDIO_ULTRASOUND_PASSBAND); |
| 32 directive.set_ttl_millis(ttl); |
| 33 return directive; |
| 34 } |
| 35 |
| 36 } // namespace |
| 37 |
19 class AudioManagerStub final : public AudioManager { | 38 class AudioManagerStub final : public AudioManager { |
20 public: | 39 public: |
21 AudioManagerStub() {} | 40 AudioManagerStub() {} |
22 ~AudioManagerStub() override {} | 41 ~AudioManagerStub() override {} |
23 | 42 |
24 // AudioManager overrides: | 43 // AudioManager overrides: |
25 void Initialize(WhispernetClient* whispernet_client, | 44 void Initialize(WhispernetClient* whispernet_client, |
26 const TokensCallback& tokens_cb) override {} | 45 const TokensCallback& tokens_cb) override {} |
27 void StartPlaying(AudioType type) override { playing_[type] = true; } | 46 void StartPlaying(AudioType type) override { playing_[type] = true; } |
28 void StopPlaying(AudioType type) override { playing_[type] = false; } | 47 void StopPlaying(AudioType type) override { playing_[type] = false; } |
(...skipping 14 matching lines...) Expand all Loading... |
43 }; | 62 }; |
44 | 63 |
45 class AudioDirectiveHandlerTest : public testing::Test { | 64 class AudioDirectiveHandlerTest : public testing::Test { |
46 public: | 65 public: |
47 AudioDirectiveHandlerTest() { | 66 AudioDirectiveHandlerTest() { |
48 manager_ptr_ = new AudioManagerStub; | 67 manager_ptr_ = new AudioManagerStub; |
49 timer_ptr_ = new base::MockTimer(false, false); | 68 timer_ptr_ = new base::MockTimer(false, false); |
50 clock_ptr_ = new base::SimpleTestTickClock; | 69 clock_ptr_ = new base::SimpleTestTickClock; |
51 | 70 |
52 directive_handler_.reset(new AudioDirectiveHandlerImpl( | 71 directive_handler_.reset(new AudioDirectiveHandlerImpl( |
| 72 base::Bind(&AudioDirectiveHandlerTest::GetDirectiveUpdates, |
| 73 base::Unretained(this)), |
53 make_scoped_ptr<AudioManager>(manager_ptr_), | 74 make_scoped_ptr<AudioManager>(manager_ptr_), |
54 make_scoped_ptr<base::Timer>(timer_ptr_), | 75 make_scoped_ptr<base::Timer>(timer_ptr_), |
55 make_scoped_refptr(new TickClockRefCounted(clock_ptr_)))); | 76 make_scoped_refptr(new TickClockRefCounted(clock_ptr_)))); |
56 directive_handler_->Initialize(nullptr, TokensCallback()); | 77 directive_handler_->Initialize(nullptr, TokensCallback()); |
57 } | 78 } |
58 ~AudioDirectiveHandlerTest() override {} | 79 ~AudioDirectiveHandlerTest() override {} |
59 | 80 |
60 protected: | 81 protected: |
61 TokenInstruction CreateTransmitInstruction(const std::string& token, | 82 const std::vector<Directive>& current_directives() { |
62 bool audible) { | 83 return current_directives_; |
63 TokenInstruction instruction; | |
64 instruction.set_token_instruction_type(TRANSMIT); | |
65 instruction.set_token_id(token); | |
66 instruction.set_medium(audible ? AUDIO_AUDIBLE_DTMF | |
67 : AUDIO_ULTRASOUND_PASSBAND); | |
68 return instruction; | |
69 } | |
70 | |
71 TokenInstruction CreateReceiveInstruction(bool audible) { | |
72 TokenInstruction instruction; | |
73 instruction.set_token_instruction_type(RECEIVE); | |
74 instruction.set_medium(audible ? AUDIO_AUDIBLE_DTMF | |
75 : AUDIO_ULTRASOUND_PASSBAND); | |
76 return instruction; | |
77 } | 84 } |
78 | 85 |
79 bool IsPlaying(AudioType type) { return manager_ptr_->IsPlaying(type); } | 86 bool IsPlaying(AudioType type) { return manager_ptr_->IsPlaying(type); } |
80 | 87 |
81 bool IsRecording(AudioType type) { return manager_ptr_->IsRecording(type); } | 88 bool IsRecording(AudioType type) { return manager_ptr_->IsRecording(type); } |
82 | 89 |
83 // This order is important. We want the message loop to get created before | 90 // This order is important. We want the message loop to get created before |
84 // our the audio directive handler since the directive list ctor (invoked | 91 // our the audio directive handler since the directive list ctor (invoked |
85 // from the directive handler ctor) will post tasks. | 92 // from the directive handler ctor) will post tasks. |
86 base::MessageLoop message_loop_; | 93 base::MessageLoop message_loop_; |
87 scoped_ptr<AudioDirectiveHandler> directive_handler_; | 94 scoped_ptr<AudioDirectiveHandler> directive_handler_; |
88 | 95 |
| 96 std::vector<Directive> current_directives_; |
| 97 |
89 // Unowned. | 98 // Unowned. |
90 AudioManagerStub* manager_ptr_; | 99 AudioManagerStub* manager_ptr_; |
91 base::MockTimer* timer_ptr_; | 100 base::MockTimer* timer_ptr_; |
92 base::SimpleTestTickClock* clock_ptr_; | 101 base::SimpleTestTickClock* clock_ptr_; |
93 | 102 |
94 private: | 103 private: |
| 104 void GetDirectiveUpdates(const std::vector<Directive>& current_directives) { |
| 105 current_directives_ = current_directives; |
| 106 } |
| 107 |
95 DISALLOW_COPY_AND_ASSIGN(AudioDirectiveHandlerTest); | 108 DISALLOW_COPY_AND_ASSIGN(AudioDirectiveHandlerTest); |
96 }; | 109 }; |
97 | 110 |
98 TEST_F(AudioDirectiveHandlerTest, Basic) { | 111 TEST_F(AudioDirectiveHandlerTest, Basic) { |
99 const base::TimeDelta kTtl = base::TimeDelta::FromMilliseconds(9999); | 112 const int64 kTtl = 10; |
100 directive_handler_->AddInstruction( | 113 directive_handler_->AddInstruction(CreateDirective(TRANSMIT, true, kTtl), |
101 CreateTransmitInstruction("token", true), "op_id1", kTtl); | 114 "op_id1"); |
102 directive_handler_->AddInstruction( | 115 directive_handler_->AddInstruction(CreateDirective(TRANSMIT, false, kTtl), |
103 CreateTransmitInstruction("token", false), "op_id1", kTtl); | 116 "op_id1"); |
104 directive_handler_->AddInstruction( | 117 directive_handler_->AddInstruction(CreateDirective(TRANSMIT, false, kTtl), |
105 CreateTransmitInstruction("token", false), "op_id2", kTtl); | 118 "op_id2"); |
106 directive_handler_->AddInstruction( | 119 directive_handler_->AddInstruction(CreateDirective(RECEIVE, false, kTtl), |
107 CreateReceiveInstruction(false), "op_id1", kTtl); | 120 "op_id1"); |
108 directive_handler_->AddInstruction( | 121 directive_handler_->AddInstruction(CreateDirective(RECEIVE, true, kTtl), |
109 CreateReceiveInstruction(true), "op_id2", kTtl); | 122 "op_id2"); |
110 directive_handler_->AddInstruction( | 123 directive_handler_->AddInstruction(CreateDirective(RECEIVE, false, kTtl), |
111 CreateReceiveInstruction(false), "op_id3", kTtl); | 124 "op_id3"); |
112 | 125 |
113 EXPECT_TRUE(IsPlaying(AUDIBLE)); | 126 EXPECT_TRUE(IsPlaying(AUDIBLE)); |
114 EXPECT_TRUE(IsPlaying(INAUDIBLE)); | 127 EXPECT_TRUE(IsPlaying(INAUDIBLE)); |
115 EXPECT_TRUE(IsRecording(AUDIBLE)); | 128 EXPECT_TRUE(IsRecording(AUDIBLE)); |
116 EXPECT_TRUE(IsRecording(INAUDIBLE)); | 129 EXPECT_TRUE(IsRecording(INAUDIBLE)); |
117 | 130 |
118 directive_handler_->RemoveInstructions("op_id1"); | 131 directive_handler_->RemoveInstructions("op_id1"); |
119 EXPECT_FALSE(IsPlaying(AUDIBLE)); | 132 EXPECT_FALSE(IsPlaying(AUDIBLE)); |
120 EXPECT_TRUE(IsPlaying(INAUDIBLE)); | 133 EXPECT_TRUE(IsPlaying(INAUDIBLE)); |
121 EXPECT_TRUE(IsRecording(AUDIBLE)); | 134 EXPECT_TRUE(IsRecording(AUDIBLE)); |
122 EXPECT_TRUE(IsRecording(INAUDIBLE)); | 135 EXPECT_TRUE(IsRecording(INAUDIBLE)); |
123 | 136 |
124 directive_handler_->RemoveInstructions("op_id2"); | 137 directive_handler_->RemoveInstructions("op_id2"); |
125 EXPECT_FALSE(IsPlaying(INAUDIBLE)); | 138 EXPECT_FALSE(IsPlaying(INAUDIBLE)); |
126 EXPECT_FALSE(IsRecording(AUDIBLE)); | 139 EXPECT_FALSE(IsRecording(AUDIBLE)); |
127 EXPECT_TRUE(IsRecording(INAUDIBLE)); | 140 EXPECT_TRUE(IsRecording(INAUDIBLE)); |
128 | 141 |
129 directive_handler_->RemoveInstructions("op_id3"); | 142 directive_handler_->RemoveInstructions("op_id3"); |
130 EXPECT_FALSE(IsRecording(INAUDIBLE)); | 143 EXPECT_FALSE(IsRecording(INAUDIBLE)); |
131 } | 144 } |
132 | 145 |
133 TEST_F(AudioDirectiveHandlerTest, Timed) { | 146 TEST_F(AudioDirectiveHandlerTest, Timed) { |
134 const base::TimeDelta kTtl1 = base::TimeDelta::FromMilliseconds(1337); | 147 directive_handler_->AddInstruction(CreateDirective(TRANSMIT, true, 6), |
135 directive_handler_->AddInstruction( | 148 "op_id1"); |
136 CreateTransmitInstruction("token", true), "op_id1", kTtl1); | 149 directive_handler_->AddInstruction(CreateDirective(TRANSMIT, false, 8), |
| 150 "op_id1"); |
| 151 directive_handler_->AddInstruction(CreateDirective(RECEIVE, false, 4), |
| 152 "op_id3"); |
137 | 153 |
138 const base::TimeDelta kTtl2 = base::TimeDelta::FromMilliseconds(1338); | |
139 directive_handler_->AddInstruction( | |
140 CreateTransmitInstruction("token", false), "op_id1", kTtl2); | |
141 | |
142 const base::TimeDelta kTtl3 = base::TimeDelta::FromMilliseconds(1336); | |
143 directive_handler_->AddInstruction( | |
144 CreateReceiveInstruction(false), "op_id3", kTtl3); | |
145 EXPECT_TRUE(IsPlaying(AUDIBLE)); | 154 EXPECT_TRUE(IsPlaying(AUDIBLE)); |
146 EXPECT_TRUE(IsPlaying(INAUDIBLE)); | 155 EXPECT_TRUE(IsPlaying(INAUDIBLE)); |
147 EXPECT_FALSE(IsRecording(AUDIBLE)); | 156 EXPECT_FALSE(IsRecording(AUDIBLE)); |
148 EXPECT_TRUE(IsRecording(INAUDIBLE)); | 157 EXPECT_TRUE(IsRecording(INAUDIBLE)); |
149 | 158 |
150 // We *have* to call an operation on the directive handler after we advance | 159 // Every time we advance and a directive expires, the timer should fire also. |
151 // time to trigger the next set of operations, so ensure that after calling | 160 clock_ptr_->Advance(base::TimeDelta::FromMilliseconds(5)); |
152 // advance, we are also calling another operation. | 161 timer_ptr_->Fire(); |
153 clock_ptr_->Advance(kTtl3 + base::TimeDelta::FromMilliseconds(1)); | |
154 | 162 |
155 // We are now at base + 1337ms. | 163 // We are now at +5ms. This instruction expires at +10ms. |
156 // This instruction expires at base + (1337 + 1337 = 2674) | 164 directive_handler_->AddInstruction(CreateDirective(RECEIVE, true, 5), |
157 directive_handler_->AddInstruction( | 165 "op_id4"); |
158 CreateReceiveInstruction(true), "op_id4", kTtl1); | |
159 EXPECT_TRUE(IsPlaying(AUDIBLE)); | 166 EXPECT_TRUE(IsPlaying(AUDIBLE)); |
160 EXPECT_TRUE(IsPlaying(INAUDIBLE)); | 167 EXPECT_TRUE(IsPlaying(INAUDIBLE)); |
161 EXPECT_TRUE(IsRecording(AUDIBLE)); | 168 EXPECT_TRUE(IsRecording(AUDIBLE)); |
162 EXPECT_FALSE(IsRecording(INAUDIBLE)); | 169 EXPECT_FALSE(IsRecording(INAUDIBLE)); |
163 | 170 |
164 clock_ptr_->Advance(base::TimeDelta::FromMilliseconds(1)); | 171 // Advance to +7ms. |
| 172 const base::TimeDelta twoMs = base::TimeDelta::FromMilliseconds(2); |
| 173 clock_ptr_->Advance(twoMs); |
| 174 timer_ptr_->Fire(); |
165 | 175 |
166 // We are now at base + 1338ms. | |
167 timer_ptr_->Fire(); | |
168 EXPECT_FALSE(IsPlaying(AUDIBLE)); | 176 EXPECT_FALSE(IsPlaying(AUDIBLE)); |
169 EXPECT_TRUE(IsPlaying(INAUDIBLE)); | 177 EXPECT_TRUE(IsPlaying(INAUDIBLE)); |
170 EXPECT_TRUE(IsRecording(AUDIBLE)); | 178 EXPECT_TRUE(IsRecording(AUDIBLE)); |
171 | 179 |
172 clock_ptr_->Advance(base::TimeDelta::FromMilliseconds(1)); | 180 // Advance to +9ms. |
173 | 181 clock_ptr_->Advance(twoMs); |
174 // We are now at base + 1339ms. | |
175 timer_ptr_->Fire(); | 182 timer_ptr_->Fire(); |
176 EXPECT_FALSE(IsPlaying(INAUDIBLE)); | 183 EXPECT_FALSE(IsPlaying(INAUDIBLE)); |
177 EXPECT_TRUE(IsRecording(AUDIBLE)); | 184 EXPECT_TRUE(IsRecording(AUDIBLE)); |
178 | 185 |
179 clock_ptr_->Advance(kTtl3); | 186 // Advance to +11ms. |
180 | 187 clock_ptr_->Advance(twoMs); |
181 // We are now at base + 2676ms. | |
182 timer_ptr_->Fire(); | 188 timer_ptr_->Fire(); |
183 EXPECT_FALSE(IsRecording(AUDIBLE)); | 189 EXPECT_FALSE(IsRecording(AUDIBLE)); |
184 } | 190 } |
185 | 191 |
186 // TODO(rkc): Write more tests that check more convoluted sequences of | 192 // TODO(rkc): Write more tests that check more convoluted sequences of |
187 // transmits/receives. | 193 // transmits/receives. |
188 | 194 |
189 } // namespace copresence | 195 } // namespace copresence |
OLD | NEW |