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

Side by Side Diff: chrome/browser/browser_accessibility_manager.cc

Issue 4057: Adds MSAA/IAccessible exposure of web content. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 2 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2006-2008 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/browser_accessibility_manager.h"
6
7 #include "chrome/browser/browser_accessibility.h"
8 #include "chrome/browser/render_process_host.h"
9 #include "chrome/browser/render_widget_host.h"
10
11 // The time in ms after which we give up and return an error when processing an
12 // accessibility message and no response has been received from the renderer.
13 static const int kAccessibilityMessageTimeOut = 500;
14
15 // static
16 BrowserAccessibilityManager* BrowserAccessibilityManager::Instance() {
17 return Singleton<BrowserAccessibilityManager>::get();
18 }
19
20 BrowserAccessibilityManager::BrowserAccessibilityManager()
21 : instance_id_(0) {
22 NotificationService::current()->AddObserver(this,
23 NOTIFY_RENDERER_PROCESS_TERMINATED, NotificationService::AllSources());
24 }
25
26 BrowserAccessibilityManager::~BrowserAccessibilityManager() {
27 // Clear hashmaps.
28 instance_map_.clear();
29 render_process_host_map_.clear();
30
31 NotificationService::current()->RemoveObserver(this,
32 NOTIFY_RENDERER_PROCESS_TERMINATED, NotificationService::AllSources());
33 }
34
35 STDMETHODIMP BrowserAccessibilityManager::CreateAccessibilityInstance(
36 REFIID iid, int iaccessible_id, int instance_id, void** interface_ptr) {
37 if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid) {
38 CComObject<BrowserAccessibility>* instance = NULL;
39
40 HRESULT hr = CComObject<BrowserAccessibility>::CreateInstance(&instance);
41 DCHECK(SUCCEEDED(hr));
42
43 if (!instance)
44 return E_FAIL;
45
46 CComPtr<IAccessible> accessibility_instance(instance);
47
48 // Set unique ids.
49 instance->set_iaccessible_id(iaccessible_id);
50 instance->set_instance_id(instance_id);
51
52 // Retrieve the RenderWidgetHost connected to this request.
53 InstanceMap::iterator it = instance_map_.find(instance_id);
54
55 if (it != instance_map_.end()) {
56 UniqueMembers* members = it->second;
57
58 if (!members || !members->render_widget_host_)
59 return E_FAIL;
60
61 render_process_host_map_[members->render_widget_host_->process()] =
62 instance;
63 } else {
64 // No RenderProcess active for this instance.
65 return E_FAIL;
66 }
67
68 // All is well, assign the temp instance to the output pointer.
69 *interface_ptr = accessibility_instance.Detach();
70 return S_OK;
71 }
72 // No supported interface found, return error.
73 *interface_ptr = NULL;
74 return E_NOINTERFACE;
75 }
76
77 bool BrowserAccessibilityManager::RequestAccessibilityInfo(
78 int iaccessible_id, int instance_id, int iaccessible_func_id,
79 VARIANT var_id, LONG input1, LONG input2) {
80 // Create and populate input message structure.
81 ViewMsg_Accessibility_In_Params in_params;
82
83 in_params.iaccessible_id = iaccessible_id;
84 in_params.iaccessible_function_id = iaccessible_func_id;
85 in_params.input_variant_lval = var_id.lVal;
86 in_params.input_long1 = input1;
87 in_params.input_long2 = input2;
88
89 // Retrieve the RenderWidgetHost connected to this request.
90 InstanceMap::iterator it = instance_map_.find(instance_id);
91
92 if (it == instance_map_.end()) {
93 // Id not found.
94 return false;
95 }
96
97 UniqueMembers* members = it->second;
98
99 if (!members || !members->render_widget_host_)
100 return false;
101
102 IPC::SyncMessage* msg =
103 new ViewMsg_GetAccessibilityInfo(
104 members->render_widget_host_->routing_id(), in_params, &out_params_);
105
106 // Necessary for the send to keep the UI responsive.
107 msg->EnableMessagePumping();
108 bool success = members->render_widget_host_->process()->channel()->
109 SendWithTimeout(msg, kAccessibilityMessageTimeOut);
110
111 return success;
112 }
113
114 ViewHostMsg_Accessibility_Out_Params BrowserAccessibilityManager::response() {
115 return out_params_;
116 }
117
118 HWND BrowserAccessibilityManager::parent_hwnd(int id) {
119 // Retrieve the parent HWND connected to the requester's id.
120 InstanceMap::iterator it = instance_map_.find(id);
121
122 if (it == instance_map_.end()) {
123 // Id not found.
124 return NULL;
125 }
126
127 UniqueMembers* members = it->second;
128
129 if (!members || !members->parent_hwnd_)
130 return NULL;
131
132 return members->parent_hwnd_;
133 }
134
135 int BrowserAccessibilityManager::SetMembers(BrowserAccessibility* browser_acc,
136 HWND parent_hwnd, RenderWidgetHost* render_widget_host) {
137 // Set HWND and RenderWidgetHost connected to |browser_acc|.
138 instance_map_[instance_id_] =
139 new UniqueMembers(parent_hwnd, render_widget_host);
140
141 render_process_host_map_[render_widget_host->process()] = browser_acc;
142 return instance_id_++;
143 }
144
145 void BrowserAccessibilityManager::Observe(NotificationType type,
146 const NotificationSource& source,
147 const NotificationDetails& details) {
148 DCHECK(type == NOTIFY_RENDERER_PROCESS_TERMINATED);
149 RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr();
150 DCHECK(rph);
151 RenderProcessHostMap::iterator it = render_process_host_map_.find(rph);
152
153 if (it == render_process_host_map_.end() || !it->second) {
154 // RenderProcessHost not associated with any BrowserAccessibility instance.
155 return;
156 }
157
158 // Set BrowserAccessibility instance to inactive state.
159 it->second->set_instance_active(false);
160 render_process_host_map_.erase(it);
161
162 // Delete entry also from InstanceMap.
163 InstanceMap::iterator it2 = instance_map_.find(it->second->instance_id());
164
165 if (it2 != instance_map_.end())
166 instance_map_.erase(it2);
167 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698