blob: ac9ebcbf647790fbeffc828d211a13c356bea6cc [file] [log] [blame]
// 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 "chrome/browser/chromeos/accessibility/ax_host_service.h"
#include <utility>
#include "base/bind.h"
#include "base/stl_util.h"
#include "chrome/browser/chromeos/accessibility/ax_remote_host_delegate.h"
#include "ui/accessibility/ax_tree_id.h"
AXHostService* AXHostService::instance_ = nullptr;
bool AXHostService::automation_enabled_ = false;
AXHostService::AXHostService(service_manager::mojom::ServiceRequest request)
: service_binding_(this, std::move(request)) {
DCHECK(!instance_);
instance_ = this;
registry_.AddInterface<ax::mojom::AXHost>(
base::BindRepeating(&AXHostService::AddBinding, base::Unretained(this)));
}
AXHostService::~AXHostService() {
DCHECK_EQ(instance_, this);
instance_ = nullptr;
}
// static
void AXHostService::SetAutomationEnabled(bool enabled) {
automation_enabled_ = enabled;
if (instance_)
instance_->NotifyAutomationEnabled();
}
void AXHostService::OnBindInterface(
const service_manager::BindSourceInfo& remote_info,
const std::string& interface_name,
mojo::ScopedMessagePipeHandle interface_pipe) {
registry_.BindInterface(interface_name, std::move(interface_pipe));
}
void AXHostService::RegisterRemoteHost(
ax::mojom::AXRemoteHostPtr remote_host_ptr,
RegisterRemoteHostCallback cb) {
// Create the AXRemoteHostDelegate first so a tree ID will be assigned.
auto remote_host_delegate =
std::make_unique<AXRemoteHostDelegate>(this, std::move(remote_host_ptr));
ui::AXTreeID tree_id = remote_host_delegate->ax_tree_id();
DCHECK_NE(ui::AXTreeIDUnknown(), tree_id);
DCHECK(!base::ContainsKey(remote_host_delegate_map_, tree_id));
remote_host_delegate_map_[tree_id] = std::move(remote_host_delegate);
// Inform the remote process of the tree ID.
std::move(cb).Run(tree_id, automation_enabled_);
}
void AXHostService::HandleAccessibilityEvent(
const ui::AXTreeID& tree_id,
const std::vector<ui::AXTreeUpdate>& updates,
const ui::AXEvent& event) {
auto it = remote_host_delegate_map_.find(tree_id);
if (it == remote_host_delegate_map_.end())
return;
AXRemoteHostDelegate* delegate = it->second.get();
delegate->HandleAccessibilityEvent(tree_id, updates, event);
}
void AXHostService::OnRemoteHostDisconnected(const ui::AXTreeID& tree_id) {
// AXRemoteHostDelegate notified the extension that the tree was destroyed.
// Delete the AXRemoteHostDelegate.
remote_host_delegate_map_.erase(tree_id);
}
void AXHostService::FlushForTesting() {
for (const auto& pair : remote_host_delegate_map_) {
AXRemoteHostDelegate* delegate = pair.second.get();
delegate->FlushForTesting();
}
}
void AXHostService::AddBinding(ax::mojom::AXHostRequest request) {
bindings_.AddBinding(this, std::move(request));
}
void AXHostService::NotifyAutomationEnabled() {
for (const auto& pair : remote_host_delegate_map_) {
AXRemoteHostDelegate* delegate = pair.second.get();
delegate->OnAutomationEnabled(automation_enabled_);
}
}