0
Files
src/content/browser/keyboard_lock_browsertest.cc
Lei Zhang 05c13df891 Remove unnecessary ContentBrowserTest::SetUpCommandLine() calls
ContentBrowserTest::SetUpCommandLine() is actually not defined. Calls to
this method ends up running BrowserTestBase::SetUpCommandLine(), which
is always going to be empty. Since there is no point in calling this
method, delete all the callers from SetUpCommandLine() overrides. When
the override becomes empty, delete the override altogether.

Make a note of this in the comments in content_browser_test.h. Also fix
some lint errors along the way.

Change-Id: I81f263286d72ebdab68dfd9575ad4cf2b6378a3c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5691227
Reviewed-by: Avi Drissman <avi@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1325736}
2024-07-10 20:59:12 +00:00

892 lines
32 KiB
C++

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/keyboard_lock_browsertest.h"
#include <string>
#include "base/metrics/histogram_base.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/keyboard_lock/keyboard_lock_metrics.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/common/content_features.h"
#include "content/public/test/browser_test.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/public/test/content_mock_cert_verifier.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "third_party/blink/public/mojom/frame/fullscreen.mojom.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/native_widget_types.h"
#ifdef USE_AURA
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/web_contents/web_contents_view_aura.h"
#endif // USE_AURA
namespace content {
namespace {
constexpr char kFullscreenFramePath[] = "/fullscreen_frame.html";
constexpr char kHelloFramePath[] = "/hello.html";
constexpr char kInputFieldFramePath[] = "/page_with_input_field.html";
// Set up a DOM structure which contains three inner iframes for testing:
// - Same domain iframe w/ fullscreen attribute.
// - Cross domain iframe.
// - Cross domain iframe w/ fullscreen attribute.
constexpr char kCrossSiteFramePath[] =
"/cross_site_iframe_factory.html"
"?a(a{allowfullscreen}(),b(),c{allowfullscreen}())";
constexpr char kCrossSiteTopLevelDomain[] = "a.com";
constexpr char kChildIframeName_0[] = "child-0";
constexpr char kChildIframeName_1[] = "child-1";
constexpr char kChildIframeName_2[] = "child-2";
constexpr char kCrossSiteChildDomain1[] = "b.com";
constexpr char kCrossSiteChildDomain2[] = "c.com";
constexpr char kKeyboardLockMethodExistanceCheck[] =
"(navigator.keyboard != undefined) &&"
"(navigator.keyboard.lock != undefined);";
constexpr char kKeyboardLockMethodCallWithAllKeys[] =
"navigator.keyboard.lock().then("
" () => true,"
" () => false,"
");";
constexpr char kKeyboardLockMethodCallWithSomeKeys[] =
"navigator.keyboard.lock(['MetaLeft', 'Tab', 'AltLeft']).then("
" () => true,"
" () => false,"
");";
// Calling lock() with no valid key codes will cause the promise to be rejected.
constexpr char kKeyboardLockMethodCallWithAllInvalidKeys[] =
"navigator.keyboard.lock(['BlerghLeft', 'BlarghRight']).then("
" () => false,"
" () => true,"
");";
// Calling lock() with some invalid key codes will reject the promise.
constexpr char kKeyboardLockMethodCallWithSomeInvalidKeys[] =
"navigator.keyboard.lock(['Tab', 'BlarghTab', 'Space', 'BlerghLeft']).then("
" () => false,"
" () => true,"
");";
constexpr char kKeyboardUnlockMethodCall[] = "navigator.keyboard.unlock()";
constexpr char kFocusInputFieldScript[] =
"function onInput(e) {"
" resultQueue.push(getInputFieldText());"
"}"
"inputField = document.getElementById('text-field');"
"inputField.addEventListener('input', onInput, false);";
void SimulateKeyPress(WebContents* web_contents,
RenderFrameHost* event_recipient,
const std::string& code_string,
const std::string& expected_result) {
ui::DomKey dom_key = ui::KeycodeConverter::KeyStringToDomKey(code_string);
ui::DomCode dom_code = ui::KeycodeConverter::CodeStringToDomCode(code_string);
SimulateKeyPress(web_contents, dom_key, dom_code,
ui::DomCodeToUsLayoutKeyboardCode(dom_code), false, false,
false, false);
ASSERT_EQ(expected_result, EvalJs(event_recipient, "waitForInput()"));
}
#if defined(USE_AURA)
bool g_window_has_focus = false;
class TestRenderWidgetHostView : public RenderWidgetHostViewAura {
public:
explicit TestRenderWidgetHostView(RenderWidgetHost* host)
: RenderWidgetHostViewAura(host) {}
~TestRenderWidgetHostView() override {}
bool HasFocus() override { return g_window_has_focus; }
void OnWindowFocused(aura::Window* gained_focus,
aura::Window* lost_focus) override {
// Ignore all focus events.
}
};
#endif // USE_AURA
class FakeKeyboardLockWebContentsDelegate : public WebContentsDelegate {
public:
FakeKeyboardLockWebContentsDelegate() {}
FakeKeyboardLockWebContentsDelegate(
const FakeKeyboardLockWebContentsDelegate&) = delete;
FakeKeyboardLockWebContentsDelegate& operator=(
const FakeKeyboardLockWebContentsDelegate&) = delete;
~FakeKeyboardLockWebContentsDelegate() override {}
// WebContentsDelegate overrides.
void EnterFullscreenModeForTab(
RenderFrameHost* requesting_frame,
const blink::mojom::FullscreenOptions& options) override;
void ExitFullscreenModeForTab(WebContents* web_contents) override;
bool IsFullscreenForTabOrPending(const WebContents* web_contents) override;
void RequestKeyboardLock(WebContents* web_contents,
bool esc_key_locked) override;
void CancelKeyboardLockRequest(WebContents* web_contents) override;
private:
bool is_fullscreen_ = false;
bool keyboard_lock_requested_ = false;
};
void FakeKeyboardLockWebContentsDelegate::EnterFullscreenModeForTab(
RenderFrameHost* requesting_frame,
const blink::mojom::FullscreenOptions& options) {
is_fullscreen_ = true;
auto* web_contents = WebContents::FromRenderFrameHost(requesting_frame);
if (keyboard_lock_requested_)
web_contents->GotResponseToKeyboardLockRequest(/*allowed=*/true);
}
void FakeKeyboardLockWebContentsDelegate::ExitFullscreenModeForTab(
WebContents* web_contents) {
is_fullscreen_ = false;
if (keyboard_lock_requested_)
web_contents->GotResponseToKeyboardLockRequest(/*allowed=*/false);
}
bool FakeKeyboardLockWebContentsDelegate::IsFullscreenForTabOrPending(
const WebContents* web_contents) {
return is_fullscreen_;
}
void FakeKeyboardLockWebContentsDelegate::RequestKeyboardLock(
WebContents* web_contents,
bool esc_key_locked) {
keyboard_lock_requested_ = true;
web_contents->GotResponseToKeyboardLockRequest(/*allowed=*/true);
}
void FakeKeyboardLockWebContentsDelegate::CancelKeyboardLockRequest(
WebContents* web_contents) {
keyboard_lock_requested_ = false;
}
} // namespace
#if defined(USE_AURA)
void SetWindowFocusForKeyboardLockBrowserTests(bool is_focused) {
g_window_has_focus = is_focused;
}
void InstallCreateHooksForKeyboardLockBrowserTests() {
WebContentsViewAura::InstallCreateHookForTests(
[](RenderWidgetHost* host) -> RenderWidgetHostViewAura* {
return new TestRenderWidgetHostView(host);
});
}
#endif // USE_AURA
class KeyboardLockBrowserTest : public ContentBrowserTest {
public:
KeyboardLockBrowserTest();
~KeyboardLockBrowserTest() override;
protected:
// ContentBrowserTest overrides.
void SetUp() override;
void SetUpCommandLine(base::CommandLine* command_line) override;
void SetUpOnMainThread() override;
void SetUpInProcessBrowserTestFixture() override;
void TearDownInProcessBrowserTestFixture() override;
// Helper methods for common tasks.
bool KeyboardLockApiExists();
void NavigateToTestURL(const GURL& gurl);
void RequestKeyboardLock(const base::Location& from_here,
bool lock_all_keys = true);
void CancelKeyboardLock(const base::Location& from_here);
void EnterFullscreen(const base::Location& from_here);
void ExitFullscreen(const base::Location& from_here);
void FocusContent(const base::Location& from_here);
void BlurContent(const base::Location& from_here);
void VerifyKeyboardLockState(const base::Location& from_here);
WebContentsImpl* web_contents() const {
return static_cast<WebContentsImpl*>(shell()->web_contents());
}
net::EmbeddedTestServer* https_test_server() { return &https_test_server_; }
GURL https_fullscreen_frame() {
return https_test_server()->GetURL(kFullscreenFramePath);
}
GURL https_cross_site_frame() {
return https_test_server()->GetURL(kCrossSiteTopLevelDomain,
kCrossSiteFramePath);
}
base::test::ScopedFeatureList* feature_list() {
return &scoped_feature_list_;
}
WebContentsDelegate* web_contents_delegate() {
return &web_contents_delegate_;
}
private:
content::ContentMockCertVerifier mock_cert_verifier_;
base::test::ScopedFeatureList scoped_feature_list_;
net::EmbeddedTestServer https_test_server_;
FakeKeyboardLockWebContentsDelegate web_contents_delegate_;
};
KeyboardLockBrowserTest::KeyboardLockBrowserTest()
: https_test_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
KeyboardLockBrowserTest::~KeyboardLockBrowserTest() = default;
void KeyboardLockBrowserTest::SetUp() {
// Assume we have focus to start with.
SetWindowFocusForKeyboardLockBrowserTests(true);
InstallCreateHooksForKeyboardLockBrowserTests();
ContentBrowserTest::SetUp();
}
void KeyboardLockBrowserTest::SetUpCommandLine(
base::CommandLine* command_line) {
mock_cert_verifier_.SetUpCommandLine(command_line);
}
void KeyboardLockBrowserTest::SetUpOnMainThread() {
ContentBrowserTest::SetUpOnMainThread();
mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
web_contents()->SetDelegate(&web_contents_delegate_);
// KeyboardLock requires a secure context (HTTPS).
https_test_server()->AddDefaultHandlers(GetTestDataFilePath());
host_resolver()->AddRule("*", "127.0.0.1");
SetupCrossSiteRedirector(https_test_server());
ASSERT_TRUE(https_test_server()->Start());
}
void KeyboardLockBrowserTest::SetUpInProcessBrowserTestFixture() {
ContentBrowserTest::SetUpInProcessBrowserTestFixture();
mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
}
void KeyboardLockBrowserTest::TearDownInProcessBrowserTestFixture() {
ContentBrowserTest::TearDownInProcessBrowserTestFixture();
mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
}
bool KeyboardLockBrowserTest::KeyboardLockApiExists() {
return EvalJs(web_contents(), kKeyboardLockMethodExistanceCheck)
.ExtractBool();
}
void KeyboardLockBrowserTest::NavigateToTestURL(const GURL& gurl) {
ASSERT_TRUE(NavigateToURL(shell(), gurl));
ASSERT_TRUE(KeyboardLockApiExists());
// Ensure the window has focus and is in windowed mode after the navigation.
FocusContent(FROM_HERE);
ExitFullscreen(FROM_HERE);
}
void KeyboardLockBrowserTest::RequestKeyboardLock(
const base::Location& from_here,
bool lock_all_keys /*=true*/) {
// keyboard.lock() is an async call which requires a promise handling dance.
bool result = EvalJs(web_contents()->GetPrimaryMainFrame(),
lock_all_keys ? kKeyboardLockMethodCallWithAllKeys
: kKeyboardLockMethodCallWithSomeKeys)
.ExtractBool();
ASSERT_TRUE(result) << "Location: " << from_here.ToString();
ASSERT_EQ(result, web_contents()->GetKeyboardLockWidget() != nullptr)
<< "Location: " << from_here.ToString();
VerifyKeyboardLockState(from_here);
}
void KeyboardLockBrowserTest::CancelKeyboardLock(
const base::Location& from_here) {
// keyboard.unlock() is a synchronous call.
ASSERT_TRUE(
ExecJs(web_contents()->GetPrimaryMainFrame(), kKeyboardUnlockMethodCall));
ASSERT_EQ(nullptr, web_contents()->GetKeyboardLockWidget())
<< "Location: " << from_here.ToString();
VerifyKeyboardLockState(from_here);
}
void KeyboardLockBrowserTest::EnterFullscreen(const base::Location& from_here) {
web_contents()->EnterFullscreenMode(web_contents()->GetPrimaryMainFrame(),
{});
ASSERT_TRUE(web_contents()->IsFullscreen())
<< "Location: " << from_here.ToString();
VerifyKeyboardLockState(from_here);
}
void KeyboardLockBrowserTest::ExitFullscreen(const base::Location& from_here) {
web_contents()->ExitFullscreenMode(/*should_resize=*/true);
ASSERT_FALSE(web_contents()->IsFullscreen())
<< "Location: " << from_here.ToString();
VerifyKeyboardLockState(from_here);
}
void KeyboardLockBrowserTest::FocusContent(const base::Location& from_here) {
SetWindowFocusForKeyboardLockBrowserTests(true);
RenderWidgetHostImpl* host = RenderWidgetHostImpl::From(
web_contents()->GetRenderWidgetHostView()->GetRenderWidgetHost());
host->GotFocus();
host->SetActive(true);
ASSERT_TRUE(web_contents()->GetRenderWidgetHostView()->HasFocus())
<< "Location: " << from_here.ToString();
VerifyKeyboardLockState(from_here);
}
void KeyboardLockBrowserTest::BlurContent(const base::Location& from_here) {
SetWindowFocusForKeyboardLockBrowserTests(false);
RenderWidgetHostImpl* host = RenderWidgetHostImpl::From(
web_contents()->GetRenderWidgetHostView()->GetRenderWidgetHost());
host->SetActive(false);
host->LostFocus();
ASSERT_FALSE(web_contents()->GetRenderWidgetHostView()->HasFocus())
<< "Location: " << from_here.ToString();
VerifyKeyboardLockState(from_here);
}
void KeyboardLockBrowserTest::VerifyKeyboardLockState(
const base::Location& from_here) {
bool keyboard_lock_requested = !!web_contents()->GetKeyboardLockWidget();
bool ux_conditions_satisfied =
web_contents()->GetRenderWidgetHostView()->HasFocus() &&
web_contents()->IsFullscreen();
bool keyboard_lock_active =
web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked();
// Keyboard lock only active when requested and the UX is in the right state.
ASSERT_EQ(keyboard_lock_active,
ux_conditions_satisfied && keyboard_lock_requested)
<< "Location: " << from_here.ToString();
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, SingleLockCall) {
NavigateToTestURL(https_fullscreen_frame());
base::HistogramTester uma;
RequestKeyboardLock(FROM_HERE);
// Don't explicitly call CancelKeyboardLock().
uma.ExpectTotalCount(kKeyboardLockMethodCalledHistogramName, 1);
uma.ExpectBucketCount(kKeyboardLockMethodCalledHistogramName,
static_cast<int>(KeyboardLockMethods::kRequestAllKeys),
1);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, SingleLockCallForSomeKeys) {
NavigateToTestURL(https_fullscreen_frame());
base::HistogramTester uma;
RequestKeyboardLock(FROM_HERE, /*lock_all_keys=*/false);
// Don't explicitly call CancelKeyboardLock().
uma.ExpectTotalCount(kKeyboardLockMethodCalledHistogramName, 1);
uma.ExpectBucketCount(kKeyboardLockMethodCalledHistogramName,
static_cast<int>(KeyboardLockMethods::kRequestSomeKeys),
1);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, SingleLockWithCancelCall) {
NavigateToTestURL(https_fullscreen_frame());
base::HistogramTester uma;
RequestKeyboardLock(FROM_HERE);
CancelKeyboardLock(FROM_HERE);
uma.ExpectTotalCount(kKeyboardLockMethodCalledHistogramName, 2);
uma.ExpectBucketCount(kKeyboardLockMethodCalledHistogramName,
static_cast<int>(KeyboardLockMethods::kRequestAllKeys),
1);
uma.ExpectBucketCount(kKeyboardLockMethodCalledHistogramName,
static_cast<int>(KeyboardLockMethods::kCancelLock), 1);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, LockCalledBeforeFullscreen) {
GURL url_for_test = https_fullscreen_frame();
NavigateToTestURL(url_for_test);
RequestKeyboardLock(FROM_HERE);
EnterFullscreen(FROM_HERE);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, LockCalledAfterFullscreen) {
GURL url_for_test = https_fullscreen_frame();
NavigateToTestURL(url_for_test);
EnterFullscreen(FROM_HERE);
RequestKeyboardLock(FROM_HERE);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
LockAndCancelCyclingNoActivation) {
NavigateToTestURL(https_fullscreen_frame());
base::HistogramTester uma;
RequestKeyboardLock(FROM_HERE);
CancelKeyboardLock(FROM_HERE);
RequestKeyboardLock(FROM_HERE, /*lock_all_keys=*/false);
CancelKeyboardLock(FROM_HERE);
RequestKeyboardLock(FROM_HERE);
CancelKeyboardLock(FROM_HERE);
RequestKeyboardLock(FROM_HERE);
CancelKeyboardLock(FROM_HERE);
uma.ExpectTotalCount(kKeyboardLockMethodCalledHistogramName, 8);
uma.ExpectBucketCount(kKeyboardLockMethodCalledHistogramName,
static_cast<int>(KeyboardLockMethods::kRequestAllKeys),
3);
uma.ExpectBucketCount(kKeyboardLockMethodCalledHistogramName,
static_cast<int>(KeyboardLockMethods::kRequestSomeKeys),
1);
uma.ExpectBucketCount(kKeyboardLockMethodCalledHistogramName,
static_cast<int>(KeyboardLockMethods::kCancelLock), 4);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
LockAndCancelCyclingInFullscreen) {
GURL url_for_test = https_fullscreen_frame();
NavigateToTestURL(url_for_test);
EnterFullscreen(FROM_HERE);
RequestKeyboardLock(FROM_HERE);
CancelKeyboardLock(FROM_HERE);
RequestKeyboardLock(FROM_HERE, /*lock_all_keys=*/false);
CancelKeyboardLock(FROM_HERE);
RequestKeyboardLock(FROM_HERE, /*lock_all_keys=*/false);
CancelKeyboardLock(FROM_HERE);
RequestKeyboardLock(FROM_HERE);
CancelKeyboardLock(FROM_HERE);
RequestKeyboardLock(FROM_HERE);
CancelKeyboardLock(FROM_HERE);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, CancelInFullscreen) {
GURL url_for_test = https_fullscreen_frame();
NavigateToTestURL(url_for_test);
RequestKeyboardLock(FROM_HERE);
EnterFullscreen(FROM_HERE);
CancelKeyboardLock(FROM_HERE);
ExitFullscreen(FROM_HERE);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, EnterAndExitFullscreenCycling) {
GURL url_for_test = https_fullscreen_frame();
NavigateToTestURL(url_for_test);
RequestKeyboardLock(FROM_HERE);
EnterFullscreen(FROM_HERE);
ExitFullscreen(FROM_HERE);
EnterFullscreen(FROM_HERE);
ExitFullscreen(FROM_HERE);
EnterFullscreen(FROM_HERE);
ExitFullscreen(FROM_HERE);
EnterFullscreen(FROM_HERE);
ExitFullscreen(FROM_HERE);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, GainAndLoseFocusInWindowMode) {
NavigateToTestURL(https_fullscreen_frame());
RequestKeyboardLock(FROM_HERE);
FocusContent(FROM_HERE);
BlurContent(FROM_HERE);
FocusContent(FROM_HERE);
BlurContent(FROM_HERE);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, EnterFullscreenWithoutFocus) {
GURL url_for_test = https_fullscreen_frame();
NavigateToTestURL(url_for_test);
RequestKeyboardLock(FROM_HERE);
BlurContent(FROM_HERE);
EnterFullscreen(FROM_HERE);
ExitFullscreen(FROM_HERE);
EnterFullscreen(FROM_HERE);
FocusContent(FROM_HERE);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
GainAndLoseFocusCyclingInFullscreen) {
GURL url_for_test = https_fullscreen_frame();
NavigateToTestURL(url_for_test);
RequestKeyboardLock(FROM_HERE);
BlurContent(FROM_HERE);
EnterFullscreen(FROM_HERE);
FocusContent(FROM_HERE);
BlurContent(FROM_HERE);
FocusContent(FROM_HERE);
BlurContent(FROM_HERE);
FocusContent(FROM_HERE);
BlurContent(FROM_HERE);
FocusContent(FROM_HERE);
BlurContent(FROM_HERE);
ExitFullscreen(FROM_HERE);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, CancelWithoutLock) {
NavigateToTestURL(https_fullscreen_frame());
CancelKeyboardLock(FROM_HERE);
CancelKeyboardLock(FROM_HERE);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, MultipleLockCalls) {
NavigateToTestURL(https_fullscreen_frame());
RequestKeyboardLock(FROM_HERE);
RequestKeyboardLock(FROM_HERE);
RequestKeyboardLock(FROM_HERE);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, MultipleCancelCalls) {
NavigateToTestURL(https_fullscreen_frame());
RequestKeyboardLock(FROM_HERE);
CancelKeyboardLock(FROM_HERE);
CancelKeyboardLock(FROM_HERE);
CancelKeyboardLock(FROM_HERE);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, LockCallWithAllInvalidKeys) {
GURL url_for_test = https_fullscreen_frame();
NavigateToTestURL(url_for_test);
ASSERT_EQ(true,
EvalJs(web_contents(), kKeyboardLockMethodCallWithAllInvalidKeys));
// If no valid Keys are passed in, then keyboard lock will not be requested.
ASSERT_FALSE(web_contents()->GetKeyboardLockWidget());
EnterFullscreen(FROM_HERE);
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, LockCallWithSomeInvalidKeys) {
GURL url_for_test = https_fullscreen_frame();
NavigateToTestURL(url_for_test);
ASSERT_EQ(true,
EvalJs(web_contents(), kKeyboardLockMethodCallWithSomeInvalidKeys));
// If some valid Keys are passed in, then keyboard lock will not be requested.
ASSERT_FALSE(web_contents()->GetKeyboardLockWidget());
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
ValidLockCallFollowedByInvalidLockCall) {
NavigateToTestURL(https_fullscreen_frame());
RequestKeyboardLock(FROM_HERE);
ASSERT_TRUE(web_contents()->GetKeyboardLockWidget());
ASSERT_EQ(true,
EvalJs(web_contents(), kKeyboardLockMethodCallWithSomeInvalidKeys));
// An invalid call will cancel any previous lock request.
ASSERT_FALSE(web_contents()->GetKeyboardLockWidget());
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
KeyboardLockNotAllowedForSameOriginIFrame) {
NavigateToTestURL(https_cross_site_frame());
// The first child has the same origin as the top-level domain.
RenderFrameHost* child_frame =
ChildFrameAt(web_contents()->GetPrimaryMainFrame(),
/*index=*/0);
ASSERT_TRUE(child_frame);
ASSERT_EQ(true, EvalJs(child_frame, kKeyboardLockMethodExistanceCheck));
ASSERT_EQ(false, EvalJs(child_frame, kKeyboardLockMethodCallWithAllKeys));
ASSERT_FALSE(web_contents()->GetKeyboardLockWidget());
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
KeyboardLockNotAllowedForCrossOriginIFrame) {
NavigateToTestURL(https_cross_site_frame());
// The second child has a different origin as the top-level domain.
RenderFrameHost* child_frame =
ChildFrameAt(web_contents()->GetPrimaryMainFrame(),
/*index=*/1);
ASSERT_TRUE(child_frame);
ASSERT_EQ(true, EvalJs(child_frame, kKeyboardLockMethodExistanceCheck));
ASSERT_EQ(false, EvalJs(child_frame, kKeyboardLockMethodCallWithAllKeys));
ASSERT_FALSE(web_contents()->GetKeyboardLockWidget());
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
KeyboardUnlockedWhenNavigatingToSameUrl) {
GURL url_for_test = https_fullscreen_frame();
NavigateToTestURL(url_for_test);
EnterFullscreen(FROM_HERE);
RequestKeyboardLock(FROM_HERE);
// Navigate to the same URL which will reset the keyboard lock state.
NavigateToTestURL(url_for_test);
ASSERT_FALSE(web_contents()->GetKeyboardLockWidget());
// Entering fullscreen on the new page should not engage keyboard lock.
EnterFullscreen(FROM_HERE);
ASSERT_FALSE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
KeyboardUnlockedWhenNavigatingAway) {
GURL first_url_for_test = https_fullscreen_frame();
NavigateToTestURL(first_url_for_test);
EnterFullscreen(FROM_HERE);
RequestKeyboardLock(FROM_HERE);
// Navigate to a new URL which will reset the keyboard lock state.
GURL second_url_for_test = https_cross_site_frame();
NavigateToTestURL(second_url_for_test);
ASSERT_FALSE(web_contents()->GetKeyboardLockWidget());
// Entering fullscreen on the new page should not engage keyboard lock.
EnterFullscreen(FROM_HERE);
ASSERT_FALSE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
KeyboardRemainsLockedWhenIframeNavigates) {
NavigateToTestURL(https_cross_site_frame());
EnterFullscreen(FROM_HERE);
RequestKeyboardLock(FROM_HERE);
ASSERT_TRUE(NavigateIframeToURL(
web_contents(), kChildIframeName_0,
https_test_server()->GetURL(kCrossSiteTopLevelDomain, kHelloFramePath)));
ASSERT_TRUE(web_contents()->GetKeyboardLockWidget());
ASSERT_TRUE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
ASSERT_TRUE(NavigateIframeToURL(
web_contents(), kChildIframeName_1,
https_test_server()->GetURL(kCrossSiteChildDomain1, kHelloFramePath)));
ASSERT_TRUE(web_contents()->GetKeyboardLockWidget());
ASSERT_TRUE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
ASSERT_TRUE(NavigateIframeToURL(
web_contents(), kChildIframeName_2,
https_test_server()->GetURL(kCrossSiteChildDomain2, kHelloFramePath)));
ASSERT_TRUE(web_contents()->GetKeyboardLockWidget());
ASSERT_TRUE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
ASSERT_TRUE(
NavigateIframeToURL(web_contents(), kChildIframeName_0,
https_test_server()->GetURL(kCrossSiteChildDomain2,
kInputFieldFramePath)));
ASSERT_TRUE(web_contents()->GetKeyboardLockWidget());
ASSERT_TRUE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
ASSERT_TRUE(
NavigateIframeToURL(web_contents(), kChildIframeName_1,
https_test_server()->GetURL(kCrossSiteTopLevelDomain,
kInputFieldFramePath)));
ASSERT_TRUE(web_contents()->GetKeyboardLockWidget());
ASSERT_TRUE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
ASSERT_TRUE(
NavigateIframeToURL(web_contents(), kChildIframeName_2,
https_test_server()->GetURL(kCrossSiteChildDomain1,
kInputFieldFramePath)));
ASSERT_TRUE(web_contents()->GetKeyboardLockWidget());
ASSERT_TRUE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
CrossOriginIFrameReceivesInputWhenFocused) {
NavigateToTestURL(https_cross_site_frame());
EnterFullscreen(FROM_HERE);
RequestKeyboardLock(FROM_HERE);
GURL iframe_url =
https_test_server()->GetURL(kCrossSiteChildDomain1, kInputFieldFramePath);
ASSERT_TRUE(
NavigateIframeToURL(web_contents(), kChildIframeName_1, iframe_url));
ASSERT_TRUE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
RenderFrameHost* main_frame = web_contents()->GetPrimaryMainFrame();
RenderFrameHost* child = ChildFrameAt(main_frame, 1);
ASSERT_TRUE(child);
ASSERT_EQ(main_frame, web_contents()->GetFocusedFrame());
ASSERT_TRUE(ExecJs(child, kFocusInputFieldScript));
ASSERT_EQ("input-focus", EvalJs(child, "window.focus(); focusInputField();"));
ASSERT_EQ(child, web_contents()->GetFocusedFrame());
ASSERT_TRUE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
SimulateKeyPress(web_contents(), child, "KeyB", "B");
SimulateKeyPress(web_contents(), child, "KeyL", "BL");
SimulateKeyPress(web_contents(), child, "KeyA", "BLA");
SimulateKeyPress(web_contents(), child, "KeyR", "BLAR");
SimulateKeyPress(web_contents(), child, "KeyG", "BLARG");
SimulateKeyPress(web_contents(), child, "KeyH", "BLARGH");
ASSERT_TRUE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
LockRequestBeforeCrossOriginIFrameIsFullscreen) {
// If the main frame trusts the child frame by granting it the allowfullscreen
// permission, then we will allow keyboard lock to be activated when the child
// frame activates fullscreen.
NavigateToTestURL(https_cross_site_frame());
RequestKeyboardLock(FROM_HERE);
ASSERT_TRUE(web_contents()->GetKeyboardLockWidget());
ASSERT_FALSE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
// The third child is cross-domain and has the allowfullscreen attribute set.
ASSERT_TRUE(
NavigateIframeToURL(web_contents(), kChildIframeName_2,
https_test_server()->GetURL(kCrossSiteChildDomain2,
kFullscreenFramePath)));
RenderFrameHost* main_frame = web_contents()->GetPrimaryMainFrame();
RenderFrameHost* child = ChildFrameAt(main_frame, 2);
ASSERT_TRUE(child);
ASSERT_TRUE(ExecJs(child, "activateFullscreen()"));
ASSERT_EQ(main_frame->GetView()->GetRenderWidgetHost(),
web_contents()->GetKeyboardLockWidget());
ASSERT_TRUE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
LockRequestWhileCrossOriginIFrameIsFullscreen) {
// If the main frame trusts the child frame by granting it the allowfullscreen
// permission, then we will allow keyboard lock to be activated when the child
// frame activates fullscreen.
NavigateToTestURL(https_cross_site_frame());
// The third child is cross-domain and has the allowfullscreen attribute set.
ASSERT_TRUE(
NavigateIframeToURL(web_contents(), kChildIframeName_2,
https_test_server()->GetURL(kCrossSiteChildDomain2,
kFullscreenFramePath)));
RenderFrameHost* main_frame = web_contents()->GetPrimaryMainFrame();
RenderFrameHost* child = ChildFrameAt(main_frame, 2);
ASSERT_TRUE(child);
ASSERT_TRUE(ExecJs(child, "activateFullscreen()"));
RequestKeyboardLock(FROM_HERE);
ASSERT_EQ(main_frame->GetView()->GetRenderWidgetHost(),
web_contents()->GetKeyboardLockWidget());
ASSERT_TRUE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
LockRequestFailsFromInnerWebContents) {
NavigateToTestURL(https_cross_site_frame());
// The first child is a same-origin iframe.
RenderFrameHost* main_frame = web_contents()->GetPrimaryMainFrame();
RenderFrameHost* child = ChildFrameAt(main_frame, 0);
ASSERT_TRUE(child);
WebContents* inner_contents = CreateAndAttachInnerContents(child);
inner_contents->SetDelegate(web_contents_delegate());
ASSERT_TRUE(
NavigateToURLFromRenderer(inner_contents, https_fullscreen_frame()));
ASSERT_EQ(true, EvalJs(inner_contents, kKeyboardLockMethodExistanceCheck));
ASSERT_EQ(false, EvalJs(inner_contents, kKeyboardLockMethodCallWithAllKeys));
// Verify neither inner nor outer WebContents have a pending lock request.
WebContentsImpl* inner_contents_impl =
static_cast<WebContentsImpl*>(inner_contents);
ASSERT_FALSE(inner_contents_impl->GetKeyboardLockWidget());
ASSERT_FALSE(
inner_contents_impl->GetRenderWidgetHostView()->IsKeyboardLocked());
ASSERT_FALSE(web_contents()->GetKeyboardLockWidget());
ASSERT_FALSE(web_contents()->GetRenderWidgetHostView()->IsKeyboardLocked());
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest,
InnerContentsFullscreenBehavior) {
// TODO(joedow): Added per code review feedback. Need to define the behavior
// for KeyboardLock when an attached InnerWebContents goes fullscreen.
// Steps: 1. Request keyboard lock for all keys
// 2. InnerWebContents request fullscreen
// 3. Verify KeyboardLock behavior (should match iframe behavior)
}
IN_PROC_BROWSER_TEST_F(KeyboardLockBrowserTest, InnerContentsInputBehavior) {
// TODO(joedow): Added per code review feedback. Need to define the behavior
// for KeyboardLock when an attached InnerWebContents goes fullscreen.
// Steps: 1. Request keyboard lock for all keys
// 2. Main frame goes fullscreen
// 3. Inner web contents is focused
// 4. Verify input behavior (should match iframe behavior)
}
} // namespace content