cef/tests/ceftests/thread_unittest.cc

444 lines
13 KiB
C++
Raw Normal View History

2016-11-12 00:22:53 +01:00
// Copyright 2016 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "include/base/cef_callback.h"
#include "include/base/cef_callback_helpers.h"
2016-11-12 00:22:53 +01:00
#include "include/cef_task.h"
#include "include/cef_thread.h"
#include "include/wrapper/cef_closure_task.h"
#include "tests/ceftests/test_handler.h"
#include "tests/gtest/include/gtest/gtest.h"
#include "tests/shared/browser/client_app_browser.h"
#include "tests/shared/renderer/client_app_renderer.h"
2016-11-12 00:22:53 +01:00
using client::ClientAppBrowser;
using client::ClientAppRenderer;
namespace {
// Base class for creating and testing threads.
class ThreadTest : public base::RefCountedThreadSafe<ThreadTest> {
public:
ThreadTest() = default;
virtual ~ThreadTest() = default;
2016-11-12 00:22:53 +01:00
// Create the test thread. Should only be called one time.
void CreateTestThread() {
EXPECT_TRUE(!thread_.get());
owner_task_runner_ = CefTaskRunner::GetForCurrentThread();
EXPECT_TRUE(owner_task_runner_.get());
EXPECT_TRUE(owner_task_runner_->BelongsToCurrentThread());
thread_ = CefThread::CreateThread("test_thread");
EXPECT_TRUE(thread_.get());
EXPECT_TRUE(thread_->IsRunning());
thread_id_ = thread_->GetPlatformThreadId();
EXPECT_NE(thread_id_, kInvalidPlatformThreadId);
thread_task_runner_ = thread_->GetTaskRunner();
EXPECT_TRUE(thread_task_runner_.get());
AssertOwnerThread();
}
// Destroy the test thread. Should only be called one time.
void DestroyTestThread() {
EXPECT_TRUE(thread_.get());
AssertOwnerThread();
EXPECT_TRUE(thread_->IsRunning());
thread_->Stop();
EXPECT_FALSE(thread_->IsRunning());
AssertOwnerThread();
thread_ = nullptr;
}
// Execute |test_task| on the test thread. After execution |callback| will be
// posted to |callback_task_runner|.
void PostOnTestThreadAndCallback(
base::OnceClosure test_task,
2016-11-12 00:22:53 +01:00
CefRefPtr<CefTaskRunner> callback_task_runner,
base::OnceClosure callback) {
2016-11-12 00:22:53 +01:00
EXPECT_TRUE(thread_.get());
thread_task_runner_->PostTask(CefCreateClosureTask(base::BindOnce(
&ThreadTest::ExecuteOnTestThread, this, std::move(test_task),
callback_task_runner, std::move(callback))));
2016-11-12 00:22:53 +01:00
}
CefRefPtr<CefTaskRunner> owner_task_runner() const {
return owner_task_runner_;
}
CefRefPtr<CefTaskRunner> thread_task_runner() const {
return thread_task_runner_;
}
// Assert that we're running on the owner thread.
void AssertOwnerThread() {
EXPECT_TRUE(owner_task_runner_->BelongsToCurrentThread());
EXPECT_FALSE(thread_task_runner_->BelongsToCurrentThread());
EXPECT_TRUE(thread_task_runner_->IsSame(thread_->GetTaskRunner()));
EXPECT_EQ(thread_id_, thread_->GetPlatformThreadId());
}
// Assert that we're running on the test thread.
void AssertTestThread() {
EXPECT_FALSE(owner_task_runner_->BelongsToCurrentThread());
EXPECT_TRUE(thread_task_runner_->BelongsToCurrentThread());
EXPECT_TRUE(thread_task_runner_->IsSame(thread_->GetTaskRunner()));
EXPECT_EQ(thread_id_, thread_->GetPlatformThreadId());
}
private:
// Helper for PostOnTestThreadAndCallback().
void ExecuteOnTestThread(base::OnceClosure test_task,
2016-11-12 00:22:53 +01:00
CefRefPtr<CefTaskRunner> callback_task_runner,
base::OnceClosure callback) {
2016-11-12 00:22:53 +01:00
AssertTestThread();
std::move(test_task).Run();
2016-11-12 00:22:53 +01:00
callback_task_runner->PostTask(CefCreateClosureTask(std::move(callback)));
2016-11-12 00:22:53 +01:00
}
CefRefPtr<CefTaskRunner> owner_task_runner_;
CefRefPtr<CefThread> thread_;
cef_platform_thread_id_t thread_id_;
CefRefPtr<CefTaskRunner> thread_task_runner_;
DISALLOW_COPY_AND_ASSIGN(ThreadTest);
};
} // namespace
// Test thread creation and destruction without any task execution.
TEST(ThreadTest, Create) {
scoped_refptr<ThreadTest> thread_test = new ThreadTest();
thread_test->CreateTestThread();
thread_test->DestroyTestThread();
thread_test = nullptr;
}
namespace {
// Simple implementation of ThreadTest that creates a thread, executes tasks
// on the thread, then destroys the thread after all tasks have completed.
class SimpleThreadTest : public ThreadTest {
public:
SimpleThreadTest(size_t expected_task_count,
base::OnceClosure task_callback,
base::OnceClosure done_callback)
: expected_task_count_(expected_task_count),
task_callback_(std::move(task_callback)),
done_callback_(std::move(done_callback)) {}
2016-11-12 00:22:53 +01:00
void RunTest() {
// Create the test thread.
CreateTestThread();
for (size_t i = 0U; i < expected_task_count_; ++i) {
// Execute Task() on the test thread and then call Done() on this thread.
PostOnTestThreadAndCallback(
base::BindOnce(&SimpleThreadTest::Task, this), owner_task_runner(),
base::BindOnce(&SimpleThreadTest::Done, this));
2016-11-12 00:22:53 +01:00
}
}
void DestroyTest() {
EXPECT_EQ(expected_task_count_, got_task_count_);
EXPECT_EQ(expected_task_count_, got_done_count_);
// Destroy the test thread.
DestroyTestThread();
}
private:
void Task() {
AssertTestThread();
got_task_count_++;
2023-01-02 23:59:03 +01:00
if (!task_callback_.is_null()) {
std::move(task_callback_).Run();
2023-01-02 23:59:03 +01:00
}
2016-11-12 00:22:53 +01:00
}
void Done() {
AssertOwnerThread();
2023-01-02 23:59:03 +01:00
if (++got_done_count_ == expected_task_count_ &&
!done_callback_.is_null()) {
std::move(done_callback_).Run();
2023-01-02 23:59:03 +01:00
}
2016-11-12 00:22:53 +01:00
}
const size_t expected_task_count_;
base::OnceClosure task_callback_;
base::OnceClosure done_callback_;
2016-11-12 00:22:53 +01:00
size_t got_task_count_ = 0U;
size_t got_done_count_ = 0U;
2016-11-12 00:22:53 +01:00
DISALLOW_COPY_AND_ASSIGN(SimpleThreadTest);
};
// Test creation/execution of threads in the browser process.
const char kBrowserThreadTestHtml[] = "https://test.com/browserthread.html";
2016-11-12 00:22:53 +01:00
// Browser side.
class BrowserThreadTestHandler : public TestHandler {
public:
explicit BrowserThreadTestHandler(CefThreadId owner_thread_id)
: owner_thread_id_(owner_thread_id) {}
2016-11-12 00:22:53 +01:00
void RunTest() override {
AddResource(kBrowserThreadTestHtml, "<html><body>Test</body></html>",
"text/html");
CreateBrowser(kBrowserThreadTestHtml);
// Time out the test after a reasonable period of time.
SetTestTimeout();
}
void RunThreadTestOnOwnerThread() {
if (!CefCurrentlyOn(owner_thread_id_)) {
// Run the test on the desired owner thread.
CefPostTask(
owner_thread_id_,
base::BindOnce(&BrowserThreadTestHandler::RunThreadTestOnOwnerThread,
this));
2016-11-12 00:22:53 +01:00
return;
}
EXPECT_FALSE(thread_test_.get());
thread_test_ = new SimpleThreadTest(
3, base::DoNothing(),
base::BindOnce(&BrowserThreadTestHandler::DoneOnOwnerThread, this));
2016-11-12 00:22:53 +01:00
thread_test_->RunTest();
}
void DoneOnOwnerThread() {
// Let the call stack unwind before destroying |thread_test_|.
CefPostTask(owner_thread_id_,
base::BindOnce(
&BrowserThreadTestHandler::DestroyTestOnOwnerThread, this));
2016-11-12 00:22:53 +01:00
}
void DestroyTestOnOwnerThread() {
EXPECT_TRUE(CefCurrentlyOn(owner_thread_id_));
EXPECT_TRUE(thread_test_.get());
if (thread_test_) {
thread_test_->DestroyTest();
thread_test_ = nullptr;
}
got_test_done_.yes();
// Call DestroyTest() on the UI thread.
CefPostTask(TID_UI,
base::BindOnce(&BrowserThreadTestHandler::DestroyTest, this));
2016-11-12 00:22:53 +01:00
}
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) override {
2023-01-02 23:59:03 +01:00
if (!isLoading) {
2016-11-12 00:22:53 +01:00
RunThreadTestOnOwnerThread();
2023-01-02 23:59:03 +01:00
}
2016-11-12 00:22:53 +01:00
}
private:
void DestroyTest() override {
EXPECT_FALSE(thread_test_.get());
EXPECT_TRUE(got_test_done_);
TestHandler::DestroyTest();
}
const CefThreadId owner_thread_id_;
scoped_refptr<SimpleThreadTest> thread_test_;
TrackCallback got_test_done_;
IMPLEMENT_REFCOUNTING(BrowserThreadTestHandler);
DISALLOW_COPY_AND_ASSIGN(BrowserThreadTestHandler);
};
} // namespace
// Test creation of new threads from the browser UI thread.
TEST(ThreadTest, CreateFromBrowserUIThread) {
CefRefPtr<BrowserThreadTestHandler> handler =
new BrowserThreadTestHandler(TID_UI);
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
// Test creation of new threads from the browser IO thread.
TEST(ThreadTest, CreateFromBrowserIOThread) {
CefRefPtr<BrowserThreadTestHandler> handler =
new BrowserThreadTestHandler(TID_IO);
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
// Test creation of new threads from the browser FILE thread.
TEST(ThreadTest, CreateFromBrowserFILEThread) {
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
// Use a FILE thread that will run tasks relatively quickly.
2016-11-12 00:22:53 +01:00
CefRefPtr<BrowserThreadTestHandler> handler =
Add chrome runtime support for more callbacks and ceftests (see issue #2969) This change adds support for: - Protocol and request handling. - Loading and navigation events. - Display and focus events. - Mouse/keyboard events. - Popup browsers. - Callbacks in the renderer process. - Misc. functionality required for ceftests. This change also adds a new CefBrowserProcessHandler::GetCookieableSchemes callback for configuring global state that will be applied to all CefCookieManagers by default. This global callback is currently required by the chrome runtime because the primary ProfileImpl is created via ChromeBrowserMainParts::PreMainMessageLoopRun (CreatePrimaryProfile) before OnContextCreated can be called. ProfileImpl will use the "C:\Users\[user]\AppData\Local\CEF\User Data\Default" directory by default (on Windows). Cookies may persist in this directory when running ceftests and may need to be manually deleted if those tests fail. Remaining work includes: - Support for client-created request contexts. - Embedding the browser in a Views hierarchy (cefclient support). - TryCloseBrowser and DoClose support. - Most of the CefSettings configuration. - DevTools protocol and window control (ShowDevTools, ExecuteDevToolsMethod). - CEF-specific WebUI pages (about, license, webui-hosts). - Context menu customization (CefContextMenuHandler). - Auto resize (SetAutoResizeEnabled). - Zoom settings (SetZoomLevel). - File dialog runner (RunFileDialog). - File and JS dialog handlers (CefDialogHandler, CefJSDialogHandler). - Extension loading (LoadExtension, etc). - Plugin loading (OnBeforePluginLoad). - Widevine loading (CefRegisterWidevineCdm). - PDF and print preview does not display. - Crash reporting is untested. - Mac: Web content loads but does not display. The following ceftests are now passing when run with the "--enable-chrome-runtime" command-line flag: CorsTest.* DisplayTest.*:-DisplayTest.AutoResize DOMTest.* DraggableRegionsTest.* ImageTest.* MessageRouterTest.* NavigationTest.* ParserTest.* RequestContextTest.*Global* RequestTest.* ResourceManagerTest.* ResourceRequestHandlerTest.* ResponseTest.* SchemeHandlerTest.* ServerTest.* StreamResourceHandlerTest.* StreamTest.* StringTest.* TaskTest.* TestServerTest.* ThreadTest.* URLRequestTest.*Global* V8Test.*:-V8Test.OnUncaughtExceptionDevTools ValuesTest.* WaitableEventTest.* XmlReaderTest.* ZipReaderTest.*
2020-09-25 03:40:47 +02:00
new BrowserThreadTestHandler(TID_FILE_USER_VISIBLE);
2016-11-12 00:22:53 +01:00
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
namespace {
// Test creation/execution of threads in the render process.
const char kRenderThreadTestHtml[] = "https://test.com/renderthread.html";
2016-11-12 00:22:53 +01:00
const char kRenderThreadTestMsg[] = "ThreadTest.RenderThreadTest";
// Browser side.
class RenderThreadTestHandler : public TestHandler {
public:
RenderThreadTestHandler() = default;
2016-11-12 00:22:53 +01:00
void RunTest() override {
AddResource(kRenderThreadTestHtml, "<html><body>Test</body></html>",
"text/html");
CreateBrowser(kRenderThreadTestHtml);
// Time out the test after a reasonable period of time.
SetTestTimeout();
}
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) override {
if (!isLoading) {
// Return the test in the render process.
CefRefPtr<CefProcessMessage> msg =
CefProcessMessage::Create(kRenderThreadTestMsg);
Move message routing from CefBrowser to CefFrame (see issue #2498). This change moves the SendProcessMessage method from CefBrowser to CefFrame and adds CefBrowser parameters to OnProcessMessageReceived and OnDraggableRegionsChanged. The internal implementation has changed as follows: - Frame IDs are now a 64-bit combination of the 32-bit render_process_id and render_routing_id values that uniquely identify a RenderFrameHost (RFH). - CefFrameHostImpl objects are now managed by CefBrowserInfo with life span tied to RFH expectations. Specifically, a CefFrameHostImpl object representing a sub-frame will be created when a RenderFrame is created in the renderer process and detached when the associated RenderFrame is deleted or the renderer process in which it runs has died. - The CefFrameHostImpl object representing the main frame will always be valid but the underlying RFH (and associated frame ID) may change over time as a result of cross-origin navigations. Despite these changes calling LoadURL on the main frame object in the browser process will always navigate as expected. - Speculative RFHs, which may be created as a result of a cross-origin navigation and discarded if that navigation is not committed, are now handled correctly (e.g. ignored in most cases until they're committed). - It is less likely, but still possible, to receive a CefFrame object with an invalid frame ID (ID < 0). This can happen in cases where a RFH has not yet been created for a sub-frame. For example, when OnBeforeBrowse is called before initiating navigation in a previously nonexisting sub-frame. To test: All tests pass with NetworkService enabled and disabled.
2019-05-24 22:23:43 +02:00
browser->GetMainFrame()->SendProcessMessage(PID_RENDERER, msg);
2016-11-12 00:22:53 +01:00
}
}
bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
Move message routing from CefBrowser to CefFrame (see issue #2498). This change moves the SendProcessMessage method from CefBrowser to CefFrame and adds CefBrowser parameters to OnProcessMessageReceived and OnDraggableRegionsChanged. The internal implementation has changed as follows: - Frame IDs are now a 64-bit combination of the 32-bit render_process_id and render_routing_id values that uniquely identify a RenderFrameHost (RFH). - CefFrameHostImpl objects are now managed by CefBrowserInfo with life span tied to RFH expectations. Specifically, a CefFrameHostImpl object representing a sub-frame will be created when a RenderFrame is created in the renderer process and detached when the associated RenderFrame is deleted or the renderer process in which it runs has died. - The CefFrameHostImpl object representing the main frame will always be valid but the underlying RFH (and associated frame ID) may change over time as a result of cross-origin navigations. Despite these changes calling LoadURL on the main frame object in the browser process will always navigate as expected. - Speculative RFHs, which may be created as a result of a cross-origin navigation and discarded if that navigation is not committed, are now handled correctly (e.g. ignored in most cases until they're committed). - It is less likely, but still possible, to receive a CefFrame object with an invalid frame ID (ID < 0). This can happen in cases where a RFH has not yet been created for a sub-frame. For example, when OnBeforeBrowse is called before initiating navigation in a previously nonexisting sub-frame. To test: All tests pass with NetworkService enabled and disabled.
2019-05-24 22:23:43 +02:00
CefRefPtr<CefFrame> frame,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message) override {
2016-11-12 00:22:53 +01:00
EXPECT_TRUE(browser.get());
Move message routing from CefBrowser to CefFrame (see issue #2498). This change moves the SendProcessMessage method from CefBrowser to CefFrame and adds CefBrowser parameters to OnProcessMessageReceived and OnDraggableRegionsChanged. The internal implementation has changed as follows: - Frame IDs are now a 64-bit combination of the 32-bit render_process_id and render_routing_id values that uniquely identify a RenderFrameHost (RFH). - CefFrameHostImpl objects are now managed by CefBrowserInfo with life span tied to RFH expectations. Specifically, a CefFrameHostImpl object representing a sub-frame will be created when a RenderFrame is created in the renderer process and detached when the associated RenderFrame is deleted or the renderer process in which it runs has died. - The CefFrameHostImpl object representing the main frame will always be valid but the underlying RFH (and associated frame ID) may change over time as a result of cross-origin navigations. Despite these changes calling LoadURL on the main frame object in the browser process will always navigate as expected. - Speculative RFHs, which may be created as a result of a cross-origin navigation and discarded if that navigation is not committed, are now handled correctly (e.g. ignored in most cases until they're committed). - It is less likely, but still possible, to receive a CefFrame object with an invalid frame ID (ID < 0). This can happen in cases where a RFH has not yet been created for a sub-frame. For example, when OnBeforeBrowse is called before initiating navigation in a previously nonexisting sub-frame. To test: All tests pass with NetworkService enabled and disabled.
2019-05-24 22:23:43 +02:00
EXPECT_TRUE(frame.get());
2016-11-12 00:22:53 +01:00
EXPECT_EQ(PID_RENDERER, source_process);
EXPECT_TRUE(message.get());
EXPECT_TRUE(message->IsReadOnly());
const std::string& message_name = message->GetName();
EXPECT_STREQ(kRenderThreadTestMsg, message_name.c_str());
got_message_.yes();
2023-01-02 23:59:03 +01:00
if (message->GetArgumentList()->GetBool(0)) {
2016-11-12 00:22:53 +01:00
got_success_.yes();
2023-01-02 23:59:03 +01:00
}
2016-11-12 00:22:53 +01:00
// Test is complete.
DestroyTest();
return true;
}
protected:
void DestroyTest() override {
EXPECT_TRUE(got_message_);
EXPECT_TRUE(got_success_);
TestHandler::DestroyTest();
}
TrackCallback got_message_;
TrackCallback got_success_;
IMPLEMENT_REFCOUNTING(RenderThreadTestHandler);
DISALLOW_COPY_AND_ASSIGN(RenderThreadTestHandler);
};
// Renderer side.
class RenderThreadRendererTest : public ClientAppRenderer::Delegate {
public:
RenderThreadRendererTest() = default;
2016-11-12 00:22:53 +01:00
bool OnProcessMessageReceived(CefRefPtr<ClientAppRenderer> app,
CefRefPtr<CefBrowser> browser,
Move message routing from CefBrowser to CefFrame (see issue #2498). This change moves the SendProcessMessage method from CefBrowser to CefFrame and adds CefBrowser parameters to OnProcessMessageReceived and OnDraggableRegionsChanged. The internal implementation has changed as follows: - Frame IDs are now a 64-bit combination of the 32-bit render_process_id and render_routing_id values that uniquely identify a RenderFrameHost (RFH). - CefFrameHostImpl objects are now managed by CefBrowserInfo with life span tied to RFH expectations. Specifically, a CefFrameHostImpl object representing a sub-frame will be created when a RenderFrame is created in the renderer process and detached when the associated RenderFrame is deleted or the renderer process in which it runs has died. - The CefFrameHostImpl object representing the main frame will always be valid but the underlying RFH (and associated frame ID) may change over time as a result of cross-origin navigations. Despite these changes calling LoadURL on the main frame object in the browser process will always navigate as expected. - Speculative RFHs, which may be created as a result of a cross-origin navigation and discarded if that navigation is not committed, are now handled correctly (e.g. ignored in most cases until they're committed). - It is less likely, but still possible, to receive a CefFrame object with an invalid frame ID (ID < 0). This can happen in cases where a RFH has not yet been created for a sub-frame. For example, when OnBeforeBrowse is called before initiating navigation in a previously nonexisting sub-frame. To test: All tests pass with NetworkService enabled and disabled.
2019-05-24 22:23:43 +02:00
CefRefPtr<CefFrame> frame,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message) override {
2016-11-12 00:22:53 +01:00
if (message->GetName().ToString() == kRenderThreadTestMsg) {
browser_ = browser;
EXPECT_FALSE(thread_test_.get());
thread_test_ = new SimpleThreadTest(
3, base::DoNothing(),
base::BindOnce(&RenderThreadRendererTest::Done, this));
2016-11-12 00:22:53 +01:00
thread_test_->RunTest();
return true;
}
// Message not handled.
return false;
}
private:
void Done() {
// Let the call stack unwind before destroying |thread_test_|.
CefPostTask(TID_RENDERER,
base::BindOnce(&RenderThreadRendererTest::DestroyTest, this));
2016-11-12 00:22:53 +01:00
}
void DestroyTest() {
EXPECT_TRUE(thread_test_.get());
if (thread_test_) {
thread_test_->DestroyTest();
thread_test_ = nullptr;
}
// Check if the test has failed.
bool result = !TestFailed();
// Return the result to the browser process.
CefRefPtr<CefProcessMessage> return_msg =
CefProcessMessage::Create(kRenderThreadTestMsg);
EXPECT_TRUE(return_msg->GetArgumentList()->SetBool(0, result));
Move message routing from CefBrowser to CefFrame (see issue #2498). This change moves the SendProcessMessage method from CefBrowser to CefFrame and adds CefBrowser parameters to OnProcessMessageReceived and OnDraggableRegionsChanged. The internal implementation has changed as follows: - Frame IDs are now a 64-bit combination of the 32-bit render_process_id and render_routing_id values that uniquely identify a RenderFrameHost (RFH). - CefFrameHostImpl objects are now managed by CefBrowserInfo with life span tied to RFH expectations. Specifically, a CefFrameHostImpl object representing a sub-frame will be created when a RenderFrame is created in the renderer process and detached when the associated RenderFrame is deleted or the renderer process in which it runs has died. - The CefFrameHostImpl object representing the main frame will always be valid but the underlying RFH (and associated frame ID) may change over time as a result of cross-origin navigations. Despite these changes calling LoadURL on the main frame object in the browser process will always navigate as expected. - Speculative RFHs, which may be created as a result of a cross-origin navigation and discarded if that navigation is not committed, are now handled correctly (e.g. ignored in most cases until they're committed). - It is less likely, but still possible, to receive a CefFrame object with an invalid frame ID (ID < 0). This can happen in cases where a RFH has not yet been created for a sub-frame. For example, when OnBeforeBrowse is called before initiating navigation in a previously nonexisting sub-frame. To test: All tests pass with NetworkService enabled and disabled.
2019-05-24 22:23:43 +02:00
browser_->GetMainFrame()->SendProcessMessage(PID_BROWSER, return_msg);
2016-11-12 00:22:53 +01:00
browser_ = nullptr;
}
CefRefPtr<CefBrowser> browser_;
scoped_refptr<SimpleThreadTest> thread_test_;
IMPLEMENT_REFCOUNTING(RenderThreadRendererTest);
DISALLOW_COPY_AND_ASSIGN(RenderThreadRendererTest);
};
} // namespace
TEST(ThreadTest, CreateFromRenderThread) {
CefRefPtr<RenderThreadTestHandler> handler = new RenderThreadTestHandler();
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
// Entry point for creating request handler renderer test objects.
// Called from client_app_delegates.cc.
void CreateThreadRendererTests(ClientAppRenderer::DelegateSet& delegates) {
2016-11-12 00:22:53 +01:00
delegates.insert(new RenderThreadRendererTest);
}