chrome_render_message_filter.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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 WebViewPermissionHelper* web_view_permission_helper = 231 WebViewPermissionHelper::FromFrameID(render_process_id, render_frame_id); 232 web_view_permission_helper->FileSystemAccessedSync(render_process_id, 233 render_frame_id, 234 url, 235 blocked_by_policy, 236 reply_msg); 237} 238#endif 239 240void ChromeRenderMessageFilter::OnRequestFileSystemAccessAsync( 241 int render_frame_id, 242 int request_id, 243 const GURL& origin_url, 244 const GURL& top_origin_url) { 245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 246 base::Callback<void(bool)> callback = 247 base::Bind(&ChromeRenderMessageFilter:: 248 OnRequestFileSystemAccessAsyncResponse, 249 make_scoped_refptr(this), 250 render_frame_id, 251 request_id); 252 OnRequestFileSystemAccess(render_frame_id, 253 origin_url, 254 top_origin_url, 255 callback); 256} 257 258void ChromeRenderMessageFilter::OnRequestFileSystemAccessAsyncResponse( 259 int render_frame_id, 260 int request_id, 261 bool allowed) { 262 Send(new ChromeViewMsg_RequestFileSystemAccessAsyncResponse( 263 render_frame_id, request_id, allowed)); 264} 265 266void ChromeRenderMessageFilter::OnRequestFileSystemAccess( 267 int render_frame_id, 268 const GURL& origin_url, 269 const GURL& top_origin_url, 270 base::Callback<void(bool)> callback) { 271 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 272 273 bool allowed = 274 cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url); 275 276#if defined(ENABLE_EXTENSIONS) 277 bool is_web_view_guest = 278 WebViewRendererState::GetInstance()->IsGuest(render_process_id_); 279 if (is_web_view_guest) { 280 // Record access to file system for potential display in UI. 281 BrowserThread::PostTask( 282 BrowserThread::UI, 283 FROM_HERE, 284 base::Bind(&ChromeRenderMessageFilter::FileSystemAccessedOnUIThread, 285 render_process_id_, 286 render_frame_id, 287 origin_url, 288 allowed, 289 callback)); 290 return; 291 } 292#endif 293 callback.Run(allowed); 294 // Record access to file system for potential display in UI. 295 BrowserThread::PostTask( 296 BrowserThread::UI, 297 FROM_HERE, 298 base::Bind(&TabSpecificContentSettings::FileSystemAccessed, 299 render_process_id_, 300 render_frame_id, 301 origin_url, 302 !allowed)); 303} 304 305#if defined(ENABLE_EXTENSIONS) 306void ChromeRenderMessageFilter::FileSystemAccessedOnUIThread( 307 int render_process_id, 308 int render_frame_id, 309 const GURL& url, 310 bool allowed, 311 base::Callback<void(bool)> callback) { 312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 313 WebViewPermissionHelper* web_view_permission_helper = 314 WebViewPermissionHelper::FromFrameID(render_process_id, render_frame_id); 315 web_view_permission_helper->RequestFileSystemPermission( 316 url, 317 allowed, 318 base::Bind(&ChromeRenderMessageFilter::FileSystemAccessedResponse, 319 render_process_id, 320 render_frame_id, 321 url, 322 callback)); 323} 324 325void ChromeRenderMessageFilter::FileSystemAccessedResponse( 326 int render_process_id, 327 int render_frame_id, 328 const GURL& url, 329 base::Callback<void(bool)> callback, 330 bool allowed) { 331 TabSpecificContentSettings::FileSystemAccessed( 332 render_process_id, render_frame_id, url, !allowed); 333 callback.Run(allowed); 334} 335#endif 336 337void ChromeRenderMessageFilter::OnAllowIndexedDB(int render_frame_id, 338 const GURL& origin_url, 339 const GURL& top_origin_url, 340 const base::string16& name, 341 bool* allowed) { 342 *allowed = 343 cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url); 344 BrowserThread::PostTask( 345 BrowserThread::UI, FROM_HERE, 346 base::Bind(&TabSpecificContentSettings::IndexedDBAccessed, 347 render_process_id_, render_frame_id, origin_url, name, 348 !*allowed)); 349} 350 351#if defined(ENABLE_PLUGINS) 352void ChromeRenderMessageFilter::OnIsCrashReportingEnabled(bool* enabled) { 353 *enabled = ChromeMetricsServiceAccessor::IsCrashReportingEnabled(); 354} 355#endif 356