Commit 8a5175d4 authored by James Cook's avatar James Cook Committed by Commit Bot

Move ViewsDelegate::NotifyAccessibilityEvent to an observer pattern

Introduce AXEventManager to maintain an ObserverList of objects
interested in views accessibility events.

This makes testing easier by eliminating the need for several
TestViewsDelegates.

BUG=908884
TEST=views_unittests, views_mus_unittests, browser_tests

Change-Id: Ic7017444fec7e694675ad675e0fefaf78b622130
Reviewed-on: https://chromium-review.googlesource.com/c/1352265Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: James Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612192}
parent c32bc6f2
......@@ -5,7 +5,6 @@
#include "ash/test/ash_test_views_delegate.h"
#include "ash/shell.h"
#include "ash/test/ash_test_helper.h"
namespace ash {
......@@ -31,17 +30,6 @@ void AshTestViewsDelegate::OnBeforeWidgetInit(
TestViewsDelegate::OnBeforeWidgetInit(params, delegate);
}
void AshTestViewsDelegate::NotifyAccessibilityEvent(
views::View* view,
ax::mojom::Event event_type) {
TestViewsDelegate::NotifyAccessibilityEvent(view, event_type);
if (test_accessibility_event_delegate_) {
test_accessibility_event_delegate_->NotifyAccessibilityEvent(view,
event_type);
}
}
views::TestViewsDelegate::ProcessMenuAcceleratorResult
AshTestViewsDelegate::ProcessAcceleratorWhileMenuShowing(
const ui::Accelerator& accelerator) {
......
......@@ -10,14 +10,6 @@
namespace ash {
class TestAccessibilityEventDelegate {
public:
TestAccessibilityEventDelegate() {}
virtual ~TestAccessibilityEventDelegate() {}
virtual void NotifyAccessibilityEvent(views::View* view,
ax::mojom::Event event_type) = 0;
};
// Ash specific ViewsDelegate. In addition to creating a TestWebContents this
// parents widget with no parent/context to the shell. This is created by
// default AshTestHelper.
......@@ -32,18 +24,10 @@ class AshTestViewsDelegate : public views::TestViewsDelegate {
// TODO: remove this and ban usage of AshTestHelper outside of ash.
void set_running_outside_ash() { running_outside_ash_ = true; }
// Not owned.
void set_test_accessibility_event_delegate(
TestAccessibilityEventDelegate* test_accessibility_event_delegate) {
test_accessibility_event_delegate_ = test_accessibility_event_delegate;
}
// Overriden from TestViewsDelegate.
void OnBeforeWidgetInit(
views::Widget::InitParams* params,
views::internal::NativeWidgetDelegate* delegate) override;
void NotifyAccessibilityEvent(views::View* view,
ax::mojom::Event event_type) override;
views::TestViewsDelegate::ProcessMenuAcceleratorResult
ProcessAcceleratorWhileMenuShowing(
const ui::Accelerator& accelerator) override;
......@@ -57,9 +41,6 @@ class AshTestViewsDelegate : public views::TestViewsDelegate {
// matches with this.
ui::Accelerator close_menu_accelerator_;
// Not owned.
TestAccessibilityEventDelegate* test_accessibility_event_delegate_ = nullptr;
bool running_outside_ash_ = false;
DISALLOW_COPY_AND_ASSIGN(AshTestViewsDelegate);
......
......@@ -21,6 +21,7 @@
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/views/accessibility/ax_aura_obj_wrapper.h"
#include "ui/views/accessibility/ax_event_manager.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
......@@ -43,6 +44,8 @@ void AutomationManagerAura::Enable() {
Reset(false);
SendEvent(current_tree_->GetRoot(), ax::mojom::Event::kLoadComplete);
// Intentionally not reset at shutdown since we cannot rely on the shutdown
// ordering of two base::Singletons.
views::AXAuraObjCache::GetInstance()->SetDelegate(this);
#if defined(OS_CHROMEOS)
......@@ -70,7 +73,7 @@ void AutomationManagerAura::Disable() {
#endif
}
void AutomationManagerAura::HandleEvent(views::View* view,
void AutomationManagerAura::OnViewEvent(views::View* view,
ax::mojom::Event event_type) {
CHECK(view);
......@@ -161,9 +164,12 @@ AutomationManagerAura::AutomationManagerAura()
: AXHostDelegate(ui::DesktopAXTreeID()),
enabled_(false),
processing_events_(false),
weak_ptr_factory_(this) {}
weak_ptr_factory_(this) {
views::AXEventManager::Get()->AddObserver(this);
}
AutomationManagerAura::~AutomationManagerAura() {
views::AXEventManager::Get()->RemoveObserver(this);
}
void AutomationManagerAura::Reset(bool reset_serializer) {
......
......@@ -18,6 +18,7 @@
#include "ui/accessibility/ax_host_delegate.h"
#include "ui/accessibility/ax_tree_serializer.h"
#include "ui/views/accessibility/ax_aura_obj_cache.h"
#include "ui/views/accessibility/ax_event_observer.h"
namespace base {
template <typename T>
......@@ -36,7 +37,8 @@ struct ExtensionMsg_AccessibilityEventBundleParams;
// Manages a tree of automation nodes.
class AutomationManagerAura : public ui::AXHostDelegate,
public views::AXAuraObjCache::Delegate {
public views::AXAuraObjCache::Delegate,
public views::AXEventObserver {
public:
// Get the single instance of this class.
static AutomationManagerAura* GetInstance();
......@@ -47,9 +49,6 @@ class AutomationManagerAura : public ui::AXHostDelegate,
// Disable automation support for views.
void Disable();
// Handle an event fired upon a |View|.
void HandleEvent(views::View* view, ax::mojom::Event event_type);
// Handle an event fired upon the root view.
void HandleEvent(ax::mojom::Event event_type);
......@@ -63,6 +62,9 @@ class AutomationManagerAura : public ui::AXHostDelegate,
void OnEvent(views::AXAuraObjWrapper* aura_obj,
ax::mojom::Event event_type) override;
// views::AXEventObserver:
void OnViewEvent(views::View* view, ax::mojom::Event event_type) override;
void set_event_bundle_callback_for_testing(
base::RepeatingCallback<void(ExtensionMsg_AccessibilityEventBundleParams)>
callback) {
......
......@@ -20,10 +20,6 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/views/widget/widget.h"
#if defined(USE_AURA)
#include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h"
#endif
#if defined(OS_CHROMEOS)
#include "chrome/browser/ui/views/touch_selection_menu_runner_chromeos.h"
#endif
......@@ -136,14 +132,6 @@ bool ChromeViewsDelegate::GetSavedWindowPlacement(
return true;
}
void ChromeViewsDelegate::NotifyAccessibilityEvent(
views::View* view,
ax::mojom::Event event_type) {
#if defined(USE_AURA)
AutomationManagerAura::GetInstance()->HandleEvent(view, event_type);
#endif
}
void ChromeViewsDelegate::AddRef() {
if (ref_count_ == 0u) {
keep_alive_.reset(
......
......@@ -14,7 +14,6 @@
#include "base/location.h"
#include "base/macros.h"
#include "build/build_config.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/views/views_delegate.h"
class ScopedKeepAlive;
......@@ -33,8 +32,6 @@ class ChromeViewsDelegate : public views::ViewsDelegate {
const std::string& window_name,
gfx::Rect* bounds,
ui::WindowShowState* show_state) const override;
void NotifyAccessibilityEvent(views::View* view,
ax::mojom::Event event_type) override;
#if defined(OS_CHROMEOS)
ProcessMenuAcceleratorResult ProcessAcceleratorWhileMenuShowing(
const ui::Accelerator& accelerator) override;
......
......@@ -17,7 +17,6 @@
#include "chrome/browser/ui/views/tabs/tab_strip_observer.h"
#include "chrome/browser/ui/views/tabs/tab_style.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/views/chrome_test_views_delegate.h"
#include "chrome/test/views/chrome_views_test_base.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/material_design/material_design_controller.h"
......@@ -27,6 +26,8 @@
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/path.h"
#include "ui/gfx/skia_util.h"
#include "ui/views/accessibility/ax_event_manager.h"
#include "ui/views/accessibility/ax_event_observer.h"
#include "ui/views/controls/label.h"
#include "ui/views/view.h"
#include "ui/views/view_targeter.h"
......@@ -44,12 +45,16 @@ views::View* FindTabView(views::View* view) {
return current;
}
class TabStripTestViewsDelegate : public ChromeTestViewsDelegate {
class TestAXEventObserver : public views::AXEventObserver {
public:
TabStripTestViewsDelegate() = default;
~TabStripTestViewsDelegate() override = default;
void NotifyAccessibilityEvent(views::View* view,
ax::mojom::Event event_type) override {
TestAXEventObserver() { views::AXEventManager::Get()->AddObserver(this); }
~TestAXEventObserver() override {
views::AXEventManager::Get()->RemoveObserver(this);
}
// views::AXEventObserver:
void OnViewEvent(views::View* view, ax::mojom::Event event_type) override {
if (event_type == ax::mojom::Event::kSelectionRemove) {
remove_count_++;
}
......@@ -64,7 +69,8 @@ class TabStripTestViewsDelegate : public ChromeTestViewsDelegate {
private:
int add_count_ = 0;
int remove_count_ = 0;
DISALLOW_COPY_AND_ASSIGN(TabStripTestViewsDelegate);
DISALLOW_COPY_AND_ASSIGN(TestAXEventObserver);
};
class AnimationWaiter {
......@@ -170,13 +176,6 @@ class TabStripTest : public ChromeViewsTestBase,
}
protected:
std::unique_ptr<views::TestViewsDelegate> CreateTestViewsDelegate() override {
std::unique_ptr<TabStripTestViewsDelegate> delegate =
std::make_unique<TabStripTestViewsDelegate>();
test_views_delegate_ = delegate.get();
return delegate;
}
bool IsShowingAttentionIndicator(Tab* tab) {
return tab->icon_->ShowingAttentionIndicator();
}
......@@ -222,7 +221,6 @@ class TabStripTest : public ChromeViewsTestBase,
// Owns |tab_strip_|.
views::View parent_;
TabStrip* tab_strip_ = nullptr;
TabStripTestViewsDelegate* test_views_delegate_ = nullptr;
std::unique_ptr<views::Widget> widget_;
private:
......@@ -236,6 +234,8 @@ TEST_P(TabStripTest, GetModelCount) {
}
TEST_P(TabStripTest, AccessibilityEvents) {
TestAXEventObserver observer;
// When adding tabs, SetSelection() is called after AddTabAt(), as
// otherwise the index would not be meaningful.
tab_strip_->AddTabAt(0, TabRendererData(), false);
......@@ -243,16 +243,16 @@ TEST_P(TabStripTest, AccessibilityEvents) {
ui::ListSelectionModel selection;
selection.SetSelectedIndex(1);
tab_strip_->SetSelection(selection);
EXPECT_EQ(1, test_views_delegate_->add_count());
EXPECT_EQ(0, test_views_delegate_->remove_count());
EXPECT_EQ(1, observer.add_count());
EXPECT_EQ(0, observer.remove_count());
// When removing tabs, SetSelection() is called before RemoveTabAt(), as
// otherwise the index would not be meaningful.
selection.SetSelectedIndex(0);
tab_strip_->SetSelection(selection);
tab_strip_->RemoveTabAt(nullptr, 1, true);
EXPECT_EQ(2, test_views_delegate_->add_count());
EXPECT_EQ(1, test_views_delegate_->remove_count());
EXPECT_EQ(2, observer.add_count());
EXPECT_EQ(1, observer.remove_count());
}
TEST_P(TabStripTest, IsValidModelIndex) {
......
......@@ -11,11 +11,6 @@ ChromeViewsTestBase::ChromeViewsTestBase() {}
ChromeViewsTestBase::~ChromeViewsTestBase() {}
void ChromeViewsTestBase::SetUp() {
set_views_delegate(CreateTestViewsDelegate());
set_views_delegate(std::make_unique<ChromeTestViewsDelegate>());
views::ViewsTestBase::SetUp();
}
std::unique_ptr<views::TestViewsDelegate>
ChromeViewsTestBase::CreateTestViewsDelegate() {
return std::make_unique<ChromeTestViewsDelegate>();
}
......@@ -20,9 +20,6 @@ class ChromeViewsTestBase : public views::ViewsTestBase {
// views::ViewsTestBase:
void SetUp() override;
// Subclasses can override to provide their own TestViewsDelegate
virtual std::unique_ptr<views::TestViewsDelegate> CreateTestViewsDelegate();
private:
DISALLOW_COPY_AND_ASSIGN(ChromeViewsTestBase);
};
......
......@@ -59,6 +59,8 @@ jumbo_component("views") {
"../views_bridge_mac/bridged_native_widget_impl.h",
"../views_bridge_mac/native_widget_mac_nswindow.h",
"../views_bridge_mac/window_touch_bar_delegate.h",
"accessibility/ax_event_manager.h",
"accessibility/ax_event_observer.h",
"accessibility/ax_virtual_view.h",
"accessibility/view_accessibility.h",
"accessibility/view_accessibility_utils.h",
......@@ -266,6 +268,8 @@ jumbo_component("views") {
# TODO(ccameron): Move these sources to the views_bridge_mac component
"../views_bridge_mac/bridged_native_widget_impl.mm",
"../views_bridge_mac/native_widget_mac_nswindow.mm",
"accessibility/ax_event_manager.cc",
"accessibility/ax_event_observer.cc",
"accessibility/ax_virtual_view.cc",
"accessibility/view_accessibility.cc",
"accessibility/view_accessibility_utils.cc",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/accessibility/ax_event_manager.h"
#include "base/no_destructor.h"
#include "ui/views/accessibility/ax_event_observer.h"
namespace views {
AXEventManager::AXEventManager() = default;
AXEventManager::~AXEventManager() = default;
// static
AXEventManager* AXEventManager::Get() {
static base::NoDestructor<AXEventManager> instance;
return instance.get();
}
void AXEventManager::AddObserver(AXEventObserver* observer) {
observers_.AddObserver(observer);
}
void AXEventManager::RemoveObserver(AXEventObserver* observer) {
observers_.RemoveObserver(observer);
}
void AXEventManager::NotifyViewEvent(views::View* view,
ax::mojom::Event event_type) {
for (AXEventObserver& observer : observers_)
observer.OnViewEvent(view, event_type);
}
} // namespace views
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_VIEWS_ACCESSIBILITY_AX_EVENT_MANAGER_H_
#define UI_VIEWS_ACCESSIBILITY_AX_EVENT_MANAGER_H_
#include "base/macros.h"
#include "base/observer_list.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/views/views_export.h"
namespace views {
class AXEventObserver;
class View;
// AXEventManager allows observation of accessibility events for all views.
class VIEWS_EXPORT AXEventManager {
public:
AXEventManager();
~AXEventManager();
// Returns the singleton instance.
static AXEventManager* Get();
void AddObserver(AXEventObserver* observer);
void RemoveObserver(AXEventObserver* observer);
// Notifies observers of an accessibility event. |view| must not be null.
void NotifyViewEvent(views::View* view, ax::mojom::Event event_type);
private:
base::ObserverList<AXEventObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(AXEventManager);
};
} // namespace views
#endif // UI_VIEWS_ACCESSIBILITY_AX_EVENT_MANAGER_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/accessibility/ax_event_observer.h"
namespace views {
AXEventObserver::AXEventObserver() = default;
AXEventObserver::~AXEventObserver() = default;
} // namespace views
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_VIEWS_ACCESSIBILITY_AX_EVENT_OBSERVER_H_
#define UI_VIEWS_ACCESSIBILITY_AX_EVENT_OBSERVER_H_
#include "base/observer_list_types.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/views/views_export.h"
namespace views {
class View;
// AXEventObserver is notified for accessibility events on all views.
class VIEWS_EXPORT AXEventObserver : public base::CheckedObserver {
public:
virtual void OnViewEvent(views::View* view, ax::mojom::Event event_type) = 0;
protected:
AXEventObserver();
~AXEventObserver() override;
};
} // namespace views
#endif // UI_VIEWS_ACCESSIBILITY_AX_EVENT_OBSERVER_H_
......@@ -13,6 +13,8 @@
#include "ui/gfx/geometry/size.h"
#include "ui/views/accessibility/ax_aura_obj_cache.h"
#include "ui/views/accessibility/ax_aura_obj_wrapper.h"
#include "ui/views/accessibility/ax_event_manager.h"
#include "ui/views/accessibility/ax_event_observer.h"
#include "ui/views/accessibility/ax_widget_obj_wrapper.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/label.h"
......@@ -178,13 +180,16 @@ class DerivedTestView : public View {
void OnBlur() override { SetVisible(false); }
};
class AxTestViewsDelegate : public TestViewsDelegate {
class TestAXEventObserver : public AXEventObserver {
public:
AxTestViewsDelegate() = default;
~AxTestViewsDelegate() override = default;
TestAXEventObserver() { AXEventManager::Get()->AddObserver(this); }
void NotifyAccessibilityEvent(View* view,
ax::mojom::Event event_type) override {
~TestAXEventObserver() override {
AXEventManager::Get()->RemoveObserver(this);
}
// AXEventObserver:
void OnViewEvent(View* view, ax::mojom::Event event_type) override {
AXAuraObjCache* ax = AXAuraObjCache::GetInstance();
std::vector<AXAuraObjWrapper*> out_children;
AXAuraObjWrapper* ax_obj = ax->GetOrCreate(view->GetWidget());
......@@ -192,24 +197,17 @@ class AxTestViewsDelegate : public TestViewsDelegate {
}
private:
DISALLOW_COPY_AND_ASSIGN(AxTestViewsDelegate);
DISALLOW_COPY_AND_ASSIGN(TestAXEventObserver);
};
class ViewAccessibilityTest : public ViewsTestBase {
public:
ViewAccessibilityTest() = default;
~ViewAccessibilityTest() override = default;
void SetUp() override {
std::unique_ptr<TestViewsDelegate> views_delegate(
new AxTestViewsDelegate());
set_views_delegate(std::move(views_delegate));
ViewsTestBase::SetUp();
}
};
using ViewAccessibilityTest = ViewsTestBase;
// Check if the destruction of the widget ends successfully if |view|'s
// visibility changed during destruction.
TEST_F(ViewAccessibilityTest, LayoutCalledInvalidateRootView) {
// TODO: Construct a real AutomationManagerAura rather than using this
// observer to simulate it.
TestAXEventObserver observer;
std::unique_ptr<Widget> widget(new Widget);
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
......
......@@ -18,8 +18,9 @@
#include "ui/events/gesture_event_details.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/accessibility/ax_event_manager.h"
#include "ui/views/accessibility/ax_event_observer.h"
#include "ui/views/test/slider_test_api.h"
#include "ui/views/test/test_views_delegate.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
......@@ -118,29 +119,37 @@ void TestSliderListener::SliderDragEnded(views::Slider* sender) {
last_drag_ended_epoch_ = ++last_event_epoch_;
}
} // namespace
class TestAXEventObserver : public views::AXEventObserver {
public:
TestAXEventObserver() { views::AXEventManager::Get()->AddObserver(this); }
namespace views {
~TestAXEventObserver() override {
views::AXEventManager::Get()->RemoveObserver(this);
}
// Base test fixture for Slider tests.
class SliderTest : public views::ViewsTestBase {
public:
class SliderTestViewsDelegate : public views::TestViewsDelegate {
public:
bool has_value_changed() { return has_value_changed_; }
bool value_changed() const { return value_changed_; }
private:
void NotifyAccessibilityEvent(View* view,
ax::mojom::Event event_type) override {
// views::AXEventObserver:
void OnViewEvent(views::View* view, ax::mojom::Event event_type) override {
if (event_type == ax::mojom::Event::kValueChanged)
has_value_changed_ = true;
value_changed_ = true;
}
bool has_value_changed_ = false;
};
private:
bool value_changed_ = false;
DISALLOW_COPY_AND_ASSIGN(TestAXEventObserver);
};
} // namespace
namespace views {
SliderTest();
~SliderTest() override;
// Base test fixture for Slider tests.
class SliderTest : public views::ViewsTestBase {
public:
SliderTest() = default;
~SliderTest() override = default;
protected:
Slider* slider() {
......@@ -169,43 +178,26 @@ class SliderTest : public views::ViewsTestBase {
return event_generator_.get();
}
SliderTestViewsDelegate* delegate() { return delegate_; }
private:
// The Slider to be tested.
Slider* slider_;
Slider* slider_ = nullptr;
// A simple SliderListener test double.
TestSliderListener slider_listener_;
// Stores the default locale at test setup so it can be restored
// during test teardown.
std::string default_locale_;
// The maximum x value within the bounds of the slider.
int max_x_;
int max_x_ = 0;
// The maximum y value within the bounds of the slider.
int max_y_;
int max_y_ = 0;
// The widget container for the slider being tested.
views::Widget* widget_;
views::Widget* widget_ = nullptr;
// An event generator.
std::unique_ptr<ui::test::EventGenerator> event_generator_;
// A TestViewsDelegate that intercepts accessibility notifications. Weak.
SliderTestViewsDelegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(SliderTest);
};
SliderTest::SliderTest()
: slider_(NULL),
default_locale_(),
max_x_(0),
max_y_(0),
delegate_(new SliderTestViewsDelegate()) {
std::unique_ptr<views::TestViewsDelegate> delegate(delegate_);
set_views_delegate(std::move(delegate));
}
SliderTest::~SliderTest() {
}
void SliderTest::SetUp() {
views::ViewsTestBase::SetUp();
......@@ -401,7 +393,8 @@ TEST_F(SliderTest, SliderListenerEventsForMultiFingerScrollGesture) {
// Verifies the correct SliderListener events are raised for an accessible
// slider.
TEST_F(SliderTest, SliderRaisesA11yEvents) {
EXPECT_FALSE(delegate()->has_value_changed());
TestAXEventObserver observer;
EXPECT_FALSE(observer.value_changed());
// First, detach/reattach the slider without setting value.
// Temporarily detach the slider.
......@@ -410,18 +403,18 @@ TEST_F(SliderTest, SliderRaisesA11yEvents) {
// Re-attachment should cause nothing to get fired.
root_view->AddChildView(slider());
EXPECT_FALSE(delegate()->has_value_changed());
EXPECT_FALSE(observer.value_changed());
// Now, set value before reattaching.
root_view->RemoveChildView(slider());
// Value changes won't trigger accessibility events before re-attachment.
slider()->SetValue(22);
EXPECT_FALSE(delegate()->has_value_changed());
EXPECT_FALSE(observer.value_changed());
// Re-attachment should trigger the value change.
root_view->AddChildView(slider());
EXPECT_TRUE(delegate()->has_value_changed());
EXPECT_TRUE(observer.value_changed());
}
#endif // !defined(OS_MACOSX) || defined(USE_AURA)
......
......@@ -18,6 +18,7 @@
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/views/accessibility/ax_aura_obj_wrapper.h"
#include "ui/views/accessibility/ax_event_manager.h"
#include "ui/views/mus/ax_tree_source_mus.h"
#include "ui/views/mus/mus_client.h"
#include "ui/views/view.h"
......@@ -30,6 +31,7 @@ using display::Screen;
namespace views {
AXRemoteHost::AXRemoteHost() {
AXEventManager::Get()->AddObserver(this);
AXAuraObjCache::GetInstance()->SetDelegate(this);
}
......@@ -37,6 +39,7 @@ AXRemoteHost::~AXRemoteHost() {
if (widget_)
StopMonitoringWidget();
AXAuraObjCache::GetInstance()->SetDelegate(nullptr);
AXEventManager::Get()->RemoveObserver(this);
}
void AXRemoteHost::Init(service_manager::Connector* connector) {
......@@ -98,19 +101,6 @@ void AXRemoteHost::StopMonitoringWidget() {
tree_source_.reset();
}
void AXRemoteHost::HandleEvent(View* view, ax::mojom::Event event_type) {
CHECK(view);
if (!enabled_)
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);
}
void AXRemoteHost::OnAutomationEnabled(bool enabled) {
if (enabled)
Enable();
......@@ -170,6 +160,19 @@ void AXRemoteHost::OnEvent(AXAuraObjWrapper* aura_obj,
SendEvent(aura_obj, event_type);
}
void AXRemoteHost::OnViewEvent(View* view, ax::mojom::Event event_type) {
CHECK(view);
if (!enabled_)
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);
}
void AXRemoteHost::FlushForTesting() {
ax_host_ptr_.FlushForTesting();
}
......
......@@ -15,6 +15,7 @@
#include "ui/accessibility/mojom/ax_host.mojom.h"
#include "ui/display/display_observer.h"
#include "ui/views/accessibility/ax_aura_obj_cache.h"
#include "ui/views/accessibility/ax_event_observer.h"
#include "ui/views/mus/mus_export.h"
#include "ui/views/widget/widget_observer.h"
......@@ -40,7 +41,8 @@ class Widget;
class VIEWS_MUS_EXPORT AXRemoteHost : public ax::mojom::AXRemoteHost,
public WidgetObserver,
public display::DisplayObserver,
public AXAuraObjCache::Delegate {
public AXAuraObjCache::Delegate,
public AXEventObserver {
public:
AXRemoteHost();
~AXRemoteHost() override;
......@@ -56,9 +58,6 @@ class VIEWS_MUS_EXPORT AXRemoteHost : public ax::mojom::AXRemoteHost,
void StartMonitoringWidget(Widget* widget);
void StopMonitoringWidget();
// Handles an event fired upon a |view|.
void HandleEvent(View* view, ax::mojom::Event event_type);
// ax::mojom::AXRemoteHost:
void OnAutomationEnabled(bool enabled) override;
void PerformAction(const ui::AXActionData& action) override;
......@@ -76,6 +75,9 @@ class VIEWS_MUS_EXPORT AXRemoteHost : public ax::mojom::AXRemoteHost,
void OnEvent(AXAuraObjWrapper* aura_obj,
ax::mojom::Event event_type) override;
// AXEventObserver:
void OnViewEvent(View* view, ax::mojom::Event event_type) override;
void FlushForTesting();
Widget* widget_for_testing() { return widget_; }
......
......@@ -117,8 +117,9 @@ AXRemoteHost* CreateRemote(TestAXHostService* service) {
remote->InitForTesting(service->CreateInterfacePtr());
remote->FlushForTesting();
// Install the AXRemoteHost on MusClient so it monitors Widget creation.
AXRemoteHost* remote_raw = remote.get();
MusClientTestApi::SetAXRemoteHost(std::move(remote));
return MusClient::Get()->ax_remote_host();
return remote_raw;
}
std::unique_ptr<Widget> CreateTestWidget() {
......@@ -193,7 +194,7 @@ TEST_F(AXRemoteHostTest, SendEventOnViewWithNoWidget) {
// Create a view that is not yet associated with the widget.
views::View view;
remote->HandleEvent(&view, ax::mojom::Event::kLocationChanged);
remote->OnViewEvent(&view, ax::mojom::Event::kLocationChanged);
// No crash.
}
......
......@@ -115,8 +115,6 @@ class VIEWS_MUS_EXPORT MusClient : public aura::WindowTreeClientDelegate,
aura::WindowTreeClient* window_tree_client() { return window_tree_client_; }
AXRemoteHost* ax_remote_host() { return ax_remote_host_.get(); }
// Creates DesktopNativeWidgetAura with DesktopWindowTreeHostMus. This is
// set as the factory function used for creating NativeWidgets when a
// NativeWidget has not been explicitly set.
......
......@@ -4,7 +4,6 @@
#include "ui/views/mus/mus_views_delegate.h"
#include "ui/views/mus/ax_remote_host.h"
#include "ui/views/mus/mus_client.h"
namespace views {
......@@ -13,10 +12,4 @@ MusViewsDelegate::MusViewsDelegate() = default;
MusViewsDelegate::~MusViewsDelegate() = default;
void MusViewsDelegate::NotifyAccessibilityEvent(View* view,
ax::mojom::Event event_type) {
if (MusClient::Get()->ax_remote_host())
MusClient::Get()->ax_remote_host()->HandleEvent(view, event_type);
}
} // namespace views
......@@ -12,15 +12,12 @@
namespace views {
// TODO(jamescook): Move the LayoutProvider and delete this class.
class VIEWS_MUS_EXPORT MusViewsDelegate : public ViewsDelegate {
public:
MusViewsDelegate();
~MusViewsDelegate() override;
// ViewsDelegate:
void NotifyAccessibilityEvent(View* view,
ax::mojom::Event event_type) override;
private:
LayoutProvider layout_provider_;
......
......@@ -44,6 +44,7 @@
#include "ui/gfx/skia_util.h"
#include "ui/gfx/transform.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/accessibility/ax_event_manager.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
......@@ -52,7 +53,6 @@
#include "ui/views/layout/layout_manager.h"
#include "ui/views/view_observer.h"
#include "ui/views/view_tracker.h"
#include "ui/views/views_delegate.h"
#include "ui/views/views_switches.h"
#include "ui/views/widget/native_widget_private.h"
#include "ui/views/widget/root_view.h"
......@@ -1451,8 +1451,7 @@ gfx::NativeViewAccessible View::GetNativeViewAccessible() {
void View::NotifyAccessibilityEvent(ax::mojom::Event event_type,
bool send_native_event) {
if (ViewsDelegate::GetInstance())
ViewsDelegate::GetInstance()->NotifyAccessibilityEvent(this, event_type);
AXEventManager::Get()->NotifyViewEvent(this, event_type);
if (send_native_event && GetWidget())
GetViewAccessibility().NotifyAccessibilityEvent(event_type);
......
......@@ -61,9 +61,6 @@ bool ViewsDelegate::GetSavedWindowPlacement(
return false;
}
void ViewsDelegate::NotifyAccessibilityEvent(View* view,
ax::mojom::Event event_type) {}
void ViewsDelegate::NotifyMenuItemFocused(const base::string16& menu_name,
const base::string16& menu_item_name,
int item_index,
......
......@@ -17,7 +17,6 @@
#include "base/macros.h"
#include "base/strings/string16.h"
#include "build/build_config.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/base/ui_base_types.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/views_export.h"
......@@ -37,7 +36,6 @@ namespace views {
class NativeWidget;
class NonClientFrameView;
class View;
class Widget;
#if defined(USE_AURA)
......@@ -125,10 +123,6 @@ class VIEWS_EXPORT ViewsDelegate {
gfx::Rect* bounds,
ui::WindowShowState* show_state) const;
// Handles an event on a |view|. The |view| must not be null.
virtual void NotifyAccessibilityEvent(View* view,
ax::mojom::Event event_type);
// For accessibility, notify the delegate that a menu item was focused
// so that alternate feedback (speech / magnified text) can be provided.
virtual void NotifyMenuItemFocused(const base::string16& menu_name,
......
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