blob: 96267b1b368944ef3fc7f34a58614322350034f9 [file] [log] [blame]
[email protected]9f76c1e2012-03-05 15:15:581// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]40bd6582009-12-04 23:49:512// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]5c9250872012-01-30 17:24:055#include "content/browser/host_zoom_map_impl.h"
[email protected]40bd6582009-12-04 23:49:516
[email protected]fce823222014-05-30 16:24:307#include <algorithm>
[email protected]b9e7c479f2013-04-12 04:33:248#include <cmath>
Lukasz Anforowiczc773bbd2017-10-02 19:25:299#include <memory>
10#include <utility>
[email protected]b9e7c479f2013-04-12 04:33:2411
12#include "base/strings/string_piece.h"
[email protected]74ebfb12013-06-07 20:48:0013#include "base/strings/utf_string_conversions.h"
Christian Dullwebercc736c12017-09-04 09:27:5014#include "base/time/default_clock.h"
[email protected]d407cc02011-09-13 16:01:4615#include "base/values.h"
[email protected]fce823222014-05-30 16:24:3016#include "content/browser/frame_host/navigation_entry_impl.h"
[email protected]f3b1a082011-11-18 00:34:3017#include "content/browser/renderer_host/render_process_host_impl.h"
[email protected]b3c41c0b2012-03-06 15:48:3218#include "content/browser/renderer_host/render_view_host_impl.h"
[email protected]fce823222014-05-30 16:24:3019#include "content/browser/web_contents/web_contents_impl.h"
[email protected]4e2a25a2012-01-27 00:42:0820#include "content/common/view_messages.h"
21#include "content/public/browser/browser_context.h"
[email protected]c38831a12011-10-28 12:44:4922#include "content/public/browser/browser_thread.h"
Lukasz Anforowiczc773bbd2017-10-02 19:25:2923#include "content/public/browser/render_frame_host.h"
[email protected]5fe3713a2012-02-22 08:31:5624#include "content/public/browser/resource_context.h"
wjmacleancaa7d6d2014-11-12 16:42:1125#include "content/public/browser/site_instance.h"
26#include "content/public/browser/storage_partition.h"
[email protected]0f083402011-11-22 02:59:0127#include "content/public/common/page_zoom.h"
wjmacleande29ed52014-10-28 21:09:0628#include "content/public/common/url_constants.h"
tfarina7a4a7fd2016-01-20 14:23:4429#include "net/base/url_util.h"
[email protected]40bd6582009-12-04 23:49:5130
[email protected]5c9250872012-01-30 17:24:0531namespace content {
32
[email protected]d42bf472014-06-14 01:49:3833namespace {
34
35std::string GetHostFromProcessView(int render_process_id, int render_view_id) {
mostynb4c27d042015-03-18 21:47:4736 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]d42bf472014-06-14 01:49:3837 RenderViewHost* render_view_host =
38 RenderViewHost::FromID(render_process_id, render_view_id);
39 if (!render_view_host)
40 return std::string();
41
42 WebContents* web_contents = WebContents::FromRenderViewHost(render_view_host);
43
44 NavigationEntry* entry =
45 web_contents->GetController().GetLastCommittedEntry();
46 if (!entry)
47 return std::string();
48
wjmacleande29ed52014-10-28 21:09:0649 return net::GetHostOrSpecFromURL(HostZoomMap::GetURLFromEntry(entry));
[email protected]d42bf472014-06-14 01:49:3850}
51
52} // namespace
53
wjmacleande29ed52014-10-28 21:09:0654GURL HostZoomMap::GetURLFromEntry(const NavigationEntry* entry) {
Lei Zhang9d40e7902017-11-20 19:54:3655 DCHECK_CURRENTLY_ON(BrowserThread::UI);
wjmacleande29ed52014-10-28 21:09:0656 switch (entry->GetPageType()) {
57 case PAGE_TYPE_ERROR:
58 return GURL(kUnreachableWebDataURL);
59 // TODO(wjmaclean): In future, give interstitial pages special treatment as
60 // well.
61 default:
62 return entry->GetURL();
63 }
64}
65
wjmacleanf9b6ec82014-08-27 14:33:2466HostZoomMap* HostZoomMap::GetDefaultForBrowserContext(BrowserContext* context) {
Lei Zhang9d40e7902017-11-20 19:54:3667 DCHECK_CURRENTLY_ON(BrowserThread::UI);
wjmacleancaa7d6d2014-11-12 16:42:1168 StoragePartition* partition =
69 BrowserContext::GetDefaultStoragePartition(context);
70 DCHECK(partition);
71 return partition->GetHostZoomMap();
72}
73
74HostZoomMap* HostZoomMap::Get(SiteInstance* instance) {
Lei Zhang9d40e7902017-11-20 19:54:3675 DCHECK_CURRENTLY_ON(BrowserThread::UI);
wjmacleancaa7d6d2014-11-12 16:42:1176 StoragePartition* partition = BrowserContext::GetStoragePartition(
77 instance->GetBrowserContext(), instance);
78 DCHECK(partition);
79 return partition->GetHostZoomMap();
80}
81
82HostZoomMap* HostZoomMap::GetForWebContents(const WebContents* contents) {
Lei Zhang9d40e7902017-11-20 19:54:3683 DCHECK_CURRENTLY_ON(BrowserThread::UI);
mcnee432e47d2015-11-09 19:37:4684 // TODO(wjmaclean): Update this behaviour to work with OOPIF.
85 // See crbug.com/528407.
wjmacleancaa7d6d2014-11-12 16:42:1186 StoragePartition* partition =
87 BrowserContext::GetStoragePartition(contents->GetBrowserContext(),
88 contents->GetSiteInstance());
89 DCHECK(partition);
90 return partition->GetHostZoomMap();
[email protected]5c9250872012-01-30 17:24:0591}
92
[email protected]fce823222014-05-30 16:24:3093// Helper function for setting/getting zoom levels for WebContents without
94// having to import HostZoomMapImpl everywhere.
95double HostZoomMap::GetZoomLevel(const WebContents* web_contents) {
Lei Zhang9d40e7902017-11-20 19:54:3696 DCHECK_CURRENTLY_ON(BrowserThread::UI);
wjmacleancaa7d6d2014-11-12 16:42:1197 HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
98 HostZoomMap::GetForWebContents(web_contents));
[email protected]fce823222014-05-30 16:24:3099 return host_zoom_map->GetZoomLevelForWebContents(
100 *static_cast<const WebContentsImpl*>(web_contents));
101}
102
ccameronb7c1d6c2015-03-09 17:08:24103bool HostZoomMap::PageScaleFactorIsOne(const WebContents* web_contents) {
Lei Zhang9d40e7902017-11-20 19:54:36104 DCHECK_CURRENTLY_ON(BrowserThread::UI);
ccameronb7c1d6c2015-03-09 17:08:24105 HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
106 HostZoomMap::GetForWebContents(web_contents));
107 return host_zoom_map->PageScaleFactorIsOneForWebContents(
108 *static_cast<const WebContentsImpl*>(web_contents));
109}
110
[email protected]fce823222014-05-30 16:24:30111void HostZoomMap::SetZoomLevel(const WebContents* web_contents, double level) {
Lei Zhang9d40e7902017-11-20 19:54:36112 DCHECK_CURRENTLY_ON(BrowserThread::UI);
wjmacleancaa7d6d2014-11-12 16:42:11113 HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
114 HostZoomMap::GetForWebContents(web_contents));
[email protected]fce823222014-05-30 16:24:30115 host_zoom_map->SetZoomLevelForWebContents(
116 *static_cast<const WebContentsImpl*>(web_contents), level);
117}
118
wjmacleande29ed52014-10-28 21:09:06119void HostZoomMap::SendErrorPageZoomLevelRefresh(
120 const WebContents* web_contents) {
Lei Zhang9d40e7902017-11-20 19:54:36121 DCHECK_CURRENTLY_ON(BrowserThread::UI);
wjmacleande29ed52014-10-28 21:09:06122 HostZoomMapImpl* host_zoom_map =
123 static_cast<HostZoomMapImpl*>(HostZoomMap::GetDefaultForBrowserContext(
124 web_contents->GetBrowserContext()));
125 host_zoom_map->SendErrorPageZoomLevelRefresh();
126}
127
[email protected]5c9250872012-01-30 17:24:05128HostZoomMapImpl::HostZoomMapImpl()
Christian Dullwebercc736c12017-09-04 09:27:50129 : default_zoom_level_(0.0),
130 store_last_modified_(false),
tzik67025f672017-11-29 05:04:44131 clock_(base::DefaultClock::GetInstance()) {
Lei Zhang9d40e7902017-11-20 19:54:36132 DCHECK_CURRENTLY_ON(BrowserThread::UI);
133}
[email protected]40bd6582009-12-04 23:49:51134
[email protected]5c9250872012-01-30 17:24:05135void HostZoomMapImpl::CopyFrom(HostZoomMap* copy_interface) {
mostynb4c27d042015-03-18 21:47:47136 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]5c9250872012-01-30 17:24:05137 HostZoomMapImpl* copy = static_cast<HostZoomMapImpl*>(copy_interface);
Lei Zhang9d40e7902017-11-20 19:54:36138 host_zoom_levels_.insert(copy->host_zoom_levels_.begin(),
139 copy->host_zoom_levels_.end());
140 for (const auto& it : copy->scheme_host_zoom_levels_) {
141 const std::string& host = it.first;
142 scheme_host_zoom_levels_[host] = HostZoomLevels();
143 scheme_host_zoom_levels_[host].insert(it.second.begin(), it.second.end());
[email protected]4e2a25a2012-01-27 00:42:08144 }
[email protected]19d26692013-01-12 19:56:33145 default_zoom_level_ = copy->default_zoom_level_;
[email protected]4e2a25a2012-01-27 00:42:08146}
147
[email protected]367c5c1d2013-03-11 18:59:02148double HostZoomMapImpl::GetZoomLevelForHost(const std::string& host) const {
Lei Zhang9d40e7902017-11-20 19:54:36149 DCHECK_CURRENTLY_ON(BrowserThread::UI);
150 const auto it = host_zoom_levels_.find(host);
151 return it != host_zoom_levels_.end() ? it->second.level : default_zoom_level_;
[email protected]40bd6582009-12-04 23:49:51152}
153
[email protected]d42bf472014-06-14 01:49:38154bool HostZoomMapImpl::HasZoomLevel(const std::string& scheme,
155 const std::string& host) const {
Lei Zhang9d40e7902017-11-20 19:54:36156 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]d42bf472014-06-14 01:49:38157 SchemeHostZoomLevels::const_iterator scheme_iterator(
158 scheme_host_zoom_levels_.find(scheme));
159
160 const HostZoomLevels& zoom_levels =
161 (scheme_iterator != scheme_host_zoom_levels_.end())
162 ? scheme_iterator->second
163 : host_zoom_levels_;
164
Lei Zhang9d40e7902017-11-20 19:54:36165 return base::ContainsKey(zoom_levels, host);
[email protected]d42bf472014-06-14 01:49:38166}
167
Lei Zhang9d40e7902017-11-20 19:54:36168double HostZoomMapImpl::GetZoomLevelForHostAndScheme(
wjmacleanc62490492015-02-13 22:02:07169 const std::string& scheme,
170 const std::string& host) const {
Lei Zhang9d40e7902017-11-20 19:54:36171 DCHECK_CURRENTLY_ON(BrowserThread::UI);
wjmacleanc62490492015-02-13 22:02:07172 SchemeHostZoomLevels::const_iterator scheme_iterator(
173 scheme_host_zoom_levels_.find(scheme));
174 if (scheme_iterator != scheme_host_zoom_levels_.end()) {
175 HostZoomLevels::const_iterator i(scheme_iterator->second.find(host));
176 if (i != scheme_iterator->second.end())
Christian Dullwebercc736c12017-09-04 09:27:50177 return i->second.level;
wjmacleanc62490492015-02-13 22:02:07178 }
179
Lei Zhang9d40e7902017-11-20 19:54:36180 return GetZoomLevelForHost(host);
[email protected]367c5c1d2013-03-11 18:59:02181}
182
[email protected]0f374052014-03-18 20:37:22183HostZoomMap::ZoomLevelVector HostZoomMapImpl::GetAllZoomLevels() const {
Lei Zhang9d40e7902017-11-20 19:54:36184 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]0f374052014-03-18 20:37:22185 HostZoomMap::ZoomLevelVector result;
Lei Zhang9d40e7902017-11-20 19:54:36186 result.reserve(host_zoom_levels_.size() + scheme_host_zoom_levels_.size());
187 for (const auto& entry : host_zoom_levels_) {
188 ZoomLevelChange change = {
189 HostZoomMap::ZOOM_CHANGED_FOR_HOST,
190 entry.first, // host
191 std::string(), // scheme
192 entry.second.level, // zoom level
193 entry.second.last_modified // last modified
194 };
195 result.push_back(change);
196 }
197 for (const auto& scheme_entry : scheme_host_zoom_levels_) {
198 const std::string& scheme = scheme_entry.first;
199 const HostZoomLevels& host_zoom_levels = scheme_entry.second;
200 for (const auto& entry : host_zoom_levels) {
Christian Dullwebercc736c12017-09-04 09:27:50201 ZoomLevelChange change = {
Lei Zhang9d40e7902017-11-20 19:54:36202 HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST,
Christian Dullwebercc736c12017-09-04 09:27:50203 entry.first, // host
Lei Zhang9d40e7902017-11-20 19:54:36204 scheme, // scheme
Christian Dullwebercc736c12017-09-04 09:27:50205 entry.second.level, // zoom level
206 entry.second.last_modified // last modified
[email protected]0f374052014-03-18 20:37:22207 };
208 result.push_back(change);
209 }
[email protected]0f374052014-03-18 20:37:22210 }
211 return result;
212}
213
[email protected]367c5c1d2013-03-11 18:59:02214void HostZoomMapImpl::SetZoomLevelForHost(const std::string& host,
215 double level) {
Lei Zhang9d40e7902017-11-20 19:54:36216 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Christian Dullwebercc736c12017-09-04 09:27:50217 base::Time last_modified =
218 store_last_modified_ ? clock_->Now() : base::Time();
219 SetZoomLevelForHostInternal(host, level, last_modified);
220}
221
222void HostZoomMapImpl::InitializeZoomLevelForHost(const std::string& host,
223 double level,
224 base::Time last_modified) {
Lei Zhang9d40e7902017-11-20 19:54:36225 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Christian Dullwebercc736c12017-09-04 09:27:50226 SetZoomLevelForHostInternal(host, level, last_modified);
227}
228
229void HostZoomMapImpl::SetZoomLevelForHostInternal(const std::string& host,
230 double level,
231 base::Time last_modified) {
mostynb4c27d042015-03-18 21:47:47232 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]3ef4bc632010-04-09 04:25:31233
Lei Zhang9d40e7902017-11-20 19:54:36234 if (ZoomValuesEqual(level, default_zoom_level_)) {
235 host_zoom_levels_.erase(host);
236 } else {
237 ZoomLevel& zoomLevel = host_zoom_levels_[host];
238 zoomLevel.level = level;
239 zoomLevel.last_modified = last_modified;
[email protected]40bd6582009-12-04 23:49:51240 }
241
[email protected]d42bf472014-06-14 01:49:38242 // TODO(wjmaclean) Should we use a GURL here? crbug.com/384486
243 SendZoomLevelChange(std::string(), host, level);
244
[email protected]367c5c1d2013-03-11 18:59:02245 HostZoomMap::ZoomLevelChange change;
246 change.mode = HostZoomMap::ZOOM_CHANGED_FOR_HOST;
247 change.host = host;
248 change.zoom_level = level;
Christian Dullwebercc736c12017-09-04 09:27:50249 change.last_modified = last_modified;
[email protected]367c5c1d2013-03-11 18:59:02250
[email protected]117832812013-10-02 07:06:02251 zoom_level_changed_callbacks_.Notify(change);
[email protected]367c5c1d2013-03-11 18:59:02252}
253
254void HostZoomMapImpl::SetZoomLevelForHostAndScheme(const std::string& scheme,
255 const std::string& host,
256 double level) {
mostynb4c27d042015-03-18 21:47:47257 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Lei Zhang9d40e7902017-11-20 19:54:36258 // No last_modified timestamp for scheme and host because they are
259 // not persistet and are used for special cases only.
260 scheme_host_zoom_levels_[scheme][host].level = level;
[email protected]367c5c1d2013-03-11 18:59:02261
[email protected]d42bf472014-06-14 01:49:38262 SendZoomLevelChange(scheme, host, level);
[email protected]4e2a25a2012-01-27 00:42:08263
[email protected]367c5c1d2013-03-11 18:59:02264 HostZoomMap::ZoomLevelChange change;
265 change.mode = HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST;
266 change.host = host;
267 change.scheme = scheme;
268 change.zoom_level = level;
Christian Dullwebercc736c12017-09-04 09:27:50269 change.last_modified = base::Time();
[email protected]367c5c1d2013-03-11 18:59:02270
[email protected]117832812013-10-02 07:06:02271 zoom_level_changed_callbacks_.Notify(change);
[email protected]40bd6582009-12-04 23:49:51272}
273
[email protected]5c9250872012-01-30 17:24:05274double HostZoomMapImpl::GetDefaultZoomLevel() const {
mostynb4c27d042015-03-18 21:47:47275 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]5c9250872012-01-30 17:24:05276 return default_zoom_level_;
277}
278
279void HostZoomMapImpl::SetDefaultZoomLevel(double level) {
mostynb4c27d042015-03-18 21:47:47280 DCHECK_CURRENTLY_ON(BrowserThread::UI);
wjmaclean64951902016-04-29 20:59:12281
282 if (ZoomValuesEqual(level, default_zoom_level_))
283 return;
284
[email protected]5c9250872012-01-30 17:24:05285 default_zoom_level_ = level;
wjmaclean64951902016-04-29 20:59:12286
287 // First, remove all entries that match the new default zoom level.
Lei Zhang9d40e7902017-11-20 19:54:36288 for (auto it = host_zoom_levels_.begin(); it != host_zoom_levels_.end();) {
289 if (ZoomValuesEqual(it->second.level, default_zoom_level_))
290 it = host_zoom_levels_.erase(it);
291 else
292 it++;
wjmaclean64951902016-04-29 20:59:12293 }
294
295 // Second, update zoom levels for all pages that do not have an overriding
296 // entry.
vmpstr10e0d5f2016-07-21 23:46:09297 for (auto* web_contents : WebContentsImpl::GetAllWebContents()) {
wjmaclean64951902016-04-29 20:59:12298 // Only change zoom for WebContents tied to the StoragePartition this
299 // HostZoomMap serves.
300 if (GetForWebContents(web_contents) != this)
301 continue;
302
Lukasz Anforowiczc773bbd2017-10-02 19:25:29303 int render_process_id =
304 web_contents->GetRenderViewHost()->GetProcess()->GetID();
wjmaclean64951902016-04-29 20:59:12305 int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID();
306
307 // Get the url from the navigation controller directly, as calling
308 // WebContentsImpl::GetLastCommittedURL() may give us a virtual url that
309 // is different than the one stored in the map.
310 GURL url;
311 std::string host;
312 std::string scheme;
313
314 NavigationEntry* entry =
315 web_contents->GetController().GetLastCommittedEntry();
316 // It is possible for a WebContent's zoom level to be queried before
317 // a navigation has occurred.
318 if (entry) {
319 url = GetURLFromEntry(entry);
320 scheme = url.scheme();
321 host = net::GetHostOrSpecFromURL(url);
322 }
323
324 bool uses_default_zoom =
325 !HasZoomLevel(scheme, host) &&
326 !UsesTemporaryZoomLevel(render_process_id, render_view_id);
327
328 if (uses_default_zoom) {
329 web_contents->UpdateZoom(level);
330
331 HostZoomMap::ZoomLevelChange change;
332 change.mode = HostZoomMap::ZOOM_CHANGED_FOR_HOST;
333 change.host = host;
334 change.zoom_level = level;
335
336 zoom_level_changed_callbacks_.Notify(change);
337 }
338 }
[email protected]5c9250872012-01-30 17:24:05339}
340
dcheng59716272016-04-09 05:19:08341std::unique_ptr<HostZoomMap::Subscription>
[email protected]117832812013-10-02 07:06:02342HostZoomMapImpl::AddZoomLevelChangedCallback(
[email protected]89c9aca2013-02-07 15:08:42343 const ZoomLevelChangedCallback& callback) {
Lei Zhang9d40e7902017-11-20 19:54:36344 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]117832812013-10-02 07:06:02345 return zoom_level_changed_callbacks_.Add(callback);
[email protected]89c9aca2013-02-07 15:08:42346}
347
[email protected]fce823222014-05-30 16:24:30348double HostZoomMapImpl::GetZoomLevelForWebContents(
349 const WebContentsImpl& web_contents_impl) const {
Lei Zhang9d40e7902017-11-20 19:54:36350 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Lukasz Anforowiczc773bbd2017-10-02 19:25:29351 int render_process_id =
352 web_contents_impl.GetRenderViewHost()->GetProcess()->GetID();
[email protected]fce823222014-05-30 16:24:30353 int routing_id = web_contents_impl.GetRenderViewHost()->GetRoutingID();
354
355 if (UsesTemporaryZoomLevel(render_process_id, routing_id))
356 return GetTemporaryZoomLevel(render_process_id, routing_id);
357
[email protected]acda0ef32014-06-05 23:13:30358 // Get the url from the navigation controller directly, as calling
359 // WebContentsImpl::GetLastCommittedURL() may give us a virtual url that
360 // is different than is stored in the map.
[email protected]fce823222014-05-30 16:24:30361 GURL url;
362 NavigationEntry* entry =
363 web_contents_impl.GetController().GetLastCommittedEntry();
[email protected]acda0ef32014-06-05 23:13:30364 // It is possible for a WebContent's zoom level to be queried before
365 // a navigation has occurred.
[email protected]fce823222014-05-30 16:24:30366 if (entry)
wjmacleande29ed52014-10-28 21:09:06367 url = GetURLFromEntry(entry);
[email protected]fce823222014-05-30 16:24:30368 return GetZoomLevelForHostAndScheme(url.scheme(),
369 net::GetHostOrSpecFromURL(url));
370}
371
372void HostZoomMapImpl::SetZoomLevelForWebContents(
373 const WebContentsImpl& web_contents_impl,
374 double level) {
Lei Zhang9d40e7902017-11-20 19:54:36375 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Lukasz Anforowiczc773bbd2017-10-02 19:25:29376 int render_process_id =
377 web_contents_impl.GetRenderViewHost()->GetProcess()->GetID();
[email protected]fce823222014-05-30 16:24:30378 int render_view_id = web_contents_impl.GetRenderViewHost()->GetRoutingID();
379 if (UsesTemporaryZoomLevel(render_process_id, render_view_id)) {
[email protected]fce823222014-05-30 16:24:30380 SetTemporaryZoomLevel(render_process_id, render_view_id, level);
381 } else {
[email protected]acda0ef32014-06-05 23:13:30382 // Get the url from the navigation controller directly, as calling
383 // WebContentsImpl::GetLastCommittedURL() may give us a virtual url that
384 // is different than what the render view is using. If the two don't match,
385 // the attempt to set the zoom will fail.
[email protected]acda0ef32014-06-05 23:13:30386 NavigationEntry* entry =
387 web_contents_impl.GetController().GetLastCommittedEntry();
[email protected]f3b3e5e2014-06-10 15:47:41388 // Tests may invoke this function with a null entry, but we don't
389 // want to save zoom levels in this case.
390 if (!entry)
391 return;
392
wjmacleande29ed52014-10-28 21:09:06393 GURL url = GetURLFromEntry(entry);
[email protected]acda0ef32014-06-05 23:13:30394 SetZoomLevelForHost(net::GetHostOrSpecFromURL(url), level);
[email protected]fce823222014-05-30 16:24:30395 }
396}
397
398void HostZoomMapImpl::SetZoomLevelForView(int render_process_id,
399 int render_view_id,
400 double level,
401 const std::string& host) {
Lei Zhang9d40e7902017-11-20 19:54:36402 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]fce823222014-05-30 16:24:30403 if (UsesTemporaryZoomLevel(render_process_id, render_view_id))
404 SetTemporaryZoomLevel(render_process_id, render_view_id, level);
405 else
406 SetZoomLevelForHost(host, level);
407}
408
ccameronb7c1d6c2015-03-09 17:08:24409void HostZoomMapImpl::SetPageScaleFactorIsOneForView(int render_process_id,
410 int render_view_id,
411 bool is_one) {
Lei Zhang9d40e7902017-11-20 19:54:36412 DCHECK_CURRENTLY_ON(BrowserThread::UI);
413 view_page_scale_factors_are_one_[RenderViewKey(render_process_id,
414 render_view_id)] = is_one;
ccameronb7c1d6c2015-03-09 17:08:24415 HostZoomMap::ZoomLevelChange change;
416 change.mode = HostZoomMap::PAGE_SCALE_IS_ONE_CHANGED;
417 zoom_level_changed_callbacks_.Notify(change);
418}
419
420bool HostZoomMapImpl::PageScaleFactorIsOneForWebContents(
421 const WebContentsImpl& web_contents_impl) const {
Lei Zhang9d40e7902017-11-20 19:54:36422 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Lukasz Anforowiczc773bbd2017-10-02 19:25:29423 if (!web_contents_impl.GetRenderViewHost()->GetProcess())
ccameronb7c1d6c2015-03-09 17:08:24424 return true;
Lei Zhang9d40e7902017-11-20 19:54:36425
426 const auto it = view_page_scale_factors_are_one_.find(RenderViewKey(
Lukasz Anforowiczc773bbd2017-10-02 19:25:29427 web_contents_impl.GetRenderViewHost()->GetProcess()->GetID(),
428 web_contents_impl.GetRenderViewHost()->GetRoutingID()));
Lei Zhang9d40e7902017-11-20 19:54:36429 return it != view_page_scale_factors_are_one_.end() ? it->second : true;
ccameronb7c1d6c2015-03-09 17:08:24430}
431
432void HostZoomMapImpl::ClearPageScaleFactorIsOneForView(int render_process_id,
433 int render_view_id) {
Lei Zhang9d40e7902017-11-20 19:54:36434 DCHECK_CURRENTLY_ON(BrowserThread::UI);
ccameronb7c1d6c2015-03-09 17:08:24435 view_page_scale_factors_are_one_.erase(
436 RenderViewKey(render_process_id, render_view_id));
437}
438
[email protected]fce823222014-05-30 16:24:30439bool HostZoomMapImpl::UsesTemporaryZoomLevel(int render_process_id,
440 int render_view_id) const {
Lei Zhang9d40e7902017-11-20 19:54:36441 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]d42bf472014-06-14 01:49:38442 RenderViewKey key(render_process_id, render_view_id);
skyostil66bd67912016-08-12 12:33:11443 return base::ContainsKey(temporary_zoom_levels_, key);
[email protected]fce823222014-05-30 16:24:30444}
445
[email protected]5c9250872012-01-30 17:24:05446double HostZoomMapImpl::GetTemporaryZoomLevel(int render_process_id,
447 int render_view_id) const {
Lei Zhang9d40e7902017-11-20 19:54:36448 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]d42bf472014-06-14 01:49:38449 RenderViewKey key(render_process_id, render_view_id);
Lei Zhang9d40e7902017-11-20 19:54:36450 const auto it = temporary_zoom_levels_.find(key);
451 return it != temporary_zoom_levels_.end() ? it->second : 0;
[email protected]b75b8292010-10-01 07:28:25452}
453
[email protected]5c9250872012-01-30 17:24:05454void HostZoomMapImpl::SetTemporaryZoomLevel(int render_process_id,
455 int render_view_id,
456 double level) {
mostynb4c27d042015-03-18 21:47:47457 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]b75b8292010-10-01 07:28:25458
Lei Zhang9d40e7902017-11-20 19:54:36459 RenderViewKey key(render_process_id, render_view_id);
460 temporary_zoom_levels_[key] = level;
[email protected]b75b8292010-10-01 07:28:25461
wjmaclean64951902016-04-29 20:59:12462 WebContentsImpl* web_contents =
463 static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(
464 RenderViewHost::FromID(render_process_id, render_view_id)));
465 web_contents->SetTemporaryZoomLevel(level, true);
[email protected]d42bf472014-06-14 01:49:38466
[email protected]367c5c1d2013-03-11 18:59:02467 HostZoomMap::ZoomLevelChange change;
468 change.mode = HostZoomMap::ZOOM_CHANGED_TEMPORARY_ZOOM;
[email protected]d42bf472014-06-14 01:49:38469 change.host = GetHostFromProcessView(render_process_id, render_view_id);
[email protected]367c5c1d2013-03-11 18:59:02470 change.zoom_level = level;
471
[email protected]117832812013-10-02 07:06:02472 zoom_level_changed_callbacks_.Notify(change);
[email protected]b75b8292010-10-01 07:28:25473}
474
wjmacleanc62490492015-02-13 22:02:07475double HostZoomMapImpl::GetZoomLevelForView(const GURL& url,
476 int render_process_id,
477 int render_view_id) const {
Lei Zhang9d40e7902017-11-20 19:54:36478 DCHECK_CURRENTLY_ON(BrowserThread::UI);
wjmacleanc62490492015-02-13 22:02:07479 RenderViewKey key(render_process_id, render_view_id);
wjmacleanc62490492015-02-13 22:02:07480
skyostil66bd67912016-08-12 12:33:11481 if (base::ContainsKey(temporary_zoom_levels_, key))
wjmacleanc62490492015-02-13 22:02:07482 return temporary_zoom_levels_.find(key)->second;
483
Lei Zhang9d40e7902017-11-20 19:54:36484 return GetZoomLevelForHostAndScheme(url.scheme(),
485 net::GetHostOrSpecFromURL(url));
wjmacleanc62490492015-02-13 22:02:07486}
487
Christian Dullwebercc736c12017-09-04 09:27:50488void HostZoomMapImpl::ClearZoomLevels(base::Time delete_begin,
489 base::Time delete_end) {
Lei Zhang9d40e7902017-11-20 19:54:36490 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Christian Dullwebercc736c12017-09-04 09:27:50491 double default_zoom_level = GetDefaultZoomLevel();
Lei Zhang9d40e7902017-11-20 19:54:36492 for (const auto& zoom_level : GetAllZoomLevels()) {
Christian Dullwebercc736c12017-09-04 09:27:50493 if (zoom_level.scheme.empty() && delete_begin <= zoom_level.last_modified &&
494 (delete_end.is_null() || zoom_level.last_modified < delete_end)) {
495 SetZoomLevelForHost(zoom_level.host, default_zoom_level);
496 }
497 }
498}
499
500void HostZoomMapImpl::SetStoreLastModified(bool store_last_modified) {
Lei Zhang9d40e7902017-11-20 19:54:36501 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Christian Dullwebercc736c12017-09-04 09:27:50502 store_last_modified_ = store_last_modified;
503}
504
[email protected]d42bf472014-06-14 01:49:38505void HostZoomMapImpl::ClearTemporaryZoomLevel(int render_process_id,
506 int render_view_id) {
Lei Zhang9d40e7902017-11-20 19:54:36507 DCHECK_CURRENTLY_ON(BrowserThread::UI);
508 RenderViewKey key(render_process_id, render_view_id);
509 TemporaryZoomLevels::iterator it = temporary_zoom_levels_.find(key);
510 if (it == temporary_zoom_levels_.end())
511 return;
512
513 temporary_zoom_levels_.erase(it);
wjmaclean64951902016-04-29 20:59:12514 WebContentsImpl* web_contents =
515 static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(
516 RenderViewHost::FromID(render_process_id, render_view_id)));
517 web_contents->SetTemporaryZoomLevel(GetZoomLevelForHost(
518 GetHostFromProcessView(render_process_id, render_view_id)), false);
[email protected]d42bf472014-06-14 01:49:38519}
520
521void HostZoomMapImpl::SendZoomLevelChange(const std::string& scheme,
522 const std::string& host,
523 double level) {
Lei Zhang9d40e7902017-11-20 19:54:36524 DCHECK_CURRENTLY_ON(BrowserThread::UI);
wjmaclean64951902016-04-29 20:59:12525 // We'll only send to WebContents not using temporary zoom levels. The one
526 // other case of interest is where the renderer is hosting a plugin document;
527 // that should be reflected in our temporary zoom level map, but we will
528 // double check on the renderer side to avoid the possibility of any races.
vmpstr10e0d5f2016-07-21 23:46:09529 for (auto* web_contents : WebContentsImpl::GetAllWebContents()) {
wjmaclean64951902016-04-29 20:59:12530 // Only send zoom level changes to WebContents that are using this
531 // HostZoomMap.
532 if (GetForWebContents(web_contents) != this)
533 continue;
534
Lukasz Anforowiczc773bbd2017-10-02 19:25:29535 int render_process_id =
536 web_contents->GetRenderViewHost()->GetProcess()->GetID();
wjmaclean64951902016-04-29 20:59:12537 int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID();
538
539 if (!UsesTemporaryZoomLevel(render_process_id, render_view_id))
540 web_contents->UpdateZoomIfNecessary(scheme, host, level);
[email protected]d42bf472014-06-14 01:49:38541 }
542}
543
wjmacleande29ed52014-10-28 21:09:06544void HostZoomMapImpl::SendErrorPageZoomLevelRefresh() {
Lei Zhang9d40e7902017-11-20 19:54:36545 DCHECK_CURRENTLY_ON(BrowserThread::UI);
wjmacleande29ed52014-10-28 21:09:06546 GURL error_url(kUnreachableWebDataURL);
547 std::string host = net::GetHostOrSpecFromURL(error_url);
548 double error_page_zoom_level = GetZoomLevelForHost(host);
549
550 SendZoomLevelChange(std::string(), host, error_page_zoom_level);
551}
552
Sam McNallye741fd662017-08-30 02:07:50553void HostZoomMapImpl::WillCloseRenderView(int render_process_id,
554 int render_view_id) {
Lei Zhang9d40e7902017-11-20 19:54:36555 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Sam McNallye741fd662017-08-30 02:07:50556 ClearTemporaryZoomLevel(render_process_id, render_view_id);
557 ClearPageScaleFactorIsOneForView(render_process_id, render_view_id);
558}
559
[email protected]5c9250872012-01-30 17:24:05560HostZoomMapImpl::~HostZoomMapImpl() {
mostynb4c27d042015-03-18 21:47:47561 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]40bd6582009-12-04 23:49:51562}
[email protected]46488322012-10-30 03:22:20563
tzik67025f672017-11-29 05:04:44564void HostZoomMapImpl::SetClockForTesting(base::Clock* clock) {
565 clock_ = clock;
Christian Dullwebercc736c12017-09-04 09:27:50566}
567
[email protected]46488322012-10-30 03:22:20568} // namespace content