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