1 // Copyright 2014 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/ui/aura/accessibility/automation_manager_aura.h"
9 #include "base/memory/singleton.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/extensions/api/automation_internal/automation_event_router.h"
12 #include "chrome/browser/profiles/profile_manager.h"
13 #include "chrome/common/extensions/chrome_extension_messages.h"
14 #include "content/public/browser/ax_event_notification_details.h"
15 #include "content/public/browser/browser_context.h"
16 #include "ui/aura/window.h"
17 #include "ui/views/accessibility/ax_aura_obj_cache.h"
18 #include "ui/views/accessibility/ax_aura_obj_wrapper.h"
19 #include "ui/views/view.h"
20 #include "ui/views/widget/widget.h"
22 #if defined(OS_CHROMEOS)
23 #include "ash/wm/window_util.h"
26 using content::BrowserContext
;
27 using extensions::AutomationEventRouter
;
30 AutomationManagerAura
* AutomationManagerAura::GetInstance() {
31 return Singleton
<AutomationManagerAura
>::get();
34 void AutomationManagerAura::Enable(BrowserContext
* context
) {
36 if (!current_tree_
.get())
37 current_tree_
.reset(new AXTreeSourceAura());
40 SendEvent(context
, current_tree_
->GetRoot(), ui::AX_EVENT_LOAD_COMPLETE
);
42 #if defined(OS_CHROMEOS)
43 aura::Window
* active_window
= ash::wm::GetActiveWindow();
45 views::AXAuraObjWrapper
* focus
=
46 views::AXAuraObjCache::GetInstance()->GetOrCreate(active_window
);
47 SendEvent(context
, focus
, ui::AX_EVENT_CHILDREN_CHANGED
);
52 void AutomationManagerAura::Disable() {
55 // Reset the serializer to save memory.
56 current_tree_serializer_
->Reset();
59 void AutomationManagerAura::HandleEvent(BrowserContext
* context
,
61 ui::AXEvent event_type
) {
65 if (!context
&& g_browser_process
->profile_manager())
66 context
= g_browser_process
->profile_manager()->GetLastUsedProfile();
69 LOG(WARNING
) << "Accessibility notification but no browser context";
73 views::AXAuraObjWrapper
* aura_obj
=
74 views::AXAuraObjCache::GetInstance()->GetOrCreate(view
);
75 SendEvent(context
, aura_obj
, event_type
);
78 void AutomationManagerAura::HandleAlert(content::BrowserContext
* context
,
79 const std::string
& text
) {
83 views::AXAuraObjWrapper
* obj
=
84 static_cast<AXRootObjWrapper
*>(current_tree_
->GetRoot())
85 ->GetAlertForText(text
);
86 SendEvent(context
, obj
, ui::AX_EVENT_ALERT
);
89 void AutomationManagerAura::DoDefault(int32 id
) {
91 current_tree_
->DoDefault(id
);
94 void AutomationManagerAura::Focus(int32 id
) {
96 current_tree_
->Focus(id
);
99 void AutomationManagerAura::MakeVisible(int32 id
) {
101 current_tree_
->MakeVisible(id
);
104 void AutomationManagerAura::SetSelection(int32 id
, int32 start
, int32 end
) {
106 current_tree_
->SetSelection(id
, start
, end
);
109 void AutomationManagerAura::ShowContextMenu(int32 id
) {
111 current_tree_
->ShowContextMenu(id
);
114 AutomationManagerAura::AutomationManagerAura()
115 : enabled_(false), processing_events_(false) {}
117 AutomationManagerAura::~AutomationManagerAura() {
120 void AutomationManagerAura::ResetSerializer() {
121 current_tree_serializer_
.reset(
122 new AuraAXTreeSerializer(current_tree_
.get()));
125 void AutomationManagerAura::SendEvent(BrowserContext
* context
,
126 views::AXAuraObjWrapper
* aura_obj
,
127 ui::AXEvent event_type
) {
128 if (processing_events_
) {
129 pending_events_
.push_back(std::make_pair(aura_obj
, event_type
));
132 processing_events_
= true;
134 ExtensionMsg_AccessibilityEventParams params
;
135 current_tree_serializer_
->SerializeChanges(aura_obj
, ¶ms
.update
);
137 params
.id
= aura_obj
->GetID();
138 params
.event_type
= event_type
;
139 AutomationEventRouter
* router
= AutomationEventRouter::GetInstance();
140 router
->DispatchAccessibilityEvent(params
);
142 processing_events_
= false;
143 auto pending_events_copy
= pending_events_
;
144 pending_events_
.clear();
145 for (size_t i
= 0; i
< pending_events_copy
.size(); ++i
) {
147 pending_events_copy
[i
].first
,
148 pending_events_copy
[i
].second
);