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.get(), 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   scoped_ptr<TestingProfile> profile = profile_builder.Build();
     96 
     97   HotwordServiceFactory* hotword_service_factory =
     98       HotwordServiceFactory::GetInstance();
     99 
    100   // Check that the service exists so that a NULL service be ruled out in
    101   // following tests.
    102   HotwordService* hotword_service =
    103       hotword_service_factory->GetForProfile(profile.get());
    104   EXPECT_TRUE(hotword_service != NULL);
    105 
    106   // When the field trial is empty or Disabled, it should not be allowed.
    107   std::string group = base::FieldTrialList::FindFullName(
    108       hotword_internal::kHotwordFieldTrialName);
    109   EXPECT_TRUE(group.empty());
    110   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    111 
    112   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
    113      hotword_internal::kHotwordFieldTrialName,
    114      hotword_internal::kHotwordFieldTrialDisabledGroupName));
    115   group = base::FieldTrialList::FindFullName(
    116       hotword_internal::kHotwordFieldTrialName);
    117   EXPECT_TRUE(group ==hotword_internal::kHotwordFieldTrialDisabledGroupName);
    118   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    119 
    120   // Set a valid locale with invalid field trial to be sure it is
    121   // still false.
    122   SetApplicationLocale(static_cast<Profile*>(profile.get()), "en");
    123   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    124 
    125   // Test that incognito returns false as well.
    126   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(
    127       profile->GetOffTheRecordProfile()));
    128 }
    129 
    130 TEST_F(HotwordServiceTest, IsHotwordAllowedLocale) {
    131   TestingProfile::Builder profile_builder;
    132   scoped_ptr<TestingProfile> profile = profile_builder.Build();
    133 
    134   HotwordServiceFactory* hotword_service_factory =
    135       HotwordServiceFactory::GetInstance();
    136 
    137   // Check that the service exists so that a NULL service be ruled out in
    138   // following tests.
    139   HotwordService* hotword_service =
    140       hotword_service_factory->GetForProfile(profile.get());
    141   EXPECT_TRUE(hotword_service != NULL);
    142 
    143   // Set the field trial to a valid one.
    144   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
    145       hotword_internal::kHotwordFieldTrialName, "Good"));
    146 
    147   // Set the language to an invalid one.
    148   SetApplicationLocale(static_cast<Profile*>(profile.get()), "non-valid");
    149   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    150 
    151   // Now with valid locales it should be fine.
    152   SetApplicationLocale(static_cast<Profile*>(profile.get()), "en");
    153   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    154   SetApplicationLocale(static_cast<Profile*>(profile.get()), "en-US");
    155   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    156   SetApplicationLocale(static_cast<Profile*>(profile.get()), "en_us");
    157   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    158   SetApplicationLocale(static_cast<Profile*>(profile.get()), "de_DE");
    159   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    160   SetApplicationLocale(static_cast<Profile*>(profile.get()), "fr_fr");
    161   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
    162 
    163   // Test that incognito even with a valid locale and valid field trial
    164   // still returns false.
    165   Profile* otr_profile = profile->GetOffTheRecordProfile();
    166   SetApplicationLocale(otr_profile, "en");
    167   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(otr_profile));
    168 }
    169 
    170 TEST_F(HotwordServiceTest, AudioLoggingPrefSetCorrectly) {
    171   TestingProfile::Builder profile_builder;
    172   scoped_ptr<TestingProfile> profile = profile_builder.Build();
    173 
    174   HotwordServiceFactory* hotword_service_factory =
    175       HotwordServiceFactory::GetInstance();
    176   HotwordService* hotword_service =
    177       hotword_service_factory->GetForProfile(profile.get());
    178   EXPECT_TRUE(hotword_service != NULL);
    179 
    180   // If it's a fresh profile, although the default value is true,
    181   // it should return false if the preference has never been set.
    182   EXPECT_FALSE(hotword_service->IsOptedIntoAudioLogging());
    183 }
    184 
    185 TEST_F(HotwordServiceTest, ShouldReinstallExtension) {
    186   // Set the field trial to a valid one.
    187   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
    188       hotword_internal::kHotwordFieldTrialName, "Install"));
    189 
    190   InitializeEmptyExtensionService();
    191 
    192   HotwordServiceFactory* hotword_service_factory =
    193       HotwordServiceFactory::GetInstance();
    194 
    195   MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
    196       hotword_service_factory->SetTestingFactoryAndUse(
    197           profile(), BuildMockHotwordService));
    198   EXPECT_TRUE(hotword_service != NULL);
    199 
    200   // If no locale has been set, no reason to uninstall.
    201   EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
    202 
    203   SetApplicationLocale(profile(), "en");
    204   hotword_service->SetPreviousLanguagePref();
    205 
    206   // Now a locale is set, but it hasn't changed.
    207   EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
    208 
    209   SetApplicationLocale(profile(), "fr_fr");
    210 
    211   // Now it's a different locale so it should uninstall.
    212   EXPECT_TRUE(hotword_service->ShouldReinstallHotwordExtension());
    213 }
    214 
    215 TEST_F(HotwordServiceTest, PreviousLanguageSetOnInstall) {
    216   // Set the field trial to a valid one.
    217   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
    218       hotword_internal::kHotwordFieldTrialName, "Install"));
    219 
    220   InitializeEmptyExtensionService();
    221   service_->Init();
    222 
    223   HotwordServiceFactory* hotword_service_factory =
    224       HotwordServiceFactory::GetInstance();
    225 
    226   MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
    227       hotword_service_factory->SetTestingFactoryAndUse(
    228           profile(), BuildMockHotwordService));
    229   EXPECT_TRUE(hotword_service != NULL);
    230   hotword_service->SetExtensionService(service());
    231 
    232   // If no locale has been set, no reason to uninstall.
    233   EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
    234 
    235   SetApplicationLocale(profile(), "test_locale");
    236 
    237   hotword_service->InstallHotwordExtensionFromWebstore();
    238   base::MessageLoop::current()->RunUntilIdle();
    239 
    240   EXPECT_EQ("test_locale",
    241             profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
    242 }
    243 
    244 TEST_F(HotwordServiceTest, UninstallReinstallTriggeredCorrectly) {
    245   // Set the field trial to a valid one.
    246   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
    247       hotword_internal::kHotwordFieldTrialName, "Install"));
    248 
    249   InitializeEmptyExtensionService();
    250   service_->Init();
    251 
    252   HotwordServiceFactory* hotword_service_factory =
    253       HotwordServiceFactory::GetInstance();
    254 
    255   MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
    256       hotword_service_factory->SetTestingFactoryAndUse(
    257           profile(), BuildMockHotwordService));
    258   EXPECT_TRUE(hotword_service != NULL);
    259   hotword_service->SetExtensionService(service());
    260 
    261   // Initialize the locale to "en".
    262   SetApplicationLocale(profile(), "en");
    263 
    264   // The previous locale should not be set. No reason to uninstall.
    265   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
    266 
    267    // Do an initial installation.
    268   hotword_service->InstallHotwordExtensionFromWebstore();
    269   base::MessageLoop::current()->RunUntilIdle();
    270   EXPECT_EQ("en",
    271             profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
    272 
    273   // Verify the extension is installed but disabled.
    274   EXPECT_EQ(1U, registry()->disabled_extensions().size());
    275   EXPECT_TRUE(registry()->disabled_extensions().Contains(
    276       extension_misc::kHotwordExtensionId));
    277 
    278    // The previous locale should be set but should match the current
    279   // locale. No reason to uninstall.
    280   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
    281 
    282   // Switch the locale to a valid but different one.
    283   SetApplicationLocale(profile(), "fr_fr");
    284   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
    285 
    286    // Different but valid locale so expect uninstall.
    287   EXPECT_TRUE(hotword_service->MaybeReinstallHotwordExtension());
    288   EXPECT_EQ(1, hotword_service->uninstall_count());
    289   EXPECT_EQ("fr_fr",
    290             profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
    291 
    292   // Verify the extension is installed. It's still disabled.
    293   EXPECT_TRUE(registry()->disabled_extensions().Contains(
    294       extension_misc::kHotwordExtensionId));
    295 
    296   // Switch the locale to an invalid one.
    297   SetApplicationLocale(profile(), "invalid");
    298   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile()));
    299   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
    300   EXPECT_EQ("fr_fr",
    301             profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
    302 
    303   // If the locale is set back to the last valid one, then an uninstall-install
    304   // shouldn't be needed.
    305   SetApplicationLocale(profile(), "fr_fr");
    306   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
    307   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
    308   EXPECT_EQ(1, hotword_service->uninstall_count());  // no change
    309 }
    310