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