1 // 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.
7 #include "content/browser/host_zoom_map_impl.h"
9 #include "base/string_piece.h"
10 #include "base/utf_string_conversions.h"
11 #include "base/values.h"
12 #include "content/browser/renderer_host/render_process_host_impl.h"
13 #include "content/browser/renderer_host/render_view_host_impl.h"
14 #include "content/common/view_messages.h"
15 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/notification_service.h"
18 #include "content/public/browser/notification_types.h"
19 #include "content/public/browser/resource_context.h"
20 #include "content/public/common/page_zoom.h"
21 #include "googleurl/src/gurl.h"
22 #include "net/base/net_util.h"
23 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
25 using WebKit::WebView
;
27 static const char* kHostZoomMapKeyName
= "content_host_zoom_map";
31 HostZoomMap
* HostZoomMap::GetForBrowserContext(BrowserContext
* context
) {
32 HostZoomMapImpl
* rv
= static_cast<HostZoomMapImpl
*>(
33 context
->GetUserData(kHostZoomMapKeyName
));
35 rv
= new HostZoomMapImpl();
36 context
->SetUserData(kHostZoomMapKeyName
, rv
);
41 HostZoomMapImpl::HostZoomMapImpl()
42 : default_zoom_level_(0.0) {
44 this, NOTIFICATION_RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW
,
45 NotificationService::AllSources());
48 void HostZoomMapImpl::CopyFrom(HostZoomMap
* copy_interface
) {
49 // This can only be called on the UI thread to avoid deadlocks, otherwise
53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
54 HostZoomMapImpl
* copy
= static_cast<HostZoomMapImpl
*>(copy_interface
);
55 base::AutoLock
auto_lock(lock_
);
56 base::AutoLock
copy_auto_lock(copy
->lock_
);
57 for (HostZoomLevels::const_iterator
i(copy
->host_zoom_levels_
.begin());
58 i
!= copy
->host_zoom_levels_
.end(); ++i
) {
59 host_zoom_levels_
[i
->first
] = i
->second
;
61 default_zoom_level_
= copy
->default_zoom_level_
;
64 double HostZoomMapImpl::GetZoomLevel(const std::string
& host
) const {
65 base::AutoLock
auto_lock(lock_
);
66 HostZoomLevels::const_iterator
i(host_zoom_levels_
.find(host
));
67 return (i
== host_zoom_levels_
.end()) ? default_zoom_level_
: i
->second
;
70 void HostZoomMapImpl::SetZoomLevel(const std::string
& host
, double level
) {
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
74 base::AutoLock
auto_lock(lock_
);
76 if (ZoomValuesEqual(level
, default_zoom_level_
))
77 host_zoom_levels_
.erase(host
);
79 host_zoom_levels_
[host
] = level
;
82 // Notify renderers from this browser context.
83 for (RenderProcessHost::iterator
i(RenderProcessHost::AllHostsIterator());
84 !i
.IsAtEnd(); i
.Advance()) {
85 RenderProcessHost
* render_process_host
= i
.GetCurrentValue();
86 if (HostZoomMap::GetForBrowserContext(
87 render_process_host
->GetBrowserContext()) == this) {
88 render_process_host
->Send(
89 new ViewMsg_SetZoomLevelForCurrentURL(host
, level
));
93 NotificationService::current()->Notify(
94 NOTIFICATION_ZOOM_LEVEL_CHANGED
,
95 Source
<HostZoomMap
>(this),
96 Details
<const std::string
>(&host
));
99 double HostZoomMapImpl::GetDefaultZoomLevel() const {
100 return default_zoom_level_
;
103 void HostZoomMapImpl::SetDefaultZoomLevel(double level
) {
104 default_zoom_level_
= level
;
107 double HostZoomMapImpl::GetTemporaryZoomLevel(int render_process_id
,
108 int render_view_id
) const {
109 base::AutoLock
auto_lock(lock_
);
110 for (size_t i
= 0; i
< temporary_zoom_levels_
.size(); ++i
) {
111 if (temporary_zoom_levels_
[i
].render_process_id
== render_process_id
&&
112 temporary_zoom_levels_
[i
].render_view_id
== render_view_id
) {
113 return temporary_zoom_levels_
[i
].zoom_level
;
119 void HostZoomMapImpl::SetTemporaryZoomLevel(int render_process_id
,
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
125 base::AutoLock
auto_lock(lock_
);
127 for (i
= 0; i
< temporary_zoom_levels_
.size(); ++i
) {
128 if (temporary_zoom_levels_
[i
].render_process_id
== render_process_id
&&
129 temporary_zoom_levels_
[i
].render_view_id
== render_view_id
) {
131 temporary_zoom_levels_
[i
].zoom_level
= level
;
133 temporary_zoom_levels_
.erase(temporary_zoom_levels_
.begin() + i
);
139 if (level
&& i
== temporary_zoom_levels_
.size()) {
140 TemporaryZoomLevel temp
;
141 temp
.render_process_id
= render_process_id
;
142 temp
.render_view_id
= render_view_id
;
143 temp
.zoom_level
= level
;
144 temporary_zoom_levels_
.push_back(temp
);
149 NotificationService::current()->Notify(
150 NOTIFICATION_ZOOM_LEVEL_CHANGED
,
151 Source
<HostZoomMap
>(this),
152 Details
<const std::string
>(&host
));
155 void HostZoomMapImpl::Observe(int type
,
156 const NotificationSource
& source
,
157 const NotificationDetails
& details
) {
159 case NOTIFICATION_RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW
: {
160 base::AutoLock
auto_lock(lock_
);
161 int render_view_id
= Source
<RenderViewHost
>(source
)->GetRoutingID();
162 int render_process_id
=
163 Source
<RenderViewHost
>(source
)->GetProcess()->GetID();
165 for (size_t i
= 0; i
< temporary_zoom_levels_
.size(); ++i
) {
166 if (temporary_zoom_levels_
[i
].render_process_id
== render_process_id
&&
167 temporary_zoom_levels_
[i
].render_view_id
== render_view_id
) {
168 temporary_zoom_levels_
.erase(temporary_zoom_levels_
.begin() + i
);
175 NOTREACHED() << "Unexpected preference observed.";
179 HostZoomMapImpl::~HostZoomMapImpl() {
182 } // namespace content