| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/extensions/api/audio_modem/audio_modem_api.h" |
| 6 |
| 5 #include <map> | 7 #include <map> |
| 8 #include <memory> |
| 6 #include <string> | 9 #include <string> |
| 7 #include <utility> | 10 #include <utility> |
| 8 #include <vector> | 11 #include <vector> |
| 9 | 12 |
| 10 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/memory/ptr_util.h" |
| 11 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
| 12 #include "base/memory/scoped_ptr.h" | |
| 13 #include "base/values.h" | 16 #include "base/values.h" |
| 14 #include "chrome/browser/extensions/api/audio_modem/audio_modem_api.h" | |
| 15 #include "chrome/browser/extensions/extension_api_unittest.h" | 17 #include "chrome/browser/extensions/extension_api_unittest.h" |
| 16 #include "chrome/browser/extensions/extension_function_test_utils.h" | 18 #include "chrome/browser/extensions/extension_function_test_utils.h" |
| 17 #include "chrome/browser/extensions/test_extension_system.h" | 19 #include "chrome/browser/extensions/test_extension_system.h" |
| 18 #include "components/audio_modem/public/modem.h" | 20 #include "components/audio_modem/public/modem.h" |
| 19 #include "components/audio_modem/test/stub_modem.h" | 21 #include "components/audio_modem/test/stub_modem.h" |
| 20 #include "components/audio_modem/test/stub_whispernet_client.h" | 22 #include "components/audio_modem/test/stub_whispernet_client.h" |
| 21 #include "extensions/browser/api_test_utils.h" | 23 #include "extensions/browser/api_test_utils.h" |
| 22 #include "extensions/browser/event_router.h" | 24 #include "extensions/browser/event_router.h" |
| 23 #include "extensions/browser/event_router_factory.h" | 25 #include "extensions/browser/event_router_factory.h" |
| 24 | 26 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 41 namespace extensions { | 43 namespace extensions { |
| 42 | 44 |
| 43 namespace { | 45 namespace { |
| 44 | 46 |
| 45 // The TestingFactoryFunction uses a BrowserContext as its context pointer. | 47 // The TestingFactoryFunction uses a BrowserContext as its context pointer. |
| 46 // But each BrowserContext is still associated with a unit test. | 48 // But each BrowserContext is still associated with a unit test. |
| 47 // So we store the StubModem created in each test. | 49 // So we store the StubModem created in each test. |
| 48 std::map<BrowserContext*, StubModem*> g_modems; | 50 std::map<BrowserContext*, StubModem*> g_modems; |
| 49 | 51 |
| 50 // Create a test AudioModemAPI and store the modem it uses. | 52 // Create a test AudioModemAPI and store the modem it uses. |
| 51 scoped_ptr<KeyedService> ApiFactoryFunction(BrowserContext* context) { | 53 std::unique_ptr<KeyedService> ApiFactoryFunction(BrowserContext* context) { |
| 52 StubModem* modem = new StubModem; | 54 StubModem* modem = new StubModem; |
| 53 g_modems[context] = modem; | 55 g_modems[context] = modem; |
| 54 return make_scoped_ptr(new AudioModemAPI( | 56 return base::WrapUnique(new AudioModemAPI( |
| 55 context, | 57 context, |
| 56 make_scoped_ptr<audio_modem::WhispernetClient>(new StubWhispernetClient), | 58 base::WrapUnique<audio_modem::WhispernetClient>(new StubWhispernetClient), |
| 57 make_scoped_ptr<audio_modem::Modem>(modem))); | 59 base::WrapUnique<audio_modem::Modem>(modem))); |
| 58 } | 60 } |
| 59 | 61 |
| 60 DictionaryValue* CreateParams(const std::string& audio_band) { | 62 DictionaryValue* CreateParams(const std::string& audio_band) { |
| 61 DictionaryValue* params = new DictionaryValue; | 63 DictionaryValue* params = new DictionaryValue; |
| 62 params->SetInteger("timeoutMillis", 60000); | 64 params->SetInteger("timeoutMillis", 60000); |
| 63 params->SetString("band", audio_band); | 65 params->SetString("band", audio_band); |
| 64 params->SetInteger("encoding.tokenLength", 4); | 66 params->SetInteger("encoding.tokenLength", 4); |
| 65 return params; | 67 return params; |
| 66 } | 68 } |
| 67 | 69 |
| 68 BinaryValue* CreateToken(const std::string& token) { | 70 BinaryValue* CreateToken(const std::string& token) { |
| 69 return BinaryValue::CreateWithCopiedBuffer(token.c_str(), token.size()); | 71 return BinaryValue::CreateWithCopiedBuffer(token.c_str(), token.size()); |
| 70 } | 72 } |
| 71 | 73 |
| 72 scoped_ptr<ListValue> CreateList(Value* single_elt) { | 74 std::unique_ptr<ListValue> CreateList(Value* single_elt) { |
| 73 scoped_ptr<ListValue> list(new ListValue); | 75 std::unique_ptr<ListValue> list(new ListValue); |
| 74 list->Append(single_elt); | 76 list->Append(single_elt); |
| 75 return list; | 77 return list; |
| 76 } | 78 } |
| 77 | 79 |
| 78 scoped_ptr<ListValue> CreateList(Value* elt1, Value* elt2) { | 80 std::unique_ptr<ListValue> CreateList(Value* elt1, Value* elt2) { |
| 79 scoped_ptr<ListValue> list(new ListValue); | 81 std::unique_ptr<ListValue> list(new ListValue); |
| 80 list->Append(elt1); | 82 list->Append(elt1); |
| 81 list->Append(elt2); | 83 list->Append(elt2); |
| 82 return list; | 84 return list; |
| 83 } | 85 } |
| 84 | 86 |
| 85 DictionaryValue* CreateReceivedToken(const std::string& token, | 87 DictionaryValue* CreateReceivedToken(const std::string& token, |
| 86 const std::string& audio_band) { | 88 const std::string& audio_band) { |
| 87 DictionaryValue* out = new DictionaryValue; | 89 DictionaryValue* out = new DictionaryValue; |
| 88 out->Set("token", CreateToken(token)); | 90 out->Set("token", CreateToken(token)); |
| 89 out->SetString("band", audio_band); | 91 out->SetString("band", audio_band); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 101 received_tokens->GetDictionary(0, &received_token); | 103 received_tokens->GetDictionary(0, &received_token); |
| 102 return received_token->Equals(expected_token); | 104 return received_token->Equals(expected_token); |
| 103 } | 105 } |
| 104 | 106 |
| 105 // TODO(ckehoe): Put this in //extensions/test. | 107 // TODO(ckehoe): Put this in //extensions/test. |
| 106 // Then replace the other EventRouter mocks. | 108 // Then replace the other EventRouter mocks. |
| 107 class StubEventRouter : public EventRouter { | 109 class StubEventRouter : public EventRouter { |
| 108 public: | 110 public: |
| 109 // Callback to receive events. First argument is | 111 // Callback to receive events. First argument is |
| 110 // the extension id to receive the event. | 112 // the extension id to receive the event. |
| 111 using EventCallback = base::Callback<void(const std::string&, | 113 using EventCallback = |
| 112 scoped_ptr<Event>)>; | 114 base::Callback<void(const std::string&, std::unique_ptr<Event>)>; |
| 113 | 115 |
| 114 explicit StubEventRouter(BrowserContext* context) | 116 explicit StubEventRouter(BrowserContext* context) |
| 115 : EventRouter(context, nullptr) {} | 117 : EventRouter(context, nullptr) {} |
| 116 | 118 |
| 117 void DispatchEventToExtension(const std::string& extension_id, | 119 void DispatchEventToExtension(const std::string& extension_id, |
| 118 scoped_ptr<Event> event) override { | 120 std::unique_ptr<Event> event) override { |
| 119 event_callback_.Run(extension_id, std::move(event)); | 121 event_callback_.Run(extension_id, std::move(event)); |
| 120 } | 122 } |
| 121 | 123 |
| 122 void SetEventCallBack(EventCallback event_callback) { | 124 void SetEventCallBack(EventCallback event_callback) { |
| 123 event_callback_ = event_callback; | 125 event_callback_ = event_callback; |
| 124 } | 126 } |
| 125 | 127 |
| 126 void ClearEventCallback() { | 128 void ClearEventCallback() { |
| 127 event_callback_.Reset(); | 129 event_callback_.Reset(); |
| 128 } | 130 } |
| 129 | 131 |
| 130 private: | 132 private: |
| 131 EventCallback event_callback_; | 133 EventCallback event_callback_; |
| 132 }; | 134 }; |
| 133 | 135 |
| 134 // StubEventRouter factory function | 136 // StubEventRouter factory function |
| 135 scoped_ptr<KeyedService> StubEventRouterFactoryFunction( | 137 std::unique_ptr<KeyedService> StubEventRouterFactoryFunction( |
| 136 content::BrowserContext* context) { | 138 content::BrowserContext* context) { |
| 137 return make_scoped_ptr(new StubEventRouter(context)); | 139 return base::WrapUnique(new StubEventRouter(context)); |
| 138 } | 140 } |
| 139 | 141 |
| 140 } // namespace | 142 } // namespace |
| 141 | 143 |
| 142 class AudioModemApiUnittest : public ExtensionApiUnittest { | 144 class AudioModemApiUnittest : public ExtensionApiUnittest { |
| 143 public: | 145 public: |
| 144 AudioModemApiUnittest() {} | 146 AudioModemApiUnittest() {} |
| 145 ~AudioModemApiUnittest() override {} | 147 ~AudioModemApiUnittest() override {} |
| 146 | 148 |
| 147 protected: | 149 protected: |
| 148 template<typename Function> | 150 template <typename Function> |
| 149 const std::string RunFunction(scoped_ptr<ListValue> args, | 151 const std::string RunFunction(std::unique_ptr<ListValue> args, |
| 150 const Extension* extension) { | 152 const Extension* extension) { |
| 151 scoped_refptr<UIThreadExtensionFunction> function(new Function); | 153 scoped_refptr<UIThreadExtensionFunction> function(new Function); |
| 152 function->set_extension(extension); | 154 function->set_extension(extension); |
| 153 function->set_browser_context(profile()); | 155 function->set_browser_context(profile()); |
| 154 function->set_has_callback(true); | 156 function->set_has_callback(true); |
| 155 ext_test_utils::RunFunction(function.get(), std::move(args), browser(), | 157 ext_test_utils::RunFunction(function.get(), std::move(args), browser(), |
| 156 ext_test_utils::NONE); | 158 ext_test_utils::NONE); |
| 157 | 159 |
| 158 std::string result_status; | 160 std::string result_status; |
| 159 CHECK(function->GetResultList()->GetString(0, &result_status)); | 161 CHECK(function->GetResultList()->GetString(0, &result_status)); |
| 160 return result_status; | 162 return result_status; |
| 161 } | 163 } |
| 162 | 164 |
| 163 template<typename Function> | 165 template <typename Function> |
| 164 const std::string RunFunction(scoped_ptr<ListValue> args) { | 166 const std::string RunFunction(std::unique_ptr<ListValue> args) { |
| 165 return RunFunction<Function>(std::move(args), GetExtension(std::string())); | 167 return RunFunction<Function>(std::move(args), GetExtension(std::string())); |
| 166 } | 168 } |
| 167 | 169 |
| 168 StubModem* GetModem() const { | 170 StubModem* GetModem() const { |
| 169 return g_modems[profile()]; | 171 return g_modems[profile()]; |
| 170 } | 172 } |
| 171 | 173 |
| 172 const Extension* GetExtension(const std::string& name) { | 174 const Extension* GetExtension(const std::string& name) { |
| 173 if (!extensions_by_name_[name].get()) { | 175 if (!extensions_by_name_[name].get()) { |
| 174 scoped_ptr<DictionaryValue> extension_definition(new DictionaryValue); | 176 std::unique_ptr<DictionaryValue> extension_definition( |
| 177 new DictionaryValue); |
| 175 extension_definition->SetString("name", name); | 178 extension_definition->SetString("name", name); |
| 176 extension_definition->SetString("version", "1.0"); | 179 extension_definition->SetString("version", "1.0"); |
| 177 extensions_by_name_[name] = api_test_utils::CreateExtension( | 180 extensions_by_name_[name] = api_test_utils::CreateExtension( |
| 178 Manifest::INTERNAL, extension_definition.get(), name); | 181 Manifest::INTERNAL, extension_definition.get(), name); |
| 179 DVLOG(2) << "Created extension " << extensions_by_name_[name]->id(); | 182 DVLOG(2) << "Created extension " << extensions_by_name_[name]->id(); |
| 180 } | 183 } |
| 181 return extensions_by_name_[name].get(); | 184 return extensions_by_name_[name].get(); |
| 182 } | 185 } |
| 183 | 186 |
| 184 const std::vector<scoped_ptr<const Event>>& GetEventsForExtension( | 187 const std::vector<std::unique_ptr<const Event>>& GetEventsForExtension( |
| 185 const std::string& name) { | 188 const std::string& name) { |
| 186 const Extension* extension = extensions_by_name_[name].get(); | 189 const Extension* extension = extensions_by_name_[name].get(); |
| 187 DCHECK(extension); | 190 DCHECK(extension); |
| 188 return events_by_extension_id_[extension->id()]; | 191 return events_by_extension_id_[extension->id()]; |
| 189 } | 192 } |
| 190 | 193 |
| 191 const std::vector<scoped_ptr<const Event>>& GetEvents() { | 194 const std::vector<std::unique_ptr<const Event>>& GetEvents() { |
| 192 return GetEventsForExtension(std::string()); | 195 return GetEventsForExtension(std::string()); |
| 193 } | 196 } |
| 194 | 197 |
| 195 private: | 198 private: |
| 196 void SetUp() override { | 199 void SetUp() override { |
| 197 ExtensionApiUnittest::SetUp(); | 200 ExtensionApiUnittest::SetUp(); |
| 198 AudioModemAPI::GetFactoryInstance()->SetTestingFactory( | 201 AudioModemAPI::GetFactoryInstance()->SetTestingFactory( |
| 199 profile(), &ApiFactoryFunction); | 202 profile(), &ApiFactoryFunction); |
| 200 | 203 |
| 201 StubEventRouter* stub_event_router = static_cast<StubEventRouter*>( | 204 StubEventRouter* stub_event_router = static_cast<StubEventRouter*>( |
| 202 extensions::EventRouterFactory::GetInstance()->SetTestingFactoryAndUse( | 205 extensions::EventRouterFactory::GetInstance()->SetTestingFactoryAndUse( |
| 203 profile(), &StubEventRouterFactoryFunction)); | 206 profile(), &StubEventRouterFactoryFunction)); |
| 204 stub_event_router->SetEventCallBack(base::Bind( | 207 stub_event_router->SetEventCallBack(base::Bind( |
| 205 &AudioModemApiUnittest::CaptureEvent, base::Unretained(this))); | 208 &AudioModemApiUnittest::CaptureEvent, base::Unretained(this))); |
| 206 } | 209 } |
| 207 | 210 |
| 208 void CaptureEvent(const std::string& extension_id, | 211 void CaptureEvent(const std::string& extension_id, |
| 209 scoped_ptr<Event> event) { | 212 std::unique_ptr<Event> event) { |
| 210 events_by_extension_id_[extension_id].push_back(std::move(event)); | 213 events_by_extension_id_[extension_id].push_back(std::move(event)); |
| 211 } | 214 } |
| 212 | 215 |
| 213 std::map<std::string, scoped_refptr<Extension>> extensions_by_name_; | 216 std::map<std::string, scoped_refptr<Extension>> extensions_by_name_; |
| 214 | 217 |
| 215 std::map<std::string, std::vector<scoped_ptr<const Event>>> | 218 std::map<std::string, std::vector<std::unique_ptr<const Event>>> |
| 216 events_by_extension_id_; | 219 events_by_extension_id_; |
| 217 }; | 220 }; |
| 218 | 221 |
| 219 TEST_F(AudioModemApiUnittest, TransmitBasic) { | 222 TEST_F(AudioModemApiUnittest, TransmitBasic) { |
| 220 // Start transmitting inaudibly. | 223 // Start transmitting inaudibly. |
| 221 EXPECT_EQ("success", RunFunction<AudioModemTransmitFunction>( | 224 EXPECT_EQ("success", RunFunction<AudioModemTransmitFunction>( |
| 222 CreateList(CreateParams("inaudible"), CreateToken("1234")))); | 225 CreateList(CreateParams("inaudible"), CreateToken("1234")))); |
| 223 EXPECT_TRUE(GetModem()->IsPlaying(INAUDIBLE)); | 226 EXPECT_TRUE(GetModem()->IsPlaying(INAUDIBLE)); |
| 224 | 227 |
| 225 // Can't cancel audible transmit - we haven't started it yet. | 228 // Can't cancel audible transmit - we haven't started it yet. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 255 | 258 |
| 256 // Send some audible tokens. | 259 // Send some audible tokens. |
| 257 std::vector<AudioToken> tokens; | 260 std::vector<AudioToken> tokens; |
| 258 tokens.push_back(AudioToken("1234", true)); | 261 tokens.push_back(AudioToken("1234", true)); |
| 259 tokens.push_back(AudioToken("ABCD", true)); | 262 tokens.push_back(AudioToken("ABCD", true)); |
| 260 tokens.push_back(AudioToken("abcd", false)); | 263 tokens.push_back(AudioToken("abcd", false)); |
| 261 GetModem()->DeliverTokens(tokens); | 264 GetModem()->DeliverTokens(tokens); |
| 262 | 265 |
| 263 // Check the tokens received. | 266 // Check the tokens received. |
| 264 EXPECT_EQ(1u, GetEvents().size()); | 267 EXPECT_EQ(1u, GetEvents().size()); |
| 265 scoped_ptr<ListValue> expected_tokens(new ListValue); | 268 std::unique_ptr<ListValue> expected_tokens(new ListValue); |
| 266 expected_tokens->Append(CreateReceivedToken("1234", "audible")); | 269 expected_tokens->Append(CreateReceivedToken("1234", "audible")); |
| 267 expected_tokens->Append(CreateReceivedToken("ABCD", "audible")); | 270 expected_tokens->Append(CreateReceivedToken("ABCD", "audible")); |
| 268 ListValue* received_tokens; | 271 ListValue* received_tokens; |
| 269 GetEvents()[0]->event_args->GetList(0, &received_tokens); | 272 GetEvents()[0]->event_args->GetList(0, &received_tokens); |
| 270 EXPECT_TRUE(received_tokens->Equals(expected_tokens.get())); | 273 EXPECT_TRUE(received_tokens->Equals(expected_tokens.get())); |
| 271 | 274 |
| 272 // Start listening for inaudible tokens. | 275 // Start listening for inaudible tokens. |
| 273 EXPECT_EQ("success", RunFunction<AudioModemReceiveFunction>( | 276 EXPECT_EQ("success", RunFunction<AudioModemReceiveFunction>( |
| 274 CreateList(CreateParams("inaudible")))); | 277 CreateList(CreateParams("inaudible")))); |
| 275 EXPECT_TRUE(GetModem()->IsRecording(INAUDIBLE)); | 278 EXPECT_TRUE(GetModem()->IsRecording(INAUDIBLE)); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 EXPECT_EQ("success", RunFunction<AudioModemReceiveFunction>( | 347 EXPECT_EQ("success", RunFunction<AudioModemReceiveFunction>( |
| 345 CreateList(CreateParams("inaudible")), GetExtension("ext2"))); | 348 CreateList(CreateParams("inaudible")), GetExtension("ext2"))); |
| 346 | 349 |
| 347 // Receive a token. | 350 // Receive a token. |
| 348 GetModem()->DeliverTokens(std::vector<AudioToken>( | 351 GetModem()->DeliverTokens(std::vector<AudioToken>( |
| 349 1, AudioToken("abcd", false))); | 352 1, AudioToken("abcd", false))); |
| 350 EXPECT_EQ(1u, GetEventsForExtension("ext1").size()); | 353 EXPECT_EQ(1u, GetEventsForExtension("ext1").size()); |
| 351 EXPECT_EQ(1u, GetEventsForExtension("ext2").size()); | 354 EXPECT_EQ(1u, GetEventsForExtension("ext2").size()); |
| 352 | 355 |
| 353 // Check the token received. | 356 // Check the token received. |
| 354 scoped_ptr<DictionaryValue> expected_token( | 357 std::unique_ptr<DictionaryValue> expected_token( |
| 355 CreateReceivedToken("abcd", "inaudible")); | 358 CreateReceivedToken("abcd", "inaudible")); |
| 356 EXPECT_TRUE(ReceivedSingleToken(GetEventsForExtension("ext1")[0].get(), | 359 EXPECT_TRUE(ReceivedSingleToken(GetEventsForExtension("ext1")[0].get(), |
| 357 expected_token.get())); | 360 expected_token.get())); |
| 358 EXPECT_TRUE(ReceivedSingleToken(GetEventsForExtension("ext2")[0].get(), | 361 EXPECT_TRUE(ReceivedSingleToken(GetEventsForExtension("ext2")[0].get(), |
| 359 expected_token.get())); | 362 expected_token.get())); |
| 360 | 363 |
| 361 // If one extension stops, the modem is still receiving for the other. | 364 // If one extension stops, the modem is still receiving for the other. |
| 362 EXPECT_EQ("success", RunFunction<AudioModemStopReceiveFunction>( | 365 EXPECT_EQ("success", RunFunction<AudioModemStopReceiveFunction>( |
| 363 CreateList(new StringValue("inaudible")), GetExtension("ext1"))); | 366 CreateList(new StringValue("inaudible")), GetExtension("ext1"))); |
| 364 EXPECT_TRUE(GetModem()->IsRecording(INAUDIBLE)); | 367 EXPECT_TRUE(GetModem()->IsRecording(INAUDIBLE)); |
| 365 | 368 |
| 366 // Receive another token. Should only go to ext2. | 369 // Receive another token. Should only go to ext2. |
| 367 GetModem()->DeliverTokens(std::vector<AudioToken>( | 370 GetModem()->DeliverTokens(std::vector<AudioToken>( |
| 368 1, AudioToken("1234", false))); | 371 1, AudioToken("1234", false))); |
| 369 EXPECT_EQ(1u, GetEventsForExtension("ext1").size()); | 372 EXPECT_EQ(1u, GetEventsForExtension("ext1").size()); |
| 370 EXPECT_EQ(2u, GetEventsForExtension("ext2").size()); | 373 EXPECT_EQ(2u, GetEventsForExtension("ext2").size()); |
| 371 expected_token.reset(CreateReceivedToken("1234", "inaudible")); | 374 expected_token.reset(CreateReceivedToken("1234", "inaudible")); |
| 372 EXPECT_TRUE(ReceivedSingleToken(GetEventsForExtension("ext2")[1].get(), | 375 EXPECT_TRUE(ReceivedSingleToken(GetEventsForExtension("ext2")[1].get(), |
| 373 expected_token.get())); | 376 expected_token.get())); |
| 374 | 377 |
| 375 EXPECT_EQ("success", RunFunction<AudioModemStopReceiveFunction>( | 378 EXPECT_EQ("success", RunFunction<AudioModemStopReceiveFunction>( |
| 376 CreateList(new StringValue("inaudible")), GetExtension("ext2"))); | 379 CreateList(new StringValue("inaudible")), GetExtension("ext2"))); |
| 377 EXPECT_FALSE(GetModem()->IsRecording(INAUDIBLE)); | 380 EXPECT_FALSE(GetModem()->IsRecording(INAUDIBLE)); |
| 378 } | 381 } |
| 379 | 382 |
| 380 } // namespace extensions | 383 } // namespace extensions |
| OLD | NEW |