Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / extensions / api / automation_internal / automation_event_router.cc
blob3e4539d6e85c5c8455ff4fdb75d1f25022b162eb
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.
5 #include "chrome/browser/extensions/api/automation_internal/automation_event_router.h"
7 #include <algorithm>
8 #include <string>
9 #include <utility>
11 #include "base/stl_util.h"
12 #include "base/values.h"
13 #include "chrome/common/extensions/api/automation_internal.h"
14 #include "chrome/common/extensions/chrome_extension_messages.h"
15 #include "content/public/browser/notification_service.h"
16 #include "content/public/browser/notification_source.h"
17 #include "content/public/browser/notification_types.h"
18 #include "content/public/browser/render_process_host.h"
19 #include "extensions/browser/event_router.h"
20 #include "ui/accessibility/ax_enums.h"
21 #include "ui/accessibility/ax_node_data.h"
23 namespace extensions {
25 // static
26 AutomationEventRouter* AutomationEventRouter::GetInstance() {
27 return Singleton<AutomationEventRouter,
28 LeakySingletonTraits<AutomationEventRouter>>::get();
31 AutomationEventRouter::AutomationEventRouter() {
32 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
33 content::NotificationService::AllBrowserContextsAndSources());
34 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
35 content::NotificationService::AllBrowserContextsAndSources());
38 AutomationEventRouter::~AutomationEventRouter() {
41 void AutomationEventRouter::RegisterListenerForOneTree(
42 int listener_process_id,
43 int listener_routing_id,
44 int source_ax_tree_id) {
45 Register(listener_process_id, listener_routing_id, source_ax_tree_id, false);
48 void AutomationEventRouter::RegisterListenerWithDesktopPermission(
49 int listener_process_id,
50 int listener_routing_id) {
51 Register(listener_process_id, listener_routing_id, 0, true);
54 void AutomationEventRouter::DispatchAccessibilityEvent(
55 const ExtensionMsg_AccessibilityEventParams& params) {
56 for (const auto& listener : listeners_) {
57 if (!listener.desktop &&
58 listener.tree_ids.find(params.tree_id) == listener.tree_ids.end()) {
59 continue;
62 content::RenderProcessHost* rph =
63 content::RenderProcessHost::FromID(listener.process_id);
64 rph->Send(new ExtensionMsg_AccessibilityEvent(listener.routing_id,
65 params));
69 void AutomationEventRouter::DispatchTreeDestroyedEvent(
70 int tree_id,
71 content::BrowserContext* browser_context) {
72 scoped_ptr<base::ListValue> args(
73 api::automation_internal::OnAccessibilityTreeDestroyed::Create(tree_id));
74 scoped_ptr<Event> event(new Event(
75 events::AUTOMATION_INTERNAL_ON_ACCESSIBILITY_TREE_DESTROYED,
76 api::automation_internal::OnAccessibilityTreeDestroyed::kEventName,
77 args.Pass()));
78 event->restrict_to_browser_context = browser_context;
79 EventRouter::Get(browser_context)->BroadcastEvent(event.Pass());
82 AutomationEventRouter::AutomationListener::AutomationListener() {
85 AutomationEventRouter::AutomationListener::~AutomationListener() {
88 void AutomationEventRouter::Register(
89 int listener_process_id,
90 int listener_routing_id,
91 int ax_tree_id,
92 bool desktop) {
93 auto iter = std::find_if(
94 listeners_.begin(),
95 listeners_.end(),
96 [listener_process_id, listener_routing_id](
97 const AutomationListener& item) {
98 return (item.process_id == listener_process_id &&
99 item.routing_id == listener_routing_id);
102 // Add a new entry if we don't have one with that process and routing id.
103 if (iter == listeners_.end()) {
104 AutomationListener listener;
105 listener.routing_id = listener_routing_id;
106 listener.process_id = listener_process_id;
107 listener.desktop = desktop;
108 listener.tree_ids.insert(ax_tree_id);
109 listeners_.push_back(listener);
110 return;
113 // We have an entry with that process and routing id, so update the set of
114 // tree ids it wants to listen to, and update its desktop permission.
115 iter->tree_ids.insert(ax_tree_id);
116 if (desktop)
117 iter->desktop = true;
120 void AutomationEventRouter::Observe(
121 int type,
122 const content::NotificationSource& source,
123 const content::NotificationDetails& details) {
124 if (type != content::NOTIFICATION_RENDERER_PROCESS_TERMINATED &&
125 type != content::NOTIFICATION_RENDERER_PROCESS_CLOSED) {
126 NOTREACHED();
127 return;
130 content::RenderProcessHost* rph =
131 content::Source<content::RenderProcessHost>(source).ptr();
132 int process_id = rph->GetID();
133 listeners_.erase(
134 std::remove_if(
135 listeners_.begin(),
136 listeners_.end(),
137 [process_id](const AutomationListener& item) {
138 return item.process_id == process_id;
140 listeners_.end());
143 } // namespace extensions