blob: 758b2abb0cf2d8164fa9f5f5a30913cec3fd32f0 [file] [log] [blame]
[email protected]3cac87232012-11-20 01:48:271// 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
5#include "chrome/browser/ui/browser_command_controller.h"
6
mlerman67fa17a2015-02-13 21:59:227#include "base/command_line.h"
avi655876a2015-12-25 07:18:158#include "base/macros.h"
fdorayfd4c7ba2016-06-10 17:44:369#include "base/run_loop.h"
Haeun Kim3f6123502018-08-26 18:03:0410#include "base/stl_util.h"
avi655876a2015-12-25 07:18:1511#include "build/build_config.h"
[email protected]3cac87232012-11-20 01:48:2712#include "chrome/app/chrome_command_ids.h"
mlerman67fa17a2015-02-13 21:59:2213#include "chrome/browser/browser_process.h"
mlerman67fa17a2015-02-13 21:59:2214#include "chrome/browser/profiles/profile_manager.h"
15#include "chrome/browser/profiles/profile_window.h"
16#include "chrome/browser/search_engines/template_url_service_factory.h"
Cliff Smolinsky2c9586e2019-02-08 18:48:3017#include "chrome/browser/sessions/tab_restore_service_factory.h"
18#include "chrome/browser/sessions/tab_restore_service_load_waiter.h"
[email protected]57892182012-12-03 19:15:3919#include "chrome/browser/ui/browser.h"
[email protected]3cac87232012-11-20 01:48:2720#include "chrome/browser/ui/browser_commands.h"
mlerman67fa17a2015-02-13 21:59:2221#include "chrome/browser/ui/browser_finder.h"
22#include "chrome/browser/ui/browser_list.h"
23#include "chrome/browser/ui/browser_window.h"
24#include "chrome/browser/ui/startup/startup_browser_creator.h"
[email protected]3cac87232012-11-20 01:48:2725#include "chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h"
[email protected]57892182012-12-03 19:15:3926#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]3cac87232012-11-20 01:48:2727#include "chrome/test/base/in_process_browser_test.h"
Cliff Smolinsky2c9586e2019-02-08 18:48:3028#include "chrome/test/base/ui_test_utils.h"
mlerman67fa17a2015-02-13 21:59:2229#include "components/search_engines/template_url_service.h"
Cliff Smolinsky2c9586e2019-02-08 18:48:3030#include "components/sessions/core/tab_restore_service.h"
31#include "components/sessions/core/tab_restore_service_observer.h"
Colin Blundellac55c9972018-11-07 15:30:3332#include "components/signin/core/browser/account_consistency_method.h"
[email protected]51a24782013-02-06 06:50:2333#include "content/public/test/test_utils.h"
[email protected]3cac87232012-11-20 01:48:2734
mlerman67fa17a2015-02-13 21:59:2235#if defined(OS_CHROMEOS)
Xiyuan Xia4f992f22019-06-05 15:33:4636#include "ash/public/cpp/window_pin_type.h"
Ivan Sandrk9669d0e2017-12-15 23:50:2037#include "ash/public/cpp/window_properties.h"
Steven Bennetts38e9bde22019-01-03 17:31:1038#include "chromeos/constants/chromeos_switches.h"
Ivan Sandrk9669d0e2017-12-15 23:50:2039#include "ui/aura/window.h"
mlerman67fa17a2015-02-13 21:59:2240#endif
41
Ivan Sandrk9669d0e2017-12-15 23:50:2042namespace chrome {
43
Aran Gilmand217b5b2019-04-11 17:45:4344class BrowserCommandControllerBrowserTest : public InProcessBrowserTest {
mlerman67fa17a2015-02-13 21:59:2245 public:
46 BrowserCommandControllerBrowserTest() {}
47 ~BrowserCommandControllerBrowserTest() override {}
48
49 void SetUpCommandLine(base::CommandLine* command_line) override {
mlerman67fa17a2015-02-13 21:59:2250#if defined(OS_CHROMEOS)
51 command_line->AppendSwitch(
52 chromeos::switches::kIgnoreUserProfileMappingForTests);
53#endif
54 }
55
56 private:
57 DISALLOW_COPY_AND_ASSIGN(BrowserCommandControllerBrowserTest);
58};
[email protected]3cac87232012-11-20 01:48:2759
60// Verify that showing a constrained window disables find.
61IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest, DisableFind) {
62 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_FIND));
63
64 // Showing constrained window should disable find.
[email protected]57892182012-12-03 19:15:3965 content::WebContents* web_contents =
66 browser()->tab_strip_model()->GetActiveWebContents();
Jeremy Chinsene54596432019-05-29 00:18:4667 auto delegate = std::make_unique<MockTabModalConfirmDialogDelegate>(
68 web_contents, nullptr);
69 MockTabModalConfirmDialogDelegate* delegate_ptr = delegate.get();
70 TabModalConfirmDialog::Create(std::move(delegate), web_contents);
[email protected]3cac87232012-11-20 01:48:2771 EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_FIND));
72
73 // Switching to a new (unblocked) tab should reenable it.
74 AddBlankTabAndShow(browser());
75 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_FIND));
76
77 // Switching back to the blocked tab should disable it again.
Edwin Joe6f6fc1e2019-02-27 20:00:3778 browser()->tab_strip_model()->ActivateTabAt(0);
[email protected]3cac87232012-11-20 01:48:2779 EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_FIND));
80
81 // Closing the constrained window should reenable it.
Jeremy Chinsene54596432019-05-29 00:18:4682 delegate_ptr->Cancel();
[email protected]51a24782013-02-06 06:50:2383 content::RunAllPendingInMessageLoop();
[email protected]3cac87232012-11-20 01:48:2784 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_FIND));
85}
mlerman67fa17a2015-02-13 21:59:2286
87// Note that a Browser's destructor, when the browser's profile is guest, will
88// create and execute a BrowsingDataRemover.
jamdb04346c2015-04-23 00:06:4489// Flakes http://crbug.com/471953
mlerman67fa17a2015-02-13 21:59:2290IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest,
jamdb04346c2015-04-23 00:06:4491 DISABLED_NewAvatarMenuEnabledInGuestMode) {
scottmg0d8e4ab2016-01-28 00:34:5592 EXPECT_EQ(1U, BrowserList::GetInstance()->size());
mlerman67fa17a2015-02-13 21:59:2293
94 // Create a guest browser nicely. Using CreateProfile() and CreateBrowser()
95 // does incomplete initialization that would lead to
96 // SystemUrlRequestContextGetter being leaked.
scottmgff189b62016-02-11 19:47:1697 profiles::SwitchToGuestProfile(ProfileManager::CreateCallback());
Evan Stade4487c452019-07-11 00:58:0698 ui_test_utils::WaitForBrowserToOpen();
scottmg0d8e4ab2016-01-28 00:34:5599 EXPECT_EQ(2U, BrowserList::GetInstance()->size());
mlerman67fa17a2015-02-13 21:59:22100
101 // Access the browser that was created for the new Guest Profile.
102 Profile* guest = g_browser_process->profile_manager()->GetProfileByPath(
103 ProfileManager::GetGuestProfilePath());
scottmg34c5dd882016-02-03 05:21:54104 Browser* browser = chrome::FindAnyBrowser(guest, true);
mlerman67fa17a2015-02-13 21:59:22105 EXPECT_TRUE(browser);
106
107 // The BrowsingDataRemover needs a loaded TemplateUrlService or else it hangs
108 // on to a CallbackList::Subscription forever.
109 TemplateURLServiceFactory::GetForProfile(guest)->set_loaded(true);
110
Ivan Sandrk9669d0e2017-12-15 23:50:20111 const CommandUpdater* command_updater = browser->command_controller();
Aran Gilmand217b5b2019-04-11 17:45:43112#if defined(OS_CHROMEOS)
113 // Chrome OS uses system tray menu to handle multi-profiles.
114 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_SHOW_AVATAR_MENU));
115#else
116 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_AVATAR_MENU));
117#endif
mlerman67fa17a2015-02-13 21:59:22118}
Ivan Sandrk9669d0e2017-12-15 23:50:20119
120#if defined(OS_CHROMEOS)
121IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest, LockedFullscreen) {
122 CommandUpdaterImpl* command_updater =
123 &browser()->command_controller()->command_updater_;
124 // IDC_EXIT is always enabled in regular mode so it's a perfect candidate for
125 // testing.
126 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_EXIT));
127 // Set locked fullscreen mode.
128 browser()->window()->GetNativeWindow()->SetProperty(
Xiyuan Xia4f992f22019-06-05 15:33:46129 ash::kWindowPinTypeKey, ash::WindowPinType::kTrustedPinned);
Ivan Sandrk9669d0e2017-12-15 23:50:20130 // Update the corresponding command_controller state.
131 browser()->command_controller()->LockedFullscreenStateChanged();
132 // Update some more states just to make sure the wrong commands don't get
133 // enabled.
134 browser()->command_controller()->TabStateChanged();
135 browser()->command_controller()->FullscreenStateChanged();
136 browser()->command_controller()->PrintingStateChanged();
137 browser()->command_controller()->ExtensionStateChanged();
138 // IDC_EXIT is not enabled in locked fullscreen.
139 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_EXIT));
140
Ivan Sandrk6ac9c9a2018-12-14 14:15:07141 constexpr int kWhitelistedIds[] = {IDC_CUT, IDC_COPY, IDC_PASTE};
Ivan Sandrk9669d0e2017-12-15 23:50:20142
143 // Go through all the command ids and make sure all non-whitelisted commands
144 // are disabled.
145 for (int id : command_updater->GetAllIds()) {
Jan Wilken Dörriea8cb56302019-06-06 18:59:36146 if (base::Contains(kWhitelistedIds, id)) {
Ivan Sandrk9669d0e2017-12-15 23:50:20147 continue;
148 }
149 EXPECT_FALSE(command_updater->IsCommandEnabled(id));
150 }
151
Ivan Sandrk6ac9c9a2018-12-14 14:15:07152 // Verify the set of whitelisted commands.
Ivan Sandrk9669d0e2017-12-15 23:50:20153 for (int id : kWhitelistedIds) {
Ivan Sandrk9669d0e2017-12-15 23:50:20154 EXPECT_TRUE(command_updater->IsCommandEnabled(id));
155 }
156
157 // Exit locked fullscreen mode.
158 browser()->window()->GetNativeWindow()->SetProperty(
Xiyuan Xia4f992f22019-06-05 15:33:46159 ash::kWindowPinTypeKey, ash::WindowPinType::kNone);
Ivan Sandrk9669d0e2017-12-15 23:50:20160 // Update the corresponding command_controller state.
161 browser()->command_controller()->LockedFullscreenStateChanged();
162 // IDC_EXIT is enabled again.
163 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_EXIT));
164}
165#endif
166
Cliff Smolinsky2c9586e2019-02-08 18:48:30167IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest,
168 TestTabRestoreServiceInitialized) {
169 // Note: The command should start out as enabled as the default.
170 // All the initialization happens before any test code executes,
171 // so we can't validate it.
172
173 // The TabRestoreService should get initialized (Loaded)
174 // automatically upon launch.
175 // Wait for robustness because InProcessBrowserTest::PreRunTestOnMainThread
176 // does not flush the task scheduler.
177 TabRestoreServiceLoadWaiter waiter(browser());
178 waiter.Wait();
179
180 // After initialization, the command should become disabled because there's
181 // nothing to restore.
182 chrome::BrowserCommandController* commandController =
183 browser()->command_controller();
184 ASSERT_EQ(false, commandController->IsCommandEnabled(IDC_RESTORE_TAB));
185}
186
187IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest,
188 PRE_TestTabRestoreCommandEnabled) {
189 ui_test_utils::NavigateToURLWithDisposition(
190 browser(), GURL("about:"), WindowOpenDisposition::NEW_FOREGROUND_TAB,
191 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
192 ASSERT_EQ(2, browser()->tab_strip_model()->count());
193 EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
194 content::WebContents* tab_to_close =
195 browser()->tab_strip_model()->GetActiveWebContents();
196 content::WebContentsDestroyedWatcher destroyed_watcher(tab_to_close);
197 browser()->tab_strip_model()->CloseSelectedTabs();
198 destroyed_watcher.Wait();
199}
200
201IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest,
202 TestTabRestoreCommandEnabled) {
203 // The TabRestoreService should get initialized (Loaded)
204 // automatically upon launch.
205 // Wait for robustness because InProcessBrowserTest::PreRunTestOnMainThread
206 // does not flush the task scheduler.
207 TabRestoreServiceLoadWaiter waiter(browser());
208 waiter.Wait();
209
210 // After initialization, the command should remain enabled because there's
211 // one tab to restore.
212 chrome::BrowserCommandController* commandController =
213 browser()->command_controller();
214 ASSERT_EQ(true, commandController->IsCommandEnabled(IDC_RESTORE_TAB));
215}
216
Ivan Sandrk9669d0e2017-12-15 23:50:20217} // namespace chrome