blob: 4d22c5d23c0032b28c23458c4df6cb9749bf703a [file] [log] [blame]
[email protected]fc44f242012-02-14 16:54:391// Copyright (c) 2012 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
[email protected]66791aff2014-04-29 09:45:385#import <Carbon/Carbon.h>
[email protected]fc44f242012-02-14 16:54:396#import <Cocoa/Cocoa.h>
[email protected]66791aff2014-04-29 09:45:387#import <Foundation/Foundation.h>
8#import <Foundation/NSAppleEventDescriptor.h>
9#import <objc/message.h>
10#import <objc/runtime.h>
avie4d7b6f2015-12-26 00:59:1811#include <stddef.h>
[email protected]fc44f242012-02-14 16:54:3912
David Roger51797642018-03-20 13:29:1613#include "base/bind_helpers.h"
[email protected]fc44f242012-02-14 16:54:3914#include "base/command_line.h"
[email protected]66791aff2014-04-29 09:45:3815#include "base/mac/foundation_util.h"
[email protected]a8522032013-06-24 22:51:4616#include "base/mac/scoped_nsobject.h"
thestigaf7f4152014-10-31 23:19:1517#include "base/run_loop.h"
lgarron9e6dee22014-11-18 01:03:3918#include "base/strings/sys_string_conversions.h"
19#include "base/strings/utf_string_conversions.h"
jam3f2d3932017-04-26 20:28:5120#include "base/threading/thread_restrictions.h"
[email protected]fc44f242012-02-14 16:54:3921#include "chrome/app/chrome_command_ids.h"
22#import "chrome/browser/app_controller_mac.h"
Dominick Ng6ff51052018-07-06 05:30:2023#include "chrome/browser/apps/platform_apps/app_browsertest_util.h"
lgarron9e6dee22014-11-18 01:03:3924#include "chrome/browser/bookmarks/bookmark_model_factory.h"
[email protected]dbb03fb2014-02-15 05:36:3325#include "chrome/browser/browser_process.h"
mlerman8ae56aa2015-04-24 13:56:2726#include "chrome/browser/history/history_service_factory.h"
Trent Apted45d9ae22017-11-09 23:12:3227#include "chrome/browser/lifetime/application_lifetime.h"
lwchkg498e92492016-04-23 11:04:1228#include "chrome/browser/profiles/profile_attributes_entry.h"
29#include "chrome/browser/profiles/profile_attributes_storage.h"
[email protected]7108d912014-01-30 08:10:4530#include "chrome/browser/profiles/profile_manager.h"
[email protected]52877dbc62012-06-29 22:22:0331#include "chrome/browser/ui/browser.h"
Trent Apted45d9ae22017-11-09 23:12:3232#include "chrome/browser/ui/browser_finder.h"
[email protected]52877dbc62012-06-29 22:22:0333#include "chrome/browser/ui/browser_list.h"
thestige80821242015-09-30 23:46:0834#include "chrome/browser/ui/browser_navigator_params.h"
[email protected]ee9ccfd42013-07-23 02:31:4735#include "chrome/browser/ui/browser_window.h"
lgarron9e6dee22014-11-18 01:03:3936#include "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h"
mlerman8ae56aa2015-04-24 13:56:2737#include "chrome/browser/ui/cocoa/history_menu_bridge.h"
Christian Dullweber820ee5f2018-04-26 13:24:3138#include "chrome/browser/ui/cocoa/last_active_browser_cocoa.h"
lgrey92aad3c2016-12-10 01:22:1839#include "chrome/browser/ui/cocoa/test/run_loop_testing.h"
kristiparka34b247a2018-03-09 19:05:3440#include "chrome/browser/ui/search/local_ntp_test_utils.h"
[email protected]617ee962013-01-29 20:49:1241#include "chrome/browser/ui/tabs/tab_strip_model.h"
mlermane29d0032014-09-24 19:31:2642#include "chrome/browser/ui/user_manager.h"
Elly Fong-Jones85046032018-04-19 19:15:2843#include "chrome/browser/ui/views_mode_controller.h"
[email protected]7108d912014-01-30 08:10:4544#include "chrome/common/chrome_constants.h"
45#include "chrome/common/chrome_switches.h"
46#include "chrome/common/pref_names.h"
[email protected]66791aff2014-04-29 09:45:3847#include "chrome/common/url_constants.h"
[email protected]fc44f242012-02-14 16:54:3948#include "chrome/test/base/in_process_browser_test.h"
erikchen600f7962014-12-12 00:17:3849#include "chrome/test/base/ui_test_utils.h"
tapted574f09c2015-05-19 13:08:0850#include "components/bookmarks/browser/bookmark_model.h"
lgarron9e6dee22014-11-18 01:03:3951#include "components/bookmarks/test/bookmark_test_helpers.h"
brettwb1fc1b82016-02-02 00:19:0852#include "components/prefs/pref_service.h"
tmartino82e55782017-01-10 22:30:1753#include "content/public/browser/navigation_controller.h"
[email protected]fc44f242012-02-14 16:54:3954#include "content/public/browser/web_contents.h"
erikchen600f7962014-12-12 00:17:3855#include "content/public/test/browser_test_utils.h"
erikchen19ee3922014-10-31 19:14:2256#include "content/public/test/test_navigation_observer.h"
hashimotoad3c6872014-08-29 09:46:5757#include "extensions/browser/app_window/app_window_registry.h"
[email protected]e4452d32013-11-15 23:07:4158#include "extensions/common/extension.h"
lfg910f2f92014-09-19 05:31:0959#include "extensions/test/extension_test_message_listener.h"
[email protected]66791aff2014-04-29 09:45:3860#include "net/test/embedded_test_server/embedded_test_server.h"
Trent Apted45d9ae22017-11-09 23:12:3261#import "ui/events/test/cocoa_test_event_utils.h"
[email protected]66791aff2014-04-29 09:45:3862
Adam Riceff26dcf2017-08-14 05:01:5263using base::SysUTF16ToNSString;
64
[email protected]66791aff2014-04-29 09:45:3865namespace {
66
Scott Violet1f106b582017-07-12 15:49:5867GURL g_open_shortcut_url = GURL::EmptyGURL();
[email protected]66791aff2014-04-29 09:45:3868
erikchen19ee3922014-10-31 19:14:2269// Returns an Apple Event that instructs the application to open |url|.
70NSAppleEventDescriptor* AppleEventToOpenUrl(const GURL& url) {
71 NSAppleEventDescriptor* shortcut_event = [[[NSAppleEventDescriptor alloc]
72 initWithEventClass:kASAppleScriptSuite
73 eventID:kASSubroutineEvent
74 targetDescriptor:nil
75 returnID:kAutoGenerateReturnID
76 transactionID:kAnyTransactionID] autorelease];
77 NSString* url_string = [NSString stringWithUTF8String:url.spec().c_str()];
78 [shortcut_event setParamDescriptor:[NSAppleEventDescriptor
79 descriptorWithString:url_string]
80 forKeyword:keyDirectObject];
81 return shortcut_event;
82}
83
84// Instructs the NSApp's delegate to open |url|.
85void SendAppleEventToOpenUrlToAppController(const GURL& url) {
86 AppController* controller =
87 base::mac::ObjCCast<AppController>([NSApp delegate]);
88 Method get_url =
89 class_getInstanceMethod([controller class], @selector(getUrl:withReply:));
90
91 ASSERT_TRUE(get_url);
92
93 NSAppleEventDescriptor* shortcut_event = AppleEventToOpenUrl(url);
94
95 method_invoke(controller, get_url, shortcut_event, NULL);
96}
97
mlerman8ae56aa2015-04-24 13:56:2798void RunClosureWhenProfileInitialized(const base::Closure& closure,
99 Profile* profile,
100 Profile::CreateStatus status) {
101 if (status == Profile::CREATE_STATUS_INITIALIZED)
102 closure.Run();
103}
104
[email protected]66791aff2014-04-29 09:45:38105} // namespace
106
107@interface TestOpenShortcutOnStartup : NSObject
108- (void)applicationWillFinishLaunching:(NSNotification*)notification;
109@end
110
111@implementation TestOpenShortcutOnStartup
112
113- (void)applicationWillFinishLaunching:(NSNotification*)notification {
Scott Violet1f106b582017-07-12 15:49:58114 if (!g_open_shortcut_url.is_valid())
115 return;
116
erikchen19ee3922014-10-31 19:14:22117 SendAppleEventToOpenUrlToAppController(g_open_shortcut_url);
[email protected]66791aff2014-04-29 09:45:38118}
119
120@end
[email protected]fc44f242012-02-14 16:54:39121
122namespace {
123
Trent Apted45d9ae22017-11-09 23:12:32124using AppControllerBrowserTest = InProcessBrowserTest;
125
Elly Fong-Jones85046032018-04-19 19:15:28126// Returns whether a window's pixels are actually on the screen, which is the
127// case when it and all of its parents are marked visible.
128bool IsReallyVisible(NSWindow* window) {
129 while (window) {
130 if (!window.visible)
131 return false;
132 window = [window parentWindow];
133 }
134 return true;
135}
136
Trent Apted45d9ae22017-11-09 23:12:32137size_t CountVisibleWindows() {
138 size_t count = 0;
139 for (NSWindow* w in [NSApp windows])
Elly Fong-Jones85046032018-04-19 19:15:28140 count = count + (IsReallyVisible(w) ? 1 : 0);
Trent Apted45d9ae22017-11-09 23:12:32141 return count;
142}
143
Elly Fong-Jones85046032018-04-19 19:15:28144// Returns how many visible NSWindows are expected for a given count of browser
Sidney San Martínb247d53f2018-05-23 02:31:21145// windows.
Elly Fong-Jones85046032018-04-19 19:15:28146size_t ExpectedWindowCountForBrowserCount(size_t browsers) {
Elly Fong-Jones85046032018-04-19 19:15:28147 return browsers;
148}
149
Trent Apted45d9ae22017-11-09 23:12:32150// Test browser shutdown with a command in the message queue.
151IN_PROC_BROWSER_TEST_F(AppControllerBrowserTest, CommandDuringShutdown) {
152 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
Elly Fong-Jones85046032018-04-19 19:15:28153 EXPECT_EQ(ExpectedWindowCountForBrowserCount(1), CountVisibleWindows());
Trent Apted45d9ae22017-11-09 23:12:32154
155 chrome::AttemptExit(); // Set chrome::IsTryingToQuit and close all windows.
156
157 // Opening a new window here is fine (unload handlers can also interrupt
158 // exit). But closing the window posts an autorelease on
159 // BrowserWindowController, which calls ~Browser() and, if that was the last
160 // Browser, it invokes applicationWillTerminate: (because IsTryingToQuit is
161 // set). So, verify assumptions then process that autorelease.
162
163 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
Elly Fong-Jones85046032018-04-19 19:15:28164 EXPECT_EQ(ExpectedWindowCountForBrowserCount(0), CountVisibleWindows());
Trent Apted45d9ae22017-11-09 23:12:32165
166 base::RunLoop().RunUntilIdle();
167
168 EXPECT_EQ(0u, chrome::GetTotalBrowserCount());
Elly Fong-Jones85046032018-04-19 19:15:28169 EXPECT_EQ(ExpectedWindowCountForBrowserCount(0), CountVisibleWindows());
Trent Apted45d9ae22017-11-09 23:12:32170
171 NSEvent* cmd_n = cocoa_test_event_utils::KeyEventWithKeyCode(
172 'n', 'n', NSKeyDown, NSCommandKeyMask);
173 [[NSApp mainMenu] performSelector:@selector(performKeyEquivalent:)
174 withObject:cmd_n
175 afterDelay:0];
176 // Let the run loop get flushed, during process cleanup and try not to crash.
177}
178
[email protected]ee9ccfd42013-07-23 02:31:47179class AppControllerPlatformAppBrowserTest
180 : public extensions::PlatformAppBrowserTest {
[email protected]fc44f242012-02-14 16:54:39181 protected:
[email protected]b4207c42013-02-12 06:44:20182 AppControllerPlatformAppBrowserTest()
scottmg0d8e4ab2016-01-28 00:34:55183 : active_browser_list_(BrowserList::GetInstance()) {}
[email protected]fc44f242012-02-14 16:54:39184
avi3ef9ec9e2014-12-22 22:50:17185 void SetUpCommandLine(base::CommandLine* command_line) override {
[email protected]ee9ccfd42013-07-23 02:31:47186 PlatformAppBrowserTest::SetUpCommandLine(command_line);
[email protected]fc44f242012-02-14 16:54:39187 command_line->AppendSwitchASCII(switches::kAppId,
188 "1234");
189 }
[email protected]b4207c42013-02-12 06:44:20190
[email protected]7d1a810b2013-06-26 19:51:59191 const BrowserList* active_browser_list_;
[email protected]fc44f242012-02-14 16:54:39192};
193
194// Test that if only a platform app window is open and no browser windows are
195// open then a reopen event does nothing.
196IN_PROC_BROWSER_TEST_F(AppControllerPlatformAppBrowserTest,
197 PlatformAppReopenWithWindows) {
Owen Minb6e1bf292018-03-15 18:31:52198 AppController* ac = base::mac::ObjCCast<AppController>(
199 [[NSApplication sharedApplication] delegate]);
200 ASSERT_TRUE(ac);
201
[email protected]fc44f242012-02-14 16:54:39202 NSUInteger old_window_count = [[NSApp windows] count];
[email protected]7d1a810b2013-06-26 19:51:59203 EXPECT_EQ(1u, active_browser_list_->size());
[email protected]a25920ee2013-09-05 19:38:49204 [ac applicationShouldHandleReopen:NSApp hasVisibleWindows:YES];
205 // We do not EXPECT_TRUE the result here because the method
206 // deminiaturizes windows manually rather than return YES and have
207 // AppKit do it.
[email protected]fc44f242012-02-14 16:54:39208
[email protected]fc44f242012-02-14 16:54:39209 EXPECT_EQ(old_window_count, [[NSApp windows] count]);
[email protected]7d1a810b2013-06-26 19:51:59210 EXPECT_EQ(1u, active_browser_list_->size());
[email protected]fc44f242012-02-14 16:54:39211}
212
[email protected]2e29e2232013-07-26 10:40:59213IN_PROC_BROWSER_TEST_F(AppControllerPlatformAppBrowserTest,
214 ActivationFocusesBrowserWindow) {
Owen Minb6e1bf292018-03-15 18:31:52215 AppController* app_controller = base::mac::ObjCCast<AppController>(
216 [[NSApplication sharedApplication] delegate]);
217 ASSERT_TRUE(app_controller);
[email protected]2e29e2232013-07-26 10:40:59218
219 ExtensionTestMessageListener listener("Launched", false);
220 const extensions::Extension* app =
221 InstallAndLaunchPlatformApp("minimal");
222 ASSERT_TRUE(listener.WaitUntilSatisfied());
223
hashimotoad3c6872014-08-29 09:46:57224 NSWindow* app_window = extensions::AppWindowRegistry::Get(profile())
[email protected]dbb03fb2014-02-15 05:36:33225 ->GetAppWindowsForApp(app->id())
226 .front()
227 ->GetNativeWindow();
[email protected]2e29e2232013-07-26 10:40:59228 NSWindow* browser_window = browser()->window()->GetNativeWindow();
229
andybons346c7c62015-08-13 15:18:03230 chrome::testing::NSRunLoopRunAllPending();
[email protected]2e29e2232013-07-26 10:40:59231 EXPECT_LE([[NSApp orderedWindows] indexOfObject:app_window],
232 [[NSApp orderedWindows] indexOfObject:browser_window]);
233 [app_controller applicationShouldHandleReopen:NSApp
234 hasVisibleWindows:YES];
andybons346c7c62015-08-13 15:18:03235 chrome::testing::NSRunLoopRunAllPending();
[email protected]2e29e2232013-07-26 10:40:59236 EXPECT_LE([[NSApp orderedWindows] indexOfObject:browser_window],
237 [[NSApp orderedWindows] indexOfObject:app_window]);
238}
239
[email protected]fc44f242012-02-14 16:54:39240class AppControllerWebAppBrowserTest : public InProcessBrowserTest {
241 protected:
[email protected]b4207c42013-02-12 06:44:20242 AppControllerWebAppBrowserTest()
scottmg0d8e4ab2016-01-28 00:34:55243 : active_browser_list_(BrowserList::GetInstance()) {}
[email protected]fc44f242012-02-14 16:54:39244
avi3ef9ec9e2014-12-22 22:50:17245 void SetUpCommandLine(base::CommandLine* command_line) override {
[email protected]90ca44272012-07-18 18:15:48246 command_line->AppendSwitchASCII(switches::kApp, GetAppURL());
[email protected]fc44f242012-02-14 16:54:39247 }
248
249 std::string GetAppURL() const {
250 return "http://example.com/";
251 }
[email protected]b4207c42013-02-12 06:44:20252
[email protected]7d1a810b2013-06-26 19:51:59253 const BrowserList* active_browser_list_;
[email protected]fc44f242012-02-14 16:54:39254};
255
256// Test that in web app mode a reopen event opens the app URL.
257IN_PROC_BROWSER_TEST_F(AppControllerWebAppBrowserTest,
258 WebAppReopenWithNoWindows) {
Owen Minb6e1bf292018-03-15 18:31:52259 AppController* ac = base::mac::ObjCCast<AppController>(
260 [[NSApplication sharedApplication] delegate]);
261 ASSERT_TRUE(ac);
262
[email protected]7d1a810b2013-06-26 19:51:59263 EXPECT_EQ(1u, active_browser_list_->size());
[email protected]fc44f242012-02-14 16:54:39264 BOOL result = [ac applicationShouldHandleReopen:NSApp hasVisibleWindows:NO];
265
266 EXPECT_FALSE(result);
[email protected]7d1a810b2013-06-26 19:51:59267 EXPECT_EQ(2u, active_browser_list_->size());
[email protected]fc44f242012-02-14 16:54:39268
[email protected]7d1a810b2013-06-26 19:51:59269 Browser* browser = active_browser_list_->get(0);
[email protected]617ee962013-01-29 20:49:12270 GURL current_url =
271 browser->tab_strip_model()->GetActiveWebContents()->GetURL();
[email protected]fc44f242012-02-14 16:54:39272 EXPECT_EQ(GetAppURL(), current_url.spec());
273}
274
[email protected]7108d912014-01-30 08:10:45275// Called when the ProfileManager has created a profile.
276void CreateProfileCallback(const base::Closure& quit_closure,
277 Profile* profile,
278 Profile::CreateStatus status) {
279 EXPECT_TRUE(profile);
280 EXPECT_NE(Profile::CREATE_STATUS_LOCAL_FAIL, status);
281 EXPECT_NE(Profile::CREATE_STATUS_REMOTE_FAIL, status);
282 // This will be called multiple times. Wait until the profile is initialized
283 // fully to quit the loop.
284 if (status == Profile::CREATE_STATUS_INITIALIZED)
285 quit_closure.Run();
286}
287
mlermanb8df6e82015-01-23 19:55:34288void CreateAndWaitForSystemProfile() {
[email protected]7108d912014-01-30 08:10:45289 ProfileManager::CreateCallback create_callback =
290 base::Bind(&CreateProfileCallback,
Gabriel Charette87f2bef72018-05-17 20:37:53291 base::RunLoop::QuitCurrentWhenIdleClosureDeprecated());
[email protected]7108d912014-01-30 08:10:45292 g_browser_process->profile_manager()->CreateProfileAsync(
mlermanb8df6e82015-01-23 19:55:34293 ProfileManager::GetSystemProfilePath(),
[email protected]7108d912014-01-30 08:10:45294 create_callback,
295 base::string16(),
lwchkg1f62d242015-10-29 00:50:43296 std::string(),
[email protected]7108d912014-01-30 08:10:45297 std::string());
298 base::RunLoop().Run();
299}
300
301class AppControllerNewProfileManagementBrowserTest
302 : public InProcessBrowserTest {
303 protected:
304 AppControllerNewProfileManagementBrowserTest()
scottmg0d8e4ab2016-01-28 00:34:55305 : active_browser_list_(BrowserList::GetInstance()) {}
[email protected]7108d912014-01-30 08:10:45306
[email protected]7108d912014-01-30 08:10:45307 const BrowserList* active_browser_list_;
308};
309
310// Test that for a regular last profile, a reopen event opens a browser.
311IN_PROC_BROWSER_TEST_F(AppControllerNewProfileManagementBrowserTest,
312 RegularProfileReopenWithNoWindows) {
Owen Minb6e1bf292018-03-15 18:31:52313 AppController* ac = base::mac::ObjCCast<AppController>(
314 [[NSApplication sharedApplication] delegate]);
315 ASSERT_TRUE(ac);
316
[email protected]7108d912014-01-30 08:10:45317 EXPECT_EQ(1u, active_browser_list_->size());
318 BOOL result = [ac applicationShouldHandleReopen:NSApp hasVisibleWindows:NO];
319
320 EXPECT_FALSE(result);
321 EXPECT_EQ(2u, active_browser_list_->size());
mlermane29d0032014-09-24 19:31:26322 EXPECT_FALSE(UserManager::IsShowing());
[email protected]7108d912014-01-30 08:10:45323}
324
325// Test that for a locked last profile, a reopen event opens the User Manager.
326IN_PROC_BROWSER_TEST_F(AppControllerNewProfileManagementBrowserTest,
327 LockedProfileReopenWithNoWindows) {
mlermanb8df6e82015-01-23 19:55:34328 // The User Manager uses the system profile as its underlying profile. To
[email protected]7108d912014-01-30 08:10:45329 // minimize flakiness due to the scheduling/descheduling of tasks on the
330 // different threads, pre-initialize the guest profile before it is needed.
mlermanb8df6e82015-01-23 19:55:34331 CreateAndWaitForSystemProfile();
Owen Minb6e1bf292018-03-15 18:31:52332 AppController* ac = base::mac::ObjCCast<AppController>(
333 [[NSApplication sharedApplication] delegate]);
334 ASSERT_TRUE(ac);
[email protected]7108d912014-01-30 08:10:45335
336 // Lock the active profile.
Francois Doraye6fb2d02017-10-18 21:29:13337 base::ScopedAllowBlockingForTesting allow_blocking;
[email protected]7108d912014-01-30 08:10:45338 Profile* profile = [ac lastProfile];
lwchkg9c183942016-03-13 06:29:54339 ProfileAttributesEntry* entry;
340 ASSERT_TRUE(g_browser_process->profile_manager()->
341 GetProfileAttributesStorage().
342 GetProfileAttributesWithPath(profile->GetPath(), &entry));
343 entry->SetIsSigninRequired(true);
344 EXPECT_TRUE(entry->IsSigninRequired());
[email protected]7108d912014-01-30 08:10:45345
346 EXPECT_EQ(1u, active_browser_list_->size());
347 BOOL result = [ac applicationShouldHandleReopen:NSApp hasVisibleWindows:NO];
348 EXPECT_FALSE(result);
349
350 base::RunLoop().RunUntilIdle();
351 EXPECT_EQ(1u, active_browser_list_->size());
mlermane29d0032014-09-24 19:31:26352 EXPECT_TRUE(UserManager::IsShowing());
353 UserManager::Hide();
[email protected]7108d912014-01-30 08:10:45354}
355
Owen Minb6e1bf292018-03-15 18:31:52356// Test that for a guest last profile, commandDispatch should open UserManager
357// if guest mode is disabled. Note that this test might be flaky under ASAN
358// due to https://crbug.com/674475. Please disable this test under ASAN
359// as the tests below if that happened.
360IN_PROC_BROWSER_TEST_F(AppControllerNewProfileManagementBrowserTest,
361 OpenGuestProfileOnlyIfGuestModeIsEnabled) {
362 CreateAndWaitForSystemProfile();
363 PrefService* local_state = g_browser_process->local_state();
364 local_state->SetString(prefs::kProfileLastUsed, chrome::kGuestProfileDir);
365 local_state->SetBoolean(prefs::kBrowserGuestModeEnabled, false);
366
367 AppController* ac = base::mac::ObjCCast<AppController>(
368 [[NSApplication sharedApplication] delegate]);
369 ASSERT_TRUE(ac);
370
371 base::ScopedAllowBlockingForTesting allow_blocking;
372 Profile* profile = [ac lastProfile];
373 EXPECT_TRUE(profile->IsGuestSession());
374
375 NSMenu* menu = [ac applicationDockMenu:NSApp];
376 ASSERT_TRUE(menu);
377 NSMenuItem* item = [menu itemWithTag:IDC_NEW_WINDOW];
378 ASSERT_TRUE(item);
379 EXPECT_EQ(1u, active_browser_list_->size());
380
381 [ac commandDispatch:item];
382
383 base::RunLoop().RunUntilIdle();
384
385 EXPECT_EQ(1u, active_browser_list_->size());
386 EXPECT_TRUE(UserManager::IsShowing());
387 UserManager::Hide();
388
389 local_state->SetBoolean(prefs::kBrowserGuestModeEnabled, true);
390 [ac commandDispatch:item];
391 base::RunLoop().RunUntilIdle();
392 EXPECT_EQ(2u, active_browser_list_->size());
393 EXPECT_FALSE(UserManager::IsShowing());
394}
395
guidoubbb4787a2016-12-15 12:34:43396#if defined(ADDRESS_SANITIZER)
397// Flaky under ASAN. See https://crbug.com/674475.
398#define MAYBE_GuestProfileReopenWithNoWindows DISABLED_GuestProfileReopenWithNoWindows
399#else
400#define MAYBE_GuestProfileReopenWithNoWindows GuestProfileReopenWithNoWindows
401#endif
[email protected]7108d912014-01-30 08:10:45402// Test that for a guest last profile, a reopen event opens the User Manager.
403IN_PROC_BROWSER_TEST_F(AppControllerNewProfileManagementBrowserTest,
guidoubbb4787a2016-12-15 12:34:43404 MAYBE_GuestProfileReopenWithNoWindows) {
mlermanb8df6e82015-01-23 19:55:34405 // Create the system profile. Set the guest as the last used profile so the
[email protected]7108d912014-01-30 08:10:45406 // app controller can use it on init.
mlermanb8df6e82015-01-23 19:55:34407 CreateAndWaitForSystemProfile();
[email protected]7108d912014-01-30 08:10:45408 PrefService* local_state = g_browser_process->local_state();
409 local_state->SetString(prefs::kProfileLastUsed, chrome::kGuestProfileDir);
410
Owen Minb6e1bf292018-03-15 18:31:52411 AppController* ac = base::mac::ObjCCast<AppController>(
412 [[NSApplication sharedApplication] delegate]);
413 ASSERT_TRUE(ac);
[email protected]7108d912014-01-30 08:10:45414
Francois Doraye6fb2d02017-10-18 21:29:13415 base::ScopedAllowBlockingForTesting allow_blocking;
[email protected]7108d912014-01-30 08:10:45416 Profile* profile = [ac lastProfile];
417 EXPECT_EQ(ProfileManager::GetGuestProfilePath(), profile->GetPath());
418 EXPECT_TRUE(profile->IsGuestSession());
419
420 EXPECT_EQ(1u, active_browser_list_->size());
421 BOOL result = [ac applicationShouldHandleReopen:NSApp hasVisibleWindows:NO];
422 EXPECT_FALSE(result);
423
424 base::RunLoop().RunUntilIdle();
425
426 EXPECT_EQ(1u, active_browser_list_->size());
mlermane29d0032014-09-24 19:31:26427 EXPECT_TRUE(UserManager::IsShowing());
428 UserManager::Hide();
[email protected]7108d912014-01-30 08:10:45429}
430
guidoubbb4787a2016-12-15 12:34:43431#if defined(ADDRESS_SANITIZER)
432// Flaky under ASAN. See https://crbug.com/674475.
433#define MAYBE_AboutChromeForcesUserManager DISABLED_AboutChromeForcesUserManager
434#else
435#define MAYBE_AboutChromeForcesUserManager AboutChromeForcesUserManager
436#endif
mlermane6e040a2014-10-31 00:53:21437IN_PROC_BROWSER_TEST_F(AppControllerNewProfileManagementBrowserTest,
guidoubbb4787a2016-12-15 12:34:43438 MAYBE_AboutChromeForcesUserManager) {
Owen Minb6e1bf292018-03-15 18:31:52439 AppController* ac = base::mac::ObjCCast<AppController>(
440 [[NSApplication sharedApplication] delegate]);
441 ASSERT_TRUE(ac);
mlermane6e040a2014-10-31 00:53:21442
443 // Create the guest profile, and set it as the last used profile so the
444 // app controller can use it on init.
mlermanb8df6e82015-01-23 19:55:34445 CreateAndWaitForSystemProfile();
mlermane6e040a2014-10-31 00:53:21446 PrefService* local_state = g_browser_process->local_state();
447 local_state->SetString(prefs::kProfileLastUsed, chrome::kGuestProfileDir);
448
449 // Prohibiting guest mode forces the user manager flow for About Chrome.
450 local_state->SetBoolean(prefs::kBrowserGuestModeEnabled, false);
451
Francois Doraye6fb2d02017-10-18 21:29:13452 base::ScopedAllowBlockingForTesting allow_blocking;
mlermane6e040a2014-10-31 00:53:21453 Profile* guest_profile = [ac lastProfile];
454 EXPECT_EQ(ProfileManager::GetGuestProfilePath(), guest_profile->GetPath());
455 EXPECT_TRUE(guest_profile->IsGuestSession());
456
457 // Tell the browser to open About Chrome.
458 EXPECT_EQ(1u, active_browser_list_->size());
459 [ac orderFrontStandardAboutPanel:NSApp];
460
461 base::RunLoop().RunUntilIdle();
462
463 // No new browser is opened; the User Manager opens instead.
464 EXPECT_EQ(1u, active_browser_list_->size());
465 EXPECT_TRUE(UserManager::IsShowing());
466
467 UserManager::Hide();
468}
469
[email protected]66791aff2014-04-29 09:45:38470class AppControllerOpenShortcutBrowserTest : public InProcessBrowserTest {
471 protected:
472 AppControllerOpenShortcutBrowserTest() {
473 }
474
Daniel Chenga542fca2014-10-21 09:51:29475 void SetUpInProcessBrowserTestFixture() override {
[email protected]66791aff2014-04-29 09:45:38476 // In order to mimic opening shortcut during browser startup, we need to
477 // send the event before -applicationDidFinishLaunching is called, but
478 // after AppController is loaded.
479 //
480 // Since -applicationWillFinishLaunching does nothing now, we swizzle it to
481 // our function to send the event. We need to do this early before running
482 // the main message loop.
483 //
484 // NSApp does not exist yet. We need to get the AppController using
485 // reflection.
486 Class appControllerClass = NSClassFromString(@"AppController");
487 Class openShortcutClass = NSClassFromString(@"TestOpenShortcutOnStartup");
488
489 ASSERT_TRUE(appControllerClass != nil);
490 ASSERT_TRUE(openShortcutClass != nil);
491
492 SEL targetMethod = @selector(applicationWillFinishLaunching:);
493 Method original = class_getInstanceMethod(appControllerClass,
494 targetMethod);
495 Method destination = class_getInstanceMethod(openShortcutClass,
496 targetMethod);
497
498 ASSERT_TRUE(original != NULL);
499 ASSERT_TRUE(destination != NULL);
500
501 method_exchangeImplementations(original, destination);
Scott Violet1f106b582017-07-12 15:49:58502
503 ASSERT_TRUE(embedded_test_server()->Start());
504 g_open_shortcut_url = embedded_test_server()->GetURL("/simple.html");
[email protected]66791aff2014-04-29 09:45:38505 }
506
avi3ef9ec9e2014-12-22 22:50:17507 void SetUpCommandLine(base::CommandLine* command_line) override {
[email protected]66791aff2014-04-29 09:45:38508 // If the arg is empty, PrepareTestCommandLine() after this function will
509 // append about:blank as default url.
510 command_line->AppendArg(chrome::kChromeUINewTabURL);
511 }
512};
513
514IN_PROC_BROWSER_TEST_F(AppControllerOpenShortcutBrowserTest,
515 OpenShortcutOnStartup) {
tmartino82e55782017-01-10 22:30:17516 // The two tabs expected are the Welcome page and the desired URL.
517 EXPECT_EQ(2, browser()->tab_strip_model()->count());
[email protected]66791aff2014-04-29 09:45:38518 EXPECT_EQ(g_open_shortcut_url,
519 browser()->tab_strip_model()->GetActiveWebContents()
520 ->GetLastCommittedURL());
521}
522
erikchen19ee3922014-10-31 19:14:22523class AppControllerReplaceNTPBrowserTest : public InProcessBrowserTest {
524 protected:
525 AppControllerReplaceNTPBrowserTest() {}
526
527 void SetUpInProcessBrowserTestFixture() override {
svaldeza01f7d92015-11-18 17:47:56528 ASSERT_TRUE(embedded_test_server()->Start());
erikchen19ee3922014-10-31 19:14:22529 }
530
avi3ef9ec9e2014-12-22 22:50:17531 void SetUpCommandLine(base::CommandLine* command_line) override {
erikchen19ee3922014-10-31 19:14:22532 // If the arg is empty, PrepareTestCommandLine() after this function will
533 // append about:blank as default url.
534 command_line->AppendArg(chrome::kChromeUINewTabURL);
535 }
536};
537
538// Tests that when a GURL is opened after startup, it replaces the NTP.
539IN_PROC_BROWSER_TEST_F(AppControllerReplaceNTPBrowserTest,
540 ReplaceNTPAfterStartup) {
kristiparka34b247a2018-03-09 19:05:34541 // Depending on network connectivity, the NTP URL can either be
542 // chrome://newtab/ or chrome-search://local-ntp/local-ntp.html. See
543 // local_ntp_test_utils::GetFinalNtpUrl for more details.
544 std::string expected_url =
545 local_ntp_test_utils::GetFinalNtpUrl(browser()->profile()).spec();
546
erikchen19ee3922014-10-31 19:14:22547 // Ensure that there is exactly 1 tab showing, and the tab is the NTP.
kristiparka34b247a2018-03-09 19:05:34548 GURL ntp(expected_url);
erikchen19ee3922014-10-31 19:14:22549 EXPECT_EQ(1, browser()->tab_strip_model()->count());
tmartino82e55782017-01-10 22:30:17550 browser()->tab_strip_model()->GetActiveWebContents()->GetController().LoadURL(
kristiparka34b247a2018-03-09 19:05:34551 GURL(expected_url), content::Referrer(),
tmartino82e55782017-01-10 22:30:17552 ui::PageTransition::PAGE_TRANSITION_LINK, std::string());
553
554 // Wait for one navigation on the active web contents.
555 content::TestNavigationObserver ntp_navigation_observer(
556 browser()->tab_strip_model()->GetActiveWebContents());
557 ntp_navigation_observer.Wait();
558
erikchen19ee3922014-10-31 19:14:22559 EXPECT_EQ(ntp,
560 browser()
561 ->tab_strip_model()
562 ->GetActiveWebContents()
563 ->GetLastCommittedURL());
564
565 GURL simple(embedded_test_server()->GetURL("/simple.html"));
566 SendAppleEventToOpenUrlToAppController(simple);
567
erikchen19ee3922014-10-31 19:14:22568 EXPECT_EQ(1, browser()->tab_strip_model()->count());
tmartino82e55782017-01-10 22:30:17569 content::TestNavigationObserver event_navigation_observer(
570 browser()->tab_strip_model()->GetActiveWebContents());
571 event_navigation_observer.Wait();
erikchen19ee3922014-10-31 19:14:22572
573 EXPECT_EQ(simple,
574 browser()
575 ->tab_strip_model()
576 ->GetActiveWebContents()
577 ->GetLastCommittedURL());
578}
579
Christian Dullweber820ee5f2018-04-26 13:24:31580// Tests that when a GURL is opened, it is not opened in incognito mode.
581IN_PROC_BROWSER_TEST_F(AppControllerBrowserTest, OpenInRegularBrowser) {
582 ASSERT_TRUE(embedded_test_server()->Start());
583 // Create an incognito browser.
584 Browser* incognito_browser = CreateIncognitoBrowser(browser()->profile());
585 EXPECT_EQ(incognito_browser, chrome::GetLastActiveBrowser());
586 EXPECT_EQ(1, browser()->tab_strip_model()->count());
587 EXPECT_EQ(1, incognito_browser->tab_strip_model()->count());
588 // Open a url.
589 GURL simple(embedded_test_server()->GetURL("/simple.html"));
590 SendAppleEventToOpenUrlToAppController(simple);
591 // It should be opened in the regular browser.
592 content::TestNavigationObserver event_navigation_observer(
593 browser()->tab_strip_model()->GetActiveWebContents());
594 event_navigation_observer.Wait();
595 EXPECT_EQ(2, browser()->tab_strip_model()->count());
596 EXPECT_EQ(1, incognito_browser->tab_strip_model()->count());
597 EXPECT_EQ(simple, browser()
598 ->tab_strip_model()
599 ->GetActiveWebContents()
600 ->GetLastCommittedURL());
601}
602
lgarron9e6dee22014-11-18 01:03:39603class AppControllerMainMenuBrowserTest : public InProcessBrowserTest {
604 protected:
605 AppControllerMainMenuBrowserTest() {
606 }
607};
608
609IN_PROC_BROWSER_TEST_F(AppControllerMainMenuBrowserTest,
mlerman8ae56aa2015-04-24 13:56:27610 HistoryMenuResetAfterProfileDeletion) {
611 ProfileManager* profile_manager = g_browser_process->profile_manager();
tapted676995d2016-04-18 11:32:29612 AppController* ac =
613 base::mac::ObjCCastStrict<AppController>([NSApp delegate]);
mlerman8ae56aa2015-04-24 13:56:27614
615 // Use the existing profile as profile 1.
616 Profile* profile1 = browser()->profile();
617
618 // Create profile 2.
619 base::FilePath profile2_path =
620 profile_manager->GenerateNextProfileDirectoryPath();
621 base::RunLoop run_loop;
622 profile_manager->CreateProfileAsync(
623 profile2_path,
624 base::Bind(&RunClosureWhenProfileInitialized,
625 run_loop.QuitClosure()),
lwchkg1f62d242015-10-29 00:50:43626 base::string16(),
627 std::string(),
628 std::string());
mlerman8ae56aa2015-04-24 13:56:27629 run_loop.Run();
630 Profile* profile2 = profile_manager->GetProfileByPath(profile2_path);
631 ASSERT_TRUE(profile2);
632
Sidney San Martínaa3b48f2018-06-03 08:10:05633 // Load profile1's History Service backend so it will be assigned to the
634 // HistoryMenuBridge when windowChangedToProfile is called, or else this test
635 // will fail flaky.
636 ui_test_utils::WaitForHistoryToLoad(HistoryServiceFactory::GetForProfile(
637 profile1, ServiceAccessType::EXPLICIT_ACCESS));
mlerman8ae56aa2015-04-24 13:56:27638 // Switch the controller to profile1.
639 [ac windowChangedToProfile:profile1];
640 base::RunLoop().RunUntilIdle();
641
642 // Verify the controller's History Menu corresponds to profile1.
643 EXPECT_TRUE([ac historyMenuBridge]->service());
644 EXPECT_EQ([ac historyMenuBridge]->service(),
645 HistoryServiceFactory::GetForProfile(profile1,
646 ServiceAccessType::EXPLICIT_ACCESS));
647
648 // Load profile2's History Service backend so it will be assigned to the
649 // HistoryMenuBridge when windowChangedToProfile is called, or else this test
650 // will fail flaky.
651 ui_test_utils::WaitForHistoryToLoad(
652 HistoryServiceFactory::GetForProfile(profile2,
653 ServiceAccessType::EXPLICIT_ACCESS));
654 // Switch the controller to profile2.
655 [ac windowChangedToProfile:profile2];
656 base::RunLoop().RunUntilIdle();
657
658 // Verify the controller's History Menu has changed.
659 EXPECT_TRUE([ac historyMenuBridge]->service());
660 EXPECT_EQ([ac historyMenuBridge]->service(),
661 HistoryServiceFactory::GetForProfile(profile2,
662 ServiceAccessType::EXPLICIT_ACCESS));
663 EXPECT_NE(
664 HistoryServiceFactory::GetForProfile(profile1,
665 ServiceAccessType::EXPLICIT_ACCESS),
666 HistoryServiceFactory::GetForProfile(profile2,
667 ServiceAccessType::EXPLICIT_ACCESS));
668
669 // Delete profile2.
David Roger51797642018-03-20 13:29:16670 profile_manager->ScheduleProfileForDeletion(profile2->GetPath(),
671 base::DoNothing());
mlerman8ae56aa2015-04-24 13:56:27672 base::RunLoop().RunUntilIdle();
673
674 // Verify the controller's history is back to profile1.
675 EXPECT_EQ([ac historyMenuBridge]->service(),
676 HistoryServiceFactory::GetForProfile(profile1,
677 ServiceAccessType::EXPLICIT_ACCESS));
678}
679
680IN_PROC_BROWSER_TEST_F(AppControllerMainMenuBrowserTest,
lgarron9e6dee22014-11-18 01:03:39681 BookmarksMenuIsRestoredAfterProfileSwitch) {
682 ProfileManager* profile_manager = g_browser_process->profile_manager();
Owen Minb6e1bf292018-03-15 18:31:52683 AppController* ac = base::mac::ObjCCast<AppController>(
684 [[NSApplication sharedApplication] delegate]);
685 ASSERT_TRUE(ac);
686
Robert Sesek124f80f92018-07-24 20:31:29687 [ac mainMenuCreated];
lgarron9e6dee22014-11-18 01:03:39688
689 // Constants for bookmarks that we will create later.
690 const base::string16 title1(base::ASCIIToUTF16("Dinosaur Comics"));
691 const GURL url1("http://qwantz.com//");
692
693 const base::string16 title2(base::ASCIIToUTF16("XKCD"));
694 const GURL url2("https://www.xkcd.com/");
695
696 // Use the existing profile as profile 1.
697 Profile* profile1 = browser()->profile();
698 bookmarks::test::WaitForBookmarkModelToLoad(
pke3e0d5c92016-08-08 09:07:30699 BookmarkModelFactory::GetForBrowserContext(profile1));
lgarron9e6dee22014-11-18 01:03:39700
701 // Create profile 2.
Francois Doraye6fb2d02017-10-18 21:29:13702 base::ScopedAllowBlockingForTesting allow_blocking;
lgarron9e6dee22014-11-18 01:03:39703 base::FilePath path2 = profile_manager->GenerateNextProfileDirectoryPath();
704 Profile* profile2 =
705 Profile::CreateProfile(path2, NULL, Profile::CREATE_MODE_SYNCHRONOUS);
706 profile_manager->RegisterTestingProfile(profile2, false, true);
707 bookmarks::test::WaitForBookmarkModelToLoad(
pke3e0d5c92016-08-08 09:07:30708 BookmarkModelFactory::GetForBrowserContext(profile2));
lgarron9e6dee22014-11-18 01:03:39709
710 // Switch to profile 1, create bookmark 1 and force the menu to build.
711 [ac windowChangedToProfile:profile1];
712 [ac bookmarkMenuBridge]->GetBookmarkModel()->AddURL(
713 [ac bookmarkMenuBridge]->GetBookmarkModel()->bookmark_bar_node(),
714 0, title1, url1);
Trent Aptedcf95689a2017-11-22 00:01:10715 NSMenu* profile1_submenu = [ac bookmarkMenuBridge]->BookmarkMenu();
716 [[profile1_submenu delegate] menuNeedsUpdate:profile1_submenu];
lgarron9e6dee22014-11-18 01:03:39717
718 // Switch to profile 2, create bookmark 2 and force the menu to build.
719 [ac windowChangedToProfile:profile2];
720 [ac bookmarkMenuBridge]->GetBookmarkModel()->AddURL(
721 [ac bookmarkMenuBridge]->GetBookmarkModel()->bookmark_bar_node(),
722 0, title2, url2);
Trent Aptedcf95689a2017-11-22 00:01:10723 NSMenu* profile2_submenu = [ac bookmarkMenuBridge]->BookmarkMenu();
724 [[profile2_submenu delegate] menuNeedsUpdate:profile2_submenu];
725 EXPECT_NE(profile1_submenu, profile2_submenu);
lgarron9e6dee22014-11-18 01:03:39726
727 // Test that only bookmark 2 is shown.
728 EXPECT_FALSE([[ac bookmarkMenuBridge]->BookmarkMenu() itemWithTitle:
729 SysUTF16ToNSString(title1)]);
730 EXPECT_TRUE([[ac bookmarkMenuBridge]->BookmarkMenu() itemWithTitle:
731 SysUTF16ToNSString(title2)]);
732
733 // Switch *back* to profile 1 and *don't* force the menu to build.
734 [ac windowChangedToProfile:profile1];
735
736 // Test that only bookmark 1 is shown in the restored menu.
737 EXPECT_TRUE([[ac bookmarkMenuBridge]->BookmarkMenu() itemWithTitle:
738 SysUTF16ToNSString(title1)]);
739 EXPECT_FALSE([[ac bookmarkMenuBridge]->BookmarkMenu() itemWithTitle:
740 SysUTF16ToNSString(title2)]);
Trent Aptedcf95689a2017-11-22 00:01:10741
742 // Ensure a cached menu was used.
743 EXPECT_EQ(profile1_submenu, [ac bookmarkMenuBridge]->BookmarkMenu());
lgarron9e6dee22014-11-18 01:03:39744}
745
[email protected]fc44f242012-02-14 16:54:39746} // namespace
erikchen600f7962014-12-12 00:17:38747
748//--------------------------AppControllerHandoffBrowserTest---------------------
749
750static GURL g_handoff_url;
751
752@interface AppController (BrowserTest)
753- (BOOL)new_shouldUseHandoff;
754- (void)new_passURLToHandoffManager:(const GURL&)handoffURL;
755@end
756
757@implementation AppController (BrowserTest)
758- (BOOL)new_shouldUseHandoff {
759 return YES;
760}
761
762- (void)new_passURLToHandoffManager:(const GURL&)handoffURL {
763 g_handoff_url = handoffURL;
764}
765@end
766
767namespace {
768
769class AppControllerHandoffBrowserTest : public InProcessBrowserTest {
770 protected:
771 AppControllerHandoffBrowserTest() {}
772
773 // Exchanges the implementations of the two selectors on the class
774 // AppController.
775 void ExchangeSelectors(SEL originalMethod, SEL newMethod) {
776 Class appControllerClass = NSClassFromString(@"AppController");
777
778 ASSERT_TRUE(appControllerClass != nil);
779
780 Method original =
781 class_getInstanceMethod(appControllerClass, originalMethod);
782 Method destination = class_getInstanceMethod(appControllerClass, newMethod);
783
784 ASSERT_TRUE(original != NULL);
785 ASSERT_TRUE(destination != NULL);
786
787 method_exchangeImplementations(original, destination);
788 }
789
790 // Swizzle Handoff related implementations.
791 void SetUpInProcessBrowserTestFixture() override {
792 // Handoff is only available on OSX 10.10+. This swizzle makes the logic
793 // run on all OSX versions.
794 SEL originalMethod = @selector(shouldUseHandoff);
795 SEL newMethod = @selector(new_shouldUseHandoff);
796 ExchangeSelectors(originalMethod, newMethod);
797
798 // This swizzle intercepts the URL that would be sent to the Handoff
799 // Manager, and instead puts it into a variable accessible to this test.
800 originalMethod = @selector(passURLToHandoffManager:);
801 newMethod = @selector(new_passURLToHandoffManager:);
802 ExchangeSelectors(originalMethod, newMethod);
803 }
804
805 // Closes the tab, and waits for the close to finish.
806 void CloseTab(Browser* browser, int index) {
807 content::WebContentsDestroyedWatcher destroyed_watcher(
808 browser->tab_strip_model()->GetWebContentsAt(index));
809 browser->tab_strip_model()->CloseWebContentsAt(
810 index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
811 destroyed_watcher.Wait();
812 }
813};
814
815// Tests that as a user switches between tabs, navigates within a tab, and
816// switches between browser windows, the correct URL is being passed to the
817// Handoff.
818IN_PROC_BROWSER_TEST_F(AppControllerHandoffBrowserTest, TestHandoffURLs) {
svaldeza01f7d92015-11-18 17:47:56819 ASSERT_TRUE(embedded_test_server()->Start());
erikchen600f7962014-12-12 00:17:38820 EXPECT_EQ(g_handoff_url, GURL(url::kAboutBlankURL));
821
822 // Test that navigating to a URL updates the handoff URL.
823 GURL test_url1 = embedded_test_server()->GetURL("/title1.html");
824 ui_test_utils::NavigateToURL(browser(), test_url1);
825 EXPECT_EQ(g_handoff_url, test_url1);
826
827 // Test that opening a new tab updates the handoff URL.
828 GURL test_url2 = embedded_test_server()->GetURL("/title2.html");
cm.sanchi2522bc92017-12-04 08:04:13829 NavigateParams params(browser(), test_url2, ui::PAGE_TRANSITION_LINK);
nick3b04f322016-08-31 19:29:19830 params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
erikchen600f7962014-12-12 00:17:38831 ui_test_utils::NavigateToURL(&params);
832 EXPECT_EQ(g_handoff_url, test_url2);
833
834 // Test that switching tabs updates the handoff URL.
835 browser()->tab_strip_model()->ActivateTabAt(0, true);
836 EXPECT_EQ(g_handoff_url, test_url1);
837
838 // Test that closing the current tab updates the handoff URL.
839 CloseTab(browser(), 0);
840 EXPECT_EQ(g_handoff_url, test_url2);
841
842 // Test that opening a new browser window updates the handoff URL.
843 GURL test_url3 = embedded_test_server()->GetURL("/title3.html");
844 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19845 browser(), GURL(test_url3), WindowOpenDisposition::NEW_WINDOW,
erikchen600f7962014-12-12 00:17:38846 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
847 EXPECT_EQ(g_handoff_url, test_url3);
848
849 // Check that there are exactly 2 browsers.
scottmg0d8e4ab2016-01-28 00:34:55850 BrowserList* active_browser_list = BrowserList::GetInstance();
erikchen600f7962014-12-12 00:17:38851 EXPECT_EQ(2u, active_browser_list->size());
852
erikchen64a6d442015-07-10 19:38:20853 // Close the second browser window (which only has 1 tab left).
erikchen600f7962014-12-12 00:17:38854 Browser* browser2 = active_browser_list->get(1);
erikchen64a6d442015-07-10 19:38:20855 CloseBrowserSynchronously(browser2);
erikchen600f7962014-12-12 00:17:38856 EXPECT_EQ(g_handoff_url, test_url2);
857
858 // The URLs of incognito windows should not be passed to Handoff.
859 GURL test_url4 = embedded_test_server()->GetURL("/simple.html");
860 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19861 browser(), GURL(test_url4), WindowOpenDisposition::OFF_THE_RECORD,
erikchen600f7962014-12-12 00:17:38862 ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
863 EXPECT_EQ(g_handoff_url, GURL());
864
865 // Open a new tab in the incognito window.
866 EXPECT_EQ(2u, active_browser_list->size());
867 Browser* browser3 = active_browser_list->get(1);
868 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19869 browser3, test_url4, WindowOpenDisposition::NEW_FOREGROUND_TAB,
erikchen600f7962014-12-12 00:17:38870 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
871 EXPECT_EQ(g_handoff_url, GURL());
872
873 // Navigate the current tab in the incognito window.
thestig53986dc2014-12-16 06:09:18874 ui_test_utils::NavigateToURL(browser3, test_url1);
erikchen600f7962014-12-12 00:17:38875 EXPECT_EQ(g_handoff_url, GURL());
876
877 // Activate the original browser window.
878 Browser* browser1 = active_browser_list->get(0);
879 browser1->window()->Show();
880 EXPECT_EQ(g_handoff_url, test_url2);
881}
882
883} // namespace