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