// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_ACCESSIBILITY_SERVICE_ACCESSIBILITY_SERVICE_CLIENT_H_
#define CHROME_BROWSER_ASH_ACCESSIBILITY_SERVICE_ACCESSIBILITY_SERVICE_CLIENT_H_
#include <vector>
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/accessibility/public/mojom/accessibility_service.mojom.h"
#include "services/accessibility/public/mojom/file_loader.mojom.h"
#include "services/accessibility/public/mojom/speech_recognition.mojom-forward.h"
#include "services/accessibility/public/mojom/tts.mojom-forward.h"
#include "services/accessibility/public/mojom/user_interface.mojom-forward.h"
#include "ui/gfx/geometry/point.h"
namespace content {
class BrowserContext;
class DevToolsAgentHost;
}
namespace ash {
class AutoclickClientImpl;
class AutomationClientImpl;
class SpeechRecognitionImpl;
class TtsClientImpl;
class UserInputImpl;
class UserInterfaceImpl;
// The AccessibilityServiceClient in the Browser process interacts with the
// AccessibilityService process over mojom. It is responsible for communicating
// to the service which features are running and binding helper classes for the
// service.
// TODO(crbug.com/1355633): Move to ash/accessibility/service.
class AccessibilityServiceClient : public ax::mojom::AccessibilityServiceClient,
public ax::mojom::AccessibilityFileLoader {
public:
AccessibilityServiceClient();
AccessibilityServiceClient(const AccessibilityServiceClient&) = delete;
AccessibilityServiceClient& operator=(const AccessibilityServiceClient&) =
delete;
~AccessibilityServiceClient() override;
// ax::mojom::AccessibilityServiceClient:
void BindAutomation(
mojo::PendingAssociatedRemote<ax::mojom::Automation> automation) override;
void BindAutomationClient(mojo::PendingReceiver<ax::mojom::AutomationClient>
automation_client) override;
void BindAutoclickClient(mojo::PendingReceiver<ax::mojom::AutoclickClient>
autoclick_receiver) override;
void BindSpeechRecognition(
mojo::PendingReceiver<ax::mojom::SpeechRecognition> sr_receiver) override;
void BindTts(mojo::PendingReceiver<ax::mojom::Tts> tts_receiver) override;
void BindUserInput(
mojo::PendingReceiver<ax::mojom::UserInput> ui_receiver) override;
void BindUserInterface(
mojo::PendingReceiver<ax::mojom::UserInterface> ui_receiver) override;
void BindAccessibilityFileLoader(
mojo::PendingReceiver<ax::mojom::AccessibilityFileLoader>
file_loader_receiver) override;
// ax::mojom::AccessibilityFileLoader:
void Load(const base::FilePath& path, LoadCallback callback) override;
void SetProfile(content::BrowserContext* profile);
// Enables or disables accessibility features in the service.
void SetChromeVoxEnabled(bool enabled);
void SetSelectToSpeakEnabled(bool enabled);
void SetSwitchAccessEnabled(bool enabled);
void SetAutoclickEnabled(bool enabled);
void SetMagnifierEnabled(bool enabled);
void SetDictationEnabled(bool enabled);
// Sends information into the accessibility service.
void RequestScrollableBoundsForPoint(const gfx::Point& point);
private:
friend class AccessibilityServiceClientTest;
friend class AccessibilityManagerWithAccessibilityServiceTest;
// Called when the profile changes or on destruction. Disconnects all mojom
// endpoints.
void Reset();
void EnableAssistiveTechnology(ax::mojom::AssistiveTechnologyType type,
bool enabled);
void LaunchAccessibilityServiceAndBind();
void CreateDevToolsAgentHost(ax::mojom::AssistiveTechnologyType type);
// Function is used to create a callback that is passed into a
// AccessibilityServiceDevToolsDelegate. It should not be called directly.
void ConnectDevToolsAgent(
::mojo::PendingAssociatedReceiver<blink::mojom::DevToolsAgent> agent,
ax::mojom::AssistiveTechnologyType type);
// Helper method to return the opened file from the UI thread once it has been
// opened.
void OnFileLoaded(LoadCallback callback, base::File file);
std::unique_ptr<AutoclickClientImpl> autoclick_client_;
std::unique_ptr<AutomationClientImpl> automation_client_;
std::unique_ptr<SpeechRecognitionImpl> speech_recognition_impl_;
std::unique_ptr<TtsClientImpl> tts_client_;
std::unique_ptr<UserInputImpl> user_input_client_;
std::unique_ptr<UserInterfaceImpl> user_interface_client_;
// Track the currently enabled features in case we disconnect from the service
// and need to reconnect, for example when the profile changes.
std::vector<ax::mojom::AssistiveTechnologyType> enabled_features_;
raw_ptr<content::BrowserContext> profile_ = nullptr;
// Here is the remote to the AT Controller, used to toggle features.
mojo::Remote<ax::mojom::AssistiveTechnologyController> at_controller_;
// This class receives mojom requests from the service via the interface
// AccessibilityServiceClient.
mojo::Receiver<ax::mojom::AccessibilityServiceClient> service_client_{this};
// Loads files on demand by the accessibility service.
mojo::Receiver<ax::mojom::AccessibilityFileLoader> file_loader_{this};
// Container mapping AT type and devtools host.
std::map<ax::mojom::AssistiveTechnologyType,
scoped_refptr<content::DevToolsAgentHost>>
devtools_agent_hosts_;
base::WeakPtrFactory<AccessibilityServiceClient> weak_ptr_factory_{this};
};
} // namespace ash
#endif // CHROME_BROWSER_ASH_ACCESSIBILITY_SERVICE_ACCESSIBILITY_SERVICE_CLIENT_H_