chrome_render_message_filter.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
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 "base/bind.h" 8#include "base/command_line.h" 9#include "base/file_util.h" 10#include "base/metrics/histogram.h" 11#include "chrome/browser/automation/automation_resource_message_filter.h" 12#include "chrome/browser/browser_process.h" 13#include "chrome/browser/content_settings/cookie_settings.h" 14#include "chrome/browser/content_settings/tab_specific_content_settings.h" 15#include "chrome/browser/extensions/activity_log.h" 16#include "chrome/browser/extensions/api/messaging/message_service.h" 17#include "chrome/browser/extensions/event_router.h" 18#include "chrome/browser/extensions/extension_function_dispatcher.h" 19#include "chrome/browser/extensions/extension_info_map.h" 20#include "chrome/browser/extensions/extension_process_manager.h" 21#include "chrome/browser/extensions/extension_service.h" 22#include "chrome/browser/extensions/extension_system.h" 23#include "chrome/browser/nacl_host/nacl_file_host.h" 24#include "chrome/browser/nacl_host/nacl_infobar.h" 25#include "chrome/browser/nacl_host/nacl_process_host.h" 26#include "chrome/browser/net/chrome_url_request_context.h" 27#include "chrome/browser/net/predictor.h" 28#include "chrome/browser/profiles/profile.h" 29#include "chrome/browser/task_manager/task_manager.h" 30#include "chrome/common/chrome_notification_types.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.h" 34#include "chrome/common/extensions/extension_file_util.h" 35#include "chrome/common/extensions/extension_messages.h" 36#include "chrome/common/extensions/message_bundle.h" 37#include "chrome/common/render_messages.h" 38#include "chrome/common/url_constants.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 "content/public/common/process_type.h" 43#include "extensions/common/constants.h" 44#include "googleurl/src/gurl.h" 45 46#if defined(USE_TCMALLOC) 47#include "chrome/browser/browser_about_handler.h" 48#endif 49 50using content::BrowserThread; 51using extensions::APIPermission; 52using WebKit::WebCache; 53 54namespace { 55 56enum ActivityLogCallType { 57 ACTIVITYAPI, 58 ACTIVITYEVENT 59}; 60 61void AddAPIActionToExtensionActivityLog( 62 Profile* profile, 63 const ActivityLogCallType call_type, 64 const extensions::Extension* extension, 65 const std::string& api_call, 66 scoped_ptr<ListValue> args, 67 const std::string& extra) { 68 // The ActivityLog can only be accessed from the main (UI) thread. If we're 69 // running on the wrong thread, re-dispatch from the main thread. 70 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 71 BrowserThread::PostTask(BrowserThread::UI, 72 FROM_HERE, 73 base::Bind(&AddAPIActionToExtensionActivityLog, 74 profile, 75 call_type, 76 extension, 77 api_call, 78 base::Passed(&args), 79 extra)); 80 } else { 81 extensions::ActivityLog* activity_log = 82 extensions::ActivityLog::GetInstance(profile); 83 if (activity_log && activity_log->IsLogEnabled()) { 84 if (call_type == ACTIVITYAPI) 85 activity_log->LogAPIAction(extension, api_call, args.get(), extra); 86 else if (call_type == ACTIVITYEVENT) 87 activity_log->LogEventAction(extension, api_call, args.get(), extra); 88 } 89 } 90} 91 92void AddDOMActionToExtensionActivityLog( 93 Profile* profile, 94 const extensions::Extension* extension, 95 const GURL& url, 96 const string16& url_title, 97 const std::string& api_call, 98 scoped_ptr<ListValue> args, 99 const std::string& extra) { 100 // The ActivityLog can only be accessed from the main (UI) thread. If we're 101 // running on the wrong thread, re-dispatch from the main thread. 102 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 103 BrowserThread::PostTask(BrowserThread::UI, 104 FROM_HERE, 105 base::Bind(&AddDOMActionToExtensionActivityLog, 106 profile, 107 extension, 108 url, 109 url_title, 110 api_call, 111 base::Passed(&args), 112 extra)); 113 } else { 114 extensions::ActivityLog* activity_log = 115 extensions::ActivityLog::GetInstance(profile); 116 if (activity_log && activity_log->IsLogEnabled()) 117 activity_log->LogDOMAction(extension, url, url_title, 118 api_call, args.get(), extra); 119 } 120} 121 122} // namespace 123 124ChromeRenderMessageFilter::ChromeRenderMessageFilter( 125 int render_process_id, 126 Profile* profile, 127 net::URLRequestContextGetter* request_context) 128 : render_process_id_(render_process_id), 129 profile_(profile), 130 off_the_record_(profile_->IsOffTheRecord()), 131 request_context_(request_context), 132 extension_info_map_( 133 extensions::ExtensionSystem::Get(profile)->info_map()), 134 cookie_settings_(CookieSettings::Factory::GetForProfile(profile)), 135 weak_ptr_factory_(this) { 136} 137 138ChromeRenderMessageFilter::~ChromeRenderMessageFilter() { 139} 140 141bool ChromeRenderMessageFilter::OnMessageReceived(const IPC::Message& message, 142 bool* message_was_ok) { 143 bool handled = true; 144 IPC_BEGIN_MESSAGE_MAP_EX(ChromeRenderMessageFilter, message, *message_was_ok) 145#if !defined(DISABLE_NACL) 146 IPC_MESSAGE_HANDLER_DELAY_REPLY(ChromeViewHostMsg_LaunchNaCl, OnLaunchNaCl) 147 IPC_MESSAGE_HANDLER_DELAY_REPLY(ChromeViewHostMsg_GetReadonlyPnaclFD, 148 OnGetReadonlyPnaclFd) 149 IPC_MESSAGE_HANDLER_DELAY_REPLY(ChromeViewHostMsg_NaClCreateTemporaryFile, 150 OnNaClCreateTemporaryFile) 151 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_NaClErrorStatus, OnNaClErrorStatus) 152 IPC_MESSAGE_HANDLER_DELAY_REPLY(ChromeViewHostMsg_OpenNaClExecutable, 153 OnOpenNaClExecutable) 154#endif 155 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DnsPrefetch, OnDnsPrefetch) 156 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ResourceTypeStats, 157 OnResourceTypeStats) 158 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_UpdatedCacheStats, 159 OnUpdatedCacheStats) 160 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FPS, OnFPS) 161 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_V8HeapStats, OnV8HeapStats) 162 IPC_MESSAGE_HANDLER(ExtensionHostMsg_OpenChannelToExtension, 163 OnOpenChannelToExtension) 164 IPC_MESSAGE_HANDLER(ExtensionHostMsg_OpenChannelToTab, OnOpenChannelToTab) 165 IPC_MESSAGE_HANDLER(ExtensionHostMsg_OpenChannelToNativeApp, 166 OnOpenChannelToNativeApp) 167 IPC_MESSAGE_HANDLER_DELAY_REPLY(ExtensionHostMsg_GetMessageBundle, 168 OnGetExtensionMessageBundle) 169 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddListener, OnExtensionAddListener) 170 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveListener, 171 OnExtensionRemoveListener) 172 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddLazyListener, 173 OnExtensionAddLazyListener) 174 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveLazyListener, 175 OnExtensionRemoveLazyListener) 176 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddFilteredListener, 177 OnExtensionAddFilteredListener) 178 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RemoveFilteredListener, 179 OnExtensionRemoveFilteredListener) 180 IPC_MESSAGE_HANDLER(ExtensionHostMsg_CloseChannel, OnExtensionCloseChannel) 181 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RequestForIOThread, 182 OnExtensionRequestForIOThread) 183 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ShouldSuspendAck, 184 OnExtensionShouldSuspendAck) 185 IPC_MESSAGE_HANDLER(ExtensionHostMsg_GenerateUniqueID, 186 OnExtensionGenerateUniqueID) 187 IPC_MESSAGE_HANDLER(ExtensionHostMsg_SuspendAck, OnExtensionSuspendAck) 188 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ResumeRequests, 189 OnExtensionResumeRequests); 190 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddAPIActionToActivityLog, 191 OnAddAPIActionToExtensionActivityLog); 192 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddDOMActionToActivityLog, 193 OnAddDOMActionToExtensionActivityLog); 194 IPC_MESSAGE_HANDLER(ExtensionHostMsg_AddEventToActivityLog, 195 OnAddEventToExtensionActivityLog); 196 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDatabase, OnAllowDatabase) 197 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDOMStorage, OnAllowDOMStorage) 198 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowFileSystem, OnAllowFileSystem) 199 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowIndexedDB, OnAllowIndexedDB) 200 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_CanTriggerClipboardRead, 201 OnCanTriggerClipboardRead) 202 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_CanTriggerClipboardWrite, 203 OnCanTriggerClipboardWrite) 204 IPC_MESSAGE_UNHANDLED(handled = false) 205 IPC_END_MESSAGE_MAP() 206 207#if defined(ENABLE_AUTOMATION) 208 if ((message.type() == ChromeViewHostMsg_GetCookies::ID || 209 message.type() == ChromeViewHostMsg_SetCookie::ID) && 210 AutomationResourceMessageFilter::ShouldFilterCookieMessages( 211 render_process_id_, message.routing_id())) { 212 // ChromeFrame then we need to get/set cookies from the external host. 213 IPC_BEGIN_MESSAGE_MAP_EX(ChromeRenderMessageFilter, message, 214 *message_was_ok) 215 IPC_MESSAGE_HANDLER_DELAY_REPLY(ChromeViewHostMsg_GetCookies, 216 OnGetCookies) 217 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SetCookie, OnSetCookie) 218 IPC_END_MESSAGE_MAP() 219 handled = true; 220 } 221#endif 222 223 return handled; 224} 225 226void ChromeRenderMessageFilter::OverrideThreadForMessage( 227 const IPC::Message& message, BrowserThread::ID* thread) { 228 switch (message.type()) { 229 case ChromeViewHostMsg_ResourceTypeStats::ID: 230 case ExtensionHostMsg_AddListener::ID: 231 case ExtensionHostMsg_RemoveListener::ID: 232 case ExtensionHostMsg_AddLazyListener::ID: 233 case ExtensionHostMsg_RemoveLazyListener::ID: 234 case ExtensionHostMsg_AddFilteredListener::ID: 235 case ExtensionHostMsg_RemoveFilteredListener::ID: 236 case ExtensionHostMsg_CloseChannel::ID: 237 case ExtensionHostMsg_ShouldSuspendAck::ID: 238 case ExtensionHostMsg_SuspendAck::ID: 239 case ChromeViewHostMsg_UpdatedCacheStats::ID: 240 *thread = BrowserThread::UI; 241 break; 242 default: 243 break; 244 } 245} 246 247net::HostResolver* ChromeRenderMessageFilter::GetHostResolver() { 248 return request_context_->GetURLRequestContext()->host_resolver(); 249} 250 251#if !defined(DISABLE_NACL) 252void ChromeRenderMessageFilter::OnLaunchNaCl( 253 const nacl::NaClLaunchParams& launch_params, 254 IPC::Message* reply_msg) { 255 NaClProcessHost* host = new NaClProcessHost( 256 GURL(launch_params.manifest_url), 257 launch_params.render_view_id, 258 launch_params.permission_bits, 259 launch_params.uses_irt, 260 launch_params.enable_dyncode_syscalls, 261 off_the_record_, 262 profile_->GetPath()); 263 host->Launch(this, reply_msg, extension_info_map_); 264} 265 266void ChromeRenderMessageFilter::OnGetReadonlyPnaclFd( 267 const std::string& filename, IPC::Message* reply_msg) { 268 // This posts a task to another thread, but the renderer will 269 // block until the reply is sent. 270 nacl_file_host::GetReadonlyPnaclFd(this, filename, reply_msg); 271} 272 273void ChromeRenderMessageFilter::OnNaClCreateTemporaryFile( 274 IPC::Message* reply_msg) { 275 nacl_file_host::CreateTemporaryFile(this, reply_msg); 276} 277 278void ChromeRenderMessageFilter::OnNaClErrorStatus(int render_view_id, 279 int error_id) { 280 // Currently there is only one kind of error status, for which 281 // we want to show the user an infobar. 282 ShowNaClInfobar(render_process_id_, render_view_id, error_id); 283} 284 285void ChromeRenderMessageFilter::OnOpenNaClExecutable(int render_view_id, 286 const GURL& file_url, 287 IPC::Message* reply_msg) { 288 nacl_file_host::OpenNaClExecutable(this, extension_info_map_, 289 render_view_id, file_url, reply_msg); 290} 291#endif 292 293void ChromeRenderMessageFilter::OnDnsPrefetch( 294 const std::vector<std::string>& hostnames) { 295 if (profile_->GetNetworkPredictor()) 296 profile_->GetNetworkPredictor()->DnsPrefetchList(hostnames); 297} 298 299void ChromeRenderMessageFilter::OnResourceTypeStats( 300 const WebCache::ResourceTypeStats& stats) { 301 HISTOGRAM_COUNTS("WebCoreCache.ImagesSizeKB", 302 static_cast<int>(stats.images.size / 1024)); 303 HISTOGRAM_COUNTS("WebCoreCache.CSSStylesheetsSizeKB", 304 static_cast<int>(stats.cssStyleSheets.size / 1024)); 305 HISTOGRAM_COUNTS("WebCoreCache.ScriptsSizeKB", 306 static_cast<int>(stats.scripts.size / 1024)); 307 HISTOGRAM_COUNTS("WebCoreCache.XSLStylesheetsSizeKB", 308 static_cast<int>(stats.xslStyleSheets.size / 1024)); 309 HISTOGRAM_COUNTS("WebCoreCache.FontsSizeKB", 310 static_cast<int>(stats.fonts.size / 1024)); 311 312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 313#if defined(ENABLE_TASK_MANAGER) 314 TaskManager::GetInstance()->model()->NotifyResourceTypeStats( 315 base::GetProcId(peer_handle()), stats); 316#endif // defined(ENABLE_TASK_MANAGER) 317} 318 319void ChromeRenderMessageFilter::OnUpdatedCacheStats( 320 const WebCache::UsageStats& stats) { 321 WebCacheManager::GetInstance()->ObserveStats(render_process_id_, stats); 322} 323 324void ChromeRenderMessageFilter::OnFPS(int routing_id, float fps) { 325 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 326 BrowserThread::PostTask( 327 BrowserThread::UI, FROM_HERE, 328 base::Bind( 329 &ChromeRenderMessageFilter::OnFPS, this, 330 routing_id, fps)); 331 return; 332 } 333 334 base::ProcessId renderer_id = base::GetProcId(peer_handle()); 335 336#if defined(ENABLE_TASK_MANAGER) 337 TaskManager::GetInstance()->model()->NotifyFPS( 338 renderer_id, routing_id, fps); 339#endif // defined(ENABLE_TASK_MANAGER) 340 341 FPSDetails details(routing_id, fps); 342 content::NotificationService::current()->Notify( 343 chrome::NOTIFICATION_RENDERER_FPS_COMPUTED, 344 content::Source<const base::ProcessId>(&renderer_id), 345 content::Details<const FPSDetails>(&details)); 346} 347 348void ChromeRenderMessageFilter::OnV8HeapStats(int v8_memory_allocated, 349 int v8_memory_used) { 350 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 351 BrowserThread::PostTask( 352 BrowserThread::UI, FROM_HERE, 353 base::Bind( 354 &ChromeRenderMessageFilter::OnV8HeapStats, this, 355 v8_memory_allocated, v8_memory_used)); 356 return; 357 } 358 359 base::ProcessId renderer_id = base::GetProcId(peer_handle()); 360 361#if defined(ENABLE_TASK_MANAGER) 362 TaskManager::GetInstance()->model()->NotifyV8HeapStats( 363 renderer_id, 364 static_cast<size_t>(v8_memory_allocated), 365 static_cast<size_t>(v8_memory_used)); 366#endif // defined(ENABLE_TASK_MANAGER) 367 368 V8HeapStatsDetails details(v8_memory_allocated, v8_memory_used); 369 content::NotificationService::current()->Notify( 370 chrome::NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED, 371 content::Source<const base::ProcessId>(&renderer_id), 372 content::Details<const V8HeapStatsDetails>(&details)); 373} 374 375void ChromeRenderMessageFilter::OnOpenChannelToExtension( 376 int routing_id, 377 const ExtensionMsg_ExternalConnectionInfo& info, 378 const std::string& channel_name, int* port_id) { 379 int port2_id; 380 extensions::MessageService::AllocatePortIdPair(port_id, &port2_id); 381 382 BrowserThread::PostTask( 383 BrowserThread::UI, FROM_HERE, 384 base::Bind( 385 &ChromeRenderMessageFilter::OpenChannelToExtensionOnUIThread, this, 386 render_process_id_, routing_id, port2_id, info, channel_name)); 387} 388 389void ChromeRenderMessageFilter::OpenChannelToExtensionOnUIThread( 390 int source_process_id, int source_routing_id, 391 int receiver_port_id, 392 const ExtensionMsg_ExternalConnectionInfo& info, 393 const std::string& channel_name) { 394 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 395 extensions::MessageService::Get(profile_)->OpenChannelToExtension( 396 source_process_id, source_routing_id, receiver_port_id, 397 info.source_id, info.target_id, info.source_url, channel_name); 398} 399 400void ChromeRenderMessageFilter::OnOpenChannelToNativeApp( 401 int routing_id, 402 const std::string& source_extension_id, 403 const std::string& native_app_name, 404 int* port_id) { 405 int port2_id; 406 extensions::MessageService::AllocatePortIdPair(port_id, &port2_id); 407 408 BrowserThread::PostTask( 409 BrowserThread::UI, FROM_HERE, 410 base::Bind(&ChromeRenderMessageFilter::OpenChannelToNativeAppOnUIThread, 411 this, routing_id, port2_id, source_extension_id, 412 native_app_name)); 413} 414 415void ChromeRenderMessageFilter::OpenChannelToNativeAppOnUIThread( 416 int source_routing_id, 417 int receiver_port_id, 418 const std::string& source_extension_id, 419 const std::string& native_app_name) { 420 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 421 extensions::MessageService::Get(profile_)->OpenChannelToNativeApp( 422 render_process_id_, source_routing_id, receiver_port_id, 423 source_extension_id, native_app_name); 424} 425 426void ChromeRenderMessageFilter::OnOpenChannelToTab( 427 int routing_id, int tab_id, const std::string& extension_id, 428 const std::string& channel_name, int* port_id) { 429 int port2_id; 430 extensions::MessageService::AllocatePortIdPair(port_id, &port2_id); 431 432 BrowserThread::PostTask( 433 BrowserThread::UI, FROM_HERE, 434 base::Bind(&ChromeRenderMessageFilter::OpenChannelToTabOnUIThread, this, 435 render_process_id_, routing_id, port2_id, tab_id, extension_id, 436 channel_name)); 437} 438 439void ChromeRenderMessageFilter::OpenChannelToTabOnUIThread( 440 int source_process_id, int source_routing_id, 441 int receiver_port_id, 442 int tab_id, 443 const std::string& extension_id, 444 const std::string& channel_name) { 445 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 446 extensions::MessageService::Get(profile_)->OpenChannelToTab( 447 source_process_id, source_routing_id, receiver_port_id, 448 tab_id, extension_id, channel_name); 449} 450 451void ChromeRenderMessageFilter::OnGetExtensionMessageBundle( 452 const std::string& extension_id, IPC::Message* reply_msg) { 453 const extensions::Extension* extension = 454 extension_info_map_->extensions().GetByID(extension_id); 455 base::FilePath extension_path; 456 std::string default_locale; 457 if (extension) { 458 extension_path = extension->path(); 459 default_locale = extensions::LocaleInfo::GetDefaultLocale(extension); 460 } 461 462 BrowserThread::PostTask( 463 BrowserThread::FILE, FROM_HERE, 464 base::Bind( 465 &ChromeRenderMessageFilter::OnGetExtensionMessageBundleOnFileThread, 466 this, extension_path, extension_id, default_locale, reply_msg)); 467} 468 469void ChromeRenderMessageFilter::OnGetExtensionMessageBundleOnFileThread( 470 const base::FilePath& extension_path, 471 const std::string& extension_id, 472 const std::string& default_locale, 473 IPC::Message* reply_msg) { 474 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 475 476 scoped_ptr<extensions::MessageBundle::SubstitutionMap> dictionary_map( 477 extension_file_util::LoadMessageBundleSubstitutionMap( 478 extension_path, 479 extension_id, 480 default_locale)); 481 482 ExtensionHostMsg_GetMessageBundle::WriteReplyParams( 483 reply_msg, *dictionary_map); 484 Send(reply_msg); 485} 486 487void ChromeRenderMessageFilter::OnExtensionAddListener( 488 const std::string& extension_id, 489 const std::string& event_name) { 490 content::RenderProcessHost* process = 491 content::RenderProcessHost::FromID(render_process_id_); 492 if (!process || 493 !extensions::ExtensionSystem::Get(profile_)->event_router()) 494 return; 495 496 extensions::ExtensionSystem::Get(profile_)->event_router()-> 497 AddEventListener(event_name, process, extension_id); 498} 499 500void ChromeRenderMessageFilter::OnExtensionRemoveListener( 501 const std::string& extension_id, 502 const std::string& event_name) { 503 content::RenderProcessHost* process = 504 content::RenderProcessHost::FromID(render_process_id_); 505 if (!process || 506 !extensions::ExtensionSystem::Get(profile_)->event_router()) 507 return; 508 509 extensions::ExtensionSystem::Get(profile_)->event_router()-> 510 RemoveEventListener(event_name, process, extension_id); 511} 512 513void ChromeRenderMessageFilter::OnExtensionAddLazyListener( 514 const std::string& extension_id, const std::string& event_name) { 515 if (extensions::ExtensionSystem::Get(profile_)->event_router()) { 516 extensions::ExtensionSystem::Get(profile_)->event_router()-> 517 AddLazyEventListener(event_name, extension_id); 518 } 519} 520 521void ChromeRenderMessageFilter::OnExtensionRemoveLazyListener( 522 const std::string& extension_id, const std::string& event_name) { 523 if (extensions::ExtensionSystem::Get(profile_)->event_router()) { 524 extensions::ExtensionSystem::Get(profile_)->event_router()-> 525 RemoveLazyEventListener(event_name, extension_id); 526 } 527} 528 529void ChromeRenderMessageFilter::OnExtensionAddFilteredListener( 530 const std::string& extension_id, 531 const std::string& event_name, 532 const base::DictionaryValue& filter, 533 bool lazy) { 534 content::RenderProcessHost* process = 535 content::RenderProcessHost::FromID(render_process_id_); 536 if (!process || 537 !extensions::ExtensionSystem::Get(profile_)->event_router()) 538 return; 539 540 extensions::ExtensionSystem::Get(profile_)->event_router()-> 541 AddFilteredEventListener(event_name, process, extension_id, filter, lazy); 542} 543 544void ChromeRenderMessageFilter::OnExtensionRemoveFilteredListener( 545 const std::string& extension_id, 546 const std::string& event_name, 547 const base::DictionaryValue& filter, 548 bool lazy) { 549 content::RenderProcessHost* process = 550 content::RenderProcessHost::FromID(render_process_id_); 551 if (!process || 552 !extensions::ExtensionSystem::Get(profile_)->event_router()) 553 return; 554 555 extensions::ExtensionSystem::Get(profile_)->event_router()-> 556 RemoveFilteredEventListener(event_name, process, extension_id, filter, 557 lazy); 558} 559 560void ChromeRenderMessageFilter::OnExtensionCloseChannel( 561 int port_id, 562 const std::string& error_message) { 563 if (!content::RenderProcessHost::FromID(render_process_id_)) 564 return; // To guard against crash in browser_tests shutdown. 565 566 extensions::MessageService* message_service = 567 extensions::MessageService::Get(profile_); 568 if (message_service) 569 message_service->CloseChannel(port_id, error_message); 570} 571 572void ChromeRenderMessageFilter::OnExtensionRequestForIOThread( 573 int routing_id, 574 const ExtensionHostMsg_Request_Params& params) { 575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 576 577 ExtensionFunctionDispatcher::DispatchOnIOThread( 578 extension_info_map_, profile_, render_process_id_, 579 weak_ptr_factory_.GetWeakPtr(), routing_id, params); 580} 581 582void ChromeRenderMessageFilter::OnExtensionShouldSuspendAck( 583 const std::string& extension_id, int sequence_id) { 584 if (extensions::ExtensionSystem::Get(profile_)->process_manager()) { 585 extensions::ExtensionSystem::Get(profile_)->process_manager()-> 586 OnShouldSuspendAck(extension_id, sequence_id); 587 } 588} 589 590void ChromeRenderMessageFilter::OnExtensionSuspendAck( 591 const std::string& extension_id) { 592 if (extensions::ExtensionSystem::Get(profile_)->process_manager()) { 593 extensions::ExtensionSystem::Get(profile_)->process_manager()-> 594 OnSuspendAck(extension_id); 595 } 596} 597 598void ChromeRenderMessageFilter::OnExtensionGenerateUniqueID(int* unique_id) { 599 static int next_unique_id = 1; 600 *unique_id = next_unique_id++; 601} 602 603void ChromeRenderMessageFilter::OnExtensionResumeRequests(int route_id) { 604 content::ResourceDispatcherHost::Get()->ResumeBlockedRequestsForRoute( 605 render_process_id_, route_id); 606} 607 608void ChromeRenderMessageFilter::OnAddAPIActionToExtensionActivityLog( 609 const std::string& extension_id, 610 const ExtensionHostMsg_APIActionOrEvent_Params& params) { 611 const extensions::Extension* extension = 612 extension_info_map_->extensions().GetByID(extension_id); 613 scoped_ptr<ListValue> args(params.arguments.DeepCopy()); 614 // The activity is recorded as an API action in the extension 615 // activity log. 616 AddAPIActionToExtensionActivityLog(profile_, ACTIVITYAPI, extension, 617 params.api_call, args.Pass(), 618 params.extra); 619} 620 621void ChromeRenderMessageFilter::OnAddDOMActionToExtensionActivityLog( 622 const std::string& extension_id, 623 const ExtensionHostMsg_DOMAction_Params& params) { 624 const extensions::Extension* extension = 625 extension_info_map_->extensions().GetByID(extension_id); 626 scoped_ptr<ListValue> args(params.arguments.DeepCopy()); 627 // The activity is recorded as a DOM action on the extension 628 // activity log. 629 AddDOMActionToExtensionActivityLog(profile_, extension, 630 params.url, params.url_title, 631 params.api_call, args.Pass(), 632 params.extra); 633} 634 635void ChromeRenderMessageFilter::OnAddEventToExtensionActivityLog( 636 const std::string& extension_id, 637 const ExtensionHostMsg_APIActionOrEvent_Params& params) { 638 const extensions::Extension* extension = 639 extension_info_map_->extensions().GetByID(extension_id); 640 scoped_ptr<ListValue> args(params.arguments.DeepCopy()); 641 // The activity is recorded as an event in the extension 642 // activity log. 643 AddAPIActionToExtensionActivityLog(profile_, ACTIVITYEVENT, extension, 644 params.api_call, args.Pass(), 645 params.extra); 646} 647 648void ChromeRenderMessageFilter::OnAllowDatabase(int render_view_id, 649 const GURL& origin_url, 650 const GURL& top_origin_url, 651 const string16& name, 652 const string16& display_name, 653 bool* allowed) { 654 *allowed = cookie_settings_->IsSettingCookieAllowed(origin_url, 655 top_origin_url); 656 BrowserThread::PostTask( 657 BrowserThread::UI, FROM_HERE, 658 base::Bind( 659 &TabSpecificContentSettings::WebDatabaseAccessed, 660 render_process_id_, render_view_id, origin_url, name, display_name, 661 !*allowed)); 662} 663 664void ChromeRenderMessageFilter::OnAllowDOMStorage(int render_view_id, 665 const GURL& origin_url, 666 const GURL& top_origin_url, 667 bool local, 668 bool* allowed) { 669 *allowed = cookie_settings_->IsSettingCookieAllowed(origin_url, 670 top_origin_url); 671 // Record access to DOM storage for potential display in UI. 672 BrowserThread::PostTask( 673 BrowserThread::UI, FROM_HERE, 674 base::Bind( 675 &TabSpecificContentSettings::DOMStorageAccessed, 676 render_process_id_, render_view_id, origin_url, local, !*allowed)); 677} 678 679void ChromeRenderMessageFilter::OnAllowFileSystem(int render_view_id, 680 const GURL& origin_url, 681 const GURL& top_origin_url, 682 bool* allowed) { 683 *allowed = cookie_settings_->IsSettingCookieAllowed(origin_url, 684 top_origin_url); 685 // Record access to file system for potential display in UI. 686 BrowserThread::PostTask( 687 BrowserThread::UI, FROM_HERE, 688 base::Bind( 689 &TabSpecificContentSettings::FileSystemAccessed, 690 render_process_id_, render_view_id, origin_url, !*allowed)); 691} 692 693void ChromeRenderMessageFilter::OnAllowIndexedDB(int render_view_id, 694 const GURL& origin_url, 695 const GURL& top_origin_url, 696 const string16& name, 697 bool* allowed) { 698 *allowed = cookie_settings_->IsSettingCookieAllowed(origin_url, 699 top_origin_url); 700 BrowserThread::PostTask( 701 BrowserThread::UI, FROM_HERE, 702 base::Bind( 703 &TabSpecificContentSettings::IndexedDBAccessed, 704 render_process_id_, render_view_id, origin_url, name, !*allowed)); 705} 706 707void ChromeRenderMessageFilter::OnCanTriggerClipboardRead( 708 const GURL& origin, bool* allowed) { 709 *allowed = extension_info_map_->SecurityOriginHasAPIPermission( 710 origin, render_process_id_, APIPermission::kClipboardRead); 711} 712 713void ChromeRenderMessageFilter::OnCanTriggerClipboardWrite( 714 const GURL& origin, bool* allowed) { 715 // Since all extensions could historically write to the clipboard, preserve it 716 // for compatibility. 717 *allowed = (origin.SchemeIs(extensions::kExtensionScheme) || 718 extension_info_map_->SecurityOriginHasAPIPermission( 719 origin, render_process_id_, APIPermission::kClipboardWrite)); 720} 721 722void ChromeRenderMessageFilter::OnGetCookies( 723 const GURL& url, 724 const GURL& first_party_for_cookies, 725 IPC::Message* reply_msg) { 726#if defined(ENABLE_AUTOMATION) 727 AutomationResourceMessageFilter::GetCookiesForUrl( 728 this, request_context_->GetURLRequestContext(), render_process_id_, 729 reply_msg, url); 730#endif 731} 732 733void ChromeRenderMessageFilter::OnSetCookie(const IPC::Message& message, 734 const GURL& url, 735 const GURL& first_party_for_cookies, 736 const std::string& cookie) { 737#if defined(ENABLE_AUTOMATION) 738 AutomationResourceMessageFilter::SetCookiesForUrl( 739 render_process_id_, message.routing_id(), url, cookie); 740#endif 741} 742