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.
6 #include "base/memory/scoped_ptr.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/test/simple_test_tick_clock.h"
9 #include "base/timer/mock_timer.h"
10 #include "components/copresence/handlers/audio/audio_directive_handler_impl.h"
11 #include "components/copresence/handlers/audio/tick_clock_ref_counted.h"
12 #include "components/copresence/mediums/audio/audio_manager.h"
13 #include "components/copresence/proto/data.pb.h"
14 #include "components/copresence/test/audio_test_support.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 namespace copresence {
19 class AudioManagerStub final : public AudioManager {
22 ~AudioManagerStub() override {}
24 // AudioManager overrides:
25 void Initialize(WhispernetClient* whispernet_client,
26 const TokensCallback& tokens_cb) override {}
27 void StartPlaying(AudioType type) override { playing_[type] = true; }
28 void StopPlaying(AudioType type) override { playing_[type] = false; }
29 void StartRecording(AudioType type) override { recording_[type] = true; }
30 void StopRecording(AudioType type) override { recording_[type] = false; }
31 void SetToken(AudioType type, const std::string& url_unsafe_token) override {}
32 const std::string GetToken(AudioType type) override { return std::string(); }
33 bool IsRecording(AudioType type) override { return recording_[type]; }
34 bool IsPlaying(AudioType type) override { return playing_[type]; }
35 bool IsPlayingTokenHeard(AudioType type) override { return false; }
38 // Indexed using enum AudioType.
42 DISALLOW_COPY_AND_ASSIGN(AudioManagerStub);
45 class AudioDirectiveHandlerTest : public testing::Test {
47 AudioDirectiveHandlerTest() {
48 manager_ptr_ = new AudioManagerStub;
49 timer_ptr_ = new base::MockTimer(false, false);
50 clock_ptr_ = new base::SimpleTestTickClock;
52 directive_handler_.reset(new AudioDirectiveHandlerImpl(
53 make_scoped_ptr<AudioManager>(manager_ptr_),
54 make_scoped_ptr<base::Timer>(timer_ptr_),
55 make_scoped_refptr(new TickClockRefCounted(clock_ptr_))));
56 directive_handler_->Initialize(nullptr, TokensCallback());
58 ~AudioDirectiveHandlerTest() override {}
61 TokenInstruction CreateTransmitInstruction(const std::string& token,
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);
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);
79 bool IsPlaying(AudioType type) { return manager_ptr_->IsPlaying(type); }
81 bool IsRecording(AudioType type) { return manager_ptr_->IsRecording(type); }
83 // 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
85 // from the directive handler ctor) will post tasks.
86 base::MessageLoop message_loop_;
87 scoped_ptr<AudioDirectiveHandler> directive_handler_;
90 AudioManagerStub* manager_ptr_;
91 base::MockTimer* timer_ptr_;
92 base::SimpleTestTickClock* clock_ptr_;
95 DISALLOW_COPY_AND_ASSIGN(AudioDirectiveHandlerTest);
98 TEST_F(AudioDirectiveHandlerTest, Basic) {
99 const base::TimeDelta kTtl = base::TimeDelta::FromMilliseconds(9999);
100 directive_handler_->AddInstruction(
101 CreateTransmitInstruction("token", true), "op_id1", kTtl);
102 directive_handler_->AddInstruction(
103 CreateTransmitInstruction("token", false), "op_id1", kTtl);
104 directive_handler_->AddInstruction(
105 CreateTransmitInstruction("token", false), "op_id2", kTtl);
106 directive_handler_->AddInstruction(
107 CreateReceiveInstruction(false), "op_id1", kTtl);
108 directive_handler_->AddInstruction(
109 CreateReceiveInstruction(true), "op_id2", kTtl);
110 directive_handler_->AddInstruction(
111 CreateReceiveInstruction(false), "op_id3", kTtl);
113 EXPECT_TRUE(IsPlaying(AUDIBLE));
114 EXPECT_TRUE(IsPlaying(INAUDIBLE));
115 EXPECT_TRUE(IsRecording(AUDIBLE));
116 EXPECT_TRUE(IsRecording(INAUDIBLE));
118 directive_handler_->RemoveInstructions("op_id1");
119 EXPECT_FALSE(IsPlaying(AUDIBLE));
120 EXPECT_TRUE(IsPlaying(INAUDIBLE));
121 EXPECT_TRUE(IsRecording(AUDIBLE));
122 EXPECT_TRUE(IsRecording(INAUDIBLE));
124 directive_handler_->RemoveInstructions("op_id2");
125 EXPECT_FALSE(IsPlaying(INAUDIBLE));
126 EXPECT_FALSE(IsRecording(AUDIBLE));
127 EXPECT_TRUE(IsRecording(INAUDIBLE));
129 directive_handler_->RemoveInstructions("op_id3");
130 EXPECT_FALSE(IsRecording(INAUDIBLE));
133 TEST_F(AudioDirectiveHandlerTest, Timed) {
134 const base::TimeDelta kTtl1 = base::TimeDelta::FromMilliseconds(1337);
135 directive_handler_->AddInstruction(
136 CreateTransmitInstruction("token", true), "op_id1", kTtl1);
138 const base::TimeDelta kTtl2 = base::TimeDelta::FromMilliseconds(1338);
139 directive_handler_->AddInstruction(
140 CreateTransmitInstruction("token", false), "op_id1", kTtl2);
142 const base::TimeDelta kTtl3 = base::TimeDelta::FromMilliseconds(1336);
143 directive_handler_->AddInstruction(
144 CreateReceiveInstruction(false), "op_id3", kTtl3);
145 EXPECT_TRUE(IsPlaying(AUDIBLE));
146 EXPECT_TRUE(IsPlaying(INAUDIBLE));
147 EXPECT_FALSE(IsRecording(AUDIBLE));
148 EXPECT_TRUE(IsRecording(INAUDIBLE));
150 // We *have* to call an operation on the directive handler after we advance
151 // time to trigger the next set of operations, so ensure that after calling
152 // advance, we are also calling another operation.
153 clock_ptr_->Advance(kTtl3 + base::TimeDelta::FromMilliseconds(1));
155 // We are now at base + 1337ms.
156 // This instruction expires at base + (1337 + 1337 = 2674)
157 directive_handler_->AddInstruction(
158 CreateReceiveInstruction(true), "op_id4", kTtl1);
159 EXPECT_TRUE(IsPlaying(AUDIBLE));
160 EXPECT_TRUE(IsPlaying(INAUDIBLE));
161 EXPECT_TRUE(IsRecording(AUDIBLE));
162 EXPECT_FALSE(IsRecording(INAUDIBLE));
164 clock_ptr_->Advance(base::TimeDelta::FromMilliseconds(1));
166 // We are now at base + 1338ms.
168 EXPECT_FALSE(IsPlaying(AUDIBLE));
169 EXPECT_TRUE(IsPlaying(INAUDIBLE));
170 EXPECT_TRUE(IsRecording(AUDIBLE));
172 clock_ptr_->Advance(base::TimeDelta::FromMilliseconds(1));
174 // We are now at base + 1339ms.
176 EXPECT_FALSE(IsPlaying(INAUDIBLE));
177 EXPECT_TRUE(IsRecording(AUDIBLE));
179 clock_ptr_->Advance(kTtl3);
181 // We are now at base + 2676ms.
183 EXPECT_FALSE(IsRecording(AUDIBLE));
186 // TODO(rkc): Write more tests that check more convoluted sequences of
187 // transmits/receives.
189 } // namespace copresence