| 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 |