blob: 96855c96e20f63f30f9fcba54510b96a49b19934 [file] [log] [blame]
// Copyright 2019 The Chromium 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 "base/bind.h"
#include "base/callback.h"
#include "base/run_loop.h"
#include "base/test/test_timeouts.h"
#include "cc/base/switches.h"
#include "content/common/input/input_event.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "third_party/blink/public/platform/web_input_event.h"
namespace content {
class SyntheticInputTest : public ContentBrowserTest {
public:
SyntheticInputTest() {}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitch(cc::switches::kEnableGpuBenchmarking);
}
RenderWidgetHost* GetRenderWidgetHost() const {
RenderWidgetHost* const rwh = shell()
->web_contents()
->GetRenderWidgetHostView()
->GetRenderWidgetHost();
CHECK(rwh);
return rwh;
}
};
class GestureScrollObserver : public RenderWidgetHost::InputEventObserver {
public:
void OnInputEvent(const blink::WebInputEvent& event) override {
if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin)
gesture_scroll_seen_ = true;
}
bool HasSeenGestureScrollBegin() const { return gesture_scroll_seen_; }
bool gesture_scroll_seen_ = false;
};
// This test checks that we destroying a render widget host with an ongoing
// gesture doesn't cause lifetime issues. Namely, that the gesture
// CompletionCallback isn't destroyed before being called or the Mojo pipe
// being closed.
IN_PROC_BROWSER_TEST_F(SyntheticInputTest, DestroyWidgetWithOngoingGesture) {
NavigateToURL(shell(), GURL("about:blank"));
WaitForLoadStop(shell()->web_contents());
GestureScrollObserver gesture_observer;
GetRenderWidgetHost()->AddInputEventObserver(&gesture_observer);
// By starting a gesture, there's a Mojo callback that the renderer is
// waiting on the browser to resolve. If the browser is shutdown before
// ACKing the callback or closing the channel, we'll DCHECK.
ASSERT_TRUE(ExecJs(shell()->web_contents(),
"chrome.gpuBenchmarking.smoothScrollBy(10000, ()=>{}, "
"100, 100, chrome.gpuBenchmarking.TOUCH_INPUT);"));
while (!gesture_observer.HasSeenGestureScrollBegin()) {
base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
run_loop.Run();
}
shell()->Close();
}
} // namespace content