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/common/extensions/api/i18n/default_locale_handler.h"
20 #include "chrome/common/render_messages.h"
21 #include "components/web_cache/browser/web_cache_manager.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 "extensions/browser/guest_view/web_view/web_view_permission_helper.h"
27 #include "extensions/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 LOCAL_HISTOGRAM_COUNTS("WebCoreCache.ImagesSizeKB",
118 static_cast<int>(stats.images.size / 1024));
119 LOCAL_HISTOGRAM_COUNTS("WebCoreCache.CSSStylesheetsSizeKB",
120 static_cast<int>(stats.cssStyleSheets.size / 1024));
121 LOCAL_HISTOGRAM_COUNTS("WebCoreCache.ScriptsSizeKB",
122 static_cast<int>(stats.scripts.size / 1024));
123 LOCAL_HISTOGRAM_COUNTS("WebCoreCache.XSLStylesheetsSizeKB",
124 static_cast<int>(stats.xslStyleSheets.size / 1024));
125 LOCAL_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 web_cache::WebCacheManager::GetInstance()->ObserveStats(
138 render_process_id_, stats);
141 void ChromeRenderMessageFilter::OnV8HeapStats(int v8_memory_allocated,
142 int v8_memory_used) {
143 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
144 BrowserThread::PostTask(
145 BrowserThread::UI, FROM_HERE,
146 base::Bind(&ChromeRenderMessageFilter::OnV8HeapStats, this,
147 v8_memory_allocated, v8_memory_used));
151 base::ProcessId renderer_id = peer_pid();
153 #if defined(ENABLE_TASK_MANAGER)
154 TaskManager::GetInstance()->model()->NotifyV8HeapStats(
156 static_cast<size_t>(v8_memory_allocated),
157 static_cast<size_t>(v8_memory_used));
158 #endif // defined(ENABLE_TASK_MANAGER)
160 V8HeapStatsDetails details(v8_memory_allocated, v8_memory_used);
161 content::NotificationService::current()->Notify(
162 chrome::NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED,
163 content::Source<const base::ProcessId>(&renderer_id),
164 content::Details<const V8HeapStatsDetails>(&details));
167 void ChromeRenderMessageFilter::OnAllowDatabase(
169 const GURL& origin_url,
170 const GURL& top_origin_url,
171 const base::string16& name,
172 const base::string16& display_name,
175 cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
176 BrowserThread::PostTask(
177 BrowserThread::UI, FROM_HERE,
178 base::Bind(&TabSpecificContentSettings::WebDatabaseAccessed,
179 render_process_id_, render_frame_id, origin_url, name,
180 display_name, !*allowed));
183 void ChromeRenderMessageFilter::OnAllowDOMStorage(int render_frame_id,
184 const GURL& origin_url,
185 const GURL& top_origin_url,
189 cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
190 // Record access to DOM storage for potential display in UI.
191 BrowserThread::PostTask(
192 BrowserThread::UI, FROM_HERE,
193 base::Bind(&TabSpecificContentSettings::DOMStorageAccessed,
194 render_process_id_, render_frame_id, origin_url, local,
198 void ChromeRenderMessageFilter::OnRequestFileSystemAccessSync(
200 const GURL& origin_url,
201 const GURL& top_origin_url,
202 IPC::Message* reply_msg) {
203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
204 base::Callback<void(bool)> callback =
205 base::Bind(&ChromeRenderMessageFilter::
206 OnRequestFileSystemAccessSyncResponse,
207 make_scoped_refptr(this),
209 OnRequestFileSystemAccess(render_frame_id,
215 void ChromeRenderMessageFilter::OnRequestFileSystemAccessSyncResponse(
216 IPC::Message* reply_msg,
218 ChromeViewHostMsg_RequestFileSystemAccessSync::WriteReplyParams(reply_msg,
223 #if defined(ENABLE_EXTENSIONS)
224 void ChromeRenderMessageFilter::FileSystemAccessedSyncOnUIThread(
225 int render_process_id,
228 bool blocked_by_policy,
229 IPC::Message* reply_msg) {
230 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
231 extensions::WebViewPermissionHelper* web_view_permission_helper =
232 extensions::WebViewPermissionHelper::FromFrameID(
233 render_process_id, render_frame_id);
234 // Between the time the permission request is made and the time it is handled
235 // by the UI thread, the extensions::WebViewPermissionHelper might be gone.
236 if (!web_view_permission_helper)
238 web_view_permission_helper->FileSystemAccessedSync(
239 render_process_id, render_frame_id, url, blocked_by_policy, reply_msg);
243 void ChromeRenderMessageFilter::OnRequestFileSystemAccessAsync(
246 const GURL& origin_url,
247 const GURL& top_origin_url) {
248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
249 base::Callback<void(bool)> callback =
250 base::Bind(&ChromeRenderMessageFilter::
251 OnRequestFileSystemAccessAsyncResponse,
252 make_scoped_refptr(this),
255 OnRequestFileSystemAccess(render_frame_id,
261 void ChromeRenderMessageFilter::OnRequestFileSystemAccessAsyncResponse(
265 Send(new ChromeViewMsg_RequestFileSystemAccessAsyncResponse(
266 render_frame_id, request_id, allowed));
269 void ChromeRenderMessageFilter::OnRequestFileSystemAccess(
271 const GURL& origin_url,
272 const GURL& top_origin_url,
273 base::Callback<void(bool)> callback) {
274 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
277 cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
279 #if defined(ENABLE_EXTENSIONS)
280 bool is_web_view_guest = extensions::WebViewRendererState::GetInstance()
281 ->IsGuest(render_process_id_);
282 if (is_web_view_guest) {
283 // Record access to file system for potential display in UI.
284 BrowserThread::PostTask(
287 base::Bind(&ChromeRenderMessageFilter::FileSystemAccessedOnUIThread,
296 callback.Run(allowed);
297 // Record access to file system for potential display in UI.
298 BrowserThread::PostTask(
301 base::Bind(&TabSpecificContentSettings::FileSystemAccessed,
308 #if defined(ENABLE_EXTENSIONS)
309 void ChromeRenderMessageFilter::FileSystemAccessedOnUIThread(
310 int render_process_id,
314 base::Callback<void(bool)> callback) {
315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
316 extensions::WebViewPermissionHelper* web_view_permission_helper =
317 extensions::WebViewPermissionHelper::FromFrameID(
318 render_process_id, render_frame_id);
319 // Between the time the permission request is made and the time it is handled
320 // by the UI thread, the extensions::WebViewPermissionHelper might be gone.
321 if (!web_view_permission_helper)
323 web_view_permission_helper->RequestFileSystemPermission(
326 base::Bind(&ChromeRenderMessageFilter::FileSystemAccessedResponse,
333 void ChromeRenderMessageFilter::FileSystemAccessedResponse(
334 int render_process_id,
337 base::Callback<void(bool)> callback,
339 TabSpecificContentSettings::FileSystemAccessed(
340 render_process_id, render_frame_id, url, !allowed);
341 callback.Run(allowed);
345 void ChromeRenderMessageFilter::OnAllowIndexedDB(int render_frame_id,
346 const GURL& origin_url,
347 const GURL& top_origin_url,
348 const base::string16& name,
351 cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
352 BrowserThread::PostTask(
353 BrowserThread::UI, FROM_HERE,
354 base::Bind(&TabSpecificContentSettings::IndexedDBAccessed,
355 render_process_id_, render_frame_id, origin_url, name,
359 #if defined(ENABLE_PLUGINS)
360 void ChromeRenderMessageFilter::OnIsCrashReportingEnabled(bool* enabled) {
361 *enabled = ChromeMetricsServiceAccessor::IsCrashReportingEnabled();