Upstream version 9.38.198.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/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
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   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
135 void ChromeRenderMessageFilter::OnUpdatedCacheStats(
136     const WebCache::UsageStats& stats) {
137   WebCacheManager::GetInstance()->ObserveStats(render_process_id_, stats);
138 }
139
140 void 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
166 void 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
182 void 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
197 void 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
214 void 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)
223 void 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
242 void 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
260 void 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
268 void 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)
308 void 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
332 void 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
344 void 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)
359 void ChromeRenderMessageFilter::OnIsCrashReportingEnabled(bool* enabled) {
360   *enabled = ChromeMetricsServiceAccessor::IsCrashReportingEnabled();
361 }
362 #endif