Commit 1ed701bc authored by David Tseng's avatar David Tseng Committed by Commit Bot

Remove fake alert AXObjWrapper object

Rather than including a fake alert object within the client accessibility tree, make the views tree include it with an explicit aura::Window.

TBR=servolk@chromium.org

Bug: 888152
Change-Id: I9e190a8e437a78c7e27ebfaab70ec20980dff32d
Reviewed-on: https://chromium-review.googlesource.com/c/1368828
Commit-Queue: David Tseng <dtseng@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/master@{#616064}
parent 8ea7172e
......@@ -170,9 +170,8 @@ TEST_F(AXTreeSourceAuraTest, Serialize) {
// This is the initial serialization.
ax_serializer.SerializeChanges(ax_tree.GetRoot(), &out_update);
// The update should just be the desktop node and the fake alert window we use
// to handle posting text alerts.
ASSERT_EQ(2U, out_update.nodes.size());
// The update should just be the desktop node.
ASSERT_EQ(1U, out_update.nodes.size());
// Try removing some child views and re-adding which should fire some events.
content_->RemoveAllChildViews(false /* delete_children */);
......
......@@ -18,6 +18,7 @@
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/views/accessibility/accessibility_alert_window.h"
#include "ui/views/accessibility/ax_aura_obj_wrapper.h"
#include "ui/views/accessibility/ax_event_manager.h"
#include "ui/views/accessibility/ax_root_obj_wrapper.h"
......@@ -25,6 +26,7 @@
#include "ui/views/widget/widget.h"
#if defined(OS_CHROMEOS)
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/shell.h"
#include "ash/wm/window_util.h"
#include "chrome/browser/chromeos/accessibility/ax_host_service.h"
......@@ -119,13 +121,8 @@ void AutomationManagerAura::SendEventOnObjectById(int32_t id,
}
void AutomationManagerAura::HandleAlert(const std::string& text) {
if (!enabled_)
return;
views::AXAuraObjWrapper* obj =
static_cast<AXRootObjWrapper*>(current_tree_->GetRoot())
->GetAlertForText(text);
SendEvent(obj, ax::mojom::Event::kAlert);
if (alert_window_.get())
alert_window_->HandleAlert(text);
}
void AutomationManagerAura::PerformAction(const ui::AXActionData& data) {
......@@ -172,9 +169,22 @@ void AutomationManagerAura::Reset(bool reset_serializer) {
current_tree_ = std::make_unique<views::AXTreeSourceViews>(
desktop_root_.get(), ax_tree_id());
}
reset_serializer ? current_tree_serializer_.reset()
: current_tree_serializer_.reset(
new AuraAXTreeSerializer(current_tree_.get()));
if (reset_serializer) {
current_tree_serializer_.reset();
alert_window_.reset();
} else {
current_tree_serializer_ =
std::make_unique<AuraAXTreeSerializer>(current_tree_.get());
#if defined(OS_CHROMEOS)
ash::Shell* shell = ash::Shell::Get();
// Windows within the overlay container get moved to the new monitor when
// the primary display gets swapped.
alert_window_ = std::make_unique<views::AccessibilityAlertWindow>(
shell->GetContainer(shell->GetPrimaryRootWindow(),
ash::kShellWindowId_OverlayContainer),
views::AXAuraObjCache::GetInstance());
#endif // defined(OS_CHROMEOS)
}
}
void AutomationManagerAura::SendEvent(views::AXAuraObjWrapper* aura_obj,
......
......@@ -32,6 +32,7 @@ class AXEventBundleSink;
}
namespace views {
class AccessibilityAlertWindow;
class AXAuraObjWrapper;
class View;
} // namespace views
......@@ -117,6 +118,8 @@ class AutomationManagerAura : public ui::AXHostDelegate,
// a fake for tests).
ui::AXEventBundleSink* event_bundle_sink_ = nullptr;
std::unique_ptr<views::AccessibilityAlertWindow> alert_window_;
base::WeakPtrFactory<AutomationManagerAura> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(AutomationManagerAura);
......
......@@ -23,6 +23,7 @@
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/views/accessibility/accessibility_alert_window.h"
#include "ui/views/accessibility/ax_aura_obj_wrapper.h"
#include "ui/views/accessibility/ax_root_obj_wrapper.h"
#include "ui/views/view.h"
......@@ -85,13 +86,8 @@ void AutomationManagerAura::HandleEvent(BrowserContext* context,
void AutomationManagerAura::HandleAlert(content::BrowserContext* context,
const std::string& text) {
if (!enabled_)
return;
views::AXAuraObjWrapper* obj =
static_cast<AXRootObjWrapper*>(current_tree_->GetRoot())
->GetAlertForText(text);
SendEvent(context, obj, ax::mojom::Event::kAlert);
if (alert_window_.get())
alert_window_->HandleAlert(text);
}
void AutomationManagerAura::PerformAction(const ui::AXActionData& data) {
......@@ -127,9 +123,22 @@ void AutomationManagerAura::Reset(bool reset_serializer) {
current_tree_ =
std::make_unique<AXTreeSourceAura>(desktop_root_.get(), ax_tree_id());
}
reset_serializer ? current_tree_serializer_.reset()
: current_tree_serializer_.reset(
new AuraAXTreeSerializer(current_tree_.get()));
if (reset_serializer) {
current_tree_serializer_.reset();
alert_window_.reset();
} else {
current_tree_serializer_ =
std::make_unique<AuraAXTreeSerializer>(current_tree_.get());
#if defined(OS_CHROMEOS)
ash::Shell* shell = ash::Shell::Get();
// Windows within the overlay container get moved to the new monitor when
// the primary display gets swapped.
alert_window_ = std::make_unique<views::AccessibilityAlertWindow>(
shell->GetContainer(shell->GetPrimaryRootWindow(),
ash::kShellWindowId_OverlayContainer),
views::AXAuraObjCache::GetInstance());
#endif // defined(OS_CHROMEOS)
}
}
void AutomationManagerAura::SendEvent(BrowserContext* context,
......
......@@ -30,6 +30,7 @@ class BrowserContext;
} // namespace content
namespace views {
class AccessibilityAlertWindow;
class AXAuraObjWrapper;
class View;
} // namespace views
......@@ -102,6 +103,8 @@ class AutomationManagerAura : public ui::AXHostDelegate,
std::vector<std::pair<views::AXAuraObjWrapper*, ax::mojom::Event>>
pending_events_;
std::unique_ptr<views::AccessibilityAlertWindow> alert_window_;
DISALLOW_COPY_AND_ASSIGN(AutomationManagerAura);
};
......
......@@ -1106,6 +1106,8 @@ void Window::NotifyWindowVisibilityChangedUp(aura::Window* target,
}
bool Window::CleanupGestureState() {
if (!env_->gesture_recognizer())
return false;
bool state_modified = false;
state_modified |= env_->gesture_recognizer()->CancelActiveTouches(this);
state_modified |= env_->gesture_recognizer()->CleanupStateForConsumer(this);
......
......@@ -614,6 +614,8 @@ jumbo_component("views") {
if (use_aura) {
public += [
"accessibility/accessibility_alert_window.cc",
"accessibility/accessibility_alert_window.h",
"accessibility/ax_aura_obj_cache.h",
"accessibility/ax_aura_obj_wrapper.h",
"accessibility/ax_aura_window_utils.h",
......@@ -649,6 +651,8 @@ jumbo_component("views") {
]
sources += [
"accessibility/accessibility_alert_window.cc",
"accessibility/accessibility_alert_window.h",
"accessibility/ax_aura_obj_cache.cc",
"accessibility/ax_aura_obj_wrapper.cc",
"accessibility/ax_aura_window_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/accessibility_alert_window.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/accessibility/platform/aura_window_properties.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer_type.h"
#include "ui/views/accessibility/ax_aura_obj_cache.h"
#include "ui/views/accessibility/view_accessibility.h"
namespace views {
AccessibilityAlertWindow::AccessibilityAlertWindow(aura::Window* parent,
views::AXAuraObjCache* cache)
: cache_(cache) {
CHECK(parent);
alert_window_ = std::make_unique<aura::Window>(
nullptr, aura::client::WINDOW_TYPE_UNKNOWN, parent->env());
alert_window_->set_owned_by_parent(false);
alert_window_->Init(ui::LayerType::LAYER_NOT_DRAWN);
alert_window_->SetProperty(ui::kAXRoleOverride, ax::mojom::Role::kAlert);
parent->AddChild(alert_window_.get());
}
AccessibilityAlertWindow::~AccessibilityAlertWindow() {}
void AccessibilityAlertWindow::HandleAlert(const std::string& alert_string) {
if (!alert_window_->parent())
return;
alert_window_->SetTitle(base::UTF8ToUTF16(alert_string));
cache_->FireEvent(cache_->GetOrCreate(alert_window_.get()),
ax::mojom::Event::kAlert);
}
} // 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_ACCESSIBILITY_ALERT_WINDOW_H_
#define UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_ALERT_WINDOW_H_
#include <string>
#include "base/macros.h"
#include "ui/views/views_export.h"
namespace aura {
class Window;
}
namespace views {
class AXAuraObjCache;
// This class provides a caller a way to alert an accessibility client such as
// ChromeVox with a text string without a backing visible window or view.
class VIEWS_EXPORT AccessibilityAlertWindow {
public:
// |parent| is the window where a child alert window will be added.
AccessibilityAlertWindow(aura::Window* parent, views::AXAuraObjCache* cache);
~AccessibilityAlertWindow();
// Triggers an alert with the text |alert_string| to be sent to an
// accessibility client.
void HandleAlert(const std::string& alert_string);
private:
// The child alert window.
std::unique_ptr<aura::Window> alert_window_;
// The accessibility cache associated with |alert_window_|.
views::AXAuraObjCache* cache_;
DISALLOW_COPY_AND_ASSIGN(AccessibilityAlertWindow);
};
} // namespace views
#endif // UI_VIEWS_ACCESSIBILITY_ACCESSIBILITY_ALERT_WINDOW_H_
......@@ -11,7 +11,6 @@
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/platform/ax_unique_id.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
......@@ -19,11 +18,7 @@
#include "ui/views/accessibility/ax_window_obj_wrapper.h"
AXRootObjWrapper::AXRootObjWrapper(views::AXAuraObjCache::Delegate* delegate)
: alert_window_(std::make_unique<aura::Window>(nullptr)),
delegate_(delegate) {
alert_window_->Init(ui::LAYER_NOT_DRAWN);
aura::Env::GetInstance()->AddObserver(this);
: delegate_(delegate) {
if (display::Screen::GetScreen())
display::Screen::GetScreen()->AddObserver(this);
}
......@@ -31,25 +26,6 @@ AXRootObjWrapper::AXRootObjWrapper(views::AXAuraObjCache::Delegate* delegate)
AXRootObjWrapper::~AXRootObjWrapper() {
if (display::Screen::GetScreen())
display::Screen::GetScreen()->RemoveObserver(this);
// If alert_window_ is nullptr already, that means OnWillDestroyEnv
// was already called, so we shouldn't call RemoveObserver(this) again.
if (!alert_window_)
return;
aura::Env::GetInstance()->RemoveObserver(this);
alert_window_.reset();
}
views::AXAuraObjWrapper* AXRootObjWrapper::GetAlertForText(
const std::string& text) {
alert_window_->SetTitle(base::UTF8ToUTF16((text)));
views::AXWindowObjWrapper* window_obj =
static_cast<views::AXWindowObjWrapper*>(
views::AXAuraObjCache::GetInstance()->GetOrCreate(
alert_window_.get()));
window_obj->set_is_alert(true);
return window_obj;
}
bool AXRootObjWrapper::HasChild(views::AXAuraObjWrapper* child) {
......@@ -69,8 +45,6 @@ views::AXAuraObjWrapper* AXRootObjWrapper::GetParent() {
void AXRootObjWrapper::GetChildren(
std::vector<views::AXAuraObjWrapper*>* out_children) {
views::AXAuraObjCache::GetInstance()->GetTopLevelWindows(out_children);
out_children->push_back(
views::AXAuraObjCache::GetInstance()->GetOrCreate(alert_window_.get()));
}
void AXRootObjWrapper::Serialize(ui::AXNodeData* out_node_data) {
......@@ -104,10 +78,3 @@ void AXRootObjWrapper::OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) {
delegate_->OnEvent(this, ax::mojom::Event::kLocationChanged);
}
void AXRootObjWrapper::OnWindowInitialized(aura::Window* window) {}
void AXRootObjWrapper::OnWillDestroyEnv() {
alert_window_.reset();
aura::Env::GetInstance()->RemoveObserver(this);
}
......@@ -13,21 +13,16 @@
#include "base/macros.h"
#include "ui/accessibility/platform/ax_unique_id.h"
#include "ui/aura/env_observer.h"
#include "ui/display/display_observer.h"
#include "ui/views/accessibility/ax_aura_obj_cache.h"
#include "ui/views/accessibility/ax_aura_obj_wrapper.h"
class VIEWS_EXPORT AXRootObjWrapper : public views::AXAuraObjWrapper,
display::DisplayObserver,
aura::EnvObserver {
display::DisplayObserver {
public:
explicit AXRootObjWrapper(views::AXAuraObjCache::Delegate* delegate);
~AXRootObjWrapper() override;
// Returns an AXAuraObjWrapper for an alert window with title set to |text|.
views::AXAuraObjWrapper* GetAlertForText(const std::string& text);
// Convenience method to check for existence of a child.
bool HasChild(views::AXAuraObjWrapper* child);
......@@ -44,14 +39,8 @@ class VIEWS_EXPORT AXRootObjWrapper : public views::AXAuraObjWrapper,
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) override;
// aura::EnvObserver:
void OnWindowInitialized(aura::Window* window) override;
void OnWillDestroyEnv() override;
ui::AXUniqueId unique_id_;
std::unique_ptr<aura::Window> alert_window_;
views::AXAuraObjCache::Delegate* delegate_;
DISALLOW_COPY_AND_ASSIGN(AXRootObjWrapper);
......
......@@ -44,7 +44,6 @@ AXWindowObjWrapper::AXWindowObjWrapper(AXAuraObjCache* aura_obj_cache,
aura::Window* window)
: aura_obj_cache_(aura_obj_cache),
window_(window),
is_alert_(false),
is_root_window_(window->IsRootWindow()) {
window->AddObserver(this);
......@@ -91,8 +90,7 @@ void AXWindowObjWrapper::Serialize(ui::AXNodeData* out_node_data) {
if (role != ax::mojom::Role::kNone)
out_node_data->role = role;
else
out_node_data->role =
is_alert_ ? ax::mojom::Role::kAlert : ax::mojom::Role::kWindow;
out_node_data->role = ax::mojom::Role::kWindow;
out_node_data->AddStringAttribute(ax::mojom::StringAttribute::kName,
base::UTF16ToUTF8(window_->GetTitle()));
if (!window_->IsVisible())
......
......@@ -28,12 +28,6 @@ class AXWindowObjWrapper : public AXAuraObjWrapper,
AXWindowObjWrapper(AXAuraObjCache* aura_obj_cache, aura::Window* window);
~AXWindowObjWrapper() override;
// Whether this window is an alert window.
bool is_alert() { return is_alert_; }
// Sets whether this window is an alert window.
void set_is_alert(bool is_alert) { is_alert_ = is_alert; }
// AXAuraObjWrapper overrides.
bool IsIgnored() override;
AXAuraObjWrapper* GetParent() override;
......@@ -66,8 +60,6 @@ class AXWindowObjWrapper : public AXAuraObjWrapper,
aura::Window* window_;
bool is_alert_;
bool is_root_window_;
const ui::AXUniqueId unique_id_;
......
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