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
|
// Copyright 2015 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.
#ifndef CHROME_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_AUTOMATION_EVENT_ROUTER_H_
#define CHROME_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_AUTOMATION_EVENT_ROUTER_H_
#include <set>
#include <vector>
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/singleton.h"
#include "chrome/common/extensions/api/automation_internal.h"
#include "content/public/browser/ax_event_notification_details.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/extension_messages.h"
#include "ui/accessibility/ax_event_bundle_sink.h"
#include "ui/accessibility/ax_tree_id.h"
class Profile;
namespace content {
class BrowserContext;
} // namespace content
namespace ui {
struct AXActionData;
} // namespace ui
struct ExtensionMsg_AccessibilityEventBundleParams;
struct ExtensionMsg_AccessibilityLocationChangeParams;
namespace extensions {
struct AutomationListener;
class AutomationEventRouter : public ui::AXEventBundleSink,
public content::NotificationObserver {
public:
static AutomationEventRouter* GetInstance();
// Indicates that the listener at |listener_process_id| wants to receive
// automation events from the accessibility tree indicated by
// |source_ax_tree_id|. Automation events are forwarded from now on until the
// listener process dies.
void RegisterListenerForOneTree(const ExtensionId& extension_id,
int listener_process_id,
ui::AXTreeID source_ax_tree_id);
// Indicates that the listener at |listener_process_id| wants to receive
// automation events from all accessibility trees because it has Desktop
// permission.
void RegisterListenerWithDesktopPermission(const ExtensionId& extension_id,
int listener_process_id);
void DispatchAccessibilityEvents(
const ExtensionMsg_AccessibilityEventBundleParams& events);
void DispatchAccessibilityLocationChange(
const ExtensionMsg_AccessibilityLocationChangeParams& params);
// Notify all automation extensions that an accessibility tree was
// destroyed. If |browser_context| is null,
void DispatchTreeDestroyedEvent(ui::AXTreeID tree_id,
content::BrowserContext* browser_context);
// Notify the source extension of the action of an action result.
void DispatchActionResult(const ui::AXActionData& data, bool result);
void SetTreeDestroyedCallbackForTest(
base::RepeatingCallback<void(ui::AXTreeID)> cb);
// Notify the source extension of the result to getTextLocation.
void DispatchGetTextLocationDataResult(const ui::AXActionData& data,
const base::Optional<gfx::Rect>& rect);
private:
struct AutomationListener {
AutomationListener();
AutomationListener(const AutomationListener& other);
~AutomationListener();
ExtensionId extension_id;
int process_id;
bool desktop;
std::set<ui::AXTreeID> tree_ids;
bool is_active_profile;
};
AutomationEventRouter();
~AutomationEventRouter() override;
void Register(const ExtensionId& extension_id,
int listener_process_id,
ui::AXTreeID source_ax_tree_id,
bool desktop);
// ui::AXEventBundleSink:
void DispatchAccessibilityEvents(const ui::AXTreeID& tree_id,
std::vector<ui::AXTreeUpdate> updates,
const gfx::Point& mouse_location,
std::vector<ui::AXEvent> events) override;
// content::NotificationObserver interface.
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override;
// Called when the user switches profiles or when a listener is added
// or removed. The purpose is to ensure that multiple instances of the
// same extension running in different profiles don't interfere with one
// another, so in that case only the one associated with the active profile
// is marked as active.
//
// This is needed on Chrome OS because ChromeVox loads into the login profile
// in addition to the active profile. If a similar fix is needed on other
// platforms, we'd need an equivalent of SessionStateObserver that works
// everywhere.
void UpdateActiveProfile();
content::NotificationRegistrar registrar_;
std::vector<AutomationListener> listeners_;
Profile* active_profile_;
base::RepeatingCallback<void(ui::AXTreeID)> tree_destroyed_callback_for_test_;
friend struct base::DefaultSingletonTraits<AutomationEventRouter>;
DISALLOW_COPY_AND_ASSIGN(AutomationEventRouter);
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_AUTOMATION_EVENT_ROUTER_H_
|