Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / chrome / browser / extensions / api / automation_internal / automation_event_router.cc
blobc13e9197187d1316d092c2c3402b83365e4df935
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 base::Singleton<
28 AutomationEventRouter,
29 base::LeakySingletonTraits<AutomationEventRouter>>::get();
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());
39 AutomationEventRouter::~AutomationEventRouter() {
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);
49 void AutomationEventRouter::RegisterListenerWithDesktopPermission(
50 int listener_process_id,
51 int listener_routing_id) {
52 Register(listener_process_id, listener_routing_id, 0, true);
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;
63 content::RenderProcessHost* rph =
64 content::RenderProcessHost::FromID(listener.process_id);
65 rph->Send(new ExtensionMsg_AccessibilityEvent(listener.routing_id,
66 params));
70 void AutomationEventRouter::DispatchTreeDestroyedEvent(
71 int tree_id,
72 content::BrowserContext* browser_context) {
73 scoped_ptr<base::ListValue> args(
74 api::automation_internal::OnAccessibilityTreeDestroyed::Create(tree_id));
75 scoped_ptr<Event> event(new Event(
76 events::AUTOMATION_INTERNAL_ON_ACCESSIBILITY_TREE_DESTROYED,
77 api::automation_internal::OnAccessibilityTreeDestroyed::kEventName,
78 args.Pass()));
79 event->restrict_to_browser_context = browser_context;
80 EventRouter::Get(browser_context)->BroadcastEvent(event.Pass());
83 AutomationEventRouter::AutomationListener::AutomationListener() {
86 AutomationEventRouter::AutomationListener::~AutomationListener() {
89 void AutomationEventRouter::Register(
90 int listener_process_id,
91 int listener_routing_id,
92 int ax_tree_id,
93 bool desktop) {
94 auto iter = std::find_if(
95 listeners_.begin(),
96 listeners_.end(),
97 [listener_process_id, listener_routing_id](
98 const AutomationListener& item) {
99 return (item.process_id == listener_process_id &&
100 item.routing_id == listener_routing_id);
103 // Add a new entry if we don't have one with that process and routing id.
104 if (iter == listeners_.end()) {
105 AutomationListener listener;
106 listener.routing_id = listener_routing_id;
107 listener.process_id = listener_process_id;
108 listener.desktop = desktop;
109 listener.tree_ids.insert(ax_tree_id);
110 listeners_.push_back(listener);
111 return;
114 // We have an entry with that process and routing id, so update the set of
115 // tree ids it wants to listen to, and update its desktop permission.
116 iter->tree_ids.insert(ax_tree_id);
117 if (desktop)
118 iter->desktop = true;
121 void AutomationEventRouter::Observe(
122 int type,
123 const content::NotificationSource& source,
124 const content::NotificationDetails& details) {
125 if (type != content::NOTIFICATION_RENDERER_PROCESS_TERMINATED &&
126 type != content::NOTIFICATION_RENDERER_PROCESS_CLOSED) {
127 NOTREACHED();
128 return;
131 content::RenderProcessHost* rph =
132 content::Source<content::RenderProcessHost>(source).ptr();
133 int process_id = rph->GetID();
134 listeners_.erase(
135 std::remove_if(
136 listeners_.begin(),
137 listeners_.end(),
138 [process_id](const AutomationListener& item) {
139 return item.process_id == process_id;
141 listeners_.end());
144 } // namespace extensions