• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
NewExtensionFunction()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();
FactoryRegistry()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>
RegisterFunction()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 
GetInstance()113 FactoryRegistry* FactoryRegistry::GetInstance() {
114   return Singleton<FactoryRegistry>::get();
115 }
116 
ResetFunctions()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 
GetAllNames(std::vector<std::string> * names)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 
OverrideFunction(const std::string & name,ExtensionFunctionFactory factory)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 
NewFunction(const std::string & name)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 
GetAllFunctionNames(std::vector<std::string> * names)364 void ExtensionFunctionDispatcher::GetAllFunctionNames(
365     std::vector<std::string>* names) {
366   FactoryRegistry::GetInstance()->GetAllNames(names);
367 }
368 
OverrideFunction(const std::string & name,ExtensionFunctionFactory factory)369 bool ExtensionFunctionDispatcher::OverrideFunction(
370     const std::string& name, ExtensionFunctionFactory factory) {
371   return FactoryRegistry::GetInstance()->OverrideFunction(name, factory);
372 }
373 
ResetFunctions()374 void ExtensionFunctionDispatcher::ResetFunctions() {
375   FactoryRegistry::GetInstance()->ResetFunctions();
376 }
377 
Create(RenderViewHost * render_view_host,Delegate * delegate,const GURL & url)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 
ExtensionFunctionDispatcher(RenderViewHost * render_view_host,Delegate * delegate,const Extension * extension,const GURL & url)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 
~ExtensionFunctionDispatcher()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 
GetCurrentBrowser(bool include_incognito)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 
HandleRequest(const ExtensionHostMsg_DomMessage_Params & params)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 
SendResponse(ExtensionFunction * function,bool success)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 
HandleBadMessage(ExtensionFunction * api)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 
profile()540 Profile* ExtensionFunctionDispatcher::profile() {
541   return profile_;
542 }
543