Home | History | Annotate | Download | only in search
      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.
      4 
      5 #include "base/memory/scoped_ptr.h"
      6 #include "base/metrics/field_trial.h"
      7 #include "base/prefs/pref_service.h"
      8 #include "chrome/browser/browser_process.h"
      9 #include "chrome/browser/extensions/extension_service_test_base.h"
     10 #include "chrome/browser/extensions/test_extension_service.h"
     11 #include "chrome/browser/search/hotword_service.h"
     12 #include "chrome/browser/search/hotword_service_factory.h"
     13 #include "chrome/common/extensions/extension_constants.h"
     14 #include "chrome/common/pref_names.h"
     15 #include "chrome/test/base/testing_profile.h"
     16 #include "content/public/test/test_browser_thread_bundle.h"
     17 #include "extensions/browser/extension_system.h"
     18 #include "extensions/common/extension.h"
     19 #include "extensions/common/extension_builder.h"
     20 #include "extensions/common/manifest.h"
     21 #include "extensions/common/one_shot_event.h"
     22 #include "testing/gtest/include/gtest/gtest.h"
     23 
     24 namespace {
     25 
     26 class MockHotwordService : public HotwordService {
     27  public:
     28   explicit MockHotwordService(Profile* profile)
     29       : HotwordService(profile),
     30         uninstall_count_(0) {
     31   }
     32 
     33   virtual bool UninstallHotwordExtension(
     34       ExtensionService* extension_service) OVERRIDE {
     35     uninstall_count_++;
     36     return HotwordService::UninstallHotwordExtension(extension_service);
     37   }
     38 
     39   virtual void InstallHotwordExtensionFromWebstore() OVERRIDE{
     40     scoped_ptr<base::DictionaryValue> manifest =
     41         extensions::DictionaryBuilder()
     42         .Set("name", "Hotword Test Extension")
     43         .Set("version", "1.0")
     44         .Set("manifest_version", 2)
     45         .Build();
     46     scoped_refptr<extensions::Extension> extension =
     47         extensions::ExtensionBuilder().SetManifest(manifest.Pass())
     48         .AddFlags(extensions::Extension::FROM_WEBSTORE
     49                   | extensions::Extension::WAS_INSTALLED_BY_DEFAULT)
     50         .SetID(extension_misc::kHotwordExtensionId)
     51         .SetLocation(extensions::Manifest::EXTERNAL_COMPONENT)
     52         .Build();
     53     ASSERT_TRUE(extension.get());
     54     service_->OnExtensionInstalled(extension, syncer::StringOrdinal());
     55   }
     56 
     57 
     58   int uninstall_count() { return uninstall_count_; }
     59 
     60   void SetExtensionService(ExtensionService* service) { service_ = service; }
     61 
     62   ExtensionService* extension_service() { return service_; }
     63 
     64  private:
     65   ExtensionService* service_;
     66   int uninstall_count_;
     67 };
     68 
     69 KeyedService* BuildMockHotwordService(content::BrowserContext* context) {
     70   return new MockHotwordService(static_cast<Profile*>(context));
     71 }
     72 
     73 }  // namespace
     74 
     75 class HotwordServiceTest : public extensions::ExtensionServiceTestBase {
     76  protected:
     77   HotwordServiceTest() : field_trial_list_(NULL) {}
     78   virtual ~HotwordServiceTest() {}
     79 
     80   void SetApplicationLocale(Profile* profile, const std::string& new_locale) {
     81 #if defined(OS_CHROMEOS)
     82         // On ChromeOS locale is per-profile.
     83     profile->GetPrefs()->SetString(prefs::kApplicationLocale, new_locale);
     84 #else
     85     g_browser_process->SetApplicationLocale(new_locale);
     86 #endif
     87   }
     88 
     89  private:
     90   base::FieldTrialList field_trial_list_;
     91 };
     92 
     93 TEST_F(HotwordServiceTest, IsHotwordAllowedBadFieldTrial) {
     94   TestingProfile::Builder profile_builder;
     95   TestingProfile::Builder otr_profile_builder;
     96   otr_profile_builder.SetIncognito();
     97   scoped_ptr<TestingProfile> profile = profile_builder.Build();
     98   scoped_ptr<TestingProfile> otr_profile = otr_profile_builder.Build();
     99 
    100   HotwordServiceFactory* hotword_service_factory =
    101       HotwordServiceFactory::GetInstance();
    102 
    103   // Check that the service exists so that a NULL service be ruled out in
    104   // following tests.
    105   HotwordService* hotword_service =
    106       hotword_service_factory->GetForProfile(profile.get());
    107   EXPECT_TRUE(hotword_service != NULL);
    108 
    109   // When the field trial is empty or Disabled, it should not be allowed.
    110   std::string group = base::FieldTrialList::FindFullName(
    111       hotword_internal::kHotwordFieldTrialName);
    112   EXPECT_TRUE(group.empty());
    113   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    114 
    115   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
    116      hotword_internal::kHotwordFieldTrialName,
    117      hotword_internal::kHotwordFieldTrialDisabledGroupName));
    118   group = base::FieldTrialList::FindFullName(
    119       hotword_internal::kHotwordFieldTrialName);
    120   EXPECT_TRUE(group ==hotword_internal::kHotwordFieldTrialDisabledGroupName);
    121   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    122 
    123   // Set a valid locale with invalid field trial to be sure it is
    124   // still false.
    125   SetApplicationLocale(static_cast<Profile*>(profile.get()), "en");
    126   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    127 
    128   // Test that incognito returns false as well.
    129   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(otr_profile.get()));
    130 }
    131 
    132 TEST_F(HotwordServiceTest, IsHotwordAllowedLocale) {
    133   TestingProfile::Builder profile_builder;
    134   TestingProfile::Builder otr_profile_builder;
    135   otr_profile_builder.SetIncognito();
    136   scoped_ptr<TestingProfile> profile = profile_builder.Build();
    137   scoped_ptr<TestingProfile> otr_profile = otr_profile_builder.Build();
    138 
    139   HotwordServiceFactory* hotword_service_factory =
    140       HotwordServiceFactory::GetInstance();
    141 
    142   // Check that the service exists so that a NULL service be ruled out in
    143   // following tests.
    144   HotwordService* hotword_service =
    145       hotword_service_factory->GetForProfile(profile.get());
    146   EXPECT_TRUE(hotword_service != NULL);
    147 
    148   // Set the field trial to a valid one.
    149   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
    150       hotword_internal::kHotwordFieldTrialName, "Good"));
    151 
    152   // Set the language to an invalid one.
    153   SetApplicationLocale(static_cast<Profile*>(profile.get()), "non-valid");
    154   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    155 
    156   // Now with valid locales it should be fine.
    157   SetApplicationLocale(static_cast<Profile*>(profile.get()), "en");
    158   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    159   SetApplicationLocale(static_cast<Profile*>(profile.get()), "en-US");
    160   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    161   SetApplicationLocale(static_cast<Profile*>(profile.get()), "en_us");
    162   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    163   SetApplicationLocale(static_cast<Profile*>(profile.get()), "de_DE");
    164   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    165   SetApplicationLocale(static_cast<Profile*>(profile.get()), "fr_fr");
    166   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    167 
    168   // Test that incognito even with a valid locale and valid field trial
    169   // still returns false.
    170   SetApplicationLocale(static_cast<Profile*>(otr_profile.get()), "en");
    171   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(otr_profile.get()));
    172 }
    173 
    174 TEST_F(HotwordServiceTest, AudioLoggingPrefSetCorrectly) {
    175   TestingProfile::Builder profile_builder;
    176   scoped_ptr<TestingProfile> profile = profile_builder.Build();
    177 
    178   HotwordServiceFactory* hotword_service_factory =
    179       HotwordServiceFactory::GetInstance();
    180   HotwordService* hotword_service =
    181       hotword_service_factory->GetForProfile(profile.get());
    182   EXPECT_TRUE(hotword_service != NULL);
    183 
    184   // If it's a fresh profile, although the default value is true,
    185   // it should return false if the preference has never been set.
    186   EXPECT_FALSE(hotword_service->IsOptedIntoAudioLogging());
    187 }
    188 
    189 TEST_F(HotwordServiceTest, ShouldReinstallExtension) {
    190   // Set the field trial to a valid one.
    191   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
    192       hotword_internal::kHotwordFieldTrialName, "Install"));
    193 
    194   InitializeEmptyExtensionService();
    195 
    196   HotwordServiceFactory* hotword_service_factory =
    197       HotwordServiceFactory::GetInstance();
    198 
    199   MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
    200       hotword_service_factory->SetTestingFactoryAndUse(
    201           profile(), BuildMockHotwordService));
    202   EXPECT_TRUE(hotword_service != NULL);
    203 
    204   // If no locale has been set, no reason to uninstall.
    205   EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
    206 
    207   SetApplicationLocale(profile(), "en");
    208   hotword_service->SetPreviousLanguagePref();
    209 
    210   // Now a locale is set, but it hasn't changed.
    211   EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
    212 
    213   SetApplicationLocale(profile(), "fr_fr");
    214 
    215   // Now it's a different locale so it should uninstall.
    216   EXPECT_TRUE(hotword_service->ShouldReinstallHotwordExtension());
    217 }
    218 
    219 TEST_F(HotwordServiceTest, PreviousLanguageSetOnInstall) {
    220   // Set the field trial to a valid one.
    221   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
    222       hotword_internal::kHotwordFieldTrialName, "Install"));
    223 
    224   InitializeEmptyExtensionService();
    225   service_->Init();
    226 
    227   HotwordServiceFactory* hotword_service_factory =
    228       HotwordServiceFactory::GetInstance();
    229 
    230   MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
    231       hotword_service_factory->SetTestingFactoryAndUse(
    232           profile(), BuildMockHotwordService));
    233   EXPECT_TRUE(hotword_service != NULL);
    234   hotword_service->SetExtensionService(service());
    235 
    236   // If no locale has been set, no reason to uninstall.
    237   EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
    238 
    239   SetApplicationLocale(profile(), "test_locale");
    240 
    241   hotword_service->InstallHotwordExtensionFromWebstore();
    242   base::MessageLoop::current()->RunUntilIdle();
    243 
    244   EXPECT_EQ("test_locale",
    245             profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
    246 }
    247 
    248 TEST_F(HotwordServiceTest, UninstallReinstallTriggeredCorrectly) {
    249   // Set the field trial to a valid one.
    250   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
    251       hotword_internal::kHotwordFieldTrialName, "Install"));
    252 
    253   InitializeEmptyExtensionService();
    254   service_->Init();
    255 
    256   HotwordServiceFactory* hotword_service_factory =
    257       HotwordServiceFactory::GetInstance();
    258 
    259   MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
    260       hotword_service_factory->SetTestingFactoryAndUse(
    261           profile(), BuildMockHotwordService));
    262   EXPECT_TRUE(hotword_service != NULL);
    263   hotword_service->SetExtensionService(service());
    264 
    265   // Initialize the locale to "en".
    266   SetApplicationLocale(profile(), "en");
    267 
    268   // The previous locale should not be set. No reason to uninstall.
    269   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
    270 
    271    // Do an initial installation.
    272   hotword_service->InstallHotwordExtensionFromWebstore();
    273   base::MessageLoop::current()->RunUntilIdle();
    274   EXPECT_EQ("en",
    275             profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
    276 
    277   // Verify the extension is installed but disabled.
    278   EXPECT_EQ(1U, registry()->disabled_extensions().size());
    279   EXPECT_TRUE(registry()->disabled_extensions().Contains(
    280       extension_misc::kHotwordExtensionId));
    281 
    282    // The previous locale should be set but should match the current
    283   // locale. No reason to uninstall.
    284   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
    285 
    286   // Switch the locale to a valid but different one.
    287   SetApplicationLocale(profile(), "fr_fr");
    288   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
    289 
    290    // Different but valid locale so expect uninstall.
    291   EXPECT_TRUE(hotword_service->MaybeReinstallHotwordExtension());
    292   EXPECT_EQ(1, hotword_service->uninstall_count());
    293   EXPECT_EQ("fr_fr",
    294             profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
    295 
    296   // Verify the extension is installed. It's still disabled.
    297   EXPECT_TRUE(registry()->disabled_extensions().Contains(
    298       extension_misc::kHotwordExtensionId));
    299 
    300   // Switch the locale to an invalid one.
    301   SetApplicationLocale(profile(), "invalid");
    302   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile()));
    303   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
    304   EXPECT_EQ("fr_fr",
    305             profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
    306 
    307   // If the locale is set back to the last valid one, then an uninstall-install
    308   // shouldn't be needed.
    309   SetApplicationLocale(profile(), "fr_fr");
    310   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
    311   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
    312   EXPECT_EQ(1, hotword_service->uninstall_count());  // no change
    313 }
    314