• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
MockHotwordService(Profile * profile)28   explicit MockHotwordService(Profile* profile)
29       : HotwordService(profile),
30         uninstall_count_(0) {
31   }
32 
UninstallHotwordExtension(ExtensionService * extension_service)33   virtual bool UninstallHotwordExtension(
34       ExtensionService* extension_service) OVERRIDE {
35     uninstall_count_++;
36     return HotwordService::UninstallHotwordExtension(extension_service);
37   }
38 
InstallHotwordExtensionFromWebstore()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 
uninstall_count()58   int uninstall_count() { return uninstall_count_; }
59 
SetExtensionService(ExtensionService * service)60   void SetExtensionService(ExtensionService* service) { service_ = service; }
61 
extension_service()62   ExtensionService* extension_service() { return service_; }
63 
64  private:
65   ExtensionService* service_;
66   int uninstall_count_;
67 };
68 
BuildMockHotwordService(content::BrowserContext * context)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:
HotwordServiceTest()77   HotwordServiceTest() : field_trial_list_(NULL) {}
~HotwordServiceTest()78   virtual ~HotwordServiceTest() {}
79 
SetApplicationLocale(Profile * profile,const std::string & new_locale)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 
TEST_F(HotwordServiceTest,IsHotwordAllowedBadFieldTrial)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 
TEST_F(HotwordServiceTest,IsHotwordAllowedLocale)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 
TEST_F(HotwordServiceTest,AudioLoggingPrefSetCorrectly)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 
TEST_F(HotwordServiceTest,ShouldReinstallExtension)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 
TEST_F(HotwordServiceTest,PreviousLanguageSetOnInstall)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 
TEST_F(HotwordServiceTest,UninstallReinstallTriggeredCorrectly)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