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