[Cleanup] Used scoped pointers in KeyedServiceFactory's SetTestingFactory functions.
[chromium-blink-merge.git] / chrome / browser / search / hotword_service_unittest.cc
blob9d53410d4cfbd88bdd56dd4b9d934da979637274
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 "base/command_line.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/metrics/field_trial.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/test/test_simple_task_runner.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/extensions/extension_service_test_base.h"
12 #include "chrome/browser/extensions/test_extension_service.h"
13 #include "chrome/browser/search/hotword_audio_history_handler.h"
14 #include "chrome/browser/search/hotword_service.h"
15 #include "chrome/browser/search/hotword_service_factory.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/common/extensions/extension_constants.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "components/history/core/browser/web_history_service.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22 #include "extensions/browser/extension_system.h"
23 #include "extensions/common/extension.h"
24 #include "extensions/common/extension_builder.h"
25 #include "extensions/common/manifest.h"
26 #include "extensions/common/one_shot_event.h"
27 #include "testing/gtest/include/gtest/gtest.h"
29 #if defined(OS_CHROMEOS)
30 #include "chromeos/audio/cras_audio_handler.h"
31 #endif
33 namespace {
35 class MockAudioHistoryHandler : public HotwordAudioHistoryHandler {
36 public:
37 MockAudioHistoryHandler(
38 content::BrowserContext* context,
39 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
40 history::WebHistoryService* web_history)
41 : HotwordAudioHistoryHandler(context, task_runner),
42 get_audio_history_calls_(0),
43 web_history_(web_history) {
45 ~MockAudioHistoryHandler() override {}
47 void GetAudioHistoryEnabled(
48 const HotwordAudioHistoryCallback& callback) override {
49 get_audio_history_calls_++;
50 callback.Run(true, true);
53 history::WebHistoryService* GetWebHistory() override {
54 return web_history_.get();
57 int GetAudioHistoryCalls() {
58 return get_audio_history_calls_;
61 private:
62 int get_audio_history_calls_;
63 scoped_ptr<history::WebHistoryService> web_history_;
66 class MockHotwordService : public HotwordService {
67 public:
68 explicit MockHotwordService(Profile* profile)
69 : HotwordService(profile),
70 uninstall_count_(0) {
73 bool UninstallHotwordExtension(ExtensionService* extension_service) override {
74 uninstall_count_++;
75 return HotwordService::UninstallHotwordExtension(extension_service);
78 void InstallHotwordExtensionFromWebstore(int num_tries) override {
79 scoped_ptr<base::DictionaryValue> manifest =
80 extensions::DictionaryBuilder()
81 .Set("name", "Hotword Test Extension")
82 .Set("version", "1.0")
83 .Set("manifest_version", 2)
84 .Build();
85 scoped_refptr<extensions::Extension> extension =
86 extensions::ExtensionBuilder().SetManifest(manifest.Pass())
87 .AddFlags(extensions::Extension::FROM_WEBSTORE
88 | extensions::Extension::WAS_INSTALLED_BY_DEFAULT)
89 .SetID(extension_id_)
90 .SetLocation(extensions::Manifest::EXTERNAL_COMPONENT)
91 .Build();
92 ASSERT_TRUE(extension.get());
93 service_->OnExtensionInstalled(extension.get(), syncer::StringOrdinal());
97 int uninstall_count() { return uninstall_count_; }
99 void SetExtensionService(ExtensionService* service) { service_ = service; }
100 void SetExtensionId(const std::string& extension_id) {
101 extension_id_ = extension_id;
104 ExtensionService* extension_service() { return service_; }
106 private:
107 ExtensionService* service_;
108 int uninstall_count_;
109 std::string extension_id_;
112 scoped_ptr<KeyedService> BuildMockHotwordService(
113 content::BrowserContext* context) {
114 return make_scoped_ptr(
115 new MockHotwordService(static_cast<Profile*>(context)));
118 } // namespace
120 class HotwordServiceTest :
121 public extensions::ExtensionServiceTestBase,
122 public ::testing::WithParamInterface<const char*> {
123 protected:
124 HotwordServiceTest() {}
125 virtual ~HotwordServiceTest() {}
127 void SetApplicationLocale(Profile* profile, const std::string& new_locale) {
128 #if defined(OS_CHROMEOS)
129 // On ChromeOS locale is per-profile.
130 profile->GetPrefs()->SetString(prefs::kApplicationLocale, new_locale);
131 #else
132 g_browser_process->SetApplicationLocale(new_locale);
133 #endif
136 void SetUp() override {
137 extension_id_ = GetParam();
138 #if defined(OS_CHROMEOS)
139 // Tests on chromeos need to have the handler initialized.
140 chromeos::CrasAudioHandler::InitializeForTesting();
141 #endif
143 extensions::ExtensionServiceTestBase::SetUp();
146 void TearDown() override {
147 #if defined(OS_CHROMEOS)
148 DCHECK(chromeos::CrasAudioHandler::IsInitialized());
149 chromeos::CrasAudioHandler::Shutdown();
150 #endif
153 std::string extension_id_;
156 INSTANTIATE_TEST_CASE_P(HotwordServiceTests,
157 HotwordServiceTest,
158 ::testing::Values(
159 extension_misc::kHotwordSharedModuleId));
161 TEST_P(HotwordServiceTest, IsHotwordAllowedLocale) {
162 #if defined(ENABLE_HOTWORDING)
163 TestingProfile::Builder profile_builder;
164 scoped_ptr<TestingProfile> profile = profile_builder.Build();
166 // Check that the service exists so that a NULL service be ruled out in
167 // following tests.
168 HotwordService* hotword_service =
169 HotwordServiceFactory::GetForProfile(profile.get());
170 EXPECT_TRUE(hotword_service != NULL);
172 // Set the language to an invalid one.
173 SetApplicationLocale(static_cast<Profile*>(profile.get()), "non-valid");
174 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
176 // Now with valid locales it should be fine.
177 SetApplicationLocale(static_cast<Profile*>(profile.get()), "en");
178 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
179 SetApplicationLocale(static_cast<Profile*>(profile.get()), "en-US");
180 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
181 SetApplicationLocale(static_cast<Profile*>(profile.get()), "en_us");
182 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
183 SetApplicationLocale(static_cast<Profile*>(profile.get()), "de_DE");
184 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
185 SetApplicationLocale(static_cast<Profile*>(profile.get()), "fr_fr");
186 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
188 // Test that incognito even with a valid locale and valid field trial
189 // still returns false.
190 Profile* otr_profile = profile->GetOffTheRecordProfile();
191 SetApplicationLocale(otr_profile, "en");
192 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(otr_profile));
193 #endif // defined(ENABLE_HOTWORDING)
196 TEST_P(HotwordServiceTest, ShouldReinstallExtension) {
197 InitializeEmptyExtensionService();
199 HotwordServiceFactory* hotword_service_factory =
200 HotwordServiceFactory::GetInstance();
202 MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
203 hotword_service_factory->SetTestingFactoryAndUse(
204 profile(), BuildMockHotwordService));
205 ASSERT_TRUE(hotword_service != NULL);
206 hotword_service->SetExtensionId(extension_id_);
208 // If no locale has been set, no reason to uninstall.
209 EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
211 SetApplicationLocale(profile(), "en");
212 hotword_service->SetPreviousLanguagePref();
214 // Now a locale is set, but it hasn't changed.
215 EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
217 SetApplicationLocale(profile(), "fr_fr");
219 // Now it's a different locale so it should uninstall.
220 EXPECT_TRUE(hotword_service->ShouldReinstallHotwordExtension());
223 TEST_P(HotwordServiceTest, PreviousLanguageSetOnInstall) {
224 InitializeEmptyExtensionService();
225 service_->Init();
227 HotwordServiceFactory* hotword_service_factory =
228 HotwordServiceFactory::GetInstance();
230 MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
231 hotword_service_factory->SetTestingFactoryAndUse(
232 profile(), BuildMockHotwordService));
233 ASSERT_TRUE(hotword_service != NULL);
234 hotword_service->SetExtensionService(service());
235 hotword_service->SetExtensionId(extension_id_);
237 // If no locale has been set, no reason to uninstall.
238 EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
240 SetApplicationLocale(profile(), "test_locale");
242 hotword_service->InstallHotwordExtensionFromWebstore(1);
243 base::MessageLoop::current()->RunUntilIdle();
245 EXPECT_EQ("test_locale",
246 profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
249 TEST_P(HotwordServiceTest, UninstallReinstallTriggeredCorrectly) {
250 #if defined(ENABLE_HOTWORDING)
251 InitializeEmptyExtensionService();
252 service_->Init();
254 HotwordServiceFactory* hotword_service_factory =
255 HotwordServiceFactory::GetInstance();
257 MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
258 hotword_service_factory->SetTestingFactoryAndUse(
259 profile(), BuildMockHotwordService));
260 ASSERT_TRUE(hotword_service != NULL);
261 hotword_service->SetExtensionService(service());
262 hotword_service->SetExtensionId(extension_id_);
264 // Initialize the locale to "en".
265 SetApplicationLocale(profile(), "en");
267 // The previous locale should not be set. No reason to uninstall.
268 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
270 // Do an initial installation.
271 hotword_service->InstallHotwordExtensionFromWebstore(1);
272 base::MessageLoop::current()->RunUntilIdle();
273 EXPECT_EQ("en",
274 profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
276 if (extension_id_ == extension_misc::kHotwordSharedModuleId) {
277 // Shared module is installed and enabled.
278 EXPECT_EQ(0U, registry()->disabled_extensions().size());
279 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_id_));
280 } else {
281 // Verify the extension is installed but disabled.
282 EXPECT_EQ(1U, registry()->disabled_extensions().size());
283 EXPECT_TRUE(registry()->disabled_extensions().Contains(extension_id_));
286 // The previous locale should be set but should match the current
287 // locale. No reason to uninstall.
288 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
290 // Switch the locale to a valid but different one.
291 SetApplicationLocale(profile(), "fr_fr");
292 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
294 // Different but valid locale so expect uninstall.
295 EXPECT_TRUE(hotword_service->MaybeReinstallHotwordExtension());
296 EXPECT_EQ(1, hotword_service->uninstall_count());
297 EXPECT_EQ("fr_fr",
298 profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
300 if (extension_id_ == extension_misc::kHotwordSharedModuleId) {
301 // Shared module is installed and enabled.
302 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_id_));
303 } else {
304 // Verify the extension is installed. It's still disabled.
305 EXPECT_TRUE(registry()->disabled_extensions().Contains(extension_id_));
308 // Switch the locale to an invalid one.
309 SetApplicationLocale(profile(), "invalid");
310 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile()));
311 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
312 EXPECT_EQ("fr_fr",
313 profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
315 // If the locale is set back to the last valid one, then an uninstall-install
316 // shouldn't be needed.
317 SetApplicationLocale(profile(), "fr_fr");
318 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
319 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
320 EXPECT_EQ(1, hotword_service->uninstall_count()); // no change
321 #endif // defined(ENABLE_HOTWORDING)
324 TEST_P(HotwordServiceTest, DisableAlwaysOnOnLanguageChange) {
325 // Bypass test for old hotwording.
326 if (extension_id_ != extension_misc::kHotwordSharedModuleId)
327 return;
329 // Turn on Always On
330 base::CommandLine::ForCurrentProcess()->AppendSwitch(
331 switches::kEnableExperimentalHotwordHardware);
333 InitializeEmptyExtensionService();
334 service_->Init();
336 // Enable always-on.
337 profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, true);
339 HotwordServiceFactory* hotword_service_factory =
340 HotwordServiceFactory::GetInstance();
342 MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
343 hotword_service_factory->SetTestingFactoryAndUse(
344 profile(), BuildMockHotwordService));
345 ASSERT_TRUE(hotword_service != NULL);
346 hotword_service->SetExtensionService(service());
347 hotword_service->SetExtensionId(extension_id_);
349 // Initialize the locale to "en_us".
350 SetApplicationLocale(profile(), "en_us");
352 // The previous locale should not be set. No reason to uninstall.
353 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
354 EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
356 // Do an initial installation.
357 hotword_service->InstallHotwordExtensionFromWebstore(1);
358 base::MessageLoop::current()->RunUntilIdle();
360 // The previous locale should be set but should match the current
361 // locale. No reason to uninstall.
362 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
363 EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
365 // TODO(kcarattini): Uncomment this sectione once we launch always-on
366 // in more languages.
367 // // Switch the locale to a valid but different one.
368 // SetApplicationLocale(profile(), "fr_fr");
369 // EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
371 // // Different but valid locale so expect uninstall.
372 // EXPECT_TRUE(hotword_service->MaybeReinstallHotwordExtension());
373 // EXPECT_FALSE(hotword_service->IsAlwaysOnEnabled());
375 // Re-enable always-on.
376 profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, true);
378 // Switch the locale to an invalid one.
379 SetApplicationLocale(profile(), "invalid");
380 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile()));
381 EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
382 EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
384 // TODO(kcarattini): Uncomment this sectione once we launch always-on
385 // in more languages.
386 // // If the locale is set back to the last valid one, then an
387 // // uninstall-install shouldn't be needed.
388 // SetApplicationLocale(profile(), "fr_fr");
389 // EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
390 // EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
391 // EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
394 TEST_P(HotwordServiceTest, IsAlwaysOnEnabled) {
395 // Bypass test for old hotwording.
396 if (extension_id_ != extension_misc::kHotwordSharedModuleId)
397 return;
399 InitializeEmptyExtensionService();
400 service_->Init();
401 HotwordServiceFactory* hotword_service_factory =
402 HotwordServiceFactory::GetInstance();
404 MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
405 hotword_service_factory->SetTestingFactoryAndUse(
406 profile(), BuildMockHotwordService));
407 ASSERT_TRUE(hotword_service != NULL);
408 hotword_service->SetExtensionService(service());
409 hotword_service->SetExtensionId(extension_id_);
411 // No hardware available. Should never be true.
412 EXPECT_FALSE(hotword_service->IsAlwaysOnEnabled());
414 // Enable always-on, still not available.
415 profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, true);
416 EXPECT_FALSE(hotword_service->IsAlwaysOnEnabled());
418 // Enable regular hotwording, still not available.
419 profile()->GetPrefs()->SetBoolean(prefs::kHotwordSearchEnabled, true);
420 EXPECT_FALSE(hotword_service->IsAlwaysOnEnabled());
422 // Bypass hardware check.
423 base::CommandLine::ForCurrentProcess()->AppendSwitch(
424 switches::kEnableExperimentalHotwordHardware);
425 EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
427 // Disable.
428 profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled,
429 false);
430 EXPECT_FALSE(hotword_service->IsAlwaysOnEnabled());
433 TEST_P(HotwordServiceTest, IsSometimesOnEnabled) {
434 InitializeEmptyExtensionService();
435 service_->Init();
436 HotwordServiceFactory* hotword_service_factory =
437 HotwordServiceFactory::GetInstance();
439 MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
440 hotword_service_factory->SetTestingFactoryAndUse(
441 profile(), BuildMockHotwordService));
442 ASSERT_TRUE(hotword_service != NULL);
443 hotword_service->SetExtensionService(service());
444 hotword_service->SetExtensionId(extension_id_);
446 // No pref set.
447 EXPECT_FALSE(hotword_service->IsSometimesOnEnabled());
449 // Set pref.
450 profile()->GetPrefs()->SetBoolean(prefs::kHotwordSearchEnabled, true);
451 EXPECT_TRUE(hotword_service->IsSometimesOnEnabled());
453 // Turn on always-on pref. Should have no effect.
454 profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, true);
455 EXPECT_TRUE(hotword_service->IsSometimesOnEnabled());
457 // Disable.
458 profile()->GetPrefs()->SetBoolean(prefs::kHotwordSearchEnabled, false);
459 EXPECT_FALSE(hotword_service->IsSometimesOnEnabled());
461 // Bypass rest of test for old hotwording.
462 if (extension_id_ != extension_misc::kHotwordSharedModuleId)
463 return;
465 // Bypass hardware check.
466 base::CommandLine::ForCurrentProcess()->AppendSwitch(
467 switches::kEnableExperimentalHotwordHardware);
469 // With hardware, only always-on is allowed.
470 EXPECT_FALSE(hotword_service->IsSometimesOnEnabled());
472 // Set pref.
473 profile()->GetPrefs()->SetBoolean(prefs::kHotwordSearchEnabled, true);
474 EXPECT_FALSE(hotword_service->IsSometimesOnEnabled());
476 // Disable always-on.
477 profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled,
478 false);
479 EXPECT_FALSE(hotword_service->IsSometimesOnEnabled());
482 TEST_P(HotwordServiceTest, AudioHistorySyncOccurs) {
483 InitializeEmptyExtensionService();
484 service_->Init();
486 HotwordServiceFactory* hotword_service_factory =
487 HotwordServiceFactory::GetInstance();
489 MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
490 hotword_service_factory->SetTestingFactoryAndUse(
491 profile(), BuildMockHotwordService));
492 ASSERT_TRUE(hotword_service != NULL);
493 hotword_service->SetExtensionService(service());
494 hotword_service->SetExtensionId(extension_id_);
496 scoped_refptr<base::TestSimpleTaskRunner> test_task_runner(
497 new base::TestSimpleTaskRunner());
498 MockAudioHistoryHandler* audio_history_handler =
499 new MockAudioHistoryHandler(profile(), test_task_runner, nullptr);
500 hotword_service->SetAudioHistoryHandler(audio_history_handler);
501 EXPECT_EQ(1, audio_history_handler->GetAudioHistoryCalls());
502 // We expect the next check for audio history to be in the queue.
503 EXPECT_EQ(base::TimeDelta::FromDays(1),
504 test_task_runner->NextPendingTaskDelay());
505 EXPECT_TRUE(test_task_runner->HasPendingTask());
506 test_task_runner->RunPendingTasks();
507 EXPECT_EQ(2, audio_history_handler->GetAudioHistoryCalls());
508 EXPECT_TRUE(test_task_runner->HasPendingTask());
509 test_task_runner->ClearPendingTasks();