chromium/chrome/browser/lacros/automation_manager_lacros.cc

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/lacros/automation_manager_lacros.h"

#include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h"
#include "chromeos/lacros/lacros_service.h"
#include "extensions/browser/api/automation_internal/automation_event_router.h"
#include "extensions/browser/api/automation_internal/automation_internal_api.h"
#include "ui/accessibility/ax_tree_id.h"

AutomationManagerLacros::AutomationManagerLacros() {
  chromeos::LacrosService* impl = chromeos::LacrosService::Get();
  if (!impl->IsAvailable<crosapi::mojom::AutomationFactory>())
    return;

  impl->GetRemote<crosapi::mojom::AutomationFactory>()->BindAutomation(
      automation_client_receiver_.BindNewPipeAndPassRemoteWithVersion(),
      automation_remote_.BindNewPipeAndPassReceiver());

  extensions::AutomationEventRouter::GetInstance()->RegisterRemoteRouter(this);
}

AutomationManagerLacros::~AutomationManagerLacros() {
  chromeos::LacrosService* impl = chromeos::LacrosService::Get();
  if (!impl->IsAvailable<crosapi::mojom::AutomationFactory>())
    return;

  extensions::AutomationEventRouter::GetInstance()->RegisterRemoteRouter(
      nullptr);
}

void AutomationManagerLacros::DispatchAccessibilityEvents(
    const ui::AXTreeID& tree_id,
    const std::vector<ui::AXTreeUpdate>& updates,
    const gfx::Point& mouse_location,
    const std::vector<ui::AXEvent>& events) {
  if (!tree_id.token())
    return;

  // TODO: we probably don't want to check every time but only once and cache
  // the value(s). Also, we need to check all accessibility enums, structs
  // reachable from AXTreeUpdate and AXEvent.
  int remote_version = chromeos::LacrosService::Get()
                           ->GetInterfaceVersion<crosapi::mojom::Automation>();
  if (remote_version < 0 ||
      crosapi::mojom::Automation::kDispatchAccessibilityEventsMinVersion >
          static_cast<uint32_t>(remote_version)) {
    return;
  }

  DCHECK(automation_remote_);
  automation_remote_->DispatchAccessibilityEvents(*tree_id.token(), updates,
                                                  mouse_location, events);
}

void AutomationManagerLacros::DispatchAccessibilityLocationChange(
    const ui::AXLocationChanges& details) {
  ui::AXTreeID tree_id = details.ax_tree_id;
  if (!tree_id.token())
    return;

  DCHECK(automation_remote_);
  automation_remote_->DispatchAccessibilityLocationChange(
      *tree_id.token(), details.id, details.new_location);
}

void AutomationManagerLacros::DispatchTreeDestroyedEvent(ui::AXTreeID tree_id) {
  if (!tree_id.token())
    return;

  DCHECK(automation_remote_);
  automation_remote_->DispatchTreeDestroyedEvent(*(tree_id.token()));
}

void AutomationManagerLacros::DispatchActionResult(
    const ui::AXActionData& data,
    bool result,
    content::BrowserContext* browser_context) {
  DCHECK(automation_remote_);
  automation_remote_->DispatchActionResult(data, result);
}

void AutomationManagerLacros::DispatchGetTextLocationDataResult(
    const ui::AXActionData& data,
    const std::optional<gfx::Rect>& rect) {
  // Unsupported by Laros.
}

void AutomationManagerLacros::Enable() {
  AutomationManagerAura::GetInstance()->Enable();
}

void AutomationManagerLacros::EnableTree(const base::UnguessableToken& token) {
  ui::AXTreeID tree_id = ui::AXTreeID::FromToken(token);
  extensions::AutomationInternalEnableTreeFunction::EnableTree(
      tree_id, /*extension_id=*/"");
}

void AutomationManagerLacros::Disable() {
  AutomationManagerAura::GetInstance()->Disable();
}

void AutomationManagerLacros::PerformActionDeprecated(
    const base::UnguessableToken& token,
    int32_t automation_node_id,
    const std::string& action_type,
    int32_t request_id,
    base::Value::Dict optional_args) {}

void AutomationManagerLacros::PerformAction(
    const ui::AXActionData& action_data) {
  extensions::AutomationInternalPerformActionFunction::PerformAction(
      action_data, /*extension=*/nullptr, /*automation_info=*/nullptr);
}

void AutomationManagerLacros::NotifyAllAutomationExtensionsGone() {
  extensions::AutomationEventRouter::GetInstance()
      ->NotifyAllAutomationExtensionsGone();
}

void AutomationManagerLacros::NotifyExtensionListenerAdded() {
  extensions::AutomationEventRouter::GetInstance()
      ->NotifyExtensionListenerAdded();
}