Commit 2a14c955 authored by Dominique Fauteux-Chapleau's avatar Dominique Fauteux-Chapleau Committed by Commit Bot

Fix Aura focus loss crash on headless Chrome

This modifies the fix from crrev.com/c/2363692 to only suppress the
calls that cause the cursor bug instead of the entire "focus loss"
section of RenderWidgetHostViewAura::OnWindowFocused

Bug: 1100902, 1121744
Change-Id: I3846b9381f3fc04442bbd8b00cfcf289d8871e08
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2391514Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: default avatarRoger Tawa <rogerta@chromium.org>
Commit-Queue: Dominique Fauteux-Chapleau <domfc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#808033}
parent 82b1af68
...@@ -1857,13 +1857,13 @@ void RenderWidgetHostViewAura::OnCursorVisibilityChanged(bool is_visible) { ...@@ -1857,13 +1857,13 @@ void RenderWidgetHostViewAura::OnCursorVisibilityChanged(bool is_visible) {
void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus, void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus,
aura::Window* lost_focus) { aura::Window* lost_focus) {
// We need to honor input bypass if the associated tab is does not want
// input. This gives the current focused window a chance to be the text
// input client and handle events.
if (host()->IsIgnoringInputEvents())
return;
if (window_ == gained_focus) { if (window_ == gained_focus) {
// We need to honor input bypass if the associated tab does not want input.
// This gives the current focused window a chance to be the text input
// client and handle events.
if (host()->IsIgnoringInputEvents())
return;
host()->GotFocus(); host()->GotFocus();
host()->SetActive(true); host()->SetActive(true);
...@@ -1886,10 +1886,15 @@ void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus, ...@@ -1886,10 +1886,15 @@ void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus,
return; return;
} }
host()->SetActive(false); // Only lose focus if the associated tab doesn't want input. This ensures
host()->LostFocus(); // focus losses from clicking on a page while it has a modal dialog won't
// break it's text cursor after the dialog goes away.
if (!host()->IsIgnoringInputEvents()) {
host()->SetActive(false);
host()->LostFocus();
DetachFromInputMethod(false); DetachFromInputMethod(false);
}
// TODO(wjmaclean): Do we need to let TouchSelectionControllerClientAura // TODO(wjmaclean): Do we need to let TouchSelectionControllerClientAura
// handle this, just in case it stomps on a new highlight in another view // handle this, just in case it stomps on a new highlight in another view
......
...@@ -433,6 +433,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura ...@@ -433,6 +433,8 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
DiscardDelegatedFramesWithMemoryPressure); DiscardDelegatedFramesWithMemoryPressure);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraInputMethodTest, FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraInputMethodTest,
OnCaretBoundsChanged); OnCaretBoundsChanged);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraInputMethodFocusTest,
OnFocusLost);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraKeyboardTest, FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraKeyboardTest,
KeyboardObserverDestroyed); KeyboardObserverDestroyed);
FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraKeyboardTest, FRIEND_TEST_ALL_PREFIXES(RenderWidgetHostViewAuraKeyboardTest,
......
...@@ -6497,9 +6497,7 @@ class RenderWidgetHostViewAuraInputMethodTest ...@@ -6497,9 +6497,7 @@ class RenderWidgetHostViewAuraInputMethodTest
TEST_F(RenderWidgetHostViewAuraInputMethodTest, OnCaretBoundsChanged) { TEST_F(RenderWidgetHostViewAuraInputMethodTest, OnCaretBoundsChanged) {
ui::InputMethod* input_method = parent_view_->GetInputMethod(); ui::InputMethod* input_method = parent_view_->GetInputMethod();
if (input_method != input_method_) { if (input_method != input_method_) {
// Some platform doesn't support mocking input method. e.g. InputMethodMus. // Some platforms don't support mocking input method. In that case, ignore this test.
// In that case, ignore this test.
// TODO(shuchen): support mocking InputMethodMus, http://crbug.com/905518.
return; return;
} }
ActivateViewForTextInputManager(parent_view_, ui::TEXT_INPUT_TYPE_TEXT); ActivateViewForTextInputManager(parent_view_, ui::TEXT_INPUT_TYPE_TEXT);
...@@ -6519,6 +6517,41 @@ TEST_F(RenderWidgetHostViewAuraInputMethodTest, OnCaretBoundsChanged) { ...@@ -6519,6 +6517,41 @@ TEST_F(RenderWidgetHostViewAuraInputMethodTest, OnCaretBoundsChanged) {
input_method->RemoveObserver(this); input_method->RemoveObserver(this);
} }
class RenderWidgetHostViewAuraInputMethodFocusTest
: public RenderWidgetHostViewAuraInputMethodTest,
public testing::WithParamInterface<bool> {
public:
RenderWidgetHostViewAuraInputMethodFocusTest() = default;
~RenderWidgetHostViewAuraInputMethodFocusTest() override = default;
bool ignore_input_events() { return GetParam(); }
};
INSTANTIATE_TEST_SUITE_P(RenderWidgetHostViewAuraInputMethodFocusTest,
RenderWidgetHostViewAuraInputMethodFocusTest,
testing::Bool());
TEST_P(RenderWidgetHostViewAuraInputMethodFocusTest, OnFocusLost) {
render_widget_host_delegate()->set_should_ignore_input_events(
ignore_input_events());
ui::InputMethod* input_method = view_->GetInputMethod();
if (input_method != input_method_) {
// Some platforms doesn't support mocking input method. In that case, ignore this test.
return;
}
EXPECT_EQ(input_method, input_method_);
ActivateViewForTextInputManager(view_, ui::TEXT_INPUT_TYPE_TEXT);
input_method->SetFocusedTextInputClient(view_);
EXPECT_EQ(input_method->GetTextInputClient(), view_);
view_->OnWindowFocused(nullptr, view_->GetNativeView());
if (ignore_input_events())
EXPECT_EQ(input_method->GetTextInputClient(), view_);
else
EXPECT_EQ(input_method->GetTextInputClient(), nullptr);
}
#if defined(OS_WIN) #if defined(OS_WIN)
class MockInputMethodKeyboardController final class MockInputMethodKeyboardController final
: public ui::InputMethodKeyboardController { : public ui::InputMethodKeyboardController {
......
...@@ -81,4 +81,8 @@ FrameTree* MockRenderWidgetHostDelegate::GetFrameTree() { ...@@ -81,4 +81,8 @@ FrameTree* MockRenderWidgetHostDelegate::GetFrameTree() {
return frame_tree_; return frame_tree_;
} }
bool MockRenderWidgetHostDelegate::ShouldIgnoreInputEvents() {
return should_ignore_input_events_;
}
} // namespace content } // namespace content
...@@ -35,6 +35,9 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate { ...@@ -35,6 +35,9 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
pre_handle_keyboard_event_result_ = result; pre_handle_keyboard_event_result_ = result;
} }
void set_frame_tree(FrameTree* frame_tree) { frame_tree_ = frame_tree; } void set_frame_tree(FrameTree* frame_tree) { frame_tree_ = frame_tree; }
void set_should_ignore_input_events(bool ignore) {
should_ignore_input_events_ = ignore;
}
void CreateInputEventRouter(); void CreateInputEventRouter();
// RenderWidgetHostDelegate: // RenderWidgetHostDelegate:
...@@ -59,6 +62,7 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate { ...@@ -59,6 +62,7 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
bool IsFullscreen() override; bool IsFullscreen() override;
RenderViewHostDelegateView* GetDelegateView() override; RenderViewHostDelegateView* GetDelegateView() override;
FrameTree* GetFrameTree() override; FrameTree* GetFrameTree() override;
bool ShouldIgnoreInputEvents() override;
private: private:
std::unique_ptr<NativeWebKeyboardEvent> last_event_; std::unique_ptr<NativeWebKeyboardEvent> last_event_;
...@@ -71,6 +75,7 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate { ...@@ -71,6 +75,7 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
KeyboardEventProcessingResult::NOT_HANDLED; KeyboardEventProcessingResult::NOT_HANDLED;
StubRenderViewHostDelegateView rvh_delegate_view_; StubRenderViewHostDelegateView rvh_delegate_view_;
FrameTree* frame_tree_ = nullptr; FrameTree* frame_tree_ = nullptr;
bool should_ignore_input_events_ = false;
DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHostDelegate); DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHostDelegate);
}; };
......
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