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.
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"
26 class MockHotwordService
: public HotwordService
{
28 explicit MockHotwordService(Profile
* profile
)
29 : HotwordService(profile
),
33 virtual bool UninstallHotwordExtension(
34 ExtensionService
* extension_service
) override
{
36 return HotwordService::UninstallHotwordExtension(extension_service
);
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)
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
)
53 ASSERT_TRUE(extension
.get());
54 service_
->OnExtensionInstalled(extension
.get(), syncer::StringOrdinal());
58 int uninstall_count() { return uninstall_count_
; }
60 void SetExtensionService(ExtensionService
* service
) { service_
= service
; }
62 ExtensionService
* extension_service() { return service_
; }
65 ExtensionService
* service_
;
69 KeyedService
* BuildMockHotwordService(content::BrowserContext
* context
) {
70 return new MockHotwordService(static_cast<Profile
*>(context
));
75 class HotwordServiceTest
: public extensions::ExtensionServiceTestBase
{
77 HotwordServiceTest() : field_trial_list_(NULL
) {}
78 virtual ~HotwordServiceTest() {}
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
);
85 g_browser_process
->SetApplicationLocale(new_locale
);
90 base::FieldTrialList field_trial_list_
;
93 TEST_F(HotwordServiceTest
, IsHotwordAllowedBadFieldTrial
) {
94 TestingProfile::Builder profile_builder
;
95 scoped_ptr
<TestingProfile
> profile
= profile_builder
.Build();
97 HotwordServiceFactory
* hotword_service_factory
=
98 HotwordServiceFactory::GetInstance();
100 // Check that the service exists so that a NULL service be ruled out in
102 HotwordService
* hotword_service
=
103 hotword_service_factory
->GetForProfile(profile
.get());
104 EXPECT_TRUE(hotword_service
!= NULL
);
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()));
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()));
120 // Set a valid locale with invalid field trial to be sure it is
122 SetApplicationLocale(static_cast<Profile
*>(profile
.get()), "en");
123 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile
.get()));
125 // Test that incognito returns false as well.
126 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(
127 profile
->GetOffTheRecordProfile()));
130 TEST_F(HotwordServiceTest
, IsHotwordAllowedLocale
) {
131 TestingProfile::Builder profile_builder
;
132 scoped_ptr
<TestingProfile
> profile
= profile_builder
.Build();
134 HotwordServiceFactory
* hotword_service_factory
=
135 HotwordServiceFactory::GetInstance();
137 // Check that the service exists so that a NULL service be ruled out in
139 HotwordService
* hotword_service
=
140 hotword_service_factory
->GetForProfile(profile
.get());
141 EXPECT_TRUE(hotword_service
!= NULL
);
143 // Set the field trial to a valid one.
144 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial(
145 hotword_internal::kHotwordFieldTrialName
, "Good"));
147 // Set the language to an invalid one.
148 SetApplicationLocale(static_cast<Profile
*>(profile
.get()), "non-valid");
149 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile
.get()));
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()));
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
));
170 TEST_F(HotwordServiceTest
, AudioLoggingPrefSetCorrectly
) {
171 TestingProfile::Builder profile_builder
;
172 scoped_ptr
<TestingProfile
> profile
= profile_builder
.Build();
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
);
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());
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"));
190 InitializeEmptyExtensionService();
192 HotwordServiceFactory
* hotword_service_factory
=
193 HotwordServiceFactory::GetInstance();
195 MockHotwordService
* hotword_service
= static_cast<MockHotwordService
*>(
196 hotword_service_factory
->SetTestingFactoryAndUse(
197 profile(), BuildMockHotwordService
));
198 EXPECT_TRUE(hotword_service
!= NULL
);
200 // If no locale has been set, no reason to uninstall.
201 EXPECT_FALSE(hotword_service
->ShouldReinstallHotwordExtension());
203 SetApplicationLocale(profile(), "en");
204 hotword_service
->SetPreviousLanguagePref();
206 // Now a locale is set, but it hasn't changed.
207 EXPECT_FALSE(hotword_service
->ShouldReinstallHotwordExtension());
209 SetApplicationLocale(profile(), "fr_fr");
211 // Now it's a different locale so it should uninstall.
212 EXPECT_TRUE(hotword_service
->ShouldReinstallHotwordExtension());
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"));
220 InitializeEmptyExtensionService();
223 HotwordServiceFactory
* hotword_service_factory
=
224 HotwordServiceFactory::GetInstance();
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());
232 // If no locale has been set, no reason to uninstall.
233 EXPECT_FALSE(hotword_service
->ShouldReinstallHotwordExtension());
235 SetApplicationLocale(profile(), "test_locale");
237 hotword_service
->InstallHotwordExtensionFromWebstore();
238 base::MessageLoop::current()->RunUntilIdle();
240 EXPECT_EQ("test_locale",
241 profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage
));
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"));
249 InitializeEmptyExtensionService();
252 HotwordServiceFactory
* hotword_service_factory
=
253 HotwordServiceFactory::GetInstance();
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());
261 // Initialize the locale to "en".
262 SetApplicationLocale(profile(), "en");
264 // The previous locale should not be set. No reason to uninstall.
265 EXPECT_FALSE(hotword_service
->MaybeReinstallHotwordExtension());
267 // Do an initial installation.
268 hotword_service
->InstallHotwordExtensionFromWebstore();
269 base::MessageLoop::current()->RunUntilIdle();
271 profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage
));
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
));
278 // The previous locale should be set but should match the current
279 // locale. No reason to uninstall.
280 EXPECT_FALSE(hotword_service
->MaybeReinstallHotwordExtension());
282 // Switch the locale to a valid but different one.
283 SetApplicationLocale(profile(), "fr_fr");
284 EXPECT_TRUE(HotwordServiceFactory::IsHotwordAllowed(profile()));
286 // Different but valid locale so expect uninstall.
287 EXPECT_TRUE(hotword_service
->MaybeReinstallHotwordExtension());
288 EXPECT_EQ(1, hotword_service
->uninstall_count());
290 profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage
));
292 // Verify the extension is installed. It's still disabled.
293 EXPECT_TRUE(registry()->disabled_extensions().Contains(
294 extension_misc::kHotwordExtensionId
));
296 // Switch the locale to an invalid one.
297 SetApplicationLocale(profile(), "invalid");
298 EXPECT_FALSE(HotwordServiceFactory::IsHotwordAllowed(profile()));
299 EXPECT_FALSE(hotword_service
->MaybeReinstallHotwordExtension());
301 profile()->GetPrefs()->GetString(prefs::kHotwordPreviousLanguage
));
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