blob: 276dd168644ccde35435eeeb3f7185a3b24e950f [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"
10#include "chrome/browser/extensions/extension_bookmarks_module.h"
[email protected]f93914852009-05-26 06:05:4011#include "chrome/browser/extensions/extension_bookmarks_module_constants.h"
[email protected]bfdffe2b2009-04-24 22:05:3512#include "chrome/browser/extensions/extension_function.h"
[email protected]198bcfe2009-09-09 22:56:2813#include "chrome/browser/extensions/extension_i18n_api.h"
[email protected]e916901c2009-05-07 00:14:3114#include "chrome/browser/extensions/extension_message_service.h"
[email protected]f7f3a5f2009-05-01 22:02:3415#include "chrome/browser/extensions/extension_page_actions_module.h"
[email protected]f93914852009-05-26 06:05:4016#include "chrome/browser/extensions/extension_page_actions_module_constants.h"
[email protected]45776222009-07-15 20:21:5817#include "chrome/browser/extensions/extension_process_manager.h"
[email protected]bfdffe2b2009-04-24 22:05:3518#include "chrome/browser/extensions/extension_tabs_module.h"
[email protected]f93914852009-05-26 06:05:4019#include "chrome/browser/extensions/extension_tabs_module_constants.h"
[email protected]25fd1b2e2009-08-17 20:57:1420#include "chrome/browser/extensions/extension_test_api.h"
[email protected]9c45b7182009-08-04 16:44:4321#include "chrome/browser/extensions/extension_toolstrip_api.h"
[email protected]e916901c2009-05-07 00:14:3122#include "chrome/browser/profile.h"
[email protected]bfdffe2b2009-04-24 22:05:3523#include "chrome/browser/renderer_host/render_process_host.h"
24#include "chrome/browser/renderer_host/render_view_host.h"
[email protected]35506352009-08-07 18:58:1925#include "chrome/common/render_messages.h"
[email protected]bfdffe2b2009-04-24 22:05:3526#include "chrome/common/result_codes.h"
[email protected]9c45b7182009-08-04 16:44:4327#include "chrome/common/url_constants.h"
[email protected]bfdffe2b2009-04-24 22:05:3528
29// FactoryRegistry -------------------------------------------------------------
30
31namespace {
32
[email protected]b83e4602009-05-15 22:58:3333// Template for defining ExtensionFunctionFactory.
34template<class T>
35ExtensionFunction* NewExtensionFunction() {
36 return new T();
37}
[email protected]bfdffe2b2009-04-24 22:05:3538
[email protected]b83e4602009-05-15 22:58:3339// Contains a list of all known extension functions and allows clients to
40// create instances of them.
[email protected]bfdffe2b2009-04-24 22:05:3541class FactoryRegistry {
42 public:
43 static FactoryRegistry* instance();
[email protected]b83e4602009-05-15 22:58:3344 FactoryRegistry() { ResetFunctions(); }
45
46 // Resets all functions to their default values.
47 void ResetFunctions();
48
49 // Adds all function names to 'names'.
[email protected]bfdffe2b2009-04-24 22:05:3550 void GetAllNames(std::vector<std::string>* names);
[email protected]b83e4602009-05-15 22:58:3351
52 // Allows overriding of specific functions (e.g. for testing). Functions
53 // must be previously registered. Returns true if successful.
54 bool OverrideFunction(const std::string& name,
55 ExtensionFunctionFactory factory);
56
57 // Factory method for the ExtensionFunction registered as 'name'.
[email protected]bfdffe2b2009-04-24 22:05:3558 ExtensionFunction* NewFunction(const std::string& name);
59
60 private:
61 typedef std::map<std::string, ExtensionFunctionFactory> FactoryMap;
62 FactoryMap factories_;
63};
64
[email protected]bfdffe2b2009-04-24 22:05:3565FactoryRegistry* FactoryRegistry::instance() {
66 return Singleton<FactoryRegistry>::get();
67}
68
[email protected]b83e4602009-05-15 22:58:3369void FactoryRegistry::ResetFunctions() {
[email protected]bfdffe2b2009-04-24 22:05:3570 // Register all functions here.
71
[email protected]f93914852009-05-26 06:05:4072 namespace bookmarks = extension_bookmarks_module_constants;
[email protected]198bcfe2009-09-09 22:56:2873 namespace i18n = extension_i18n_api_functions;
[email protected]25fd1b2e2009-08-17 20:57:1474 namespace page_actions = extension_page_actions_module_constants;
75 namespace tabs = extension_tabs_module_constants;
76 namespace test = extension_test_api_functions;
[email protected]9c45b7182009-08-04 16:44:4377 namespace toolstrip = extension_toolstrip_api_functions;
[email protected]f93914852009-05-26 06:05:4078
[email protected]e515f5d2009-05-05 03:05:0079 // Windows
[email protected]afac6fe2009-06-04 14:58:1880 factories_[tabs::kGetWindowFunction] =
[email protected]f93914852009-05-26 06:05:4081 &NewExtensionFunction<GetWindowFunction>;
82 factories_[tabs::kGetCurrentWindowFunction] =
[email protected]e515f5d2009-05-05 03:05:0083 &NewExtensionFunction<GetCurrentWindowFunction>;
[email protected]f93914852009-05-26 06:05:4084 factories_[tabs::kGetLastFocusedWindowFunction] =
[email protected]c6619182009-05-12 14:59:3285 &NewExtensionFunction<GetLastFocusedWindowFunction>;
[email protected]f93914852009-05-26 06:05:4086 factories_[tabs::kGetAllWindowsFunction] =
87 &NewExtensionFunction<GetAllWindowsFunction>;
[email protected]afac6fe2009-06-04 14:58:1888 factories_[tabs::kCreateWindowFunction] =
[email protected]f93914852009-05-26 06:05:4089 &NewExtensionFunction<CreateWindowFunction>;
[email protected]afac6fe2009-06-04 14:58:1890 factories_[tabs::kUpdateWindowFunction] =
[email protected]f93914852009-05-26 06:05:4091 &NewExtensionFunction<UpdateWindowFunction>;
[email protected]afac6fe2009-06-04 14:58:1892 factories_[tabs::kRemoveWindowFunction] =
[email protected]f93914852009-05-26 06:05:4093 &NewExtensionFunction<RemoveWindowFunction>;
[email protected]b83e4602009-05-15 22:58:3394
[email protected]e515f5d2009-05-05 03:05:0095 // Tabs
[email protected]afac6fe2009-06-04 14:58:1896 factories_[tabs::kGetTabFunction] =
[email protected]f93914852009-05-26 06:05:4097 &NewExtensionFunction<GetTabFunction>;
98 factories_[tabs::kGetSelectedTabFunction] =
[email protected]b83e4602009-05-15 22:58:3399 &NewExtensionFunction<GetSelectedTabFunction>;
[email protected]f93914852009-05-26 06:05:40100 factories_[tabs::kGetAllTabsInWindowFunction] =
[email protected]e515f5d2009-05-05 03:05:00101 &NewExtensionFunction<GetAllTabsInWindowFunction>;
[email protected]afac6fe2009-06-04 14:58:18102 factories_[tabs::kCreateTabFunction] =
[email protected]f93914852009-05-26 06:05:40103 &NewExtensionFunction<CreateTabFunction>;
[email protected]afac6fe2009-06-04 14:58:18104 factories_[tabs::kUpdateTabFunction] =
[email protected]f93914852009-05-26 06:05:40105 &NewExtensionFunction<UpdateTabFunction>;
[email protected]afac6fe2009-06-04 14:58:18106 factories_[tabs::kMoveTabFunction] =
[email protected]f93914852009-05-26 06:05:40107 &NewExtensionFunction<MoveTabFunction>;
[email protected]afac6fe2009-06-04 14:58:18108 factories_[tabs::kRemoveTabFunction] =
[email protected]f93914852009-05-26 06:05:40109 &NewExtensionFunction<RemoveTabFunction>;
[email protected]5bf39352009-07-16 20:43:01110 factories_[tabs::kDetectTabLanguageFunction] =
111 &NewExtensionFunction<DetectTabLanguageFunction>;
[email protected]3947c4d2009-08-13 00:04:06112 factories_[tabs::kCaptureVisibleTabFunction] =
113 &NewExtensionFunction<CaptureVisibleTabFunction>;
[email protected]bfdffe2b2009-04-24 22:05:35114
[email protected]f7f3a5f2009-05-01 22:02:34115 // Page Actions.
[email protected]f93914852009-05-26 06:05:40116 factories_[page_actions::kEnablePageActionFunction] =
[email protected]f7f3a5f2009-05-01 22:02:34117 &NewExtensionFunction<EnablePageActionFunction>;
[email protected]f9b1a7b2009-06-22 17:26:38118 factories_[page_actions::kDisablePageActionFunction] =
119 &NewExtensionFunction<DisablePageActionFunction>;
[email protected]f7f3a5f2009-05-01 22:02:34120
121 // Bookmarks.
[email protected]f93914852009-05-26 06:05:40122 factories_[bookmarks::kGetBookmarksFunction] =
123 &NewExtensionFunction<GetBookmarksFunction>;
124 factories_[bookmarks::kGetBookmarkChildrenFunction] =
[email protected]309934c42009-04-29 20:28:46125 &NewExtensionFunction<GetBookmarkChildrenFunction>;
[email protected]f93914852009-05-26 06:05:40126 factories_[bookmarks::kGetBookmarkTreeFunction] =
[email protected]309934c42009-04-29 20:28:46127 &NewExtensionFunction<GetBookmarkTreeFunction>;
[email protected]f93914852009-05-26 06:05:40128 factories_[bookmarks::kSearchBookmarksFunction] =
[email protected]bfdffe2b2009-04-24 22:05:35129 &NewExtensionFunction<SearchBookmarksFunction>;
[email protected]f93914852009-05-26 06:05:40130 factories_[bookmarks::kRemoveBookmarkFunction] =
[email protected]b83e4602009-05-15 22:58:33131 &NewExtensionFunction<RemoveBookmarkFunction>;
[email protected]434c21e2009-07-16 22:20:00132 factories_[bookmarks::kRemoveBookmarkTreeFunction] =
133 &NewExtensionFunction<RemoveBookmarkFunction>;
[email protected]f93914852009-05-26 06:05:40134 factories_[bookmarks::kCreateBookmarkFunction] =
[email protected]b83e4602009-05-15 22:58:33135 &NewExtensionFunction<CreateBookmarkFunction>;
[email protected]f93914852009-05-26 06:05:40136 factories_[bookmarks::kMoveBookmarkFunction] =
137 &NewExtensionFunction<MoveBookmarkFunction>;
[email protected]ea7c4fb2009-09-01 15:49:37138 factories_[bookmarks::kUpdateBookmarkFunction] =
139 &NewExtensionFunction<UpdateBookmarkFunction>;
[email protected]9c45b7182009-08-04 16:44:43140
141 // Toolstrips.
142 factories_[toolstrip::kExpandFunction] =
143 &NewExtensionFunction<ToolstripExpandFunction>;
144 factories_[toolstrip::kCollapseFunction] =
145 &NewExtensionFunction<ToolstripCollapseFunction>;
[email protected]25fd1b2e2009-08-17 20:57:14146
[email protected]198bcfe2009-09-09 22:56:28147 // I18N.
148 factories_[i18n::kGetAcceptLanguagesFunction] =
149 &NewExtensionFunction<GetAcceptLanguagesFunction>;
150
[email protected]25fd1b2e2009-08-17 20:57:14151 // Test.
152 factories_[test::kPassFunction] =
153 &NewExtensionFunction<ExtensionTestPassFunction>;
154 factories_[test::kFailFunction] =
155 &NewExtensionFunction<ExtensionTestFailFunction>;
[email protected]9b6d31d2009-09-01 01:44:03156 factories_[test::kLogFunction] =
157 &NewExtensionFunction<ExtensionTestLogFunction>;
[email protected]bfdffe2b2009-04-24 22:05:35158}
159
[email protected]b83e4602009-05-15 22:58:33160void FactoryRegistry::GetAllNames(std::vector<std::string>* names) {
161 for (FactoryMap::iterator iter = factories_.begin();
162 iter != factories_.end(); ++iter) {
[email protected]bfdffe2b2009-04-24 22:05:35163 names->push_back(iter->first);
164 }
165}
166
[email protected]b83e4602009-05-15 22:58:33167bool FactoryRegistry::OverrideFunction(const std::string& name,
168 ExtensionFunctionFactory factory) {
169 FactoryMap::iterator iter = factories_.find(name);
170 if (iter == factories_.end()) {
171 return false;
172 } else {
173 iter->second = factory;
174 return true;
175 }
176}
177
[email protected]bfdffe2b2009-04-24 22:05:35178ExtensionFunction* FactoryRegistry::NewFunction(const std::string& name) {
179 FactoryMap::iterator iter = factories_.find(name);
180 DCHECK(iter != factories_.end());
[email protected]b83e4602009-05-15 22:58:33181 ExtensionFunction* function = iter->second();
[email protected]76a3db852009-07-24 02:14:56182 function->set_name(name);
[email protected]b83e4602009-05-15 22:58:33183 return function;
[email protected]bfdffe2b2009-04-24 22:05:35184}
185
[email protected]b83e4602009-05-15 22:58:33186}; // namespace
[email protected]bfdffe2b2009-04-24 22:05:35187
188// ExtensionFunctionDispatcher -------------------------------------------------
189
190void ExtensionFunctionDispatcher::GetAllFunctionNames(
191 std::vector<std::string>* names) {
192 FactoryRegistry::instance()->GetAllNames(names);
193}
194
[email protected]b83e4602009-05-15 22:58:33195bool ExtensionFunctionDispatcher::OverrideFunction(
196 const std::string& name, ExtensionFunctionFactory factory) {
197 return FactoryRegistry::instance()->OverrideFunction(name, factory);
198}
199
200void ExtensionFunctionDispatcher::ResetFunctions() {
201 FactoryRegistry::instance()->ResetFunctions();
202}
203
[email protected]811bfe32009-07-01 08:46:25204std::set<ExtensionFunctionDispatcher*>*
205 ExtensionFunctionDispatcher::all_instances() {
206 static std::set<ExtensionFunctionDispatcher*> instances;
207 return &instances;
208}
209
[email protected]bfdffe2b2009-04-24 22:05:35210ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(
211 RenderViewHost* render_view_host,
[email protected]7eecaed52009-05-07 21:44:12212 Delegate* delegate,
[email protected]811bfe32009-07-01 08:46:25213 const GURL& url)
[email protected]bfdffe2b2009-04-24 22:05:35214 : render_view_host_(render_view_host),
[email protected]7eecaed52009-05-07 21:44:12215 delegate_(delegate),
[email protected]811bfe32009-07-01 08:46:25216 url_(url),
[email protected]32dda362009-06-05 19:07:01217 ALLOW_THIS_IN_INITIALIZER_LIST(peer_(new Peer(this))) {
[email protected]9c45b7182009-08-04 16:44:43218 // TODO(erikkay) should we do something for these errors in Release?
219 DCHECK(url.SchemeIs(chrome::kExtensionScheme));
[email protected]35506352009-08-07 18:58:19220
221 Extension* extension =
222 profile()->GetExtensionsService()->GetExtensionByURL(url);
223 DCHECK(extension);
[email protected]9c45b7182009-08-04 16:44:43224
[email protected]811bfe32009-07-01 08:46:25225 all_instances()->insert(this);
[email protected]0f6053962009-07-09 19:26:35226
[email protected]45776222009-07-15 20:21:58227 // Notify the ExtensionProcessManager that the view was created.
228 ExtensionProcessManager* epm = profile()->GetExtensionProcessManager();
229 epm->RegisterExtensionProcess(extension_id(),
[email protected]76543b92009-08-31 17:27:45230 render_view_host->process()->id());
[email protected]35506352009-08-07 18:58:19231
232 // Update the extension permissions. Doing this each time we create an EFD
233 // ensures that new processes are informed of permissions for newly installed
234 // extensions.
[email protected]cccf90932009-08-23 17:56:25235 render_view_host->Send(new ViewMsg_Extension_SetAPIPermissions(
[email protected]35506352009-08-07 18:58:19236 extension->id(), extension->api_permissions()));
[email protected]cccf90932009-08-23 17:56:25237 render_view_host->Send(new ViewMsg_Extension_SetHostPermissions(
238 extension->url(), extension->host_permissions()));
[email protected]bfdffe2b2009-04-24 22:05:35239}
240
[email protected]32dda362009-06-05 19:07:01241ExtensionFunctionDispatcher::~ExtensionFunctionDispatcher() {
[email protected]811bfe32009-07-01 08:46:25242 all_instances()->erase(this);
[email protected]32dda362009-06-05 19:07:01243 peer_->dispatcher_ = NULL;
244}
245
[email protected]7eecaed52009-05-07 21:44:12246Browser* ExtensionFunctionDispatcher::GetBrowser() {
[email protected]4ba60e22009-08-14 21:02:11247 return delegate_->GetBrowser();
[email protected]7eecaed52009-05-07 21:44:12248}
249
[email protected]9c45b7182009-08-04 16:44:43250ExtensionHost* ExtensionFunctionDispatcher::GetExtensionHost() {
[email protected]9c45b7182009-08-04 16:44:43251 return delegate_->GetExtensionHost();
252}
253
[email protected]bfdffe2b2009-04-24 22:05:35254void ExtensionFunctionDispatcher::HandleRequest(const std::string& name,
255 const std::string& args,
[email protected]c6619182009-05-12 14:59:32256 int request_id,
257 bool has_callback) {
[email protected]32dda362009-06-05 19:07:01258 scoped_refptr<ExtensionFunction> function(
[email protected]bfdffe2b2009-04-24 22:05:35259 FactoryRegistry::instance()->NewFunction(name));
[email protected]32dda362009-06-05 19:07:01260 function->set_dispatcher_peer(peer_);
[email protected]b83e4602009-05-15 22:58:33261 function->SetArgs(args);
[email protected]c6619182009-05-12 14:59:32262 function->set_request_id(request_id);
263 function->set_has_callback(has_callback);
[email protected]bfdffe2b2009-04-24 22:05:35264 function->Run();
265}
266
[email protected]c6619182009-05-12 14:59:32267void ExtensionFunctionDispatcher::SendResponse(ExtensionFunction* function,
268 bool success) {
[email protected]c6619182009-05-12 14:59:32269 render_view_host_->SendExtensionResponse(function->request_id(), success,
[email protected]b83e4602009-05-15 22:58:33270 function->GetResult(), function->GetError());
[email protected]bfdffe2b2009-04-24 22:05:35271}
272
273void ExtensionFunctionDispatcher::HandleBadMessage(ExtensionFunction* api) {
[email protected]25fd1b2e2009-08-17 20:57:14274 LOG(ERROR) << "bad extension message " <<
[email protected]76543b92009-08-31 17:27:45275 api->name() <<
[email protected]bfdffe2b2009-04-24 22:05:35276 " : terminating renderer.";
277 if (RenderProcessHost::run_renderer_in_process()) {
278 // In single process mode it is better if we don't suicide but just crash.
279 CHECK(false);
280 } else {
281 NOTREACHED();
282 base::KillProcess(render_view_host_->process()->process().handle(),
283 ResultCodes::KILLED_BAD_MESSAGE, false);
284 }
285}
286
287Profile* ExtensionFunctionDispatcher::profile() {
288 return render_view_host_->process()->profile();
289}