Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(593)

Side by Side Diff: chrome/browser/extensions/api/automation_internal/automation_event_router.cc

Issue 1151523009: Forward accessibility events to the automation extension process. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@step1
Patch Set: Address feedback Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/api/automation_internal/automation_event_rou ter.h"
6
7 #include <algorithm>
8 #include <string>
9 #include <utility>
10
11 #include "base/stl_util.h"
12 #include "base/values.h"
13 #include "chrome/browser/accessibility/ax_tree_id_registry.h"
14 #include "chrome/common/extensions/api/automation_internal.h"
15 #include "chrome/common/extensions/chrome_extension_messages.h"
16 #include "content/public/browser/notification_service.h"
17 #include "content/public/browser/notification_source.h"
18 #include "content/public/browser/notification_types.h"
19 #include "content/public/browser/render_process_host.h"
20 #include "extensions/browser/event_router.h"
21 #include "ui/accessibility/ax_enums.h"
22 #include "ui/accessibility/ax_node_data.h"
23
24 namespace extensions {
25
26 // static
27 AutomationEventRouter* AutomationEventRouter::GetInstance() {
28 return Singleton<AutomationEventRouter,
29 LeakySingletonTraits<AutomationEventRouter>>::get();
30 }
31
32 AutomationEventRouter::AutomationEventRouter() {
33 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
34 content::NotificationService::AllBrowserContextsAndSources());
35 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
36 content::NotificationService::AllBrowserContextsAndSources());
37 }
38
39 AutomationEventRouter::~AutomationEventRouter() {
40 }
41
42 void AutomationEventRouter::RegisterListenerForOneTree(
43 int listener_process_id,
44 int listener_routing_id,
45 int source_ax_tree_id) {
46 Register(listener_process_id, listener_routing_id, source_ax_tree_id, false);
47 }
48
49 void AutomationEventRouter::RegisterListenerWithDesktopPermission(
50 int listener_process_id,
51 int listener_routing_id) {
52 Register(listener_process_id, listener_routing_id, 0, true);
53 }
54
55 void AutomationEventRouter::DispatchAccessibilityEvent(
56 const ExtensionMsg_AccessibilityEventParams& params) {
57 for (const auto& listener : listeners_) {
58 if (!listener.desktop &&
59 listener.tree_ids.find(params.tree_id) == listener.tree_ids.end()) {
60 continue;
61 }
62
63 content::RenderProcessHost* rph =
64 content::RenderProcessHost::FromID(listener.process_id);
65 rph->Send(new ExtensionMsg_AccessibilityEvent(listener.routing_id, params));
66 }
67 }
68
69 void AutomationEventRouter::DispatchTreeDestroyedEvent(
70 int tree_id,
71 content::BrowserContext* browser_context) {
72 std::string event_name(
73 api::automation_internal::OnAccessibilityTreeDestroyed::kEventName);
74 scoped_ptr<base::ListValue> args(
75 api::automation_internal::OnAccessibilityTreeDestroyed::Create(tree_id));
76 scoped_ptr<Event> event(new Event(event_name, args.Pass()));
77 event->restrict_to_browser_context = browser_context;
78 EventRouter::Get(browser_context)->BroadcastEvent(event.Pass());
79 }
80
81 AutomationEventRouter::AutomationListener::AutomationListener() {
82 }
83
84 AutomationEventRouter::AutomationListener::~AutomationListener() {
85 }
86
87 void AutomationEventRouter::Register(
88 int listener_process_id,
89 int listener_routing_id,
90 int ax_tree_id,
91 bool desktop) {
92 auto iter = std::find_if(
93 listeners_.begin(),
94 listeners_.end(),
95 [listener_process_id, listener_routing_id](AutomationListener& item) {
96 return (item.process_id == listener_process_id &&
97 item.routing_id == listener_routing_id);
98 });
99
100 // Add a new entry if we don't have one with that process and routing id.
101 if (iter == listeners_.end()) {
102 AutomationListener listener;
103 listener.routing_id = listener_routing_id;
104 listener.process_id = listener_process_id;
105 listener.desktop = desktop;
106 listener.tree_ids.insert(ax_tree_id);
107 listeners_.push_back(listener);
108 return;
109 }
110
111 // We have an entry with that process and routing id, so update the set of
112 // tree ids it wants to listen to, and update its desktop permission.
113 iter->tree_ids.insert(ax_tree_id);
114 if (desktop)
115 iter->desktop = true;
116 }
117
118 void AutomationEventRouter::Observe(
119 int type,
120 const content::NotificationSource& source,
121 const content::NotificationDetails& details) {
122 if (type != content::NOTIFICATION_RENDERER_PROCESS_TERMINATED &&
123 type != content::NOTIFICATION_RENDERER_PROCESS_CLOSED) {
124 NOTREACHED();
125 return;
126 }
127
128 content::RenderProcessHost* rph =
129 content::Source<content::RenderProcessHost>(source).ptr();
130 int process_id = rph->GetID();
131 std::remove_if(
132 listeners_.begin(),
133 listeners_.end(),
134 [=](AutomationListener& item) {
dcheng 2015/06/08 18:07:05 This lambda is using default capture too
dmazzoni 2015/06/08 18:45:57 Done.
135 return item.process_id = process_id;
136 });
137 }
138
139 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698