Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / search / hotword_service_unittest.cc
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/command_line.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/metrics/field_trial.h"
8 #include "base/prefs/pref_service.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/extensions/extension_service_test_base.h"
11 #include "chrome/browser/extensions/test_extension_service.h"
12 #include "chrome/browser/search/hotword_service.h"
13 #include "chrome/browser/search/hotword_service_factory.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/extensions/extension_constants.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "extensions/browser/extension_system.h"
20 #include "extensions/common/extension.h"
21 #include "extensions/common/extension_builder.h"
22 #include "extensions/common/manifest.h"
23 #include "extensions/common/one_shot_event.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 namespace {
27
28 class MockHotwordService : public HotwordService {
29  public:
30   explicit MockHotwordService(Profile* profile)
31       : HotwordService(profile),
32         uninstall_count_(0) {
33   }
34
35   bool UninstallHotwordExtension(ExtensionService* extension_service) override {
36     uninstall_count_++;
37     return HotwordService::UninstallHotwordExtension(extension_service);
38   }
39
40   void InstallHotwordExtensionFromWebstore() override {
41     scoped_ptr<base::DictionaryValue> manifest =
42         extensions::DictionaryBuilder()
43         .Set("name", "Hotword Test Extension")
44         .Set("version", "1.0")
45         .Set("manifest_version", 2)
46         .Build();
47     scoped_refptr<extensions::Extension> extension =
48         extensions::ExtensionBuilder().SetManifest(manifest.Pass())
49         .AddFlags(extensions::Extension::FROM_WEBSTORE
50                   | extensions::Extension::WAS_INSTALLED_BY_DEFAULT)
51         .SetID(extension_id_)
52         .SetLocation(extensions::Manifest::EXTERNAL_COMPONENT)
53         .Build();
54     ASSERT_TRUE(extension.get());
55     service_->OnExtensionInstalled(extension.get(), syncer::StringOrdinal());
56   }
57
58
59   int uninstall_count() { return uninstall_count_; }
60
61   void SetExtensionService(ExtensionService* service) { service_ = service; }
62   void SetExtensionId(const std::string& extension_id) {
63     extension_id_ = extension_id;
64   }
65
66   ExtensionService* extension_service() { return service_; }
67
68  private:
69   ExtensionService* service_;
70   int uninstall_count_;
71   std::string extension_id_;
72 };
73
74 KeyedService* BuildMockHotwordService(content::BrowserContext* context) {
75   return new MockHotwordService(static_cast<Profile*>(context));
76 }
77
78 }  // namespace
79
80 class HotwordServiceTest :
81   public extensions::ExtensionServiceTestBase,
82   public ::testing::WithParamInterface<const char*> {
83  protected:
84   HotwordServiceTest() : field_trial_list_(NULL) {}
85   virtual ~HotwordServiceTest() {}
86
87   void SetApplicationLocale(Profile* profile, const std::string& new_locale) {
88 #if defined(OS_CHROMEOS)
89         // On ChromeOS locale is per-profile.
90     profile->GetPrefs()->SetString(prefs::kApplicationLocale, new_locale);
91 #else
92     g_browser_process->SetApplicationLocale(new_locale);
93 #endif
94   }
95
96   void SetUp() override {
97     extension_id_ = GetParam();
98     if (extension_id_ == extension_misc::kHotwordSharedModuleId) {
99       base::CommandLine::ForCurrentProcess()->AppendSwitch(
100           switches::kEnableExperimentalHotwording);
101     }
102
103     extensions::ExtensionServiceTestBase::SetUp();
104   }
105
106   base::FieldTrialList field_trial_list_;
107   std::string extension_id_;
108 };
109
110 INSTANTIATE_TEST_CASE_P(HotwordServiceTests,
111                         HotwordServiceTest,
112                         ::testing::Values(
113                             extension_misc::kHotwordExtensionId,
114                             extension_misc::kHotwordSharedModuleId));
115
116 TEST_P(HotwordServiceTest, IsHotwordAllowedBadFieldTrial) {
117   TestingProfile::Builder profile_builder;
118   scoped_ptr<TestingProfile> profile = profile_builder.Build();
119
120   HotwordServiceFactory* hotword_service_factory =
121       HotwordServiceFactory::GetInstance();
122
123   // Check that the service exists so that a NULL service be ruled out in
124   // following tests.
125   HotwordService* hotword_service =
126       hotword_service_factory->GetForProfile(profile.get());
127   EXPECT_TRUE(hotword_service != NULL);
128
129   // When the field trial is empty or Disabled, it should not be allowed.
130   std::string group = base::FieldTrialList::FindFullName(
131       hotword_internal::kHotwordFieldTrialName);
132   EXPECT_TRUE(group.empty());
133   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
134
135   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
136      hotword_internal::kHotwordFieldTrialName,
137      hotword_internal::kHotwordFieldTrialDisabledGroupName));
138   group = base::FieldTrialList::FindFullName(
139       hotword_internal::kHotwordFieldTrialName);
140   EXPECT_TRUE(group ==hotword_internal::kHotwordFieldTrialDisabledGroupName);
141   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
142
143   // Set a valid locale with invalid field trial to be sure it is
144   // still false.
145   SetApplicationLocale(static_cast<Profile*>(profile.get()), "en");
146   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
147
148   // Test that incognito returns false as well.
149   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(
150       profile->GetOffTheRecordProfile()));
151 }
152
153 TEST_P(HotwordServiceTest, IsHotwordAllowedLocale) {
154   TestingProfile::Builder profile_builder;
155   scoped_ptr<TestingProfile> profile = profile_builder.Build();
156
157   HotwordServiceFactory* hotword_service_factory =
158       HotwordServiceFactory::GetInstance();
159
160   // Check that the service exists so that a NULL service be ruled out in
161   // following tests.
162   HotwordService* hotword_service =
163       hotword_service_factory->GetForProfile(profile.get());
164   EXPECT_TRUE(hotword_service != NULL);
165
166   // Set the field trial to a valid one.
167   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
168       hotword_internal::kHotwordFieldTrialName, "Good"));
169
170   // Set the language to an invalid one.
171   SetApplicationLocale(static_cast<Profile*>(profile.get()), "non-valid");
172   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
173
174   // Now with valid locales it should be fine.
175   SetApplicationLocale(static_cast<Profile*>(profile.get()), "en");
176   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
177   SetApplicationLocale(static_cast<Profile*>(profile.get()), "en-US");
178   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
179   SetApplicationLocale(static_cast<Profile*>(profile.get()), "en_us");
180   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
181   SetApplicationLocale(static_cast<Profile*>(profile.get()), "de_DE");
182   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
183   SetApplicationLocale(static_cast<Profile*>(profile.get()), "fr_fr");
184   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile.get()));
185
186   // Test that incognito even with a valid locale and valid field trial
187   // still returns false.
188   Profile* otr_profile = profile->GetOffTheRecordProfile();
189   SetApplicationLocale(otr_profile, "en");
190   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(otr_profile));
191 }
192
193 TEST_P(HotwordServiceTest, AudioLoggingPrefSetCorrectly) {
194   TestingProfile::Builder profile_builder;
195   scoped_ptr<TestingProfile> profile = profile_builder.Build();
196
197   HotwordServiceFactory* hotword_service_factory =
198       HotwordServiceFactory::GetInstance();
199   HotwordService* hotword_service =
200       hotword_service_factory->GetForProfile(profile.get());
201   EXPECT_TRUE(hotword_service != NULL);
202
203   // If it's a fresh profile, although the default value is true,
204   // it should return false if the preference has never been set.
205   EXPECT_FALSE(hotword_service->IsOptedIntoAudioLogging());
206 }
207
208 TEST_P(HotwordServiceTest, ShouldReinstallExtension) {
209   // Set the field trial to a valid one.
210   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
211       hotword_internal::kHotwordFieldTrialName, "Install"));
212
213   InitializeEmptyExtensionService();
214
215   HotwordServiceFactory* hotword_service_factory =
216       HotwordServiceFactory::GetInstance();
217
218   MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
219       hotword_service_factory->SetTestingFactoryAndUse(
220           profile(), BuildMockHotwordService));
221   EXPECT_TRUE(hotword_service != NULL);
222   hotword_service->SetExtensionId(extension_id_);
223
224   // If no locale has been set, no reason to uninstall.
225   EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
226
227   SetApplicationLocale(profile(), "en");
228   hotword_service->SetPreviousLanguagePref();
229
230   // Now a locale is set, but it hasn't changed.
231   EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
232
233   SetApplicationLocale(profile(), "fr_fr");
234
235   // Now it's a different locale so it should uninstall.
236   EXPECT_TRUE(hotword_service->ShouldReinstallHotwordExtension());
237 }
238
239 TEST_P(HotwordServiceTest, PreviousLanguageSetOnInstall) {
240   // Set the field trial to a valid one.
241   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
242       hotword_internal::kHotwordFieldTrialName, "Install"));
243
244   InitializeEmptyExtensionService();
245   service_->Init();
246
247   HotwordServiceFactory* hotword_service_factory =
248       HotwordServiceFactory::GetInstance();
249
250   MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
251       hotword_service_factory->SetTestingFactoryAndUse(
252           profile(), BuildMockHotwordService));
253   EXPECT_TRUE(hotword_service != NULL);
254   hotword_service->SetExtensionService(service());
255   hotword_service->SetExtensionId(extension_id_);
256
257   // If no locale has been set, no reason to uninstall.
258   EXPECT_FALSE(hotword_service->ShouldReinstallHotwordExtension());
259
260   SetApplicationLocale(profile(), "test_locale");
261
262   hotword_service->InstallHotwordExtensionFromWebstore();
263   base::MessageLoop::current()->RunUntilIdle();
264
265   EXPECT_EQ("test_locale",
266             profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
267 }
268
269 TEST_P(HotwordServiceTest, UninstallReinstallTriggeredCorrectly) {
270   // Set the field trial to a valid one.
271   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
272       hotword_internal::kHotwordFieldTrialName, "Install"));
273
274   InitializeEmptyExtensionService();
275   service_->Init();
276
277   HotwordServiceFactory* hotword_service_factory =
278       HotwordServiceFactory::GetInstance();
279
280   MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
281       hotword_service_factory->SetTestingFactoryAndUse(
282           profile(), BuildMockHotwordService));
283   EXPECT_TRUE(hotword_service != NULL);
284   hotword_service->SetExtensionService(service());
285   hotword_service->SetExtensionId(extension_id_);
286
287   // Initialize the locale to "en".
288   SetApplicationLocale(profile(), "en");
289
290   // The previous locale should not be set. No reason to uninstall.
291   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
292
293    // Do an initial installation.
294   hotword_service->InstallHotwordExtensionFromWebstore();
295   base::MessageLoop::current()->RunUntilIdle();
296   EXPECT_EQ("en",
297             profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
298
299   if (extension_id_ == extension_misc::kHotwordSharedModuleId) {
300     // Shared module is installed and enabled.
301     EXPECT_EQ(0U, registry()->disabled_extensions().size());
302     EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_id_));
303   } else {
304     // Verify the extension is installed but disabled.
305     EXPECT_EQ(1U, registry()->disabled_extensions().size());
306     EXPECT_TRUE(registry()->disabled_extensions().Contains(extension_id_));
307   }
308
309    // The previous locale should be set but should match the current
310   // locale. No reason to uninstall.
311   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
312
313   // Switch the locale to a valid but different one.
314   SetApplicationLocale(profile(), "fr_fr");
315   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
316
317    // Different but valid locale so expect uninstall.
318   EXPECT_TRUE(hotword_service->MaybeReinstallHotwordExtension());
319   EXPECT_EQ(1, hotword_service->uninstall_count());
320   EXPECT_EQ("fr_fr",
321             profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
322
323   if (extension_id_ == extension_misc::kHotwordSharedModuleId) {
324     // Shared module is installed and enabled.
325     EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_id_));
326   } else {
327     // Verify the extension is installed. It's still disabled.
328     EXPECT_TRUE(registry()->disabled_extensions().Contains(extension_id_));
329   }
330
331   // Switch the locale to an invalid one.
332   SetApplicationLocale(profile(), "invalid");
333   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile()));
334   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
335   EXPECT_EQ("fr_fr",
336             profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage));
337
338   // If the locale is set back to the last valid one, then an uninstall-install
339   // shouldn't be needed.
340   SetApplicationLocale(profile(), "fr_fr");
341   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
342   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
343   EXPECT_EQ(1, hotword_service->uninstall_count());  // no change
344 }
345
346 TEST_P(HotwordServiceTest, DisableAlwaysOnOnLanguageChange) {
347   // Bypass test for old hotwording.
348   if (extension_id_ != extension_misc::kHotwordSharedModuleId)
349     return;
350
351   // Set the field trial to a valid one.
352   ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
353       hotword_internal::kHotwordFieldTrialName, "Install"));
354
355   InitializeEmptyExtensionService();
356   service_->Init();
357
358   // Enable always-on.
359   profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, true);
360
361   HotwordServiceFactory* hotword_service_factory =
362       HotwordServiceFactory::GetInstance();
363
364   MockHotwordService* hotword_service = static_cast<MockHotwordService*>(
365       hotword_service_factory->SetTestingFactoryAndUse(
366           profile(), BuildMockHotwordService));
367   EXPECT_TRUE(hotword_service != NULL);
368   hotword_service->SetExtensionService(service());
369   hotword_service->SetExtensionId(extension_id_);
370
371   // Initialize the locale to "en".
372   SetApplicationLocale(profile(), "en");
373
374   // The previous locale should not be set. No reason to uninstall.
375   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
376   EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
377
378   // Do an initial installation.
379   hotword_service->InstallHotwordExtensionFromWebstore();
380   base::MessageLoop::current()->RunUntilIdle();
381
382   // The previous locale should be set but should match the current
383   // locale. No reason to uninstall.
384   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
385   EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
386
387   // Switch the locale to a valid but different one.
388   SetApplicationLocale(profile(), "fr_fr");
389   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
390
391   // Different but valid locale so expect uninstall.
392   EXPECT_TRUE(hotword_service->MaybeReinstallHotwordExtension());
393   EXPECT_FALSE(hotword_service->IsAlwaysOnEnabled());
394
395   // Re-enable always-on.
396   profile()->GetPrefs()->SetBoolean(prefs::kHotwordAlwaysOnSearchEnabled, true);
397
398   // Switch the locale to an invalid one.
399   SetApplicationLocale(profile(), "invalid");
400   EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile()));
401   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
402   EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
403
404   // If the locale is set back to the last valid one, then an uninstall-install
405   // shouldn't be needed.
406   SetApplicationLocale(profile(), "fr_fr");
407   EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
408   EXPECT_FALSE(hotword_service->MaybeReinstallHotwordExtension());
409   EXPECT_TRUE(hotword_service->IsAlwaysOnEnabled());
410 }