1 // Copyright (c) 2015 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/profiles/profile_window.h"
7 #include "base/command_line.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/app/chrome_command_ids.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/history/history_service_factory.h"
13 #include "chrome/browser/profiles/profile_manager.h"
14 #include "chrome/browser/search_engines/template_url_service_factory.h"
15 #include "chrome/browser/signin/signin_manager_factory.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_finder.h"
18 #include "chrome/browser/ui/browser_list.h"
19 #include "chrome/browser/ui/toolbar/wrench_menu_model.h"
20 #include "chrome/test/base/in_process_browser_test.h"
21 #include "chrome/test/base/ui_test_utils.h"
22 #include "components/history/core/browser/history_db_task.h"
23 #include "components/history/core/browser/history_service.h"
24 #include "components/search_engines/template_url_service.h"
25 #include "components/signin/core/common/profile_management_switches.h"
26 #include "content/public/browser/notification_service.h"
27 #include "content/public/test/browser_test_utils.h"
28 #include "content/public/test/test_utils.h"
29 #include "net/test/spawned_test_server/spawned_test_server.h"
31 // This test verifies the Desktop implementation of Guest only.
32 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) && !defined(OS_IOS)
36 // Code related to history borrowed from:
37 // chrome/browser/history/history_browsertest.cc
39 // Note: WaitableEvent is not used for synchronization between the main thread
40 // and history backend thread because the history subsystem posts tasks back
41 // to the main thread. Had we tried to Signal an event in such a task
42 // and Wait for it on the main thread, the task would not run at all because
43 // the main thread would be blocked on the Wait call, resulting in a deadlock.
45 // A task to be scheduled on the history backend thread.
46 // Notifies the main thread after all history backend thread tasks have run.
47 class WaitForHistoryTask
: public history::HistoryDBTask
{
49 WaitForHistoryTask() {}
51 bool RunOnDBThread(history::HistoryBackend
* backend
,
52 history::HistoryDatabase
* db
) override
{
56 void DoneRunOnMainThread() override
{ base::MessageLoop::current()->Quit(); }
59 ~WaitForHistoryTask() override
{}
61 DISALLOW_COPY_AND_ASSIGN(WaitForHistoryTask
);
64 void WaitForHistoryBackendToRun(Profile
* profile
) {
65 base::CancelableTaskTracker task_tracker
;
66 scoped_ptr
<history::HistoryDBTask
> task(new WaitForHistoryTask());
67 history::HistoryService
* history
= HistoryServiceFactory::GetForProfile(
68 profile
, ServiceAccessType::EXPLICIT_ACCESS
);
69 history
->ScheduleDBTask(task
.Pass(), &task_tracker
);
70 content::RunMessageLoop();
73 class EmptyAcceleratorHandler
: public ui::AcceleratorProvider
{
75 // Don't handle accelerators.
76 bool GetAcceleratorForCommandId(int command_id
,
77 ui::Accelerator
* accelerator
) override
{
84 class ProfileWindowBrowserTest
: public InProcessBrowserTest
{
86 ProfileWindowBrowserTest() {}
87 ~ProfileWindowBrowserTest() override
{}
89 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
90 InProcessBrowserTest::SetUpCommandLine(command_line
);
91 switches::EnableNewAvatarMenuForTesting(
92 base::CommandLine::ForCurrentProcess());
95 Browser
* OpenGuestBrowser();
96 void CloseBrowser(Browser
* browser
);
99 DISALLOW_COPY_AND_ASSIGN(ProfileWindowBrowserTest
);
102 Browser
* ProfileWindowBrowserTest::OpenGuestBrowser() {
103 size_t num_browsers
=
104 BrowserList::GetInstance(chrome::GetActiveDesktop())->size();
106 // Create a guest browser nicely. Using CreateProfile() and CreateBrowser()
107 // does incomplete initialization that would lead to
108 // SystemUrlRequestContextGetter being leaked.
109 content::WindowedNotificationObserver
browser_creation_observer(
110 chrome::NOTIFICATION_BROWSER_WINDOW_READY
,
111 content::NotificationService::AllSources());
112 profiles::SwitchToGuestProfile(chrome::GetActiveDesktop(),
113 ProfileManager::CreateCallback());
115 browser_creation_observer
.Wait();
116 DCHECK_NE(static_cast<Profile
*>(nullptr),
117 g_browser_process
->profile_manager()->GetProfileByPath(
118 ProfileManager::GetGuestProfilePath()));
119 EXPECT_EQ(num_browsers
+ 1,
120 BrowserList::GetInstance(chrome::GetActiveDesktop())->size());
122 Profile
* guest
= g_browser_process
->profile_manager()->GetProfileByPath(
123 ProfileManager::GetGuestProfilePath());
124 Browser
* browser
= chrome::FindAnyBrowser(
125 guest
, true, chrome::GetActiveDesktop());
126 EXPECT_TRUE(browser
);
128 // When |browser| closes a BrowsingDataRemover will be created and executed.
129 // It needs a loaded TemplateUrlService or else it hangs on to a
130 // CallbackList::Subscription forever.
131 ui_test_utils::WaitForTemplateURLServiceToLoad(
132 TemplateURLServiceFactory::GetForProfile(guest
));
137 void ProfileWindowBrowserTest::CloseBrowser(Browser
* browser
) {
138 content::WindowedNotificationObserver
window_close_observer(
139 chrome::NOTIFICATION_BROWSER_CLOSED
,
140 content::Source
<Browser
>(browser
));
141 browser
->window()->Close();
142 window_close_observer
.Wait();
145 IN_PROC_BROWSER_TEST_F(ProfileWindowBrowserTest
, OpenGuestBrowser
) {
146 EXPECT_TRUE(OpenGuestBrowser());
149 IN_PROC_BROWSER_TEST_F(ProfileWindowBrowserTest
, GuestIsIncognito
) {
150 Browser
* guest_browser
= OpenGuestBrowser();
151 EXPECT_TRUE(guest_browser
->profile()->IsOffTheRecord());
154 IN_PROC_BROWSER_TEST_F(ProfileWindowBrowserTest
, GuestIgnoresHistory
) {
155 Browser
* guest_browser
= OpenGuestBrowser();
157 ui_test_utils::WaitForHistoryToLoad(HistoryServiceFactory::GetForProfile(
158 guest_browser
->profile(), ServiceAccessType::EXPLICIT_ACCESS
));
160 GURL test_url
= ui_test_utils::GetTestUrl(
161 base::FilePath(base::FilePath::kCurrentDirectory
),
162 base::FilePath(FILE_PATH_LITERAL("title2.html")));
164 ui_test_utils::NavigateToURL(guest_browser
, test_url
);
165 WaitForHistoryBackendToRun(guest_browser
->profile());
167 std::vector
<GURL
> urls
=
168 ui_test_utils::HistoryEnumerator(guest_browser
->profile()).urls();
169 ASSERT_EQ(0U, urls
.size());
172 IN_PROC_BROWSER_TEST_F(ProfileWindowBrowserTest
, GuestClearsCookies
) {
173 Browser
* guest_browser
= OpenGuestBrowser();
174 Profile
* guest_profile
= guest_browser
->profile();
176 ASSERT_TRUE(test_server()->Start());
177 GURL
url(test_server()->GetURL("set-cookie?cookie1"));
179 // Before navigation there are no cookies for the URL.
180 std::string cookie
= content::GetCookies(guest_profile
, url
);
181 ASSERT_EQ("", cookie
);
183 // After navigation there is a cookie for the URL.
184 ui_test_utils::NavigateToURL(guest_browser
, url
);
185 cookie
= content::GetCookies(guest_profile
, url
);
186 EXPECT_EQ("cookie1", cookie
);
188 CloseBrowser(guest_browser
);
190 // Closing the browser has removed the cookie.
191 cookie
= content::GetCookies(guest_profile
, url
);
192 ASSERT_EQ("", cookie
);
195 IN_PROC_BROWSER_TEST_F(ProfileWindowBrowserTest
, GuestCannotSignin
) {
196 Browser
* guest_browser
= OpenGuestBrowser();
198 SigninManager
* signin_manager
= SigninManagerFactory::GetForProfile(
199 guest_browser
->profile());
201 // Guest profiles can't sign in without a SigninManager.
202 ASSERT_FALSE(signin_manager
);
205 IN_PROC_BROWSER_TEST_F(ProfileWindowBrowserTest
, GuestWrenchLacksBookmarks
) {
206 EmptyAcceleratorHandler accelerator_handler
;
207 // Verify the normal browser has a bookmark menu.
208 WrenchMenuModel
model_normal_profile(&accelerator_handler
, browser());
209 EXPECT_NE(-1, model_normal_profile
.GetIndexOfCommandId(IDC_BOOKMARKS_MENU
));
211 // Guest browser has no bookmark menu.
212 Browser
* guest_browser
= OpenGuestBrowser();
213 WrenchMenuModel
model_guest_profile(&accelerator_handler
, guest_browser
);
214 EXPECT_EQ(-1, model_guest_profile
.GetIndexOfCommandId(IDC_BOOKMARKS_MENU
));
217 #endif // !defined(OS_CHROMEOS) && !defined(OS_ANDROID) && !defined(OS_IOS)