Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Side by Side Diff: extensions/browser/extension_function.cc

Issue 2017113002: [Extensions] DCHECK that ExtensionFunctions respond (and only once) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « extensions/browser/extension_function.h ('k') | extensions/browser/extension_function_dispatcher.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698