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.
5 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
10 #include "base/bind_helpers.h"
11 #include "base/metrics/histogram.h"
12 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/content_settings/cookie_settings.h"
14 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
15 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
16 #include "chrome/browser/net/predictor.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/browser/renderer_host/web_cache_manager.h"
20 #include "chrome/common/extensions/api/i18n/default_locale_handler.h"
21 #include "chrome/common/render_messages.h"
22 #include "content/public/browser/notification_service.h"
23 #include "content/public/browser/render_process_host.h"
25 #if defined(ENABLE_EXTENSIONS)
26 #include "chrome/browser/guest_view/web_view/web_view_permission_helper.h"
27 #include "chrome/browser/guest_view/web_view/web_view_renderer_state.h"
30 #if defined(ENABLE_TASK_MANAGER)
31 #include "chrome/browser/task_manager/task_manager.h"
34 #if defined(USE_TCMALLOC)
35 #include "chrome/browser/browser_about_handler.h"
38 using content::BrowserThread;
39 using blink::WebCache;
43 const uint32 kFilteredMessageClasses[] = {
49 ChromeRenderMessageFilter::ChromeRenderMessageFilter(
50 int render_process_id,
52 : BrowserMessageFilter(kFilteredMessageClasses,
53 arraysize(kFilteredMessageClasses)),
54 render_process_id_(render_process_id),
56 predictor_(profile_->GetNetworkPredictor()),
57 cookie_settings_(CookieSettings::Factory::GetForProfile(profile)) {
60 ChromeRenderMessageFilter::~ChromeRenderMessageFilter() {
63 bool ChromeRenderMessageFilter::OnMessageReceived(const IPC::Message& message) {
65 IPC_BEGIN_MESSAGE_MAP(ChromeRenderMessageFilter, message)
66 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DnsPrefetch, OnDnsPrefetch)
67 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_Preconnect, OnPreconnect)
68 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ResourceTypeStats,
70 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_UpdatedCacheStats,
72 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_V8HeapStats, OnV8HeapStats)
73 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDatabase, OnAllowDatabase)
74 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDOMStorage, OnAllowDOMStorage)
75 IPC_MESSAGE_HANDLER_DELAY_REPLY(
76 ChromeViewHostMsg_RequestFileSystemAccessSync,
77 OnRequestFileSystemAccessSync)
78 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RequestFileSystemAccessAsync,
79 OnRequestFileSystemAccessAsync)
80 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowIndexedDB, OnAllowIndexedDB)
81 #if defined(ENABLE_PLUGINS)
82 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_IsCrashReportingEnabled,
83 OnIsCrashReportingEnabled)
85 IPC_MESSAGE_UNHANDLED(handled = false)
91 void ChromeRenderMessageFilter::OverrideThreadForMessage(
92 const IPC::Message& message, BrowserThread::ID* thread) {
93 switch (message.type()) {
94 case ChromeViewHostMsg_ResourceTypeStats::ID:
95 case ChromeViewHostMsg_UpdatedCacheStats::ID:
96 *thread = BrowserThread::UI;
103 void ChromeRenderMessageFilter::OnDnsPrefetch(
104 const std::vector<std::string>& hostnames) {
106 predictor_->DnsPrefetchList(hostnames);
109 void ChromeRenderMessageFilter::OnPreconnect(const GURL& url) {
111 predictor_->PreconnectUrl(
112 url, GURL(), chrome_browser_net::UrlInfo::MOUSE_OVER_MOTIVATED, 1);
115 void ChromeRenderMessageFilter::OnResourceTypeStats(
116 const WebCache::ResourceTypeStats& stats) {
117 HISTOGRAM_COUNTS("WebCoreCache.ImagesSizeKB",
118 static_cast<int>(stats.images.size / 1024));
119 HISTOGRAM_COUNTS("WebCoreCache.CSSStylesheetsSizeKB",
120 static_cast<int>(stats.cssStyleSheets.size / 1024));
121 HISTOGRAM_COUNTS("WebCoreCache.ScriptsSizeKB",
122 static_cast<int>(stats.scripts.size / 1024));
123 HISTOGRAM_COUNTS("WebCoreCache.XSLStylesheetsSizeKB",
124 static_cast<int>(stats.xslStyleSheets.size / 1024));
125 HISTOGRAM_COUNTS("WebCoreCache.FontsSizeKB",
126 static_cast<int>(stats.fonts.size / 1024));
128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
129 #if defined(ENABLE_TASK_MANAGER)
130 TaskManager::GetInstance()->model()->NotifyResourceTypeStats(peer_pid(),
132 #endif // defined(ENABLE_TASK_MANAGER)
135 void ChromeRenderMessageFilter::OnUpdatedCacheStats(
136 const WebCache::UsageStats& stats) {
137 WebCacheManager::GetInstance()->ObserveStats(render_process_id_, stats);
140 void ChromeRenderMessageFilter::OnV8HeapStats(int v8_memory_allocated,
141 int v8_memory_used) {
142 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
143 BrowserThread::PostTask(
144 BrowserThread::UI, FROM_HERE,
145 base::Bind(&ChromeRenderMessageFilter::OnV8HeapStats, this,
146 v8_memory_allocated, v8_memory_used));
150 base::ProcessId renderer_id = peer_pid();
152 #if defined(ENABLE_TASK_MANAGER)
153 TaskManager::GetInstance()->model()->NotifyV8HeapStats(
155 static_cast<size_t>(v8_memory_allocated),
156 static_cast<size_t>(v8_memory_used));
157 #endif // defined(ENABLE_TASK_MANAGER)
159 V8HeapStatsDetails details(v8_memory_allocated, v8_memory_used);
160 content::NotificationService::current()->Notify(
161 chrome::NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED,
162 content::Source<const base::ProcessId>(&renderer_id),
163 content::Details<const V8HeapStatsDetails>(&details));
166 void ChromeRenderMessageFilter::OnAllowDatabase(
168 const GURL& origin_url,
169 const GURL& top_origin_url,
170 const base::string16& name,
171 const base::string16& display_name,
174 cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
175 BrowserThread::PostTask(
176 BrowserThread::UI, FROM_HERE,
177 base::Bind(&TabSpecificContentSettings::WebDatabaseAccessed,
178 render_process_id_, render_frame_id, origin_url, name,
179 display_name, !*allowed));
182 void ChromeRenderMessageFilter::OnAllowDOMStorage(int render_frame_id,
183 const GURL& origin_url,
184 const GURL& top_origin_url,
188 cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
189 // Record access to DOM storage for potential display in UI.
190 BrowserThread::PostTask(
191 BrowserThread::UI, FROM_HERE,
192 base::Bind(&TabSpecificContentSettings::DOMStorageAccessed,
193 render_process_id_, render_frame_id, origin_url, local,
197 void ChromeRenderMessageFilter::OnRequestFileSystemAccessSync(
199 const GURL& origin_url,
200 const GURL& top_origin_url,
201 IPC::Message* reply_msg) {
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
203 base::Callback<void(bool)> callback =
204 base::Bind(&ChromeRenderMessageFilter::
205 OnRequestFileSystemAccessSyncResponse,
206 make_scoped_refptr(this),
208 OnRequestFileSystemAccess(render_frame_id,
214 void ChromeRenderMessageFilter::OnRequestFileSystemAccessSyncResponse(
215 IPC::Message* reply_msg,
217 ChromeViewHostMsg_RequestFileSystemAccessSync::WriteReplyParams(reply_msg,
222 #if defined(ENABLE_EXTENSIONS)
223 void ChromeRenderMessageFilter::FileSystemAccessedSyncOnUIThread(
224 int render_process_id,
227 bool blocked_by_policy,
228 IPC::Message* reply_msg) {
229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
230 extensions::WebViewPermissionHelper* web_view_permission_helper =
231 extensions::WebViewPermissionHelper::FromFrameID(
232 render_process_id, render_frame_id);
233 // Between the time the permission request is made and the time it is handled
234 // by the UI thread, the extensions::WebViewPermissionHelper might be gone.
235 if (!web_view_permission_helper)
237 web_view_permission_helper->FileSystemAccessedSync(
238 render_process_id, render_frame_id, url, blocked_by_policy, reply_msg);
242 void ChromeRenderMessageFilter::OnRequestFileSystemAccessAsync(
245 const GURL& origin_url,
246 const GURL& top_origin_url) {
247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
248 base::Callback<void(bool)> callback =
249 base::Bind(&ChromeRenderMessageFilter::
250 OnRequestFileSystemAccessAsyncResponse,
251 make_scoped_refptr(this),
254 OnRequestFileSystemAccess(render_frame_id,
260 void ChromeRenderMessageFilter::OnRequestFileSystemAccessAsyncResponse(
264 Send(new ChromeViewMsg_RequestFileSystemAccessAsyncResponse(
265 render_frame_id, request_id, allowed));
268 void ChromeRenderMessageFilter::OnRequestFileSystemAccess(
270 const GURL& origin_url,
271 const GURL& top_origin_url,
272 base::Callback<void(bool)> callback) {
273 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
276 cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
278 #if defined(ENABLE_EXTENSIONS)
279 bool is_web_view_guest = extensions::WebViewRendererState::GetInstance()
280 ->IsGuest(render_process_id_);
281 if (is_web_view_guest) {
282 // Record access to file system for potential display in UI.
283 BrowserThread::PostTask(
286 base::Bind(&ChromeRenderMessageFilter::FileSystemAccessedOnUIThread,
295 callback.Run(allowed);
296 // Record access to file system for potential display in UI.
297 BrowserThread::PostTask(
300 base::Bind(&TabSpecificContentSettings::FileSystemAccessed,
307 #if defined(ENABLE_EXTENSIONS)
308 void ChromeRenderMessageFilter::FileSystemAccessedOnUIThread(
309 int render_process_id,
313 base::Callback<void(bool)> callback) {
314 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
315 extensions::WebViewPermissionHelper* web_view_permission_helper =
316 extensions::WebViewPermissionHelper::FromFrameID(
317 render_process_id, render_frame_id);
318 // Between the time the permission request is made and the time it is handled
319 // by the UI thread, the extensions::WebViewPermissionHelper might be gone.
320 if (!web_view_permission_helper)
322 web_view_permission_helper->RequestFileSystemPermission(
325 base::Bind(&ChromeRenderMessageFilter::FileSystemAccessedResponse,
332 void ChromeRenderMessageFilter::FileSystemAccessedResponse(
333 int render_process_id,
336 base::Callback<void(bool)> callback,
338 TabSpecificContentSettings::FileSystemAccessed(
339 render_process_id, render_frame_id, url, !allowed);
340 callback.Run(allowed);
344 void ChromeRenderMessageFilter::OnAllowIndexedDB(int render_frame_id,
345 const GURL& origin_url,
346 const GURL& top_origin_url,
347 const base::string16& name,
350 cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
351 BrowserThread::PostTask(
352 BrowserThread::UI, FROM_HERE,
353 base::Bind(&TabSpecificContentSettings::IndexedDBAccessed,
354 render_process_id_, render_frame_id, origin_url, name,
358 #if defined(ENABLE_PLUGINS)
359 void ChromeRenderMessageFilter::OnIsCrashReportingEnabled(bool* enabled) {
360 *enabled = ChromeMetricsServiceAccessor::IsCrashReportingEnabled();