1 // Copyright 2013 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/command_line.h"
6 #include "base/files/file_path.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/prefs/pref_registry_simple.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/prefs/pref_service_factory.h"
11 #include "base/prefs/testing_pref_store.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/profiles/profiles_state.h"
14 #include "chrome/browser/ui/app_list/app_list_service.h"
15 #include "chrome/browser/ui/app_list/app_list_service_impl.h"
16 #include "chrome/browser/ui/app_list/test/fake_profile.h"
17 #include "chrome/browser/ui/app_list/test/fake_profile_store.h"
18 #include "chrome/common/chrome_constants.h"
19 #include "chrome/common/chrome_switches.h"
20 #include "chrome/common/pref_names.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 class TestingAppListServiceImpl
: public AppListServiceImpl
{
25 TestingAppListServiceImpl(const base::CommandLine
& command_line
,
26 PrefService
* local_state
,
27 scoped_ptr
<ProfileStore
> profile_store
)
28 : AppListServiceImpl(command_line
, local_state
, profile_store
.Pass()),
29 showing_for_profile_(NULL
),
30 destroy_app_list_call_count_(0) {}
32 Profile
* showing_for_profile() const {
33 return showing_for_profile_
;
36 int destroy_app_list_call_count() const {
37 return destroy_app_list_call_count_
;
40 void PerformStartupChecks(Profile
* profile
) {
41 AppListServiceImpl::PerformStartupChecks(profile
);
44 // AppListService overrides:
45 Profile
* GetCurrentAppListProfile() override
{
46 // We don't return showing_for_profile_ here because that is only defined if
47 // the app list is visible.
51 void CreateForProfile(Profile
* requested_profile
) override
{}
53 void ShowForProfile(Profile
* requested_profile
) override
{
54 showing_for_profile_
= requested_profile
;
55 RecordAppListLaunch();
58 void ShowForCustomLauncherPage(Profile
* profile
) override
{}
60 void DismissAppList() override
{ showing_for_profile_
= NULL
; }
62 bool IsAppListVisible() const override
{ return !!showing_for_profile_
; }
64 gfx::NativeWindow
GetAppListWindow() override
{ return NULL
; }
66 AppListControllerDelegate
* GetControllerDelegate() override
{ return NULL
; }
68 // AppListServiceImpl overrides:
69 void DestroyAppList() override
{ ++destroy_app_list_call_count_
; }
72 Profile
* showing_for_profile_
;
73 int destroy_app_list_call_count_
;
75 DISALLOW_COPY_AND_ASSIGN(TestingAppListServiceImpl
);
78 class AppListServiceUnitTest
: public testing::Test
{
80 AppListServiceUnitTest() {}
82 void SetUp() override
{
83 SetupWithCommandLine(base::CommandLine(base::CommandLine::NO_PROGRAM
));
87 void SetupWithCommandLine(const base::CommandLine
& command_line
) {
88 user_data_dir_
= base::FilePath(FILE_PATH_LITERAL("udd"));
90 new FakeProfile("p1", user_data_dir_
.AppendASCII("profile1")));
92 new FakeProfile("p2", user_data_dir_
.AppendASCII("profile2")));
93 PrefRegistrySimple
* pref_registry
= new PrefRegistrySimple
;
95 AppListService::RegisterPrefs(pref_registry
);
96 profiles::RegisterPrefs(pref_registry
);
98 base::PrefServiceFactory factory
;
99 factory
.set_user_prefs(make_scoped_refptr(new TestingPrefStore
));
100 local_state_
= factory
.Create(pref_registry
).Pass();
102 profile_store_
= new FakeProfileStore(user_data_dir_
);
103 service_
.reset(new TestingAppListServiceImpl(
106 scoped_ptr
<ProfileStore
>(profile_store_
)));
109 void EnableAppList() {
110 service_
->EnableAppList(profile1_
.get(),
111 AppListService::ENABLE_VIA_COMMAND_LINE
);
114 base::FilePath user_data_dir_
;
115 scoped_ptr
<PrefService
> local_state_
;
116 FakeProfileStore
* profile_store_
;
117 scoped_ptr
<TestingAppListServiceImpl
> service_
;
118 scoped_ptr
<FakeProfile
> profile1_
;
119 scoped_ptr
<FakeProfile
> profile2_
;
121 DISALLOW_COPY_AND_ASSIGN(AppListServiceUnitTest
);
124 TEST_F(AppListServiceUnitTest
, EnablingStateIsPersisted
) {
125 EXPECT_FALSE(local_state_
->GetBoolean(prefs::kAppLauncherHasBeenEnabled
));
127 EXPECT_TRUE(local_state_
->GetBoolean(prefs::kAppLauncherHasBeenEnabled
));
128 EXPECT_EQ(profile1_
->GetPath(), user_data_dir_
.Append(
129 local_state_
->GetFilePath(prefs::kAppListProfile
)));
132 TEST_F(AppListServiceUnitTest
, ShowingForProfileLoadsAProfile
) {
133 profile_store_
->LoadProfile(profile1_
.get());
136 EXPECT_EQ(profile1_
.get(), service_
->showing_for_profile());
137 EXPECT_TRUE(service_
->IsAppListVisible());
140 TEST_F(AppListServiceUnitTest
, RemovedProfileResetsToInitialProfile
) {
142 profile_store_
->RemoveProfile(profile1_
.get());
143 base::FilePath initial_profile_path
=
144 user_data_dir_
.AppendASCII(chrome::kInitialProfile
);
145 EXPECT_EQ(initial_profile_path
,
146 service_
->GetProfilePath(profile_store_
->GetUserDataDir()));
149 TEST_F(AppListServiceUnitTest
,
150 RemovedProfileResetsToLastUsedProfileIfExists
) {
151 local_state_
->SetString(prefs::kProfileLastUsed
, "last-used");
153 profile_store_
->RemoveProfile(profile1_
.get());
155 base::FilePath last_used_profile_path
=
156 user_data_dir_
.AppendASCII("last-used");
157 EXPECT_EQ(last_used_profile_path
,
158 service_
->GetProfilePath(profile_store_
->GetUserDataDir()));
160 // For this test, the AppListViewDelegate is not created because the
161 // app list is never shown, so there is nothing to destroy.
162 EXPECT_EQ(0, service_
->destroy_app_list_call_count());
165 TEST_F(AppListServiceUnitTest
, SwitchingProfilesPersists
) {
166 profile_store_
->LoadProfile(profile1_
.get());
167 profile_store_
->LoadProfile(profile2_
.get());
169 service_
->SetProfilePath(profile2_
->GetPath());
171 EXPECT_EQ(profile2_
.get(), service_
->showing_for_profile());
172 EXPECT_EQ(profile2_
->GetPath(),
173 service_
->GetProfilePath(profile_store_
->GetUserDataDir()));
174 service_
->SetProfilePath(profile1_
->GetPath());
175 EXPECT_EQ(profile1_
->GetPath(),
176 service_
->GetProfilePath(profile_store_
->GetUserDataDir()));
179 TEST_F(AppListServiceUnitTest
, EnableViaCommandLineFlag
) {
180 base::CommandLine
command_line(base::CommandLine::NO_PROGRAM
);
181 command_line
.AppendSwitch(switches::kEnableAppList
);
182 SetupWithCommandLine(command_line
);
183 service_
->PerformStartupChecks(profile1_
.get());
184 EXPECT_TRUE(local_state_
->GetBoolean(prefs::kAppLauncherHasBeenEnabled
));
187 TEST_F(AppListServiceUnitTest
, DisableViaCommandLineFlag
) {
188 base::CommandLine
command_line(base::CommandLine::NO_PROGRAM
);
189 command_line
.AppendSwitch(switches::kResetAppListInstallState
);
190 SetupWithCommandLine(command_line
);
191 service_
->PerformStartupChecks(profile1_
.get());
192 EXPECT_FALSE(local_state_
->GetBoolean(prefs::kAppLauncherHasBeenEnabled
));
195 TEST_F(AppListServiceUnitTest
, UMAPrefStates
) {
196 EXPECT_FALSE(local_state_
->GetBoolean(prefs::kAppLauncherHasBeenEnabled
));
197 EXPECT_EQ(AppListService::ENABLE_NOT_RECORDED
,
198 local_state_
->GetInteger(prefs::kAppListEnableMethod
));
199 EXPECT_EQ(0, local_state_
->GetInt64(prefs::kAppListEnableTime
));
201 service_
->EnableAppList(profile1_
.get(),
202 AppListService::ENABLE_FOR_APP_INSTALL
);
204 // After enable, method and time should be recorded.
205 EXPECT_TRUE(local_state_
->GetBoolean(prefs::kAppLauncherHasBeenEnabled
));
206 EXPECT_EQ(AppListService::ENABLE_FOR_APP_INSTALL
,
207 local_state_
->GetInteger(prefs::kAppListEnableMethod
));
208 EXPECT_NE(0, local_state_
->GetInt64(prefs::kAppListEnableTime
));
210 service_
->ShowForProfile(profile1_
.get());
212 // After a regular "show", time should be cleared, so UMA is not re-recorded.
213 EXPECT_EQ(AppListService::ENABLE_FOR_APP_INSTALL
,
214 local_state_
->GetInteger(prefs::kAppListEnableMethod
));
215 EXPECT_EQ(0, local_state_
->GetInt64(prefs::kAppListEnableTime
));
217 // A second enable should be a no-op.
218 service_
->EnableAppList(profile1_
.get(),
219 AppListService::ENABLE_FOR_APP_INSTALL
);
220 EXPECT_EQ(AppListService::ENABLE_FOR_APP_INSTALL
,
221 local_state_
->GetInteger(prefs::kAppListEnableMethod
));
222 EXPECT_EQ(0, local_state_
->GetInt64(prefs::kAppListEnableTime
));
224 // An app install auto-show here should keep the recorded enable method.
225 service_
->ShowForAppInstall(profile1_
.get(), "", false);
226 EXPECT_EQ(AppListService::ENABLE_FOR_APP_INSTALL
,
227 local_state_
->GetInteger(prefs::kAppListEnableMethod
));
229 // Clear the enable state, so we can enable again.
230 local_state_
->SetBoolean(prefs::kAppLauncherHasBeenEnabled
, false);
231 service_
->EnableAppList(profile1_
.get(),
232 AppListService::ENABLE_FOR_APP_INSTALL
);
234 EXPECT_EQ(AppListService::ENABLE_FOR_APP_INSTALL
,
235 local_state_
->GetInteger(prefs::kAppListEnableMethod
));
236 EXPECT_NE(0, local_state_
->GetInt64(prefs::kAppListEnableTime
));
238 // An auto-show here should update the enable method to prevent recording it
239 // as ENABLE_FOR_APP_INSTALL.
240 service_
->ShowForAppInstall(profile1_
.get(), "", false);
241 EXPECT_EQ(AppListService::ENABLE_SHOWN_UNDISCOVERED
,
242 local_state_
->GetInteger(prefs::kAppListEnableMethod
));