Commit 187edaa9 authored by rdevlin.cronin's avatar rdevlin.cronin Committed by Commit bot

[Extensions] Remove UIThreadExtensionFunction::DelegateForTests

The ExtensionFunction test delegate basically just served as a way of
getting the results from the function, but we already have that by simply
setting the response callback in the function. Remove the
DelegateForTests class and update uses of it to use the callback.

Also add a response() field on ExtensionFunction for use in determining
if the function succeeded or failed. Previously, code would rely on
whether or not results_ were set, but this was wrong for a few reasons:
- The absence of results doesn't always indicate failure
- The presence of results doesn't always indicate success
- In practice, we always send back an empty list value (even if
  results weren't previously set).
Update code to use the response() value instead.

BUG=648276
TBR=benwells@chromium.org (apps browsertest change)

Review-Url: https://codereview.chromium.org/2348723002
Cr-Commit-Position: refs/heads/master@{#419560}
parent 093e8f03
...@@ -179,7 +179,7 @@ bool PlatformAppBrowserTest::RunGetWindowFunctionForExtension( ...@@ -179,7 +179,7 @@ bool PlatformAppBrowserTest::RunGetWindowFunctionForExtension(
base::StringPrintf("[%u]", window_id), base::StringPrintf("[%u]", window_id),
browser(), browser(),
utils::NONE); utils::NONE);
return function->GetResultList() != NULL; return *function->response_type() == ExtensionFunction::SUCCEEDED;
} }
size_t PlatformAppBrowserTest::GetAppWindowCount() { size_t PlatformAppBrowserTest::GetAppWindowCount() {
......
...@@ -210,11 +210,8 @@ class EPKChallengeKeyTestBase : public BrowserWithTestWindowTest { ...@@ -210,11 +210,8 @@ class EPKChallengeKeyTestBase : public BrowserWithTestWindowTest {
std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function,
std::unique_ptr<base::ListValue> args, std::unique_ptr<base::ListValue> args,
Browser* browser) { Browser* browser) {
scoped_refptr<ExtensionFunction> function_owner(function);
// Without a callback the function will not generate a result.
function->set_has_callback(true);
utils::RunFunction(function, std::move(args), browser, utils::NONE); utils::RunFunction(function, std::move(args), browser, utils::NONE);
EXPECT_FALSE(function->GetResultList()) << "Did not expect a result"; EXPECT_EQ(ExtensionFunction::FAILED, *function->response_type());
return function->GetError(); return function->GetError();
} }
......
...@@ -78,45 +78,6 @@ namespace utils = extension_function_test_utils; ...@@ -78,45 +78,6 @@ namespace utils = extension_function_test_utils;
static const char kAccessToken[] = "auth_token"; static const char kAccessToken[] = "auth_token";
static const char kExtensionId[] = "ext_id"; static const char kExtensionId[] = "ext_id";
// This helps us be able to wait until an UIThreadExtensionFunction calls
// SendResponse.
class SendResponseDelegate
: public UIThreadExtensionFunction::DelegateForTests {
public:
SendResponseDelegate() : should_post_quit_(false) {}
virtual ~SendResponseDelegate() {}
void set_should_post_quit(bool should_quit) {
should_post_quit_ = should_quit;
}
bool HasResponse() {
return response_.get() != NULL;
}
bool GetResponse() {
EXPECT_TRUE(HasResponse());
return *response_;
}
void OnSendResponse(UIThreadExtensionFunction* function,
bool success,
bool bad_message) override {
ASSERT_FALSE(bad_message);
ASSERT_FALSE(HasResponse());
response_.reset(new bool);
*response_ = success;
if (should_post_quit_) {
base::MessageLoopForUI::current()->QuitWhenIdle();
}
}
private:
std::unique_ptr<bool> response_;
bool should_post_quit_;
};
class AsyncExtensionBrowserTest : public ExtensionBrowserTest { class AsyncExtensionBrowserTest : public ExtensionBrowserTest {
protected: protected:
// Asynchronous function runner allows tests to manipulate the browser window // Asynchronous function runner allows tests to manipulate the browser window
...@@ -124,8 +85,7 @@ class AsyncExtensionBrowserTest : public ExtensionBrowserTest { ...@@ -124,8 +85,7 @@ class AsyncExtensionBrowserTest : public ExtensionBrowserTest {
void RunFunctionAsync( void RunFunctionAsync(
UIThreadExtensionFunction* function, UIThreadExtensionFunction* function,
const std::string& args) { const std::string& args) {
response_delegate_.reset(new SendResponseDelegate); response_delegate_.reset(new api_test_utils::SendResponseHelper(function));
function->set_test_delegate(response_delegate_.get());
std::unique_ptr<base::ListValue> parsed_args(utils::ParseList(args)); std::unique_ptr<base::ListValue> parsed_args(utils::ParseList(args));
EXPECT_TRUE(parsed_args.get()) << EXPECT_TRUE(parsed_args.get()) <<
"Could not parse extension function arguments: " << args; "Could not parse extension function arguments: " << args;
...@@ -144,7 +104,8 @@ class AsyncExtensionBrowserTest : public ExtensionBrowserTest { ...@@ -144,7 +104,8 @@ class AsyncExtensionBrowserTest : public ExtensionBrowserTest {
std::string WaitForError(UIThreadExtensionFunction* function) { std::string WaitForError(UIThreadExtensionFunction* function) {
RunMessageLoopUntilResponse(); RunMessageLoopUntilResponse();
EXPECT_FALSE(function->GetResultList()) << "Did not expect a result"; CHECK(function->response_type());
EXPECT_EQ(ExtensionFunction::FAILED, *function->response_type());
return function->GetError(); return function->GetError();
} }
...@@ -162,16 +123,11 @@ class AsyncExtensionBrowserTest : public ExtensionBrowserTest { ...@@ -162,16 +123,11 @@ class AsyncExtensionBrowserTest : public ExtensionBrowserTest {
private: private:
void RunMessageLoopUntilResponse() { void RunMessageLoopUntilResponse() {
// If the RunAsync of |function| didn't already call SendResponse, run the response_delegate_->WaitForResponse();
// message loop until they do. EXPECT_TRUE(response_delegate_->has_response());
if (!response_delegate_->HasResponse()) {
response_delegate_->set_should_post_quit(true);
content::RunMessageLoop();
}
EXPECT_TRUE(response_delegate_->HasResponse());
} }
std::unique_ptr<SendResponseDelegate> response_delegate_; std::unique_ptr<api_test_utils::SendResponseHelper> response_delegate_;
}; };
class TestHangOAuth2MintTokenFlow : public OAuth2MintTokenFlow { class TestHangOAuth2MintTokenFlow : public OAuth2MintTokenFlow {
......
...@@ -88,10 +88,14 @@ std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, ...@@ -88,10 +88,14 @@ std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function,
Browser* browser, Browser* browser,
RunFunctionFlags flags) { RunFunctionFlags flags) {
scoped_refptr<ExtensionFunction> function_owner(function); scoped_refptr<ExtensionFunction> function_owner(function);
// Without a callback the function will not generate a result.
function->set_has_callback(true);
RunFunction(function, args, browser, flags); RunFunction(function, args, browser, flags);
EXPECT_FALSE(function->GetResultList()) << "Did not expect a result"; // When sending a response, the function will set an empty list value if there
// is no specified result.
const base::ListValue* results = function->GetResultList();
CHECK(results);
EXPECT_TRUE(results->empty()) << "Did not expect a result";
CHECK(function->response_type());
EXPECT_EQ(ExtensionFunction::FAILED, *function->response_type());
return function->GetError(); return function->GetError();
} }
...@@ -107,8 +111,6 @@ base::Value* RunFunctionAndReturnSingleResult( ...@@ -107,8 +111,6 @@ base::Value* RunFunctionAndReturnSingleResult(
Browser* browser, Browser* browser,
RunFunctionFlags flags) { RunFunctionFlags flags) {
scoped_refptr<ExtensionFunction> function_owner(function); scoped_refptr<ExtensionFunction> function_owner(function);
// Without a callback the function will not generate a result.
function->set_has_callback(true);
RunFunction(function, args, browser, flags); RunFunction(function, args, browser, flags);
EXPECT_TRUE(function->GetError().empty()) << "Unexpected error: " EXPECT_TRUE(function->GetError().empty()) << "Unexpected error: "
<< function->GetError(); << function->GetError();
...@@ -120,45 +122,6 @@ base::Value* RunFunctionAndReturnSingleResult( ...@@ -120,45 +122,6 @@ base::Value* RunFunctionAndReturnSingleResult(
return NULL; return NULL;
} }
// This helps us be able to wait until an UIThreadExtensionFunction calls
// SendResponse.
class SendResponseDelegate
: public UIThreadExtensionFunction::DelegateForTests {
public:
SendResponseDelegate() : should_post_quit_(false) {}
virtual ~SendResponseDelegate() {}
void set_should_post_quit(bool should_quit) {
should_post_quit_ = should_quit;
}
bool HasResponse() {
return response_.get() != NULL;
}
bool GetResponse() {
EXPECT_TRUE(HasResponse());
return *response_;
}
void OnSendResponse(UIThreadExtensionFunction* function,
bool success,
bool bad_message) override {
ASSERT_FALSE(bad_message);
ASSERT_FALSE(HasResponse());
response_.reset(new bool);
*response_ = success;
if (should_post_quit_) {
base::MessageLoopForUI::current()->QuitWhenIdle();
}
}
private:
std::unique_ptr<bool> response_;
bool should_post_quit_;
};
bool RunFunction(UIThreadExtensionFunction* function, bool RunFunction(UIThreadExtensionFunction* function,
const std::string& args, const std::string& args,
Browser* browser, Browser* browser,
......
...@@ -197,8 +197,7 @@ IN_PROC_BROWSER_TEST_F(BluetoothApiTest, Discovery) { ...@@ -197,8 +197,7 @@ IN_PROC_BROWSER_TEST_F(BluetoothApiTest, Discovery) {
.WillOnce( .WillOnce(
testing::Invoke(this, &BluetoothApiTest::DiscoverySessionCallback)); testing::Invoke(this, &BluetoothApiTest::DiscoverySessionCallback));
start_function = setupFunction(new api::BluetoothStartDiscoveryFunction); start_function = setupFunction(new api::BluetoothStartDiscoveryFunction);
(void) utils::RunFunction(start_function.get(), "[]", browser(), utils::NONE);
utils::RunFunctionAndReturnError(start_function.get(), "[]", browser());
// End the discovery session. The StopDiscovery function should succeed. // End the discovery session. The StopDiscovery function should succeed.
testing::Mock::VerifyAndClearExpectations(mock_adapter_); testing::Mock::VerifyAndClearExpectations(mock_adapter_);
......
...@@ -476,23 +476,16 @@ IN_PROC_BROWSER_TEST_F(CastChannelAPITest, TestSetAuthorityKeysInvalid) { ...@@ -476,23 +476,16 @@ IN_PROC_BROWSER_TEST_F(CastChannelAPITest, TestSetAuthorityKeysInvalid) {
// been removed. The API is deprecated and will trivially return // been removed. The API is deprecated and will trivially return
// success. So this is just testing that it succeeds for all inputs // success. So this is just testing that it succeeds for all inputs
// (even invalid ones). // (even invalid ones).
std::string errorResult = "";
cast_channel_set_authority_keys_function = cast_channel_set_authority_keys_function =
CreateSetAuthorityKeysFunction(empty_extension); CreateSetAuthorityKeysFunction(empty_extension);
std::string error = utils::RunFunctionAndReturnError( EXPECT_TRUE(utils::RunFunction(cast_channel_set_authority_keys_function.get(),
cast_channel_set_authority_keys_function.get(), "[\"\", \"signature\"]", browser(),
"[\"\", \"signature\"]", utils::NONE));
browser());
EXPECT_EQ(error, errorResult);
cast_channel_set_authority_keys_function = cast_channel_set_authority_keys_function =
CreateSetAuthorityKeysFunction(empty_extension); CreateSetAuthorityKeysFunction(empty_extension);
error = utils::RunFunctionAndReturnError( EXPECT_TRUE(utils::RunFunction(cast_channel_set_authority_keys_function.get(),
cast_channel_set_authority_keys_function.get(), "[\"keys\", \"\"]", browser(), utils::NONE));
"[\"keys\", \"\"]",
browser());
EXPECT_EQ(error, errorResult);
std::string keys = std::string keys =
"CrMCCiBSnZzWf+XraY5w3SbX2PEmWfHm5SNIv2pc9xbhP0EOcxKOAjCCAQoCggEBALwigL" "CrMCCiBSnZzWf+XraY5w3SbX2PEmWfHm5SNIv2pc9xbhP0EOcxKOAjCCAQoCggEBALwigL"
...@@ -511,27 +504,21 @@ IN_PROC_BROWSER_TEST_F(CastChannelAPITest, TestSetAuthorityKeysInvalid) { ...@@ -511,27 +504,21 @@ IN_PROC_BROWSER_TEST_F(CastChannelAPITest, TestSetAuthorityKeysInvalid) {
cast_channel_set_authority_keys_function = cast_channel_set_authority_keys_function =
CreateSetAuthorityKeysFunction(empty_extension); CreateSetAuthorityKeysFunction(empty_extension);
error = utils::RunFunctionAndReturnError( EXPECT_TRUE(utils::RunFunction(cast_channel_set_authority_keys_function.get(),
cast_channel_set_authority_keys_function.get(), "[\"" + keys + "\", \"signature\"]", browser(),
"[\"" + keys + "\", \"signature\"]", utils::NONE));
browser());
EXPECT_EQ(error, errorResult);
cast_channel_set_authority_keys_function = cast_channel_set_authority_keys_function =
CreateSetAuthorityKeysFunction(empty_extension); CreateSetAuthorityKeysFunction(empty_extension);
error = utils::RunFunctionAndReturnError( EXPECT_TRUE(utils::RunFunction(cast_channel_set_authority_keys_function.get(),
cast_channel_set_authority_keys_function.get(), "[\"keys\", \"" + signature + "\"]", browser(),
"[\"keys\", \"" + signature + "\"]", utils::NONE));
browser());
EXPECT_EQ(error, errorResult);
cast_channel_set_authority_keys_function = cast_channel_set_authority_keys_function =
CreateSetAuthorityKeysFunction(empty_extension); CreateSetAuthorityKeysFunction(empty_extension);
error = utils::RunFunctionAndReturnError( EXPECT_TRUE(utils::RunFunction(cast_channel_set_authority_keys_function.get(),
cast_channel_set_authority_keys_function.get(),
"[\"" + keys + "\", \"" + signature + "\"]", "[\"" + keys + "\", \"" + signature + "\"]",
browser()); browser(), utils::NONE));
EXPECT_EQ(error, errorResult);
} }
IN_PROC_BROWSER_TEST_F(CastChannelAPITest, TestSetAuthorityKeysValid) { IN_PROC_BROWSER_TEST_F(CastChannelAPITest, TestSetAuthorityKeysValid) {
...@@ -563,9 +550,8 @@ IN_PROC_BROWSER_TEST_F(CastChannelAPITest, TestSetAuthorityKeysValid) { ...@@ -563,9 +550,8 @@ IN_PROC_BROWSER_TEST_F(CastChannelAPITest, TestSetAuthorityKeysValid) {
"bzPtNRRlTqfv7Rxm5YXkZMLmJJMZiTs5+o8FMRMTQZT4hRR3DQ+A/jofViyTGA=="; "bzPtNRRlTqfv7Rxm5YXkZMLmJJMZiTs5+o8FMRMTQZT4hRR3DQ+A/jofViyTGA==";
std::string args = "[\"" + keys + "\", \"" + signature + "\"]"; std::string args = "[\"" + keys + "\", \"" + signature + "\"]";
std::string error = utils::RunFunctionAndReturnError( EXPECT_TRUE(utils::RunFunction(cast_channel_set_authority_keys_function.get(),
cast_channel_set_authority_keys_function.get(), args, browser()); args, browser(), utils::NONE));
EXPECT_EQ(error, std::string());
} }
// TODO(vadimgo): Win Dbg has a workaround that makes RunExtensionSubtest // TODO(vadimgo): Win Dbg has a workaround that makes RunExtensionSubtest
......
...@@ -31,49 +31,37 @@ std::unique_ptr<base::ListValue> ParseList(const std::string& data) { ...@@ -31,49 +31,37 @@ std::unique_ptr<base::ListValue> ParseList(const std::string& data) {
return base::ListValue::From(ParseJSON(data)); return base::ListValue::From(ParseJSON(data));
} }
// This helps us be able to wait until an UIThreadExtensionFunction calls } // namespace
// SendResponse.
class SendResponseDelegate namespace extensions {
: public UIThreadExtensionFunction::DelegateForTests {
public:
SendResponseDelegate() {}
virtual ~SendResponseDelegate() {} namespace api_test_utils {
SendResponseHelper::SendResponseHelper(UIThreadExtensionFunction* function) {
function->set_has_callback(true);
function->set_response_callback(
base::Bind(&SendResponseHelper::OnResponse, base::Unretained(this)));
}
bool HasResponse() { return response_.get() != NULL; } SendResponseHelper::~SendResponseHelper() {}
bool GetResponse() { bool SendResponseHelper::GetResponse() {
EXPECT_TRUE(HasResponse()); EXPECT_TRUE(has_response());
return *response_; return *response_;
} }
void OnSendResponse(UIThreadExtensionFunction* function, void SendResponseHelper::OnResponse(ExtensionFunction::ResponseType response,
bool success, const base::ListValue& results,
bool bad_message) override { const std::string& error,
ASSERT_FALSE(bad_message); functions::HistogramValue histogram_value) {
ASSERT_FALSE(HasResponse()); ASSERT_NE(ExtensionFunction::BAD_MESSAGE, response);
response_.reset(new bool); response_.reset(new bool(response == ExtensionFunction::SUCCEEDED));
*response_ = success;
run_loop_.Quit(); run_loop_.Quit();
} }
void WaitForResponse() { void SendResponseHelper::WaitForResponse() {
// If the RunAsync of UIThreadExtensionFunction already called SendResponse,
// this will finish immediately.
run_loop_.Run(); run_loop_.Run();
} }
private:
base::RunLoop run_loop_;
std::unique_ptr<bool> response_;
DISALLOW_COPY_AND_ASSIGN(SendResponseDelegate);
};
} // namespace
namespace extensions {
namespace api_test_utils {
std::unique_ptr<base::DictionaryValue> ParseDictionary( std::unique_ptr<base::DictionaryValue> ParseDictionary(
const std::string& data) { const std::string& data) {
...@@ -160,8 +148,6 @@ std::unique_ptr<base::Value> RunFunctionWithDelegateAndReturnSingleResult( ...@@ -160,8 +148,6 @@ std::unique_ptr<base::Value> RunFunctionWithDelegateAndReturnSingleResult(
content::BrowserContext* context, content::BrowserContext* context,
std::unique_ptr<extensions::ExtensionFunctionDispatcher> dispatcher, std::unique_ptr<extensions::ExtensionFunctionDispatcher> dispatcher,
RunFunctionFlags flags) { RunFunctionFlags flags) {
// Without a callback the function will not generate a result.
function->set_has_callback(true);
RunFunction(function.get(), std::move(args), context, std::move(dispatcher), RunFunction(function.get(), std::move(args), context, std::move(dispatcher),
flags); flags);
EXPECT_TRUE(function->GetError().empty()) << "Unexpected error: " EXPECT_TRUE(function->GetError().empty()) << "Unexpected error: "
...@@ -207,9 +193,14 @@ std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, ...@@ -207,9 +193,14 @@ std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function,
new ExtensionFunctionDispatcher(context)); new ExtensionFunctionDispatcher(context));
scoped_refptr<ExtensionFunction> function_owner(function); scoped_refptr<ExtensionFunction> function_owner(function);
// Without a callback the function will not generate a result. // Without a callback the function will not generate a result.
function->set_has_callback(true);
RunFunction(function, args, context, std::move(dispatcher), flags); RunFunction(function, args, context, std::move(dispatcher), flags);
EXPECT_FALSE(function->GetResultList()) << "Did not expect a result"; // When sending a response, the function will set an empty list value if there
// is no specified result.
const base::ListValue* results = function->GetResultList();
CHECK(results);
EXPECT_TRUE(results->empty()) << "Did not expect a result";
CHECK(function->response_type());
EXPECT_EQ(ExtensionFunction::FAILED, *function->response_type());
return function->GetError(); return function->GetError();
} }
...@@ -240,8 +231,7 @@ bool RunFunction( ...@@ -240,8 +231,7 @@ bool RunFunction(
content::BrowserContext* context, content::BrowserContext* context,
std::unique_ptr<extensions::ExtensionFunctionDispatcher> dispatcher, std::unique_ptr<extensions::ExtensionFunctionDispatcher> dispatcher,
RunFunctionFlags flags) { RunFunctionFlags flags) {
SendResponseDelegate response_delegate; SendResponseHelper response_helper(function);
function->set_test_delegate(&response_delegate);
function->SetArgs(args.get()); function->SetArgs(args.get());
CHECK(dispatcher); CHECK(dispatcher);
...@@ -250,10 +240,10 @@ bool RunFunction( ...@@ -250,10 +240,10 @@ bool RunFunction(
function->set_browser_context(context); function->set_browser_context(context);
function->set_include_incognito(flags & INCLUDE_INCOGNITO); function->set_include_incognito(flags & INCLUDE_INCOGNITO);
function->RunWithValidation()->Execute(); function->RunWithValidation()->Execute();
response_delegate.WaitForResponse(); response_helper.WaitForResponse();
EXPECT_TRUE(response_delegate.HasResponse()); EXPECT_TRUE(response_helper.has_response());
return response_delegate.GetResponse(); return response_helper.GetResponse();
} }
} // namespace api_test_utils } // namespace api_test_utils
......
...@@ -9,10 +9,10 @@ ...@@ -9,10 +9,10 @@
#include <string> #include <string>
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "extensions/browser/extension_function.h"
#include "extensions/common/manifest.h" #include "extensions/common/manifest.h"
class UIThreadExtensionFunction;
namespace base { namespace base {
class DictionaryValue; class DictionaryValue;
class ListValue; class ListValue;
...@@ -34,6 +34,33 @@ class ExtensionFunctionDispatcher; ...@@ -34,6 +34,33 @@ class ExtensionFunctionDispatcher;
// and migrate existing users to the new API. // and migrate existing users to the new API.
namespace api_test_utils { namespace api_test_utils {
// A helper class to handle waiting for a function response.
class SendResponseHelper {
public:
explicit SendResponseHelper(UIThreadExtensionFunction* function);
~SendResponseHelper();
bool has_response() { return response_.get() != nullptr; }
// Asserts a response has been posted (has_response()) and returns the value.
bool GetResponse();
// Waits until a response is posted.
void WaitForResponse();
private:
// Response handler.
void OnResponse(ExtensionFunction::ResponseType response,
const base::ListValue& results,
const std::string& error,
functions::HistogramValue histogram_value);
base::RunLoop run_loop_;
std::unique_ptr<bool> response_;
DISALLOW_COPY_AND_ASSIGN(SendResponseHelper);
};
enum RunFunctionFlags { NONE = 0, INCLUDE_INCOGNITO = 1 << 0 }; enum RunFunctionFlags { NONE = 0, INCLUDE_INCOGNITO = 1 << 0 };
// Parse JSON and return as the specified type, or NULL if the JSON is invalid // Parse JSON and return as the specified type, or NULL if the JSON is invalid
......
...@@ -449,17 +449,18 @@ bool ExtensionFunction::HasOptionalArgument(size_t index) { ...@@ -449,17 +449,18 @@ bool ExtensionFunction::HasOptionalArgument(size_t index) {
void ExtensionFunction::SendResponseImpl(bool success) { void ExtensionFunction::SendResponseImpl(bool success) {
DCHECK(!response_callback_.is_null()); DCHECK(!response_callback_.is_null());
ResponseType type = success ? SUCCEEDED : FAILED; ResponseType response = success ? SUCCEEDED : FAILED;
if (bad_message_) { if (bad_message_) {
type = BAD_MESSAGE; response = BAD_MESSAGE;
LOG(ERROR) << "Bad extension message " << name_; LOG(ERROR) << "Bad extension message " << name_;
} }
response_type_ = base::MakeUnique<ResponseType>(response);
// If results were never set, we send an empty argument list. // If results were never set, we send an empty argument list.
if (!results_) if (!results_)
results_.reset(new base::ListValue()); results_.reset(new base::ListValue());
response_callback_.Run(type, *results_, GetError(), histogram_value()); response_callback_.Run(response, *results_, GetError(), histogram_value());
LogUma(success, timer_.Elapsed(), histogram_value_); LogUma(success, timer_.Elapsed(), histogram_value_);
} }
...@@ -470,8 +471,7 @@ void ExtensionFunction::OnRespondingLater(ResponseValue value) { ...@@ -470,8 +471,7 @@ void ExtensionFunction::OnRespondingLater(ResponseValue value) {
UIThreadExtensionFunction::UIThreadExtensionFunction() UIThreadExtensionFunction::UIThreadExtensionFunction()
: context_(nullptr), : context_(nullptr),
render_frame_host_(nullptr), render_frame_host_(nullptr),
is_from_service_worker_(false), is_from_service_worker_(false) {}
delegate_(nullptr) {}
UIThreadExtensionFunction::~UIThreadExtensionFunction() { UIThreadExtensionFunction::~UIThreadExtensionFunction() {
if (dispatcher() && render_frame_host()) if (dispatcher() && render_frame_host())
...@@ -551,13 +551,9 @@ content::WebContents* UIThreadExtensionFunction::GetSenderWebContents() { ...@@ -551,13 +551,9 @@ content::WebContents* UIThreadExtensionFunction::GetSenderWebContents() {
void UIThreadExtensionFunction::SendResponse(bool success) { void UIThreadExtensionFunction::SendResponse(bool success) {
DCHECK(!did_respond_) << name_; DCHECK(!did_respond_) << name_;
did_respond_ = true; did_respond_ = true;
if (delegate_)
delegate_->OnSendResponse(this, success, bad_message_);
else
SendResponseImpl(success); SendResponseImpl(success);
if (!transferred_blob_uuids_.empty()) { if (!transferred_blob_uuids_.empty()) {
DCHECK(!delegate_) << "Blob transfer not supported with test delegate.";
render_frame_host_->Send( render_frame_host_->Send(
new ExtensionMsg_TransferBlobs(transferred_blob_uuids_)); new ExtensionMsg_TransferBlobs(transferred_blob_uuids_));
} }
......
...@@ -315,6 +315,8 @@ class ExtensionFunction ...@@ -315,6 +315,8 @@ class ExtensionFunction
return source_process_id_; return source_process_id_;
} }
ResponseType* response_type() const { return response_type_.get(); }
// Sets did_respond_ to true so that the function won't DCHECK if it never // Sets did_respond_ to true so that the function won't DCHECK if it never
// sends a response. Typically, this shouldn't be used, even in testing. It's // sends a response. Typically, this shouldn't be used, even in testing. It's
// only for when you want to test functionality that doesn't exercise the // only for when you want to test functionality that doesn't exercise the
...@@ -475,6 +477,9 @@ class ExtensionFunction ...@@ -475,6 +477,9 @@ class ExtensionFunction
private: private:
base::ElapsedTimer timer_; base::ElapsedTimer timer_;
// The response type of the function, if the response has been sent.
std::unique_ptr<ResponseType> response_type_;
void OnRespondingLater(ResponseValue response); void OnRespondingLater(ResponseValue response);
DISALLOW_COPY_AND_ASSIGN(ExtensionFunction); DISALLOW_COPY_AND_ASSIGN(ExtensionFunction);
...@@ -484,26 +489,12 @@ class ExtensionFunction ...@@ -484,26 +489,12 @@ class ExtensionFunction
// this category. // this category.
class UIThreadExtensionFunction : public ExtensionFunction { class UIThreadExtensionFunction : public ExtensionFunction {
public: public:
// TODO(yzshen): We should be able to remove this interface now that we
// support overriding the response callback.
// A delegate for use in testing, to intercept the call to SendResponse.
class DelegateForTests {
public:
virtual void OnSendResponse(UIThreadExtensionFunction* function,
bool success,
bool bad_message) = 0;
};
UIThreadExtensionFunction(); UIThreadExtensionFunction();
UIThreadExtensionFunction* AsUIThreadExtensionFunction() override; UIThreadExtensionFunction* AsUIThreadExtensionFunction() override;
bool PreRunValidation(std::string* error) override; bool PreRunValidation(std::string* error) override;
void set_test_delegate(DelegateForTests* delegate) {
delegate_ = delegate;
}
// Called when a message was received. // Called when a message was received.
// Should return true if it processed the message. // Should return true if it processed the message.
virtual bool OnMessageReceived(const IPC::Message& message); virtual bool OnMessageReceived(const IPC::Message& message);
...@@ -579,8 +570,6 @@ class UIThreadExtensionFunction : public ExtensionFunction { ...@@ -579,8 +570,6 @@ class UIThreadExtensionFunction : public ExtensionFunction {
std::unique_ptr<RenderFrameHostTracker> tracker_; std::unique_ptr<RenderFrameHostTracker> tracker_;
DelegateForTests* delegate_;
// The blobs transferred to the renderer process. // The blobs transferred to the renderer process.
std::vector<std::string> transferred_blob_uuids_; std::vector<std::string> transferred_blob_uuids_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment