blob: a16336c125e40764868b95e18c7e609680992261 [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
wjmaclean7f63c6b2014-12-09 14:59:555#include "components/ui/zoom/zoom_controller.h"
[email protected]c17d9e62014-08-18 19:36:526
wjmaclean32a991c2014-09-02 14:13:477#include "base/prefs/pref_service.h"
[email protected]c17d9e62014-08-18 19:36:528#include "base/process/kill.h"
wjmaclean32a991c2014-09-02 14:13:479#include "chrome/browser/profiles/profile.h"
[email protected]c17d9e62014-08-18 19:36:5210#include "chrome/browser/ui/browser.h"
wjmaclean7431bb22015-02-19 14:53:4311#include "chrome/browser/ui/browser_commands.h"
[email protected]c17d9e62014-08-18 19:36:5212#include "chrome/browser/ui/tabs/tab_strip_model.h"
rogertae77304c2015-01-07 02:53:5513#include "chrome/browser/ui/webui/signin/login_ui_test_utils.h"
wjmacleane530aa742014-10-14 21:43:3014#include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h"
wjmacleanc7bcb77d2014-12-16 15:05:3815#include "chrome/common/url_constants.h"
[email protected]c17d9e62014-08-18 19:36:5216#include "chrome/test/base/in_process_browser_test.h"
17#include "chrome/test/base/ui_test_utils.h"
rogertae77304c2015-01-07 02:53:5518#include "components/signin/core/common/profile_management_switches.h"
wjmacleanc7bcb77d2014-12-16 15:05:3819#include "content/public/browser/host_zoom_map.h"
wjmacleane6a5d222014-09-25 01:41:4120#include "content/public/browser/navigation_entry.h"
[email protected]c17d9e62014-08-18 19:36:5221#include "content/public/browser/render_process_host.h"
wjmaclean5eeba912014-09-02 20:23:4722#include "content/public/browser/render_view_host.h"
[email protected]c17d9e62014-08-18 19:36:5223#include "content/public/browser/web_contents.h"
wjmacleane6a5d222014-09-25 01:41:4124#include "content/public/common/page_type.h"
[email protected]c17d9e62014-08-18 19:36:5225#include "content/public/test/browser_test_utils.h"
wjmaclean32a991c2014-09-02 14:13:4726#include "testing/gmock/include/gmock/gmock.h"
[email protected]c17d9e62014-08-18 19:36:5227
wjmaclean7f63c6b2014-12-09 14:59:5528using ui_zoom::ZoomController;
29using ui_zoom::ZoomObserver;
30
wjmaclean32a991c2014-09-02 14:13:4731bool operator==(const ZoomController::ZoomChangedEventData& lhs,
32 const ZoomController::ZoomChangedEventData& rhs) {
33 return lhs.web_contents == rhs.web_contents &&
34 lhs.old_zoom_level == rhs.old_zoom_level &&
35 lhs.new_zoom_level == rhs.new_zoom_level &&
36 lhs.zoom_mode == rhs.zoom_mode &&
37 lhs.can_show_bubble == rhs.can_show_bubble;
38}
39
40class ZoomChangedWatcher : public ZoomObserver {
41 public:
42 ZoomChangedWatcher(
43 content::WebContents* web_contents,
44 const ZoomController::ZoomChangedEventData& expected_event_data)
45 : web_contents_(web_contents),
46 expected_event_data_(expected_event_data),
47 message_loop_runner_(new content::MessageLoopRunner) {
48 ZoomController::FromWebContents(web_contents)->AddObserver(this);
49 }
dcheng5dd5ff62014-10-21 12:42:3850 ~ZoomChangedWatcher() override {}
wjmaclean32a991c2014-09-02 14:13:4751
52 void Wait() { message_loop_runner_->Run(); }
53
dcheng5dd5ff62014-10-21 12:42:3854 void OnZoomChanged(
mostynbda49c502014-10-04 00:10:3255 const ZoomController::ZoomChangedEventData& event_data) override {
wjmaclean32a991c2014-09-02 14:13:4756 if (event_data == expected_event_data_)
57 message_loop_runner_->Quit();
58 }
59
60 private:
61 content::WebContents* web_contents_;
62 ZoomController::ZoomChangedEventData expected_event_data_;
63 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
64
65 DISALLOW_COPY_AND_ASSIGN(ZoomChangedWatcher);
66};
67
wjmaclean96fc2e92015-01-28 20:42:1168class ZoomControllerBrowserTest : public InProcessBrowserTest {
69 public:
70 ZoomControllerBrowserTest() {}
71 ~ZoomControllerBrowserTest() override {}
72
73 void TestResetOnNavigation(ZoomController::ZoomMode zoom_mode) {
74 DCHECK(zoom_mode == ZoomController::ZOOM_MODE_ISOLATED ||
75 zoom_mode == ZoomController::ZOOM_MODE_MANUAL);
76 content::WebContents* web_contents =
77 browser()->tab_strip_model()->GetActiveWebContents();
78 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
79 browser(), GURL("about:blank"), 1);
80 ZoomController* zoom_controller =
81 ZoomController::FromWebContents(web_contents);
82 double zoom_level = zoom_controller->GetDefaultZoomLevel();
83 zoom_controller->SetZoomMode(zoom_mode);
84
85 // When the navigation occurs, the zoom_mode will be reset to
86 // ZOOM_MODE_DEFAULT, and this will be reflected in the event that
87 // is generated.
88 ZoomController::ZoomChangedEventData zoom_change_data(
89 web_contents, zoom_level, zoom_level, ZoomController::ZOOM_MODE_DEFAULT,
90 false);
91 ZoomChangedWatcher zoom_change_watcher(web_contents, zoom_change_data);
92
93 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUISettingsURL));
94 zoom_change_watcher.Wait();
95 }
96}; // ZoomControllerBrowserTest
wjmacleancaa7d6d2014-11-12 16:42:1197
[email protected]c17d9e62014-08-18 19:36:5298#if defined(OS_ANDROID)
99#define MAYBE_CrashedTabsDoNotChangeZoom DISABLED_CrashedTabsDoNotChangeZoom
100#else
101#define MAYBE_CrashedTabsDoNotChangeZoom CrashedTabsDoNotChangeZoom
102#endif
103IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest,
104 MAYBE_CrashedTabsDoNotChangeZoom) {
105 // At the start of the test we are at a tab displaying about:blank.
106 content::WebContents* web_contents =
107 browser()->tab_strip_model()->GetActiveWebContents();
108
109 ZoomController* zoom_controller =
110 ZoomController::FromWebContents(web_contents);
111
112 double old_zoom_level = zoom_controller->GetZoomLevel();
113 double new_zoom_level = old_zoom_level + 0.5;
114
115 content::RenderProcessHost* host = web_contents->GetRenderProcessHost();
116 {
117 content::RenderProcessHostWatcher crash_observer(
118 host, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
jaekyun37e572a32014-12-04 23:33:35119 host->Shutdown(0, false);
[email protected]c17d9e62014-08-18 19:36:52120 crash_observer.Wait();
121 }
wjmaclean5eeba912014-09-02 20:23:47122 EXPECT_FALSE(web_contents->GetRenderViewHost()->IsRenderViewLive());
[email protected]c17d9e62014-08-18 19:36:52123
124 // The following attempt to change the zoom level for a crashed tab should
125 // fail.
126 zoom_controller->SetZoomLevel(new_zoom_level);
127 EXPECT_FLOAT_EQ(old_zoom_level, zoom_controller->GetZoomLevel());
128}
wjmaclean32a991c2014-09-02 14:13:47129
130IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest, OnPreferenceChanged) {
131 content::WebContents* web_contents =
132 browser()->tab_strip_model()->GetActiveWebContents();
133 double new_default_zoom_level = 1.0;
134 // Since this page uses the default zoom level, the changes to the default
135 // zoom level will change the zoom level for this web_contents.
136 ZoomController::ZoomChangedEventData zoom_change_data(
137 web_contents,
138 new_default_zoom_level,
139 new_default_zoom_level,
140 ZoomController::ZOOM_MODE_DEFAULT,
141 true);
142 ZoomChangedWatcher zoom_change_watcher(web_contents, zoom_change_data);
143 // TODO(wjmaclean): Convert this to call partition-specific zoom level prefs
144 // when they become available.
wjmacleane530aa742014-10-14 21:43:30145 browser()->profile()->GetZoomLevelPrefs()->SetDefaultZoomLevelPref(
146 new_default_zoom_level);
wjmaclean32a991c2014-09-02 14:13:47147 // Because this test relies on a round-trip IPC to/from the renderer process,
148 // we need to wait for it to propagate.
149 zoom_change_watcher.Wait();
150}
wjmacleane6a5d222014-09-25 01:41:41151
wjmacleande29ed52014-10-28 21:09:06152IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest, ErrorPagesCanZoom) {
wjmacleane6a5d222014-09-25 01:41:41153 ui_test_utils::NavigateToURL(browser(), GURL("http://kjfhkjsdf.com"));
154 content::WebContents* web_contents =
155 browser()->tab_strip_model()->GetActiveWebContents();
156
157 ZoomController* zoom_controller =
158 ZoomController::FromWebContents(web_contents);
159 EXPECT_EQ(
160 content::PAGE_TYPE_ERROR,
161 web_contents->GetController().GetLastCommittedEntry()->GetPageType());
162
163 double old_zoom_level = zoom_controller->GetZoomLevel();
164 double new_zoom_level = old_zoom_level + 0.5;
165
166 // The following attempt to change the zoom level for an error page should
167 // fail.
168 zoom_controller->SetZoomLevel(new_zoom_level);
wjmacleande29ed52014-10-28 21:09:06169 EXPECT_FLOAT_EQ(new_zoom_level, zoom_controller->GetZoomLevel());
wjmacleane6a5d222014-09-25 01:41:41170}
wjmacleancaa7d6d2014-11-12 16:42:11171
wjmaclean7431bb22015-02-19 14:53:43172IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest,
173 ErrorPagesCanZoomAfterTabRestore) {
174 // This url is meant to cause a network error page to be loaded.
175 // Tests can't reach the network, so this test should continue
176 // to work even if the domain listed is someday registered.
177 GURL url("http://kjfhkjsdf.com");
178
179 TabStripModel* tab_strip = browser()->tab_strip_model();
180 ASSERT_TRUE(tab_strip);
181
182 ui_test_utils::NavigateToURLWithDisposition(
183 browser(), url, NEW_FOREGROUND_TAB,
184 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
185 {
186 content::WebContents* web_contents = tab_strip->GetActiveWebContents();
187
188 EXPECT_EQ(
189 content::PAGE_TYPE_ERROR,
190 web_contents->GetController().GetLastCommittedEntry()->GetPageType());
191
192 content::WebContentsDestroyedWatcher destroyed_watcher(web_contents);
193 tab_strip->CloseWebContentsAt(tab_strip->active_index(),
194 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
195 destroyed_watcher.Wait();
196 }
197 EXPECT_EQ(1, tab_strip->count());
198
199 content::WebContentsAddedObserver new_web_contents_observer;
200 chrome::RestoreTab(browser());
201 content::WebContents* web_contents =
202 new_web_contents_observer.GetWebContents();
203 content::WaitForLoadStop(web_contents);
204
205 EXPECT_EQ(2, tab_strip->count());
206
207 EXPECT_EQ(
208 content::PAGE_TYPE_ERROR,
209 web_contents->GetController().GetLastCommittedEntry()->GetPageType());
210
211 ZoomController* zoom_controller =
212 ZoomController::FromWebContents(web_contents);
213
214 double old_zoom_level = zoom_controller->GetZoomLevel();
215 double new_zoom_level = old_zoom_level + 0.5;
216
217 // The following attempt to change the zoom level for an error page should
218 // fail.
219 zoom_controller->SetZoomLevel(new_zoom_level);
220 EXPECT_FLOAT_EQ(new_zoom_level, zoom_controller->GetZoomLevel());
221}
222
wjmacleancaa7d6d2014-11-12 16:42:11223IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest, Observe) {
224 content::WebContents* web_contents =
225 browser()->tab_strip_model()->GetActiveWebContents();
wjmacleancaa7d6d2014-11-12 16:42:11226
227 double new_zoom_level = 1.0;
228 // When the event is initiated from HostZoomMap, the old zoom level is not
229 // available.
230 ZoomController::ZoomChangedEventData zoom_change_data(
231 web_contents,
232 new_zoom_level,
233 new_zoom_level,
234 ZoomController::ZOOM_MODE_DEFAULT,
235 true); // We have a non-empty host, so this will be 'true'.
wjmaclean7f63c6b2014-12-09 14:59:55236 ZoomChangedWatcher zoom_change_watcher(web_contents, zoom_change_data);
wjmacleancaa7d6d2014-11-12 16:42:11237
238 content::HostZoomMap* host_zoom_map =
239 content::HostZoomMap::GetDefaultForBrowserContext(
240 web_contents->GetBrowserContext());
241
242 host_zoom_map->SetZoomLevelForHost("about:blank", new_zoom_level);
wjmaclean7f63c6b2014-12-09 14:59:55243 zoom_change_watcher.Wait();
wjmacleancaa7d6d2014-11-12 16:42:11244}
wjmacleanc7bcb77d2014-12-16 15:05:38245
wjmacleand96f8642015-01-07 20:10:57246IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest, PerTabModeResetSendsEvent) {
wjmaclean96fc2e92015-01-28 20:42:11247 TestResetOnNavigation(ZoomController::ZOOM_MODE_ISOLATED);
248}
wjmacleand96f8642015-01-07 20:10:57249
wjmaclean96fc2e92015-01-28 20:42:11250// Regression test: crbug.com/450909.
251IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest, NavigationResetsManualMode) {
252 TestResetOnNavigation(ZoomController::ZOOM_MODE_MANUAL);
wjmacleand96f8642015-01-07 20:10:57253}
254
rogertae77304c2015-01-07 02:53:55255#if !defined(OS_CHROMEOS)
wjmacleanc7bcb77d2014-12-16 15:05:38256// Regression test: crbug.com/438979.
257IN_PROC_BROWSER_TEST_F(ZoomControllerBrowserTest,
258 SettingsZoomAfterSigninWorks) {
259 GURL signin_url(
260 std::string(chrome::kChromeUIChromeSigninURL).append("?source=0"));
261 // We open the signin page in a new tab so that the ZoomController is
262 // created against the HostZoomMap of the special StoragePartition that
263 // backs the signin page. When we subsequently navigate away from the
264 // signin page, the HostZoomMap changes, and we need to test that the
265 // ZoomController correctly detects this.
rogertae77304c2015-01-07 02:53:55266 ui_test_utils::NavigateToURLWithDisposition(
267 browser(), signin_url, NEW_FOREGROUND_TAB,
268 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
269 login_ui_test_utils::WaitUntilUIReady(browser());
wjmacleanc7bcb77d2014-12-16 15:05:38270 content::WebContents* web_contents =
271 browser()->tab_strip_model()->GetActiveWebContents();
272 EXPECT_NE(
273 content::PAGE_TYPE_ERROR,
274 web_contents->GetController().GetLastCommittedEntry()->GetPageType());
275
276 EXPECT_EQ(signin_url, web_contents->GetLastCommittedURL());
277 ZoomController* zoom_controller =
278 ZoomController::FromWebContents(web_contents);
279
280 content::HostZoomMap* host_zoom_map_signin =
281 content::HostZoomMap::GetForWebContents(web_contents);
282
283 GURL settings_url(chrome::kChromeUISettingsURL);
284 ui_test_utils::NavigateToURL(browser(), settings_url);
285 EXPECT_NE(
286 content::PAGE_TYPE_ERROR,
287 web_contents->GetController().GetLastCommittedEntry()->GetPageType());
288
289 // Verify new tab was created.
290 EXPECT_EQ(2, browser()->tab_strip_model()->count());
291 // Verify that the settings page is using the same WebContents.
292 EXPECT_EQ(web_contents, browser()->tab_strip_model()->GetActiveWebContents());
293 // TODO(wjmaclean): figure out why this next line fails, i.e. why does this
294 // test not properly trigger a navigation to the settings page.
295 EXPECT_EQ(settings_url, web_contents->GetLastCommittedURL());
296 EXPECT_EQ(zoom_controller, ZoomController::FromWebContents(web_contents));
297
rogertae77304c2015-01-07 02:53:55298 // For the webview based sign-in code, the sign in page uses the default host
299 // zoom map.
300 if (!switches::IsEnableWebviewBasedSignin()) {
301 // We expect the navigation from the chrome sign in page to the settings
302 // page to invoke a storage partition switch, and thus a different
303 // HostZoomMap for the web_contents.
304 content::HostZoomMap* host_zoom_map_settings =
305 content::HostZoomMap::GetForWebContents(web_contents);
306 EXPECT_NE(host_zoom_map_signin, host_zoom_map_settings);
307 }
wjmacleanc7bcb77d2014-12-16 15:05:38308
309 // If we zoom the new page, it should still generate a ZoomController event.
310 double old_zoom_level = zoom_controller->GetZoomLevel();
311 double new_zoom_level = old_zoom_level + 0.5;
312
313 ZoomController::ZoomChangedEventData zoom_change_data(
314 web_contents,
315 old_zoom_level,
316 new_zoom_level,
317 ZoomController::ZOOM_MODE_DEFAULT,
318 true); // We have a non-empty host, so this will be 'true'.
319 ZoomChangedWatcher zoom_change_watcher(web_contents, zoom_change_data);
320 zoom_controller->SetZoomLevel(new_zoom_level);
321 zoom_change_watcher.Wait();
322}
rogertae77304c2015-01-07 02:53:55323#endif // !defined(OS_CHROMEOS)