| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/memory/scoped_ptr.h" |
| #include "base/metrics/field_trial.h" |
| #include "base/prefs/pref_service.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/extensions/extension_service_test_base.h" |
| #include "chrome/browser/extensions/test_extension_service.h" |
| #include "chrome/browser/search/hotword_service.h" |
| #include "chrome/browser/search/hotword_service_factory.h" |
| #include "chrome/common/extensions/extension_constants.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "content/public/test/test_browser_thread_bundle.h" |
| #include "extensions/browser/extension_system.h" |
| #include "extensions/common/extension.h" |
| #include "extensions/common/extension_builder.h" |
| #include "extensions/common/manifest.h" |
| #include "extensions/common/one_shot_event.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace { |
| |
| class MockHotwordService : public HotwordService { |
| public: |
| explicit MockHotwordService(Profile* profile) |
| : HotwordService(profile), |
| uninstall_count_(0) { |
| } |
| |
| virtual bool UninstallHotwordExtension( |
| ExtensionService* extension_service) OVERRIDE { |
| uninstall_count_++; |
| return HotwordService::UninstallHotwordExtension(extension_service); |
| } |
| |
| virtual void InstallHotwordExtensionFromWebstore() OVERRIDE{ |
| scoped_ptr<base::DictionaryValue> manifest = |
| extensions::DictionaryBuilder() |
| .Set("name", "Hotword Test Extension") |
| .Set("version", "1.0") |
| .Set("manifest_version", 2) |
| .Build(); |
| scoped_refptr<extensions::Extension> extension = |
| extensions::ExtensionBuilder().SetManifest(manifest.Pass()) |
| .AddFlags(extensions::Extension::FROM_WEBSTORE |
| | extensions::Extension::WAS_INSTALLED_BY_DEFAULT) |
| .SetID(extension_misc::kHotwordExtensionId) |
| .SetLocation(extensions::Manifest::EXTERNAL_COMPONENT) |
| .Build(); |
| ASSERT_TRUE(extension.get()); |
| service_->OnExtensionInstalled(extension, syncer::StringOrdinal()); |
| } |
| |
| |
| int uninstall_count() { return uninstall_count_; } |
| |
| void SetExtensionService(ExtensionService* service) { service_ = service; } |
| |
| ExtensionService* extension_service() { return service_; } |
| |
| private: |
| ExtensionService* service_; |
| int uninstall_count_; |
| }; |
| |
| KeyedService* BuildMockHotwordService(content::BrowserContext* context) { |
| return new MockHotwordService(static_cast<Profile*>(context)); |
| } |
| |
| } // namespace |
| |
| class HotwordServiceTest : public extensions::ExtensionServiceTestBase { |
| protected: |
| HotwordServiceTest() : field_trial_list_(NULL) {} |
| virtual ~HotwordServiceTest() {} |
| |
| void SetApplicationLocale(Profile* profile, const std::string& new_locale) { |
| #if defined(OS_CHROMEOS) |
| // On ChromeOS locale is per-profile. |
| profile->GetPrefs()->SetString(prefs::kApplicationLocale, new_locale); |
| #else |
| g_browser_process->SetApplicationLocale(new_locale); |
| #endif |
| } |
| |
| private: |
| base::FieldTrialList field_trial_list_; |
| }; |
| |
| TEST_F(HotwordServiceTest, IsHotwordAllowedBadFieldTrial) { |
| TestingProfile::Builder profile_builder; |
| TestingProfile::Builder otr_profile_builder; |
| otr_profile_builder.SetIncognito(); |
| scoped_ptr<TestingProfile> profile = profile_builder.Build(); |
| scoped_ptr<TestingProfile> otr_profile = otr_profile_builder.Build(); |
| |
| HotwordServiceFactory* hotword_service_factory = |
| HotwordServiceFactory::GetInstance(); |
| |
| // Check that the service exists so that a NULL service be ruled out in |
| // following tests. |
| HotwordService* hotword_service = |
| hotword_service_factory->GetForProfile(profile.get()); |
| EXPECT_TRUE(hotword_service != NULL); |
| |
| // When the field trial is empty or Disabled, it should not be allowed. |
| std::string group = base::FieldTrialList::FindFullName( |
| hotword_internal::kHotwordFieldTrialName); |
| EXPECT_TRUE(group.empty()); |
| EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get())); |
| |
| ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( |
| hotword_internal::kHotwordFieldTrialName, |
| hotword_internal::kHotwordFieldTrialDisabledGroupName)); |
| group = base::FieldTrialList::FindFullName( |
| hotword_internal::kHotwordFieldTrialName); |
| EXPECT_TRUE(group ==hotword_internal::kHotwordFieldTrialDisabledGroupName); |
| EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get())); |
| |
| // Set a valid locale with invalid field trial to be sure it is |
| // still false. |
| SetApplicationLocale(static_cast<Profile*>(profile.get()), "en"); |
| EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get())); |
| |
| // Test that incognito returns false as well. |
| EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(otr_profile.get())); |
| } |
| |
| TEST_F(HotwordServiceTest, IsHotwordAllowedLocale) { |
| TestingProfile::Builder profile_builder; |
| TestingProfile::Builder otr_profile_builder; |
| otr_profile_builder.SetIncognito(); |
| scoped_ptr<TestingProfile> profile = profile_builder.Build(); |
| scoped_ptr<TestingProfile> otr_profile = otr_profile_builder.Build(); |
| |
| HotwordServiceFactory* hotword_service_factory = |
| HotwordServiceFactory::GetInstance(); |
| |
| // Check that the service exists so that a NULL service be ruled out in |
| // following tests. |
| HotwordService* hotword_service = |
| hotword_service_factory->GetForProfile(profile.get()); |
| EXPECT_TRUE(hotword_service != NULL); |
| |
| // Set the field trial to a valid one. |
| ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( |
| hotword_internal::kHotwordFieldTrialName, "Good")); |
| |
| // Set the language to an invalid one. |
| SetApplicationLocale(static_cast<Profile*>(profile.get()), "non-valid"); |
| EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get())); |
| |
| // Now with valid locales it should be fine. |
| SetApplicationLocale(static_cast<Profile*>(profile.get()), "en"); |
| EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get())); |
| SetApplicationLocale(static_cast<Profile*>(profile.get()), "en-US"); |
| EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get())); |
| SetApplicationLocale(static_cast<Profile*>(profile.get()), "en_us"); |
| EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get())); |
| SetApplicationLocale(static_cast<Profile*>(profile.get()), "de_DE"); |
| EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get())); |
| SetApplicationLocale(static_cast<Profile*>(profile.get()), "fr_fr"); |
| EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get())); |
| |
| // Test that incognito even with a valid locale and valid field trial |
| // still returns false. |
| SetApplicationLocale(static_cast<Profile*>(otr_profile.get()), "en"); |
| EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(otr_profile.get())); |
| } |
| |
| TEST_F(HotwordServiceTest, AudioLoggingPrefSetCorrectly) { |
| TestingProfile::Builder profile_builder; |
| scoped_ptr<TestingProfile> profile = profile_builder.Build(); |
| |
| HotwordServiceFactory* hotword_service_factory = |
| HotwordServiceFactory::GetInstance(); |
| HotwordService* hotword_service = |
| hotword_service_factory->GetForProfile(profile.get()); |
| EXPECT_TRUE(hotword_service != NULL); |
| |
| // If it's a fresh profile, although the default value is true, |
| // it should return false if the preference has never been set. |
| EXPECT_FALSE(hotword_service->IsOptedIntoAudioLogging()); |
| } |
| |
| TEST_F(HotwordServiceTest, ShouldReinstallExtension) { |
| // Set the field trial to a valid one. |
| ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( |
| hotword_internal::kHotwordFieldTrialName, "Install")); |
| |
| InitializeEmptyExtensionService(); |
| |
| HotwordServiceFactory* hotword_service_factory = |
| HotwordServiceFactory::GetInstance(); |
| |
| MockHotwordService* hotword_service = static_cast<MockHotwordService*>( |
| hotword_service_factory->SetTestingFactoryAndUse( |
| profile(), BuildMockHotwordService)); |
| EXPECT_TRUE(hotword_service != NULL); |
| |
| // If no locale has been set, no reason to uninstall. |
| EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension()); |
| |
| SetApplicationLocale(profile(), "en"); |
| hotword_service->SetPreviousLanguagePref(); |
| |
| // Now a locale is set, but it hasn't changed. |
| EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension()); |
| |
| SetApplicationLocale(profile(), "fr_fr"); |
| |
| // Now it's a different locale so it should uninstall. |
| EXPECT_TRUE(hotword_service->ShouldReinstallHotwordExtension()); |
| } |
| |
| TEST_F(HotwordServiceTest, PreviousLanguageSetOnInstall) { |
| // Set the field trial to a valid one. |
| ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( |
| hotword_internal::kHotwordFieldTrialName, "Install")); |
| |
| InitializeEmptyExtensionService(); |
| service_->Init(); |
| |
| HotwordServiceFactory* hotword_service_factory = |
| HotwordServiceFactory::GetInstance(); |
| |
| MockHotwordService* hotword_service = static_cast<MockHotwordService*>( |
| hotword_service_factory->SetTestingFactoryAndUse( |
| profile(), BuildMockHotwordService)); |
| EXPECT_TRUE(hotword_service != NULL); |
| hotword_service->SetExtensionService(service()); |
| |
| // If no locale has been set, no reason to uninstall. |
| EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension()); |
| |
| SetApplicationLocale(profile(), "test_locale"); |
| |
| hotword_service->InstallHotwordExtensionFromWebstore(); |
| base::MessageLoop::current()->RunUntilIdle(); |
| |
| EXPECT_EQ("test_locale", |
| profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage)); |
| } |
| |
| TEST_F(HotwordServiceTest, UninstallReinstallTriggeredCorrectly) { |
| // Set the field trial to a valid one. |
| ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( |
| hotword_internal::kHotwordFieldTrialName, "Install")); |
| |
| InitializeEmptyExtensionService(); |
| service_->Init(); |
| |
| HotwordServiceFactory* hotword_service_factory = |
| HotwordServiceFactory::GetInstance(); |
| |
| MockHotwordService* hotword_service = static_cast<MockHotwordService*>( |
| hotword_service_factory->SetTestingFactoryAndUse( |
| profile(), BuildMockHotwordService)); |
| EXPECT_TRUE(hotword_service != NULL); |
| hotword_service->SetExtensionService(service()); |
| |
| // Initialize the locale to "en". |
| SetApplicationLocale(profile(), "en"); |
| |
| // The previous locale should not be set. No reason to uninstall. |
| EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension()); |
| |
| // Do an initial installation. |
| hotword_service->InstallHotwordExtensionFromWebstore(); |
| base::MessageLoop::current()->RunUntilIdle(); |
| EXPECT_EQ("en", |
| profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage)); |
| |
| // Verify the extension is installed but disabled. |
| EXPECT_EQ(1U, registry()->disabled_extensions().size()); |
| EXPECT_TRUE(registry()->disabled_extensions().Contains( |
| extension_misc::kHotwordExtensionId)); |
| |
| // The previous locale should be set but should match the current |
| // locale. No reason to uninstall. |
| EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension()); |
| |
| // Switch the locale to a valid but different one. |
| SetApplicationLocale(profile(), "fr_fr"); |
| EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile())); |
| |
| // Different but valid locale so expect uninstall. |
| EXPECT_TRUE(hotword_service->MaybeReinstallHotwordExtension()); |
| EXPECT_EQ(1, hotword_service->uninstall_count()); |
| EXPECT_EQ("fr_fr", |
| profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage)); |
| |
| // Verify the extension is installed. It's still disabled. |
| EXPECT_TRUE(registry()->disabled_extensions().Contains( |
| extension_misc::kHotwordExtensionId)); |
| |
| // Switch the locale to an invalid one. |
| SetApplicationLocale(profile(), "invalid"); |
| EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile())); |
| EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension()); |
| EXPECT_EQ("fr_fr", |
| profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage)); |
| |
| // If the locale is set back to the last valid one, then an uninstall-install |
| // shouldn't be needed. |
| SetApplicationLocale(profile(), "fr_fr"); |
| EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile())); |
| EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension()); |
| EXPECT_EQ(1, hotword_service->uninstall_count()); // no change |
| } |