Commit 0bc05783 authored by Jun Mukai's avatar Jun Mukai Committed by Commit Bot

Fix the crash of View::OnTouchEvent in the login screen

LoginExpandedPublicAccountView is a view subclass but also
a pretarget handler of Shell. This is not great since any of
touch events will invoke the final method View::OnTouchEvent().

This CL creates an event handler for this purpose rather than
using a view directly as a pretarget handler.

I expanded the test cases to examine both mouse events and touches,
and confirmed it causes the reported crashes with touches without
this fix.

Bug: 908890
Test: the new test cases
Change-Id: I45d7de7da1eca8f874f5774971a085af8f72c9eb
Reviewed-on: https://chromium-review.googlesource.com/c/1428607Reviewed-by: default avatarJacob Dufault <jdufault@chromium.org>
Commit-Queue: Jun Mukai <mukai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#625315}
parent 9912404d
...@@ -87,6 +87,36 @@ views::Label* CreateLabel(const base::string16& text, SkColor color) { ...@@ -87,6 +87,36 @@ views::Label* CreateLabel(const base::string16& text, SkColor color) {
return label; return label;
} }
class LoginExpandedPublicAccountEventHandler : public ui::EventHandler {
public:
explicit LoginExpandedPublicAccountEventHandler(
LoginExpandedPublicAccountView* view)
: view_(view) {
Shell::Get()->AddPreTargetHandler(this);
}
~LoginExpandedPublicAccountEventHandler() override {
Shell::Get()->RemovePreTargetHandler(this);
}
private:
// ui::EventHandler:
void OnMouseEvent(ui::MouseEvent* event) override {
if (event->type() == ui::ET_MOUSE_PRESSED)
view_->ProcessPressedEvent(event->AsLocatedEvent());
}
void OnGestureEvent(ui::GestureEvent* event) override {
if ((event->type() == ui::ET_GESTURE_TAP ||
event->type() == ui::ET_GESTURE_TAP_DOWN)) {
view_->ProcessPressedEvent(event->AsLocatedEvent());
}
}
void OnKeyEvent(ui::KeyEvent* event) override { view_->OnKeyEvent(event); }
LoginExpandedPublicAccountView* view_;
DISALLOW_COPY_AND_ASSIGN(LoginExpandedPublicAccountEventHandler);
};
} // namespace } // namespace
// Button with text on the left side and an icon on the right side. // Button with text on the left side and an icon on the right side.
...@@ -648,8 +678,9 @@ LoginExpandedPublicAccountView::TestApi::monitoring_warning_icon() { ...@@ -648,8 +678,9 @@ LoginExpandedPublicAccountView::TestApi::monitoring_warning_icon() {
LoginExpandedPublicAccountView::LoginExpandedPublicAccountView( LoginExpandedPublicAccountView::LoginExpandedPublicAccountView(
const OnPublicSessionViewDismissed& on_dismissed) const OnPublicSessionViewDismissed& on_dismissed)
: NonAccessibleView(kLoginExpandedPublicAccountViewClassName), : NonAccessibleView(kLoginExpandedPublicAccountViewClassName),
on_dismissed_(on_dismissed) { on_dismissed_(on_dismissed),
Shell::Get()->AddPreTargetHandler(this); event_handler_(
std::make_unique<LoginExpandedPublicAccountEventHandler>(this)) {
SetLayoutManager( SetLayoutManager(
std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal)); std::make_unique<views::BoxLayout>(views::BoxLayout::kHorizontal));
SetPreferredSize(gfx::Size(kExpandedViewWidthDp, kExpandedViewHeightDp)); SetPreferredSize(gfx::Size(kExpandedViewWidthDp, kExpandedViewHeightDp));
...@@ -681,9 +712,7 @@ LoginExpandedPublicAccountView::LoginExpandedPublicAccountView( ...@@ -681,9 +712,7 @@ LoginExpandedPublicAccountView::LoginExpandedPublicAccountView(
AddChildView(right_pane_); AddChildView(right_pane_);
} }
LoginExpandedPublicAccountView::~LoginExpandedPublicAccountView() { LoginExpandedPublicAccountView::~LoginExpandedPublicAccountView() = default;
Shell::Get()->RemovePreTargetHandler(this);
}
void LoginExpandedPublicAccountView::ProcessPressedEvent( void LoginExpandedPublicAccountView::ProcessPressedEvent(
const ui::LocatedEvent* event) { const ui::LocatedEvent* event) {
...@@ -759,18 +788,6 @@ void LoginExpandedPublicAccountView::OnPaint(gfx::Canvas* canvas) { ...@@ -759,18 +788,6 @@ void LoginExpandedPublicAccountView::OnPaint(gfx::Canvas* canvas) {
canvas->DrawRoundRect(GetContentsBounds(), kRoundRectCornerRadiusDp, flags); canvas->DrawRoundRect(GetContentsBounds(), kRoundRectCornerRadiusDp, flags);
} }
void LoginExpandedPublicAccountView::OnMouseEvent(ui::MouseEvent* event) {
if (event->type() == ui::ET_MOUSE_PRESSED)
ProcessPressedEvent(event->AsLocatedEvent());
}
void LoginExpandedPublicAccountView::OnGestureEvent(ui::GestureEvent* event) {
if ((event->type() == ui::ET_GESTURE_TAP ||
event->type() == ui::ET_GESTURE_TAP_DOWN)) {
ProcessPressedEvent(event->AsLocatedEvent());
}
}
void LoginExpandedPublicAccountView::OnKeyEvent(ui::KeyEvent* event) { void LoginExpandedPublicAccountView::OnKeyEvent(ui::KeyEvent* event) {
if (!visible() || event->type() != ui::ET_KEY_PRESSED) if (!visible() || event->type() != ui::ET_KEY_PRESSED)
return; return;
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef ASH_LOGIN_UI_LOGIN_EXPANDED_PUBLIC_ACCOUNT_VIEW_H_ #ifndef ASH_LOGIN_UI_LOGIN_EXPANDED_PUBLIC_ACCOUNT_VIEW_H_
#define ASH_LOGIN_UI_LOGIN_EXPANDED_PUBLIC_ACCOUNT_VIEW_H_ #define ASH_LOGIN_UI_LOGIN_EXPANDED_PUBLIC_ACCOUNT_VIEW_H_
#include <memory>
#include "ash/ash_export.h" #include "ash/ash_export.h"
#include "ash/login/ui/login_menu_view.h" #include "ash/login/ui/login_menu_view.h"
#include "ash/login/ui/non_accessible_view.h" #include "ash/login/ui/non_accessible_view.h"
...@@ -65,8 +67,6 @@ class ASH_EXPORT LoginExpandedPublicAccountView : public NonAccessibleView { ...@@ -65,8 +67,6 @@ class ASH_EXPORT LoginExpandedPublicAccountView : public NonAccessibleView {
void OnPaint(gfx::Canvas* canvas) override; void OnPaint(gfx::Canvas* canvas) override;
// ui::EventHandler: // ui::EventHandler:
void OnMouseEvent(ui::MouseEvent* event) override;
void OnGestureEvent(ui::GestureEvent* event) override;
void OnKeyEvent(ui::KeyEvent* event) override; void OnKeyEvent(ui::KeyEvent* event) override;
private: private:
...@@ -74,6 +74,7 @@ class ASH_EXPORT LoginExpandedPublicAccountView : public NonAccessibleView { ...@@ -74,6 +74,7 @@ class ASH_EXPORT LoginExpandedPublicAccountView : public NonAccessibleView {
RightPaneView* right_pane_ = nullptr; RightPaneView* right_pane_ = nullptr;
OnPublicSessionViewDismissed on_dismissed_; OnPublicSessionViewDismissed on_dismissed_;
PublicAccountWarningDialog* warning_dialog_ = nullptr; PublicAccountWarningDialog* warning_dialog_ = nullptr;
std::unique_ptr<ui::EventHandler> event_handler_;
base::WeakPtrFactory<LoginExpandedPublicAccountView> weak_factory_{this}; base::WeakPtrFactory<LoginExpandedPublicAccountView> weak_factory_{this};
......
...@@ -34,7 +34,9 @@ constexpr char kKeyboardNameForItem1[] = "keyboard1"; ...@@ -34,7 +34,9 @@ constexpr char kKeyboardNameForItem1[] = "keyboard1";
constexpr char kKeyboardIdForItem2[] = "keyboard_id2"; constexpr char kKeyboardIdForItem2[] = "keyboard_id2";
constexpr char kKeyboardNameForItem2[] = "keyboard2"; constexpr char kKeyboardNameForItem2[] = "keyboard2";
class LoginExpandedPublicAccountViewTest : public LoginTestBase { class LoginExpandedPublicAccountViewTest
: public LoginTestBase,
public ::testing::WithParamInterface<const char*> {
protected: protected:
LoginExpandedPublicAccountViewTest() = default; LoginExpandedPublicAccountViewTest() = default;
~LoginExpandedPublicAccountViewTest() override = default; ~LoginExpandedPublicAccountViewTest() override = default;
...@@ -95,9 +97,16 @@ class LoginExpandedPublicAccountViewTest : public LoginTestBase { ...@@ -95,9 +97,16 @@ class LoginExpandedPublicAccountViewTest : public LoginTestBase {
} }
void TapOnView(views::View* tap_target) { void TapOnView(views::View* tap_target) {
GetEventGenerator()->MoveMouseTo( if (GetParam() == std::string("mouse")) {
tap_target->GetBoundsInScreen().CenterPoint()); GetEventGenerator()->MoveMouseTo(
GetEventGenerator()->ClickLeftButton(); tap_target->GetBoundsInScreen().CenterPoint());
GetEventGenerator()->ClickLeftButton();
} else {
GetEventGenerator()->MoveTouch(
tap_target->GetBoundsInScreen().CenterPoint());
GetEventGenerator()->PressTouch();
GetEventGenerator()->ReleaseTouch();
}
} }
mojom::LoginUserInfoPtr user_; mojom::LoginUserInfoPtr user_;
...@@ -114,7 +123,7 @@ class LoginExpandedPublicAccountViewTest : public LoginTestBase { ...@@ -114,7 +123,7 @@ class LoginExpandedPublicAccountViewTest : public LoginTestBase {
} // namespace } // namespace
// Verifies toggle advanced view will update the layout correctly. // Verifies toggle advanced view will update the layout correctly.
TEST_F(LoginExpandedPublicAccountViewTest, ToggleAdvancedView) { TEST_P(LoginExpandedPublicAccountViewTest, ToggleAdvancedView) {
public_account_->SizeToPreferredSize(); public_account_->SizeToPreferredSize();
EXPECT_EQ(public_account_->width(), kBubbleTotalWidthDp); EXPECT_EQ(public_account_->width(), kBubbleTotalWidthDp);
EXPECT_EQ(public_account_->height(), kBubbleTotalHeightDp); EXPECT_EQ(public_account_->height(), kBubbleTotalHeightDp);
...@@ -142,7 +151,7 @@ TEST_F(LoginExpandedPublicAccountViewTest, ToggleAdvancedView) { ...@@ -142,7 +151,7 @@ TEST_F(LoginExpandedPublicAccountViewTest, ToggleAdvancedView) {
} }
// Verifies warning dialog shows up correctly. // Verifies warning dialog shows up correctly.
TEST_F(LoginExpandedPublicAccountViewTest, ShowWarningDialog) { TEST_P(LoginExpandedPublicAccountViewTest, ShowWarningDialog) {
LoginExpandedPublicAccountView::TestApi test_api(public_account_); LoginExpandedPublicAccountView::TestApi test_api(public_account_);
views::StyledLabel::TestApi styled_label_test(test_api.learn_more_label()); views::StyledLabel::TestApi styled_label_test(test_api.learn_more_label());
EXPECT_EQ(test_api.warning_dialog(), nullptr); EXPECT_EQ(test_api.warning_dialog(), nullptr);
...@@ -150,17 +159,13 @@ TEST_F(LoginExpandedPublicAccountViewTest, ShowWarningDialog) { ...@@ -150,17 +159,13 @@ TEST_F(LoginExpandedPublicAccountViewTest, ShowWarningDialog) {
// Tap on the learn more link. // Tap on the learn more link.
views::View* link_view = styled_label_test.link_targets().begin()->first; views::View* link_view = styled_label_test.link_targets().begin()->first;
GetEventGenerator()->MoveMouseTo( TapOnView(link_view);
link_view->GetBoundsInScreen().CenterPoint());
GetEventGenerator()->ClickLeftButton();
EXPECT_NE(test_api.warning_dialog(), nullptr); EXPECT_NE(test_api.warning_dialog(), nullptr);
EXPECT_TRUE(test_api.warning_dialog()->IsVisible()); EXPECT_TRUE(test_api.warning_dialog()->IsVisible());
// When warning dialog is shown, tap outside of public account expanded view // When warning dialog is shown, tap outside of public account expanded view
// should not hide it. // should not hide it.
GetEventGenerator()->MoveMouseTo( TapOnView(other_view_);
other_view_->GetBoundsInScreen().CenterPoint());
GetEventGenerator()->ClickLeftButton();
EXPECT_TRUE(public_account_->visible()); EXPECT_TRUE(public_account_->visible());
EXPECT_NE(test_api.warning_dialog(), nullptr); EXPECT_NE(test_api.warning_dialog(), nullptr);
EXPECT_TRUE(test_api.warning_dialog()->IsVisible()); EXPECT_TRUE(test_api.warning_dialog()->IsVisible());
...@@ -184,7 +189,7 @@ TEST_F(LoginExpandedPublicAccountViewTest, ShowWarningDialog) { ...@@ -184,7 +189,7 @@ TEST_F(LoginExpandedPublicAccountViewTest, ShowWarningDialog) {
} }
// Verifies tap on submit button will try to launch public session. // Verifies tap on submit button will try to launch public session.
TEST_F(LoginExpandedPublicAccountViewTest, LaunchPublicSession) { TEST_P(LoginExpandedPublicAccountViewTest, LaunchPublicSession) {
LoginExpandedPublicAccountView::TestApi test_api(public_account_); LoginExpandedPublicAccountView::TestApi test_api(public_account_);
// Verify the language and keyboard information is populated correctly. // Verify the language and keyboard information is populated correctly.
...@@ -205,7 +210,7 @@ TEST_F(LoginExpandedPublicAccountViewTest, LaunchPublicSession) { ...@@ -205,7 +210,7 @@ TEST_F(LoginExpandedPublicAccountViewTest, LaunchPublicSession) {
} }
// Verifies both language and keyboard menus shows up correctly. // Verifies both language and keyboard menus shows up correctly.
TEST_F(LoginExpandedPublicAccountViewTest, ShowLanguageAndKeyboardMenu) { TEST_P(LoginExpandedPublicAccountViewTest, ShowLanguageAndKeyboardMenu) {
LoginExpandedPublicAccountView::TestApi test_api(public_account_); LoginExpandedPublicAccountView::TestApi test_api(public_account_);
EXPECT_FALSE(user_->public_account_info->show_advanced_view); EXPECT_FALSE(user_->public_account_info->show_advanced_view);
EXPECT_FALSE(test_api.advanced_view()->visible()); EXPECT_FALSE(test_api.advanced_view()->visible());
...@@ -248,7 +253,7 @@ TEST_F(LoginExpandedPublicAccountViewTest, ShowLanguageAndKeyboardMenu) { ...@@ -248,7 +253,7 @@ TEST_F(LoginExpandedPublicAccountViewTest, ShowLanguageAndKeyboardMenu) {
EXPECT_EQ(nullptr, test_api.keyboard_menu_view()); EXPECT_EQ(nullptr, test_api.keyboard_menu_view());
} }
TEST_F(LoginExpandedPublicAccountViewTest, ChangeMenuSelection) { TEST_P(LoginExpandedPublicAccountViewTest, ChangeMenuSelection) {
LoginExpandedPublicAccountView::TestApi test_api(public_account_); LoginExpandedPublicAccountView::TestApi test_api(public_account_);
user_->public_account_info->show_advanced_view = true; user_->public_account_info->show_advanced_view = true;
public_account_->UpdateForUser(user_); public_account_->UpdateForUser(user_);
...@@ -291,4 +296,8 @@ TEST_F(LoginExpandedPublicAccountViewTest, ChangeMenuSelection) { ...@@ -291,4 +296,8 @@ TEST_F(LoginExpandedPublicAccountViewTest, ChangeMenuSelection) {
EXPECT_EQ(test_api.selected_keyboard_item().value, kKeyboardIdForItem1); EXPECT_EQ(test_api.selected_keyboard_item().value, kKeyboardIdForItem1);
} }
INSTANTIATE_TEST_CASE_P(,
LoginExpandedPublicAccountViewTest,
::testing::Values("mouse", "touch"));
} // namespace ash } // namespace ash
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