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() {
}
AXAuraObjWrapper* AXAuraObjCache::GetOrCreate(View* view) {
// Avoid problems with transient focus events. https://crbug.com/729449
if (!view->GetWidget())
return nullptr;
return CreateInternal<AXViewObjWrapper>(view, view_to_id_map_);
......
......@@ -45,8 +45,11 @@ class VIEWS_EXPORT AXAuraObjCache : public aura::client::FocusChangeObserver {
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);
// Get or create an entry in the cache.
AXAuraObjWrapper* GetOrCreate(Widget* widget);
AXAuraObjWrapper* GetOrCreate(aura::Window* window);
......
......@@ -102,9 +102,15 @@ void AXRemoteHost::HandleEvent(View* view, ax::mojom::Event event_type) {
if (!enabled_)
return;
AXAuraObjWrapper* aura_obj =
view ? AXAuraObjCache::GetInstance()->GetOrCreate(view)
: tree_source_->GetRoot();
if (!view) {
SendEvent(tree_source_->GetRoot(), event_type);
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);
}
......
......@@ -165,6 +165,20 @@ TEST_F(AXRemoteHostTest, AutomationEnabledTwice) {
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
// asynchronously, like when ash requests close via DesktopWindowTreeHostMus.
// 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