blob: 956283c2402dbd629fb84c53b1296af7e3a0771e [file] [log] [blame]
// 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
}