Fix OSR crash on window.open with new client (fixes issue #2894)

This commit is contained in:
Vladislav 2020-03-06 19:51:58 +00:00 committed by Marshall Greenblatt
parent 180e9bd362
commit fecd582035
2 changed files with 225 additions and 0 deletions

View File

@ -349,6 +349,12 @@ void CefRenderWidgetHostViewOSR::Show() {
if (is_showing_)
return;
if (!content::GpuDataManagerImpl::GetInstance()->IsGpuCompositingDisabled() &&
!browser_impl_ &&
(!parent_host_view_ || !parent_host_view_->browser_impl_)) {
return;
}
is_showing_ = true;
// If the viz::LocalSurfaceIdAllocation is invalid, we may have been evicted,

View File

@ -172,3 +172,222 @@ TEST(OSRTest, NavigateWhileHidden) {
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}
namespace {
const char kOsrPopupJSOtherClientMainUrl[] =
"http://www.tests-pjse.com/main.html";
class OsrPopupJSOtherClientTestHandler : public TestHandler,
public CefRenderHandler {
public:
OsrPopupJSOtherClientTestHandler(CefRefPtr<CefClient> other) {
other_ = other;
}
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() override {
return this;
}
virtual void GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) override {
rect = CefRect(0, 0, kOsrWidth, kOsrHeight);
}
virtual void OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width,
int height) override {}
void RunTest() override {
AddResource(kOsrPopupJSOtherClientMainUrl, "<html>Main</html>",
"text/html");
// Create the browser.
CreateOSRBrowser(kOsrPopupJSOtherClientMainUrl);
// Time out the test after a reasonable period of time.
SetTestTimeout();
}
bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& target_url,
const CefString& target_frame_name,
cef_window_open_disposition_t target_disposition,
bool user_gesture,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings,
CefRefPtr<CefDictionaryValue>& extra_info,
bool* no_javascript_access) override {
#if defined(OS_WIN)
windowInfo.SetAsWindowless(GetDesktopWindow());
#else
windowInfo.SetAsWindowless(kNullWindowHandle);
#endif
client = other_;
got_before_popup_.yes();
return false;
}
void Close(CefRefPtr<CefBrowser> browser) {
browser->StopLoad();
CloseBrowser(browser, true);
}
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
TestHandler::OnAfterCreated(browser);
if (browser->IsPopup()) {
got_after_created_popup_.yes();
}
}
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) override {
if (isLoading)
return;
if (browser->IsPopup()) {
got_load_end_popup_.yes();
CefPostDelayedTask(
TID_UI,
base::Bind(&OsrPopupJSOtherClientTestHandler::Close, this, browser),
100);
} else {
browser->GetMainFrame()->LoadURL("javascript:window.open('about:blank')");
}
}
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override {
TestHandler::OnBeforeClose(browser);
other_ = nullptr;
if (browser->IsPopup()) {
got_before_close_popup_.yes();
DestroyTest();
}
}
private:
void CreateOSRBrowser(const CefString& url) {
CefWindowInfo windowInfo;
CefBrowserSettings settings;
#if defined(OS_WIN)
windowInfo.SetAsWindowless(GetDesktopWindow());
#else
windowInfo.SetAsWindowless(kNullWindowHandle);
#endif
CefBrowserHost::CreateBrowser(windowInfo, this, url, settings, nullptr,
nullptr);
}
void DestroyTest() override {
EXPECT_TRUE(got_after_created_popup_);
EXPECT_TRUE(got_load_end_popup_);
EXPECT_TRUE(got_before_close_popup_);
EXPECT_TRUE(got_before_popup_);
TestHandler::DestroyTest();
}
TrackCallback got_before_popup_;
TrackCallback got_after_created_popup_;
TrackCallback got_load_end_popup_;
TrackCallback got_before_close_popup_;
CefRefPtr<CefClient> other_;
IMPLEMENT_REFCOUNTING(OsrPopupJSOtherClientTestHandler);
};
class OsrPopupJSOtherCefClient : public CefClient,
public CefLoadHandler,
public CefLifeSpanHandler,
public CefRenderHandler {
public:
OsrPopupJSOtherCefClient() { handler_ = NULL; }
void SetHandler(CefRefPtr<OsrPopupJSOtherClientTestHandler> handler) {
handler_ = handler;
}
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() override { return this; }
virtual CefRefPtr<CefRenderHandler> GetRenderHandler() override {
return this;
}
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override {
return this;
}
virtual void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) override {
if (handler_) {
handler_->OnLoadingStateChange(browser, isLoading, canGoBack,
canGoForward);
}
}
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
handler_->OnAfterCreated(browser);
}
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) override {
handler_->OnBeforeClose(browser);
handler_ = nullptr;
}
virtual bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& target_url,
const CefString& target_frame_name,
cef_window_open_disposition_t target_disposition,
bool user_gesture,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings,
CefRefPtr<CefDictionaryValue>& extra_info,
bool* no_javascript_access) override {
return true;
}
virtual void GetViewRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) override {
rect = CefRect(0, 0, kOsrWidth, kOsrHeight);
}
virtual void OnPaint(CefRefPtr<CefBrowser> browser,
PaintElementType type,
const RectList& dirtyRects,
const void* buffer,
int width,
int height) override {}
private:
CefRefPtr<OsrPopupJSOtherClientTestHandler> handler_;
IMPLEMENT_REFCOUNTING(OsrPopupJSOtherCefClient);
};
} // namespace
// Test creation of an OSR-popup with another client.
TEST(OSRTest, OsrPopupJSOtherClient) {
CefRefPtr<OsrPopupJSOtherCefClient> client = new OsrPopupJSOtherCefClient();
CefRefPtr<OsrPopupJSOtherClientTestHandler> handler =
new OsrPopupJSOtherClientTestHandler(client);
client->SetHandler(handler);
handler->ExecuteTest();
ReleaseAndWaitForDestructor(handler);
}