Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / renderer_host / chrome_render_message_filter.cc
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/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"
24
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"
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
38 using content::BrowserThread;
39 using blink::WebCache;
40
41 namespace {
42
43 const uint32 kFilteredMessageClasses[] = {
44   ChromeMsgStart,
45 };
46
47 }  // namespace
48
49 ChromeRenderMessageFilter::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
60 ChromeRenderMessageFilter::~ChromeRenderMessageFilter() {
61 }
62
63 bool 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
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;
97       break;
98     default:
99       break;
100   }
101 }
102
103 void ChromeRenderMessageFilter::OnDnsPrefetch(
104     const std::vector<std::string>& hostnames) {
105   if (predictor_)
106     predictor_->DnsPrefetchList(hostnames);
107 }
108
109 void ChromeRenderMessageFilter::OnPreconnect(const GURL& url) {
110   if (predictor_)
111     predictor_->PreconnectUrl(
112         url, GURL(), chrome_browser_net::UrlInfo::MOUSE_OVER_MOTIVATED, 1);
113 }
114
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));
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
135 void ChromeRenderMessageFilter::OnUpdatedCacheStats(
136     const WebCache::UsageStats& stats) {
137   web_cache::WebCacheManager::GetInstance()->ObserveStats(
138       render_process_id_, stats);
139 }
140
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));
148     return;
149   }
150
151   base::ProcessId renderer_id = peer_pid();
152
153 #if defined(ENABLE_TASK_MANAGER)
154   TaskManager::GetInstance()->model()->NotifyV8HeapStats(
155       renderer_id,
156       static_cast<size_t>(v8_memory_allocated),
157       static_cast<size_t>(v8_memory_used));
158 #endif  // defined(ENABLE_TASK_MANAGER)
159
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));
165 }
166
167 void ChromeRenderMessageFilter::OnAllowDatabase(
168     int render_frame_id,
169     const GURL& origin_url,
170     const GURL& top_origin_url,
171     const base::string16& name,
172     const base::string16& display_name,
173     bool* allowed) {
174   *allowed =
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));
181 }
182
183 void ChromeRenderMessageFilter::OnAllowDOMStorage(int render_frame_id,
184                                                   const GURL& origin_url,
185                                                   const GURL& top_origin_url,
186                                                   bool local,
187                                                   bool* allowed) {
188   *allowed =
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,
195                  !*allowed));
196 }
197
198 void ChromeRenderMessageFilter::OnRequestFileSystemAccessSync(
199     int render_frame_id,
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),
208                  reply_msg);
209   OnRequestFileSystemAccess(render_frame_id,
210                             origin_url,
211                             top_origin_url,
212                             callback);
213 }
214
215 void ChromeRenderMessageFilter::OnRequestFileSystemAccessSyncResponse(
216     IPC::Message* reply_msg,
217     bool allowed) {
218   ChromeViewHostMsg_RequestFileSystemAccessSync::WriteReplyParams(reply_msg,
219                                                                   allowed);
220   Send(reply_msg);
221 }
222
223 #if defined(ENABLE_EXTENSIONS)
224 void ChromeRenderMessageFilter::FileSystemAccessedSyncOnUIThread(
225     int render_process_id,
226     int render_frame_id,
227     const GURL& url,
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)
237     return;
238   web_view_permission_helper->FileSystemAccessedSync(
239       render_process_id, render_frame_id, url, blocked_by_policy, reply_msg);
240 }
241 #endif
242
243 void ChromeRenderMessageFilter::OnRequestFileSystemAccessAsync(
244     int render_frame_id,
245     int request_id,
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),
253                  render_frame_id,
254                  request_id);
255   OnRequestFileSystemAccess(render_frame_id,
256                             origin_url,
257                             top_origin_url,
258                             callback);
259 }
260
261 void ChromeRenderMessageFilter::OnRequestFileSystemAccessAsyncResponse(
262     int render_frame_id,
263     int request_id,
264     bool allowed) {
265   Send(new ChromeViewMsg_RequestFileSystemAccessAsyncResponse(
266       render_frame_id, request_id, allowed));
267 }
268
269 void ChromeRenderMessageFilter::OnRequestFileSystemAccess(
270     int render_frame_id,
271     const GURL& origin_url,
272     const GURL& top_origin_url,
273     base::Callback<void(bool)> callback) {
274   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
275
276   bool allowed =
277       cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
278
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(
285         BrowserThread::UI,
286         FROM_HERE,
287         base::Bind(&ChromeRenderMessageFilter::FileSystemAccessedOnUIThread,
288                    render_process_id_,
289                    render_frame_id,
290                    origin_url,
291                    allowed,
292                    callback));
293     return;
294   }
295 #endif
296   callback.Run(allowed);
297   // Record access to file system for potential display in UI.
298   BrowserThread::PostTask(
299       BrowserThread::UI,
300       FROM_HERE,
301       base::Bind(&TabSpecificContentSettings::FileSystemAccessed,
302                  render_process_id_,
303                  render_frame_id,
304                  origin_url,
305                  !allowed));
306 }
307
308 #if defined(ENABLE_EXTENSIONS)
309 void ChromeRenderMessageFilter::FileSystemAccessedOnUIThread(
310     int render_process_id,
311     int render_frame_id,
312     const GURL& url,
313     bool allowed,
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)
322     return;
323   web_view_permission_helper->RequestFileSystemPermission(
324       url,
325       allowed,
326       base::Bind(&ChromeRenderMessageFilter::FileSystemAccessedResponse,
327                  render_process_id,
328                  render_frame_id,
329                  url,
330                  callback));
331 }
332
333 void ChromeRenderMessageFilter::FileSystemAccessedResponse(
334     int render_process_id,
335     int render_frame_id,
336     const GURL& url,
337     base::Callback<void(bool)> callback,
338     bool allowed) {
339   TabSpecificContentSettings::FileSystemAccessed(
340       render_process_id, render_frame_id, url, !allowed);
341   callback.Run(allowed);
342 }
343 #endif
344
345 void ChromeRenderMessageFilter::OnAllowIndexedDB(int render_frame_id,
346                                                  const GURL& origin_url,
347                                                  const GURL& top_origin_url,
348                                                  const base::string16& name,
349                                                  bool* allowed) {
350   *allowed =
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,
356                  !*allowed));
357 }
358
359 #if defined(ENABLE_PLUGINS)
360 void ChromeRenderMessageFilter::OnIsCrashReportingEnabled(bool* enabled) {
361   *enabled = ChromeMetricsServiceAccessor::IsCrashReportingEnabled();
362 }
363 #endif