blob: 32f4172e137f2cad5937337c8cd9195e127763d1 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/accessibility/tree/browser_views_ax_manager.h"
#include <utility>
#include "base/auto_reset.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/notimplemented.h"
#include "base/task/single_thread_task_runner.h"
#include "components/crash/core/common/crash_key.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/aura/aura_window_properties.h"
#include "ui/accessibility/ax_action_data.h"
#include "ui/accessibility/ax_event.h"
#include "ui/accessibility/ax_tree_source_checker.h"
#include "ui/accessibility/platform/ax_platform.h"
#include "ui/accessibility/platform/browser_accessibility_manager.h"
#include "ui/aura/client/focus_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/display/screen.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/accessibility/ax_update_notifier.h"
#include "ui/views/accessibility/ax_virtual_view.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/coordinate_conversion.h"
#include "ui/wm/public/activation_client.h"
namespace views {
BrowserViewsAXManager* g_instance = nullptr;
BrowserViewsAXManager::LifetimeHandle::LifetimeHandle(
BrowserViewsAXManagerPassKey) {
instance_ = std::make_unique<BrowserViewsAXManager>(LifetimeHandlePassKey());
}
BrowserViewsAXManager::LifetimeHandle::~LifetimeHandle() = default;
BrowserViewsAXManager::BrowserViewsAXManager(LifetimeHandlePassKey) {
CHECK(::features::IsAccessibilityTreeForViewsEnabled());
CHECK(!g_instance);
g_instance = this;
ui::AXPlatform::GetInstance().AddModeObserver(this);
if (ui::AXPlatform::GetInstance().GetMode() == ui::AXMode::kNativeAPIs) {
Enable();
}
}
BrowserViewsAXManager::~BrowserViewsAXManager() {
DCHECK_EQ(g_instance, this);
ui::AXPlatform::GetInstance().RemoveModeObserver(this);
g_instance = nullptr;
}
std::unique_ptr<BrowserViewsAXManager::LifetimeHandle>
BrowserViewsAXManager::Create() {
CHECK(::features::IsAccessibilityTreeForViewsEnabled());
CHECK(!g_instance);
return std::make_unique<LifetimeHandle>(
LifetimeHandle::BrowserViewsAXManagerPassKey());
}
BrowserViewsAXManager* BrowserViewsAXManager::GetInstance() {
CHECK(g_instance);
return g_instance;
}
ui::AXPlatformNodeId BrowserViewsAXManager::GetOrCreateAXNodeUniqueId(
ui::AXNodeID ax_node_id) {
auto iter = ax_unique_ids_.lower_bound(ax_node_id);
if (iter == ax_unique_ids_.end() || iter->first != ax_node_id) {
iter =
ax_unique_ids_.emplace_hint(iter, ax_node_id, ui::AXUniqueId::Create());
}
return iter->second;
}
void BrowserViewsAXManager::OnAXNodeDeleted(ui::AXNodeID ax_node_id) {
ax_unique_ids_.erase(ax_node_id);
}
void BrowserViewsAXManager::AccessibilityPerformAction(
const ui::AXActionData& data) {
NOTIMPLEMENTED();
}
bool BrowserViewsAXManager::AccessibilityViewHasFocus() {
NOTIMPLEMENTED();
return false;
}
void BrowserViewsAXManager::AccessibilityViewSetFocus() {
NOTIMPLEMENTED();
}
gfx::Rect BrowserViewsAXManager::AccessibilityGetViewBounds() {
NOTIMPLEMENTED();
return gfx::Rect();
}
float BrowserViewsAXManager::AccessibilityGetDeviceScaleFactor() {
NOTIMPLEMENTED();
return 1.0f;
}
void BrowserViewsAXManager::UnrecoverableAccessibilityError() {
NOTIMPLEMENTED();
}
gfx::AcceleratedWidget
BrowserViewsAXManager::AccessibilityGetAcceleratedWidget() {
NOTIMPLEMENTED();
return gfx::kNullAcceleratedWidget;
}
gfx::NativeViewAccessible
BrowserViewsAXManager::AccessibilityGetNativeViewAccessible() {
NOTIMPLEMENTED();
return nullptr;
}
gfx::NativeViewAccessible
BrowserViewsAXManager::AccessibilityGetNativeViewAccessibleForWindow() {
NOTIMPLEMENTED();
return nullptr;
}
gfx::NativeViewAccessible
BrowserViewsAXManager::GetRootViewNativeViewAccessible() {
if (!is_enabled()) {
return nullptr;
}
ui::BrowserAccessibility* root =
ax_tree_manager_->GetBrowserAccessibilityRoot();
if (!root) {
return nullptr;
}
return root->GetNativeViewAccessible();
}
void BrowserViewsAXManager::AccessibilityHitTest(
const gfx::Point& point_in_frame_pixels,
const ax::mojom::Event& opt_event_to_fire,
int opt_request_id,
base::OnceCallback<void(ui::AXPlatformTreeManager* hit_manager,
ui::AXNodeID hit_node_id)> opt_callback) {
NOTIMPLEMENTED();
}
gfx::NativeWindow BrowserViewsAXManager::GetTopLevelNativeWindow() {
NOTIMPLEMENTED();
return nullptr;
}
bool BrowserViewsAXManager::CanFireAccessibilityEvents() const {
return is_enabled();
}
bool BrowserViewsAXManager::AccessibilityIsRootFrame() const {
return false;
}
bool BrowserViewsAXManager::ShouldSuppressAXLoadComplete() {
NOTIMPLEMENTED();
return false;
}
content::WebContentsAccessibility*
BrowserViewsAXManager::AccessibilityGetWebContentsAccessibility() {
// This will never be a web content tree.
return nullptr;
}
bool BrowserViewsAXManager::AccessibilityIsWebContentSource() {
return false;
}
void BrowserViewsAXManager::OnAXModeAdded(ui::AXMode mode) {
if (mode.has_mode(ui::AXMode::kNativeAPIs)) {
Enable();
}
}
void BrowserViewsAXManager::Reset(bool reset_serializer) {
ViewsAXManager::Reset(reset_serializer);
ax_tree_manager_.reset(ui::BrowserAccessibilityManager::Create(*this, this));
}
} // namespace views