blob: 2448f1b0ccf75fae764ca660232978edfe69a5ea [file] [log] [blame]
[email protected]14c3571a2013-11-13 00:18:441// Copyright 2013 The Chromium Authors. All rights reserved.
[email protected]703e807a2009-03-28 19:56:512// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]14c3571a2013-11-13 00:18:445#include "extensions/browser/extension_function.h"
[email protected]703e807a2009-03-28 19:56:516
[email protected]73404a372009-04-17 23:09:107#include "base/logging.h"
[email protected]86ab86b2011-10-19 03:07:558#include "content/public/browser/notification_source.h"
[email protected]0d6e9bd2011-10-18 04:29:169#include "content/public/browser/notification_types.h"
[email protected]6dd625e2013-12-20 17:03:0710#include "content/public/browser/render_frame_host.h"
[email protected]9c1662b2012-03-06 15:44:3311#include "content/public/browser/render_view_host.h"
[email protected]bc0ee242013-10-22 03:46:1412#include "content/public/browser/web_contents.h"
13#include "content/public/browser/web_contents_observer.h"
[email protected]0b9de032014-03-15 05:47:0114#include "extensions/browser/extension_function_dispatcher.h"
[email protected]1a0436892014-04-01 00:38:2515#include "extensions/browser/extension_message_filter.h"
[email protected]00afda7f2014-05-29 01:18:0816#include "extensions/common/error_utils.h"
[email protected]d6ec84a2013-11-01 13:07:3817#include "extensions/common/extension_api.h"
[email protected]fb820c02014-03-13 15:07:0818#include "extensions/common/extension_messages.h"
[email protected]c5dbef02011-05-13 05:06:0919
[email protected]631bb742011-11-02 11:29:3920using content::BrowserThread;
[email protected]eaabba22012-03-07 15:02:1121using content::RenderViewHost;
[email protected]bc0ee242013-10-22 03:46:1422using content::WebContents;
[email protected]00afda7f2014-05-29 01:18:0823using extensions::ErrorUtils;
[email protected]b5b26b72013-08-02 00:25:1124using extensions::ExtensionAPI;
25using extensions::Feature;
[email protected]631bb742011-11-02 11:29:3926
[email protected]f4e972d2014-04-24 22:55:5827namespace {
28
[email protected]32f22502014-05-20 21:31:4829class ArgumentListResponseValue
[email protected]f4e972d2014-04-24 22:55:5830 : public ExtensionFunction::ResponseValueObject {
31 public:
[email protected]32f22502014-05-20 21:31:4832 ArgumentListResponseValue(const std::string& function_name,
33 const char* title,
34 ExtensionFunction* function,
35 scoped_ptr<base::ListValue> result)
[email protected]e5be73a2014-05-15 00:12:3836 : function_name_(function_name), title_(title) {
[email protected]f4e972d2014-04-24 22:55:5837 if (function->GetResultList()) {
[email protected]32f22502014-05-20 21:31:4838 DCHECK_EQ(function->GetResultList(), result.get())
[email protected]e5be73a2014-05-15 00:12:3839 << "The result set on this function (" << function_name_ << ") "
40 << "either by calling SetResult() or directly modifying |result_| is "
41 << "different to the one passed to " << title_ << "(). "
42 << "The best way to fix this problem is to exclusively use " << title_
43 << "(). SetResult() and |result_| are deprecated.";
[email protected]f4e972d2014-04-24 22:55:5844 } else {
[email protected]32f22502014-05-20 21:31:4845 function->SetResultList(result.Pass());
[email protected]f4e972d2014-04-24 22:55:5846 }
[email protected]a0c91a9f2014-05-03 03:41:4347 // It would be nice to DCHECK(error.empty()) but some legacy extension
48 // function implementations... I'm looking at chrome.input.ime... do this
49 // for some reason.
[email protected]f4e972d2014-04-24 22:55:5850 }
51
[email protected]32f22502014-05-20 21:31:4852 virtual ~ArgumentListResponseValue() {}
[email protected]f4e972d2014-04-24 22:55:5853
mostynb0eac4e1b2014-10-03 16:32:1954 virtual bool Apply() override { return true; }
[email protected]e5be73a2014-05-15 00:12:3855
56 private:
57 std::string function_name_;
58 const char* title_;
[email protected]f4e972d2014-04-24 22:55:5859};
60
61class ErrorResponseValue : public ExtensionFunction::ResponseValueObject {
62 public:
63 ErrorResponseValue(ExtensionFunction* function, const std::string& error) {
[email protected]a0c91a9f2014-05-03 03:41:4364 // It would be nice to DCHECK(!error.empty()) but too many legacy extension
65 // function implementations don't set error but signal failure.
[email protected]f4e972d2014-04-24 22:55:5866 function->SetError(error);
67 }
68
69 virtual ~ErrorResponseValue() {}
70
mostynb0eac4e1b2014-10-03 16:32:1971 virtual bool Apply() override { return false; }
[email protected]f4e972d2014-04-24 22:55:5872};
73
74class BadMessageResponseValue : public ExtensionFunction::ResponseValueObject {
75 public:
76 explicit BadMessageResponseValue(ExtensionFunction* function) {
77 function->set_bad_message(true);
78 NOTREACHED() << function->name() << ": bad message";
79 }
80
81 virtual ~BadMessageResponseValue() {}
82
mostynb0eac4e1b2014-10-03 16:32:1983 virtual bool Apply() override { return false; }
[email protected]f4e972d2014-04-24 22:55:5884};
85
86class RespondNowAction : public ExtensionFunction::ResponseActionObject {
87 public:
88 typedef base::Callback<void(bool)> SendResponseCallback;
89 RespondNowAction(ExtensionFunction::ResponseValue result,
90 const SendResponseCallback& send_response)
91 : result_(result.Pass()), send_response_(send_response) {}
92 virtual ~RespondNowAction() {}
93
mostynb0eac4e1b2014-10-03 16:32:1994 virtual void Execute() override { send_response_.Run(result_->Apply()); }
[email protected]f4e972d2014-04-24 22:55:5895
96 private:
97 ExtensionFunction::ResponseValue result_;
98 SendResponseCallback send_response_;
99};
100
101class RespondLaterAction : public ExtensionFunction::ResponseActionObject {
102 public:
103 virtual ~RespondLaterAction() {}
104
mostynb0eac4e1b2014-10-03 16:32:19105 virtual void Execute() override {}
[email protected]f4e972d2014-04-24 22:55:58106};
107
108} // namespace
109
[email protected]a2aef2e2011-05-26 22:48:12110// static
111void ExtensionFunctionDeleteTraits::Destruct(const ExtensionFunction* x) {
112 x->Destruct();
113}
114
[email protected]6dd625e2013-12-20 17:03:07115// Helper class to track the lifetime of ExtensionFunction's RenderViewHost or
116// RenderFrameHost pointer and NULL it out when it dies. It also allows us to
117// filter IPC messages coming from the RenderViewHost/RenderFrameHost.
118class UIThreadExtensionFunction::RenderHostTracker
[email protected]bc0ee242013-10-22 03:46:14119 : public content::WebContentsObserver {
120 public:
[email protected]6dd625e2013-12-20 17:03:07121 explicit RenderHostTracker(UIThreadExtensionFunction* function)
[email protected]bc0ee242013-10-22 03:46:14122 : content::WebContentsObserver(
[email protected]eb7ef5f2014-02-06 09:59:19123 function->render_view_host() ?
[email protected]6dd625e2013-12-20 17:03:07124 WebContents::FromRenderViewHost(function->render_view_host()) :
125 WebContents::FromRenderFrameHost(
126 function->render_frame_host())),
[email protected]bc0ee242013-10-22 03:46:14127 function_(function) {
128 }
[email protected]942690b132010-05-11 06:42:14129
[email protected]bc0ee242013-10-22 03:46:14130 private:
131 // content::WebContentsObserver:
132 virtual void RenderViewDeleted(
mostynb0eac4e1b2014-10-03 16:32:19133 content::RenderViewHost* render_view_host) override {
[email protected]bc0ee242013-10-22 03:46:14134 if (render_view_host != function_->render_view_host())
135 return;
[email protected]ce0e2602013-03-15 20:53:27136
[email protected]bc0ee242013-10-22 03:46:14137 function_->SetRenderViewHost(NULL);
138 }
[email protected]6dd625e2013-12-20 17:03:07139 virtual void RenderFrameDeleted(
mostynb0eac4e1b2014-10-03 16:32:19140 content::RenderFrameHost* render_frame_host) override {
[email protected]6dd625e2013-12-20 17:03:07141 if (render_frame_host != function_->render_frame_host())
142 return;
143
144 function_->SetRenderFrameHost(NULL);
145 }
[email protected]0f7daaa2011-11-22 18:34:56146
[email protected]64ffefa2014-05-10 12:06:33147 virtual bool OnMessageReceived(
148 const IPC::Message& message,
mostynb0eac4e1b2014-10-03 16:32:19149 content::RenderFrameHost* render_frame_host) override {
[email protected]64ffefa2014-05-10 12:06:33150 DCHECK(render_frame_host);
151 if (render_frame_host == function_->render_frame_host())
152 return function_->OnMessageReceived(message);
153 else
154 return false;
155 }
156
mostynb0eac4e1b2014-10-03 16:32:19157 virtual bool OnMessageReceived(const IPC::Message& message) override {
[email protected]6dd625e2013-12-20 17:03:07158 return function_->OnMessageReceived(message);
[email protected]bc0ee242013-10-22 03:46:14159 }
160
161 UIThreadExtensionFunction* function_;
162
[email protected]6dd625e2013-12-20 17:03:07163 DISALLOW_COPY_AND_ASSIGN(RenderHostTracker);
[email protected]bc0ee242013-10-22 03:46:14164};
[email protected]0f7daaa2011-11-22 18:34:56165
[email protected]3a3d47472010-07-15 21:03:54166ExtensionFunction::ExtensionFunction()
[email protected]9931fbfc2010-07-23 09:15:51167 : request_id_(-1),
[email protected]637bf322011-10-01 20:46:32168 profile_id_(NULL),
[email protected]9931fbfc2010-07-23 09:15:51169 has_callback_(false),
[email protected]6451e332010-10-05 00:14:53170 include_incognito_(false),
[email protected]a2aef2e2011-05-26 22:48:12171 user_gesture_(false),
[email protected]07ad9622013-01-18 23:00:33172 bad_message_(false),
[email protected]eb7ef5f2014-02-06 09:59:19173 histogram_value_(extensions::functions::UNKNOWN),
[email protected]0239bc52014-08-07 07:27:19174 source_tab_id_(-1),
175 source_context_type_(Feature::UNSPECIFIED_CONTEXT) {
[email protected]eb7ef5f2014-02-06 09:59:19176}
[email protected]3a3d47472010-07-15 21:03:54177
178ExtensionFunction::~ExtensionFunction() {
179}
180
[email protected]2ad65b32011-05-26 23:39:20181UIThreadExtensionFunction* ExtensionFunction::AsUIThreadExtensionFunction() {
182 return NULL;
183}
184
[email protected]c357acb42011-06-09 20:52:42185IOThreadExtensionFunction* ExtensionFunction::AsIOThreadExtensionFunction() {
186 return NULL;
187}
188
[email protected]3d0e2262012-08-02 15:32:16189bool ExtensionFunction::HasPermission() {
[email protected]b5b26b72013-08-02 00:25:11190 Feature::Availability availability =
191 ExtensionAPI::GetSharedInstance()->IsAvailable(
dcheng7921e3f2014-08-25 22:20:01192 name_, extension_.get(), source_context_type_, source_url());
[email protected]b5b26b72013-08-02 00:25:11193 return availability.is_available();
[email protected]3d0e2262012-08-02 15:32:16194}
195
[email protected]85231d72012-08-31 09:45:29196void ExtensionFunction::OnQuotaExceeded(const std::string& violation_error) {
197 error_ = violation_error;
[email protected]fd50e7b2011-11-03 09:20:25198 SendResponse(false);
199}
200
[email protected]602542d2012-04-20 02:48:01201void ExtensionFunction::SetArgs(const base::ListValue* args) {
[email protected]30294edf2009-11-10 00:24:38202 DCHECK(!args_.get()); // Should only be called once.
[email protected]16f47e082011-01-18 02:16:59203 args_.reset(args->DeepCopy());
[email protected]b83e4602009-05-15 22:58:33204}
205
[email protected]07ff5fd2012-07-12 22:39:09206void ExtensionFunction::SetResult(base::Value* result) {
207 results_.reset(new base::ListValue());
208 results_->Append(result);
209}
210
[email protected]f4e972d2014-04-24 22:55:58211void ExtensionFunction::SetResultList(scoped_ptr<base::ListValue> results) {
212 results_ = results.Pass();
213}
214
215const base::ListValue* ExtensionFunction::GetResultList() const {
[email protected]07ff5fd2012-07-12 22:39:09216 return results_.get();
[email protected]637bf322011-10-01 20:46:32217}
218
[email protected]f4e972d2014-04-24 22:55:58219std::string ExtensionFunction::GetError() const {
[email protected]3a3d47472010-07-15 21:03:54220 return error_;
221}
222
[email protected]60aad9c2012-01-13 19:55:32223void ExtensionFunction::SetError(const std::string& error) {
224 error_ = error;
225}
226
[email protected]f4e972d2014-04-24 22:55:58227ExtensionFunction::ResponseValue ExtensionFunction::NoArguments() {
[email protected]32f22502014-05-20 21:31:48228 return ResponseValue(new ArgumentListResponseValue(
229 name(), "NoArguments", this, make_scoped_ptr(new base::ListValue())));
[email protected]f4e972d2014-04-24 22:55:58230}
231
[email protected]32f22502014-05-20 21:31:48232ExtensionFunction::ResponseValue ExtensionFunction::OneArgument(
[email protected]f4e972d2014-04-24 22:55:58233 base::Value* arg) {
[email protected]32f22502014-05-20 21:31:48234 scoped_ptr<base::ListValue> args(new base::ListValue());
[email protected]f4e972d2014-04-24 22:55:58235 args->Append(arg);
[email protected]e5be73a2014-05-15 00:12:38236 return ResponseValue(
[email protected]32f22502014-05-20 21:31:48237 new ArgumentListResponseValue(name(), "OneArgument", this, args.Pass()));
[email protected]f4e972d2014-04-24 22:55:58238}
239
[email protected]32f22502014-05-20 21:31:48240ExtensionFunction::ResponseValue ExtensionFunction::TwoArguments(
241 base::Value* arg1,
242 base::Value* arg2) {
243 scoped_ptr<base::ListValue> args(new base::ListValue());
244 args->Append(arg1);
245 args->Append(arg2);
246 return ResponseValue(
247 new ArgumentListResponseValue(name(), "TwoArguments", this, args.Pass()));
248}
249
250ExtensionFunction::ResponseValue ExtensionFunction::ArgumentList(
251 scoped_ptr<base::ListValue> args) {
252 return ResponseValue(
253 new ArgumentListResponseValue(name(), "ArgumentList", this, args.Pass()));
[email protected]f4e972d2014-04-24 22:55:58254}
255
256ExtensionFunction::ResponseValue ExtensionFunction::Error(
257 const std::string& error) {
[email protected]e5be73a2014-05-15 00:12:38258 return ResponseValue(new ErrorResponseValue(this, error));
[email protected]f4e972d2014-04-24 22:55:58259}
260
[email protected]00afda7f2014-05-29 01:18:08261ExtensionFunction::ResponseValue ExtensionFunction::Error(
262 const std::string& format,
263 const std::string& s1) {
264 return ResponseValue(
265 new ErrorResponseValue(this, ErrorUtils::FormatErrorMessage(format, s1)));
266}
267
268ExtensionFunction::ResponseValue ExtensionFunction::Error(
269 const std::string& format,
270 const std::string& s1,
271 const std::string& s2) {
272 return ResponseValue(new ErrorResponseValue(
273 this, ErrorUtils::FormatErrorMessage(format, s1, s2)));
274}
275
276ExtensionFunction::ResponseValue ExtensionFunction::Error(
277 const std::string& format,
278 const std::string& s1,
279 const std::string& s2,
280 const std::string& s3) {
281 return ResponseValue(new ErrorResponseValue(
282 this, ErrorUtils::FormatErrorMessage(format, s1, s2, s3)));
283}
284
[email protected]f4e972d2014-04-24 22:55:58285ExtensionFunction::ResponseValue ExtensionFunction::BadMessage() {
[email protected]e5be73a2014-05-15 00:12:38286 return ResponseValue(new BadMessageResponseValue(this));
[email protected]f4e972d2014-04-24 22:55:58287}
288
289ExtensionFunction::ResponseAction ExtensionFunction::RespondNow(
290 ResponseValue result) {
[email protected]5b50d882014-05-09 11:37:30291 return ResponseAction(new RespondNowAction(
[email protected]f4e972d2014-04-24 22:55:58292 result.Pass(), base::Bind(&ExtensionFunction::SendResponse, this)));
293}
294
295ExtensionFunction::ResponseAction ExtensionFunction::RespondLater() {
[email protected]5b50d882014-05-09 11:37:30296 return ResponseAction(new RespondLaterAction());
297}
298
299// static
300ExtensionFunction::ResponseAction ExtensionFunction::ValidationFailure(
301 ExtensionFunction* function) {
302 return function->RespondNow(function->BadMessage());
[email protected]f4e972d2014-04-24 22:55:58303}
304
[email protected]a0c91a9f2014-05-03 03:41:43305void ExtensionFunction::Respond(ResponseValue result) {
306 SendResponse(result->Apply());
[email protected]f4e972d2014-04-24 22:55:58307}
308
[email protected]712627bf2012-04-30 03:21:04309bool ExtensionFunction::ShouldSkipQuotaLimiting() const {
310 return false;
311}
312
[email protected]a2aef2e2011-05-26 22:48:12313bool ExtensionFunction::HasOptionalArgument(size_t index) {
[email protected]4b3006f2013-12-23 22:23:08314 base::Value* value;
315 return args_->Get(index, &value) && !value->IsType(base::Value::TYPE_NULL);
[email protected]a2aef2e2011-05-26 22:48:12316}
317
[email protected]35548ab2013-05-15 08:59:47318void ExtensionFunction::SendResponseImpl(bool success) {
319 DCHECK(!response_callback_.is_null());
320
321 ResponseType type = success ? SUCCEEDED : FAILED;
[email protected]c357acb42011-06-09 20:52:42322 if (bad_message_) {
[email protected]35548ab2013-05-15 08:59:47323 type = BAD_MESSAGE;
324 LOG(ERROR) << "Bad extension message " << name_;
[email protected]c357acb42011-06-09 20:52:42325 }
326
[email protected]07ff5fd2012-07-12 22:39:09327 // If results were never set, we send an empty argument list.
[email protected]3eeddd892013-04-17 17:00:11328 if (!results_)
[email protected]aeca23f2013-06-21 22:34:41329 results_.reset(new base::ListValue());
[email protected]602542d2012-04-20 02:48:01330
[email protected]35548ab2013-05-15 08:59:47331 response_callback_.Run(type, *results_, GetError());
[email protected]c357acb42011-06-09 20:52:42332}
333
[email protected]a0c91a9f2014-05-03 03:41:43334void ExtensionFunction::OnRespondingLater(ResponseValue value) {
335 SendResponse(value->Apply());
336}
337
[email protected]a2aef2e2011-05-26 22:48:12338UIThreadExtensionFunction::UIThreadExtensionFunction()
[email protected]eb7ef5f2014-02-06 09:59:19339 : render_view_host_(NULL),
340 render_frame_host_(NULL),
341 context_(NULL),
342 delegate_(NULL) {
343}
[email protected]a2aef2e2011-05-26 22:48:12344
345UIThreadExtensionFunction::~UIThreadExtensionFunction() {
[email protected]7042b682012-04-19 22:57:51346 if (dispatcher() && render_view_host())
[email protected]eba8f7d2014-07-28 22:09:23347 dispatcher()->OnExtensionFunctionCompleted(extension());
[email protected]a2aef2e2011-05-26 22:48:12348}
349
[email protected]2ad65b32011-05-26 23:39:20350UIThreadExtensionFunction*
351UIThreadExtensionFunction::AsUIThreadExtensionFunction() {
352 return this;
353}
354
[email protected]6dd625e2013-12-20 17:03:07355bool UIThreadExtensionFunction::OnMessageReceived(const IPC::Message& message) {
[email protected]0f7daaa2011-11-22 18:34:56356 return false;
357}
358
[email protected]a2aef2e2011-05-26 22:48:12359void UIThreadExtensionFunction::Destruct() const {
360 BrowserThread::DeleteOnUIThread::Destruct(this);
361}
362
363void UIThreadExtensionFunction::SetRenderViewHost(
364 RenderViewHost* render_view_host) {
[email protected]6dd625e2013-12-20 17:03:07365 DCHECK(!render_frame_host_);
[email protected]a2aef2e2011-05-26 22:48:12366 render_view_host_ = render_view_host;
[email protected]6dd625e2013-12-20 17:03:07367 tracker_.reset(render_view_host ? new RenderHostTracker(this) : NULL);
368}
369
370void UIThreadExtensionFunction::SetRenderFrameHost(
371 content::RenderFrameHost* render_frame_host) {
372 DCHECK(!render_view_host_);
373 render_frame_host_ = render_frame_host;
374 tracker_.reset(render_frame_host ? new RenderHostTracker(this) : NULL);
[email protected]a2aef2e2011-05-26 22:48:12375}
376
[email protected]91e51d612012-10-21 23:03:05377content::WebContents* UIThreadExtensionFunction::GetAssociatedWebContents() {
[email protected]21a40082013-10-28 21:19:23378 content::WebContents* web_contents = NULL;
379 if (dispatcher())
380 web_contents = dispatcher()->delegate()->GetAssociatedWebContents();
[email protected]91e51d612012-10-21 23:03:05381
[email protected]21a40082013-10-28 21:19:23382 return web_contents;
[email protected]a2aef2e2011-05-26 22:48:12383}
384
385void UIThreadExtensionFunction::SendResponse(bool success) {
[email protected]35548ab2013-05-15 08:59:47386 if (delegate_)
[email protected]ca6df682012-04-10 23:00:20387 delegate_->OnSendResponse(this, success, bad_message_);
[email protected]35548ab2013-05-15 08:59:47388 else
389 SendResponseImpl(success);
[email protected]c0b5eb02014-06-02 17:28:10390
391 if (!transferred_blob_uuids_.empty()) {
392 DCHECK(!delegate_) << "Blob transfer not supported with test delegate.";
393 GetIPCSender()->Send(
394 new ExtensionMsg_TransferBlobs(transferred_blob_uuids_));
395 }
396}
397
398void UIThreadExtensionFunction::SetTransferredBlobUUIDs(
399 const std::vector<std::string>& blob_uuids) {
400 DCHECK(transferred_blob_uuids_.empty()); // Should only be called once.
401 transferred_blob_uuids_ = blob_uuids;
[email protected]c5dbef02011-05-13 05:06:09402}
403
[email protected]c6970072013-01-10 02:59:43404void UIThreadExtensionFunction::WriteToConsole(
405 content::ConsoleMessageLevel level,
406 const std::string& message) {
[email protected]c0b5eb02014-06-02 17:28:10407 GetIPCSender()->Send(
408 new ExtensionMsg_AddMessageToConsole(GetRoutingID(), level, message));
409}
410
411IPC::Sender* UIThreadExtensionFunction::GetIPCSender() {
412 if (render_view_host_)
413 return render_view_host_;
414 else
415 return render_frame_host_;
416}
417
418int UIThreadExtensionFunction::GetRoutingID() {
419 if (render_view_host_)
420 return render_view_host_->GetRoutingID();
421 else
422 return render_frame_host_->GetRoutingID();
[email protected]c6970072013-01-10 02:59:43423}
424
[email protected]44295a12013-06-05 08:45:46425IOThreadExtensionFunction::IOThreadExtensionFunction()
426 : routing_id_(MSG_ROUTING_NONE) {
[email protected]c357acb42011-06-09 20:52:42427}
428
429IOThreadExtensionFunction::~IOThreadExtensionFunction() {
430}
431
432IOThreadExtensionFunction*
433IOThreadExtensionFunction::AsIOThreadExtensionFunction() {
434 return this;
435}
436
437void IOThreadExtensionFunction::Destruct() const {
438 BrowserThread::DeleteOnIOThread::Destruct(this);
439}
440
441void IOThreadExtensionFunction::SendResponse(bool success) {
[email protected]35548ab2013-05-15 08:59:47442 SendResponseImpl(success);
[email protected]703e807a2009-03-28 19:56:51443}
[email protected]73404a372009-04-17 23:09:10444
[email protected]bdfc03e2011-11-22 00:20:33445AsyncExtensionFunction::AsyncExtensionFunction() {
[email protected]a2aef2e2011-05-26 22:48:12446}
447
448AsyncExtensionFunction::~AsyncExtensionFunction() {
[email protected]35213ce92010-04-08 19:06:15449}
[email protected]3a3d47472010-07-15 21:03:54450
[email protected]a0c91a9f2014-05-03 03:41:43451ExtensionFunction::ResponseAction AsyncExtensionFunction::Run() {
452 return RunAsync() ? RespondLater() : RespondNow(Error(error_));
453}
454
[email protected]5b50d882014-05-09 11:37:30455// static
456bool AsyncExtensionFunction::ValidationFailure(
457 AsyncExtensionFunction* function) {
458 return false;
459}
460
[email protected]3a3d47472010-07-15 21:03:54461SyncExtensionFunction::SyncExtensionFunction() {
462}
463
464SyncExtensionFunction::~SyncExtensionFunction() {
465}
466
[email protected]a0c91a9f2014-05-03 03:41:43467ExtensionFunction::ResponseAction SyncExtensionFunction::Run() {
[email protected]32f22502014-05-20 21:31:48468 return RespondNow(RunSync() ? ArgumentList(results_.Pass()) : Error(error_));
[email protected]3a3d47472010-07-15 21:03:54469}
[email protected]c357acb42011-06-09 20:52:42470
[email protected]5b50d882014-05-09 11:37:30471// static
472bool SyncExtensionFunction::ValidationFailure(SyncExtensionFunction* function) {
473 return false;
474}
475
[email protected]c357acb42011-06-09 20:52:42476SyncIOThreadExtensionFunction::SyncIOThreadExtensionFunction() {
477}
478
479SyncIOThreadExtensionFunction::~SyncIOThreadExtensionFunction() {
480}
481
[email protected]a0c91a9f2014-05-03 03:41:43482ExtensionFunction::ResponseAction SyncIOThreadExtensionFunction::Run() {
[email protected]32f22502014-05-20 21:31:48483 return RespondNow(RunSync() ? ArgumentList(results_.Pass()) : Error(error_));
[email protected]c357acb42011-06-09 20:52:42484}
[email protected]5b50d882014-05-09 11:37:30485
486// static
487bool SyncIOThreadExtensionFunction::ValidationFailure(
488 SyncIOThreadExtensionFunction* function) {
489 return false;
490}