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.
5 #include "chrome/browser/copresence/chrome_whispernet_client.h"
10 #include "base/bind.h"
11 #include "base/macros.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/run_loop.h"
14 #include "base/stl_util.h"
15 #include "chrome/browser/extensions/api/copresence/copresence_api.h"
16 #include "chrome/browser/extensions/extension_browsertest.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "media/base/audio_bus.h"
24 const char kSixZeros
[] = "MDAwMDAw";
26 copresence::WhispernetClient
* GetWhispernetClient(
27 content::BrowserContext
* context
) {
28 extensions::CopresenceService
* service
=
29 extensions::CopresenceService::GetFactoryInstance()->Get(context
);
30 return service
? service
->whispernet_client() : NULL
;
33 // Copied from src/components/copresence/mediums/audio/audio_recorder.cc
34 std::string
AudioBusToString(scoped_refptr
<media::AudioBusRefCounted
> source
) {
36 buffer
.resize(source
->frames() * source
->channels() * sizeof(float));
37 float* buffer_view
= reinterpret_cast<float*>(string_as_array(&buffer
));
39 const int channels
= source
->channels();
40 for (int ch
= 0; ch
< channels
; ++ch
) {
41 for (int si
= 0, di
= ch
; si
< source
->frames(); ++si
, di
+= channels
)
42 buffer_view
[di
] = source
->channel(ch
)[si
];
50 class ChromeWhispernetClientTest
: public ExtensionBrowserTest
{
52 ChromeWhispernetClientTest() : context_(NULL
), initialized_(false) {}
54 virtual ~ChromeWhispernetClientTest() {}
56 void InitializeWhispernet() {
57 context_
= browser()->profile();
58 run_loop_
.reset(new base::RunLoop());
59 GetWhispernetClient(context_
)->Initialize(base::Bind(
60 &ChromeWhispernetClientTest::InitCallback
, base::Unretained(this)));
63 EXPECT_TRUE(initialized_
);
66 void EncodeTokenAndSaveSamples(bool audible
) {
67 copresence::WhispernetClient
* client
= GetWhispernetClient(context_
);
70 run_loop_
.reset(new base::RunLoop());
71 client
->RegisterSamplesCallback(base::Bind(
72 &ChromeWhispernetClientTest::SamplesCallback
, base::Unretained(this)));
73 expected_token_
= kSixZeros
;
74 expected_audible_
= audible
;
76 client
->EncodeToken(kSixZeros
, audible
);
79 EXPECT_GT(saved_samples_
->frames(), 0);
82 void DecodeSamplesAndVerifyToken(bool expect_audible
) {
83 copresence::WhispernetClient
* client
= GetWhispernetClient(context_
);
86 run_loop_
.reset(new base::RunLoop());
87 client
->RegisterTokensCallback(base::Bind(
88 &ChromeWhispernetClientTest::TokensCallback
, base::Unretained(this)));
89 expected_token_
= kSixZeros
;
90 expected_audible_
= expect_audible
;
92 ASSERT_GT(saved_samples_
->frames(), 0);
94 // Convert our single channel samples to two channel. Decode samples
95 // expects 2 channel data.
96 scoped_refptr
<media::AudioBusRefCounted
> samples_bus
=
97 media::AudioBusRefCounted::Create(2, saved_samples_
->frames());
98 memcpy(samples_bus
->channel(0),
99 saved_samples_
->channel(0),
100 sizeof(float) * saved_samples_
->frames());
101 memcpy(samples_bus
->channel(1),
102 saved_samples_
->channel(0),
103 sizeof(float) * saved_samples_
->frames());
105 client
->DecodeSamples(AudioBusToString(samples_bus
));
109 void DetectBroadcast() {
110 copresence::WhispernetClient
* client
= GetWhispernetClient(context_
);
113 run_loop_
.reset(new base::RunLoop());
114 client
->RegisterDetectBroadcastCallback(
115 base::Bind(&ChromeWhispernetClientTest::DetectBroadcastCallback
,
116 base::Unretained(this)));
117 client
->DetectBroadcast();
122 void InitCallback(bool success
) {
123 EXPECT_TRUE(success
);
125 ASSERT_TRUE(run_loop_
);
129 void SamplesCallback(
130 const std::string
& token
,
132 const scoped_refptr
<media::AudioBusRefCounted
>& samples
) {
133 EXPECT_EQ(expected_token_
, token
);
134 EXPECT_EQ(expected_audible_
, audible
);
135 saved_samples_
= samples
;
136 ASSERT_TRUE(run_loop_
);
140 void TokensCallback(const std::vector
<copresence::AudioToken
>& tokens
) {
141 ASSERT_TRUE(run_loop_
);
144 EXPECT_EQ(expected_token_
, tokens
[0].token
);
145 EXPECT_EQ(expected_audible_
, tokens
[0].audible
);
148 void DetectBroadcastCallback(bool success
) {
149 EXPECT_TRUE(success
);
150 ASSERT_TRUE(run_loop_
);
155 scoped_ptr
<base::RunLoop
> run_loop_
;
156 content::BrowserContext
* context_
;
158 std::string expected_token_
;
159 bool expected_audible_
;
160 scoped_refptr
<media::AudioBusRefCounted
> saved_samples_
;
164 DISALLOW_COPY_AND_ASSIGN(ChromeWhispernetClientTest
);
167 IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest
, Initialize
) {
168 InitializeWhispernet();
171 IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest
, EncodeToken
) {
172 InitializeWhispernet();
173 EncodeTokenAndSaveSamples(false);
176 IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest
, DecodeSamples
) {
177 InitializeWhispernet();
178 EncodeTokenAndSaveSamples(false);
179 DecodeSamplesAndVerifyToken(false);
182 IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest
, DetectBroadcast
) {
183 InitializeWhispernet();
184 EncodeTokenAndSaveSamples(false);
185 DecodeSamplesAndVerifyToken(false);
189 IN_PROC_BROWSER_TEST_F(ChromeWhispernetClientTest
, Audible
) {
190 InitializeWhispernet();
191 EncodeTokenAndSaveSamples(true);
192 DecodeSamplesAndVerifyToken(true);