Commit dc815dcb authored by James Cook's avatar James Cook Committed by Commit Bot

chromeos: Fix crash in shortcut viewer app with ChromeVox enabled

AXAuraObjCache::GetOrCreate(View* view) can return null if the View
is not yet associated with a Widget. The shortcut viewer creates a
ScrollView that creates a FocusRing before the ScrollView is attached
to the Widget.

Do what AutomationManagerAura does in this case and just don't send
accessibility event updates for these unattached views.

Bug: 889121
Test: added to views_mus_unittests
Change-Id: Ica14908778e45b9b4ee06077bd31c92fb7dfca62
Reviewed-on: https://chromium-review.googlesource.com/1244456Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Commit-Queue: James Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594113}
parent b111a625
...@@ -31,6 +31,7 @@ AXAuraObjCache* AXAuraObjCache::GetInstance() { ...@@ -31,6 +31,7 @@ AXAuraObjCache* AXAuraObjCache::GetInstance() {
} }
AXAuraObjWrapper* AXAuraObjCache::GetOrCreate(View* view) { AXAuraObjWrapper* AXAuraObjCache::GetOrCreate(View* view) {
// Avoid problems with transient focus events. https://crbug.com/729449
if (!view->GetWidget()) if (!view->GetWidget())
return nullptr; return nullptr;
return CreateInternal<AXViewObjWrapper>(view, view_to_id_map_); return CreateInternal<AXViewObjWrapper>(view, view_to_id_map_);
......
...@@ -45,8 +45,11 @@ class VIEWS_EXPORT AXAuraObjCache : public aura::client::FocusChangeObserver { ...@@ -45,8 +45,11 @@ class VIEWS_EXPORT AXAuraObjCache : public aura::client::FocusChangeObserver {
ax::mojom::Event event_type) = 0; ax::mojom::Event event_type) = 0;
}; };
// Get or create an entry in the cache based on an Aura view. // Get or create an entry in the cache. May return null if the View is not
// associated with a Widget.
AXAuraObjWrapper* GetOrCreate(View* view); AXAuraObjWrapper* GetOrCreate(View* view);
// Get or create an entry in the cache.
AXAuraObjWrapper* GetOrCreate(Widget* widget); AXAuraObjWrapper* GetOrCreate(Widget* widget);
AXAuraObjWrapper* GetOrCreate(aura::Window* window); AXAuraObjWrapper* GetOrCreate(aura::Window* window);
......
...@@ -102,9 +102,15 @@ void AXRemoteHost::HandleEvent(View* view, ax::mojom::Event event_type) { ...@@ -102,9 +102,15 @@ void AXRemoteHost::HandleEvent(View* view, ax::mojom::Event event_type) {
if (!enabled_) if (!enabled_)
return; return;
AXAuraObjWrapper* aura_obj = if (!view) {
view ? AXAuraObjCache::GetInstance()->GetOrCreate(view) SendEvent(tree_source_->GetRoot(), event_type);
: tree_source_->GetRoot(); return;
}
// Can return null for views without a widget.
AXAuraObjWrapper* aura_obj = AXAuraObjCache::GetInstance()->GetOrCreate(view);
if (!aura_obj)
return;
SendEvent(aura_obj, event_type); SendEvent(aura_obj, event_type);
} }
......
...@@ -165,6 +165,20 @@ TEST_F(AXRemoteHostTest, AutomationEnabledTwice) { ...@@ -165,6 +165,20 @@ TEST_F(AXRemoteHostTest, AutomationEnabledTwice) {
EXPECT_EQ(ax::mojom::Event::kLoadComplete, service.last_event_.event_type); EXPECT_EQ(ax::mojom::Event::kLoadComplete, service.last_event_.event_type);
} }
// Verifies that a remote app doesn't crash if a View triggers an accessibility
// event before it is attached to a Widget. https://crbug.com/889121
TEST_F(AXRemoteHostTest, SendEventOnViewWithNoWidget) {
TestAXHostService service(true /*automation_enabled*/);
AXRemoteHost* remote = CreateRemote(&service);
std::unique_ptr<Widget> widget = CreateTestWidget();
remote->FlushForTesting();
// Create a view that is not yet associated with the widget.
views::View view;
remote->HandleEvent(&view, ax::mojom::Event::kLocationChanged);
// No crash.
}
// Verifies that the AXRemoteHost stops monitoring widgets that are closed // Verifies that the AXRemoteHost stops monitoring widgets that are closed
// asynchronously, like when ash requests close via DesktopWindowTreeHostMus. // asynchronously, like when ash requests close via DesktopWindowTreeHostMus.
// https://crbug.com/869608 // https://crbug.com/869608
......
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