blob: 30676548477ec4e3c7bdb4d9800a9d91154c911a [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"
[email protected]51a24782013-02-06 06:50:2332#include "content/public/test/test_utils.h"
[email protected]3cac87232012-11-20 01:48:2733
mlerman67fa17a2015-02-13 21:59:2234#if defined(OS_CHROMEOS)
Xiyuan Xia4f992f22019-06-05 15:33:4635#include "ash/public/cpp/window_pin_type.h"
Ivan Sandrk9669d0e2017-12-15 23:50:2036#include "ash/public/cpp/window_properties.h"
Steven Bennetts38e9bde22019-01-03 17:31:1037#include "chromeos/constants/chromeos_switches.h"
Ivan Sandrk9669d0e2017-12-15 23:50:2038#include "ui/aura/window.h"
mlerman67fa17a2015-02-13 21:59:2239#endif
40
Ivan Sandrk9669d0e2017-12-15 23:50:2041namespace chrome {
42
Aran Gilmand217b5b2019-04-11 17:45:4343class BrowserCommandControllerBrowserTest : public InProcessBrowserTest {
mlerman67fa17a2015-02-13 21:59:2244 public:
45 BrowserCommandControllerBrowserTest() {}
46 ~BrowserCommandControllerBrowserTest() override {}
47
48 void SetUpCommandLine(base::CommandLine* command_line) override {
mlerman67fa17a2015-02-13 21:59:2249#if defined(OS_CHROMEOS)
50 command_line->AppendSwitch(
51 chromeos::switches::kIgnoreUserProfileMappingForTests);
52#endif
53 }
54
55 private:
56 DISALLOW_COPY_AND_ASSIGN(BrowserCommandControllerBrowserTest);
57};
[email protected]3cac87232012-11-20 01:48:2758
59// Verify that showing a constrained window disables find.
60IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest, DisableFind) {
61 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_FIND));
62
63 // Showing constrained window should disable find.
[email protected]57892182012-12-03 19:15:3964 content::WebContents* web_contents =
65 browser()->tab_strip_model()->GetActiveWebContents();
Jeremy Chinsene54596432019-05-29 00:18:4666 auto delegate = std::make_unique<MockTabModalConfirmDialogDelegate>(
67 web_contents, nullptr);
68 MockTabModalConfirmDialogDelegate* delegate_ptr = delegate.get();
69 TabModalConfirmDialog::Create(std::move(delegate), web_contents);
[email protected]3cac87232012-11-20 01:48:2770 EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_FIND));
71
72 // Switching to a new (unblocked) tab should reenable it.
73 AddBlankTabAndShow(browser());
74 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_FIND));
75
76 // Switching back to the blocked tab should disable it again.
Edwin Joe6f6fc1e2019-02-27 20:00:3777 browser()->tab_strip_model()->ActivateTabAt(0);
[email protected]3cac87232012-11-20 01:48:2778 EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_FIND));
79
80 // Closing the constrained window should reenable it.
Jeremy Chinsene54596432019-05-29 00:18:4681 delegate_ptr->Cancel();
[email protected]51a24782013-02-06 06:50:2382 content::RunAllPendingInMessageLoop();
[email protected]3cac87232012-11-20 01:48:2783 EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_FIND));
84}
mlerman67fa17a2015-02-13 21:59:2285
86// Note that a Browser's destructor, when the browser's profile is guest, will
87// create and execute a BrowsingDataRemover.
jamdb04346c2015-04-23 00:06:4488// Flakes http://crbug.com/471953
mlerman67fa17a2015-02-13 21:59:2289IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest,
jamdb04346c2015-04-23 00:06:4490 DISABLED_NewAvatarMenuEnabledInGuestMode) {
scottmg0d8e4ab2016-01-28 00:34:5591 EXPECT_EQ(1U, BrowserList::GetInstance()->size());
mlerman67fa17a2015-02-13 21:59:2292
93 // Create a guest browser nicely. Using CreateProfile() and CreateBrowser()
94 // does incomplete initialization that would lead to
95 // SystemUrlRequestContextGetter being leaked.
scottmgff189b62016-02-11 19:47:1696 profiles::SwitchToGuestProfile(ProfileManager::CreateCallback());
Evan Stade4487c452019-07-11 00:58:0697 ui_test_utils::WaitForBrowserToOpen();
scottmg0d8e4ab2016-01-28 00:34:5598 EXPECT_EQ(2U, BrowserList::GetInstance()->size());
mlerman67fa17a2015-02-13 21:59:2299
100 // Access the browser that was created for the new Guest Profile.
101 Profile* guest = g_browser_process->profile_manager()->GetProfileByPath(
102 ProfileManager::GetGuestProfilePath());
scottmg34c5dd882016-02-03 05:21:54103 Browser* browser = chrome::FindAnyBrowser(guest, true);
mlerman67fa17a2015-02-13 21:59:22104 EXPECT_TRUE(browser);
105
106 // The BrowsingDataRemover needs a loaded TemplateUrlService or else it hangs
107 // on to a CallbackList::Subscription forever.
108 TemplateURLServiceFactory::GetForProfile(guest)->set_loaded(true);
109
Ivan Sandrk9669d0e2017-12-15 23:50:20110 const CommandUpdater* command_updater = browser->command_controller();
Aran Gilmand217b5b2019-04-11 17:45:43111#if defined(OS_CHROMEOS)
112 // Chrome OS uses system tray menu to handle multi-profiles.
113 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_SHOW_AVATAR_MENU));
114#else
115 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_AVATAR_MENU));
116#endif
mlerman67fa17a2015-02-13 21:59:22117}
Ivan Sandrk9669d0e2017-12-15 23:50:20118
119#if defined(OS_CHROMEOS)
120IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest, LockedFullscreen) {
121 CommandUpdaterImpl* command_updater =
122 &browser()->command_controller()->command_updater_;
123 // IDC_EXIT is always enabled in regular mode so it's a perfect candidate for
124 // testing.
125 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_EXIT));
126 // Set locked fullscreen mode.
127 browser()->window()->GetNativeWindow()->SetProperty(
Xiyuan Xia4f992f22019-06-05 15:33:46128 ash::kWindowPinTypeKey, ash::WindowPinType::kTrustedPinned);
Ivan Sandrk9669d0e2017-12-15 23:50:20129 // Update the corresponding command_controller state.
130 browser()->command_controller()->LockedFullscreenStateChanged();
131 // Update some more states just to make sure the wrong commands don't get
132 // enabled.
133 browser()->command_controller()->TabStateChanged();
134 browser()->command_controller()->FullscreenStateChanged();
135 browser()->command_controller()->PrintingStateChanged();
136 browser()->command_controller()->ExtensionStateChanged();
137 // IDC_EXIT is not enabled in locked fullscreen.
138 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_EXIT));
139
Ivan Sandrk6ac9c9a2018-12-14 14:15:07140 constexpr int kWhitelistedIds[] = {IDC_CUT, IDC_COPY, IDC_PASTE};
Ivan Sandrk9669d0e2017-12-15 23:50:20141
142 // Go through all the command ids and make sure all non-whitelisted commands
143 // are disabled.
144 for (int id : command_updater->GetAllIds()) {
Jan Wilken Dörriea8cb56302019-06-06 18:59:36145 if (base::Contains(kWhitelistedIds, id)) {
Ivan Sandrk9669d0e2017-12-15 23:50:20146 continue;
147 }
148 EXPECT_FALSE(command_updater->IsCommandEnabled(id));
149 }
150
Ivan Sandrk6ac9c9a2018-12-14 14:15:07151 // Verify the set of whitelisted commands.
Ivan Sandrk9669d0e2017-12-15 23:50:20152 for (int id : kWhitelistedIds) {
Ivan Sandrk9669d0e2017-12-15 23:50:20153 EXPECT_TRUE(command_updater->IsCommandEnabled(id));
154 }
155
156 // Exit locked fullscreen mode.
157 browser()->window()->GetNativeWindow()->SetProperty(
Xiyuan Xia4f992f22019-06-05 15:33:46158 ash::kWindowPinTypeKey, ash::WindowPinType::kNone);
Ivan Sandrk9669d0e2017-12-15 23:50:20159 // Update the corresponding command_controller state.
160 browser()->command_controller()->LockedFullscreenStateChanged();
161 // IDC_EXIT is enabled again.
162 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_EXIT));
163}
164#endif
165
Cliff Smolinsky2c9586e2019-02-08 18:48:30166IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest,
167 TestTabRestoreServiceInitialized) {
168 // Note: The command should start out as enabled as the default.
169 // All the initialization happens before any test code executes,
170 // so we can't validate it.
171
172 // The TabRestoreService should get initialized (Loaded)
173 // automatically upon launch.
174 // Wait for robustness because InProcessBrowserTest::PreRunTestOnMainThread
175 // does not flush the task scheduler.
176 TabRestoreServiceLoadWaiter waiter(browser());
177 waiter.Wait();
178
179 // After initialization, the command should become disabled because there's
180 // nothing to restore.
181 chrome::BrowserCommandController* commandController =
182 browser()->command_controller();
183 ASSERT_EQ(false, commandController->IsCommandEnabled(IDC_RESTORE_TAB));
184}
185
186IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest,
187 PRE_TestTabRestoreCommandEnabled) {
188 ui_test_utils::NavigateToURLWithDisposition(
189 browser(), GURL("about:"), WindowOpenDisposition::NEW_FOREGROUND_TAB,
190 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
191 ASSERT_EQ(2, browser()->tab_strip_model()->count());
192 EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
193 content::WebContents* tab_to_close =
194 browser()->tab_strip_model()->GetActiveWebContents();
195 content::WebContentsDestroyedWatcher destroyed_watcher(tab_to_close);
196 browser()->tab_strip_model()->CloseSelectedTabs();
197 destroyed_watcher.Wait();
198}
199
200IN_PROC_BROWSER_TEST_F(BrowserCommandControllerBrowserTest,
201 TestTabRestoreCommandEnabled) {
202 // The TabRestoreService should get initialized (Loaded)
203 // automatically upon launch.
204 // Wait for robustness because InProcessBrowserTest::PreRunTestOnMainThread
205 // does not flush the task scheduler.
206 TabRestoreServiceLoadWaiter waiter(browser());
207 waiter.Wait();
208
209 // After initialization, the command should remain enabled because there's
210 // one tab to restore.
211 chrome::BrowserCommandController* commandController =
212 browser()->command_controller();
213 ASSERT_EQ(true, commandController->IsCommandEnabled(IDC_RESTORE_TAB));
214}
215
Ivan Sandrk9669d0e2017-12-15 23:50:20216} // namespace chrome