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 "chrome/browser/ui/views/profiles/profile_chooser_view.h"
7 #include "base/command_line.h"
8 #include "base/path_service.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/test/histogram_tester.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/extensions/extension_browsertest.h"
15 #include "chrome/browser/profiles/profile_manager.h"
16 #include "chrome/browser/profiles/profile_metrics.h"
17 #include "chrome/browser/profiles/profiles_state.h"
18 #include "chrome/browser/ui/browser_list.h"
19 #include "chrome/browser/ui/user_manager.h"
20 #include "chrome/browser/ui/views/frame/browser_view.h"
21 #include "chrome/browser/ui/views/profiles/avatar_menu_button.h"
22 #include "chrome/browser/ui/views/profiles/new_avatar_button.h"
23 #include "chrome/browser/ui/views/profiles/user_manager_view.h"
24 #include "chrome/common/chrome_paths.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/pref_names.h"
27 #include "components/signin/core/common/profile_management_switches.h"
28 #include "content/public/test/test_utils.h"
29 #include "extensions/browser/extension_registry.h"
30 #include "ui/events/event_utils.h"
31 #include "ui/views/controls/webview/webview.h"
35 Profile
* CreateTestingProfile(const std::string
& profile_name
) {
36 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
37 size_t starting_number_of_profiles
= profile_manager
->GetNumberOfProfiles();
40 PathService::Get(chrome::DIR_USER_DATA
, &path
);
41 path
= path
.AppendASCII(profile_name
);
42 if (!base::PathExists(path
) && !base::CreateDirectory(path
))
43 NOTREACHED() << "Could not create directory at " << path
.MaybeAsASCII();
46 Profile::CreateProfile(path
, NULL
, Profile::CREATE_MODE_SYNCHRONOUS
);
47 profile_manager
->RegisterTestingProfile(profile
, true, false);
48 EXPECT_EQ(starting_number_of_profiles
+ 1,
49 profile_manager
->GetNumberOfProfiles());
53 Profile
* CreateProfileOutsideUserDataDir() {
55 if (!base::CreateNewTempDirectory(base::FilePath::StringType(), &path
))
56 NOTREACHED() << "Could not create directory at " << path
.MaybeAsASCII();
58 ProfileManager
* profile_manager
= g_browser_process
->profile_manager();
60 Profile::CreateProfile(path
, NULL
, Profile::CREATE_MODE_SYNCHRONOUS
);
61 profile_manager
->RegisterTestingProfile(profile
, true, false);
65 // Set up the profiles to enable Lock. Takes as parameter a profile that will be
66 // signed in, and also creates a supervised user (necessary for lock).
67 void SetupProfilesForLock(Profile
* signed_in
) {
68 const char* signed_in_email
= "me@google.com";
69 Profile
* supervised
= CreateTestingProfile("supervised");
70 ProfileInfoCache
* cache
= &g_browser_process
->profile_manager()->
71 GetProfileInfoCache();
72 cache
->SetAuthInfoOfProfileAtIndex(cache
->GetIndexOfProfileWithPath(
73 signed_in
->GetPath()), "12345", base::UTF8ToUTF16(signed_in_email
));
74 signed_in
->GetPrefs()->
75 SetString(prefs::kGoogleServicesHostedDomain
, "google.com");
76 cache
->SetSupervisedUserIdOfProfileAtIndex(cache
->GetIndexOfProfileWithPath(
77 supervised
->GetPath()), signed_in_email
);
79 EXPECT_TRUE(profiles::IsLockAvailable(signed_in
));
82 views::View
* FindWebView(views::View
* view
) {
83 std::queue
<views::View
*> queue
;
85 while (!queue
.empty()) {
86 views::View
* current
= queue
.front();
88 if (current
->GetClassName() == views::WebView::kViewClassName
)
91 for (int i
= 0; i
< current
->child_count(); ++i
)
92 queue
.push(current
->child_at(i
));
99 class ProfileChooserViewExtensionsTest
: public ExtensionBrowserTest
{
101 ProfileChooserViewExtensionsTest() {}
102 ~ProfileChooserViewExtensionsTest() override
{}
105 void SetUp() override
{
106 ExtensionBrowserTest::SetUp();
107 DCHECK(switches::IsNewAvatarMenu());
108 DCHECK(switches::IsNewProfileManagement());
111 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
112 ExtensionBrowserTest::SetUpCommandLine(command_line
);
113 switches::EnableNewProfileManagementForTesting(command_line
);
116 void OpenProfileChooserView(Browser
* browser
){
117 BrowserView
* browser_view
= BrowserView::GetBrowserViewForBrowser(browser
);
118 NewAvatarButton
* button
= browser_view
->frame()->GetNewAvatarMenuButton();
120 NOTREACHED() << "NewAvatarButton not found.";
121 if (browser_view
->frame()->GetAvatarMenuButton())
122 NOTREACHED() << "Old Avatar Menu Button found.";
124 ProfileChooserView::close_on_deactivate_for_testing_
= false;
126 ui::MouseEvent
e(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
127 ui::EventTimeForNow(), 0, 0);
128 button
->NotifyClick(e
);
129 base::MessageLoop::current()->RunUntilIdle();
130 EXPECT_TRUE(ProfileChooserView::IsShowing());
132 // Create this observer before lock is pressed to avoid a race condition.
133 window_close_observer_
.reset(new content::WindowedNotificationObserver(
134 chrome::NOTIFICATION_BROWSER_CLOSED
,
135 content::Source
<Browser
>(browser
)));
138 AvatarMenu
* GetProfileChooserViewAvatarMenu() {
139 return ProfileChooserView::profile_bubble_
->avatar_menu_
.get();
142 void ClickProfileChooserViewLockButton() {
143 ui::MouseEvent
e(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
144 ui::EventTimeForNow(), 0, 0);
145 ProfileChooserView::profile_bubble_
->ButtonPressed(
146 ProfileChooserView::profile_bubble_
->lock_button_
, e
);
149 // Access the registry that has been prepared with at least one extension.
150 extensions::ExtensionRegistry
* GetPreparedRegistry(Profile
* signed_in
) {
151 extensions::ExtensionRegistry
* registry
=
152 extensions::ExtensionRegistry::Get(signed_in
);
153 const size_t initial_num_extensions
= registry
->enabled_extensions().size();
154 const extensions::Extension
* ext
= LoadExtension(
155 test_data_dir_
.AppendASCII("app"));
157 EXPECT_EQ(initial_num_extensions
+ 1,
158 registry
->enabled_extensions().size());
159 EXPECT_EQ(0U, registry
->blocked_extensions().size());
163 void WaitForUserManager() {
164 // If the User Manager hasn't shown yet, wait for it to show up.
165 // TODO(mlerman): As per crbug.com/450221, we should somehow observe when
166 // the UserManager is created and wait for that event.
167 if (!UserManager::IsShowing())
168 base::MessageLoop::current()->RunUntilIdle();
169 EXPECT_TRUE(UserManager::IsShowing());
172 content::WindowedNotificationObserver
* window_close_observer() {
173 return window_close_observer_
.get();
176 ProfileChooserView
* current_profile_bubble() {
177 return ProfileChooserView::profile_bubble_
;
180 views::View
* signin_current_profile_link() {
181 return ProfileChooserView::profile_bubble_
->signin_current_profile_link_
;
184 void ShowSigninView() {
185 DCHECK(current_profile_bubble());
186 DCHECK(current_profile_bubble()->avatar_menu_
);
187 current_profile_bubble()->ShowView(
188 profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN
,
189 current_profile_bubble()->avatar_menu_
.get());
190 base::MessageLoop::current()->RunUntilIdle();
194 scoped_ptr
<content::WindowedNotificationObserver
> window_close_observer_
;
196 DISALLOW_COPY_AND_ASSIGN(ProfileChooserViewExtensionsTest
);
199 IN_PROC_BROWSER_TEST_F(ProfileChooserViewExtensionsTest
,
200 NoProfileChooserOnOutsideUserDataDirProfiles
) {
201 // Test that the profile chooser view does not show when avatar menu is not
202 // available. This can be repro'ed with a profile path outside user_data_dir.
204 Profile
* new_profile
= CreateProfileOutsideUserDataDir();
205 Browser
* browser
= CreateBrowser(new_profile
);
206 browser
->window()->ShowAvatarBubbleFromAvatarButton(
207 BrowserWindow::AVATAR_BUBBLE_MODE_CONFIRM_SIGNIN
,
208 signin::ManageAccountsParams());
209 ASSERT_FALSE(ProfileChooserView::IsShowing());
210 CloseBrowserSynchronously(browser
);
213 IN_PROC_BROWSER_TEST_F(ProfileChooserViewExtensionsTest
, SigninButtonHasFocus
) {
214 ASSERT_TRUE(profiles::IsMultipleProfilesEnabled());
215 ASSERT_NO_FATAL_FAILURE(OpenProfileChooserView(browser()));
217 EXPECT_TRUE(signin_current_profile_link()->HasFocus());
220 IN_PROC_BROWSER_TEST_F(ProfileChooserViewExtensionsTest
, ContentAreaHasFocus
) {
221 ASSERT_TRUE(profiles::IsMultipleProfilesEnabled());
223 ASSERT_NO_FATAL_FAILURE(OpenProfileChooserView(browser()));
227 ASSERT_TRUE(current_profile_bubble());
228 views::View
* web_view
= FindWebView(current_profile_bubble());
229 ASSERT_TRUE(web_view
);
230 EXPECT_TRUE(web_view
->HasFocus());
233 IN_PROC_BROWSER_TEST_F(ProfileChooserViewExtensionsTest
, ViewProfileUMA
) {
234 ASSERT_TRUE(profiles::IsMultipleProfilesEnabled());
236 base::HistogramTester histograms
;
237 Profile
* profile
= browser()->profile();
238 profile
->GetPrefs()->SetInteger(prefs::kProfileAvatarTutorialShown
, 0);
240 ASSERT_NO_FATAL_FAILURE(OpenProfileChooserView(browser()));
242 histograms
.ExpectUniqueSample("Profile.NewAvatarMenu.Upgrade",
243 ProfileMetrics::PROFILE_AVATAR_MENU_UPGRADE_VIEW
, 1);
246 // Flaky: http://crbug.com/450221
247 // WaitForUserManager()'s RunUntilIdle isn't always sufficient for the
248 // UserManager to be showing.
249 IN_PROC_BROWSER_TEST_F(ProfileChooserViewExtensionsTest
, DISABLED_LockProfile
) {
250 ASSERT_TRUE(profiles::IsMultipleProfilesEnabled());
252 SetupProfilesForLock(browser()->profile());
253 EXPECT_EQ(1U, BrowserList::GetInstance(chrome::GetActiveDesktop())->size());
255 ASSERT_NO_FATAL_FAILURE(OpenProfileChooserView(browser()));
256 AvatarMenu
* menu
= GetProfileChooserViewAvatarMenu();
257 EXPECT_FALSE(menu
->GetItemAt(menu
->GetActiveProfileIndex()).signin_required
);
259 ClickProfileChooserViewLockButton();
260 EXPECT_TRUE(menu
->GetItemAt(menu
->GetActiveProfileIndex()).signin_required
);
262 window_close_observer()->Wait();
263 EXPECT_TRUE(BrowserList::GetInstance(chrome::GetActiveDesktop())->empty());
265 WaitForUserManager();
266 // We need to hide the User Manager or else the process can't die.
270 // Flaky: http://crbug.com/450221
271 // WaitForUserManager()'s RunUntilIdle isn't always sufficient for the
272 // UserManager to be showing.
273 IN_PROC_BROWSER_TEST_F(ProfileChooserViewExtensionsTest
,
274 DISABLED_LockProfileBlockExtensions
) {
275 ASSERT_TRUE(profiles::IsMultipleProfilesEnabled());
276 // Make sure we have at least one enabled extension.
277 extensions::ExtensionRegistry
* registry
=
278 GetPreparedRegistry(browser()->profile());
279 SetupProfilesForLock(browser()->profile());
281 ASSERT_NO_FATAL_FAILURE(OpenProfileChooserView(browser()));
282 ClickProfileChooserViewLockButton();
283 window_close_observer()->Wait();
285 WaitForUserManager();
286 // Assert that the ExtensionService is blocked.
287 ASSERT_EQ(1U, registry
->blocked_extensions().size());
289 // We need to hide the User Manager or else the process can't die.
293 // Flaky: http://crbug.com/450221
294 // WaitForUserManager()'s RunUntilIdle isn't always sufficient for the
295 // UserManager to be showing.
296 IN_PROC_BROWSER_TEST_F(ProfileChooserViewExtensionsTest
,
297 DISABLED_LockProfileNoBlockOtherProfileExtensions
) {
298 ASSERT_TRUE(profiles::IsMultipleProfilesEnabled());
299 // Make sure we have at least one enabled extension.
300 extensions::ExtensionRegistry
* registry
=
301 GetPreparedRegistry(browser()->profile());
302 const size_t total_enabled_extensions
= registry
->enabled_extensions().size();
304 // Create a different profile and then lock it.
305 Profile
*signed_in
= CreateTestingProfile("signed_in");
306 SetupProfilesForLock(signed_in
);
307 extensions::ExtensionSystem::Get(signed_in
)->InitForRegularProfile(true);
308 Browser
* browser_to_lock
= CreateBrowser(signed_in
);
309 EXPECT_EQ(2U, BrowserList::GetInstance(chrome::GetActiveDesktop())->size());
311 ASSERT_NO_FATAL_FAILURE(OpenProfileChooserView(browser_to_lock
));
312 ClickProfileChooserViewLockButton();
313 window_close_observer()->Wait();
314 EXPECT_EQ(1U, BrowserList::GetInstance(chrome::GetActiveDesktop())->size());
316 WaitForUserManager();
317 // Assert that the first profile's extensions are not blocked.
318 ASSERT_EQ(total_enabled_extensions
, registry
->enabled_extensions().size());
319 ASSERT_EQ(0U, registry
->blocked_extensions().size());
321 // We need to hide the User Manager or else the process can't die.