blob: d17e575c261bc87db60b3884ea0a9cc195b7b89e [file] [log] [blame]
[email protected]bfdffe2b2009-04-24 22:05:351// Copyright (c) 2009 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
[email protected]bfdffe2b2009-04-24 22:05:357#include "base/process_util.h"
8#include "base/singleton.h"
9#include "base/values.h"
[email protected]912256b32009-09-18 09:47:3510#include "chrome/browser/extensions/execute_code_in_tab_function.h"
[email protected]bfdffe2b2009-04-24 22:05:3511#include "chrome/browser/extensions/extension_bookmarks_module.h"
[email protected]f93914852009-05-26 06:05:4012#include "chrome/browser/extensions/extension_bookmarks_module_constants.h"
[email protected]ec9ac0df2009-10-01 18:06:4713#include "chrome/browser/extensions/extension_browser_actions_api.h"
[email protected]bfdffe2b2009-04-24 22:05:3514#include "chrome/browser/extensions/extension_function.h"
[email protected]198bcfe2009-09-09 22:56:2815#include "chrome/browser/extensions/extension_i18n_api.h"
[email protected]e916901c2009-05-07 00:14:3116#include "chrome/browser/extensions/extension_message_service.h"
[email protected]f7f3a5f2009-05-01 22:02:3417#include "chrome/browser/extensions/extension_page_actions_module.h"
[email protected]f93914852009-05-26 06:05:4018#include "chrome/browser/extensions/extension_page_actions_module_constants.h"
[email protected]45776222009-07-15 20:21:5819#include "chrome/browser/extensions/extension_process_manager.h"
[email protected]bfdffe2b2009-04-24 22:05:3520#include "chrome/browser/extensions/extension_tabs_module.h"
[email protected]f93914852009-05-26 06:05:4021#include "chrome/browser/extensions/extension_tabs_module_constants.h"
[email protected]25fd1b2e2009-08-17 20:57:1422#include "chrome/browser/extensions/extension_test_api.h"
[email protected]9c45b7182009-08-04 16:44:4323#include "chrome/browser/extensions/extension_toolstrip_api.h"
[email protected]e916901c2009-05-07 00:14:3124#include "chrome/browser/profile.h"
[email protected]bfdffe2b2009-04-24 22:05:3525#include "chrome/browser/renderer_host/render_process_host.h"
26#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]35506352009-08-07 18:58:1927#include "chrome/common/render_messages.h"
[email protected]bfdffe2b2009-04-24 22:05:3528#include "chrome/common/result_codes.h"
[email protected]9c45b7182009-08-04 16:44:4329#include "chrome/common/url_constants.h"
[email protected]bfdffe2b2009-04-24 22:05:3530
31// FactoryRegistry -------------------------------------------------------------
32
33namespace {
34
[email protected]b83e4602009-05-15 22:58:3335// Template for defining ExtensionFunctionFactory.
36template<class T>
37ExtensionFunction* NewExtensionFunction() {
38 return new T();
39}
[email protected]bfdffe2b2009-04-24 22:05:3540
[email protected]b83e4602009-05-15 22:58:3341// Contains a list of all known extension functions and allows clients to
42// create instances of them.
[email protected]bfdffe2b2009-04-24 22:05:3543class FactoryRegistry {
44 public:
45 static FactoryRegistry* instance();
[email protected]b83e4602009-05-15 22:58:3346 FactoryRegistry() { ResetFunctions(); }
47
48 // Resets all functions to their default values.
49 void ResetFunctions();
50
51 // Adds all function names to 'names'.
[email protected]bfdffe2b2009-04-24 22:05:3552 void GetAllNames(std::vector<std::string>* names);
[email protected]b83e4602009-05-15 22:58:3353
54 // Allows overriding of specific functions (e.g. for testing). Functions
55 // must be previously registered. Returns true if successful.
56 bool OverrideFunction(const std::string& name,
57 ExtensionFunctionFactory factory);
58
59 // Factory method for the ExtensionFunction registered as 'name'.
[email protected]bfdffe2b2009-04-24 22:05:3560 ExtensionFunction* NewFunction(const std::string& name);
61
62 private:
63 typedef std::map<std::string, ExtensionFunctionFactory> FactoryMap;
64 FactoryMap factories_;
65};
66
[email protected]bfdffe2b2009-04-24 22:05:3567FactoryRegistry* FactoryRegistry::instance() {
68 return Singleton<FactoryRegistry>::get();
69}
70
[email protected]b83e4602009-05-15 22:58:3371void FactoryRegistry::ResetFunctions() {
[email protected]bfdffe2b2009-04-24 22:05:3572 // Register all functions here.
73
[email protected]f93914852009-05-26 06:05:4074 namespace bookmarks = extension_bookmarks_module_constants;
[email protected]198bcfe2009-09-09 22:56:2875 namespace i18n = extension_i18n_api_functions;
[email protected]25fd1b2e2009-08-17 20:57:1476 namespace page_actions = extension_page_actions_module_constants;
[email protected]ec9ac0df2009-10-01 18:06:4777 namespace browser_actions = extension_browser_actions_api_constants;
[email protected]25fd1b2e2009-08-17 20:57:1478 namespace tabs = extension_tabs_module_constants;
79 namespace test = extension_test_api_functions;
[email protected]9c45b7182009-08-04 16:44:4380 namespace toolstrip = extension_toolstrip_api_functions;
[email protected]f93914852009-05-26 06:05:4081
[email protected]e515f5d2009-05-05 03:05:0082 // Windows
[email protected]afac6fe2009-06-04 14:58:1883 factories_[tabs::kGetWindowFunction] =
[email protected]f93914852009-05-26 06:05:4084 &NewExtensionFunction<GetWindowFunction>;
85 factories_[tabs::kGetCurrentWindowFunction] =
[email protected]e515f5d2009-05-05 03:05:0086 &NewExtensionFunction<GetCurrentWindowFunction>;
[email protected]f93914852009-05-26 06:05:4087 factories_[tabs::kGetLastFocusedWindowFunction] =
[email protected]c6619182009-05-12 14:59:3288 &NewExtensionFunction<GetLastFocusedWindowFunction>;
[email protected]f93914852009-05-26 06:05:4089 factories_[tabs::kGetAllWindowsFunction] =
90 &NewExtensionFunction<GetAllWindowsFunction>;
[email protected]afac6fe2009-06-04 14:58:1891 factories_[tabs::kCreateWindowFunction] =
[email protected]f93914852009-05-26 06:05:4092 &NewExtensionFunction<CreateWindowFunction>;
[email protected]afac6fe2009-06-04 14:58:1893 factories_[tabs::kUpdateWindowFunction] =
[email protected]f93914852009-05-26 06:05:4094 &NewExtensionFunction<UpdateWindowFunction>;
[email protected]afac6fe2009-06-04 14:58:1895 factories_[tabs::kRemoveWindowFunction] =
[email protected]f93914852009-05-26 06:05:4096 &NewExtensionFunction<RemoveWindowFunction>;
[email protected]b83e4602009-05-15 22:58:3397
[email protected]e515f5d2009-05-05 03:05:0098 // Tabs
[email protected]afac6fe2009-06-04 14:58:1899 factories_[tabs::kGetTabFunction] =
[email protected]f93914852009-05-26 06:05:40100 &NewExtensionFunction<GetTabFunction>;
101 factories_[tabs::kGetSelectedTabFunction] =
[email protected]b83e4602009-05-15 22:58:33102 &NewExtensionFunction<GetSelectedTabFunction>;
[email protected]f93914852009-05-26 06:05:40103 factories_[tabs::kGetAllTabsInWindowFunction] =
[email protected]e515f5d2009-05-05 03:05:00104 &NewExtensionFunction<GetAllTabsInWindowFunction>;
[email protected]afac6fe2009-06-04 14:58:18105 factories_[tabs::kCreateTabFunction] =
[email protected]f93914852009-05-26 06:05:40106 &NewExtensionFunction<CreateTabFunction>;
[email protected]afac6fe2009-06-04 14:58:18107 factories_[tabs::kUpdateTabFunction] =
[email protected]f93914852009-05-26 06:05:40108 &NewExtensionFunction<UpdateTabFunction>;
[email protected]afac6fe2009-06-04 14:58:18109 factories_[tabs::kMoveTabFunction] =
[email protected]f93914852009-05-26 06:05:40110 &NewExtensionFunction<MoveTabFunction>;
[email protected]afac6fe2009-06-04 14:58:18111 factories_[tabs::kRemoveTabFunction] =
[email protected]f93914852009-05-26 06:05:40112 &NewExtensionFunction<RemoveTabFunction>;
[email protected]5bf39352009-07-16 20:43:01113 factories_[tabs::kDetectTabLanguageFunction] =
114 &NewExtensionFunction<DetectTabLanguageFunction>;
[email protected]3947c4d2009-08-13 00:04:06115 factories_[tabs::kCaptureVisibleTabFunction] =
116 &NewExtensionFunction<CaptureVisibleTabFunction>;
[email protected]912256b32009-09-18 09:47:35117 factories_[tabs::kExecuteScriptFunction] =
118 &NewExtensionFunction<ExecuteCodeInTabFunction>;
119 factories_[tabs::kInsertCSSFunction] =
120 &NewExtensionFunction<ExecuteCodeInTabFunction>;
[email protected]bfdffe2b2009-04-24 22:05:35121
[email protected]f7f3a5f2009-05-01 22:02:34122 // Page Actions.
[email protected]f93914852009-05-26 06:05:40123 factories_[page_actions::kEnablePageActionFunction] =
[email protected]f7f3a5f2009-05-01 22:02:34124 &NewExtensionFunction<EnablePageActionFunction>;
[email protected]f9b1a7b2009-06-22 17:26:38125 factories_[page_actions::kDisablePageActionFunction] =
126 &NewExtensionFunction<DisablePageActionFunction>;
[email protected]f7f3a5f2009-05-01 22:02:34127
[email protected]ec9ac0df2009-10-01 18:06:47128 // Browser Actions.
129 factories_[browser_actions::kSetNameFunction] =
130 &NewExtensionFunction<BrowserActionSetNameFunction>;
131 factories_[browser_actions::kSetIconFunction] =
132 &NewExtensionFunction<BrowserActionSetIconFunction>;
[email protected]5132483c2009-10-03 19:39:24133 factories_[browser_actions::kSetBadgeTextFunction] =
134 &NewExtensionFunction<BrowserActionSetBadgeTextFunction>;
135 factories_[browser_actions::kSetBadgeBackgroundColorFunction] =
136 &NewExtensionFunction<BrowserActionSetBadgeBackgroundColorFunction>;
[email protected]ec9ac0df2009-10-01 18:06:47137
[email protected]f7f3a5f2009-05-01 22:02:34138 // Bookmarks.
[email protected]f93914852009-05-26 06:05:40139 factories_[bookmarks::kGetBookmarksFunction] =
140 &NewExtensionFunction<GetBookmarksFunction>;
141 factories_[bookmarks::kGetBookmarkChildrenFunction] =
[email protected]309934c42009-04-29 20:28:46142 &NewExtensionFunction<GetBookmarkChildrenFunction>;
[email protected]f93914852009-05-26 06:05:40143 factories_[bookmarks::kGetBookmarkTreeFunction] =
[email protected]309934c42009-04-29 20:28:46144 &NewExtensionFunction<GetBookmarkTreeFunction>;
[email protected]f93914852009-05-26 06:05:40145 factories_[bookmarks::kSearchBookmarksFunction] =
[email protected]bfdffe2b2009-04-24 22:05:35146 &NewExtensionFunction<SearchBookmarksFunction>;
[email protected]f93914852009-05-26 06:05:40147 factories_[bookmarks::kRemoveBookmarkFunction] =
[email protected]b83e4602009-05-15 22:58:33148 &NewExtensionFunction<RemoveBookmarkFunction>;
[email protected]434c21e2009-07-16 22:20:00149 factories_[bookmarks::kRemoveBookmarkTreeFunction] =
150 &NewExtensionFunction<RemoveBookmarkFunction>;
[email protected]f93914852009-05-26 06:05:40151 factories_[bookmarks::kCreateBookmarkFunction] =
[email protected]b83e4602009-05-15 22:58:33152 &NewExtensionFunction<CreateBookmarkFunction>;
[email protected]f93914852009-05-26 06:05:40153 factories_[bookmarks::kMoveBookmarkFunction] =
154 &NewExtensionFunction<MoveBookmarkFunction>;
[email protected]ea7c4fb2009-09-01 15:49:37155 factories_[bookmarks::kUpdateBookmarkFunction] =
156 &NewExtensionFunction<UpdateBookmarkFunction>;
[email protected]9c45b7182009-08-04 16:44:43157
158 // Toolstrips.
159 factories_[toolstrip::kExpandFunction] =
160 &NewExtensionFunction<ToolstripExpandFunction>;
161 factories_[toolstrip::kCollapseFunction] =
162 &NewExtensionFunction<ToolstripCollapseFunction>;
[email protected]25fd1b2e2009-08-17 20:57:14163
[email protected]198bcfe2009-09-09 22:56:28164 // I18N.
165 factories_[i18n::kGetAcceptLanguagesFunction] =
166 &NewExtensionFunction<GetAcceptLanguagesFunction>;
167
[email protected]25fd1b2e2009-08-17 20:57:14168 // Test.
169 factories_[test::kPassFunction] =
170 &NewExtensionFunction<ExtensionTestPassFunction>;
171 factories_[test::kFailFunction] =
172 &NewExtensionFunction<ExtensionTestFailFunction>;
[email protected]9b6d31d2009-09-01 01:44:03173 factories_[test::kLogFunction] =
174 &NewExtensionFunction<ExtensionTestLogFunction>;
[email protected]bfdffe2b2009-04-24 22:05:35175}
176
[email protected]b83e4602009-05-15 22:58:33177void FactoryRegistry::GetAllNames(std::vector<std::string>* names) {
178 for (FactoryMap::iterator iter = factories_.begin();
179 iter != factories_.end(); ++iter) {
[email protected]bfdffe2b2009-04-24 22:05:35180 names->push_back(iter->first);
181 }
182}
183
[email protected]b83e4602009-05-15 22:58:33184bool FactoryRegistry::OverrideFunction(const std::string& name,
185 ExtensionFunctionFactory factory) {
186 FactoryMap::iterator iter = factories_.find(name);
187 if (iter == factories_.end()) {
188 return false;
189 } else {
190 iter->second = factory;
191 return true;
192 }
193}
194
[email protected]bfdffe2b2009-04-24 22:05:35195ExtensionFunction* FactoryRegistry::NewFunction(const std::string& name) {
196 FactoryMap::iterator iter = factories_.find(name);
197 DCHECK(iter != factories_.end());
[email protected]b83e4602009-05-15 22:58:33198 ExtensionFunction* function = iter->second();
[email protected]76a3db852009-07-24 02:14:56199 function->set_name(name);
[email protected]b83e4602009-05-15 22:58:33200 return function;
[email protected]bfdffe2b2009-04-24 22:05:35201}
202
[email protected]b83e4602009-05-15 22:58:33203}; // namespace
[email protected]bfdffe2b2009-04-24 22:05:35204
205// ExtensionFunctionDispatcher -------------------------------------------------
206
207void ExtensionFunctionDispatcher::GetAllFunctionNames(
208 std::vector<std::string>* names) {
209 FactoryRegistry::instance()->GetAllNames(names);
210}
211
[email protected]b83e4602009-05-15 22:58:33212bool ExtensionFunctionDispatcher::OverrideFunction(
213 const std::string& name, ExtensionFunctionFactory factory) {
214 return FactoryRegistry::instance()->OverrideFunction(name, factory);
215}
216
217void ExtensionFunctionDispatcher::ResetFunctions() {
218 FactoryRegistry::instance()->ResetFunctions();
219}
220
[email protected]811bfe32009-07-01 08:46:25221std::set<ExtensionFunctionDispatcher*>*
222 ExtensionFunctionDispatcher::all_instances() {
223 static std::set<ExtensionFunctionDispatcher*> instances;
224 return &instances;
225}
226
[email protected]bfdffe2b2009-04-24 22:05:35227ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(
228 RenderViewHost* render_view_host,
[email protected]7eecaed52009-05-07 21:44:12229 Delegate* delegate,
[email protected]811bfe32009-07-01 08:46:25230 const GURL& url)
[email protected]bfdffe2b2009-04-24 22:05:35231 : render_view_host_(render_view_host),
[email protected]7eecaed52009-05-07 21:44:12232 delegate_(delegate),
[email protected]811bfe32009-07-01 08:46:25233 url_(url),
[email protected]32dda362009-06-05 19:07:01234 ALLOW_THIS_IN_INITIALIZER_LIST(peer_(new Peer(this))) {
[email protected]9c45b7182009-08-04 16:44:43235 // TODO(erikkay) should we do something for these errors in Release?
236 DCHECK(url.SchemeIs(chrome::kExtensionScheme));
[email protected]35506352009-08-07 18:58:19237
238 Extension* extension =
239 profile()->GetExtensionsService()->GetExtensionByURL(url);
240 DCHECK(extension);
[email protected]9c45b7182009-08-04 16:44:43241
[email protected]811bfe32009-07-01 08:46:25242 all_instances()->insert(this);
[email protected]0f6053962009-07-09 19:26:35243
[email protected]45776222009-07-15 20:21:58244 // Notify the ExtensionProcessManager that the view was created.
245 ExtensionProcessManager* epm = profile()->GetExtensionProcessManager();
246 epm->RegisterExtensionProcess(extension_id(),
[email protected]76543b92009-08-31 17:27:45247 render_view_host->process()->id());
[email protected]35506352009-08-07 18:58:19248
249 // Update the extension permissions. Doing this each time we create an EFD
250 // ensures that new processes are informed of permissions for newly installed
251 // extensions.
[email protected]cccf90932009-08-23 17:56:25252 render_view_host->Send(new ViewMsg_Extension_SetAPIPermissions(
[email protected]35506352009-08-07 18:58:19253 extension->id(), extension->api_permissions()));
[email protected]cccf90932009-08-23 17:56:25254 render_view_host->Send(new ViewMsg_Extension_SetHostPermissions(
255 extension->url(), extension->host_permissions()));
[email protected]bfdffe2b2009-04-24 22:05:35256}
257
[email protected]32dda362009-06-05 19:07:01258ExtensionFunctionDispatcher::~ExtensionFunctionDispatcher() {
[email protected]811bfe32009-07-01 08:46:25259 all_instances()->erase(this);
[email protected]32dda362009-06-05 19:07:01260 peer_->dispatcher_ = NULL;
261}
262
[email protected]7eecaed52009-05-07 21:44:12263Browser* ExtensionFunctionDispatcher::GetBrowser() {
[email protected]4ba60e22009-08-14 21:02:11264 return delegate_->GetBrowser();
[email protected]7eecaed52009-05-07 21:44:12265}
266
[email protected]9c45b7182009-08-04 16:44:43267ExtensionHost* ExtensionFunctionDispatcher::GetExtensionHost() {
[email protected]9c45b7182009-08-04 16:44:43268 return delegate_->GetExtensionHost();
269}
270
[email protected]c7ad50f2009-09-11 06:28:15271Extension* ExtensionFunctionDispatcher::GetExtension() {
272 ExtensionsService* service = profile()->GetExtensionsService();
273 DCHECK(service);
274
275 Extension* extension = service->GetExtensionById(extension_id());
276 DCHECK(extension);
277
278 return extension;
279}
280
[email protected]bfdffe2b2009-04-24 22:05:35281void ExtensionFunctionDispatcher::HandleRequest(const std::string& name,
[email protected]e4dad9fb2009-10-06 18:15:58282 const Value* args,
[email protected]c6619182009-05-12 14:59:32283 int request_id,
284 bool has_callback) {
[email protected]32dda362009-06-05 19:07:01285 scoped_refptr<ExtensionFunction> function(
[email protected]bfdffe2b2009-04-24 22:05:35286 FactoryRegistry::instance()->NewFunction(name));
[email protected]32dda362009-06-05 19:07:01287 function->set_dispatcher_peer(peer_);
[email protected]b83e4602009-05-15 22:58:33288 function->SetArgs(args);
[email protected]c6619182009-05-12 14:59:32289 function->set_request_id(request_id);
290 function->set_has_callback(has_callback);
[email protected]bfdffe2b2009-04-24 22:05:35291 function->Run();
292}
293
[email protected]c6619182009-05-12 14:59:32294void ExtensionFunctionDispatcher::SendResponse(ExtensionFunction* function,
295 bool success) {
[email protected]c6619182009-05-12 14:59:32296 render_view_host_->SendExtensionResponse(function->request_id(), success,
[email protected]b83e4602009-05-15 22:58:33297 function->GetResult(), function->GetError());
[email protected]bfdffe2b2009-04-24 22:05:35298}
299
300void ExtensionFunctionDispatcher::HandleBadMessage(ExtensionFunction* api) {
[email protected]25fd1b2e2009-08-17 20:57:14301 LOG(ERROR) << "bad extension message " <<
[email protected]76543b92009-08-31 17:27:45302 api->name() <<
[email protected]bfdffe2b2009-04-24 22:05:35303 " : terminating renderer.";
304 if (RenderProcessHost::run_renderer_in_process()) {
305 // In single process mode it is better if we don't suicide but just crash.
306 CHECK(false);
307 } else {
308 NOTREACHED();
309 base::KillProcess(render_view_host_->process()->process().handle(),
310 ResultCodes::KILLED_BAD_MESSAGE, false);
311 }
312}
313
314Profile* ExtensionFunctionDispatcher::profile() {
315 return render_view_host_->process()->profile();
316}