Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: chrome/browser/extensions/api/audio_modem/audio_modem_api_unittest.cc

Issue 2131993002: Delete the audio modem and copresence private APIs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@eol
Patch Set: Sync again Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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.
4
5 #include "chrome/browser/extensions/api/audio_modem/audio_modem_api.h"
6
7 #include <map>
8 #include <memory>
9 #include <string>
10 #include <utility>
11 #include <vector>
12
13 #include "base/callback.h"
14 #include "base/memory/ptr_util.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/values.h"
17 #include "chrome/browser/extensions/extension_api_unittest.h"
18 #include "chrome/browser/extensions/extension_function_test_utils.h"
19 #include "chrome/browser/extensions/test_extension_system.h"
20 #include "components/audio_modem/public/modem.h"
21 #include "components/audio_modem/test/stub_modem.h"
22 #include "components/audio_modem/test/stub_whispernet_client.h"
23 #include "extensions/browser/api_test_utils.h"
24 #include "extensions/browser/event_router.h"
25 #include "extensions/browser/event_router_factory.h"
26
27 using audio_modem::AUDIBLE;
28 using audio_modem::AudioToken;
29 using audio_modem::INAUDIBLE;
30 using audio_modem::StubModem;
31 using audio_modem::StubWhispernetClient;
32
33 using base::BinaryValue;
34 using base::DictionaryValue;
35 using base::ListValue;
36 using base::StringValue;
37 using base::Value;
38
39 using content::BrowserContext;
40
41 namespace ext_test_utils = extension_function_test_utils;
42
43 namespace extensions {
44
45 namespace {
46
47 // The TestingFactoryFunction uses a BrowserContext as its context pointer.
48 // But each BrowserContext is still associated with a unit test.
49 // So we store the StubModem created in each test.
50 std::map<BrowserContext*, StubModem*> g_modems;
51
52 // Create a test AudioModemAPI and store the modem it uses.
53 std::unique_ptr<KeyedService> ApiFactoryFunction(BrowserContext* context) {
54 StubModem* modem = new StubModem;
55 g_modems[context] = modem;
56 return base::WrapUnique(new AudioModemAPI(
57 context,
58 base::WrapUnique<audio_modem::WhispernetClient>(new StubWhispernetClient),
59 base::WrapUnique<audio_modem::Modem>(modem)));
60 }
61
62 std::unique_ptr<DictionaryValue> CreateParams(const std::string& audio_band) {
63 std::unique_ptr<DictionaryValue> params(new DictionaryValue);
64 params->SetInteger("timeoutMillis", 60000);
65 params->SetString("band", audio_band);
66 params->SetInteger("encoding.tokenLength", 4);
67 return params;
68 }
69
70 std::unique_ptr<BinaryValue> CreateToken(const std::string& token) {
71 return BinaryValue::CreateWithCopiedBuffer(token.c_str(), token.size());
72 }
73
74 std::unique_ptr<ListValue> CreateList(std::unique_ptr<Value> single_elt) {
75 std::unique_ptr<ListValue> list(new ListValue);
76 list->Append(std::move(single_elt));
77 return list;
78 }
79
80 std::unique_ptr<ListValue> CreateList(std::unique_ptr<Value> elt1,
81 std::unique_ptr<Value> elt2) {
82 std::unique_ptr<ListValue> list(new ListValue);
83 list->Append(std::move(elt1));
84 list->Append(std::move(elt2));
85 return list;
86 }
87
88 DictionaryValue* CreateReceivedToken(const std::string& token,
89 const std::string& audio_band) {
90 DictionaryValue* out = new DictionaryValue;
91 out->Set("token", CreateToken(token));
92 out->SetString("band", audio_band);
93 return out;
94 }
95
96 bool ReceivedSingleToken(const Event* event,
97 const DictionaryValue* expected_token) {
98 ListValue* received_tokens;
99 event->event_args->GetList(0, &received_tokens);
100 if (received_tokens->GetSize() != 1)
101 return false;
102
103 DictionaryValue* received_token;
104 received_tokens->GetDictionary(0, &received_token);
105 return received_token->Equals(expected_token);
106 }
107
108 // TODO(ckehoe): Put this in //extensions/test.
109 // Then replace the other EventRouter mocks.
110 class StubEventRouter : public EventRouter {
111 public:
112 // Callback to receive events. First argument is
113 // the extension id to receive the event.
114 using EventCallback =
115 base::Callback<void(const std::string&, std::unique_ptr<Event>)>;
116
117 explicit StubEventRouter(BrowserContext* context)
118 : EventRouter(context, nullptr) {}
119
120 void DispatchEventToExtension(const std::string& extension_id,
121 std::unique_ptr<Event> event) override {
122 event_callback_.Run(extension_id, std::move(event));
123 }
124
125 void SetEventCallBack(EventCallback event_callback) {
126 event_callback_ = event_callback;
127 }
128
129 void ClearEventCallback() {
130 event_callback_.Reset();
131 }
132
133 private:
134 EventCallback event_callback_;
135 };
136
137 // StubEventRouter factory function
138 std::unique_ptr<KeyedService> StubEventRouterFactoryFunction(
139 content::BrowserContext* context) {
140 return base::WrapUnique(new StubEventRouter(context));
141 }
142
143 } // namespace
144
145 class AudioModemApiUnittest : public ExtensionApiUnittest {
146 public:
147 AudioModemApiUnittest() {}
148 ~AudioModemApiUnittest() override {}
149
150 protected:
151 template <typename Function>
152 const std::string RunFunction(std::unique_ptr<ListValue> args,
153 const Extension* extension) {
154 scoped_refptr<UIThreadExtensionFunction> function(new Function);
155 function->set_extension(extension);
156 function->set_browser_context(profile());
157 function->set_has_callback(true);
158 ext_test_utils::RunFunction(function.get(), std::move(args), browser(),
159 ext_test_utils::NONE);
160
161 std::string result_status;
162 CHECK(function->GetResultList()->GetString(0, &result_status));
163 return result_status;
164 }
165
166 template <typename Function>
167 const std::string RunFunction(std::unique_ptr<ListValue> args) {
168 return RunFunction<Function>(std::move(args), GetExtension(std::string()));
169 }
170
171 StubModem* GetModem() const {
172 return g_modems[profile()];
173 }
174
175 const Extension* GetExtension(const std::string& name) {
176 if (!extensions_by_name_[name].get()) {
177 std::unique_ptr<DictionaryValue> extension_definition(
178 new DictionaryValue);
179 extension_definition->SetString("name", name);
180 extension_definition->SetString("version", "1.0");
181 extensions_by_name_[name] = api_test_utils::CreateExtension(
182 Manifest::INTERNAL, extension_definition.get(), name);
183 DVLOG(2) << "Created extension " << extensions_by_name_[name]->id();
184 }
185 return extensions_by_name_[name].get();
186 }
187
188 const std::vector<std::unique_ptr<const Event>>& GetEventsForExtension(
189 const std::string& name) {
190 const Extension* extension = extensions_by_name_[name].get();
191 DCHECK(extension);
192 return events_by_extension_id_[extension->id()];
193 }
194
195 const std::vector<std::unique_ptr<const Event>>& GetEvents() {
196 return GetEventsForExtension(std::string());
197 }
198
199 private:
200 void SetUp() override {
201 ExtensionApiUnittest::SetUp();
202 AudioModemAPI::GetFactoryInstance()->SetTestingFactory(
203 profile(), &ApiFactoryFunction);
204
205 StubEventRouter* stub_event_router = static_cast<StubEventRouter*>(
206 extensions::EventRouterFactory::GetInstance()->SetTestingFactoryAndUse(
207 profile(), &StubEventRouterFactoryFunction));
208 stub_event_router->SetEventCallBack(base::Bind(
209 &AudioModemApiUnittest::CaptureEvent, base::Unretained(this)));
210 }
211
212 void CaptureEvent(const std::string& extension_id,
213 std::unique_ptr<Event> event) {
214 events_by_extension_id_[extension_id].push_back(std::move(event));
215 }
216
217 std::map<std::string, scoped_refptr<Extension>> extensions_by_name_;
218
219 std::map<std::string, std::vector<std::unique_ptr<const Event>>>
220 events_by_extension_id_;
221 };
222
223 TEST_F(AudioModemApiUnittest, TransmitBasic) {
224 // Start transmitting inaudibly.
225 EXPECT_EQ("success", RunFunction<AudioModemTransmitFunction>(
226 CreateList(CreateParams("inaudible"), CreateToken("1234"))));
227 EXPECT_TRUE(GetModem()->IsPlaying(INAUDIBLE));
228
229 // Can't cancel audible transmit - we haven't started it yet.
230 EXPECT_EQ("invalidRequest",
231 RunFunction<AudioModemStopTransmitFunction>(
232 CreateList(base::MakeUnique<StringValue>("audible"))));
233
234 // Start transmitting audibly.
235 EXPECT_EQ("success", RunFunction<AudioModemTransmitFunction>(
236 CreateList(CreateParams("audible"), CreateToken("ABCD"))));
237 EXPECT_TRUE(GetModem()->IsPlaying(AUDIBLE));
238
239 // Stop audible transmit. We're still transmitting inaudibly.
240 EXPECT_EQ("success", RunFunction<AudioModemStopTransmitFunction>(CreateList(
241 base::MakeUnique<StringValue>("audible"))));
242 EXPECT_FALSE(GetModem()->IsPlaying(AUDIBLE));
243 EXPECT_TRUE(GetModem()->IsPlaying(INAUDIBLE));
244
245 // Stop inaudible transmit.
246 EXPECT_EQ("success", RunFunction<AudioModemStopTransmitFunction>(CreateList(
247 base::MakeUnique<StringValue>("inaudible"))));
248 EXPECT_FALSE(GetModem()->IsPlaying(INAUDIBLE));
249 }
250
251 TEST_F(AudioModemApiUnittest, ReceiveBasic) {
252 // Start listening for audible tokens.
253 EXPECT_EQ("success", RunFunction<AudioModemReceiveFunction>(
254 CreateList(CreateParams("audible"))));
255 EXPECT_TRUE(GetModem()->IsRecording(AUDIBLE));
256
257 // Can't cancel inaudible receive - we haven't started it yet.
258 EXPECT_EQ("invalidRequest",
259 RunFunction<AudioModemStopReceiveFunction>(
260 CreateList(base::MakeUnique<StringValue>("inaudible"))));
261
262 // Send some audible tokens.
263 std::vector<AudioToken> tokens;
264 tokens.push_back(AudioToken("1234", true));
265 tokens.push_back(AudioToken("ABCD", true));
266 tokens.push_back(AudioToken("abcd", false));
267 GetModem()->DeliverTokens(tokens);
268
269 // Check the tokens received.
270 EXPECT_EQ(1u, GetEvents().size());
271 std::unique_ptr<ListValue> expected_tokens(new ListValue);
272 expected_tokens->Append(CreateReceivedToken("1234", "audible"));
273 expected_tokens->Append(CreateReceivedToken("ABCD", "audible"));
274 ListValue* received_tokens;
275 GetEvents()[0]->event_args->GetList(0, &received_tokens);
276 EXPECT_TRUE(received_tokens->Equals(expected_tokens.get()));
277
278 // Start listening for inaudible tokens.
279 EXPECT_EQ("success", RunFunction<AudioModemReceiveFunction>(
280 CreateList(CreateParams("inaudible"))));
281 EXPECT_TRUE(GetModem()->IsRecording(INAUDIBLE));
282
283 // Send some more tokens.
284 tokens.push_back(AudioToken("5678", false));
285 GetModem()->DeliverTokens(tokens);
286
287 // Check the tokens received.
288 EXPECT_EQ(2u, GetEvents().size());
289 expected_tokens->Append(CreateReceivedToken("abcd", "inaudible"));
290 expected_tokens->Append(CreateReceivedToken("5678", "inaudible"));
291 GetEvents()[1]->event_args->GetList(0, &received_tokens);
292 EXPECT_TRUE(received_tokens->Equals(expected_tokens.get()));
293
294 // Stop audible receive. We're still receiving inaudible.
295 EXPECT_EQ("success", RunFunction<AudioModemStopReceiveFunction>(CreateList(
296 base::MakeUnique<StringValue>("audible"))));
297 EXPECT_FALSE(GetModem()->IsRecording(AUDIBLE));
298 EXPECT_TRUE(GetModem()->IsRecording(INAUDIBLE));
299
300 // Stop inaudible receive.
301 EXPECT_EQ("success", RunFunction<AudioModemStopReceiveFunction>(CreateList(
302 base::MakeUnique<StringValue>("inaudible"))));
303 EXPECT_FALSE(GetModem()->IsRecording(INAUDIBLE));
304 }
305
306 TEST_F(AudioModemApiUnittest, TransmitMultiple) {
307 // Start transmit.
308 EXPECT_EQ("success", RunFunction<AudioModemTransmitFunction>(
309 CreateList(CreateParams("audible"), CreateToken("1234")),
310 GetExtension("ext1")));
311 EXPECT_TRUE(GetModem()->IsPlaying(AUDIBLE));
312
313 // Another extension can't interfere with the first one.
314 EXPECT_EQ("inUse", RunFunction<AudioModemTransmitFunction>(
315 CreateList(CreateParams("audible"), CreateToken("ABCD")),
316 GetExtension("ext2")));
317 EXPECT_EQ("invalidRequest",
318 RunFunction<AudioModemStopTransmitFunction>(
319 CreateList(base::MakeUnique<StringValue>("audible")),
320 GetExtension("ext2")));
321 EXPECT_TRUE(GetModem()->IsPlaying(AUDIBLE));
322
323 // The other extension can use the other audio band, however.
324 EXPECT_EQ("success", RunFunction<AudioModemTransmitFunction>(
325 CreateList(CreateParams("inaudible"), CreateToken("ABCD")),
326 GetExtension("ext2")));
327 EXPECT_TRUE(GetModem()->IsPlaying(INAUDIBLE));
328
329 // The first extension can change its token.
330 // But the other band is still in use.
331 EXPECT_EQ("success", RunFunction<AudioModemTransmitFunction>(
332 CreateList(CreateParams("audible"), CreateToken("abcd")),
333 GetExtension("ext1")));
334 EXPECT_EQ("inUse", RunFunction<AudioModemTransmitFunction>(
335 CreateList(CreateParams("inaudible"), CreateToken("1234")),
336 GetExtension("ext1")));
337
338 // Stop transmission.
339 EXPECT_EQ("success", RunFunction<AudioModemStopTransmitFunction>(
340 CreateList(base::MakeUnique<StringValue>("audible")),
341 GetExtension("ext1")));
342 EXPECT_FALSE(GetModem()->IsPlaying(AUDIBLE));
343 EXPECT_EQ("success",
344 RunFunction<AudioModemStopTransmitFunction>(
345 CreateList(base::MakeUnique<StringValue>("inaudible")),
346 GetExtension("ext2")));
347 EXPECT_FALSE(GetModem()->IsPlaying(INAUDIBLE));
348 }
349
350 TEST_F(AudioModemApiUnittest, ReceiveMultiple) {
351 // Start receive. Multiple extensions can receive on the same band.
352 EXPECT_EQ("success", RunFunction<AudioModemReceiveFunction>(
353 CreateList(CreateParams("inaudible")), GetExtension("ext1")));
354 EXPECT_TRUE(GetModem()->IsRecording(INAUDIBLE));
355 EXPECT_EQ("success", RunFunction<AudioModemReceiveFunction>(
356 CreateList(CreateParams("inaudible")), GetExtension("ext2")));
357
358 // Receive a token.
359 GetModem()->DeliverTokens(std::vector<AudioToken>(
360 1, AudioToken("abcd", false)));
361 EXPECT_EQ(1u, GetEventsForExtension("ext1").size());
362 EXPECT_EQ(1u, GetEventsForExtension("ext2").size());
363
364 // Check the token received.
365 std::unique_ptr<DictionaryValue> expected_token(
366 CreateReceivedToken("abcd", "inaudible"));
367 EXPECT_TRUE(ReceivedSingleToken(GetEventsForExtension("ext1")[0].get(),
368 expected_token.get()));
369 EXPECT_TRUE(ReceivedSingleToken(GetEventsForExtension("ext2")[0].get(),
370 expected_token.get()));
371
372 // If one extension stops, the modem is still receiving for the other.
373 EXPECT_EQ("success",
374 RunFunction<AudioModemStopReceiveFunction>(
375 CreateList(base::MakeUnique<StringValue>("inaudible")),
376 GetExtension("ext1")));
377 EXPECT_TRUE(GetModem()->IsRecording(INAUDIBLE));
378
379 // Receive another token. Should only go to ext2.
380 GetModem()->DeliverTokens(std::vector<AudioToken>(
381 1, AudioToken("1234", false)));
382 EXPECT_EQ(1u, GetEventsForExtension("ext1").size());
383 EXPECT_EQ(2u, GetEventsForExtension("ext2").size());
384 expected_token.reset(CreateReceivedToken("1234", "inaudible"));
385 EXPECT_TRUE(ReceivedSingleToken(GetEventsForExtension("ext2")[1].get(),
386 expected_token.get()));
387
388 EXPECT_EQ("success",
389 RunFunction<AudioModemStopReceiveFunction>(
390 CreateList(base::MakeUnique<StringValue>("inaudible")),
391 GetExtension("ext2")));
392 EXPECT_FALSE(GetModem()->IsRecording(INAUDIBLE));
393 }
394
395 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/audio_modem/audio_modem_api.cc ('k') | chrome/browser/extensions/api/copresence_private/OWNERS » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698