| 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" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/memory/singleton.h" | 12 #include "base/memory/singleton.h" |
| 13 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
| 14 #include "base/synchronization/lock.h" | 14 #include "base/synchronization/lock.h" |
| 15 #include "content/public/browser/notification_source.h" | 15 #include "content/public/browser/notification_source.h" |
| 16 #include "content/public/browser/notification_types.h" | 16 #include "content/public/browser/notification_types.h" |
| 17 #include "content/public/browser/render_frame_host.h" | 17 #include "content/public/browser/render_frame_host.h" |
| 18 #include "content/public/browser/web_contents.h" | 18 #include "content/public/browser/web_contents.h" |
| 19 #include "content/public/browser/web_contents_observer.h" | 19 #include "content/public/browser/web_contents_observer.h" |
| 20 #include "extensions/browser/extension_function_dispatcher.h" | 20 #include "extensions/browser/extension_function_dispatcher.h" |
| 21 #include "extensions/browser/extension_message_filter.h" | 21 #include "extensions/browser/extension_message_filter.h" |
| 22 #include "extensions/browser/extensions_browser_client.h" |
| 22 #include "extensions/common/error_utils.h" | 23 #include "extensions/common/error_utils.h" |
| 23 #include "extensions/common/extension_api.h" | 24 #include "extensions/common/extension_api.h" |
| 24 #include "extensions/common/extension_messages.h" | 25 #include "extensions/common/extension_messages.h" |
| 25 | 26 |
| 26 using content::BrowserThread; | 27 using content::BrowserThread; |
| 27 using content::RenderViewHost; | 28 using content::RenderViewHost; |
| 28 using content::WebContents; | 29 using content::WebContents; |
| 29 using extensions::ErrorUtils; | 30 using extensions::ErrorUtils; |
| 30 using extensions::ExtensionAPI; | 31 using extensions::ExtensionAPI; |
| 31 using extensions::Feature; | 32 using extensions::Feature; |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 | 172 |
| 172 void UserGestureForTests::DecrementCount() { | 173 void UserGestureForTests::DecrementCount() { |
| 173 base::AutoLock autolock(lock_); | 174 base::AutoLock autolock(lock_); |
| 174 --count_; | 175 --count_; |
| 175 } | 176 } |
| 176 | 177 |
| 177 | 178 |
| 178 } // namespace | 179 } // namespace |
| 179 | 180 |
| 180 // static | 181 // static |
| 182 bool ExtensionFunction::ignore_all_did_respond_for_testing_do_not_use = false; |
| 183 |
| 184 // static |
| 181 void ExtensionFunctionDeleteTraits::Destruct(const ExtensionFunction* x) { | 185 void ExtensionFunctionDeleteTraits::Destruct(const ExtensionFunction* x) { |
| 182 x->Destruct(); | 186 x->Destruct(); |
| 183 } | 187 } |
| 184 | 188 |
| 185 // Helper class to track the lifetime of ExtensionFunction's RenderFrameHost and | 189 // Helper class to track the lifetime of ExtensionFunction's RenderFrameHost and |
| 186 // notify the function when it is deleted, as well as forwarding any messages | 190 // notify the function when it is deleted, as well as forwarding any messages |
| 187 // to the ExtensionFunction. | 191 // to the ExtensionFunction. |
| 188 class UIThreadExtensionFunction::RenderFrameHostTracker | 192 class UIThreadExtensionFunction::RenderFrameHostTracker |
| 189 : public content::WebContentsObserver { | 193 : public content::WebContentsObserver { |
| 190 public: | 194 public: |
| (...skipping 30 matching lines...) Expand all Loading... |
| 221 : request_id_(-1), | 225 : request_id_(-1), |
| 222 profile_id_(NULL), | 226 profile_id_(NULL), |
| 223 name_(""), | 227 name_(""), |
| 224 has_callback_(false), | 228 has_callback_(false), |
| 225 include_incognito_(false), | 229 include_incognito_(false), |
| 226 user_gesture_(false), | 230 user_gesture_(false), |
| 227 bad_message_(false), | 231 bad_message_(false), |
| 228 histogram_value_(extensions::functions::UNKNOWN), | 232 histogram_value_(extensions::functions::UNKNOWN), |
| 229 source_tab_id_(-1), | 233 source_tab_id_(-1), |
| 230 source_context_type_(Feature::UNSPECIFIED_CONTEXT), | 234 source_context_type_(Feature::UNSPECIFIED_CONTEXT), |
| 231 source_process_id_(-1) { | 235 source_process_id_(-1), |
| 232 } | 236 did_respond_(false) {} |
| 233 | 237 |
| 234 ExtensionFunction::~ExtensionFunction() { | 238 ExtensionFunction::~ExtensionFunction() { |
| 235 } | 239 } |
| 236 | 240 |
| 237 UIThreadExtensionFunction* ExtensionFunction::AsUIThreadExtensionFunction() { | 241 UIThreadExtensionFunction* ExtensionFunction::AsUIThreadExtensionFunction() { |
| 238 return NULL; | 242 return NULL; |
| 239 } | 243 } |
| 240 | 244 |
| 241 IOThreadExtensionFunction* ExtensionFunction::AsIOThreadExtensionFunction() { | 245 IOThreadExtensionFunction* ExtensionFunction::AsIOThreadExtensionFunction() { |
| 242 return NULL; | 246 return NULL; |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 // static | 376 // static |
| 373 ExtensionFunction::ResponseAction ExtensionFunction::ValidationFailure( | 377 ExtensionFunction::ResponseAction ExtensionFunction::ValidationFailure( |
| 374 ExtensionFunction* function) { | 378 ExtensionFunction* function) { |
| 375 return function->RespondNow(function->BadMessage()); | 379 return function->RespondNow(function->BadMessage()); |
| 376 } | 380 } |
| 377 | 381 |
| 378 void ExtensionFunction::Respond(ResponseValue result) { | 382 void ExtensionFunction::Respond(ResponseValue result) { |
| 379 SendResponse(result->Apply()); | 383 SendResponse(result->Apply()); |
| 380 } | 384 } |
| 381 | 385 |
| 386 bool ExtensionFunction::PreRunValidation(std::string* error) { |
| 387 return true; |
| 388 } |
| 389 |
| 390 ExtensionFunction::ResponseAction ExtensionFunction::RunWithValidation() { |
| 391 std::string error; |
| 392 if (!PreRunValidation(&error)) { |
| 393 DCHECK(!error.empty() || bad_message_); |
| 394 return bad_message_ ? ValidationFailure(this) : RespondNow(Error(error)); |
| 395 } |
| 396 return Run(); |
| 397 } |
| 398 |
| 382 bool ExtensionFunction::ShouldSkipQuotaLimiting() const { | 399 bool ExtensionFunction::ShouldSkipQuotaLimiting() const { |
| 383 return false; | 400 return false; |
| 384 } | 401 } |
| 385 | 402 |
| 386 bool ExtensionFunction::HasOptionalArgument(size_t index) { | 403 bool ExtensionFunction::HasOptionalArgument(size_t index) { |
| 387 base::Value* value; | 404 base::Value* value; |
| 388 return args_->Get(index, &value) && !value->IsType(base::Value::TYPE_NULL); | 405 return args_->Get(index, &value) && !value->IsType(base::Value::TYPE_NULL); |
| 389 } | 406 } |
| 390 | 407 |
| 391 void ExtensionFunction::SendResponseImpl(bool success) { | 408 void ExtensionFunction::SendResponseImpl(bool success) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 | 441 |
| 425 UIThreadExtensionFunction::UIThreadExtensionFunction() | 442 UIThreadExtensionFunction::UIThreadExtensionFunction() |
| 426 : context_(nullptr), | 443 : context_(nullptr), |
| 427 render_frame_host_(nullptr), | 444 render_frame_host_(nullptr), |
| 428 delegate_(nullptr) { | 445 delegate_(nullptr) { |
| 429 } | 446 } |
| 430 | 447 |
| 431 UIThreadExtensionFunction::~UIThreadExtensionFunction() { | 448 UIThreadExtensionFunction::~UIThreadExtensionFunction() { |
| 432 if (dispatcher() && render_frame_host()) | 449 if (dispatcher() && render_frame_host()) |
| 433 dispatcher()->OnExtensionFunctionCompleted(extension()); | 450 dispatcher()->OnExtensionFunctionCompleted(extension()); |
| 451 // The extension function should always respond to avoid leaks in the |
| 452 // renderer, dangling callbacks, etc. The exception is if the system is |
| 453 // shutting down. |
| 454 // TODO(devlin): Duplicate this check in IOThreadExtensionFunction. It's |
| 455 // tricky because checking IsShuttingDown has to be called from the UI thread. |
| 456 DCHECK(extensions::ExtensionsBrowserClient::Get()->IsShuttingDown() || |
| 457 did_respond_ || ignore_all_did_respond_for_testing_do_not_use) |
| 458 << name_; |
| 434 } | 459 } |
| 435 | 460 |
| 436 UIThreadExtensionFunction* | 461 UIThreadExtensionFunction* |
| 437 UIThreadExtensionFunction::AsUIThreadExtensionFunction() { | 462 UIThreadExtensionFunction::AsUIThreadExtensionFunction() { |
| 438 return this; | 463 return this; |
| 439 } | 464 } |
| 440 | 465 |
| 441 bool UIThreadExtensionFunction::OnMessageReceived(const IPC::Message& message) { | 466 bool UIThreadExtensionFunction::OnMessageReceived(const IPC::Message& message) { |
| 442 return false; | 467 return false; |
| 443 } | 468 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 469 | 494 |
| 470 return web_contents; | 495 return web_contents; |
| 471 } | 496 } |
| 472 | 497 |
| 473 content::WebContents* UIThreadExtensionFunction::GetSenderWebContents() { | 498 content::WebContents* UIThreadExtensionFunction::GetSenderWebContents() { |
| 474 return render_frame_host_ ? | 499 return render_frame_host_ ? |
| 475 content::WebContents::FromRenderFrameHost(render_frame_host_) : nullptr; | 500 content::WebContents::FromRenderFrameHost(render_frame_host_) : nullptr; |
| 476 } | 501 } |
| 477 | 502 |
| 478 void UIThreadExtensionFunction::SendResponse(bool success) { | 503 void UIThreadExtensionFunction::SendResponse(bool success) { |
| 504 DCHECK(!did_respond_) << name_; |
| 505 did_respond_ = true; |
| 479 if (delegate_) | 506 if (delegate_) |
| 480 delegate_->OnSendResponse(this, success, bad_message_); | 507 delegate_->OnSendResponse(this, success, bad_message_); |
| 481 else | 508 else |
| 482 SendResponseImpl(success); | 509 SendResponseImpl(success); |
| 483 | 510 |
| 484 if (!transferred_blob_uuids_.empty()) { | 511 if (!transferred_blob_uuids_.empty()) { |
| 485 DCHECK(!delegate_) << "Blob transfer not supported with test delegate."; | 512 DCHECK(!delegate_) << "Blob transfer not supported with test delegate."; |
| 486 render_frame_host_->Send( | 513 render_frame_host_->Send( |
| 487 new ExtensionMsg_TransferBlobs(transferred_blob_uuids_)); | 514 new ExtensionMsg_TransferBlobs(transferred_blob_uuids_)); |
| 488 } | 515 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 513 IOThreadExtensionFunction* | 540 IOThreadExtensionFunction* |
| 514 IOThreadExtensionFunction::AsIOThreadExtensionFunction() { | 541 IOThreadExtensionFunction::AsIOThreadExtensionFunction() { |
| 515 return this; | 542 return this; |
| 516 } | 543 } |
| 517 | 544 |
| 518 void IOThreadExtensionFunction::Destruct() const { | 545 void IOThreadExtensionFunction::Destruct() const { |
| 519 BrowserThread::DeleteOnIOThread::Destruct(this); | 546 BrowserThread::DeleteOnIOThread::Destruct(this); |
| 520 } | 547 } |
| 521 | 548 |
| 522 void IOThreadExtensionFunction::SendResponse(bool success) { | 549 void IOThreadExtensionFunction::SendResponse(bool success) { |
| 550 DCHECK(!did_respond_) << name_; |
| 551 did_respond_ = true; |
| 523 SendResponseImpl(success); | 552 SendResponseImpl(success); |
| 524 } | 553 } |
| 525 | 554 |
| 526 AsyncExtensionFunction::AsyncExtensionFunction() { | 555 AsyncExtensionFunction::AsyncExtensionFunction() { |
| 527 } | 556 } |
| 528 | 557 |
| 529 AsyncExtensionFunction::~AsyncExtensionFunction() { | 558 AsyncExtensionFunction::~AsyncExtensionFunction() { |
| 530 } | 559 } |
| 531 | 560 |
| 532 ExtensionFunction::ScopedUserGestureForTests::ScopedUserGestureForTests() { | 561 ExtensionFunction::ScopedUserGestureForTests::ScopedUserGestureForTests() { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 ExtensionFunction::ResponseAction SyncIOThreadExtensionFunction::Run() { | 601 ExtensionFunction::ResponseAction SyncIOThreadExtensionFunction::Run() { |
| 573 return RespondNow(RunSync() ? ArgumentList(std::move(results_)) | 602 return RespondNow(RunSync() ? ArgumentList(std::move(results_)) |
| 574 : Error(error_)); | 603 : Error(error_)); |
| 575 } | 604 } |
| 576 | 605 |
| 577 // static | 606 // static |
| 578 bool SyncIOThreadExtensionFunction::ValidationFailure( | 607 bool SyncIOThreadExtensionFunction::ValidationFailure( |
| 579 SyncIOThreadExtensionFunction* function) { | 608 SyncIOThreadExtensionFunction* function) { |
| 580 return false; | 609 return false; |
| 581 } | 610 } |
| OLD | NEW |