blob: 2df3e15d3dce55952ee734df11818d126bec3f7b [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
#include <string>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/metrics/histogram.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/content_settings/cookie_settings.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/extensions/extension_renderer_state.h"
#if defined(ENABLE_EXTENSIONS)
#include "chrome/browser/guest_view/web_view/web_view_guest.h"
#endif
#include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
#include "chrome/browser/net/predictor.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/renderer_host/web_cache_manager.h"
#include "chrome/common/extensions/api/i18n/default_locale_handler.h"
#include "chrome/common/render_messages.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h"
#if defined(ENABLE_TASK_MANAGER)
#include "chrome/browser/task_manager/task_manager.h"
#endif
#if defined(USE_TCMALLOC)
#include "chrome/browser/browser_about_handler.h"
#endif
using content::BrowserThread;
using blink::WebCache;
namespace {
const uint32 kFilteredMessageClasses[] = {
ChromeMsgStart,
};
} // namespace
ChromeRenderMessageFilter::ChromeRenderMessageFilter(
int render_process_id,
Profile* profile)
: BrowserMessageFilter(kFilteredMessageClasses,
arraysize(kFilteredMessageClasses)),
render_process_id_(render_process_id),
profile_(profile),
predictor_(profile_->GetNetworkPredictor()),
cookie_settings_(CookieSettings::Factory::GetForProfile(profile)) {
}
ChromeRenderMessageFilter::~ChromeRenderMessageFilter() {
}
bool ChromeRenderMessageFilter::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(ChromeRenderMessageFilter, message)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DnsPrefetch, OnDnsPrefetch)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_Preconnect, OnPreconnect)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ResourceTypeStats,
OnResourceTypeStats)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_UpdatedCacheStats,
OnUpdatedCacheStats)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_V8HeapStats, OnV8HeapStats)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDatabase, OnAllowDatabase)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDOMStorage, OnAllowDOMStorage)
IPC_MESSAGE_HANDLER_DELAY_REPLY(
ChromeViewHostMsg_RequestFileSystemAccessSync,
OnRequestFileSystemAccessSync)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RequestFileSystemAccessAsync,
OnRequestFileSystemAccessAsync)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowIndexedDB, OnAllowIndexedDB)
#if defined(ENABLE_PLUGINS)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_IsCrashReportingEnabled,
OnIsCrashReportingEnabled)
#endif
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void ChromeRenderMessageFilter::OverrideThreadForMessage(
const IPC::Message& message, BrowserThread::ID* thread) {
switch (message.type()) {
case ChromeViewHostMsg_ResourceTypeStats::ID:
case ChromeViewHostMsg_UpdatedCacheStats::ID:
*thread = BrowserThread::UI;
break;
default:
break;
}
}
void ChromeRenderMessageFilter::OnDnsPrefetch(
const std::vector<std::string>& hostnames) {
if (predictor_)
predictor_->DnsPrefetchList(hostnames);
}
void ChromeRenderMessageFilter::OnPreconnect(const GURL& url) {
if (predictor_)
predictor_->PreconnectUrl(
url, GURL(), chrome_browser_net::UrlInfo::MOUSE_OVER_MOTIVATED, 1);
}
void ChromeRenderMessageFilter::OnResourceTypeStats(
const WebCache::ResourceTypeStats& stats) {
HISTOGRAM_COUNTS("WebCoreCache.ImagesSizeKB",
static_cast<int>(stats.images.size / 1024));
HISTOGRAM_COUNTS("WebCoreCache.CSSStylesheetsSizeKB",
static_cast<int>(stats.cssStyleSheets.size / 1024));
HISTOGRAM_COUNTS("WebCoreCache.ScriptsSizeKB",
static_cast<int>(stats.scripts.size / 1024));
HISTOGRAM_COUNTS("WebCoreCache.XSLStylesheetsSizeKB",
static_cast<int>(stats.xslStyleSheets.size / 1024));
HISTOGRAM_COUNTS("WebCoreCache.FontsSizeKB",
static_cast<int>(stats.fonts.size / 1024));
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
#if defined(ENABLE_TASK_MANAGER)
TaskManager::GetInstance()->model()->NotifyResourceTypeStats(peer_pid(),
stats);
#endif // defined(ENABLE_TASK_MANAGER)
}
void ChromeRenderMessageFilter::OnUpdatedCacheStats(
const WebCache::UsageStats& stats) {
WebCacheManager::GetInstance()->ObserveStats(render_process_id_, stats);
}
void ChromeRenderMessageFilter::OnV8HeapStats(int v8_memory_allocated,
int v8_memory_used) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&ChromeRenderMessageFilter::OnV8HeapStats, this,
v8_memory_allocated, v8_memory_used));
return;
}
base::ProcessId renderer_id = peer_pid();
#if defined(ENABLE_TASK_MANAGER)
TaskManager::GetInstance()->model()->NotifyV8HeapStats(
renderer_id,
static_cast<size_t>(v8_memory_allocated),
static_cast<size_t>(v8_memory_used));
#endif // defined(ENABLE_TASK_MANAGER)
V8HeapStatsDetails details(v8_memory_allocated, v8_memory_used);
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED,
content::Source<const base::ProcessId>(&renderer_id),
content::Details<const V8HeapStatsDetails>(&details));
}
void ChromeRenderMessageFilter::OnAllowDatabase(
int render_frame_id,
const GURL& origin_url,
const GURL& top_origin_url,
const base::string16& name,
const base::string16& display_name,
bool* allowed) {
*allowed =
cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&TabSpecificContentSettings::WebDatabaseAccessed,
render_process_id_, render_frame_id, origin_url, name,
display_name, !*allowed));
}
void ChromeRenderMessageFilter::OnAllowDOMStorage(int render_frame_id,
const GURL& origin_url,
const GURL& top_origin_url,
bool local,
bool* allowed) {
*allowed =
cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
// Record access to DOM storage for potential display in UI.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&TabSpecificContentSettings::DOMStorageAccessed,
render_process_id_, render_frame_id, origin_url, local,
!*allowed));
}
void ChromeRenderMessageFilter::OnRequestFileSystemAccessSync(
int render_frame_id,
const GURL& origin_url,
const GURL& top_origin_url,
IPC::Message* reply_msg) {
bool allowed =
cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
#if defined(ENABLE_EXTENSIONS)
bool is_web_view_guest =
ExtensionRendererState::GetInstance()->IsWebViewRenderer(
render_process_id_);
if (is_web_view_guest) {
// Record access to file system for potential display in UI.
BrowserThread::PostTask(BrowserThread::UI,
FROM_HERE,
base::Bind(&WebViewGuest::FileSystemAccessedSync,
render_process_id_,
render_frame_id,
origin_url,
!allowed,
reply_msg));
return;
}
#endif
ChromeViewHostMsg_RequestFileSystemAccessSync::WriteReplyParams(reply_msg,
allowed);
Send(reply_msg);
// Record access to file system for potential display in UI.
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(&TabSpecificContentSettings::FileSystemAccessed,
render_process_id_,
render_frame_id,
origin_url,
!allowed));
}
void ChromeRenderMessageFilter::OnRequestFileSystemAccessAsync(
int render_frame_id,
int request_id,
const GURL& origin_url,
const GURL& top_origin_url) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
bool allowed =
cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
#if defined(ENABLE_EXTENSIONS)
bool is_web_view_guest =
ExtensionRendererState::GetInstance()->IsWebViewRenderer(
render_process_id_);
if (is_web_view_guest) {
// Record access to file system for potential display in UI.
BrowserThread::PostTask(BrowserThread::UI,
FROM_HERE,
base::Bind(&WebViewGuest::FileSystemAccessedAsync,
render_process_id_,
render_frame_id,
request_id,
origin_url,
!allowed));
return;
}
#endif
Send(new ChromeViewMsg_RequestFileSystemAccessAsyncResponse(render_frame_id,
request_id,
allowed));
// Record access to file system for potential display in UI.
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(&TabSpecificContentSettings::FileSystemAccessed,
render_process_id_,
render_frame_id,
origin_url,
!allowed));
}
void ChromeRenderMessageFilter::OnAllowIndexedDB(int render_frame_id,
const GURL& origin_url,
const GURL& top_origin_url,
const base::string16& name,
bool* allowed) {
*allowed =
cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&TabSpecificContentSettings::IndexedDBAccessed,
render_process_id_, render_frame_id, origin_url, name,
!*allowed));
}
#if defined(ENABLE_PLUGINS)
void ChromeRenderMessageFilter::OnIsCrashReportingEnabled(bool* enabled) {
*enabled = ChromeMetricsServiceAccessor::IsCrashReportingEnabled();
}
#endif