Home | History | Annotate | Download | only in extensions
      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(&params.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, &params.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