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
;
63 double HostZoomMapImpl::GetZoomLevel(const std::string
& host
) const {
64 base::AutoLock
auto_lock(lock_
);
65 HostZoomLevels::const_iterator
i(host_zoom_levels_
.find(host
));
66 return (i
== host_zoom_levels_
.end()) ? default_zoom_level_
: i
->second
;
69 void HostZoomMapImpl::SetZoomLevel(const std::string
& host
, double level
) {
70 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
73 base::AutoLock
auto_lock(lock_
);
75 if (ZoomValuesEqual(level
, default_zoom_level_
))
76 host_zoom_levels_
.erase(host
);
78 host_zoom_levels_
[host
] = level
;
81 // Notify renderers from this browser context.
82 for (RenderProcessHost::iterator
i(RenderProcessHost::AllHostsIterator());
83 !i
.IsAtEnd(); i
.Advance()) {
84 RenderProcessHost
* render_process_host
= i
.GetCurrentValue();
85 if (HostZoomMap::GetForBrowserContext(
86 render_process_host
->GetBrowserContext()) == this) {
87 render_process_host
->Send(
88 new ViewMsg_SetZoomLevelForCurrentURL(host
, level
));
92 NotificationService::current()->Notify(
93 NOTIFICATION_ZOOM_LEVEL_CHANGED
,
94 Source
<HostZoomMap
>(this),
95 Details
<const std::string
>(&host
));
98 double HostZoomMapImpl::GetDefaultZoomLevel() const {
99 return default_zoom_level_
;
102 void HostZoomMapImpl::SetDefaultZoomLevel(double level
) {
103 default_zoom_level_
= level
;
106 double HostZoomMapImpl::GetTemporaryZoomLevel(int render_process_id
,
107 int render_view_id
) const {
108 base::AutoLock
auto_lock(lock_
);
109 for (size_t i
= 0; i
< temporary_zoom_levels_
.size(); ++i
) {
110 if (temporary_zoom_levels_
[i
].render_process_id
== render_process_id
&&
111 temporary_zoom_levels_
[i
].render_view_id
== render_view_id
) {
112 return temporary_zoom_levels_
[i
].zoom_level
;
118 void HostZoomMapImpl::SetTemporaryZoomLevel(int render_process_id
,
121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
124 base::AutoLock
auto_lock(lock_
);
126 for (i
= 0; i
< temporary_zoom_levels_
.size(); ++i
) {
127 if (temporary_zoom_levels_
[i
].render_process_id
== render_process_id
&&
128 temporary_zoom_levels_
[i
].render_view_id
== render_view_id
) {
130 temporary_zoom_levels_
[i
].zoom_level
= level
;
132 temporary_zoom_levels_
.erase(temporary_zoom_levels_
.begin() + i
);
138 if (level
&& i
== temporary_zoom_levels_
.size()) {
139 TemporaryZoomLevel temp
;
140 temp
.render_process_id
= render_process_id
;
141 temp
.render_view_id
= render_view_id
;
142 temp
.zoom_level
= level
;
143 temporary_zoom_levels_
.push_back(temp
);
148 NotificationService::current()->Notify(
149 NOTIFICATION_ZOOM_LEVEL_CHANGED
,
150 Source
<HostZoomMap
>(this),
151 Details
<const std::string
>(&host
));
154 void HostZoomMapImpl::Observe(int type
,
155 const NotificationSource
& source
,
156 const NotificationDetails
& details
) {
158 case NOTIFICATION_RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW
: {
159 base::AutoLock
auto_lock(lock_
);
160 int render_view_id
= Source
<RenderViewHost
>(source
)->GetRoutingID();
161 int render_process_id
=
162 Source
<RenderViewHost
>(source
)->GetProcess()->GetID();
164 for (size_t i
= 0; i
< temporary_zoom_levels_
.size(); ++i
) {
165 if (temporary_zoom_levels_
[i
].render_process_id
== render_process_id
&&
166 temporary_zoom_levels_
[i
].render_view_id
== render_view_id
) {
167 temporary_zoom_levels_
.erase(temporary_zoom_levels_
.begin() + i
);
174 NOTREACHED() << "Unexpected preference observed.";
178 HostZoomMapImpl::~HostZoomMapImpl() {
181 } // namespace content