- add sources.
[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/command_line.h"
12 #include "base/metrics/field_trial.h"
13 #include "base/metrics/histogram.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/browser/automation/automation_resource_message_filter.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/chrome_notification_types.h"
18 #include "chrome/browser/content_settings/cookie_settings.h"
19 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
20 #include "chrome/browser/extensions/activity_log/activity_action_constants.h"
21 #include "chrome/browser/extensions/activity_log/activity_actions.h"
22 #include "chrome/browser/extensions/activity_log/activity_log.h"
23 #include "chrome/browser/extensions/api/activity_log_private/activity_log_private_api.h"
24 #include "chrome/browser/extensions/api/messaging/message_service.h"
25 #include "chrome/browser/extensions/event_router.h"
26 #include "chrome/browser/extensions/extension_process_manager.h"
27 #include "chrome/browser/extensions/extension_system.h"
28 #include "chrome/browser/google/google_util.h"
29 #include "chrome/browser/net/chrome_url_request_context.h"
30 #include "chrome/browser/net/predictor.h"
31 #include "chrome/browser/profiles/profile_manager.h"
32 #include "chrome/browser/task_manager/task_manager.h"
33 #include "chrome/common/chrome_switches.h"
34 #include "chrome/common/extensions/api/i18n/default_locale_handler.h"
35 #include "chrome/common/extensions/extension_file_util.h"
36 #include "chrome/common/extensions/extension_messages.h"
37 #include "chrome/common/extensions/message_bundle.h"
38 #include "chrome/common/render_messages.h"
39 #include "content/public/browser/notification_service.h"
40 #include "content/public/browser/render_process_host.h"
41 #include "content/public/browser/resource_dispatcher_host.h"
42 #include "extensions/common/constants.h"
43
44 #if defined(USE_TCMALLOC)
45 #include "chrome/browser/browser_about_handler.h"
46 #endif
47
48 using content::BrowserThread;
49 using extensions::APIPermission;
50 using WebKit::WebCache;
51
52 namespace {
53
54 // Logs an action to the extension activity log for the specified profile.  Can
55 // be called from any thread.
56 void AddActionToExtensionActivityLog(
57     Profile* profile,
58     scoped_refptr<extensions::Action> action) {
59 #if defined(ENABLE_EXTENSIONS)
60   // The ActivityLog can only be accessed from the main (UI) thread.  If we're
61   // running on the wrong thread, re-dispatch from the main thread.
62   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
63     BrowserThread::PostTask(
64         BrowserThread::UI, FROM_HERE,
65         base::Bind(&AddActionToExtensionActivityLog, profile, action));
66   } else {
67     if (!g_browser_process->profile_manager()->IsValidProfile(profile))
68       return;
69     // If the action included a URL, check whether it is for an incognito
70     // profile.  The check is performed here so that it can safely be done from
71     // the UI thread.
72     if (action->page_url().is_valid() || !action->page_title().empty())
73       action->set_page_incognito(profile->IsOffTheRecord());
74     extensions::ActivityLog* activity_log =
75         extensions::ActivityLog::GetInstance(profile);
76     activity_log->LogAction(action);
77   }
78 #endif
79 }
80
81 } // namespace
82
83 ChromeRenderMessageFilter::ChromeRenderMessageFilter(
84     int render_process_id,
85     Profile* profile,
86     net::URLRequestContextGetter* request_context)
87     : render_process_id_(render_process_id),
88       profile_(profile),
89       off_the_record_(profile_->IsOffTheRecord()),
90       request_context_(request_context),
91       extension_info_map_(
92           extensions::ExtensionSystem::Get(profile)->info_map()),
93       cookie_settings_(CookieSettings::Factory::GetForProfile(profile)),
94       weak_ptr_factory_(this) {
95 }
96
97 ChromeRenderMessageFilter::~ChromeRenderMessageFilter() {
98 }
99
100 bool ChromeRenderMessageFilter::OnMessageReceived(const IPC::Message& message,
101                                                   bool* message_was_ok) {
102   bool handled = true;
103   IPC_BEGIN_MESSAGE_MAP_EX(ChromeRenderMessageFilter, message, *message_was_ok)
104     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DnsPrefetch, OnDnsPrefetch)
105     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_Preconnect, OnPreconnect)
106     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ResourceTypeStats,
107                         OnResourceTypeStats)
108     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_UpdatedCacheStats,
109                         OnUpdatedCacheStats)
110     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FPS, OnFPS)
111     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_V8HeapStats, OnV8HeapStats)
112     IPC_MESSAGE_HANDLER(ExtensionHostMsg_OpenChannelToExtension,
113                         OnOpenChannelToExtension)
114     IPC_MESSAGE_HANDLER(ExtensionHostMsg_OpenChannelToTab, OnOpenChannelToTab)
115     IPC_MESSAGE_HANDLER(ExtensionHostMsg_OpenChannelToNativeApp,
116                         OnOpenChannelToNativeApp)
117     IPC_MESSAGE_HANDLER_DELAY_REPLY(ExtensionHostMsg_GetMessageBundle,
118                                     OnGetExtensionMessageBundle)
119     IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddListener, OnExtensionAddListener)
120     IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveListener,
121                         OnExtensionRemoveListener)
122     IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddLazyListener,
123                         OnExtensionAddLazyListener)
124     IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveLazyListener,
125                         OnExtensionRemoveLazyListener)
126     IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener,
127                         OnExtensionAddFilteredListener)
128     IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener,
129                         OnExtensionRemoveFilteredListener)
130     IPC_MESSAGE_HANDLER(ExtensionHostMsg_CloseChannel, OnExtensionCloseChannel)
131     IPC_MESSAGE_HANDLER(ExtensionHostMsg_RequestForIOThread,
132                         OnExtensionRequestForIOThread)
133     IPC_MESSAGE_HANDLER(ExtensionHostMsg_ShouldSuspendAck,
134                         OnExtensionShouldSuspendAck)
135     IPC_MESSAGE_HANDLER(ExtensionHostMsg_GenerateUniqueID,
136                         OnExtensionGenerateUniqueID)
137     IPC_MESSAGE_HANDLER(ExtensionHostMsg_SuspendAck, OnExtensionSuspendAck)
138     IPC_MESSAGE_HANDLER(ExtensionHostMsg_ResumeRequests,
139                         OnExtensionResumeRequests);
140     IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddAPIActionToActivityLog,
141                         OnAddAPIActionToExtensionActivityLog);
142     IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddDOMActionToActivityLog,
143                         OnAddDOMActionToExtensionActivityLog);
144     IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddEventToActivityLog,
145                         OnAddEventToExtensionActivityLog);
146     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDatabase, OnAllowDatabase)
147     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDOMStorage, OnAllowDOMStorage)
148     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowFileSystem, OnAllowFileSystem)
149     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowIndexedDB, OnAllowIndexedDB)
150     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_CanTriggerClipboardRead,
151                         OnCanTriggerClipboardRead)
152     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_CanTriggerClipboardWrite,
153                         OnCanTriggerClipboardWrite)
154     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_IsWebGLDebugRendererInfoAllowed,
155                         OnIsWebGLDebugRendererInfoAllowed)
156     IPC_MESSAGE_UNHANDLED(handled = false)
157   IPC_END_MESSAGE_MAP()
158
159 #if defined(ENABLE_AUTOMATION)
160   if ((message.type() == ChromeViewHostMsg_GetCookies::ID ||
161        message.type() == ChromeViewHostMsg_SetCookie::ID) &&
162     AutomationResourceMessageFilter::ShouldFilterCookieMessages(
163         render_process_id_, message.routing_id())) {
164     // ChromeFrame then we need to get/set cookies from the external host.
165     IPC_BEGIN_MESSAGE_MAP_EX(ChromeRenderMessageFilter, message,
166                              *message_was_ok)
167       IPC_MESSAGE_HANDLER_DELAY_REPLY(ChromeViewHostMsg_GetCookies,
168                                       OnGetCookies)
169       IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SetCookie, OnSetCookie)
170     IPC_END_MESSAGE_MAP()
171     handled = true;
172   }
173 #endif
174
175   return handled;
176 }
177
178 void ChromeRenderMessageFilter::OverrideThreadForMessage(
179     const IPC::Message& message, BrowserThread::ID* thread) {
180   switch (message.type()) {
181     case ChromeViewHostMsg_ResourceTypeStats::ID:
182     case ExtensionHostMsg_AddListener::ID:
183     case ExtensionHostMsg_RemoveListener::ID:
184     case ExtensionHostMsg_AddLazyListener::ID:
185     case ExtensionHostMsg_RemoveLazyListener::ID:
186     case ExtensionHostMsg_AddFilteredListener::ID:
187     case ExtensionHostMsg_RemoveFilteredListener::ID:
188     case ExtensionHostMsg_CloseChannel::ID:
189     case ExtensionHostMsg_ShouldSuspendAck::ID:
190     case ExtensionHostMsg_SuspendAck::ID:
191     case ChromeViewHostMsg_UpdatedCacheStats::ID:
192       *thread = BrowserThread::UI;
193       break;
194     default:
195       break;
196   }
197 }
198
199 net::HostResolver* ChromeRenderMessageFilter::GetHostResolver() {
200   return request_context_->GetURLRequestContext()->host_resolver();
201 }
202
203 void ChromeRenderMessageFilter::OnDnsPrefetch(
204     const std::vector<std::string>& hostnames) {
205   if (profile_->GetNetworkPredictor())
206     profile_->GetNetworkPredictor()->DnsPrefetchList(hostnames);
207 }
208
209 void ChromeRenderMessageFilter::OnPreconnect(const GURL& url) {
210   if (profile_->GetNetworkPredictor())
211     profile_->GetNetworkPredictor()->PreconnectUrl(
212         url, GURL(), chrome_browser_net::UrlInfo::MOUSE_OVER_MOTIVATED, 1);
213 }
214
215 void ChromeRenderMessageFilter::OnResourceTypeStats(
216     const WebCache::ResourceTypeStats& stats) {
217   HISTOGRAM_COUNTS("WebCoreCache.ImagesSizeKB",
218                    static_cast<int>(stats.images.size / 1024));
219   HISTOGRAM_COUNTS("WebCoreCache.CSSStylesheetsSizeKB",
220                    static_cast<int>(stats.cssStyleSheets.size / 1024));
221   HISTOGRAM_COUNTS("WebCoreCache.ScriptsSizeKB",
222                    static_cast<int>(stats.scripts.size / 1024));
223   HISTOGRAM_COUNTS("WebCoreCache.XSLStylesheetsSizeKB",
224                    static_cast<int>(stats.xslStyleSheets.size / 1024));
225   HISTOGRAM_COUNTS("WebCoreCache.FontsSizeKB",
226                    static_cast<int>(stats.fonts.size / 1024));
227
228   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
229 #if defined(ENABLE_TASK_MANAGER)
230   TaskManager::GetInstance()->model()->NotifyResourceTypeStats(peer_pid(),
231                                                                stats);
232 #endif  // defined(ENABLE_TASK_MANAGER)
233 }
234
235 void ChromeRenderMessageFilter::OnUpdatedCacheStats(
236     const WebCache::UsageStats& stats) {
237   WebCacheManager::GetInstance()->ObserveStats(render_process_id_, stats);
238 }
239
240 void ChromeRenderMessageFilter::OnFPS(int routing_id, float fps) {
241   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
242     BrowserThread::PostTask(
243         BrowserThread::UI, FROM_HERE,
244         base::Bind(
245             &ChromeRenderMessageFilter::OnFPS, this,
246             routing_id, fps));
247     return;
248   }
249
250   base::ProcessId renderer_id = peer_pid();
251
252 #if defined(ENABLE_TASK_MANAGER)
253   TaskManager::GetInstance()->model()->NotifyFPS(
254       renderer_id, routing_id, fps);
255 #endif  // defined(ENABLE_TASK_MANAGER)
256
257   FPSDetails details(routing_id, fps);
258   content::NotificationService::current()->Notify(
259       chrome::NOTIFICATION_RENDERER_FPS_COMPUTED,
260       content::Source<const base::ProcessId>(&renderer_id),
261       content::Details<const FPSDetails>(&details));
262 }
263
264 void ChromeRenderMessageFilter::OnV8HeapStats(int v8_memory_allocated,
265                                               int v8_memory_used) {
266   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
267     BrowserThread::PostTask(
268         BrowserThread::UI, FROM_HERE,
269         base::Bind(&ChromeRenderMessageFilter::OnV8HeapStats, this,
270                    v8_memory_allocated, v8_memory_used));
271     return;
272   }
273
274   base::ProcessId renderer_id = peer_pid();
275
276 #if defined(ENABLE_TASK_MANAGER)
277   TaskManager::GetInstance()->model()->NotifyV8HeapStats(
278       renderer_id,
279       static_cast<size_t>(v8_memory_allocated),
280       static_cast<size_t>(v8_memory_used));
281 #endif  // defined(ENABLE_TASK_MANAGER)
282
283   V8HeapStatsDetails details(v8_memory_allocated, v8_memory_used);
284   content::NotificationService::current()->Notify(
285       chrome::NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED,
286       content::Source<const base::ProcessId>(&renderer_id),
287       content::Details<const V8HeapStatsDetails>(&details));
288 }
289
290 void ChromeRenderMessageFilter::OnOpenChannelToExtension(
291     int routing_id,
292     const ExtensionMsg_ExternalConnectionInfo& info,
293     const std::string& channel_name,
294     bool include_tls_channel_id,
295     int* port_id) {
296   int port2_id;
297   extensions::MessageService::AllocatePortIdPair(port_id, &port2_id);
298
299   BrowserThread::PostTask(
300       BrowserThread::UI, FROM_HERE,
301       base::Bind(&ChromeRenderMessageFilter::OpenChannelToExtensionOnUIThread,
302                  this, render_process_id_, routing_id, port2_id, info,
303                  channel_name, include_tls_channel_id));
304 }
305
306 void ChromeRenderMessageFilter::OpenChannelToExtensionOnUIThread(
307     int source_process_id, int source_routing_id,
308     int receiver_port_id,
309     const ExtensionMsg_ExternalConnectionInfo& info,
310     const std::string& channel_name,
311     bool include_tls_channel_id) {
312   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
313   extensions::MessageService::Get(profile_)->OpenChannelToExtension(
314       source_process_id, source_routing_id, receiver_port_id,
315       info.source_id, info.target_id, info.source_url, channel_name,
316       include_tls_channel_id);
317 }
318
319 void ChromeRenderMessageFilter::OnOpenChannelToNativeApp(
320     int routing_id,
321     const std::string& source_extension_id,
322     const std::string& native_app_name,
323     int* port_id) {
324   int port2_id;
325   extensions::MessageService::AllocatePortIdPair(port_id, &port2_id);
326
327   BrowserThread::PostTask(
328       BrowserThread::UI, FROM_HERE,
329       base::Bind(&ChromeRenderMessageFilter::OpenChannelToNativeAppOnUIThread,
330                  this, routing_id, port2_id, source_extension_id,
331                  native_app_name));
332 }
333
334 void ChromeRenderMessageFilter::OpenChannelToNativeAppOnUIThread(
335     int source_routing_id,
336     int receiver_port_id,
337     const std::string& source_extension_id,
338     const std::string& native_app_name) {
339   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
340   extensions::MessageService::Get(profile_)->OpenChannelToNativeApp(
341       render_process_id_, source_routing_id, receiver_port_id,
342       source_extension_id, native_app_name);
343 }
344
345 void ChromeRenderMessageFilter::OnOpenChannelToTab(
346     int routing_id, int tab_id, const std::string& extension_id,
347     const std::string& channel_name, int* port_id) {
348   int port2_id;
349   extensions::MessageService::AllocatePortIdPair(port_id, &port2_id);
350
351   BrowserThread::PostTask(
352       BrowserThread::UI, FROM_HERE,
353       base::Bind(&ChromeRenderMessageFilter::OpenChannelToTabOnUIThread, this,
354                  render_process_id_, routing_id, port2_id, tab_id, extension_id,
355                  channel_name));
356 }
357
358 void ChromeRenderMessageFilter::OpenChannelToTabOnUIThread(
359     int source_process_id, int source_routing_id,
360     int receiver_port_id,
361     int tab_id,
362     const std::string& extension_id,
363     const std::string& channel_name) {
364   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
365   extensions::MessageService::Get(profile_)->OpenChannelToTab(
366       source_process_id, source_routing_id, receiver_port_id,
367       tab_id, extension_id, channel_name);
368 }
369
370 void ChromeRenderMessageFilter::OnGetExtensionMessageBundle(
371     const std::string& extension_id, IPC::Message* reply_msg) {
372   const extensions::Extension* extension =
373       extension_info_map_->extensions().GetByID(extension_id);
374   base::FilePath extension_path;
375   std::string default_locale;
376   if (extension) {
377     extension_path = extension->path();
378     default_locale = extensions::LocaleInfo::GetDefaultLocale(extension);
379   }
380
381   BrowserThread::PostTask(
382       BrowserThread::FILE, FROM_HERE,
383       base::Bind(
384           &ChromeRenderMessageFilter::OnGetExtensionMessageBundleOnFileThread,
385           this, extension_path, extension_id, default_locale, reply_msg));
386 }
387
388 void ChromeRenderMessageFilter::OnGetExtensionMessageBundleOnFileThread(
389     const base::FilePath& extension_path,
390     const std::string& extension_id,
391     const std::string& default_locale,
392     IPC::Message* reply_msg) {
393   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
394
395   scoped_ptr<extensions::MessageBundle::SubstitutionMap> dictionary_map(
396       extension_file_util::LoadMessageBundleSubstitutionMap(
397           extension_path, extension_id, default_locale));
398
399   ExtensionHostMsg_GetMessageBundle::WriteReplyParams(reply_msg,
400                                                       *dictionary_map);
401   Send(reply_msg);
402 }
403
404 void ChromeRenderMessageFilter::OnExtensionAddListener(
405     const std::string& extension_id,
406     const std::string& event_name) {
407   content::RenderProcessHost* process =
408       content::RenderProcessHost::FromID(render_process_id_);
409   if (!process || !extensions::ExtensionSystem::Get(profile_)->event_router())
410     return;
411
412   extensions::ExtensionSystem::Get(profile_)->event_router()->AddEventListener(
413       event_name, process, extension_id);
414 }
415
416 void ChromeRenderMessageFilter::OnExtensionRemoveListener(
417     const std::string& extension_id,
418     const std::string& event_name) {
419   content::RenderProcessHost* process =
420       content::RenderProcessHost::FromID(render_process_id_);
421   if (!process || !extensions::ExtensionSystem::Get(profile_)->event_router())
422     return;
423
424   extensions::ExtensionSystem::Get(profile_)->event_router()->
425       RemoveEventListener(event_name, process, extension_id);
426 }
427
428 void ChromeRenderMessageFilter::OnExtensionAddLazyListener(
429     const std::string& extension_id, const std::string& event_name) {
430   if (extensions::ExtensionSystem::Get(profile_)->event_router()) {
431     extensions::ExtensionSystem::Get(profile_)->event_router()->
432         AddLazyEventListener(event_name, extension_id);
433   }
434 }
435
436 void ChromeRenderMessageFilter::OnExtensionRemoveLazyListener(
437     const std::string& extension_id, const std::string& event_name) {
438   if (extensions::ExtensionSystem::Get(profile_)->event_router()) {
439     extensions::ExtensionSystem::Get(profile_)->event_router()->
440         RemoveLazyEventListener(event_name, extension_id);
441   }
442 }
443
444 void ChromeRenderMessageFilter::OnExtensionAddFilteredListener(
445     const std::string& extension_id,
446     const std::string& event_name,
447     const base::DictionaryValue& filter,
448     bool lazy) {
449   content::RenderProcessHost* process =
450       content::RenderProcessHost::FromID(render_process_id_);
451   if (!process || !extensions::ExtensionSystem::Get(profile_)->event_router())
452     return;
453
454   extensions::ExtensionSystem::Get(profile_)->event_router()->
455       AddFilteredEventListener(event_name, process, extension_id, filter, lazy);
456 }
457
458 void ChromeRenderMessageFilter::OnExtensionRemoveFilteredListener(
459     const std::string& extension_id,
460     const std::string& event_name,
461     const base::DictionaryValue& filter,
462     bool lazy) {
463   content::RenderProcessHost* process =
464       content::RenderProcessHost::FromID(render_process_id_);
465   if (!process || !extensions::ExtensionSystem::Get(profile_)->event_router())
466     return;
467
468   extensions::ExtensionSystem::Get(profile_)->event_router()->
469       RemoveFilteredEventListener(event_name, process, extension_id, filter,
470                                   lazy);
471 }
472
473 void ChromeRenderMessageFilter::OnExtensionCloseChannel(
474     int port_id,
475     const std::string& error_message) {
476   if (!content::RenderProcessHost::FromID(render_process_id_))
477     return;  // To guard against crash in browser_tests shutdown.
478
479   extensions::MessageService* message_service =
480       extensions::MessageService::Get(profile_);
481   if (message_service)
482     message_service->CloseChannel(port_id, error_message);
483 }
484
485 void ChromeRenderMessageFilter::OnExtensionRequestForIOThread(
486     int routing_id,
487     const ExtensionHostMsg_Request_Params& params) {
488   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
489
490   ExtensionFunctionDispatcher::DispatchOnIOThread(
491       extension_info_map_.get(), profile_, render_process_id_,
492       weak_ptr_factory_.GetWeakPtr(), routing_id, params);
493 }
494
495 void ChromeRenderMessageFilter::OnExtensionShouldSuspendAck(
496      const std::string& extension_id, int sequence_id) {
497   if (extensions::ExtensionSystem::Get(profile_)->process_manager()) {
498     extensions::ExtensionSystem::Get(profile_)->process_manager()->
499         OnShouldSuspendAck(extension_id, sequence_id);
500   }
501 }
502
503 void ChromeRenderMessageFilter::OnExtensionSuspendAck(
504      const std::string& extension_id) {
505   if (extensions::ExtensionSystem::Get(profile_)->process_manager()) {
506     extensions::ExtensionSystem::Get(profile_)->process_manager()->
507         OnSuspendAck(extension_id);
508   }
509 }
510
511 void ChromeRenderMessageFilter::OnExtensionGenerateUniqueID(int* unique_id) {
512   static int next_unique_id = 0;
513   *unique_id = ++next_unique_id;
514 }
515
516 void ChromeRenderMessageFilter::OnExtensionResumeRequests(int route_id) {
517   content::ResourceDispatcherHost::Get()->ResumeBlockedRequestsForRoute(
518       render_process_id_, route_id);
519 }
520
521 void ChromeRenderMessageFilter::OnAddAPIActionToExtensionActivityLog(
522     const std::string& extension_id,
523     const ExtensionHostMsg_APIActionOrEvent_Params& params) {
524   scoped_refptr<extensions::Action> action = new extensions::Action(
525       extension_id, base::Time::Now(), extensions::Action::ACTION_API_CALL,
526       params.api_call);
527   action->set_args(make_scoped_ptr(params.arguments.DeepCopy()));
528   if (!params.extra.empty()) {
529     action->mutable_other()->SetString(
530         activity_log_constants::kActionExtra, params.extra);
531   }
532   AddActionToExtensionActivityLog(profile_, action);
533 }
534
535 void ChromeRenderMessageFilter::OnAddDOMActionToExtensionActivityLog(
536     const std::string& extension_id,
537     const ExtensionHostMsg_DOMAction_Params& params) {
538   scoped_refptr<extensions::Action> action = new extensions::Action(
539       extension_id, base::Time::Now(), extensions::Action::ACTION_DOM_ACCESS,
540       params.api_call);
541   action->set_args(make_scoped_ptr(params.arguments.DeepCopy()));
542   action->set_page_url(params.url);
543   action->set_page_title(base::UTF16ToUTF8(params.url_title));
544   action->mutable_other()->SetInteger(activity_log_constants::kActionDomVerb,
545                                       params.call_type);
546   AddActionToExtensionActivityLog(profile_, action);
547 }
548
549 void ChromeRenderMessageFilter::OnAddEventToExtensionActivityLog(
550     const std::string& extension_id,
551     const ExtensionHostMsg_APIActionOrEvent_Params& params) {
552   scoped_refptr<extensions::Action> action = new extensions::Action(
553       extension_id, base::Time::Now(), extensions::Action::ACTION_API_EVENT,
554       params.api_call);
555   action->set_args(make_scoped_ptr(params.arguments.DeepCopy()));
556   if (!params.extra.empty()) {
557     action->mutable_other()->SetString(activity_log_constants::kActionExtra,
558                                        params.extra);
559   }
560   AddActionToExtensionActivityLog(profile_, action);
561 }
562
563 void ChromeRenderMessageFilter::OnAllowDatabase(int render_view_id,
564                                                 const GURL& origin_url,
565                                                 const GURL& top_origin_url,
566                                                 const string16& name,
567                                                 const string16& display_name,
568                                                 bool* allowed) {
569   *allowed =
570       cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
571   BrowserThread::PostTask(
572       BrowserThread::UI, FROM_HERE,
573       base::Bind(&TabSpecificContentSettings::WebDatabaseAccessed,
574                  render_process_id_, render_view_id, origin_url, name,
575                  display_name, !*allowed));
576 }
577
578 void ChromeRenderMessageFilter::OnAllowDOMStorage(int render_view_id,
579                                                   const GURL& origin_url,
580                                                   const GURL& top_origin_url,
581                                                   bool local,
582                                                   bool* allowed) {
583   *allowed =
584       cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
585   // Record access to DOM storage for potential display in UI.
586   BrowserThread::PostTask(
587       BrowserThread::UI, FROM_HERE,
588       base::Bind(&TabSpecificContentSettings::DOMStorageAccessed,
589                  render_process_id_, render_view_id, origin_url, local,
590                  !*allowed));
591 }
592
593 void ChromeRenderMessageFilter::OnAllowFileSystem(int render_view_id,
594                                                   const GURL& origin_url,
595                                                   const GURL& top_origin_url,
596                                                   bool* allowed) {
597   *allowed =
598       cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
599   // Record access to file system for potential display in UI.
600   BrowserThread::PostTask(
601       BrowserThread::UI, FROM_HERE,
602       base::Bind(&TabSpecificContentSettings::FileSystemAccessed,
603                  render_process_id_, render_view_id, origin_url, !*allowed));
604 }
605
606 void ChromeRenderMessageFilter::OnAllowIndexedDB(int render_view_id,
607                                                  const GURL& origin_url,
608                                                  const GURL& top_origin_url,
609                                                  const string16& name,
610                                                  bool* allowed) {
611   *allowed =
612       cookie_settings_->IsSettingCookieAllowed(origin_url, top_origin_url);
613   BrowserThread::PostTask(
614       BrowserThread::UI, FROM_HERE,
615       base::Bind(&TabSpecificContentSettings::IndexedDBAccessed,
616                  render_process_id_, render_view_id, origin_url, name,
617                  !*allowed));
618 }
619
620 void ChromeRenderMessageFilter::OnCanTriggerClipboardRead(
621     const GURL& origin, bool* allowed) {
622   *allowed = extension_info_map_->SecurityOriginHasAPIPermission(
623       origin, render_process_id_, APIPermission::kClipboardRead);
624 }
625
626 void ChromeRenderMessageFilter::OnCanTriggerClipboardWrite(
627     const GURL& origin, bool* allowed) {
628   // Since all extensions could historically write to the clipboard, preserve it
629   // for compatibility.
630   *allowed = (origin.SchemeIs(extensions::kExtensionScheme) ||
631       extension_info_map_->SecurityOriginHasAPIPermission(
632           origin, render_process_id_, APIPermission::kClipboardWrite));
633 }
634
635 void ChromeRenderMessageFilter::OnIsWebGLDebugRendererInfoAllowed(
636     const GURL& origin, bool* allowed) {
637   *allowed = false;
638   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
639   if (command_line.HasSwitch(switches::kDisableWebGLDebugRendererInfo))
640     return;
641
642   // TODO(zmo): in this experimental stage, we only expose WebGL extension
643   // WEBGL_debug_renderer_info for Google domains. Once we finish the experiment
644   // and make a decision, this extension should be avaiable to all or none.
645   if (!google_util::IsGoogleDomainUrl(origin, google_util::ALLOW_SUBDOMAIN,
646                                       google_util::ALLOW_NON_STANDARD_PORTS)) {
647     return;
648   }
649
650   const char kWebGLDebugRendererInfoFieldTrialName[] = "WebGLDebugRendererInfo";
651   const char kWebGLDebugRendererInfoFieldTrialEnabledName[] = "enabled";
652   *allowed = (base::FieldTrialList::FindFullName(
653       kWebGLDebugRendererInfoFieldTrialName) ==
654       kWebGLDebugRendererInfoFieldTrialEnabledName);
655 }
656
657 void ChromeRenderMessageFilter::OnGetCookies(
658     const GURL& url,
659     const GURL& first_party_for_cookies,
660     IPC::Message* reply_msg) {
661 #if defined(ENABLE_AUTOMATION)
662   AutomationResourceMessageFilter::GetCookiesForUrl(
663       this, request_context_->GetURLRequestContext(), render_process_id_,
664       reply_msg, url);
665 #endif
666 }
667
668 void ChromeRenderMessageFilter::OnSetCookie(const IPC::Message& message,
669                                             const GURL& url,
670                                             const GURL& first_party_for_cookies,
671                                             const std::string& cookie) {
672 #if defined(ENABLE_AUTOMATION)
673   AutomationResourceMessageFilter::SetCookiesForUrl(
674       render_process_id_, message.routing_id(), url, cookie);
675 #endif
676 }