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