blob: 93a34db8dc5288bf8b273b6d1e67d0219351dc66 [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]e916901c2009-05-07 00:14:3113#include "chrome/browser/extensions/extension_message_service.h"
[email protected]f7f3a5f2009-05-01 22:02:3414#include "chrome/browser/extensions/extension_page_actions_module.h"
[email protected]f93914852009-05-26 06:05:4015#include "chrome/browser/extensions/extension_page_actions_module_constants.h"
[email protected]bfdffe2b2009-04-24 22:05:3516#include "chrome/browser/extensions/extension_tabs_module.h"
[email protected]f93914852009-05-26 06:05:4017#include "chrome/browser/extensions/extension_tabs_module_constants.h"
[email protected]e916901c2009-05-07 00:14:3118#include "chrome/browser/profile.h"
[email protected]bfdffe2b2009-04-24 22:05:3519#include "chrome/browser/renderer_host/render_process_host.h"
20#include "chrome/browser/renderer_host/render_view_host.h"
21#include "chrome/common/result_codes.h"
22
23// FactoryRegistry -------------------------------------------------------------
24
25namespace {
26
[email protected]b83e4602009-05-15 22:58:3327// Template for defining ExtensionFunctionFactory.
28template<class T>
29ExtensionFunction* NewExtensionFunction() {
30 return new T();
31}
[email protected]bfdffe2b2009-04-24 22:05:3532
[email protected]b83e4602009-05-15 22:58:3333// Contains a list of all known extension functions and allows clients to
34// create instances of them.
[email protected]bfdffe2b2009-04-24 22:05:3535class FactoryRegistry {
36 public:
37 static FactoryRegistry* instance();
[email protected]b83e4602009-05-15 22:58:3338 FactoryRegistry() { ResetFunctions(); }
39
40 // Resets all functions to their default values.
41 void ResetFunctions();
42
43 // Adds all function names to 'names'.
[email protected]bfdffe2b2009-04-24 22:05:3544 void GetAllNames(std::vector<std::string>* names);
[email protected]b83e4602009-05-15 22:58:3345
46 // Allows overriding of specific functions (e.g. for testing). Functions
47 // must be previously registered. Returns true if successful.
48 bool OverrideFunction(const std::string& name,
49 ExtensionFunctionFactory factory);
50
51 // Factory method for the ExtensionFunction registered as 'name'.
[email protected]bfdffe2b2009-04-24 22:05:3552 ExtensionFunction* NewFunction(const std::string& name);
53
54 private:
55 typedef std::map<std::string, ExtensionFunctionFactory> FactoryMap;
56 FactoryMap factories_;
57};
58
[email protected]bfdffe2b2009-04-24 22:05:3559FactoryRegistry* FactoryRegistry::instance() {
60 return Singleton<FactoryRegistry>::get();
61}
62
[email protected]b83e4602009-05-15 22:58:3363void FactoryRegistry::ResetFunctions() {
[email protected]bfdffe2b2009-04-24 22:05:3564 // Register all functions here.
65
[email protected]f93914852009-05-26 06:05:4066 namespace tabs = extension_tabs_module_constants;
67 namespace page_actions = extension_page_actions_module_constants;
68 namespace bookmarks = extension_bookmarks_module_constants;
69
[email protected]e515f5d2009-05-05 03:05:0070 // Windows
[email protected]afac6fe2009-06-04 14:58:1871 factories_[tabs::kGetWindowFunction] =
[email protected]f93914852009-05-26 06:05:4072 &NewExtensionFunction<GetWindowFunction>;
73 factories_[tabs::kGetCurrentWindowFunction] =
[email protected]e515f5d2009-05-05 03:05:0074 &NewExtensionFunction<GetCurrentWindowFunction>;
[email protected]f93914852009-05-26 06:05:4075 factories_[tabs::kGetLastFocusedWindowFunction] =
[email protected]c6619182009-05-12 14:59:3276 &NewExtensionFunction<GetLastFocusedWindowFunction>;
[email protected]f93914852009-05-26 06:05:4077 factories_[tabs::kGetAllWindowsFunction] =
78 &NewExtensionFunction<GetAllWindowsFunction>;
[email protected]afac6fe2009-06-04 14:58:1879 factories_[tabs::kCreateWindowFunction] =
[email protected]f93914852009-05-26 06:05:4080 &NewExtensionFunction<CreateWindowFunction>;
[email protected]afac6fe2009-06-04 14:58:1881 factories_[tabs::kUpdateWindowFunction] =
[email protected]f93914852009-05-26 06:05:4082 &NewExtensionFunction<UpdateWindowFunction>;
[email protected]afac6fe2009-06-04 14:58:1883 factories_[tabs::kRemoveWindowFunction] =
[email protected]f93914852009-05-26 06:05:4084 &NewExtensionFunction<RemoveWindowFunction>;
[email protected]b83e4602009-05-15 22:58:3385
[email protected]e515f5d2009-05-05 03:05:0086 // Tabs
[email protected]afac6fe2009-06-04 14:58:1887 factories_[tabs::kGetTabFunction] =
[email protected]f93914852009-05-26 06:05:4088 &NewExtensionFunction<GetTabFunction>;
89 factories_[tabs::kGetSelectedTabFunction] =
[email protected]b83e4602009-05-15 22:58:3390 &NewExtensionFunction<GetSelectedTabFunction>;
[email protected]f93914852009-05-26 06:05:4091 factories_[tabs::kGetAllTabsInWindowFunction] =
[email protected]e515f5d2009-05-05 03:05:0092 &NewExtensionFunction<GetAllTabsInWindowFunction>;
[email protected]afac6fe2009-06-04 14:58:1893 factories_[tabs::kCreateTabFunction] =
[email protected]f93914852009-05-26 06:05:4094 &NewExtensionFunction<CreateTabFunction>;
[email protected]afac6fe2009-06-04 14:58:1895 factories_[tabs::kUpdateTabFunction] =
[email protected]f93914852009-05-26 06:05:4096 &NewExtensionFunction<UpdateTabFunction>;
[email protected]afac6fe2009-06-04 14:58:1897 factories_[tabs::kMoveTabFunction] =
[email protected]f93914852009-05-26 06:05:4098 &NewExtensionFunction<MoveTabFunction>;
[email protected]afac6fe2009-06-04 14:58:1899 factories_[tabs::kRemoveTabFunction] =
[email protected]f93914852009-05-26 06:05:40100 &NewExtensionFunction<RemoveTabFunction>;
[email protected]bfdffe2b2009-04-24 22:05:35101
[email protected]f7f3a5f2009-05-01 22:02:34102 // Page Actions.
[email protected]f93914852009-05-26 06:05:40103 factories_[page_actions::kEnablePageActionFunction] =
[email protected]f7f3a5f2009-05-01 22:02:34104 &NewExtensionFunction<EnablePageActionFunction>;
105
106 // Bookmarks.
[email protected]f93914852009-05-26 06:05:40107 factories_[bookmarks::kGetBookmarksFunction] =
108 &NewExtensionFunction<GetBookmarksFunction>;
109 factories_[bookmarks::kGetBookmarkChildrenFunction] =
[email protected]309934c42009-04-29 20:28:46110 &NewExtensionFunction<GetBookmarkChildrenFunction>;
[email protected]f93914852009-05-26 06:05:40111 factories_[bookmarks::kGetBookmarkTreeFunction] =
[email protected]309934c42009-04-29 20:28:46112 &NewExtensionFunction<GetBookmarkTreeFunction>;
[email protected]f93914852009-05-26 06:05:40113 factories_[bookmarks::kSearchBookmarksFunction] =
[email protected]bfdffe2b2009-04-24 22:05:35114 &NewExtensionFunction<SearchBookmarksFunction>;
[email protected]f93914852009-05-26 06:05:40115 factories_[bookmarks::kRemoveBookmarkFunction] =
[email protected]b83e4602009-05-15 22:58:33116 &NewExtensionFunction<RemoveBookmarkFunction>;
[email protected]f93914852009-05-26 06:05:40117 factories_[bookmarks::kCreateBookmarkFunction] =
[email protected]b83e4602009-05-15 22:58:33118 &NewExtensionFunction<CreateBookmarkFunction>;
[email protected]f93914852009-05-26 06:05:40119 factories_[bookmarks::kMoveBookmarkFunction] =
120 &NewExtensionFunction<MoveBookmarkFunction>;
121 factories_[bookmarks::kSetBookmarkTitleFunction] =
[email protected]bfdffe2b2009-04-24 22:05:35122 &NewExtensionFunction<SetBookmarkTitleFunction>;
123}
124
[email protected]b83e4602009-05-15 22:58:33125void FactoryRegistry::GetAllNames(std::vector<std::string>* names) {
126 for (FactoryMap::iterator iter = factories_.begin();
127 iter != factories_.end(); ++iter) {
[email protected]bfdffe2b2009-04-24 22:05:35128 names->push_back(iter->first);
129 }
130}
131
[email protected]b83e4602009-05-15 22:58:33132bool FactoryRegistry::OverrideFunction(const std::string& name,
133 ExtensionFunctionFactory factory) {
134 FactoryMap::iterator iter = factories_.find(name);
135 if (iter == factories_.end()) {
136 return false;
137 } else {
138 iter->second = factory;
139 return true;
140 }
141}
142
[email protected]bfdffe2b2009-04-24 22:05:35143ExtensionFunction* FactoryRegistry::NewFunction(const std::string& name) {
144 FactoryMap::iterator iter = factories_.find(name);
145 DCHECK(iter != factories_.end());
[email protected]b83e4602009-05-15 22:58:33146 ExtensionFunction* function = iter->second();
147 function->SetName(name);
148 return function;
[email protected]bfdffe2b2009-04-24 22:05:35149}
150
[email protected]b83e4602009-05-15 22:58:33151}; // namespace
[email protected]bfdffe2b2009-04-24 22:05:35152
153// ExtensionFunctionDispatcher -------------------------------------------------
154
155void ExtensionFunctionDispatcher::GetAllFunctionNames(
156 std::vector<std::string>* names) {
157 FactoryRegistry::instance()->GetAllNames(names);
158}
159
[email protected]b83e4602009-05-15 22:58:33160bool ExtensionFunctionDispatcher::OverrideFunction(
161 const std::string& name, ExtensionFunctionFactory factory) {
162 return FactoryRegistry::instance()->OverrideFunction(name, factory);
163}
164
165void ExtensionFunctionDispatcher::ResetFunctions() {
166 FactoryRegistry::instance()->ResetFunctions();
167}
168
[email protected]bfdffe2b2009-04-24 22:05:35169ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(
170 RenderViewHost* render_view_host,
[email protected]7eecaed52009-05-07 21:44:12171 Delegate* delegate,
[email protected]bfdffe2b2009-04-24 22:05:35172 const std::string& extension_id)
173 : render_view_host_(render_view_host),
[email protected]7eecaed52009-05-07 21:44:12174 delegate_(delegate),
[email protected]bfdffe2b2009-04-24 22:05:35175 extension_id_(extension_id) {
[email protected]e916901c2009-05-07 00:14:31176 RenderProcessHost* process = render_view_host_->process();
[email protected]b83e4602009-05-15 22:58:33177 ExtensionMessageService* message_service =
[email protected]e916901c2009-05-07 00:14:31178 ExtensionMessageService::GetInstance(profile()->GetRequestContext());
179 DCHECK(process);
180 DCHECK(message_service);
181 message_service->RegisterExtension(extension_id, process->pid());
[email protected]bfdffe2b2009-04-24 22:05:35182}
183
[email protected]7eecaed52009-05-07 21:44:12184Browser* ExtensionFunctionDispatcher::GetBrowser() {
[email protected]b83e4602009-05-15 22:58:33185 DCHECK(delegate_);
186
[email protected]7eecaed52009-05-07 21:44:12187 Browser* retval = delegate_->GetBrowser();
[email protected]7eecaed52009-05-07 21:44:12188 return retval;
189}
190
[email protected]bfdffe2b2009-04-24 22:05:35191void ExtensionFunctionDispatcher::HandleRequest(const std::string& name,
192 const std::string& args,
[email protected]c6619182009-05-12 14:59:32193 int request_id,
194 bool has_callback) {
[email protected]bfdffe2b2009-04-24 22:05:35195 // TODO(aa): This will get a bit more complicated when we support functions
196 // that live longer than the stack frame.
197 scoped_ptr<ExtensionFunction> function(
198 FactoryRegistry::instance()->NewFunction(name));
199 function->set_dispatcher(this);
[email protected]b83e4602009-05-15 22:58:33200 function->SetArgs(args);
[email protected]c6619182009-05-12 14:59:32201 function->set_request_id(request_id);
202 function->set_has_callback(has_callback);
[email protected]bfdffe2b2009-04-24 22:05:35203 function->Run();
204}
205
[email protected]c6619182009-05-12 14:59:32206void ExtensionFunctionDispatcher::SendResponse(ExtensionFunction* function,
207 bool success) {
[email protected]c6619182009-05-12 14:59:32208 render_view_host_->SendExtensionResponse(function->request_id(), success,
[email protected]b83e4602009-05-15 22:58:33209 function->GetResult(), function->GetError());
[email protected]bfdffe2b2009-04-24 22:05:35210}
211
212void ExtensionFunctionDispatcher::HandleBadMessage(ExtensionFunction* api) {
213 LOG(ERROR) << "bad extension message " << // TODO(erikkay) name?
214 " : terminating renderer.";
215 if (RenderProcessHost::run_renderer_in_process()) {
216 // In single process mode it is better if we don't suicide but just crash.
217 CHECK(false);
218 } else {
219 NOTREACHED();
220 base::KillProcess(render_view_host_->process()->process().handle(),
221 ResultCodes::KILLED_BAD_MESSAGE, false);
222 }
223}
224
225Profile* ExtensionFunctionDispatcher::profile() {
226 return render_view_host_->process()->profile();
227}