OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "extensions/browser/extension_function.h" | 5 #include "extensions/browser/extension_function.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 histogram_value); | 72 histogram_value); |
73 } | 73 } |
74 UMA_HISTOGRAM_TIMES("Extensions.Functions.FailedTotalExecutionTime", | 74 UMA_HISTOGRAM_TIMES("Extensions.Functions.FailedTotalExecutionTime", |
75 elapsed_time); | 75 elapsed_time); |
76 } | 76 } |
77 } | 77 } |
78 | 78 |
79 class ArgumentListResponseValue | 79 class ArgumentListResponseValue |
80 : public ExtensionFunction::ResponseValueObject { | 80 : public ExtensionFunction::ResponseValueObject { |
81 public: | 81 public: |
82 ArgumentListResponseValue(const std::string& function_name, | 82 ArgumentListResponseValue(ExtensionFunction* function, |
83 const char* title, | 83 std::unique_ptr<base::ListValue> result) { |
84 ExtensionFunction* function, | 84 SetFunctionResults(function, std::move(result)); |
85 std::unique_ptr<base::ListValue> result) | |
86 : function_name_(function_name), title_(title) { | |
87 if (function->GetResultList()) { | |
88 DCHECK_EQ(function->GetResultList(), result.get()) | |
89 << "The result set on this function (" << function_name_ << ") " | |
90 << "either by calling SetResult() or directly modifying |result_| is " | |
91 << "different to the one passed to " << title_ << "(). " | |
92 << "The best way to fix this problem is to exclusively use " << title_ | |
93 << "(). SetResult() and |result_| are deprecated."; | |
94 } else { | |
95 function->SetResultList(std::move(result)); | |
96 } | |
97 // It would be nice to DCHECK(error.empty()) but some legacy extension | 85 // It would be nice to DCHECK(error.empty()) but some legacy extension |
98 // function implementations... I'm looking at chrome.input.ime... do this | 86 // function implementations... I'm looking at chrome.input.ime... do this |
99 // for some reason. | 87 // for some reason. |
100 } | 88 } |
101 | 89 |
102 ~ArgumentListResponseValue() override {} | 90 ~ArgumentListResponseValue() override {} |
103 | 91 |
104 bool Apply() override { return true; } | 92 bool Apply() override { return true; } |
105 | |
106 private: | |
107 std::string function_name_; | |
108 const char* title_; | |
109 }; | 93 }; |
110 | 94 |
111 class ErrorWithArgumentsResponseValue : public ArgumentListResponseValue { | 95 class ErrorWithArgumentsResponseValue : public ArgumentListResponseValue { |
112 public: | 96 public: |
113 ErrorWithArgumentsResponseValue(const std::string& function_name, | 97 ErrorWithArgumentsResponseValue(ExtensionFunction* function, |
114 const char* title, | |
115 ExtensionFunction* function, | |
116 std::unique_ptr<base::ListValue> result, | 98 std::unique_ptr<base::ListValue> result, |
117 const std::string& error) | 99 const std::string& error) |
118 : ArgumentListResponseValue(function_name, | 100 : ArgumentListResponseValue(function, std::move(result)) { |
119 title, | 101 SetFunctionError(function, error); |
120 function, | |
121 std::move(result)) { | |
122 function->SetError(error); | |
123 } | 102 } |
124 | 103 |
125 ~ErrorWithArgumentsResponseValue() override {} | 104 ~ErrorWithArgumentsResponseValue() override {} |
126 | 105 |
127 bool Apply() override { return false; } | 106 bool Apply() override { return false; } |
128 }; | 107 }; |
129 | 108 |
130 class ErrorResponseValue : public ExtensionFunction::ResponseValueObject { | 109 class ErrorResponseValue : public ExtensionFunction::ResponseValueObject { |
131 public: | 110 public: |
132 ErrorResponseValue(ExtensionFunction* function, const std::string& error) { | 111 ErrorResponseValue(ExtensionFunction* function, const std::string& error) { |
133 // It would be nice to DCHECK(!error.empty()) but too many legacy extension | 112 // It would be nice to DCHECK(!error.empty()) but too many legacy extension |
134 // function implementations don't set error but signal failure. | 113 // function implementations don't set error but signal failure. |
135 function->SetError(error); | 114 SetFunctionError(function, error); |
136 } | 115 } |
137 | 116 |
138 ~ErrorResponseValue() override {} | 117 ~ErrorResponseValue() override {} |
139 | 118 |
140 bool Apply() override { return false; } | 119 bool Apply() override { return false; } |
141 }; | 120 }; |
142 | 121 |
143 class BadMessageResponseValue : public ExtensionFunction::ResponseValueObject { | 122 class BadMessageResponseValue : public ExtensionFunction::ResponseValueObject { |
144 public: | 123 public: |
145 explicit BadMessageResponseValue(ExtensionFunction* function) { | 124 explicit BadMessageResponseValue(ExtensionFunction* function) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 } | 193 } |
215 | 194 |
216 void UserGestureForTests::DecrementCount() { | 195 void UserGestureForTests::DecrementCount() { |
217 base::AutoLock autolock(lock_); | 196 base::AutoLock autolock(lock_); |
218 --count_; | 197 --count_; |
219 } | 198 } |
220 | 199 |
221 | 200 |
222 } // namespace | 201 } // namespace |
223 | 202 |
| 203 void ExtensionFunction::ResponseValueObject::SetFunctionResults( |
| 204 ExtensionFunction* function, |
| 205 std::unique_ptr<base::ListValue> results) { |
| 206 DCHECK(!function->results_) << "Function " << function->name_ |
| 207 << "already has results set."; |
| 208 function->results_ = std::move(results); |
| 209 } |
| 210 |
| 211 void ExtensionFunction::ResponseValueObject::SetFunctionError( |
| 212 ExtensionFunction* function, |
| 213 const std::string& error) { |
| 214 DCHECK(function->error_.empty()) << "Function " << function->name_ |
| 215 << "already has an error."; |
| 216 function->error_ = error; |
| 217 } |
| 218 |
224 // static | 219 // static |
225 bool ExtensionFunction::ignore_all_did_respond_for_testing_do_not_use = false; | 220 bool ExtensionFunction::ignore_all_did_respond_for_testing_do_not_use = false; |
226 | 221 |
227 // static | 222 // static |
228 const char* ExtensionFunction::kUnknownErrorDoNotUse = "Unknown error."; | 223 const char* ExtensionFunction::kUnknownErrorDoNotUse = "Unknown error."; |
229 | 224 |
230 // static | 225 // static |
231 void ExtensionFunctionDeleteTraits::Destruct(const ExtensionFunction* x) { | 226 void ExtensionFunctionDeleteTraits::Destruct(const ExtensionFunction* x) { |
232 x->Destruct(); | 227 x->Destruct(); |
233 } | 228 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 void ExtensionFunction::OnQuotaExceeded(const std::string& violation_error) { | 297 void ExtensionFunction::OnQuotaExceeded(const std::string& violation_error) { |
303 error_ = violation_error; | 298 error_ = violation_error; |
304 SendResponseImpl(false); | 299 SendResponseImpl(false); |
305 } | 300 } |
306 | 301 |
307 void ExtensionFunction::SetArgs(const base::ListValue* args) { | 302 void ExtensionFunction::SetArgs(const base::ListValue* args) { |
308 DCHECK(!args_.get()); // Should only be called once. | 303 DCHECK(!args_.get()); // Should only be called once. |
309 args_ = args->CreateDeepCopy(); | 304 args_ = args->CreateDeepCopy(); |
310 } | 305 } |
311 | 306 |
312 void ExtensionFunction::SetResult(std::unique_ptr<base::Value> result) { | |
313 results_.reset(new base::ListValue()); | |
314 results_->Append(std::move(result)); | |
315 } | |
316 | |
317 void ExtensionFunction::SetResultList( | |
318 std::unique_ptr<base::ListValue> results) { | |
319 results_ = std::move(results); | |
320 } | |
321 | |
322 const base::ListValue* ExtensionFunction::GetResultList() const { | 307 const base::ListValue* ExtensionFunction::GetResultList() const { |
323 return results_.get(); | 308 return results_.get(); |
324 } | 309 } |
325 | 310 |
326 std::string ExtensionFunction::GetError() const { | 311 const std::string& ExtensionFunction::GetError() const { |
327 return error_; | 312 return error_; |
328 } | 313 } |
329 | 314 |
330 void ExtensionFunction::SetError(const std::string& error) { | 315 void ExtensionFunction::SetError(const std::string& error) { |
331 error_ = error; | 316 error_ = error; |
332 } | 317 } |
333 | 318 |
334 bool ExtensionFunction::user_gesture() const { | 319 bool ExtensionFunction::user_gesture() const { |
335 return user_gesture_ || UserGestureForTests::GetInstance()->HaveGesture(); | 320 return user_gesture_ || UserGestureForTests::GetInstance()->HaveGesture(); |
336 } | 321 } |
337 | 322 |
338 ExtensionFunction::ResponseValue ExtensionFunction::NoArguments() { | 323 ExtensionFunction::ResponseValue ExtensionFunction::NoArguments() { |
339 return ResponseValue(new ArgumentListResponseValue( | 324 return ResponseValue( |
340 name(), "NoArguments", this, base::MakeUnique<base::ListValue>())); | 325 new ArgumentListResponseValue(this, base::MakeUnique<base::ListValue>())); |
341 } | 326 } |
342 | 327 |
343 ExtensionFunction::ResponseValue ExtensionFunction::OneArgument( | 328 ExtensionFunction::ResponseValue ExtensionFunction::OneArgument( |
344 std::unique_ptr<base::Value> arg) { | 329 std::unique_ptr<base::Value> arg) { |
345 std::unique_ptr<base::ListValue> args(new base::ListValue()); | 330 std::unique_ptr<base::ListValue> args(new base::ListValue()); |
346 args->Append(std::move(arg)); | 331 args->Append(std::move(arg)); |
347 return ResponseValue(new ArgumentListResponseValue(name(), "OneArgument", | 332 return ResponseValue(new ArgumentListResponseValue(this, std::move(args))); |
348 this, std::move(args))); | |
349 } | 333 } |
350 | 334 |
351 ExtensionFunction::ResponseValue ExtensionFunction::TwoArguments( | 335 ExtensionFunction::ResponseValue ExtensionFunction::TwoArguments( |
352 std::unique_ptr<base::Value> arg1, | 336 std::unique_ptr<base::Value> arg1, |
353 std::unique_ptr<base::Value> arg2) { | 337 std::unique_ptr<base::Value> arg2) { |
354 std::unique_ptr<base::ListValue> args(new base::ListValue()); | 338 std::unique_ptr<base::ListValue> args(new base::ListValue()); |
355 args->Append(std::move(arg1)); | 339 args->Append(std::move(arg1)); |
356 args->Append(std::move(arg2)); | 340 args->Append(std::move(arg2)); |
357 return ResponseValue(new ArgumentListResponseValue(name(), "TwoArguments", | 341 return ResponseValue(new ArgumentListResponseValue(this, std::move(args))); |
358 this, std::move(args))); | |
359 } | 342 } |
360 | 343 |
361 ExtensionFunction::ResponseValue ExtensionFunction::ArgumentList( | 344 ExtensionFunction::ResponseValue ExtensionFunction::ArgumentList( |
362 std::unique_ptr<base::ListValue> args) { | 345 std::unique_ptr<base::ListValue> args) { |
363 return ResponseValue(new ArgumentListResponseValue(name(), "ArgumentList", | 346 return ResponseValue(new ArgumentListResponseValue(this, std::move(args))); |
364 this, std::move(args))); | |
365 } | 347 } |
366 | 348 |
367 ExtensionFunction::ResponseValue ExtensionFunction::Error( | 349 ExtensionFunction::ResponseValue ExtensionFunction::Error( |
368 const std::string& error) { | 350 const std::string& error) { |
369 return ResponseValue(new ErrorResponseValue(this, error)); | 351 return ResponseValue(new ErrorResponseValue(this, error)); |
370 } | 352 } |
371 | 353 |
372 ExtensionFunction::ResponseValue ExtensionFunction::Error( | 354 ExtensionFunction::ResponseValue ExtensionFunction::Error( |
373 const std::string& format, | 355 const std::string& format, |
374 const std::string& s1) { | 356 const std::string& s1) { |
(...skipping 14 matching lines...) Expand all Loading... |
389 const std::string& s1, | 371 const std::string& s1, |
390 const std::string& s2, | 372 const std::string& s2, |
391 const std::string& s3) { | 373 const std::string& s3) { |
392 return ResponseValue(new ErrorResponseValue( | 374 return ResponseValue(new ErrorResponseValue( |
393 this, ErrorUtils::FormatErrorMessage(format, s1, s2, s3))); | 375 this, ErrorUtils::FormatErrorMessage(format, s1, s2, s3))); |
394 } | 376 } |
395 | 377 |
396 ExtensionFunction::ResponseValue ExtensionFunction::ErrorWithArguments( | 378 ExtensionFunction::ResponseValue ExtensionFunction::ErrorWithArguments( |
397 std::unique_ptr<base::ListValue> args, | 379 std::unique_ptr<base::ListValue> args, |
398 const std::string& error) { | 380 const std::string& error) { |
399 return ResponseValue(new ErrorWithArgumentsResponseValue( | 381 return ResponseValue( |
400 name(), "ErrorWithArguments", this, std::move(args), error)); | 382 new ErrorWithArgumentsResponseValue(this, std::move(args), error)); |
401 } | 383 } |
402 | 384 |
403 ExtensionFunction::ResponseValue ExtensionFunction::BadMessage() { | 385 ExtensionFunction::ResponseValue ExtensionFunction::BadMessage() { |
404 return ResponseValue(new BadMessageResponseValue(this)); | 386 return ResponseValue(new BadMessageResponseValue(this)); |
405 } | 387 } |
406 | 388 |
407 ExtensionFunction::ResponseAction ExtensionFunction::RespondNow( | 389 ExtensionFunction::ResponseAction ExtensionFunction::RespondNow( |
408 ResponseValue result) { | 390 ResponseValue result) { |
409 return ResponseAction(new RespondNowAction( | 391 return ResponseAction(new RespondNowAction( |
410 std::move(result), | 392 std::move(result), |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 UIThreadExtensionFunction::~UIThreadExtensionFunction() { | 459 UIThreadExtensionFunction::~UIThreadExtensionFunction() { |
478 if (dispatcher() && render_frame_host()) | 460 if (dispatcher() && render_frame_host()) |
479 dispatcher()->OnExtensionFunctionCompleted(extension()); | 461 dispatcher()->OnExtensionFunctionCompleted(extension()); |
480 // The extension function should always respond to avoid leaks in the | 462 // The extension function should always respond to avoid leaks in the |
481 // renderer, dangling callbacks, etc. The exception is if the system is | 463 // renderer, dangling callbacks, etc. The exception is if the system is |
482 // shutting down. | 464 // shutting down. |
483 // TODO(devlin): Duplicate this check in IOThreadExtensionFunction. It's | 465 // TODO(devlin): Duplicate this check in IOThreadExtensionFunction. It's |
484 // tricky because checking IsShuttingDown has to be called from the UI thread. | 466 // tricky because checking IsShuttingDown has to be called from the UI thread. |
485 extensions::ExtensionsBrowserClient* browser_client = | 467 extensions::ExtensionsBrowserClient* browser_client = |
486 extensions::ExtensionsBrowserClient::Get(); | 468 extensions::ExtensionsBrowserClient::Get(); |
487 DCHECK(!browser_client || browser_client->IsShuttingDown() || did_respond_ || | 469 DCHECK(!browser_client || browser_client->IsShuttingDown() || did_respond() || |
488 ignore_all_did_respond_for_testing_do_not_use) | 470 ignore_all_did_respond_for_testing_do_not_use) |
489 << name_; | 471 << name(); |
490 } | 472 } |
491 | 473 |
492 UIThreadExtensionFunction* | 474 UIThreadExtensionFunction* |
493 UIThreadExtensionFunction::AsUIThreadExtensionFunction() { | 475 UIThreadExtensionFunction::AsUIThreadExtensionFunction() { |
494 return this; | 476 return this; |
495 } | 477 } |
496 | 478 |
497 bool UIThreadExtensionFunction::PreRunValidation(std::string* error) { | 479 bool UIThreadExtensionFunction::PreRunValidation(std::string* error) { |
498 if (!ExtensionFunction::PreRunValidation(error)) | 480 if (!ExtensionFunction::PreRunValidation(error)) |
499 return false; | 481 return false; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 return this; | 565 return this; |
584 } | 566 } |
585 | 567 |
586 void IOThreadExtensionFunction::Destruct() const { | 568 void IOThreadExtensionFunction::Destruct() const { |
587 BrowserThread::DeleteOnIOThread::Destruct(this); | 569 BrowserThread::DeleteOnIOThread::Destruct(this); |
588 } | 570 } |
589 | 571 |
590 AsyncExtensionFunction::AsyncExtensionFunction() { | 572 AsyncExtensionFunction::AsyncExtensionFunction() { |
591 } | 573 } |
592 | 574 |
| 575 void AsyncExtensionFunction::SetError(const std::string& error) { |
| 576 error_ = error; |
| 577 } |
| 578 |
| 579 const std::string& AsyncExtensionFunction::GetError() const { |
| 580 return error_.empty() ? UIThreadExtensionFunction::GetError() : error_; |
| 581 } |
| 582 |
593 AsyncExtensionFunction::~AsyncExtensionFunction() { | 583 AsyncExtensionFunction::~AsyncExtensionFunction() { |
594 } | 584 } |
595 | 585 |
| 586 void AsyncExtensionFunction::SetResult(std::unique_ptr<base::Value> result) { |
| 587 results_.reset(new base::ListValue()); |
| 588 results_->Append(std::move(result)); |
| 589 } |
| 590 |
| 591 void AsyncExtensionFunction::SetResultList( |
| 592 std::unique_ptr<base::ListValue> results) { |
| 593 results_ = std::move(results); |
| 594 } |
| 595 |
596 ExtensionFunction::ScopedUserGestureForTests::ScopedUserGestureForTests() { | 596 ExtensionFunction::ScopedUserGestureForTests::ScopedUserGestureForTests() { |
597 UserGestureForTests::GetInstance()->IncrementCount(); | 597 UserGestureForTests::GetInstance()->IncrementCount(); |
598 } | 598 } |
599 | 599 |
600 ExtensionFunction::ScopedUserGestureForTests::~ScopedUserGestureForTests() { | 600 ExtensionFunction::ScopedUserGestureForTests::~ScopedUserGestureForTests() { |
601 UserGestureForTests::GetInstance()->DecrementCount(); | 601 UserGestureForTests::GetInstance()->DecrementCount(); |
602 } | 602 } |
603 | 603 |
604 ExtensionFunction::ResponseAction AsyncExtensionFunction::Run() { | 604 ExtensionFunction::ResponseAction AsyncExtensionFunction::Run() { |
605 return RunAsync() ? RespondLater() : RespondNow(Error(error_)); | 605 if (RunAsync()) |
| 606 return RespondLater(); |
| 607 DCHECK(!results_); |
| 608 return RespondNow(Error(error_)); |
606 } | 609 } |
607 | 610 |
608 // static | 611 // static |
609 bool AsyncExtensionFunction::ValidationFailure( | 612 bool AsyncExtensionFunction::ValidationFailure( |
610 AsyncExtensionFunction* function) { | 613 AsyncExtensionFunction* function) { |
611 return false; | 614 return false; |
612 } | 615 } |
613 | 616 |
614 void AsyncExtensionFunction::SendResponse(bool success) { | 617 void AsyncExtensionFunction::SendResponse(bool success) { |
615 Respond(success ? ArgumentList(std::move(results_)) : Error(error_)); | 618 ResponseValue response; |
| 619 if (success) { |
| 620 response = ArgumentList(std::move(results_)); |
| 621 } else { |
| 622 response = results_ ? ErrorWithArguments(std::move(results_), error_) |
| 623 : Error(error_); |
| 624 } |
| 625 Respond(std::move(response)); |
616 } | 626 } |
OLD | NEW |