OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 | |
5 #include <cmath> | |
6 | |
7 #include "content/browser/host_zoom_map.h" | |
8 | |
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.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/common/page_zoom.h" | |
20 #include "googleurl/src/gurl.h" | |
21 #include "net/base/net_util.h" | |
22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | |
23 | |
24 using WebKit::WebView; | |
25 using content::BrowserThread; | |
26 using content::RenderProcessHost; | |
27 | |
28 HostZoomMap::HostZoomMap() | |
29 : default_zoom_level_(0.0) { | |
30 registrar_.Add( | |
31 this, content::NOTIFICATION_RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW, | |
32 content::NotificationService::AllSources()); | |
33 } | |
34 | |
35 void HostZoomMap::CopyFrom(HostZoomMap* copy) { | |
36 // This can only be called on the UI thread to avoid deadlocks, otherwise | |
37 // UI: a.CopyFrom(b); | |
38 // IO: b.CopyFrom(a); | |
39 // can deadlock. | |
40 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
41 base::AutoLock auto_lock(lock_); | |
42 base::AutoLock copy_auto_lock(copy->lock_); | |
43 for (HostZoomLevels::const_iterator i(copy->host_zoom_levels_.begin()); | |
44 i != copy->host_zoom_levels_.end(); ++i) { | |
45 host_zoom_levels_[i->first] = i->second; | |
46 } | |
47 } | |
48 | |
49 double HostZoomMap::GetZoomLevel(const std::string& host) const { | |
50 base::AutoLock auto_lock(lock_); | |
51 HostZoomLevels::const_iterator i(host_zoom_levels_.find(host)); | |
52 return (i == host_zoom_levels_.end()) ? default_zoom_level_ : i->second; | |
53 } | |
54 | |
55 void HostZoomMap::SetZoomLevel(std::string host, double level) { | |
56 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
57 | |
58 { | |
59 base::AutoLock auto_lock(lock_); | |
60 | |
61 if (content::ZoomValuesEqual(level, default_zoom_level_)) | |
62 host_zoom_levels_.erase(host); | |
63 else | |
64 host_zoom_levels_[host] = level; | |
65 } | |
66 | |
67 // Notify renderers from this browser context. | |
68 for (RenderProcessHost::iterator i(RenderProcessHost::AllHostsIterator()); | |
69 !i.IsAtEnd(); i.Advance()) { | |
70 RenderProcessHost* render_process_host = i.GetCurrentValue(); | |
71 if (render_process_host->GetBrowserContext()->GetHostZoomMap() == this) { | |
72 render_process_host->Send( | |
73 new ViewMsg_SetZoomLevelForCurrentURL(host, level)); | |
74 } | |
75 } | |
76 | |
77 content::NotificationService::current()->Notify( | |
78 content::NOTIFICATION_ZOOM_LEVEL_CHANGED, | |
79 content::Source<HostZoomMap>(this), | |
80 content::Details<const std::string>(&host)); | |
81 } | |
82 | |
83 double HostZoomMap::GetTemporaryZoomLevel(int render_process_id, | |
84 int render_view_id) const { | |
85 base::AutoLock auto_lock(lock_); | |
86 for (size_t i = 0; i < temporary_zoom_levels_.size(); ++i) { | |
87 if (temporary_zoom_levels_[i].render_process_id == render_process_id && | |
88 temporary_zoom_levels_[i].render_view_id == render_view_id) { | |
89 return temporary_zoom_levels_[i].zoom_level; | |
90 } | |
91 } | |
92 return 0; | |
93 } | |
94 | |
95 void HostZoomMap::SetTemporaryZoomLevel(int render_process_id, | |
96 int render_view_id, | |
97 double level) { | |
98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
99 | |
100 { | |
101 base::AutoLock auto_lock(lock_); | |
102 size_t i; | |
103 for (i = 0; i < temporary_zoom_levels_.size(); ++i) { | |
104 if (temporary_zoom_levels_[i].render_process_id == render_process_id && | |
105 temporary_zoom_levels_[i].render_view_id == render_view_id) { | |
106 if (level) { | |
107 temporary_zoom_levels_[i].zoom_level = level; | |
108 } else { | |
109 temporary_zoom_levels_.erase(temporary_zoom_levels_.begin() + i); | |
110 } | |
111 break; | |
112 } | |
113 } | |
114 | |
115 if (level && i == temporary_zoom_levels_.size()) { | |
116 TemporaryZoomLevel temp; | |
117 temp.render_process_id = render_process_id; | |
118 temp.render_view_id = render_view_id; | |
119 temp.zoom_level = level; | |
120 temporary_zoom_levels_.push_back(temp); | |
121 } | |
122 } | |
123 | |
124 std::string host; | |
125 content::NotificationService::current()->Notify( | |
126 content::NOTIFICATION_ZOOM_LEVEL_CHANGED, | |
127 content::Source<HostZoomMap>(this), | |
128 content::Details<const std::string>(&host)); | |
129 } | |
130 | |
131 void HostZoomMap::Observe( | |
132 int type, | |
133 const content::NotificationSource& source, | |
134 const content::NotificationDetails& details) { | |
135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
136 | |
137 switch (type) { | |
138 case content::NOTIFICATION_RENDER_VIEW_HOST_WILL_CLOSE_RENDER_VIEW: { | |
139 base::AutoLock auto_lock(lock_); | |
140 int render_view_id = | |
141 content::Source<RenderViewHost>(source)->routing_id(); | |
142 int render_process_id = | |
143 content::Source<RenderViewHost>(source)->process()->GetID(); | |
144 | |
145 for (size_t i = 0; i < temporary_zoom_levels_.size(); ++i) { | |
146 if (temporary_zoom_levels_[i].render_process_id == render_process_id && | |
147 temporary_zoom_levels_[i].render_view_id == render_view_id) { | |
148 temporary_zoom_levels_.erase(temporary_zoom_levels_.begin() + i); | |
149 break; | |
150 } | |
151 } | |
152 break; | |
153 } | |
154 default: | |
155 NOTREACHED() << "Unexpected preference observed."; | |
156 } | |
157 } | |
158 | |
159 HostZoomMap::~HostZoomMap() { | |
160 } | |
OLD | NEW |