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

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

Issue 1268163002: Dispatch automation events to the last used profile. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 3 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/automation_internal/automation_event_rou ter.h" 5 #include "chrome/browser/extensions/api/automation_internal/automation_event_rou ter.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "chrome/browser/profiles/profile_manager.h"
13 #include "chrome/common/extensions/api/automation_internal.h" 14 #include "chrome/common/extensions/api/automation_internal.h"
14 #include "chrome/common/extensions/chrome_extension_messages.h" 15 #include "chrome/common/extensions/chrome_extension_messages.h"
15 #include "content/public/browser/notification_service.h" 16 #include "content/public/browser/notification_service.h"
16 #include "content/public/browser/notification_source.h" 17 #include "content/public/browser/notification_source.h"
17 #include "content/public/browser/notification_types.h" 18 #include "content/public/browser/notification_types.h"
18 #include "content/public/browser/render_process_host.h" 19 #include "content/public/browser/render_process_host.h"
19 #include "extensions/browser/event_router.h" 20 #include "extensions/browser/event_router.h"
20 #include "ui/accessibility/ax_enums.h" 21 #include "ui/accessibility/ax_enums.h"
21 #include "ui/accessibility/ax_node_data.h" 22 #include "ui/accessibility/ax_node_data.h"
22 23
23 namespace extensions { 24 namespace extensions {
24 25
25 // static 26 // static
26 AutomationEventRouter* AutomationEventRouter::GetInstance() { 27 AutomationEventRouter* AutomationEventRouter::GetInstance() {
27 return base::Singleton< 28 return base::Singleton<
28 AutomationEventRouter, 29 AutomationEventRouter,
29 base::LeakySingletonTraits<AutomationEventRouter>>::get(); 30 base::LeakySingletonTraits<AutomationEventRouter>>::get();
30 } 31 }
31 32
32 AutomationEventRouter::AutomationEventRouter() { 33 AutomationEventRouter::AutomationEventRouter() {
33 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 34 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
34 content::NotificationService::AllBrowserContextsAndSources()); 35 content::NotificationService::AllBrowserContextsAndSources());
35 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, 36 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
36 content::NotificationService::AllBrowserContextsAndSources()); 37 content::NotificationService::AllBrowserContextsAndSources());
38 active_profile_ = ProfileManager::GetLastUsedProfile();
39
40 #if defined(OS_CHROMEOS)
41 session_state_observer_.reset(new ash::ScopedSessionStateObserver(this));
42 #endif
37 } 43 }
38 44
39 AutomationEventRouter::~AutomationEventRouter() { 45 AutomationEventRouter::~AutomationEventRouter() {
40 } 46 }
41 47
42 void AutomationEventRouter::RegisterListenerForOneTree( 48 void AutomationEventRouter::RegisterListenerForOneTree(
49 const ExtensionId& extension_id,
43 int listener_process_id, 50 int listener_process_id,
44 int listener_routing_id, 51 int listener_routing_id,
45 int source_ax_tree_id) { 52 int source_ax_tree_id) {
46 Register(listener_process_id, listener_routing_id, source_ax_tree_id, false); 53 Register(extension_id,
54 listener_process_id,
55 listener_routing_id,
56 source_ax_tree_id,
57 false);
47 } 58 }
48 59
49 void AutomationEventRouter::RegisterListenerWithDesktopPermission( 60 void AutomationEventRouter::RegisterListenerWithDesktopPermission(
61 const ExtensionId& extension_id,
50 int listener_process_id, 62 int listener_process_id,
51 int listener_routing_id) { 63 int listener_routing_id) {
52 Register(listener_process_id, listener_routing_id, 0, true); 64 Register(extension_id,
65 listener_process_id,
66 listener_routing_id,
67 0 /* desktop tree ID */,
68 true);
53 } 69 }
54 70
55 void AutomationEventRouter::DispatchAccessibilityEvent( 71 void AutomationEventRouter::DispatchAccessibilityEvent(
56 const ExtensionMsg_AccessibilityEventParams& params) { 72 const ExtensionMsg_AccessibilityEventParams& params) {
57 for (const auto& listener : listeners_) { 73 for (const auto& listener : listeners_) {
74 // Skip listeners that don't want to listen to this tree.
58 if (!listener.desktop && 75 if (!listener.desktop &&
59 listener.tree_ids.find(params.tree_id) == listener.tree_ids.end()) { 76 listener.tree_ids.find(params.tree_id) == listener.tree_ids.end()) {
60 continue; 77 continue;
61 } 78 }
62 79
63 content::RenderProcessHost* rph = 80 content::RenderProcessHost* rph =
64 content::RenderProcessHost::FromID(listener.process_id); 81 content::RenderProcessHost::FromID(listener.process_id);
65 rph->Send(new ExtensionMsg_AccessibilityEvent(listener.routing_id, 82 rph->Send(new ExtensionMsg_AccessibilityEvent(listener.routing_id,
66 params)); 83 params,
84 listener.is_active_profile));
67 } 85 }
68 } 86 }
69 87
70 void AutomationEventRouter::DispatchTreeDestroyedEvent( 88 void AutomationEventRouter::DispatchTreeDestroyedEvent(
71 int tree_id, 89 int tree_id,
72 content::BrowserContext* browser_context) { 90 content::BrowserContext* browser_context) {
73 scoped_ptr<base::ListValue> args( 91 scoped_ptr<base::ListValue> args(
74 api::automation_internal::OnAccessibilityTreeDestroyed::Create(tree_id)); 92 api::automation_internal::OnAccessibilityTreeDestroyed::Create(tree_id));
75 scoped_ptr<Event> event(new Event( 93 scoped_ptr<Event> event(new Event(
76 events::AUTOMATION_INTERNAL_ON_ACCESSIBILITY_TREE_DESTROYED, 94 events::AUTOMATION_INTERNAL_ON_ACCESSIBILITY_TREE_DESTROYED,
77 api::automation_internal::OnAccessibilityTreeDestroyed::kEventName, 95 api::automation_internal::OnAccessibilityTreeDestroyed::kEventName,
78 args.Pass())); 96 args.Pass()));
79 event->restrict_to_browser_context = browser_context; 97 event->restrict_to_browser_context = browser_context;
80 EventRouter::Get(browser_context)->BroadcastEvent(event.Pass()); 98 EventRouter::Get(browser_context)->BroadcastEvent(event.Pass());
81 } 99 }
82 100
83 AutomationEventRouter::AutomationListener::AutomationListener() { 101 AutomationEventRouter::AutomationListener::AutomationListener() {
84 } 102 }
85 103
86 AutomationEventRouter::AutomationListener::~AutomationListener() { 104 AutomationEventRouter::AutomationListener::~AutomationListener() {
87 } 105 }
88 106
89 void AutomationEventRouter::Register( 107 void AutomationEventRouter::Register(
108 const ExtensionId& extension_id,
90 int listener_process_id, 109 int listener_process_id,
91 int listener_routing_id, 110 int listener_routing_id,
92 int ax_tree_id, 111 int ax_tree_id,
93 bool desktop) { 112 bool desktop) {
94 auto iter = std::find_if( 113 auto iter = std::find_if(
95 listeners_.begin(), 114 listeners_.begin(),
96 listeners_.end(), 115 listeners_.end(),
97 [listener_process_id, listener_routing_id]( 116 [listener_process_id, listener_routing_id](
98 const AutomationListener& item) { 117 const AutomationListener& item) {
99 return (item.process_id == listener_process_id && 118 return (item.process_id == listener_process_id &&
100 item.routing_id == listener_routing_id); 119 item.routing_id == listener_routing_id);
101 }); 120 });
102 121
103 // Add a new entry if we don't have one with that process and routing id. 122 // Add a new entry if we don't have one with that process and routing id.
104 if (iter == listeners_.end()) { 123 if (iter == listeners_.end()) {
105 AutomationListener listener; 124 AutomationListener listener;
125 listener.extension_id = extension_id;
106 listener.routing_id = listener_routing_id; 126 listener.routing_id = listener_routing_id;
107 listener.process_id = listener_process_id; 127 listener.process_id = listener_process_id;
108 listener.desktop = desktop; 128 listener.desktop = desktop;
109 listener.tree_ids.insert(ax_tree_id); 129 listener.tree_ids.insert(ax_tree_id);
110 listeners_.push_back(listener); 130 listeners_.push_back(listener);
131 UpdateActiveProfile();
111 return; 132 return;
112 } 133 }
113 134
114 // We have an entry with that process and routing id, so update the set of 135 // 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. 136 // tree ids it wants to listen to, and update its desktop permission.
116 iter->tree_ids.insert(ax_tree_id); 137 iter->tree_ids.insert(ax_tree_id);
117 if (desktop) 138 if (desktop)
118 iter->desktop = true; 139 iter->desktop = true;
119 } 140 }
120 141
(...skipping 11 matching lines...) Expand all
132 content::Source<content::RenderProcessHost>(source).ptr(); 153 content::Source<content::RenderProcessHost>(source).ptr();
133 int process_id = rph->GetID(); 154 int process_id = rph->GetID();
134 listeners_.erase( 155 listeners_.erase(
135 std::remove_if( 156 std::remove_if(
136 listeners_.begin(), 157 listeners_.begin(),
137 listeners_.end(), 158 listeners_.end(),
138 [process_id](const AutomationListener& item) { 159 [process_id](const AutomationListener& item) {
139 return item.process_id == process_id; 160 return item.process_id == process_id;
140 }), 161 }),
141 listeners_.end()); 162 listeners_.end());
163 UpdateActiveProfile();
164 }
165
166 #if defined(OS_CHROMEOS)
167 void AutomationEventRouter::ActiveUserChanged(const std::string& user_id) {
168 active_profile_ = ProfileManager::GetLastUsedProfile();
David Tseng 2015/09/16 17:15:38 This doesn't appear to work. This observer gets ca
169 UpdateActiveProfile();
170 }
171 #endif
172
173 void AutomationEventRouter::UpdateActiveProfile() {
174 for (auto& listener : listeners_) {
175 #if defined(OS_CHROMEOS)
176 int extension_id_count = 0;
177 for (const auto& listener2 : listeners_) {
178 if (listener2.extension_id == listener.extension_id)
179 extension_id_count++;
180 }
181 content::RenderProcessHost* rph =
182 content::RenderProcessHost::FromID(listener.process_id);
183
184 // The purpose of is_active_profile is to ensure different instances of
185 // the same extension running in different profiles don't interfere with
186 // one another. If an automation extension is only running in one profile,
187 // always mark it as active. If it's running in two or more profiles,
188 // only mark one as active.
189 listener.is_active_profile = (extension_id_count == 1 ||
190 rph->GetBrowserContext() == active_profile_);
191 #else
192 listener.is_active_profile = true;
193 #endif
194 }
142 } 195 }
143 196
144 } // namespace extensions 197 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698