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