chrome_render_message_filter.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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_TASK_MANAGER)
26#include "chrome/browser/task_manager/task_manager.h"
27#endif
28
29#if defined(USE_TCMALLOC)
30#include "chrome/browser/browser_about_handler.h"
31#endif
32
33using content::BrowserThread;
34using blink::WebCache;
35
36namespace {
37
38const uint32 kFilteredMessageClasses[] = {
39  ChromeMsgStart,
40};
41
42}  // namespace
43
44ChromeRenderMessageFilter::ChromeRenderMessageFilter(
45    int render_process_id,
46    Profile* profile)
47    : BrowserMessageFilter(kFilteredMessageClasses,
48                           arraysize(kFilteredMessageClasses)),
49      render_process_id_(render_process_id),
50      profile_(profile),
51      predictor_(profile_->GetNetworkPredictor()),
52      cookie_settings_(CookieSettings::Factory::GetForProfile(profile)) {
53}
54
55ChromeRenderMessageFilter::~ChromeRenderMessageFilter() {
56}
57
58bool ChromeRenderMessageFilter::OnMessageReceived(const IPC::Message& message) {
59  bool handled = true;
60  IPC_BEGIN_MESSAGE_MAP(ChromeRenderMessageFilter, message)
61    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DnsPrefetch, OnDnsPrefetch)
62    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_Preconnect, OnPreconnect)
63    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ResourceTypeStats,
64                        OnResourceTypeStats)
65    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_UpdatedCacheStats,
66                        OnUpdatedCacheStats)
67    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FPS, OnFPS)
68    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_V8HeapStats, OnV8HeapStats)
69    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDatabase, OnAllowDatabase)
70    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDOMStorage, OnAllowDOMStorage)
71    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RequestFileSystemAccessSync,
72                        OnRequestFileSystemAccessSync)
73    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RequestFileSystemAccessAsync,
74                        OnRequestFileSystemAccessAsync)
75    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowIndexedDB, OnAllowIndexedDB)
76#if defined(ENABLE_PLUGINS)
77    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_IsCrashReportingEnabled,
78                        OnIsCrashReportingEnabled)
79#endif
80    IPC_MESSAGE_UNHANDLED(handled = false)
81  IPC_END_MESSAGE_MAP()
82
83  return handled;
84}
85
86void ChromeRenderMessageFilter::OverrideThreadForMessage(
87    const IPC::Message& message, BrowserThread::ID* thread) {
88  switch (message.type()) {
89    case ChromeViewHostMsg_ResourceTypeStats::ID:
90    case ChromeViewHostMsg_UpdatedCacheStats::ID:
91      *thread = BrowserThread::UI;
92      break;
93    default:
94      break;
95  }
96}
97
98void ChromeRenderMessageFilter::OnDnsPrefetch(
99    const std::vector<std::string>& hostnames) {
100  if (predictor_)
101    predictor_->DnsPrefetchList(hostnames);
102}
103
104void ChromeRenderMessageFilter::OnPreconnect(const GURL& url) {
105  if (predictor_)
106    predictor_->PreconnectUrl(
107        url, GURL(), chrome_browser_net::UrlInfo::MOUSE_OVER_MOTIVATED, 1);
108}
109
110void ChromeRenderMessageFilter::OnResourceTypeStats(
111    const WebCache::ResourceTypeStats& stats) {
112  HISTOGRAM_COUNTS("WebCoreCache.ImagesSizeKB",
113                   static_cast<int>(stats.images.size / 1024));
114  HISTOGRAM_COUNTS("WebCoreCache.CSSStylesheetsSizeKB",
115                   static_cast<int>(stats.cssStyleSheets.size / 1024));
116  HISTOGRAM_COUNTS("WebCoreCache.ScriptsSizeKB",
117                   static_cast<int>(stats.scripts.size / 1024));
118  HISTOGRAM_COUNTS("WebCoreCache.XSLStylesheetsSizeKB",
119                   static_cast<int>(stats.xslStyleSheets.size / 1024));
120  HISTOGRAM_COUNTS("WebCoreCache.FontsSizeKB",
121                   static_cast<int>(stats.fonts.size / 1024));
122
123  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
124#if defined(ENABLE_TASK_MANAGER)
125  TaskManager::GetInstance()->model()->NotifyResourceTypeStats(peer_pid(),
126                                                               stats);
127#endif  // defined(ENABLE_TASK_MANAGER)
128}
129
130void ChromeRenderMessageFilter::OnUpdatedCacheStats(
131    const WebCache::UsageStats& stats) {
132  WebCacheManager::GetInstance()->ObserveStats(render_process_id_, stats);
133}
134
135void ChromeRenderMessageFilter::OnFPS(int routing_id, float fps) {
136  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
137    BrowserThread::PostTask(
138        BrowserThread::UI, FROM_HERE,
139        base::Bind(
140            &ChromeRenderMessageFilter::OnFPS, this,
141            routing_id, fps));
142    return;
143  }
144
145#if defined(ENABLE_TASK_MANAGER)
146  TaskManager::GetInstance()->model()->NotifyFPS(
147      peer_pid(), routing_id, fps);
148#endif  // defined(ENABLE_TASK_MANAGER)
149}
150
151void ChromeRenderMessageFilter::OnV8HeapStats(int v8_memory_allocated,
152                                              int v8_memory_used) {
153  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
154    BrowserThread::PostTask(
155        BrowserThread::UI, FROM_HERE,
156        base::Bind(&ChromeRenderMessageFilter::OnV8HeapStats, this,
157                   v8_memory_allocated, v8_memory_used));
158    return;
159  }
160
161  base::ProcessId renderer_id = peer_pid();
162
163#if defined(ENABLE_TASK_MANAGER)
164  TaskManager::GetInstance()->model()->NotifyV8HeapStats(
165      renderer_id,
166      static_cast<size_t>(v8_memory_allocated),
167      static_cast<size_t>(v8_memory_used));
168#endif  // defined(ENABLE_TASK_MANAGER)
169
170  V8HeapStatsDetails details(v8_memory_allocated, v8_memory_used);
171  content::NotificationService::current()->Notify(
172      chrome::NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED,
173      content::Source<const base::ProcessId>(&renderer_id),
174      content::Details<const V8HeapStatsDetails>(&details));
175}
176
177void ChromeRenderMessageFilter::OnAllowDatabase(
178    int render_frame_id,
179    const GURL& origin_url,
180    const GURL& top_origin_url,
181    const base::string16& name,
182    const base::string16& display_name,
183    bool* allowed) {
184  *allowed =
185      cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
186  BrowserThread::PostTask(
187      BrowserThread::UI, FROM_HERE,
188      base::Bind(&TabSpecificContentSettings::WebDatabaseAccessed,
189                 render_process_id_, render_frame_id, origin_url, name,
190                 display_name, !*allowed));
191}
192
193void ChromeRenderMessageFilter::OnAllowDOMStorage(int render_frame_id,
194                                                  const GURL& origin_url,
195                                                  const GURL& top_origin_url,
196                                                  bool local,
197                                                  bool* allowed) {
198  *allowed =
199      cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
200  // Record access to DOM storage for potential display in UI.
201  BrowserThread::PostTask(
202      BrowserThread::UI, FROM_HERE,
203      base::Bind(&TabSpecificContentSettings::DOMStorageAccessed,
204                 render_process_id_, render_frame_id, origin_url, local,
205                 !*allowed));
206}
207
208void ChromeRenderMessageFilter::OnRequestFileSystemAccessSync(
209    int render_frame_id,
210    const GURL& origin_url,
211    const GURL& top_origin_url,
212    bool* allowed) {
213  *allowed =
214      cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
215  // Record access to file system for potential display in UI.
216  BrowserThread::PostTask(
217      BrowserThread::UI, FROM_HERE,
218      base::Bind(&TabSpecificContentSettings::FileSystemAccessed,
219                 render_process_id_, render_frame_id, origin_url, !*allowed));
220}
221
222void ChromeRenderMessageFilter::OnRequestFileSystemAccessAsync(
223    int render_frame_id,
224    int request_id,
225    const GURL& origin_url,
226    const GURL& top_origin_url) {
227  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
228
229  bool allowed =
230      cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
231  // Record access to file system for potential display in UI.
232  BrowserThread::PostTask(
233      BrowserThread::UI, FROM_HERE,
234      base::Bind(
235          &TabSpecificContentSettings::FileSystemAccessed,
236          render_process_id_,
237          render_frame_id,
238          origin_url,
239          !allowed));
240
241  Send(new ChromeViewMsg_RequestFileSystemAccessAsyncResponse(
242      render_frame_id,
243      request_id,
244      allowed));
245}
246
247void ChromeRenderMessageFilter::OnAllowIndexedDB(int render_frame_id,
248                                                 const GURL& origin_url,
249                                                 const GURL& top_origin_url,
250                                                 const base::string16& name,
251                                                 bool* allowed) {
252  *allowed =
253      cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
254  BrowserThread::PostTask(
255      BrowserThread::UI, FROM_HERE,
256      base::Bind(&TabSpecificContentSettings::IndexedDBAccessed,
257                 render_process_id_, render_frame_id, origin_url, name,
258                 !*allowed));
259}
260
261#if defined(ENABLE_PLUGINS)
262void ChromeRenderMessageFilter::OnIsCrashReportingEnabled(bool* enabled) {
263  *enabled = ChromeMetricsServiceAccessor::IsCrashReportingEnabled();
264}
265#endif
266