blob: 788ed10be5c1ea7463a4105cc8019e48c4c988df [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) {
55 switch (entry->GetPageType()) {
56 case PAGE_TYPE_ERROR:
57 return GURL(kUnreachableWebDataURL);
58 // TODO(wjmaclean): In future, give interstitial pages special treatment as
59 // well.
60 default:
61 return entry->GetURL();
62 }
63}
64
wjmacleanf9b6ec82014-08-27 14:33:2465HostZoomMap* HostZoomMap::GetDefaultForBrowserContext(BrowserContext* context) {
wjmacleancaa7d6d2014-11-12 16:42:1166 StoragePartition* partition =
67 BrowserContext::GetDefaultStoragePartition(context);
68 DCHECK(partition);
69 return partition->GetHostZoomMap();
70}
71
72HostZoomMap* HostZoomMap::Get(SiteInstance* instance) {
73 StoragePartition* partition = BrowserContext::GetStoragePartition(
74 instance->GetBrowserContext(), instance);
75 DCHECK(partition);
76 return partition->GetHostZoomMap();
77}
78
79HostZoomMap* HostZoomMap::GetForWebContents(const WebContents* contents) {
mcnee432e47d2015-11-09 19:37:4680 // TODO(wjmaclean): Update this behaviour to work with OOPIF.
81 // See crbug.com/528407.
wjmacleancaa7d6d2014-11-12 16:42:1182 StoragePartition* partition =
83 BrowserContext::GetStoragePartition(contents->GetBrowserContext(),
84 contents->GetSiteInstance());
85 DCHECK(partition);
86 return partition->GetHostZoomMap();
[email protected]5c9250872012-01-30 17:24:0587}
88
[email protected]fce823222014-05-30 16:24:3089// Helper function for setting/getting zoom levels for WebContents without
90// having to import HostZoomMapImpl everywhere.
91double HostZoomMap::GetZoomLevel(const WebContents* web_contents) {
wjmacleancaa7d6d2014-11-12 16:42:1192 HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
93 HostZoomMap::GetForWebContents(web_contents));
[email protected]fce823222014-05-30 16:24:3094 return host_zoom_map->GetZoomLevelForWebContents(
95 *static_cast<const WebContentsImpl*>(web_contents));
96}
97
ccameronb7c1d6c2015-03-09 17:08:2498bool HostZoomMap::PageScaleFactorIsOne(const WebContents* web_contents) {
99 HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
100 HostZoomMap::GetForWebContents(web_contents));
101 return host_zoom_map->PageScaleFactorIsOneForWebContents(
102 *static_cast<const WebContentsImpl*>(web_contents));
103}
104
[email protected]fce823222014-05-30 16:24:30105void HostZoomMap::SetZoomLevel(const WebContents* web_contents, double level) {
wjmacleancaa7d6d2014-11-12 16:42:11106 HostZoomMapImpl* host_zoom_map = static_cast<HostZoomMapImpl*>(
107 HostZoomMap::GetForWebContents(web_contents));
[email protected]fce823222014-05-30 16:24:30108 host_zoom_map->SetZoomLevelForWebContents(
109 *static_cast<const WebContentsImpl*>(web_contents), level);
110}
111
wjmacleande29ed52014-10-28 21:09:06112void HostZoomMap::SendErrorPageZoomLevelRefresh(
113 const WebContents* web_contents) {
114 HostZoomMapImpl* host_zoom_map =
115 static_cast<HostZoomMapImpl*>(HostZoomMap::GetDefaultForBrowserContext(
116 web_contents->GetBrowserContext()));
117 host_zoom_map->SendErrorPageZoomLevelRefresh();
118}
119
[email protected]5c9250872012-01-30 17:24:05120HostZoomMapImpl::HostZoomMapImpl()
Christian Dullwebercc736c12017-09-04 09:27:50121 : default_zoom_level_(0.0),
122 store_last_modified_(false),
123 clock_(new base::DefaultClock) {}
[email protected]40bd6582009-12-04 23:49:51124
[email protected]5c9250872012-01-30 17:24:05125void HostZoomMapImpl::CopyFrom(HostZoomMap* copy_interface) {
[email protected]4e2a25a2012-01-27 00:42:08126 // This can only be called on the UI thread to avoid deadlocks, otherwise
127 // UI: a.CopyFrom(b);
128 // IO: b.CopyFrom(a);
129 // can deadlock.
mostynb4c27d042015-03-18 21:47:47130 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]5c9250872012-01-30 17:24:05131 HostZoomMapImpl* copy = static_cast<HostZoomMapImpl*>(copy_interface);
[email protected]4e2a25a2012-01-27 00:42:08132 base::AutoLock auto_lock(lock_);
133 base::AutoLock copy_auto_lock(copy->lock_);
[email protected]367c5c1d2013-03-11 18:59:02134 host_zoom_levels_.
135 insert(copy->host_zoom_levels_.begin(), copy->host_zoom_levels_.end());
136 for (SchemeHostZoomLevels::const_iterator i(copy->
137 scheme_host_zoom_levels_.begin());
138 i != copy->scheme_host_zoom_levels_.end(); ++i) {
139 scheme_host_zoom_levels_[i->first] = HostZoomLevels();
140 scheme_host_zoom_levels_[i->first].
141 insert(i->second.begin(), i->second.end());
[email protected]4e2a25a2012-01-27 00:42:08142 }
[email protected]19d26692013-01-12 19:56:33143 default_zoom_level_ = copy->default_zoom_level_;
[email protected]4e2a25a2012-01-27 00:42:08144}
145
[email protected]367c5c1d2013-03-11 18:59:02146double HostZoomMapImpl::GetZoomLevelForHost(const std::string& host) const {
[email protected]20305ec2011-01-21 04:55:52147 base::AutoLock auto_lock(lock_);
wjmacleanc62490492015-02-13 22:02:07148 return GetZoomLevelForHostInternal(host);
149}
150
151double HostZoomMapImpl::GetZoomLevelForHostInternal(
152 const std::string& host) const {
[email protected]40bd6582009-12-04 23:49:51153 HostZoomLevels::const_iterator i(host_zoom_levels_.find(host));
Christian Dullwebercc736c12017-09-04 09:27:50154 return (i == host_zoom_levels_.end()) ? default_zoom_level_ : i->second.level;
[email protected]40bd6582009-12-04 23:49:51155}
156
[email protected]d42bf472014-06-14 01:49:38157bool HostZoomMapImpl::HasZoomLevel(const std::string& scheme,
158 const std::string& host) const {
159 base::AutoLock auto_lock(lock_);
160
161 SchemeHostZoomLevels::const_iterator scheme_iterator(
162 scheme_host_zoom_levels_.find(scheme));
163
164 const HostZoomLevels& zoom_levels =
165 (scheme_iterator != scheme_host_zoom_levels_.end())
166 ? scheme_iterator->second
167 : host_zoom_levels_;
168
169 HostZoomLevels::const_iterator i(zoom_levels.find(host));
170 return i != zoom_levels.end();
171}
172
wjmacleanc62490492015-02-13 22:02:07173double HostZoomMapImpl::GetZoomLevelForHostAndSchemeInternal(
174 const std::string& scheme,
175 const std::string& host) const {
176 SchemeHostZoomLevels::const_iterator scheme_iterator(
177 scheme_host_zoom_levels_.find(scheme));
178 if (scheme_iterator != scheme_host_zoom_levels_.end()) {
179 HostZoomLevels::const_iterator i(scheme_iterator->second.find(host));
180 if (i != scheme_iterator->second.end())
Christian Dullwebercc736c12017-09-04 09:27:50181 return i->second.level;
wjmacleanc62490492015-02-13 22:02:07182 }
183
184 return GetZoomLevelForHostInternal(host);
185}
186
[email protected]367c5c1d2013-03-11 18:59:02187double HostZoomMapImpl::GetZoomLevelForHostAndScheme(
188 const std::string& scheme,
189 const std::string& host) const {
wjmacleanc62490492015-02-13 22:02:07190 base::AutoLock auto_lock(lock_);
191 return GetZoomLevelForHostAndSchemeInternal(scheme, host);
[email protected]367c5c1d2013-03-11 18:59:02192}
193
[email protected]0f374052014-03-18 20:37:22194HostZoomMap::ZoomLevelVector HostZoomMapImpl::GetAllZoomLevels() const {
195 HostZoomMap::ZoomLevelVector result;
196 {
197 base::AutoLock auto_lock(lock_);
198 result.reserve(host_zoom_levels_.size() + scheme_host_zoom_levels_.size());
Christian Dullwebercc736c12017-09-04 09:27:50199 for (const auto& entry : host_zoom_levels_) {
200 ZoomLevelChange change = {
201 HostZoomMap::ZOOM_CHANGED_FOR_HOST,
202 entry.first, // host
203 std::string(), // scheme
204 entry.second.level, // zoom level
205 entry.second.last_modified // last modified
[email protected]0f374052014-03-18 20:37:22206 };
207 result.push_back(change);
208 }
Christian Dullwebercc736c12017-09-04 09:27:50209 for (const auto& scheme_entry : scheme_host_zoom_levels_) {
210 const std::string& scheme = scheme_entry.first;
211 const HostZoomLevels& host_zoom_levels = scheme_entry.second;
212 for (const auto& entry : host_zoom_levels) {
213 ZoomLevelChange change = {
214 HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST,
215 entry.first, // host
216 scheme, // scheme
217 entry.second.level, // zoom level
218 entry.second.last_modified // last modified
[email protected]0f374052014-03-18 20:37:22219 };
220 result.push_back(change);
221 }
222 }
223 }
224 return result;
225}
226
[email protected]367c5c1d2013-03-11 18:59:02227void HostZoomMapImpl::SetZoomLevelForHost(const std::string& host,
228 double level) {
Christian Dullwebercc736c12017-09-04 09:27:50229 base::Time last_modified =
230 store_last_modified_ ? clock_->Now() : base::Time();
231 SetZoomLevelForHostInternal(host, level, last_modified);
232}
233
234void HostZoomMapImpl::InitializeZoomLevelForHost(const std::string& host,
235 double level,
236 base::Time last_modified) {
237 SetZoomLevelForHostInternal(host, level, last_modified);
238}
239
240void HostZoomMapImpl::SetZoomLevelForHostInternal(const std::string& host,
241 double level,
242 base::Time last_modified) {
mostynb4c27d042015-03-18 21:47:47243 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]3ef4bc632010-04-09 04:25:31244
[email protected]40bd6582009-12-04 23:49:51245 {
[email protected]20305ec2011-01-21 04:55:52246 base::AutoLock auto_lock(lock_);
[email protected]0f083402011-11-22 02:59:01247
Christian Dullwebercc736c12017-09-04 09:27:50248 if (ZoomValuesEqual(level, default_zoom_level_)) {
[email protected]40bd6582009-12-04 23:49:51249 host_zoom_levels_.erase(host);
Christian Dullwebercc736c12017-09-04 09:27:50250 } else {
251 ZoomLevel& zoomLevel = host_zoom_levels_[host];
252 zoomLevel.level = level;
253 zoomLevel.last_modified = last_modified;
254 }
[email protected]40bd6582009-12-04 23:49:51255 }
256
[email protected]d42bf472014-06-14 01:49:38257 // TODO(wjmaclean) Should we use a GURL here? crbug.com/384486
258 SendZoomLevelChange(std::string(), host, level);
259
[email protected]367c5c1d2013-03-11 18:59:02260 HostZoomMap::ZoomLevelChange change;
261 change.mode = HostZoomMap::ZOOM_CHANGED_FOR_HOST;
262 change.host = host;
263 change.zoom_level = level;
Christian Dullwebercc736c12017-09-04 09:27:50264 change.last_modified = last_modified;
[email protected]367c5c1d2013-03-11 18:59:02265
[email protected]117832812013-10-02 07:06:02266 zoom_level_changed_callbacks_.Notify(change);
[email protected]367c5c1d2013-03-11 18:59:02267}
268
269void HostZoomMapImpl::SetZoomLevelForHostAndScheme(const std::string& scheme,
270 const std::string& host,
271 double level) {
mostynb4c27d042015-03-18 21:47:47272 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]367c5c1d2013-03-11 18:59:02273 {
274 base::AutoLock auto_lock(lock_);
Christian Dullwebercc736c12017-09-04 09:27:50275 // No last_modified timestamp for scheme and host because they are
276 // not persistet and are used for special cases only.
277 scheme_host_zoom_levels_[scheme][host].level = level;
[email protected]367c5c1d2013-03-11 18:59:02278 }
279
[email protected]d42bf472014-06-14 01:49:38280 SendZoomLevelChange(scheme, host, level);
[email protected]4e2a25a2012-01-27 00:42:08281
[email protected]367c5c1d2013-03-11 18:59:02282 HostZoomMap::ZoomLevelChange change;
283 change.mode = HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST;
284 change.host = host;
285 change.scheme = scheme;
286 change.zoom_level = level;
Christian Dullwebercc736c12017-09-04 09:27:50287 change.last_modified = base::Time();
[email protected]367c5c1d2013-03-11 18:59:02288
[email protected]117832812013-10-02 07:06:02289 zoom_level_changed_callbacks_.Notify(change);
[email protected]40bd6582009-12-04 23:49:51290}
291
[email protected]5c9250872012-01-30 17:24:05292double HostZoomMapImpl::GetDefaultZoomLevel() const {
mostynb4c27d042015-03-18 21:47:47293 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]5c9250872012-01-30 17:24:05294 return default_zoom_level_;
295}
296
297void HostZoomMapImpl::SetDefaultZoomLevel(double level) {
mostynb4c27d042015-03-18 21:47:47298 DCHECK_CURRENTLY_ON(BrowserThread::UI);
wjmaclean64951902016-04-29 20:59:12299
300 if (ZoomValuesEqual(level, default_zoom_level_))
301 return;
302
[email protected]5c9250872012-01-30 17:24:05303 default_zoom_level_ = level;
wjmaclean64951902016-04-29 20:59:12304
305 // First, remove all entries that match the new default zoom level.
306 {
307 base::AutoLock auto_lock(lock_);
308 for (auto it = host_zoom_levels_.begin(); it != host_zoom_levels_.end(); ) {
Christian Dullwebercc736c12017-09-04 09:27:50309 if (ZoomValuesEqual(it->second.level, default_zoom_level_))
wjmaclean64951902016-04-29 20:59:12310 it = host_zoom_levels_.erase(it);
311 else
312 it++;
313 }
314 }
315
316 // Second, update zoom levels for all pages that do not have an overriding
317 // entry.
vmpstr10e0d5f2016-07-21 23:46:09318 for (auto* web_contents : WebContentsImpl::GetAllWebContents()) {
wjmaclean64951902016-04-29 20:59:12319 // Only change zoom for WebContents tied to the StoragePartition this
320 // HostZoomMap serves.
321 if (GetForWebContents(web_contents) != this)
322 continue;
323
Lukasz Anforowiczc773bbd2017-10-02 19:25:29324 int render_process_id =
325 web_contents->GetRenderViewHost()->GetProcess()->GetID();
wjmaclean64951902016-04-29 20:59:12326 int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID();
327
328 // Get the url from the navigation controller directly, as calling
329 // WebContentsImpl::GetLastCommittedURL() may give us a virtual url that
330 // is different than the one stored in the map.
331 GURL url;
332 std::string host;
333 std::string scheme;
334
335 NavigationEntry* entry =
336 web_contents->GetController().GetLastCommittedEntry();
337 // It is possible for a WebContent's zoom level to be queried before
338 // a navigation has occurred.
339 if (entry) {
340 url = GetURLFromEntry(entry);
341 scheme = url.scheme();
342 host = net::GetHostOrSpecFromURL(url);
343 }
344
345 bool uses_default_zoom =
346 !HasZoomLevel(scheme, host) &&
347 !UsesTemporaryZoomLevel(render_process_id, render_view_id);
348
349 if (uses_default_zoom) {
350 web_contents->UpdateZoom(level);
351
352 HostZoomMap::ZoomLevelChange change;
353 change.mode = HostZoomMap::ZOOM_CHANGED_FOR_HOST;
354 change.host = host;
355 change.zoom_level = level;
356
357 zoom_level_changed_callbacks_.Notify(change);
358 }
359 }
[email protected]5c9250872012-01-30 17:24:05360}
361
dcheng59716272016-04-09 05:19:08362std::unique_ptr<HostZoomMap::Subscription>
[email protected]117832812013-10-02 07:06:02363HostZoomMapImpl::AddZoomLevelChangedCallback(
[email protected]89c9aca2013-02-07 15:08:42364 const ZoomLevelChangedCallback& callback) {
[email protected]117832812013-10-02 07:06:02365 return zoom_level_changed_callbacks_.Add(callback);
[email protected]89c9aca2013-02-07 15:08:42366}
367
[email protected]fce823222014-05-30 16:24:30368double HostZoomMapImpl::GetZoomLevelForWebContents(
369 const WebContentsImpl& web_contents_impl) const {
Lukasz Anforowiczc773bbd2017-10-02 19:25:29370 int render_process_id =
371 web_contents_impl.GetRenderViewHost()->GetProcess()->GetID();
[email protected]fce823222014-05-30 16:24:30372 int routing_id = web_contents_impl.GetRenderViewHost()->GetRoutingID();
373
374 if (UsesTemporaryZoomLevel(render_process_id, routing_id))
375 return GetTemporaryZoomLevel(render_process_id, routing_id);
376
[email protected]acda0ef32014-06-05 23:13:30377 // Get the url from the navigation controller directly, as calling
378 // WebContentsImpl::GetLastCommittedURL() may give us a virtual url that
379 // is different than is stored in the map.
[email protected]fce823222014-05-30 16:24:30380 GURL url;
381 NavigationEntry* entry =
382 web_contents_impl.GetController().GetLastCommittedEntry();
[email protected]acda0ef32014-06-05 23:13:30383 // It is possible for a WebContent's zoom level to be queried before
384 // a navigation has occurred.
[email protected]fce823222014-05-30 16:24:30385 if (entry)
wjmacleande29ed52014-10-28 21:09:06386 url = GetURLFromEntry(entry);
[email protected]fce823222014-05-30 16:24:30387 return GetZoomLevelForHostAndScheme(url.scheme(),
388 net::GetHostOrSpecFromURL(url));
389}
390
391void HostZoomMapImpl::SetZoomLevelForWebContents(
392 const WebContentsImpl& web_contents_impl,
393 double level) {
Lukasz Anforowiczc773bbd2017-10-02 19:25:29394 int render_process_id =
395 web_contents_impl.GetRenderViewHost()->GetProcess()->GetID();
[email protected]fce823222014-05-30 16:24:30396 int render_view_id = web_contents_impl.GetRenderViewHost()->GetRoutingID();
397 if (UsesTemporaryZoomLevel(render_process_id, render_view_id)) {
[email protected]fce823222014-05-30 16:24:30398 SetTemporaryZoomLevel(render_process_id, render_view_id, level);
399 } else {
[email protected]acda0ef32014-06-05 23:13:30400 // Get the url from the navigation controller directly, as calling
401 // WebContentsImpl::GetLastCommittedURL() may give us a virtual url that
402 // is different than what the render view is using. If the two don't match,
403 // the attempt to set the zoom will fail.
[email protected]acda0ef32014-06-05 23:13:30404 NavigationEntry* entry =
405 web_contents_impl.GetController().GetLastCommittedEntry();
[email protected]f3b3e5e2014-06-10 15:47:41406 // Tests may invoke this function with a null entry, but we don't
407 // want to save zoom levels in this case.
408 if (!entry)
409 return;
410
wjmacleande29ed52014-10-28 21:09:06411 GURL url = GetURLFromEntry(entry);
[email protected]acda0ef32014-06-05 23:13:30412 SetZoomLevelForHost(net::GetHostOrSpecFromURL(url), level);
[email protected]fce823222014-05-30 16:24:30413 }
414}
415
416void HostZoomMapImpl::SetZoomLevelForView(int render_process_id,
417 int render_view_id,
418 double level,
419 const std::string& host) {
420 if (UsesTemporaryZoomLevel(render_process_id, render_view_id))
421 SetTemporaryZoomLevel(render_process_id, render_view_id, level);
422 else
423 SetZoomLevelForHost(host, level);
424}
425
ccameronb7c1d6c2015-03-09 17:08:24426void HostZoomMapImpl::SetPageScaleFactorIsOneForView(int render_process_id,
427 int render_view_id,
428 bool is_one) {
429 {
430 base::AutoLock auto_lock(lock_);
431 view_page_scale_factors_are_one_[RenderViewKey(render_process_id,
432 render_view_id)] = is_one;
433 }
434 HostZoomMap::ZoomLevelChange change;
435 change.mode = HostZoomMap::PAGE_SCALE_IS_ONE_CHANGED;
436 zoom_level_changed_callbacks_.Notify(change);
437}
438
439bool HostZoomMapImpl::PageScaleFactorIsOneForWebContents(
440 const WebContentsImpl& web_contents_impl) const {
Lukasz Anforowiczc773bbd2017-10-02 19:25:29441 if (!web_contents_impl.GetRenderViewHost()->GetProcess())
ccameronb7c1d6c2015-03-09 17:08:24442 return true;
443 base::AutoLock auto_lock(lock_);
Lukasz Anforowiczc773bbd2017-10-02 19:25:29444 auto found = view_page_scale_factors_are_one_.find(RenderViewKey(
445 web_contents_impl.GetRenderViewHost()->GetProcess()->GetID(),
446 web_contents_impl.GetRenderViewHost()->GetRoutingID()));
ccameronb7c1d6c2015-03-09 17:08:24447 if (found == view_page_scale_factors_are_one_.end())
448 return true;
449 return found->second;
450}
451
452void HostZoomMapImpl::ClearPageScaleFactorIsOneForView(int render_process_id,
453 int render_view_id) {
454 base::AutoLock auto_lock(lock_);
455 view_page_scale_factors_are_one_.erase(
456 RenderViewKey(render_process_id, render_view_id));
457}
458
[email protected]fce823222014-05-30 16:24:30459bool HostZoomMapImpl::UsesTemporaryZoomLevel(int render_process_id,
460 int render_view_id) const {
[email protected]d42bf472014-06-14 01:49:38461 RenderViewKey key(render_process_id, render_view_id);
[email protected]fce823222014-05-30 16:24:30462
463 base::AutoLock auto_lock(lock_);
skyostil66bd67912016-08-12 12:33:11464 return base::ContainsKey(temporary_zoom_levels_, key);
[email protected]fce823222014-05-30 16:24:30465}
466
[email protected]5c9250872012-01-30 17:24:05467double HostZoomMapImpl::GetTemporaryZoomLevel(int render_process_id,
468 int render_view_id) const {
[email protected]20305ec2011-01-21 04:55:52469 base::AutoLock auto_lock(lock_);
[email protected]d42bf472014-06-14 01:49:38470 RenderViewKey key(render_process_id, render_view_id);
skyostil66bd67912016-08-12 12:33:11471 if (!base::ContainsKey(temporary_zoom_levels_, key))
[email protected]d42bf472014-06-14 01:49:38472 return 0;
[email protected]fce823222014-05-30 16:24:30473
[email protected]d42bf472014-06-14 01:49:38474 return temporary_zoom_levels_.find(key)->second;
[email protected]b75b8292010-10-01 07:28:25475}
476
[email protected]5c9250872012-01-30 17:24:05477void HostZoomMapImpl::SetTemporaryZoomLevel(int render_process_id,
478 int render_view_id,
479 double level) {
mostynb4c27d042015-03-18 21:47:47480 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]b75b8292010-10-01 07:28:25481
482 {
[email protected]d42bf472014-06-14 01:49:38483 RenderViewKey key(render_process_id, render_view_id);
[email protected]20305ec2011-01-21 04:55:52484 base::AutoLock auto_lock(lock_);
[email protected]d42bf472014-06-14 01:49:38485 temporary_zoom_levels_[key] = level;
[email protected]b75b8292010-10-01 07:28:25486 }
487
wjmaclean64951902016-04-29 20:59:12488 WebContentsImpl* web_contents =
489 static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(
490 RenderViewHost::FromID(render_process_id, render_view_id)));
491 web_contents->SetTemporaryZoomLevel(level, true);
[email protected]d42bf472014-06-14 01:49:38492
[email protected]367c5c1d2013-03-11 18:59:02493 HostZoomMap::ZoomLevelChange change;
494 change.mode = HostZoomMap::ZOOM_CHANGED_TEMPORARY_ZOOM;
[email protected]d42bf472014-06-14 01:49:38495 change.host = GetHostFromProcessView(render_process_id, render_view_id);
[email protected]367c5c1d2013-03-11 18:59:02496 change.zoom_level = level;
497
[email protected]117832812013-10-02 07:06:02498 zoom_level_changed_callbacks_.Notify(change);
[email protected]b75b8292010-10-01 07:28:25499}
500
wjmacleanc62490492015-02-13 22:02:07501double HostZoomMapImpl::GetZoomLevelForView(const GURL& url,
502 int render_process_id,
503 int render_view_id) const {
504 RenderViewKey key(render_process_id, render_view_id);
505 base::AutoLock auto_lock(lock_);
506
skyostil66bd67912016-08-12 12:33:11507 if (base::ContainsKey(temporary_zoom_levels_, key))
wjmacleanc62490492015-02-13 22:02:07508 return temporary_zoom_levels_.find(key)->second;
509
510 return GetZoomLevelForHostAndSchemeInternal(url.scheme(),
511 net::GetHostOrSpecFromURL(url));
512}
513
Christian Dullwebercc736c12017-09-04 09:27:50514void HostZoomMapImpl::ClearZoomLevels(base::Time delete_begin,
515 base::Time delete_end) {
516 double default_zoom_level = GetDefaultZoomLevel();
517 for (auto& zoom_level : GetAllZoomLevels()) {
518 if (zoom_level.scheme.empty() && delete_begin <= zoom_level.last_modified &&
519 (delete_end.is_null() || zoom_level.last_modified < delete_end)) {
520 SetZoomLevelForHost(zoom_level.host, default_zoom_level);
521 }
522 }
523}
524
525void HostZoomMapImpl::SetStoreLastModified(bool store_last_modified) {
526 store_last_modified_ = store_last_modified;
527}
528
[email protected]d42bf472014-06-14 01:49:38529void HostZoomMapImpl::ClearTemporaryZoomLevel(int render_process_id,
530 int render_view_id) {
531 {
532 base::AutoLock auto_lock(lock_);
533 RenderViewKey key(render_process_id, render_view_id);
534 TemporaryZoomLevels::iterator it = temporary_zoom_levels_.find(key);
535 if (it == temporary_zoom_levels_.end())
536 return;
537 temporary_zoom_levels_.erase(it);
538 }
wjmaclean64951902016-04-29 20:59:12539 WebContentsImpl* web_contents =
540 static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(
541 RenderViewHost::FromID(render_process_id, render_view_id)));
542 web_contents->SetTemporaryZoomLevel(GetZoomLevelForHost(
543 GetHostFromProcessView(render_process_id, render_view_id)), false);
[email protected]d42bf472014-06-14 01:49:38544}
545
546void HostZoomMapImpl::SendZoomLevelChange(const std::string& scheme,
547 const std::string& host,
548 double level) {
wjmaclean64951902016-04-29 20:59:12549 // We'll only send to WebContents not using temporary zoom levels. The one
550 // other case of interest is where the renderer is hosting a plugin document;
551 // that should be reflected in our temporary zoom level map, but we will
552 // double check on the renderer side to avoid the possibility of any races.
vmpstr10e0d5f2016-07-21 23:46:09553 for (auto* web_contents : WebContentsImpl::GetAllWebContents()) {
wjmaclean64951902016-04-29 20:59:12554 // Only send zoom level changes to WebContents that are using this
555 // HostZoomMap.
556 if (GetForWebContents(web_contents) != this)
557 continue;
558
Lukasz Anforowiczc773bbd2017-10-02 19:25:29559 int render_process_id =
560 web_contents->GetRenderViewHost()->GetProcess()->GetID();
wjmaclean64951902016-04-29 20:59:12561 int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID();
562
563 if (!UsesTemporaryZoomLevel(render_process_id, render_view_id))
564 web_contents->UpdateZoomIfNecessary(scheme, host, level);
[email protected]d42bf472014-06-14 01:49:38565 }
566}
567
wjmacleande29ed52014-10-28 21:09:06568void HostZoomMapImpl::SendErrorPageZoomLevelRefresh() {
569 GURL error_url(kUnreachableWebDataURL);
570 std::string host = net::GetHostOrSpecFromURL(error_url);
571 double error_page_zoom_level = GetZoomLevelForHost(host);
572
573 SendZoomLevelChange(std::string(), host, error_page_zoom_level);
574}
575
Sam McNallye741fd662017-08-30 02:07:50576void HostZoomMapImpl::WillCloseRenderView(int render_process_id,
577 int render_view_id) {
578 ClearTemporaryZoomLevel(render_process_id, render_view_id);
579 ClearPageScaleFactorIsOneForView(render_process_id, render_view_id);
580}
581
[email protected]5c9250872012-01-30 17:24:05582HostZoomMapImpl::~HostZoomMapImpl() {
mostynb4c27d042015-03-18 21:47:47583 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]40bd6582009-12-04 23:49:51584}
[email protected]46488322012-10-30 03:22:20585
Christian Dullwebercc736c12017-09-04 09:27:50586void HostZoomMapImpl::SetClockForTesting(std::unique_ptr<base::Clock> clock) {
587 clock_ = std::move(clock);
588}
589
[email protected]46488322012-10-30 03:22:20590} // namespace content