1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
// Copyright 2023 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/ash/accessibility/service/user_interface_impl.h"
#include "ash/accessibility/accessibility_controller.h"
#include "ash/public/cpp/accessibility_focus_ring_info.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ash/accessibility/accessibility_manager.h"
#include "content/public/common/color_parser.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "services/accessibility/public/mojom/user_interface.mojom-shared.h"
#include "services/accessibility/public/mojom/user_interface.mojom.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/strings/grit/ui_strings.h"
namespace ash {
UserInterfaceImpl::UserInterfaceImpl() = default;
UserInterfaceImpl::~UserInterfaceImpl() = default;
void UserInterfaceImpl::Bind(
mojo::PendingReceiver<ax::mojom::UserInterface> ui_receiver) {
ui_receivers_.Add(this, std::move(ui_receiver));
}
void UserInterfaceImpl::DarkenScreen(bool darken) {
AccessibilityManager::Get()->SetDarkenScreen(darken);
}
void UserInterfaceImpl::OpenSettingsSubpage(const std::string& subpage) {
AccessibilityManager::Get()->OpenSettingsSubpage(subpage);
}
void UserInterfaceImpl::ShowConfirmationDialog(
const std::string& title,
const std::string& description,
const std::optional<std::string>& cancel_name,
ShowConfirmationDialogCallback callback) {
// If a dialog is already being shown we do not show a new one.
// Instead, return false through the callback on the new dialog
// to indicate it was closed without the user taking any action.
// This is consistent with AcceleratorController, and matches
// the implementation in accessibility_controller_impl.cc.
if (show_confirmation_dialog_callback_) {
std::move(callback).Run(false);
return;
}
show_confirmation_dialog_callback_ = std::move(callback);
ash::AccessibilityController::Get()->ShowConfirmationDialog(
base::UTF8ToUTF16(title), base::UTF8ToUTF16(description),
l10n_util::GetStringUTF16(IDS_APP_CONTINUE),
cancel_name ? base::UTF8ToUTF16(cancel_name.value())
: l10n_util::GetStringUTF16(IDS_APP_CANCEL),
base::BindOnce(&UserInterfaceImpl::OnDialogResult,
weak_factory_.GetWeakPtr(), /* confirmed */ true),
base::BindOnce(&UserInterfaceImpl::OnDialogResult,
weak_factory_.GetWeakPtr(), /* not confirmed */ false),
base::BindOnce(&UserInterfaceImpl::OnDialogResult,
weak_factory_.GetWeakPtr(), /* not confirmed */ false));
}
void UserInterfaceImpl::OnDialogResult(bool confirmed) {
std::move(show_confirmation_dialog_callback_).Run(confirmed);
show_confirmation_dialog_callback_.Reset();
}
void UserInterfaceImpl::SetFocusRings(
std::vector<ax::mojom::FocusRingInfoPtr> focus_rings,
ax::mojom::AssistiveTechnologyType at_type) {
auto* accessibility_manager = AccessibilityManager::Get();
for (auto& focus_ring_info : focus_rings) {
auto focus_ring = std::make_unique<ash::AccessibilityFocusRingInfo>();
focus_ring->behavior = ash::FocusRingBehavior::PERSIST;
for (const gfx::Rect& rect : focus_ring_info->rects) {
focus_ring->rects_in_screen.emplace_back(rect);
}
const std::string id = accessibility_manager->GetFocusRingId(
at_type,
focus_ring_info->id.has_value() ? focus_ring_info->id.value() : "");
if (focus_ring_info->color.has_value()) {
focus_ring->color = focus_ring_info->color.value();
}
if (focus_ring_info->secondary_color.has_value()) {
focus_ring->secondary_color = focus_ring_info->secondary_color.value();
}
if (focus_ring_info->background_color.has_value()) {
focus_ring->background_color = focus_ring_info->background_color.value();
}
switch (focus_ring_info->type) {
case ax::mojom::FocusType::kSolid:
focus_ring->type = ash::FocusRingType::SOLID;
break;
case ax::mojom::FocusType::kDashed:
focus_ring->type = ash::FocusRingType::DASHED;
break;
case ax::mojom::FocusType::kGlow:
focus_ring->type = ash::FocusRingType::GLOW;
break;
}
if (focus_ring_info->stacking_order.has_value()) {
switch (focus_ring_info->stacking_order.value()) {
case ax::mojom::FocusRingStackingOrder::kAboveAccessibilityBubbles:
focus_ring->stacking_order =
ash::FocusRingStackingOrder::ABOVE_ACCESSIBILITY_BUBBLES;
break;
case ax::mojom::FocusRingStackingOrder::kBelowAccessibilityBubbles:
focus_ring->stacking_order =
ash::FocusRingStackingOrder::BELOW_ACCESSIBILITY_BUBBLES;
break;
}
}
// Update the touch exploration controller so that synthesized touch events
// are anchored within the focused object.
// NOTE: The final anchor point will be determined by the first rect of the
// final focus ring.
if (!focus_ring->rects_in_screen.empty()) {
accessibility_manager->SetTouchAccessibilityAnchorPoint(
focus_ring->rects_in_screen[0].CenterPoint());
}
accessibility_manager->SetFocusRing(id, std::move(focus_ring));
}
}
void UserInterfaceImpl::SetHighlights(const std::vector<gfx::Rect>& rects,
SkColor color) {
AccessibilityManager::Get()->SetHighlights(rects, color);
}
void UserInterfaceImpl::SetVirtualKeyboardVisible(bool is_visible) {
AccessibilityController::Get()->SetVirtualKeyboardVisible(is_visible);
}
} // namespace ash
|