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.
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/test/simple_test_tick_clock.h"
12 #include "base/timer/mock_timer.h"
13 #include "components/audio_modem/public/modem.h"
14 #include "components/audio_modem/test/random_samples.h"
15 #include "components/audio_modem/test/stub_modem.h"
16 #include "components/copresence/handlers/audio/audio_directive_handler_impl.h"
17 #include "components/copresence/handlers/audio/tick_clock_ref_counted.h"
18 #include "components/copresence/proto/data.pb.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 using audio_modem::AUDIBLE
;
22 using audio_modem::AudioType
;
23 using audio_modem::INAUDIBLE
;
24 using audio_modem::StubModem
;
26 namespace copresence
{
30 const Directive
CreateDirective(TokenInstructionType type
,
34 directive
.mutable_token_instruction()->set_token_instruction_type(type
);
35 directive
.mutable_token_instruction()->set_token_id("token");
36 directive
.mutable_token_instruction()->set_medium(audible
?
37 AUDIO_AUDIBLE_DTMF
: AUDIO_ULTRASOUND_PASSBAND
);
38 directive
.set_ttl_millis(ttl
);
44 class AudioDirectiveHandlerTest
: public testing::Test
{
46 AudioDirectiveHandlerTest() {
47 modem_ptr_
= new StubModem
;
48 timer_ptr_
= new base::MockTimer(false, false);
49 clock_ptr_
= new base::SimpleTestTickClock
;
51 directive_handler_
.reset(new AudioDirectiveHandlerImpl(
52 base::Bind(&AudioDirectiveHandlerTest::GetDirectiveUpdates
,
53 base::Unretained(this)),
54 make_scoped_ptr
<audio_modem::Modem
>(modem_ptr_
),
55 make_scoped_ptr
<base::Timer
>(timer_ptr_
),
56 make_scoped_refptr(new TickClockRefCounted(clock_ptr_
))));
57 directive_handler_
->Initialize(nullptr, audio_modem::TokensCallback());
59 ~AudioDirectiveHandlerTest() override
{}
62 const std::vector
<Directive
>& current_directives() {
63 return current_directives_
;
66 bool IsPlaying(AudioType type
) { return modem_ptr_
->IsPlaying(type
); }
68 bool IsRecording(AudioType type
) { return modem_ptr_
->IsRecording(type
); }
70 // This order is important. We want the message loop to get created before
71 // our the audio directive handler since the directive list ctor (invoked
72 // from the directive handler ctor) will post tasks.
73 base::MessageLoop message_loop_
;
74 scoped_ptr
<AudioDirectiveHandler
> directive_handler_
;
76 std::vector
<Directive
> current_directives_
;
79 StubModem
* modem_ptr_
;
80 base::MockTimer
* timer_ptr_
;
81 base::SimpleTestTickClock
* clock_ptr_
;
84 void GetDirectiveUpdates(const std::vector
<Directive
>& current_directives
) {
85 current_directives_
= current_directives
;
88 DISALLOW_COPY_AND_ASSIGN(AudioDirectiveHandlerTest
);
91 TEST_F(AudioDirectiveHandlerTest
, Basic
) {
92 const int64 kTtl
= 10;
93 directive_handler_
->AddInstruction(CreateDirective(TRANSMIT
, true, kTtl
),
95 directive_handler_
->AddInstruction(CreateDirective(TRANSMIT
, false, kTtl
),
97 directive_handler_
->AddInstruction(CreateDirective(TRANSMIT
, false, kTtl
),
99 directive_handler_
->AddInstruction(CreateDirective(RECEIVE
, false, kTtl
),
101 directive_handler_
->AddInstruction(CreateDirective(RECEIVE
, true, kTtl
),
103 directive_handler_
->AddInstruction(CreateDirective(RECEIVE
, false, kTtl
),
106 EXPECT_TRUE(IsPlaying(AUDIBLE
));
107 EXPECT_TRUE(IsPlaying(INAUDIBLE
));
108 EXPECT_TRUE(IsRecording(AUDIBLE
));
109 EXPECT_TRUE(IsRecording(INAUDIBLE
));
111 directive_handler_
->RemoveInstructions("op_id1");
112 EXPECT_FALSE(IsPlaying(AUDIBLE
));
113 EXPECT_TRUE(IsPlaying(INAUDIBLE
));
114 EXPECT_TRUE(IsRecording(AUDIBLE
));
115 EXPECT_TRUE(IsRecording(INAUDIBLE
));
117 directive_handler_
->RemoveInstructions("op_id2");
118 EXPECT_FALSE(IsPlaying(INAUDIBLE
));
119 EXPECT_FALSE(IsRecording(AUDIBLE
));
120 EXPECT_TRUE(IsRecording(INAUDIBLE
));
122 directive_handler_
->RemoveInstructions("op_id3");
123 EXPECT_FALSE(IsRecording(INAUDIBLE
));
126 TEST_F(AudioDirectiveHandlerTest
, Timed
) {
127 directive_handler_
->AddInstruction(CreateDirective(TRANSMIT
, true, 6),
129 directive_handler_
->AddInstruction(CreateDirective(TRANSMIT
, false, 8),
131 directive_handler_
->AddInstruction(CreateDirective(RECEIVE
, false, 4),
134 EXPECT_TRUE(IsPlaying(AUDIBLE
));
135 EXPECT_TRUE(IsPlaying(INAUDIBLE
));
136 EXPECT_FALSE(IsRecording(AUDIBLE
));
137 EXPECT_TRUE(IsRecording(INAUDIBLE
));
139 // Every time we advance and a directive expires, the timer should fire also.
140 clock_ptr_
->Advance(base::TimeDelta::FromMilliseconds(5));
143 // We are now at +5ms. This instruction expires at +10ms.
144 directive_handler_
->AddInstruction(CreateDirective(RECEIVE
, true, 5),
146 EXPECT_TRUE(IsPlaying(AUDIBLE
));
147 EXPECT_TRUE(IsPlaying(INAUDIBLE
));
148 EXPECT_TRUE(IsRecording(AUDIBLE
));
149 EXPECT_FALSE(IsRecording(INAUDIBLE
));
152 const base::TimeDelta twoMs
= base::TimeDelta::FromMilliseconds(2);
153 clock_ptr_
->Advance(twoMs
);
156 EXPECT_FALSE(IsPlaying(AUDIBLE
));
157 EXPECT_TRUE(IsPlaying(INAUDIBLE
));
158 EXPECT_TRUE(IsRecording(AUDIBLE
));
161 clock_ptr_
->Advance(twoMs
);
163 EXPECT_FALSE(IsPlaying(INAUDIBLE
));
164 EXPECT_TRUE(IsRecording(AUDIBLE
));
167 clock_ptr_
->Advance(twoMs
);
169 EXPECT_FALSE(IsRecording(AUDIBLE
));
172 // TODO(rkc): Write more tests that check more convoluted sequences of
173 // transmits/receives.
175 } // namespace copresence