blob: e486f89986c82cdf1d6e59187b4f3b364719987c [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]45776222009-07-15 20:21:5816#include "chrome/browser/extensions/extension_process_manager.h"
[email protected]bfdffe2b2009-04-24 22:05:3517#include "chrome/browser/extensions/extension_tabs_module.h"
[email protected]f93914852009-05-26 06:05:4018#include "chrome/browser/extensions/extension_tabs_module_constants.h"
[email protected]e916901c2009-05-07 00:14:3119#include "chrome/browser/profile.h"
[email protected]bfdffe2b2009-04-24 22:05:3520#include "chrome/browser/renderer_host/render_process_host.h"
21#include "chrome/browser/renderer_host/render_view_host.h"
22#include "chrome/common/result_codes.h"
23
24// FactoryRegistry -------------------------------------------------------------
25
26namespace {
27
[email protected]b83e4602009-05-15 22:58:3328// Template for defining ExtensionFunctionFactory.
29template<class T>
30ExtensionFunction* NewExtensionFunction() {
31 return new T();
32}
[email protected]bfdffe2b2009-04-24 22:05:3533
[email protected]b83e4602009-05-15 22:58:3334// Contains a list of all known extension functions and allows clients to
35// create instances of them.
[email protected]bfdffe2b2009-04-24 22:05:3536class FactoryRegistry {
37 public:
38 static FactoryRegistry* instance();
[email protected]b83e4602009-05-15 22:58:3339 FactoryRegistry() { ResetFunctions(); }
40
41 // Resets all functions to their default values.
42 void ResetFunctions();
43
44 // Adds all function names to 'names'.
[email protected]bfdffe2b2009-04-24 22:05:3545 void GetAllNames(std::vector<std::string>* names);
[email protected]b83e4602009-05-15 22:58:3346
47 // Allows overriding of specific functions (e.g. for testing). Functions
48 // must be previously registered. Returns true if successful.
49 bool OverrideFunction(const std::string& name,
50 ExtensionFunctionFactory factory);
51
52 // Factory method for the ExtensionFunction registered as 'name'.
[email protected]bfdffe2b2009-04-24 22:05:3553 ExtensionFunction* NewFunction(const std::string& name);
54
55 private:
56 typedef std::map<std::string, ExtensionFunctionFactory> FactoryMap;
57 FactoryMap factories_;
58};
59
[email protected]bfdffe2b2009-04-24 22:05:3560FactoryRegistry* FactoryRegistry::instance() {
61 return Singleton<FactoryRegistry>::get();
62}
63
[email protected]b83e4602009-05-15 22:58:3364void FactoryRegistry::ResetFunctions() {
[email protected]bfdffe2b2009-04-24 22:05:3565 // Register all functions here.
66
[email protected]f93914852009-05-26 06:05:4067 namespace tabs = extension_tabs_module_constants;
68 namespace page_actions = extension_page_actions_module_constants;
69 namespace bookmarks = extension_bookmarks_module_constants;
70
[email protected]e515f5d2009-05-05 03:05:0071 // Windows
[email protected]afac6fe2009-06-04 14:58:1872 factories_[tabs::kGetWindowFunction] =
[email protected]f93914852009-05-26 06:05:4073 &NewExtensionFunction<GetWindowFunction>;
74 factories_[tabs::kGetCurrentWindowFunction] =
[email protected]e515f5d2009-05-05 03:05:0075 &NewExtensionFunction<GetCurrentWindowFunction>;
[email protected]f93914852009-05-26 06:05:4076 factories_[tabs::kGetLastFocusedWindowFunction] =
[email protected]c6619182009-05-12 14:59:3277 &NewExtensionFunction<GetLastFocusedWindowFunction>;
[email protected]f93914852009-05-26 06:05:4078 factories_[tabs::kGetAllWindowsFunction] =
79 &NewExtensionFunction<GetAllWindowsFunction>;
[email protected]afac6fe2009-06-04 14:58:1880 factories_[tabs::kCreateWindowFunction] =
[email protected]f93914852009-05-26 06:05:4081 &NewExtensionFunction<CreateWindowFunction>;
[email protected]afac6fe2009-06-04 14:58:1882 factories_[tabs::kUpdateWindowFunction] =
[email protected]f93914852009-05-26 06:05:4083 &NewExtensionFunction<UpdateWindowFunction>;
[email protected]afac6fe2009-06-04 14:58:1884 factories_[tabs::kRemoveWindowFunction] =
[email protected]f93914852009-05-26 06:05:4085 &NewExtensionFunction<RemoveWindowFunction>;
[email protected]b83e4602009-05-15 22:58:3386
[email protected]e515f5d2009-05-05 03:05:0087 // Tabs
[email protected]afac6fe2009-06-04 14:58:1888 factories_[tabs::kGetTabFunction] =
[email protected]f93914852009-05-26 06:05:4089 &NewExtensionFunction<GetTabFunction>;
90 factories_[tabs::kGetSelectedTabFunction] =
[email protected]b83e4602009-05-15 22:58:3391 &NewExtensionFunction<GetSelectedTabFunction>;
[email protected]f93914852009-05-26 06:05:4092 factories_[tabs::kGetAllTabsInWindowFunction] =
[email protected]e515f5d2009-05-05 03:05:0093 &NewExtensionFunction<GetAllTabsInWindowFunction>;
[email protected]afac6fe2009-06-04 14:58:1894 factories_[tabs::kCreateTabFunction] =
[email protected]f93914852009-05-26 06:05:4095 &NewExtensionFunction<CreateTabFunction>;
[email protected]afac6fe2009-06-04 14:58:1896 factories_[tabs::kUpdateTabFunction] =
[email protected]f93914852009-05-26 06:05:4097 &NewExtensionFunction<UpdateTabFunction>;
[email protected]afac6fe2009-06-04 14:58:1898 factories_[tabs::kMoveTabFunction] =
[email protected]f93914852009-05-26 06:05:4099 &NewExtensionFunction<MoveTabFunction>;
[email protected]afac6fe2009-06-04 14:58:18100 factories_[tabs::kRemoveTabFunction] =
[email protected]f93914852009-05-26 06:05:40101 &NewExtensionFunction<RemoveTabFunction>;
[email protected]5c4266922009-07-10 16:41:27102 factories_[tabs::kGetTabLanguageFunction] =
103 &NewExtensionFunction<GetTabLanguageFunction>;
[email protected]bfdffe2b2009-04-24 22:05:35104
[email protected]f7f3a5f2009-05-01 22:02:34105 // Page Actions.
[email protected]f93914852009-05-26 06:05:40106 factories_[page_actions::kEnablePageActionFunction] =
[email protected]f7f3a5f2009-05-01 22:02:34107 &NewExtensionFunction<EnablePageActionFunction>;
[email protected]f9b1a7b2009-06-22 17:26:38108 factories_[page_actions::kDisablePageActionFunction] =
109 &NewExtensionFunction<DisablePageActionFunction>;
[email protected]f7f3a5f2009-05-01 22:02:34110
111 // Bookmarks.
[email protected]f93914852009-05-26 06:05:40112 factories_[bookmarks::kGetBookmarksFunction] =
113 &NewExtensionFunction<GetBookmarksFunction>;
114 factories_[bookmarks::kGetBookmarkChildrenFunction] =
[email protected]309934c42009-04-29 20:28:46115 &NewExtensionFunction<GetBookmarkChildrenFunction>;
[email protected]f93914852009-05-26 06:05:40116 factories_[bookmarks::kGetBookmarkTreeFunction] =
[email protected]309934c42009-04-29 20:28:46117 &NewExtensionFunction<GetBookmarkTreeFunction>;
[email protected]f93914852009-05-26 06:05:40118 factories_[bookmarks::kSearchBookmarksFunction] =
[email protected]bfdffe2b2009-04-24 22:05:35119 &NewExtensionFunction<SearchBookmarksFunction>;
[email protected]f93914852009-05-26 06:05:40120 factories_[bookmarks::kRemoveBookmarkFunction] =
[email protected]b83e4602009-05-15 22:58:33121 &NewExtensionFunction<RemoveBookmarkFunction>;
[email protected]f93914852009-05-26 06:05:40122 factories_[bookmarks::kCreateBookmarkFunction] =
[email protected]b83e4602009-05-15 22:58:33123 &NewExtensionFunction<CreateBookmarkFunction>;
[email protected]f93914852009-05-26 06:05:40124 factories_[bookmarks::kMoveBookmarkFunction] =
125 &NewExtensionFunction<MoveBookmarkFunction>;
126 factories_[bookmarks::kSetBookmarkTitleFunction] =
[email protected]bfdffe2b2009-04-24 22:05:35127 &NewExtensionFunction<SetBookmarkTitleFunction>;
128}
129
[email protected]b83e4602009-05-15 22:58:33130void FactoryRegistry::GetAllNames(std::vector<std::string>* names) {
131 for (FactoryMap::iterator iter = factories_.begin();
132 iter != factories_.end(); ++iter) {
[email protected]bfdffe2b2009-04-24 22:05:35133 names->push_back(iter->first);
134 }
135}
136
[email protected]b83e4602009-05-15 22:58:33137bool FactoryRegistry::OverrideFunction(const std::string& name,
138 ExtensionFunctionFactory factory) {
139 FactoryMap::iterator iter = factories_.find(name);
140 if (iter == factories_.end()) {
141 return false;
142 } else {
143 iter->second = factory;
144 return true;
145 }
146}
147
[email protected]bfdffe2b2009-04-24 22:05:35148ExtensionFunction* FactoryRegistry::NewFunction(const std::string& name) {
149 FactoryMap::iterator iter = factories_.find(name);
150 DCHECK(iter != factories_.end());
[email protected]b83e4602009-05-15 22:58:33151 ExtensionFunction* function = iter->second();
152 function->SetName(name);
153 return function;
[email protected]bfdffe2b2009-04-24 22:05:35154}
155
[email protected]b83e4602009-05-15 22:58:33156}; // namespace
[email protected]bfdffe2b2009-04-24 22:05:35157
158// ExtensionFunctionDispatcher -------------------------------------------------
159
160void ExtensionFunctionDispatcher::GetAllFunctionNames(
161 std::vector<std::string>* names) {
162 FactoryRegistry::instance()->GetAllNames(names);
163}
164
[email protected]b83e4602009-05-15 22:58:33165bool ExtensionFunctionDispatcher::OverrideFunction(
166 const std::string& name, ExtensionFunctionFactory factory) {
167 return FactoryRegistry::instance()->OverrideFunction(name, factory);
168}
169
170void ExtensionFunctionDispatcher::ResetFunctions() {
171 FactoryRegistry::instance()->ResetFunctions();
172}
173
[email protected]811bfe32009-07-01 08:46:25174std::set<ExtensionFunctionDispatcher*>*
175 ExtensionFunctionDispatcher::all_instances() {
176 static std::set<ExtensionFunctionDispatcher*> instances;
177 return &instances;
178}
179
[email protected]bfdffe2b2009-04-24 22:05:35180ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(
181 RenderViewHost* render_view_host,
[email protected]7eecaed52009-05-07 21:44:12182 Delegate* delegate,
[email protected]811bfe32009-07-01 08:46:25183 const GURL& url)
[email protected]bfdffe2b2009-04-24 22:05:35184 : render_view_host_(render_view_host),
[email protected]7eecaed52009-05-07 21:44:12185 delegate_(delegate),
[email protected]811bfe32009-07-01 08:46:25186 url_(url),
[email protected]32dda362009-06-05 19:07:01187 ALLOW_THIS_IN_INITIALIZER_LIST(peer_(new Peer(this))) {
[email protected]811bfe32009-07-01 08:46:25188 all_instances()->insert(this);
[email protected]0f6053962009-07-09 19:26:35189
190 // Ensure the message service is initialized.
191 ExtensionMessageService::GetInstance(profile()->GetRequestContext())->Init();
[email protected]45776222009-07-15 20:21:58192
193 // Notify the ExtensionProcessManager that the view was created.
194 ExtensionProcessManager* epm = profile()->GetExtensionProcessManager();
195 epm->RegisterExtensionProcess(extension_id(),
196 render_view_host->process()->pid());
[email protected]bfdffe2b2009-04-24 22:05:35197}
198
[email protected]32dda362009-06-05 19:07:01199ExtensionFunctionDispatcher::~ExtensionFunctionDispatcher() {
[email protected]811bfe32009-07-01 08:46:25200 all_instances()->erase(this);
[email protected]32dda362009-06-05 19:07:01201 peer_->dispatcher_ = NULL;
202}
203
[email protected]7eecaed52009-05-07 21:44:12204Browser* ExtensionFunctionDispatcher::GetBrowser() {
[email protected]b83e4602009-05-15 22:58:33205 DCHECK(delegate_);
206
[email protected]7eecaed52009-05-07 21:44:12207 Browser* retval = delegate_->GetBrowser();
[email protected]7eecaed52009-05-07 21:44:12208 return retval;
209}
210
[email protected]bfdffe2b2009-04-24 22:05:35211void ExtensionFunctionDispatcher::HandleRequest(const std::string& name,
212 const std::string& args,
[email protected]c6619182009-05-12 14:59:32213 int request_id,
214 bool has_callback) {
[email protected]32dda362009-06-05 19:07:01215 scoped_refptr<ExtensionFunction> function(
[email protected]bfdffe2b2009-04-24 22:05:35216 FactoryRegistry::instance()->NewFunction(name));
[email protected]32dda362009-06-05 19:07:01217 function->set_dispatcher_peer(peer_);
[email protected]b83e4602009-05-15 22:58:33218 function->SetArgs(args);
[email protected]c6619182009-05-12 14:59:32219 function->set_request_id(request_id);
220 function->set_has_callback(has_callback);
[email protected]bfdffe2b2009-04-24 22:05:35221 function->Run();
222}
223
[email protected]c6619182009-05-12 14:59:32224void ExtensionFunctionDispatcher::SendResponse(ExtensionFunction* function,
225 bool success) {
[email protected]c6619182009-05-12 14:59:32226 render_view_host_->SendExtensionResponse(function->request_id(), success,
[email protected]b83e4602009-05-15 22:58:33227 function->GetResult(), function->GetError());
[email protected]bfdffe2b2009-04-24 22:05:35228}
229
230void ExtensionFunctionDispatcher::HandleBadMessage(ExtensionFunction* api) {
231 LOG(ERROR) << "bad extension message " << // TODO(erikkay) name?
232 " : terminating renderer.";
233 if (RenderProcessHost::run_renderer_in_process()) {
234 // In single process mode it is better if we don't suicide but just crash.
235 CHECK(false);
236 } else {
237 NOTREACHED();
238 base::KillProcess(render_view_host_->process()->process().handle(),
239 ResultCodes::KILLED_BAD_MESSAGE, false);
240 }
241}
242
243Profile* ExtensionFunctionDispatcher::profile() {
244 return render_view_host_->process()->profile();
245}