1 // Copyright (c) 2011 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/extensions/extension_function_dispatcher.h" 6 7 #include <map> 8 9 #include "base/memory/ref_counted.h" 10 #include "base/memory/singleton.h" 11 #include "base/process_util.h" 12 #include "base/values.h" 13 #include "build/build_config.h" 14 #include "chrome/browser/extensions/execute_code_in_tab_function.h" 15 #include "chrome/browser/extensions/extension_accessibility_api.h" 16 #include "chrome/browser/extensions/extension_bookmark_manager_api.h" 17 #include "chrome/browser/extensions/extension_bookmarks_module.h" 18 #include "chrome/browser/extensions/extension_browser_actions_api.h" 19 #include "chrome/browser/extensions/extension_clipboard_api.h" 20 #include "chrome/browser/extensions/extension_context_menu_api.h" 21 #include "chrome/browser/extensions/extension_cookies_api.h" 22 #include "chrome/browser/extensions/extension_debugger_api.h" 23 #include "chrome/browser/extensions/extension_function.h" 24 #include "chrome/browser/extensions/extension_history_api.h" 25 #include "chrome/browser/extensions/extension_i18n_api.h" 26 #include "chrome/browser/extensions/extension_idle_api.h" 27 #include "chrome/browser/extensions/extension_infobar_module.h" 28 #include "chrome/browser/extensions/extension_management_api.h" 29 #include "chrome/browser/extensions/extension_message_service.h" 30 #include "chrome/browser/extensions/extension_metrics_module.h" 31 #include "chrome/browser/extensions/extension_module.h" 32 #include "chrome/browser/extensions/extension_omnibox_api.h" 33 #include "chrome/browser/extensions/extension_page_actions_module.h" 34 #include "chrome/browser/extensions/extension_preference_api.h" 35 #include "chrome/browser/extensions/extension_process_manager.h" 36 #include "chrome/browser/extensions/extension_processes_api.h" 37 #include "chrome/browser/extensions/extension_proxy_api.h" 38 #include "chrome/browser/extensions/extension_rlz_module.h" 39 #include "chrome/browser/extensions/extension_service.h" 40 #include "chrome/browser/extensions/extension_sidebar_api.h" 41 #include "chrome/browser/extensions/extension_tabs_module.h" 42 #include "chrome/browser/extensions/extension_test_api.h" 43 #include "chrome/browser/extensions/extension_tts_api.h" 44 #include "chrome/browser/extensions/extension_web_ui.h" 45 #include "chrome/browser/extensions/extension_webrequest_api.h" 46 #include "chrome/browser/extensions/extension_webstore_private_api.h" 47 #include "chrome/browser/extensions/extensions_quota_service.h" 48 #include "chrome/browser/external_protocol_handler.h" 49 #include "chrome/browser/metrics/user_metrics.h" 50 #include "chrome/browser/profiles/profile.h" 51 #include "chrome/browser/ui/browser_list.h" 52 #include "chrome/browser/ui/browser_window.h" 53 #include "chrome/browser/ui/webui/chrome_url_data_manager.h" 54 #include "chrome/browser/ui/webui/favicon_source.h" 55 #include "chrome/common/extensions/extension_messages.h" 56 #include "chrome/common/url_constants.h" 57 #include "content/browser/renderer_host/render_process_host.h" 58 #include "content/browser/renderer_host/render_view_host.h" 59 #include "content/common/notification_service.h" 60 #include "content/common/result_codes.h" 61 #include "third_party/skia/include/core/SkBitmap.h" 62 63 #if defined(TOOLKIT_VIEWS) 64 #include "chrome/browser/extensions/extension_input_api.h" 65 #endif 66 67 #if defined(OS_CHROMEOS) 68 #include "chrome/browser/extensions/extension_file_browser_private_api.h" 69 #include "chrome/browser/extensions/extension_info_private_api_chromeos.h" 70 #endif 71 72 // FactoryRegistry ------------------------------------------------------------- 73 74 namespace { 75 76 // Template for defining ExtensionFunctionFactory. 77 template<class T> 78 ExtensionFunction* NewExtensionFunction() { 79 return new T(); 80 } 81 82 // Contains a list of all known extension functions and allows clients to 83 // create instances of them. 84 class FactoryRegistry { 85 public: 86 static FactoryRegistry* GetInstance(); 87 FactoryRegistry() { ResetFunctions(); } 88 89 // Resets all functions to their default values. 90 void ResetFunctions(); 91 92 // Adds all function names to 'names'. 93 void GetAllNames(std::vector<std::string>* names); 94 95 // Allows overriding of specific functions (e.g. for testing). Functions 96 // must be previously registered. Returns true if successful. 97 bool OverrideFunction(const std::string& name, 98 ExtensionFunctionFactory factory); 99 100 // Factory method for the ExtensionFunction registered as 'name'. 101 ExtensionFunction* NewFunction(const std::string& name); 102 103 private: 104 template<class T> 105 void RegisterFunction() { 106 factories_[T::function_name()] = &NewExtensionFunction<T>; 107 } 108 109 typedef std::map<std::string, ExtensionFunctionFactory> FactoryMap; 110 FactoryMap factories_; 111 }; 112 113 FactoryRegistry* FactoryRegistry::GetInstance() { 114 return Singleton<FactoryRegistry>::get(); 115 } 116 117 void FactoryRegistry::ResetFunctions() { 118 // Register all functions here. 119 120 // Windows 121 RegisterFunction<GetWindowFunction>(); 122 RegisterFunction<GetCurrentWindowFunction>(); 123 RegisterFunction<GetLastFocusedWindowFunction>(); 124 RegisterFunction<GetAllWindowsFunction>(); 125 RegisterFunction<CreateWindowFunction>(); 126 RegisterFunction<UpdateWindowFunction>(); 127 RegisterFunction<RemoveWindowFunction>(); 128 129 // Tabs 130 RegisterFunction<GetTabFunction>(); 131 RegisterFunction<GetCurrentTabFunction>(); 132 RegisterFunction<GetSelectedTabFunction>(); 133 RegisterFunction<GetAllTabsInWindowFunction>(); 134 RegisterFunction<CreateTabFunction>(); 135 RegisterFunction<UpdateTabFunction>(); 136 RegisterFunction<MoveTabFunction>(); 137 RegisterFunction<RemoveTabFunction>(); 138 RegisterFunction<DetectTabLanguageFunction>(); 139 RegisterFunction<CaptureVisibleTabFunction>(); 140 RegisterFunction<TabsExecuteScriptFunction>(); 141 RegisterFunction<TabsInsertCSSFunction>(); 142 143 // Page Actions. 144 RegisterFunction<EnablePageActionFunction>(); 145 RegisterFunction<DisablePageActionFunction>(); 146 RegisterFunction<PageActionShowFunction>(); 147 RegisterFunction<PageActionHideFunction>(); 148 RegisterFunction<PageActionSetIconFunction>(); 149 RegisterFunction<PageActionSetTitleFunction>(); 150 RegisterFunction<PageActionSetPopupFunction>(); 151 152 // Browser Actions. 153 RegisterFunction<BrowserActionSetIconFunction>(); 154 RegisterFunction<BrowserActionSetTitleFunction>(); 155 RegisterFunction<BrowserActionSetBadgeTextFunction>(); 156 RegisterFunction<BrowserActionSetBadgeBackgroundColorFunction>(); 157 RegisterFunction<BrowserActionSetPopupFunction>(); 158 159 // Bookmarks. 160 RegisterFunction<GetBookmarksFunction>(); 161 RegisterFunction<GetBookmarkChildrenFunction>(); 162 RegisterFunction<GetBookmarkRecentFunction>(); 163 RegisterFunction<GetBookmarkTreeFunction>(); 164 RegisterFunction<SearchBookmarksFunction>(); 165 RegisterFunction<RemoveBookmarkFunction>(); 166 RegisterFunction<RemoveTreeBookmarkFunction>(); 167 RegisterFunction<CreateBookmarkFunction>(); 168 RegisterFunction<MoveBookmarkFunction>(); 169 RegisterFunction<UpdateBookmarkFunction>(); 170 171 // Infobars. 172 RegisterFunction<ShowInfoBarFunction>(); 173 174 // BookmarkManager 175 RegisterFunction<CopyBookmarkManagerFunction>(); 176 RegisterFunction<CutBookmarkManagerFunction>(); 177 RegisterFunction<PasteBookmarkManagerFunction>(); 178 RegisterFunction<CanPasteBookmarkManagerFunction>(); 179 RegisterFunction<ImportBookmarksFunction>(); 180 RegisterFunction<ExportBookmarksFunction>(); 181 RegisterFunction<SortChildrenBookmarkManagerFunction>(); 182 RegisterFunction<BookmarkManagerGetStringsFunction>(); 183 RegisterFunction<StartDragBookmarkManagerFunction>(); 184 RegisterFunction<DropBookmarkManagerFunction>(); 185 RegisterFunction<GetSubtreeBookmarkManagerFunction>(); 186 187 // History 188 RegisterFunction<AddUrlHistoryFunction>(); 189 RegisterFunction<DeleteAllHistoryFunction>(); 190 RegisterFunction<DeleteRangeHistoryFunction>(); 191 RegisterFunction<DeleteUrlHistoryFunction>(); 192 RegisterFunction<GetVisitsHistoryFunction>(); 193 RegisterFunction<SearchHistoryFunction>(); 194 195 // Idle 196 RegisterFunction<ExtensionIdleQueryStateFunction>(); 197 198 // I18N. 199 RegisterFunction<GetAcceptLanguagesFunction>(); 200 201 // Processes. 202 RegisterFunction<GetProcessIdForTabFunction>(); 203 204 // Metrics. 205 RegisterFunction<MetricsGetEnabledFunction>(); 206 RegisterFunction<MetricsSetEnabledFunction>(); 207 RegisterFunction<MetricsRecordUserActionFunction>(); 208 RegisterFunction<MetricsRecordValueFunction>(); 209 RegisterFunction<MetricsRecordPercentageFunction>(); 210 RegisterFunction<MetricsRecordCountFunction>(); 211 RegisterFunction<MetricsRecordSmallCountFunction>(); 212 RegisterFunction<MetricsRecordMediumCountFunction>(); 213 RegisterFunction<MetricsRecordTimeFunction>(); 214 RegisterFunction<MetricsRecordMediumTimeFunction>(); 215 RegisterFunction<MetricsRecordLongTimeFunction>(); 216 217 // RLZ. 218 #if defined(OS_WIN) 219 RegisterFunction<RlzRecordProductEventFunction>(); 220 RegisterFunction<RlzGetAccessPointRlzFunction>(); 221 RegisterFunction<RlzSendFinancialPingFunction>(); 222 RegisterFunction<RlzClearProductStateFunction>(); 223 #endif 224 225 // Cookies. 226 RegisterFunction<GetCookieFunction>(); 227 RegisterFunction<GetAllCookiesFunction>(); 228 RegisterFunction<SetCookieFunction>(); 229 RegisterFunction<RemoveCookieFunction>(); 230 RegisterFunction<GetAllCookieStoresFunction>(); 231 232 // Test. 233 RegisterFunction<ExtensionTestPassFunction>(); 234 RegisterFunction<ExtensionTestFailFunction>(); 235 RegisterFunction<ExtensionTestLogFunction>(); 236 RegisterFunction<ExtensionTestQuotaResetFunction>(); 237 RegisterFunction<ExtensionTestCreateIncognitoTabFunction>(); 238 RegisterFunction<ExtensionTestSendMessageFunction>(); 239 RegisterFunction<ExtensionTestGetConfigFunction>(); 240 241 // Accessibility. 242 RegisterFunction<GetFocusedControlFunction>(); 243 RegisterFunction<SetAccessibilityEnabledFunction>(); 244 245 // Text-to-speech. 246 RegisterFunction<ExtensionTtsSpeakFunction>(); 247 RegisterFunction<ExtensionTtsStopSpeakingFunction>(); 248 RegisterFunction<ExtensionTtsIsSpeakingFunction>(); 249 RegisterFunction<ExtensionTtsSpeakCompletedFunction>(); 250 251 // Clipboard. 252 RegisterFunction<ExecuteCopyClipboardFunction>(); 253 RegisterFunction<ExecuteCutClipboardFunction>(); 254 RegisterFunction<ExecutePasteClipboardFunction>(); 255 256 // Context Menus. 257 RegisterFunction<CreateContextMenuFunction>(); 258 RegisterFunction<UpdateContextMenuFunction>(); 259 RegisterFunction<RemoveContextMenuFunction>(); 260 RegisterFunction<RemoveAllContextMenusFunction>(); 261 262 // Omnibox. 263 RegisterFunction<OmniboxSendSuggestionsFunction>(); 264 RegisterFunction<OmniboxSetDefaultSuggestionFunction>(); 265 266 // Sidebar. 267 RegisterFunction<CollapseSidebarFunction>(); 268 RegisterFunction<ExpandSidebarFunction>(); 269 RegisterFunction<GetStateSidebarFunction>(); 270 RegisterFunction<HideSidebarFunction>(); 271 RegisterFunction<NavigateSidebarFunction>(); 272 RegisterFunction<SetBadgeTextSidebarFunction>(); 273 RegisterFunction<SetIconSidebarFunction>(); 274 RegisterFunction<SetTitleSidebarFunction>(); 275 RegisterFunction<ShowSidebarFunction>(); 276 277 #if defined(TOOLKIT_VIEWS) 278 // Input. 279 RegisterFunction<SendKeyboardEventInputFunction>(); 280 #endif 281 282 // Management. 283 RegisterFunction<GetAllExtensionsFunction>(); 284 RegisterFunction<GetExtensionByIdFunction>(); 285 RegisterFunction<LaunchAppFunction>(); 286 RegisterFunction<SetEnabledFunction>(); 287 RegisterFunction<UninstallFunction>(); 288 289 // Extension module. 290 RegisterFunction<SetUpdateUrlDataFunction>(); 291 RegisterFunction<IsAllowedIncognitoAccessFunction>(); 292 RegisterFunction<IsAllowedFileSchemeAccessFunction>(); 293 294 // WebstorePrivate. 295 RegisterFunction<GetBrowserLoginFunction>(); 296 RegisterFunction<GetStoreLoginFunction>(); 297 RegisterFunction<SetStoreLoginFunction>(); 298 RegisterFunction<PromptBrowserLoginFunction>(); 299 RegisterFunction<BeginInstallFunction>(); 300 RegisterFunction<BeginInstallWithManifestFunction>(); 301 RegisterFunction<CompleteInstallFunction>(); 302 303 // WebRequest. 304 RegisterFunction<WebRequestAddEventListener>(); 305 RegisterFunction<WebRequestEventHandled>(); 306 307 // Preferences. 308 RegisterFunction<GetPreferenceFunction>(); 309 RegisterFunction<SetPreferenceFunction>(); 310 RegisterFunction<ClearPreferenceFunction>(); 311 312 // ChromeOS-specific part of the API. 313 #if defined(OS_CHROMEOS) 314 // Device Customization. 315 RegisterFunction<GetChromeosInfoFunction>(); 316 317 // FileBrowserPrivate functions. 318 RegisterFunction<CancelFileDialogFunction>(); 319 RegisterFunction<ExecuteTasksFileBrowserFunction>(); 320 RegisterFunction<FileDialogStringsFunction>(); 321 RegisterFunction<GetFileTasksFileBrowserFunction>(); 322 RegisterFunction<RequestLocalFileSystemFunction>(); 323 RegisterFunction<SelectFileFunction>(); 324 RegisterFunction<SelectFilesFunction>(); 325 RegisterFunction<ViewFilesFunction>(); 326 #endif 327 328 // Debugger 329 RegisterFunction<AttachDebuggerFunction>(); 330 RegisterFunction<DetachDebuggerFunction>(); 331 RegisterFunction<SendRequestDebuggerFunction>(); 332 } 333 334 void FactoryRegistry::GetAllNames(std::vector<std::string>* names) { 335 for (FactoryMap::iterator iter = factories_.begin(); 336 iter != factories_.end(); ++iter) { 337 names->push_back(iter->first); 338 } 339 } 340 341 bool FactoryRegistry::OverrideFunction(const std::string& name, 342 ExtensionFunctionFactory factory) { 343 FactoryMap::iterator iter = factories_.find(name); 344 if (iter == factories_.end()) { 345 return false; 346 } else { 347 iter->second = factory; 348 return true; 349 } 350 } 351 352 ExtensionFunction* FactoryRegistry::NewFunction(const std::string& name) { 353 FactoryMap::iterator iter = factories_.find(name); 354 DCHECK(iter != factories_.end()); 355 ExtensionFunction* function = iter->second(); 356 function->set_name(name); 357 return function; 358 } 359 360 }; // namespace 361 362 // ExtensionFunctionDispatcher ------------------------------------------------- 363 364 void ExtensionFunctionDispatcher::GetAllFunctionNames( 365 std::vector<std::string>* names) { 366 FactoryRegistry::GetInstance()->GetAllNames(names); 367 } 368 369 bool ExtensionFunctionDispatcher::OverrideFunction( 370 const std::string& name, ExtensionFunctionFactory factory) { 371 return FactoryRegistry::GetInstance()->OverrideFunction(name, factory); 372 } 373 374 void ExtensionFunctionDispatcher::ResetFunctions() { 375 FactoryRegistry::GetInstance()->ResetFunctions(); 376 } 377 378 ExtensionFunctionDispatcher* ExtensionFunctionDispatcher::Create( 379 RenderViewHost* render_view_host, 380 Delegate* delegate, 381 const GURL& url) { 382 ExtensionService* service = 383 render_view_host->process()->profile()->GetExtensionService(); 384 DCHECK(service); 385 386 if (!service->ExtensionBindingsAllowed(url)) 387 return NULL; 388 389 const Extension* extension = service->GetExtensionByURL(url); 390 if (!extension) 391 extension = service->GetExtensionByWebExtent(url); 392 393 if (extension) 394 return new ExtensionFunctionDispatcher(render_view_host, delegate, 395 extension, url); 396 else 397 return NULL; 398 } 399 400 ExtensionFunctionDispatcher::ExtensionFunctionDispatcher( 401 RenderViewHost* render_view_host, 402 Delegate* delegate, 403 const Extension* extension, 404 const GURL& url) 405 : profile_(render_view_host->process()->profile()), 406 render_view_host_(render_view_host), 407 delegate_(delegate), 408 url_(url), 409 extension_id_(extension->id()), 410 ALLOW_THIS_IN_INITIALIZER_LIST(peer_(new Peer(this))) { 411 // TODO(erikkay) should we do something for these errors in Release? 412 DCHECK(extension); 413 DCHECK(url.SchemeIs(chrome::kExtensionScheme) || 414 extension->location() == Extension::COMPONENT); 415 416 // Notify the ExtensionProcessManager that the view was created. 417 ExtensionProcessManager* epm = profile()->GetExtensionProcessManager(); 418 epm->RegisterExtensionProcess(extension_id(), 419 render_view_host->process()->id()); 420 421 // If the extension has permission to load chrome://favicon/ resources we need 422 // to make sure that the FaviconSource is registered with the 423 // ChromeURLDataManager. 424 if (extension->HasHostPermission(GURL(chrome::kChromeUIFaviconURL))) { 425 FaviconSource* favicon_source = new FaviconSource(profile_); 426 profile_->GetChromeURLDataManager()->AddDataSource(favicon_source); 427 } 428 429 // Update the extension permissions. Doing this each time we create an EFD 430 // ensures that new processes are informed of permissions for newly installed 431 // extensions. 432 render_view_host->Send(new ExtensionMsg_SetAPIPermissions( 433 extension->id(), extension->api_permissions())); 434 render_view_host->Send(new ExtensionMsg_SetHostPermissions( 435 extension->url(), extension->host_permissions())); 436 437 NotificationService::current()->Notify( 438 NotificationType::EXTENSION_FUNCTION_DISPATCHER_CREATED, 439 Source<Profile>(profile_), 440 Details<ExtensionFunctionDispatcher>(this)); 441 } 442 443 ExtensionFunctionDispatcher::~ExtensionFunctionDispatcher() { 444 peer_->dispatcher_ = NULL; 445 446 NotificationService::current()->Notify( 447 NotificationType::EXTENSION_FUNCTION_DISPATCHER_DESTROYED, 448 Source<Profile>(profile_), 449 Details<ExtensionFunctionDispatcher>(this)); 450 } 451 452 Browser* ExtensionFunctionDispatcher::GetCurrentBrowser( 453 bool include_incognito) { 454 Browser* browser = delegate_->GetBrowser(); 455 456 // If the delegate has an associated browser, that is always the right answer. 457 if (browser) 458 return browser; 459 460 // Otherwise, try to default to a reasonable browser. If |include_incognito| 461 // is true, we will also search browsers in the incognito version of this 462 // profile. Note that the profile may already be incognito, in which case 463 // we will search the incognito version only, regardless of the value of 464 // |include_incognito|. 465 Profile* profile = render_view_host()->process()->profile(); 466 browser = BrowserList::FindBrowserWithType(profile, Browser::TYPE_NORMAL, 467 include_incognito); 468 469 // NOTE(rafaelw): This can return NULL in some circumstances. In particular, 470 // a background_page onload chrome.tabs api call can make it into here 471 // before the browser is sufficiently initialized to return here. 472 // A similar situation may arise during shutdown. 473 // TODO(rafaelw): Delay creation of background_page until the browser 474 // is available. http://code.google.com/p/chromium/issues/detail?id=13284 475 return browser; 476 } 477 478 void ExtensionFunctionDispatcher::HandleRequest( 479 const ExtensionHostMsg_DomMessage_Params& params) { 480 scoped_refptr<ExtensionFunction> function( 481 FactoryRegistry::GetInstance()->NewFunction(params.name)); 482 function->set_dispatcher_peer(peer_); 483 function->set_profile(profile_); 484 function->set_extension_id(extension_id()); 485 function->SetArgs(¶ms.arguments); 486 function->set_source_url(params.source_url); 487 function->set_request_id(params.request_id); 488 function->set_has_callback(params.has_callback); 489 function->set_user_gesture(params.user_gesture); 490 ExtensionService* service = profile()->GetExtensionService(); 491 DCHECK(service); 492 const Extension* extension = service->GetExtensionById(extension_id(), false); 493 DCHECK(extension); 494 function->set_include_incognito(service->CanCrossIncognito(extension)); 495 496 if (!service->ExtensionBindingsAllowed(function->source_url()) || 497 !extension->HasApiPermission(function->name())) { 498 render_view_host_->Send(new ExtensionMsg_Response( 499 render_view_host_->routing_id(), function->request_id(), false, 500 std::string(), "Access to extension API denied.")); 501 return; 502 } 503 504 ExtensionsQuotaService* quota = service->quota_service(); 505 if (quota->Assess(extension_id(), function, ¶ms.arguments, 506 base::TimeTicks::Now())) { 507 // See crbug.com/39178. 508 ExternalProtocolHandler::PermitLaunchUrl(); 509 510 function->Run(); 511 } else { 512 render_view_host_->Send(new ExtensionMsg_Response( 513 render_view_host_->routing_id(), function->request_id(), false, 514 std::string(), QuotaLimitHeuristic::kGenericOverQuotaError)); 515 } 516 } 517 518 void ExtensionFunctionDispatcher::SendResponse(ExtensionFunction* function, 519 bool success) { 520 render_view_host_->Send(new ExtensionMsg_Response( 521 render_view_host_->routing_id(), function->request_id(), success, 522 function->GetResult(), function->GetError())); 523 } 524 525 void ExtensionFunctionDispatcher::HandleBadMessage(ExtensionFunction* api) { 526 LOG(ERROR) << "bad extension message " << 527 api->name() << 528 " : terminating renderer."; 529 if (RenderProcessHost::run_renderer_in_process()) { 530 // In single process mode it is better if we don't suicide but just crash. 531 CHECK(false); 532 } else { 533 NOTREACHED(); 534 UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_EFD")); 535 base::KillProcess(render_view_host_->process()->GetHandle(), 536 ResultCodes::KILLED_BAD_MESSAGE, false); 537 } 538 } 539 540 Profile* ExtensionFunctionDispatcher::profile() { 541 return profile_; 542 } 543