chrome_render_message_filter.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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. 4 5#include "chrome/browser/renderer_host/chrome_render_message_filter.h" 6 7#include <string> 8 9#include "base/bind.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" 24 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" 28#endif 29 30#if defined(ENABLE_TASK_MANAGER) 31#include "chrome/browser/task_manager/task_manager.h" 32#endif 33 34#if defined(USE_TCMALLOC) 35#include "chrome/browser/browser_about_handler.h" 36#endif 37 38using content::BrowserThread; 39using blink::WebCache; 40 41namespace { 42 43const uint32 kFilteredMessageClasses[] = { 44 ChromeMsgStart, 45}; 46 47} // namespace 48 49ChromeRenderMessageFilter::ChromeRenderMessageFilter( 50 int render_process_id, 51 Profile* profile) 52 : BrowserMessageFilter(kFilteredMessageClasses, 53 arraysize(kFilteredMessageClasses)), 54 render_process_id_(render_process_id), 55 profile_(profile), 56 predictor_(profile_->GetNetworkPredictor()), 57 cookie_settings_(CookieSettings::Factory::GetForProfile(profile)) { 58} 59 60ChromeRenderMessageFilter::~ChromeRenderMessageFilter() { 61} 62 63bool ChromeRenderMessageFilter::OnMessageReceived(const IPC::Message& message) { 64 bool handled = true; 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, 69 OnResourceTypeStats) 70 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_UpdatedCacheStats, 71 OnUpdatedCacheStats) 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) 84#endif 85 IPC_MESSAGE_UNHANDLED(handled = false) 86 IPC_END_MESSAGE_MAP() 87 88 return handled; 89} 90 91void 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; 97 break; 98 default: 99 break; 100 } 101} 102 103void ChromeRenderMessageFilter::OnDnsPrefetch( 104 const std::vector<std::string>& hostnames) { 105 if (predictor_) 106 predictor_->DnsPrefetchList(hostnames); 107} 108 109void ChromeRenderMessageFilter::OnPreconnect(const GURL& url) { 110 if (predictor_) 111 predictor_->PreconnectUrl( 112 url, GURL(), chrome_browser_net::UrlInfo::MOUSE_OVER_MOTIVATED, 1); 113} 114 115void 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)); 127 128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 129#if defined(ENABLE_TASK_MANAGER) 130 TaskManager::GetInstance()->model()->NotifyResourceTypeStats(peer_pid(), 131 stats); 132#endif // defined(ENABLE_TASK_MANAGER) 133} 134 135void ChromeRenderMessageFilter::OnUpdatedCacheStats( 136 const WebCache::UsageStats& stats) { 137 WebCacheManager::GetInstance()->ObserveStats(render_process_id_, stats); 138} 139 140void 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)); 147 return; 148 } 149 150 base::ProcessId renderer_id = peer_pid(); 151 152#if defined(ENABLE_TASK_MANAGER) 153 TaskManager::GetInstance()->model()->NotifyV8HeapStats( 154 renderer_id, 155 static_cast<size_t>(v8_memory_allocated), 156 static_cast<size_t>(v8_memory_used)); 157#endif // defined(ENABLE_TASK_MANAGER) 158 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)); 164} 165 166void ChromeRenderMessageFilter::OnAllowDatabase( 167 int render_frame_id, 168 const GURL& origin_url, 169 const GURL& top_origin_url, 170 const base::string16& name, 171 const base::string16& display_name, 172 bool* allowed) { 173 *allowed = 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)); 180} 181 182void ChromeRenderMessageFilter::OnAllowDOMStorage(int render_frame_id, 183 const GURL& origin_url, 184 const GURL& top_origin_url, 185 bool local, 186 bool* allowed) { 187 *allowed = 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, 194 !*allowed)); 195} 196 197void ChromeRenderMessageFilter::OnRequestFileSystemAccessSync( 198 int render_frame_id, 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), 207 reply_msg); 208 OnRequestFileSystemAccess(render_frame_id, 209 origin_url, 210 top_origin_url, 211 callback); 212} 213 214void ChromeRenderMessageFilter::OnRequestFileSystemAccessSyncResponse( 215 IPC::Message* reply_msg, 216 bool allowed) { 217 ChromeViewHostMsg_RequestFileSystemAccessSync::WriteReplyParams(reply_msg, 218 allowed); 219 Send(reply_msg); 220} 221 222#if defined(ENABLE_EXTENSIONS) 223void ChromeRenderMessageFilter::FileSystemAccessedSyncOnUIThread( 224 int render_process_id, 225 int render_frame_id, 226 const GURL& url, 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) 236 return; 237 web_view_permission_helper->FileSystemAccessedSync( 238 render_process_id, render_frame_id, url, blocked_by_policy, reply_msg); 239} 240#endif 241 242void ChromeRenderMessageFilter::OnRequestFileSystemAccessAsync( 243 int render_frame_id, 244 int request_id, 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), 252 render_frame_id, 253 request_id); 254 OnRequestFileSystemAccess(render_frame_id, 255 origin_url, 256 top_origin_url, 257 callback); 258} 259 260void ChromeRenderMessageFilter::OnRequestFileSystemAccessAsyncResponse( 261 int render_frame_id, 262 int request_id, 263 bool allowed) { 264 Send(new ChromeViewMsg_RequestFileSystemAccessAsyncResponse( 265 render_frame_id, request_id, allowed)); 266} 267 268void ChromeRenderMessageFilter::OnRequestFileSystemAccess( 269 int render_frame_id, 270 const GURL& origin_url, 271 const GURL& top_origin_url, 272 base::Callback<void(bool)> callback) { 273 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 274 275 bool allowed = 276 cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url); 277 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( 284 BrowserThread::UI, 285 FROM_HERE, 286 base::Bind(&ChromeRenderMessageFilter::FileSystemAccessedOnUIThread, 287 render_process_id_, 288 render_frame_id, 289 origin_url, 290 allowed, 291 callback)); 292 return; 293 } 294#endif 295 callback.Run(allowed); 296 // Record access to file system for potential display in UI. 297 BrowserThread::PostTask( 298 BrowserThread::UI, 299 FROM_HERE, 300 base::Bind(&TabSpecificContentSettings::FileSystemAccessed, 301 render_process_id_, 302 render_frame_id, 303 origin_url, 304 !allowed)); 305} 306 307#if defined(ENABLE_EXTENSIONS) 308void ChromeRenderMessageFilter::FileSystemAccessedOnUIThread( 309 int render_process_id, 310 int render_frame_id, 311 const GURL& url, 312 bool allowed, 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) 321 return; 322 web_view_permission_helper->RequestFileSystemPermission( 323 url, 324 allowed, 325 base::Bind(&ChromeRenderMessageFilter::FileSystemAccessedResponse, 326 render_process_id, 327 render_frame_id, 328 url, 329 callback)); 330} 331 332void ChromeRenderMessageFilter::FileSystemAccessedResponse( 333 int render_process_id, 334 int render_frame_id, 335 const GURL& url, 336 base::Callback<void(bool)> callback, 337 bool allowed) { 338 TabSpecificContentSettings::FileSystemAccessed( 339 render_process_id, render_frame_id, url, !allowed); 340 callback.Run(allowed); 341} 342#endif 343 344void ChromeRenderMessageFilter::OnAllowIndexedDB(int render_frame_id, 345 const GURL& origin_url, 346 const GURL& top_origin_url, 347 const base::string16& name, 348 bool* allowed) { 349 *allowed = 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, 355 !*allowed)); 356} 357 358#if defined(ENABLE_PLUGINS) 359void ChromeRenderMessageFilter::OnIsCrashReportingEnabled(bool* enabled) { 360 *enabled = ChromeMetricsServiceAccessor::IsCrashReportingEnabled(); 361} 362#endif 363