blob: 74bd0894bf93c0985d89cd3cdd580e6cf73b96b4 [file] [log] [blame]
[email protected]c17d9e62014-08-18 19:36:521// 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.
4
juncaia64f769c22016-06-04 00:55:325#include "components/zoom/zoom_controller.h"
[email protected]c17d9e62014-08-18 19:36:526
avi655876a2015-12-25 07:18:157#include "base/macros.h"
[email protected]c17d9e62014-08-18 19:36:528#include "base/process/kill.h"
avi655876a2015-12-25 07:18:159#include "build/build_config.h"
wjmaclean32a991c2014-09-02 14:13:4710#include "chrome/browser/profiles/profile.h"
[email protected]c17d9e62014-08-18 19:36:5211#include "chrome/browser/ui/browser.h"
wjmaclean7431bb22015-02-19 14:53:4312#include "chrome/browser/ui/browser_commands.h"
[email protected]c17d9e62014-08-18 19:36:5213#include "chrome/browser/ui/tabs/tab_strip_model.h"
rogertae77304c2015-01-07 02:53:5514#include "chrome/browser/ui/webui/signin/login_ui_test_utils.h"
wjmacleane530aa742014-10-14 21:43:3015#include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h"
wjmacleanc7bcb77d2014-12-16 15:05:3816#include "chrome/common/url_constants.h"
[email protected]c17d9e62014-08-18 19:36:5217#include "chrome/test/base/in_process_browser_test.h"
18#include "chrome/test/base/ui_test_utils.h"
brettwb1fc1b82016-02-02 00:19:0819#include "components/prefs/pref_service.h"
rogertae77304c2015-01-07 02:53:5520#include "components/signin/core/common/profile_management_switches.h"
wjmacleanc7bcb77d2014-12-16 15:05:3821#include "content/public/browser/host_zoom_map.h"
wjmacleane6a5d222014-09-25 01:41:4122#include "content/public/browser/navigation_entry.h"
Lukasz Anforowicza192ffb2017-10-02 20:36:3823#include "content/public/browser/render_frame_host.h"
[email protected]c17d9e62014-08-18 19:36:5224#include "content/public/browser/render_process_host.h"
wjmaclean5eeba912014-09-02 20:23:4725#include "content/public/browser/render_view_host.h"
[email protected]c17d9e62014-08-18 19:36:5226#include "content/public/browser/web_contents.h"
wjmacleane6a5d222014-09-25 01:41:4127#include "content/public/common/page_type.h"
[email protected]c17d9e62014-08-18 19:36:5228#include "content/public/test/browser_test_utils.h"
wjmaclean32a991c2014-09-02 14:13:4729#include "testing/gmock/include/gmock/gmock.h"
[email protected]c17d9e62014-08-18 19:36:5230
juncaia64f769c22016-06-04 00:55:3231using zoom::ZoomController;
32using zoom::ZoomObserver;
wjmaclean7f63c6b2014-12-09 14:59:5533
wjmaclean32a991c2014-09-02 14:13:4734bool operator==(const ZoomController::ZoomChangedEventData& lhs,
35 const ZoomController::ZoomChangedEventData& rhs) {
36 return lhs.web_contents == rhs.web_contents &&
37 lhs.old_zoom_level == rhs.old_zoom_level &&
38 lhs.new_zoom_level == rhs.new_zoom_level &&
39 lhs.zoom_mode == rhs.zoom_mode &&
40 lhs.can_show_bubble == rhs.can_show_bubble;
41}
42
43class ZoomChangedWatcher : public ZoomObserver {
44 public:
45 ZoomChangedWatcher(
46 content::WebContents* web_contents,
47 const ZoomController::ZoomChangedEventData& expected_event_data)
thestig397accd2015-04-04 00:03:0448 : expected_event_data_(expected_event_data),
wjmaclean32a991c2014-09-02 14:13:4749 message_loop_runner_(new content::MessageLoopRunner) {
50 ZoomController::FromWebContents(web_contents)->AddObserver(this);
51 }
dcheng5dd5ff62014-10-21 12:42:3852 ~ZoomChangedWatcher() override {}
wjmaclean32a991c2014-09-02 14:13:4753
54 void Wait() { message_loop_runner_->Run(); }
55
dcheng5dd5ff62014-10-21 12:42:3856 void OnZoomChanged(
mostynbda49c502014-10-04 00:10:3257 const ZoomController::ZoomChangedEventData& event_data) override {
wjmaclean32a991c2014-09-02 14:13:4758 if (event_data == expected_event_data_)
59 message_loop_runner_->Quit();
60 }
61
62 private:
wjmaclean32a991c2014-09-02 14:13:4763 ZoomController::ZoomChangedEventData expected_event_data_;
64 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
65
66 DISALLOW_COPY_AND_ASSIGN(ZoomChangedWatcher);
67};
68
wjmaclean96fc2e92015-01-28 20:42:1169class ZoomControllerBrowserTest : public InProcessBrowserTest {
70 public:
71 ZoomControllerBrowserTest() {}
72 ~ZoomControllerBrowserTest() override {}
73
74 void TestResetOnNavigation(ZoomController::ZoomMode zoom_mode) {
75 DCHECK(zoom_mode == ZoomController::ZOOM_MODE_ISOLATED ||
76 zoom_mode == ZoomController::ZOOM_MODE_MANUAL);
77 content::WebContents* web_contents =
78 browser()->tab_strip_model()->GetActiveWebContents();
79 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
80 browser(), GURL("about:blank"), 1);
81 ZoomController* zoom_controller =
82 ZoomController::FromWebContents(web_contents);
83 double zoom_level = zoom_controller->GetDefaultZoomLevel();
84 zoom_controller->SetZoomMode(zoom_mode);
85
86 // When the navigation occurs, the zoom_mode will be reset to
87 // ZOOM_MODE_DEFAULT, and this will be reflected in the event that
88 // is generated.
89 ZoomController::ZoomChangedEventData zoom_change_data(
90 web_contents, zoom_level, zoom_level, ZoomController::ZOOM_MODE_DEFAULT,
91 false);
92 ZoomChangedWatcher zoom_change_watcher(web_contents, zoom_change_data);
93
94 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUISettingsURL));
95 zoom_change_watcher.Wait();
96 }
97}; // ZoomControllerBrowserTest
wjmacleancaa7d6d2014-11-12 16:42:1198
[email protected]c17d9e62014-08-18 19:36:5299#if defined(OS_ANDROID)
100#define MAYBE_CrashedTabsDoNotChangeZoom DISABLED_CrashedTabsDoNotChangeZoom
101#else
102#define MAYBE_CrashedTabsDoNotChangeZoom CrashedTabsDoNotChangeZoom
103#endif
104IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest,
105 MAYBE_CrashedTabsDoNotChangeZoom) {
106 // At the start of the test we are at a tab displaying about:blank.
107 content::WebContents* web_contents =
108 browser()->tab_strip_model()->GetActiveWebContents();
109
110 ZoomController* zoom_controller =
111 ZoomController::FromWebContents(web_contents);
112
113 double old_zoom_level = zoom_controller->GetZoomLevel();
114 double new_zoom_level = old_zoom_level + 0.5;
115
Lukasz Anforowicza192ffb2017-10-02 20:36:38116 content::RenderProcessHost* host = web_contents->GetMainFrame()->GetProcess();
[email protected]c17d9e62014-08-18 19:36:52117 {
118 content::RenderProcessHostWatcher crash_observer(
119 host, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
jaekyun37e572a32014-12-04 23:33:35120 host->Shutdown(0, false);
[email protected]c17d9e62014-08-18 19:36:52121 crash_observer.Wait();
122 }
wjmaclean5eeba912014-09-02 20:23:47123 EXPECT_FALSE(web_contents->GetRenderViewHost()->IsRenderViewLive());
[email protected]c17d9e62014-08-18 19:36:52124
125 // The following attempt to change the zoom level for a crashed tab should
126 // fail.
127 zoom_controller->SetZoomLevel(new_zoom_level);
128 EXPECT_FLOAT_EQ(old_zoom_level, zoom_controller->GetZoomLevel());
129}
wjmaclean32a991c2014-09-02 14:13:47130
131IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest, OnPreferenceChanged) {
132 content::WebContents* web_contents =
133 browser()->tab_strip_model()->GetActiveWebContents();
134 double new_default_zoom_level = 1.0;
135 // Since this page uses the default zoom level, the changes to the default
136 // zoom level will change the zoom level for this web_contents.
137 ZoomController::ZoomChangedEventData zoom_change_data(
138 web_contents,
139 new_default_zoom_level,
140 new_default_zoom_level,
141 ZoomController::ZOOM_MODE_DEFAULT,
wjmacleanff3d0f62015-02-25 19:38:36142 false);
wjmaclean32a991c2014-09-02 14:13:47143 ZoomChangedWatcher zoom_change_watcher(web_contents, zoom_change_data);
144 // TODO(wjmaclean): Convert this to call partition-specific zoom level prefs
145 // when they become available.
wjmacleane530aa742014-10-14 21:43:30146 browser()->profile()->GetZoomLevelPrefs()->SetDefaultZoomLevelPref(
147 new_default_zoom_level);
wjmaclean32a991c2014-09-02 14:13:47148 // Because this test relies on a round-trip IPC to/from the renderer process,
149 // we need to wait for it to propagate.
150 zoom_change_watcher.Wait();
151}
wjmacleane6a5d222014-09-25 01:41:41152
wjmacleande29ed52014-10-28 21:09:06153IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest, ErrorPagesCanZoom) {
wjmacleane6a5d222014-09-25 01:41:41154 ui_test_utils::NavigateToURL(browser(), GURL("http://kjfhkjsdf.com"));
155 content::WebContents* web_contents =
156 browser()->tab_strip_model()->GetActiveWebContents();
157
158 ZoomController* zoom_controller =
159 ZoomController::FromWebContents(web_contents);
160 EXPECT_EQ(
161 content::PAGE_TYPE_ERROR,
162 web_contents->GetController().GetLastCommittedEntry()->GetPageType());
163
164 double old_zoom_level = zoom_controller->GetZoomLevel();
165 double new_zoom_level = old_zoom_level + 0.5;
166
167 // The following attempt to change the zoom level for an error page should
168 // fail.
169 zoom_controller->SetZoomLevel(new_zoom_level);
wjmacleande29ed52014-10-28 21:09:06170 EXPECT_FLOAT_EQ(new_zoom_level, zoom_controller->GetZoomLevel());
wjmacleane6a5d222014-09-25 01:41:41171}
wjmacleancaa7d6d2014-11-12 16:42:11172
wjmaclean7431bb22015-02-19 14:53:43173IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest,
174 ErrorPagesCanZoomAfterTabRestore) {
175 // This url is meant to cause a network error page to be loaded.
176 // Tests can't reach the network, so this test should continue
177 // to work even if the domain listed is someday registered.
178 GURL url("http://kjfhkjsdf.com");
179
180 TabStripModel* tab_strip = browser()->tab_strip_model();
181 ASSERT_TRUE(tab_strip);
182
183 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19184 browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
wjmaclean7431bb22015-02-19 14:53:43185 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
186 {
187 content::WebContents* web_contents = tab_strip->GetActiveWebContents();
188
189 EXPECT_EQ(
190 content::PAGE_TYPE_ERROR,
191 web_contents->GetController().GetLastCommittedEntry()->GetPageType());
192
193 content::WebContentsDestroyedWatcher destroyed_watcher(web_contents);
194 tab_strip->CloseWebContentsAt(tab_strip->active_index(),
195 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
196 destroyed_watcher.Wait();
197 }
198 EXPECT_EQ(1, tab_strip->count());
199
200 content::WebContentsAddedObserver new_web_contents_observer;
201 chrome::RestoreTab(browser());
202 content::WebContents* web_contents =
203 new_web_contents_observer.GetWebContents();
204 content::WaitForLoadStop(web_contents);
205
206 EXPECT_EQ(2, tab_strip->count());
207
208 EXPECT_EQ(
209 content::PAGE_TYPE_ERROR,
210 web_contents->GetController().GetLastCommittedEntry()->GetPageType());
211
212 ZoomController* zoom_controller =
213 ZoomController::FromWebContents(web_contents);
214
215 double old_zoom_level = zoom_controller->GetZoomLevel();
216 double new_zoom_level = old_zoom_level + 0.5;
217
218 // The following attempt to change the zoom level for an error page should
219 // fail.
220 zoom_controller->SetZoomLevel(new_zoom_level);
221 EXPECT_FLOAT_EQ(new_zoom_level, zoom_controller->GetZoomLevel());
222}
223
wjmacleancaa7d6d2014-11-12 16:42:11224IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest, Observe) {
225 content::WebContents* web_contents =
226 browser()->tab_strip_model()->GetActiveWebContents();
wjmacleancaa7d6d2014-11-12 16:42:11227
228 double new_zoom_level = 1.0;
229 // When the event is initiated from HostZoomMap, the old zoom level is not
230 // available.
231 ZoomController::ZoomChangedEventData zoom_change_data(
232 web_contents,
233 new_zoom_level,
234 new_zoom_level,
235 ZoomController::ZOOM_MODE_DEFAULT,
wjmacleanff3d0f62015-02-25 19:38:36236 false); // The ZoomController did not initiate, so this will be 'false'.
wjmaclean7f63c6b2014-12-09 14:59:55237 ZoomChangedWatcher zoom_change_watcher(web_contents, zoom_change_data);
wjmacleancaa7d6d2014-11-12 16:42:11238
239 content::HostZoomMap* host_zoom_map =
240 content::HostZoomMap::GetDefaultForBrowserContext(
241 web_contents->GetBrowserContext());
242
243 host_zoom_map->SetZoomLevelForHost("about:blank", new_zoom_level);
wjmaclean7f63c6b2014-12-09 14:59:55244 zoom_change_watcher.Wait();
wjmacleancaa7d6d2014-11-12 16:42:11245}
wjmacleanc7bcb77d2014-12-16 15:05:38246
wjmacleana9373ca2015-04-01 22:53:26247IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest, ObserveDisabledModeEvent) {
248 content::WebContents* web_contents =
249 browser()->tab_strip_model()->GetActiveWebContents();
250
251 ZoomController* zoom_controller =
252 ZoomController::FromWebContents(web_contents);
253
254 double default_zoom_level = zoom_controller->GetDefaultZoomLevel();
255 double new_zoom_level = default_zoom_level + 1.0;
256 zoom_controller->SetZoomLevel(new_zoom_level);
257
258 ZoomController::ZoomChangedEventData zoom_change_data(
259 web_contents,
260 new_zoom_level,
261 default_zoom_level,
262 ZoomController::ZOOM_MODE_DISABLED,
263 true);
264 ZoomChangedWatcher zoom_change_watcher(web_contents, zoom_change_data);
265 zoom_controller->SetZoomMode(ZoomController::ZOOM_MODE_DISABLED);
266 zoom_change_watcher.Wait();
267}
268
wjmacleand96f8642015-01-07 20:10:57269IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest, PerTabModeResetSendsEvent) {
wjmaclean96fc2e92015-01-28 20:42:11270 TestResetOnNavigation(ZoomController::ZOOM_MODE_ISOLATED);
271}
wjmacleand96f8642015-01-07 20:10:57272
wjmaclean96fc2e92015-01-28 20:42:11273// Regression test: crbug.com/450909.
274IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest, NavigationResetsManualMode) {
275 TestResetOnNavigation(ZoomController::ZOOM_MODE_MANUAL);
wjmacleand96f8642015-01-07 20:10:57276}
277
rogertae77304c2015-01-07 02:53:55278#if !defined(OS_CHROMEOS)
wjmacleanc7bcb77d2014-12-16 15:05:38279// Regression test: crbug.com/438979.
280IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest,
281 SettingsZoomAfterSigninWorks) {
gogerald71bf6c902015-12-08 00:49:37282 GURL signin_url(std::string(chrome::kChromeUIChromeSigninURL)
283 .append("?access_point=0&reason=0"));
wjmacleanc7bcb77d2014-12-16 15:05:38284 // We open the signin page in a new tab so that the ZoomController is
285 // created against the HostZoomMap of the special StoragePartition that
286 // backs the signin page. When we subsequently navigate away from the
287 // signin page, the HostZoomMap changes, and we need to test that the
288 // ZoomController correctly detects this.
rogertae77304c2015-01-07 02:53:55289 ui_test_utils::NavigateToURLWithDisposition(
nick3b04f322016-08-31 19:29:19290 browser(), signin_url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
rogertae77304c2015-01-07 02:53:55291 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
292 login_ui_test_utils::WaitUntilUIReady(browser());
wjmacleanc7bcb77d2014-12-16 15:05:38293 content::WebContents* web_contents =
294 browser()->tab_strip_model()->GetActiveWebContents();
295 EXPECT_NE(
296 content::PAGE_TYPE_ERROR,
297 web_contents->GetController().GetLastCommittedEntry()->GetPageType());
298
299 EXPECT_EQ(signin_url, web_contents->GetLastCommittedURL());
300 ZoomController* zoom_controller =
301 ZoomController::FromWebContents(web_contents);
302
wjmacleanc7bcb77d2014-12-16 15:05:38303 GURL settings_url(chrome::kChromeUISettingsURL);
304 ui_test_utils::NavigateToURL(browser(), settings_url);
305 EXPECT_NE(
306 content::PAGE_TYPE_ERROR,
307 web_contents->GetController().GetLastCommittedEntry()->GetPageType());
308
309 // Verify new tab was created.
310 EXPECT_EQ(2, browser()->tab_strip_model()->count());
311 // Verify that the settings page is using the same WebContents.
312 EXPECT_EQ(web_contents, browser()->tab_strip_model()->GetActiveWebContents());
313 // TODO(wjmaclean): figure out why this next line fails, i.e. why does this
314 // test not properly trigger a navigation to the settings page.
315 EXPECT_EQ(settings_url, web_contents->GetLastCommittedURL());
316 EXPECT_EQ(zoom_controller, ZoomController::FromWebContents(web_contents));
317
wjmacleanc7bcb77d2014-12-16 15:05:38318 // If we zoom the new page, it should still generate a ZoomController event.
319 double old_zoom_level = zoom_controller->GetZoomLevel();
320 double new_zoom_level = old_zoom_level + 0.5;
321
322 ZoomController::ZoomChangedEventData zoom_change_data(
323 web_contents,
324 old_zoom_level,
325 new_zoom_level,
326 ZoomController::ZOOM_MODE_DEFAULT,
327 true); // We have a non-empty host, so this will be 'true'.
328 ZoomChangedWatcher zoom_change_watcher(web_contents, zoom_change_data);
329 zoom_controller->SetZoomLevel(new_zoom_level);
330 zoom_change_watcher.Wait();
331}
rogertae77304c2015-01-07 02:53:55332#endif // !defined(OS_CHROMEOS)