summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorklink@chromium.org <klink@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-20 00:53:06 +0000
committerklink@chromium.org <klink@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-20 00:53:06 +0000
commite846d0dba2bf9506a929c9e16294997e37014039 (patch)
tree5ac70d2216fd450b3d4f164a26f752504c8cb220
parentfabd89f6aa700cb0e59b04e92ce54e729cbd0c66 (diff)
downloadchromium_src-e846d0dba2bf9506a929c9e16294997e37014039.zip
chromium_src-e846d0dba2bf9506a929c9e16294997e37014039.tar.gz
chromium_src-e846d0dba2bf9506a929c9e16294997e37014039.tar.bz2
Adds propagation and handling of render-side focus events, for the benefit of assistive technologies (accessibility). Also cleans up the handling of WM_GETOBJECT in RenderWidgetHostViewWin and WidgetWin, as well as in BrowserAccessibilityManager.
Review URL: http://codereview.chromium.org/115374 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16449 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/browser_accessibility.cc83
-rw-r--r--chrome/browser/browser_accessibility.h50
-rw-r--r--chrome/browser/browser_accessibility_manager.cc152
-rw-r--r--chrome/browser/browser_accessibility_manager.h78
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc16
-rw-r--r--chrome/browser/renderer_host/render_view_host.h1
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_win.cc41
-rw-r--r--chrome/common/render_messages.h4
-rw-r--r--chrome/common/render_messages_internal.h9
-rw-r--r--chrome/renderer/render_view.cc26
-rw-r--r--chrome/renderer/render_view.h2
-rw-r--r--views/widget/widget_win.cc4
-rw-r--r--webkit/glue/chrome_client_impl.cc33
-rw-r--r--webkit/glue/chrome_client_impl.h5
-rw-r--r--webkit/glue/glue_accessibility_object.cc2
-rw-r--r--webkit/glue/glue_accessibility_object.h3
-rw-r--r--webkit/glue/webaccessibility.h4
-rw-r--r--webkit/glue/webaccessibilitymanager.h11
-rw-r--r--webkit/glue/webaccessibilitymanager_impl.cc79
-rw-r--r--webkit/glue/webaccessibilitymanager_impl.h26
-rw-r--r--webkit/glue/webview_delegate.h11
-rw-r--r--webkit/glue/webview_impl.h6
22 files changed, 380 insertions, 266 deletions
diff --git a/chrome/browser/browser_accessibility.cc b/chrome/browser/browser_accessibility.cc
index af56972..9fade8d 100644
--- a/chrome/browser/browser_accessibility.cc
+++ b/chrome/browser/browser_accessibility.cc
@@ -9,15 +9,29 @@
using webkit_glue::WebAccessibility;
-BrowserAccessibility::BrowserAccessibility()
- : iaccessible_id_(-1),
- instance_active_(true) {
+HRESULT BrowserAccessibility::Initialize(int iaccessible_id, int routing_id,
+ int process_id, HWND parent_hwnd) {
+ if (!parent_hwnd || iaccessible_id < 0)
+ return E_INVALIDARG;
+
+ iaccessible_id_ = iaccessible_id;
+ routing_id_ = routing_id;
+ process_id_ = process_id;
+ parent_hwnd_ = parent_hwnd;
+
+ // Mark instance as active.
+ instance_active_ = true;
+
+ // Treat child ids intitially as referring to direct children of the object.
+ direct_descendant_ = true;
+
+ return S_OK;
}
HRESULT BrowserAccessibility::accDoDefaultAction(VARIANT var_id) {
if (!instance_active()) {
// Instance no longer active, fail gracefully.
- // TODO(klink): Once we have MSAA events, change these fails for having
+ // TODO(klink): Once we have MSAA events, change these fails to having
// BrowserAccessibilityManager firing the right event.
return E_FAIL;
}
@@ -46,7 +60,7 @@ STDMETHODIMP BrowserAccessibility::accHitTest(LONG x_left, LONG y_top,
if (!child)
return E_INVALIDARG;
- if (!parent_hwnd()) {
+ if (!parent_hwnd_) {
// Parent HWND needed for coordinate conversion.
return E_FAIL;
}
@@ -54,7 +68,7 @@ STDMETHODIMP BrowserAccessibility::accHitTest(LONG x_left, LONG y_top,
// Convert coordinates to test from screen into client window coordinates, to
// maintain sandbox functionality on renderer side.
POINT p = {x_left, y_top};
- ::ScreenToClient(parent_hwnd(), &p);
+ ::ScreenToClient(parent_hwnd_, &p);
if (!RequestAccessibilityInfo(WebAccessibility::FUNCTION_HITTEST,
EmptyVariant(), p.x, p.y)) {
@@ -93,7 +107,7 @@ STDMETHODIMP BrowserAccessibility::accLocation(LONG* x_left, LONG* y_top,
}
if (var_id.vt != VT_I4 || !x_left || !y_top || !width || !height ||
- !parent_hwnd()) {
+ !parent_hwnd_) {
return E_INVALIDARG;
}
@@ -106,7 +120,7 @@ STDMETHODIMP BrowserAccessibility::accLocation(LONG* x_left, LONG* y_top,
// Find the top left corner of the containing window in screen coords, and
// adjust the output position by this amount.
- ::ClientToScreen(parent_hwnd(), &top_left);
+ ::ClientToScreen(parent_hwnd_, &top_left);
*x_left = response().output_long1 + top_left.x;
*y_top = response().output_long2 + top_left.y;
@@ -393,15 +407,15 @@ STDMETHODIMP BrowserAccessibility::get_accParent(IDispatch** disp_parent) {
return E_FAIL;
}
- if (!disp_parent || !parent_hwnd())
+ if (!disp_parent || !parent_hwnd_)
return E_INVALIDARG;
// Root node's parent is the containing HWND's IAccessible.
- if (iaccessible_id() == 0) {
+ if (iaccessible_id_ == 0) {
// For an object that has no parent (e.g. root), point the accessible parent
// to the default implementation.
HRESULT hr =
- ::CreateStdAccessibleObject(parent_hwnd(), OBJID_WINDOW,
+ ::CreateStdAccessibleObject(parent_hwnd_, OBJID_WINDOW,
IID_IAccessible,
reinterpret_cast<void**>(disp_parent));
@@ -498,20 +512,15 @@ STDMETHODIMP BrowserAccessibility::get_accValue(VARIANT var_id, BSTR* value) {
return S_OK;
}
-STDMETHODIMP BrowserAccessibility::accSelect(LONG flags_select,
- VARIANT var_id) {
- return E_NOTIMPL;
-}
-
STDMETHODIMP BrowserAccessibility::get_accHelpTopic(BSTR* help_file,
VARIANT var_id,
LONG* topic_id) {
- if (help_file) {
+ if (help_file)
*help_file = NULL;
- }
- if (topic_id) {
+
+ if (topic_id)
*topic_id = static_cast<LONG>(-1);
- }
+
return E_NOTIMPL;
}
@@ -522,38 +531,38 @@ STDMETHODIMP BrowserAccessibility::get_accSelection(VARIANT* selected) {
return E_NOTIMPL;
}
-STDMETHODIMP BrowserAccessibility::put_accName(VARIANT var_id, BSTR put_name) {
- return E_NOTIMPL;
-}
-
-STDMETHODIMP BrowserAccessibility::put_accValue(VARIANT var_id, BSTR put_val) {
- return E_NOTIMPL;
-}
-
STDMETHODIMP BrowserAccessibility::CreateInstance(REFIID iid,
int iaccessible_id,
void** interface_ptr) {
return BrowserAccessibilityManager::GetInstance()->
- CreateAccessibilityInstance(iid, iaccessible_id, instance_id(),
- interface_ptr);
+ CreateAccessibilityInstance(iid, iaccessible_id, routing_id_,
+ process_id_, parent_hwnd_, interface_ptr);
}
bool BrowserAccessibility::RequestAccessibilityInfo(int iaccessible_func_id,
VARIANT var_id, LONG input1,
LONG input2) {
- return BrowserAccessibilityManager::GetInstance()->RequestAccessibilityInfo(
- iaccessible_id(), instance_id(), iaccessible_func_id, var_id.lVal, input1,
- input2);
+ // Create and populate IPC message structure, for retrieval of accessibility
+ // information from the renderer.
+ WebAccessibility::InParams in_params;
+ in_params.object_id = iaccessible_id_;
+ in_params.function_id = iaccessible_func_id;
+ in_params.child_id = var_id.lVal;
+ in_params.direct_descendant = direct_descendant();
+ in_params.input_long1 = input1;
+ in_params.input_long2 = input2;
+
+ if (!direct_descendant())
+ set_direct_descendant(true);
+
+ return BrowserAccessibilityManager::GetInstance()->
+ RequestAccessibilityInfo(&in_params, routing_id_, process_id_);
}
const WebAccessibility::OutParams& BrowserAccessibility::response() {
return BrowserAccessibilityManager::GetInstance()->response();
}
-HWND BrowserAccessibility::parent_hwnd() {
- return BrowserAccessibilityManager::GetInstance()->parent_hwnd(instance_id());
-}
-
long BrowserAccessibility::MSAARole(long browser_accessibility_role) {
switch (browser_accessibility_role) {
case WebAccessibility::ROLE_PUSHBUTTON :
diff --git a/chrome/browser/browser_accessibility.h b/chrome/browser/browser_accessibility.h
index 8b56662..c8d4187 100644
--- a/chrome/browser/browser_accessibility.h
+++ b/chrome/browser/browser_accessibility.h
@@ -10,7 +10,6 @@
#include <oleacc.h>
-#include "base/basictypes.h"
#include "webkit/glue/webaccessibility.h"
using webkit_glue::WebAccessibility;
@@ -33,9 +32,14 @@ class ATL_NO_VTABLE BrowserAccessibility
COM_INTERFACE_ENTRY(IAccessible)
END_COM_MAP()
- BrowserAccessibility();
+ BrowserAccessibility() {}
~BrowserAccessibility() {}
+ HRESULT Initialize(int iaccessible_id,
+ int routing_id,
+ int process_id,
+ HWND parent_hwnd);
+
// Supported IAccessible methods.
// Performs the default action on a given object.
@@ -91,7 +95,7 @@ class ATL_NO_VTABLE BrowserAccessibility
STDMETHODIMP get_accValue(VARIANT var_id, BSTR* value);
// Non-supported (by WebKit) IAccessible methods.
- STDMETHODIMP accSelect(LONG flags_sel, VARIANT var_id);
+ STDMETHODIMP accSelect(LONG flags_sel, VARIANT var_id) { return E_NOTIMPL; }
STDMETHODIMP get_accHelpTopic(BSTR* help_file,
VARIANT var_id,
@@ -100,20 +104,11 @@ class ATL_NO_VTABLE BrowserAccessibility
STDMETHODIMP get_accSelection(VARIANT* selected);
// Deprecated functions, not implemented here.
- STDMETHODIMP put_accName(VARIANT var_id, BSTR put_name);
- STDMETHODIMP put_accValue(VARIANT var_id, BSTR put_val);
-
- // Modify/retrieve the unique id of this IAccessible instance.
- void set_iaccessible_id(int iaccessible_id) {
- iaccessible_id_ = iaccessible_id;
- }
- int iaccessible_id() const { return iaccessible_id_; }
+ STDMETHODIMP put_accName(VARIANT var_id, BSTR put_name) { return E_NOTIMPL; }
+ STDMETHODIMP put_accValue(VARIANT var_id, BSTR put_val) { return E_NOTIMPL; }
- // Modify/retrieve the unique id of this IAccessible's routing variables.
- void set_instance_id(int instance_id) {
- instance_id_ = instance_id;
- }
- int instance_id() const { return instance_id_; }
+ // Accessors/mutators.
+ HWND parent_hwnd() const { return parent_hwnd_;}
// Modify/retrieve the state (active/inactive) of this instance.
void set_instance_active(bool instance_active) {
@@ -121,6 +116,13 @@ class ATL_NO_VTABLE BrowserAccessibility
}
int instance_active() const { return instance_active_; }
+ void set_direct_descendant(bool direct_descendant) {
+ direct_descendant_ = direct_descendant;
+ }
+ bool direct_descendant() const { return direct_descendant_; }
+
+ int routing_id() const { return routing_id_; }
+
private:
// Creates an empty VARIANT. Used as the equivalent of a NULL (unused) input
// parameter.
@@ -148,7 +150,6 @@ class ATL_NO_VTABLE BrowserAccessibility
// Accessors.
const WebAccessibility::OutParams& response();
- HWND parent_hwnd();
// Returns a conversion from the BrowserAccessibilityRole (as defined in
// webkit/glue/webaccessibility.h) to an MSAA role.
@@ -162,10 +163,21 @@ class ATL_NO_VTABLE BrowserAccessibility
// mapping it to the correct IAccessible on that side. Initialized to -1.
int iaccessible_id_;
- // The unique id of this IAccessible instance. Used to help
+ // The unique ids of this IAccessible instance. Used to help
// BrowserAccessibilityManager instance retrieve the correct member
// variables for this process.
- int instance_id_;
+ int routing_id_;
+ int process_id_;
+
+ HWND parent_hwnd_;
+
+ // Indicates if an incoming request for child information relates to a child
+ // id of a direct child of the BrowserAccessibility object, or if it refers
+ // to an object elsewhere in the MSAA tree. Set by BrowserAccessibilityManager
+ // and applicable only to the root BrowserAccessibility object (id 0). Needed
+ // to properly handled MSAA focus events, where the child id is the only
+ // parameter in our control.
+ bool direct_descendant_;
// The instance should only be active if there is a non-terminated
// RenderProcessHost associated with it. The BrowserAccessibilityManager keeps
diff --git a/chrome/browser/browser_accessibility_manager.cc b/chrome/browser/browser_accessibility_manager.cc
index e97e0e4..0930024 100644
--- a/chrome/browser/browser_accessibility_manager.cc
+++ b/chrome/browser/browser_accessibility_manager.cc
@@ -6,7 +6,7 @@
#include "chrome/browser/browser_accessibility.h"
#include "chrome/browser/renderer_host/render_process_host.h"
-#include "chrome/browser/renderer_host/render_widget_host.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/render_messages.h"
@@ -21,16 +21,14 @@ BrowserAccessibilityManager* BrowserAccessibilityManager::GetInstance() {
return Singleton<BrowserAccessibilityManager>::get();
}
-BrowserAccessibilityManager::BrowserAccessibilityManager()
- : instance_id_(0) {
+BrowserAccessibilityManager::BrowserAccessibilityManager() {
NotificationService::current()->AddObserver(this,
NotificationType::RENDERER_PROCESS_TERMINATED,
NotificationService::AllSources());
}
BrowserAccessibilityManager::~BrowserAccessibilityManager() {
- // Clear hashmaps.
- instance_map_.clear();
+ // Clear hashmap.
render_process_host_map_.clear();
// We don't remove ourselves as an observer because we are a Singleton object,
@@ -38,7 +36,8 @@ BrowserAccessibilityManager::~BrowserAccessibilityManager() {
}
STDMETHODIMP BrowserAccessibilityManager::CreateAccessibilityInstance(
- REFIID iid, int acc_obj_id, int instance_id, void** interface_ptr) {
+ REFIID iid, int acc_obj_id, int routing_id, int process_id,
+ HWND parent_hwnd, void** interface_ptr) {
if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid) {
CComObject<BrowserAccessibility>* instance = NULL;
@@ -50,21 +49,16 @@ STDMETHODIMP BrowserAccessibilityManager::CreateAccessibilityInstance(
CComPtr<IAccessible> accessibility_instance(instance);
- // Set unique ids.
- instance->set_iaccessible_id(acc_obj_id);
- instance->set_instance_id(instance_id);
+ // Set class member variables.
+ instance->Initialize(acc_obj_id, routing_id, process_id, parent_hwnd);
- // Retrieve the RenderWidgetHost connected to this request.
- InstanceMap::iterator it = instance_map_.find(instance_id);
+ // Retrieve the RenderViewHost connected to this request.
+ RenderViewHost* rvh = RenderViewHost::FromID(process_id, routing_id);
- if (it != instance_map_.end()) {
- UniqueMembers* members = it->second;
-
- if (!members || !members->render_widget_host_)
- return E_FAIL;
-
- render_process_host_map_[members->render_widget_host_->process()] =
- instance;
+ // Update cache with RenderProcessHost/BrowserAccessibility pair.
+ if (rvh && rvh->process()) {
+ render_process_host_map_.insert(
+ MapEntry(rvh->process()->pid(), instance));
} else {
// No RenderProcess active for this instance.
return E_FAIL;
@@ -80,73 +74,71 @@ STDMETHODIMP BrowserAccessibilityManager::CreateAccessibilityInstance(
}
bool BrowserAccessibilityManager::RequestAccessibilityInfo(
- int acc_obj_id, int instance_id, int acc_func_id, int child_id, long input1,
- long input2) {
+ WebAccessibility::InParams* in, int routing_id, int process_id) {
// Create and populate IPC message structure, for retrieval of accessibility
// information from the renderer.
WebAccessibility::InParams in_params;
- in_params.object_id = acc_obj_id;
- in_params.function_id = acc_func_id;
- in_params.child_id = child_id;
- in_params.input_long1 = input1;
- in_params.input_long2 = input2;
-
- // Retrieve the RenderWidgetHost connected to this request.
- InstanceMap::iterator it = instance_map_.find(instance_id);
-
- if (it == instance_map_.end()) {
- // Id not found.
- return false;
- }
+ in_params.object_id = in->object_id;
+ in_params.function_id = in->function_id;
+ in_params.child_id = in->child_id;
+ in_params.direct_descendant = in->direct_descendant;
+ in_params.input_long1 = in->input_long1;
+ in_params.input_long2 = in->input_long2;
- UniqueMembers* members = it->second;
-
- if (!members || !members->render_widget_host_)
- return false;
+ // Retrieve the RenderViewHost connected to this request.
+ RenderViewHost* rvh = RenderViewHost::FromID(process_id, routing_id);
+ // Send accessibility information retrieval message to the renderer.
bool success = false;
- if (members->render_widget_host_->process() &&
- members->render_widget_host_->process()->channel()) {
+ if (rvh && rvh->process() && rvh->process()->channel()) {
IPC::SyncMessage* msg =
- new ViewMsg_GetAccessibilityInfo(members->render_widget_host_->
- routing_id(), in_params, &out_params_);
+ new ViewMsg_GetAccessibilityInfo(routing_id, in_params, &out_params_);
// Necessary for the send to keep the UI responsive.
msg->EnableMessagePumping();
- success = members->render_widget_host_->process()->channel()->
- SendWithTimeout(msg, kAccessibilityMessageTimeOut);
+ success = rvh->process()->channel()->SendWithTimeout(msg,
+ kAccessibilityMessageTimeOut);
}
return success;
}
+bool BrowserAccessibilityManager::ChangeAccessibilityFocus(int acc_obj_id,
+ int process_id,
+ int routing_id) {
+ BrowserAccessibility* browser_acc =
+ GetBrowserAccessibility(process_id, routing_id);
+ if (browser_acc) {
+ // Indicate that the request for child information is referring to a non-
+ // direct descendant of the root.
+ browser_acc->set_direct_descendant(false);
+
+ // Notify Access Technology that there was a change in keyboard focus.
+ ::NotifyWinEvent(EVENT_OBJECT_FOCUS, browser_acc->parent_hwnd(),
+ OBJID_CLIENT, static_cast<LONG>(acc_obj_id));
+ return true;
+ }
+ return false;
+}
+
const WebAccessibility::OutParams& BrowserAccessibilityManager::response() {
return out_params_;
}
-HWND BrowserAccessibilityManager::parent_hwnd(int id) {
- // Retrieve the parent HWND connected to the requester's id.
- InstanceMap::iterator it = instance_map_.find(id);
-
- if (it == instance_map_.end()) {
- // Id not found.
- return NULL;
- }
-
- UniqueMembers* members = it->second;
+BrowserAccessibility* BrowserAccessibilityManager::GetBrowserAccessibility(
+ int process_id, int routing_id) {
+ // Retrieve the BrowserAccessibility connected to the requester's id. There
+ // could be multiple BrowserAccessibility connected to the given |process_id|,
+ // but they all have the same parent HWND, so using the first hit is fine.
+ RenderProcessHostMap::iterator it =
+ render_process_host_map_.lower_bound(process_id);
- if (!members || !members->parent_hwnd_)
- return NULL;
+ RenderProcessHostMap::iterator end_of_matching_objects =
+ render_process_host_map_.upper_bound(process_id);
- return members->parent_hwnd_;
-}
-
-int BrowserAccessibilityManager::SetMembers(BrowserAccessibility* browser_acc,
- HWND parent_hwnd, RenderWidgetHost* render_widget_host) {
- // Set HWND and RenderWidgetHost connected to |browser_acc|.
- instance_map_[instance_id_] =
- new UniqueMembers(parent_hwnd, render_widget_host);
-
- render_process_host_map_[render_widget_host->process()] = browser_acc;
- return instance_id_++;
+ for (; it != end_of_matching_objects; ++it) {
+ if (it->second && it->second->routing_id() == routing_id)
+ return it->second;
+ }
+ return NULL;
}
void BrowserAccessibilityManager::Observe(NotificationType type,
@@ -155,22 +147,18 @@ void BrowserAccessibilityManager::Observe(NotificationType type,
DCHECK(type == NotificationType::RENDERER_PROCESS_TERMINATED);
RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr();
DCHECK(rph);
- RenderProcessHostMap::iterator it = render_process_host_map_.find(rph);
- if (it == render_process_host_map_.end() || !it->second) {
- // RenderProcessHost not associated with any BrowserAccessibility instance.
- return;
- }
+ RenderProcessHostMap::iterator it =
+ render_process_host_map_.lower_bound(rph->pid());
- // Set BrowserAccessibility instance to inactive state.
- it->second->set_instance_active(false);
+ RenderProcessHostMap::iterator end_of_matching_objects =
+ render_process_host_map_.upper_bound(rph->pid());
- // Delete entry also from InstanceMap.
- InstanceMap::iterator it2 = instance_map_.find(it->second->instance_id());
-
- if (it2 != instance_map_.end())
- instance_map_.erase(it2);
-
- // Only delete the first entry once it is no longer in use.
- render_process_host_map_.erase(it);
+ for (; it != end_of_matching_objects; ++it) {
+ if (it->second) {
+ // Set all matching BrowserAccessibility instances to inactive state.
+ // TODO(klink): Do more active memory cleanup as well.
+ it->second->set_instance_active(false);
+ }
+ }
}
diff --git a/chrome/browser/browser_accessibility_manager.h b/chrome/browser/browser_accessibility_manager.h
index defcb9e..081f978 100644
--- a/chrome/browser/browser_accessibility_manager.h
+++ b/chrome/browser/browser_accessibility_manager.h
@@ -5,8 +5,7 @@
#ifndef CHROME_BROWSER_BROWSER_ACCESSIBILITY_MANAGER_H_
#define CHROME_BROWSER_BROWSER_ACCESSIBILITY_MANAGER_H_
-#include <oaidl.h> // Needed for VARIANT structure.
-#include <hash_map>
+#include <map>
#include "base/singleton.h"
#include "chrome/common/notification_observer.h"
@@ -16,6 +15,8 @@ class BrowserAccessibility;
class RenderProcessHost;
class RenderWidgetHost;
+using webkit_glue::WebAccessibility;
+
////////////////////////////////////////////////////////////////////////////////
//
// BrowserAccessibilityManager
@@ -35,35 +36,28 @@ class BrowserAccessibilityManager : public NotificationObserver {
static BrowserAccessibilityManager* GetInstance();
// Creates an instance of BrowserAccessibility, initializes it and sets the
- // [acc_obj_id], which is used for IPC communication, and [instance_id],
+ // |acc_obj_id|, which is used for IPC communication, and |instance_id|,
// which is used to identify the mapping between accessibility instance and
// RenderProcess.
STDMETHODIMP CreateAccessibilityInstance(REFIID iid,
int acc_obj_id,
- int instance_id,
+ int routing_id,
+ int process_id,
+ HWND parent_hwnd,
void** interface_ptr);
// Composes and sends a message for requesting needed accessibility
- // information. Unused LONG input parameters should be NULL, and the VARIANT
- // [var_id] an empty, valid instance.
- bool RequestAccessibilityInfo(int acc_obj_id,
- int instance_id,
- int acc_func_id,
- int child_id,
- long input1,
- long input2);
-
- // Wrapper function, for cleaner code.
- const webkit_glue::WebAccessibility::OutParams& response();
+ // information.
+ bool RequestAccessibilityInfo(WebAccessibility::InParams* in,
+ int routing_id,
+ int process_id);
- // Retrieves the parent HWND connected to the provided id.
- HWND parent_hwnd(int id);
+ // Notifies assistive technology that renderer focus changed, through the
+ // platform-specific channels.
+ bool ChangeAccessibilityFocus(int acc_obj_id, int process_id, int routing_id);
- // Mutator, needed since constructor does not take any arguments, and to keep
- // instance accessor clean.
- int SetMembers(BrowserAccessibility* browser_acc,
- HWND parent_hwnd,
- RenderWidgetHost* render_widget_host);
+ // Wrapper function, for cleaner code.
+ const WebAccessibility::OutParams& response();
// NotificationObserver implementation.
virtual void Observe(NotificationType type,
@@ -78,32 +72,24 @@ class BrowserAccessibilityManager : public NotificationObserver {
~BrowserAccessibilityManager();
private:
- // Member variable structure, used in instance hashmap.
- struct UniqueMembers {
- RenderWidgetHost* render_widget_host_;
- HWND parent_hwnd_;
-
- UniqueMembers(HWND parent_hwnd, RenderWidgetHost* render_widget_host)
- : parent_hwnd_(parent_hwnd),
- render_widget_host_(render_widget_host) {
- }
- };
-
- typedef stdext::hash_map<int, UniqueMembers*> InstanceMap;
- typedef stdext::hash_map<RenderProcessHost*, BrowserAccessibility*>
- RenderProcessHostMap;
-
- // Caching of the unique member variables used to handle browser accessibility
- // requests from multiple processes.
- InstanceMap instance_map_;
- int instance_id_;
-
- // Reverse mapping to track which RenderProcessHosts are active. If a
- // RenderProcessHost is found to be terminated, it should be removed from this
- // mapping, and the connected BrowserAccessibility ids/instances invalidated.
+ // Retrieves the BrowserAccessibility instance connected to the
+ // RenderProcessHost identified by the process/routing id pair.
+ BrowserAccessibility* GetBrowserAccessibility(int process_id, int routing_id);
+
+ // Multi-map from process id (key) to active BrowserAccessibility instances
+ // for that RenderProcessHost.
+ typedef std::multimap<int, BrowserAccessibility*> RenderProcessHostMap;
+ typedef std::pair<int, BrowserAccessibility*> MapEntry;
+
+ // Mapping to track which RenderProcessHosts ids are active. If a
+ // RenderProcessHost is found to be terminated, its id (key) should be removed
+ // from this mapping, and the connected BrowserAccessibility ids/instances
+ // invalidated.
RenderProcessHostMap render_process_host_map_;
- webkit_glue::WebAccessibility::OutParams out_params_;
+ // Structure passed by reference to hold response parameters from the
+ // renderer.
+ WebAccessibility::OutParams out_params_;
DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManager);
};
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index 792b6ee..44c0023 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -41,6 +41,11 @@
#include "webkit/api/public/WebFindOptions.h"
#include "webkit/glue/autofill_form.h"
+#if defined(OS_WIN)
+// TODO(port): accessibility not yet implemented. See http://crbug.com/8288.
+#include "chrome/browser/browser_accessibility_manager.h"
+#endif
+
using base::TimeDelta;
using WebKit::WebConsoleMessage;
using WebKit::WebFindOptions;
@@ -800,6 +805,8 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) {
OnMsgPasteFromSelectionClipboard)
IPC_MESSAGE_HANDLER(ViewHostMsg_ExtensionPostMessage,
OnExtensionPostMessage)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_AccessibilityFocusChange,
+ OnAccessibilityFocusChange)
// Have the super handle all other messages.
IPC_MESSAGE_UNHANDLED(RenderWidgetHost::OnMessageReceived(msg))
IPC_END_MESSAGE_MAP_EX()
@@ -1432,3 +1439,12 @@ void RenderViewHost::OnExtensionPostMessage(
ExtensionMessageService::GetInstance(context)->
PostMessageFromRenderer(port_id, message);
}
+
+void RenderViewHost::OnAccessibilityFocusChange(int acc_obj_id) {
+#if defined(OS_WIN)
+ BrowserAccessibilityManager::GetInstance()->
+ ChangeAccessibilityFocus(acc_obj_id, process()->pid(), routing_id());
+#else
+ // TODO(port): accessibility not yet implemented. See http://crbug.com/8288.
+#endif
+}
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index 5c20c12..9c08f11 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -555,6 +555,7 @@ class RenderViewHost : public RenderWidgetHost {
void OnExtensionRequest(const std::string& name, const std::string& args,
int request_id, bool has_callback);
void OnExtensionPostMessage(int port_id, const std::string& message);
+ void OnAccessibilityFocusChange(int acc_obj_id);
// Helper function to send a navigation message. If a cross-site request is
// in progress, we may be suspended while waiting for the onbeforeunload
diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc
index 82d95f1c..22f50f7 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_win.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc
@@ -13,7 +13,6 @@
#include "base/gfx/rect.h"
#include "base/histogram.h"
#include "base/win_util.h"
-#include "chrome/browser/browser_accessibility.h"
#include "chrome/browser/browser_accessibility_manager.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_trial.h"
@@ -685,7 +684,7 @@ void RenderWidgetHostViewWin::OnDestroy() {
TrackMouseLeave(false);
#ifdef ENABLE_TRACK_HWND_DESTRUCTION
TRACK_HWND_DESTRUCTION(m_hWnd);
-#endif // ENABLE_TRACK_HWND_DESTRUCTION
+#endif // ENABLE_TRACK_HWND_DESTRUCTION
}
void RenderWidgetHostViewWin::OnPaint(HDC dc) {
@@ -1194,41 +1193,23 @@ LRESULT RenderWidgetHostViewWin::OnGetObject(UINT message, WPARAM wparam,
// If our MSAA DOM root is already created, reuse that pointer. Otherwise,
// create a new one.
if (!browser_accessibility_root_) {
- CComObject<BrowserAccessibility>* accessibility = NULL;
-
- if (!SUCCEEDED(CComObject<BrowserAccessibility>::CreateInstance(
- &accessibility)) || !accessibility) {
- // Return with failure.
- return static_cast<LRESULT>(0L);
- }
-
- CComPtr<IAccessible> accessibility_comptr(accessibility);
-
- // Root id is always 0, to distinguish this particular instance when
- // mapping to the render-side IAccessible.
- accessibility->set_iaccessible_id(0);
-
- // Set the unique member variables of this particular process.
- accessibility->set_instance_id(
- BrowserAccessibilityManager::GetInstance()->
- SetMembers(accessibility, m_hWnd, render_widget_host_));
-
- // All is well, assign the temp instance to the class smart pointer.
- browser_accessibility_root_.Attach(accessibility_comptr.Detach());
+ // Create a new instance of IAccessible. Root id is always 0.
+ BrowserAccessibilityManager::GetInstance()->
+ CreateAccessibilityInstance(IID_IAccessible, 0,
+ render_widget_host_->routing_id(),
+ render_widget_host_->process()->pid(),
+ m_hWnd, reinterpret_cast<void **>
+ (&browser_accessibility_root_));
if (!browser_accessibility_root_) {
- // Paranoia check. Return with failure.
+ // No valid root found, return with failure.
NOTREACHED();
return static_cast<LRESULT>(0L);
}
-
- // Notify that an instance of IAccessible was allocated for m_hWnd.
- ::NotifyWinEvent(EVENT_OBJECT_CREATE, m_hWnd, OBJID_CLIENT,
- CHILDID_SELF);
}
- // Create a reference to ViewAccessibility that MSAA will marshall
- // to the client.
+ // Create a reference to BrowserAccessibility which MSAA will marshall to
+ // the client.
reference_result = LresultFromObject(IID_IAccessible, wparam,
static_cast<IAccessible*>(browser_accessibility_root_));
}
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index 2908480..e3028a2 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -509,6 +509,7 @@ struct ParamTraits<webkit_glue::WebAccessibility::InParams> {
WriteParam(m, p.object_id);
WriteParam(m, p.function_id);
WriteParam(m, p.child_id);
+ WriteParam(m, p.direct_descendant);
WriteParam(m, p.input_long1);
WriteParam(m, p.input_long2);
}
@@ -517,6 +518,7 @@ struct ParamTraits<webkit_glue::WebAccessibility::InParams> {
ReadParam(m, iter, &p->object_id) &&
ReadParam(m, iter, &p->function_id) &&
ReadParam(m, iter, &p->child_id) &&
+ ReadParam(m, iter, &p->direct_descendant) &&
ReadParam(m, iter, &p->input_long1) &&
ReadParam(m, iter, &p->input_long2);
}
@@ -528,6 +530,8 @@ struct ParamTraits<webkit_glue::WebAccessibility::InParams> {
l->append(L", ");
LogParam(p.child_id, l);
l->append(L", ");
+ LogParam(p.direct_descendant, l);
+ l->append(L", ");
LogParam(p.input_long1, l);
l->append(L", ");
LogParam(p.input_long2, l);
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 4cf50d1..f359677 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -406,7 +406,7 @@ IPC_BEGIN_MESSAGES(View)
// id to clear a specific hashmap entry, and a bool; true clears all, false
// does not.
IPC_MESSAGE_ROUTED2(ViewMsg_ClearAccessibilityInfo,
- int /* iaccessible_id */,
+ int /* accessibility object id */,
bool /* clear_all */)
// Get all savable resource links from current webpage, include main
@@ -1381,6 +1381,13 @@ IPC_BEGIN_MESSAGES(ViewHost)
IPC_MESSAGE_ROUTED1(ViewHostMsg_ShowPopup,
ViewHostMsg_ShowPopup_Params)
+ // Sent as a result of a focus change in the renderer (if accessibility is
+ // enabled), to notify the browser side that its accessibility focus needs to
+ // change as well. Takes the id of the accessibility object that now has
+ // focus.
+ IPC_MESSAGE_ROUTED1(ViewHostMsg_AccessibilityFocusChange,
+ int /* accessibility object id */)
+
//---------------------------------------------------------------------------
// Utility process host messages:
// These are messages from the utility process to the browser. They're here
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index dc7e284..8a311af 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -91,7 +91,6 @@
using base::Time;
using base::TimeDelta;
-using webkit_glue::WebAccessibility;
using WebKit::WebConsoleMessage;
using WebKit::WebDragData;
using WebKit::WebRect;
@@ -2048,7 +2047,6 @@ void RenderView::DidDownloadImage(int id,
void RenderView::OnDownloadImage(int id,
const GURL& image_url,
int image_size) {
-
bool data_image_failed = false;
if (image_url.SchemeIs("data")) {
SkBitmap data_image = ImageFromDataUrl(image_url);
@@ -2765,8 +2763,10 @@ void RenderView::OnClearAccessibilityInfo(int acc_obj_id, bool clear_all) {
// If accessibility is not activated, ignore clearing message.
return;
}
+
if (!web_accessibility_manager_->ClearAccObjMap(acc_obj_id, clear_all))
return;
+
#else // defined(OS_WIN)
// TODO(port): accessibility not yet implemented
NOTIMPLEMENTED();
@@ -3024,3 +3024,25 @@ void RenderView::DumpLoadHistograms() const {
"Renderer.All.StartToFirstLayout", start_to_first_layout);
}
}
+
+void RenderView::FocusAccessibilityObject(
+ WebCore::AccessibilityObject* acc_obj) {
+#if defined(OS_WIN)
+ if (!web_accessibility_manager_.get()) {
+ web_accessibility_manager_.reset(
+ webkit_glue::WebAccessibilityManager::Create());
+ }
+
+ // Retrieve the accessibility object id of the AccessibilityObject.
+ int acc_obj_id = web_accessibility_manager_->FocusAccObj(acc_obj);
+
+ // If id is valid, alert the browser side that an accessibility focus change
+ // occurred.
+ if (acc_obj_id >= 0)
+ Send(new ViewHostMsg_AccessibilityFocusChange(routing_id_, acc_obj_id));
+
+#else // defined(OS_WIN)
+ // TODO(port): accessibility not yet implemented
+ NOTIMPLEMENTED();
+#endif
+}
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 936adae..f42b8ff 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -49,7 +49,6 @@ class FilePath;
class GURL;
class RenderThread;
class ResourceDispatcher;
-class WebAccessibilityManager;
class WebError;
class WebFrame;
class WebPluginDelegate;
@@ -307,6 +306,7 @@ class RenderView : public RenderWidget,
int active_match_ordinal,
const WebKit::WebRect& selection);
virtual bool WasOpenedByUserGesture() const;
+ virtual void FocusAccessibilityObject(WebCore::AccessibilityObject* acc_obj);
virtual void SpellCheck(const std::wstring& word, int& misspell_location,
int& misspell_length);
virtual void GetAutoCorrectWord(const std::wstring& misspelled_word,
diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc
index 4fa77a8..4dfb0ca 100644
--- a/views/widget/widget_win.cc
+++ b/views/widget/widget_win.cc
@@ -558,10 +558,6 @@ LRESULT WidgetWin::OnGetObject(UINT uMsg, WPARAM w_param, LPARAM l_param) {
// Return with failure.
return static_cast<LRESULT>(0L);
}
-
- // Notify that an instance of IAccessible was allocated for m_hWnd
- ::NotifyWinEvent(EVENT_OBJECT_CREATE, GetNativeView(), OBJID_CLIENT,
- CHILDID_SELF);
}
// Create a reference to ViewAccessibility that MSAA will marshall
diff --git a/webkit/glue/chrome_client_impl.cc b/webkit/glue/chrome_client_impl.cc
index b235d35..9553e93 100644
--- a/webkit/glue/chrome_client_impl.cc
+++ b/webkit/glue/chrome_client_impl.cc
@@ -7,8 +7,11 @@
#include "base/compiler_specific.h"
MSVC_PUSH_WARNING_LEVEL(0);
+#include "AccessibilityObject.h"
+#include "AXObjectCache.h"
#include "Console.h"
#include "Cursor.h"
+#include "Document.h"
#include "DocumentLoader.h"
#include "FloatRect.h"
#include "FileChooser.h"
@@ -16,6 +19,7 @@ MSVC_PUSH_WARNING_LEVEL(0);
#include "FrameView.h"
#include "HitTestResult.h"
#include "IntRect.h"
+#include "Node.h"
#include "Page.h"
#include "PopupMenuChromium.h"
#include "ScriptController.h"
@@ -29,7 +33,6 @@ MSVC_POP_WARNING();
#include "webkit/glue/chrome_client_impl.h"
-#include "base/logging.h"
#include "base/gfx/rect.h"
#include "googleurl/src/gurl.h"
#include "webkit/api/public/WebInputEvent.h"
@@ -141,6 +144,28 @@ void ChromeClientImpl::focus() {
WebViewDelegate* delegate = webview_->delegate();
if (delegate)
delegate->Focus(webview_);
+
+ // If accessibility is enabled, we should notify assistive technology that the
+ // active AccessibilityObject changed.
+ WebCore::Document* doc = webview_->GetFocusedWebCoreFrame()->document();
+
+ if (doc && doc->axObjectCache()->accessibilityEnabled()) {
+ WebCore::Node* focused_node = webview_->GetFocusedNode();
+
+ if (!focused_node) {
+ // Could not retrieve focused Node.
+ return;
+ }
+
+ // Retrieve the focused AccessibilityObject.
+ WebCore::AccessibilityObject* focused_acc_obj =
+ doc->axObjectCache()->getOrCreate(focused_node->renderer());
+
+ // Alert assistive technology that focus changed.
+ if (focused_acc_obj) {
+ delegate->FocusAccessibilityObject(focused_acc_obj);
+ }
+ }
}
void ChromeClientImpl::unfocus() {
@@ -201,7 +226,8 @@ static inline bool CurrentEventShouldCauseBackgroundTab(
if (input_event->type != WebInputEvent::MouseUp)
return false;
- const WebMouseEvent* mouse_event = static_cast<const WebMouseEvent*>(input_event);
+ const WebMouseEvent* mouse_event =
+ static_cast<const WebMouseEvent*>(input_event);
return (mouse_event->button == WebMouseEvent::ButtonMiddle);
}
@@ -294,7 +320,8 @@ void ChromeClientImpl::addMessageToConsole(WebCore::MessageSource source,
}
WebDevToolsAgentImpl* devtools_agent = webview_->GetWebDevToolsAgentImpl();
if (devtools_agent) {
- devtools_agent->AddMessageToConsole(source, level, message, line_no, source_id);
+ devtools_agent->AddMessageToConsole(source, level, message, line_no,
+ source_id);
}
}
diff --git a/webkit/glue/chrome_client_impl.h b/webkit/glue/chrome_client_impl.h
index e372f7c..3a3fdc5 100644
--- a/webkit/glue/chrome_client_impl.h
+++ b/webkit/glue/chrome_client_impl.h
@@ -24,7 +24,7 @@ struct WindowFeatures;
// Handles window-level notifications from WebCore on behalf of a WebView.
class ChromeClientImpl : public WebCore::ChromeClientChromium {
public:
- ChromeClientImpl(WebViewImpl* webview);
+ explicit ChromeClientImpl(WebViewImpl* webview);
virtual ~ChromeClientImpl();
WebViewImpl* webview() const { return webview_; }
@@ -67,7 +67,8 @@ class ChromeClientImpl : public WebCore::ChromeClientChromium {
virtual void setResizable(bool);
virtual void addMessageToConsole(WebCore::MessageSource source,
- WebCore::MessageLevel level, const WebCore::String& message,
+ WebCore::MessageLevel level,
+ const WebCore::String& message,
unsigned int lineNumber,
const WebCore::String& sourceID);
diff --git a/webkit/glue/glue_accessibility_object.cc b/webkit/glue/glue_accessibility_object.cc
index 17a693e..8c056eb 100644
--- a/webkit/glue/glue_accessibility_object.cc
+++ b/webkit/glue/glue_accessibility_object.cc
@@ -134,7 +134,7 @@ GlueAccessibilityObject* GlueAccessibilityObject::Navigate(
GlueAccessibilityObject* GlueAccessibilityObject::GetChild(int child_id) {
AccessibilityObject* child_obj;
if (!GetAccessibilityObjectForChild(child_id, child_obj))
- return false;
+ return NULL;
// TODO(klink): simple object child?
ToWrapper(child_obj)->ref();
diff --git a/webkit/glue/glue_accessibility_object.h b/webkit/glue/glue_accessibility_object.h
index 137a7e3..f94f9a1 100644
--- a/webkit/glue/glue_accessibility_object.h
+++ b/webkit/glue/glue_accessibility_object.h
@@ -27,6 +27,8 @@ class GlueAccessibilityObject : public WebCore::AccessibilityObjectWrapper {
public:
static GlueAccessibilityObject* CreateInstance(WebCore::AccessibilityObject*);
+ virtual ~GlueAccessibilityObject() {}
+
// Performs the default action on a given object.
bool DoDefaultAction(int child_id);
@@ -91,7 +93,6 @@ class GlueAccessibilityObject : public WebCore::AccessibilityObjectWrapper {
protected:
explicit GlueAccessibilityObject(WebCore::AccessibilityObject*);
- virtual ~GlueAccessibilityObject() {}
// Helper functions.
WebCore::String name() const;
diff --git a/webkit/glue/webaccessibility.h b/webkit/glue/webaccessibility.h
index 538e612..250c665 100644
--- a/webkit/glue/webaccessibility.h
+++ b/webkit/glue/webaccessibility.h
@@ -117,6 +117,10 @@ class WebAccessibility {
// Id of accessible child, whose information is being requested.
int child_id;
+ // Indicates if the |child_id| refers to a direct child of the active
+ // accessibility object (true) or not (false).
+ bool direct_descendant;
+
// LONG input parameters, used differently depending on the function called.
long input_long1;
long input_long2;
diff --git a/webkit/glue/webaccessibilitymanager.h b/webkit/glue/webaccessibilitymanager.h
index cebe94c..c94fbb9 100644
--- a/webkit/glue/webaccessibilitymanager.h
+++ b/webkit/glue/webaccessibilitymanager.h
@@ -7,6 +7,10 @@
#include "webkit/glue/webaccessibility.h"
+namespace WebCore {
+class AccessibilityObject;
+}
+
class WebView;
////////////////////////////////////////////////////////////////////////////////
@@ -24,6 +28,7 @@ class WebAccessibilityManager {
WebAccessibilityManager() {}
virtual ~WebAccessibilityManager() {}
+ // Creates a new instance of WebAccessibilityManager.
static WebAccessibilityManager* Create();
// Retrieves the accessibility information as requested in in_params, by
@@ -39,13 +44,17 @@ class WebAccessibilityManager {
// false otherwise.
virtual bool ClearAccObjMap(int acc_obj_id, bool clear_all) = 0;
+ // Retrieves the id of the input AccessibilityObject, due to a focus event.
+ // Returns an id greater than or equal to 0 if successful, -1 otherwise.
+ virtual int FocusAccObj(WebCore::AccessibilityObject* acc_obj) = 0;
+
+ private:
// Retrieves the RenderObject associated with this WebView, and uses it to
// initialize the root of the GlueAccessibilityObject tree with the
// associated accessibility information. Returns true if successful, false
// otherwise.
virtual bool InitAccObjRoot(WebView* view) = 0;
- private:
DISALLOW_COPY_AND_ASSIGN(WebAccessibilityManager);
};
diff --git a/webkit/glue/webaccessibilitymanager_impl.cc b/webkit/glue/webaccessibilitymanager_impl.cc
index 57ac0c7..f765127 100644
--- a/webkit/glue/webaccessibilitymanager_impl.cc
+++ b/webkit/glue/webaccessibilitymanager_impl.cc
@@ -34,7 +34,13 @@ WebAccessibilityManager* WebAccessibilityManager::Create() {
// class WebAccessibilityManagerImpl
WebAccessibilityManagerImpl::WebAccessibilityManagerImpl()
- : root_(new GlueAccessibilityObjectRoot) {
+ : root_(new GlueAccessibilityObjectRoot),
+ acc_obj_id_(0) {
+}
+
+WebAccessibilityManagerImpl::~WebAccessibilityManagerImpl() {
+ int_to_glue_acc_obj_map_.clear();
+ acc_obj_to_int_map_.clear();
}
bool WebAccessibilityManagerImpl::GetAccObjInfo(WebView* view,
@@ -45,18 +51,28 @@ bool WebAccessibilityManagerImpl::GetAccObjInfo(WebView* view,
return false;
}
- // Find GlueAccessibilityObject requested by [in_params.object_id].
- IntToAccObjMap::iterator it =
- int_to_acc_obj_map_.find(in_params.object_id);
- if (it == int_to_acc_obj_map_.end() || !it->second) {
+ // Function input parameters.
+ int object_id = in_params.object_id;
+ int child_id = in_params.child_id;
+
+ if (!in_params.direct_descendant) {
+ // Object is not a direct child, re-map the input parameters accordingly.
+ // The object to be retrieved is referred to by the |in_params.child_id|, as
+ // a result of e.g. a focus event. The local |child_id| is set to 0, to
+ // indicate that any function call should refer to the object itself.
+ object_id = in_params.child_id;
+ child_id = 0;
+ }
+
+ // Find GlueAccessibilityObject requested by |object_id|.
+ IntToGlueAccObjMap::iterator it =
+ int_to_glue_acc_obj_map_.find(object_id);
+ if (it == int_to_glue_acc_obj_map_.end() || !it->second) {
// Map did not contain a valid instance of the data requested.
return false;
}
RefPtr<GlueAccessibilityObject> active_acc_obj = it->second;
- // Function input parameters.
- int child_id = in_params.child_id;
-
// Temp paramters for holding output information.
RefPtr<GlueAccessibilityObject> out_acc_obj = NULL;
WebCore::String out_string;
@@ -156,7 +172,8 @@ bool WebAccessibilityManagerImpl::GetAccObjInfo(WebView* view,
out_params->output_string = StringToString16(out_string);
if (out_acc_obj) {
- AccObjToIntMap::iterator it = acc_obj_to_int_map_.find(out_acc_obj.get());
+ AccObjToIntMap::iterator it =
+ acc_obj_to_int_map_.find(out_acc_obj->accessibilityObject());
if (it != acc_obj_to_int_map_.end()) {
// Data already present in map, return previously assigned id.
@@ -164,8 +181,8 @@ bool WebAccessibilityManagerImpl::GetAccObjInfo(WebView* view,
out_params->output_long1 = -1;
} else {
// Insert new GlueAccessibilityObject in hashmaps.
- int_to_acc_obj_map_[acc_obj_id_] = out_acc_obj.get();
- acc_obj_to_int_map_[out_acc_obj.get()] = acc_obj_id_;
+ int_to_glue_acc_obj_map_[acc_obj_id_] = out_acc_obj.get();
+ acc_obj_to_int_map_[out_acc_obj->accessibilityObject()] = acc_obj_id_;
out_params->object_id = acc_obj_id_++;
out_params->output_long1 = -1;
}
@@ -175,9 +192,6 @@ bool WebAccessibilityManagerImpl::GetAccObjInfo(WebView* view,
}
bool WebAccessibilityManagerImpl::InitAccObjRoot(WebView* view) {
- // Root id is always 0.
- acc_obj_id_ = 0;
-
// Enable accessibility and retrieve Document.
WebCore::AXObjectCache::enableAccessibility();
WebFrameImpl* main_frame_impl =
@@ -199,8 +213,9 @@ bool WebAccessibilityManagerImpl::InitAccObjRoot(WebView* view) {
axObjectCache()->getOrCreate(doc->renderer()));
}
// Insert root in hashmaps.
- int_to_acc_obj_map_[acc_obj_id_] = root_->acc_obj_root_.get();
- acc_obj_to_int_map_[root_->acc_obj_root_.get()] = acc_obj_id_++;
+ int_to_glue_acc_obj_map_[acc_obj_id_] = root_->acc_obj_root_.get();
+ acc_obj_to_int_map_[root_->acc_obj_root_->accessibilityObject()] =
+ acc_obj_id_++;
return true;
}
@@ -209,27 +224,28 @@ bool WebAccessibilityManagerImpl::ClearAccObjMap(int acc_obj_id,
bool clear_all) {
if (clear_all) {
// Clear maps and invalidate root.
- int_to_acc_obj_map_.clear();
+ int_to_glue_acc_obj_map_.clear();
acc_obj_to_int_map_.clear();
root_->acc_obj_root_ = 0;
return true;
}
- IntToAccObjMap::iterator it = int_to_acc_obj_map_.find(acc_obj_id);
+ IntToGlueAccObjMap::iterator it = int_to_glue_acc_obj_map_.find(acc_obj_id);
- if (it == int_to_acc_obj_map_.end()) {
+ if (it == int_to_glue_acc_obj_map_.end()) {
// Element not found.
return false;
}
if (it->second) {
// Erase element from reverse hashmap.
- AccObjToIntMap::iterator it2 = acc_obj_to_int_map_.find(it->second);
+ AccObjToIntMap::iterator it2 =
+ acc_obj_to_int_map_.find(it->second->accessibilityObject());
if (it2 != acc_obj_to_int_map_.end())
acc_obj_to_int_map_.erase(it2);
}
- int_to_acc_obj_map_.erase(it);
+ int_to_glue_acc_obj_map_.erase(it);
if (acc_obj_id == 0) {
// Invalidate root.
@@ -238,4 +254,25 @@ bool WebAccessibilityManagerImpl::ClearAccObjMap(int acc_obj_id,
return true;
}
+int WebAccessibilityManagerImpl::FocusAccObj(
+ WebCore::AccessibilityObject* acc_obj) {
+ if (!acc_obj) {
+ // Return with failure.
+ return -1;
+ }
+
+ AccObjToIntMap::iterator it = acc_obj_to_int_map_.find(acc_obj);
+
+ if (it != acc_obj_to_int_map_.end())
+ return it->second;
+
+ // Insert new accessibility object in hashmaps and return its newly
+ // assigned accessibility object id.
+ int_to_glue_acc_obj_map_[acc_obj_id_] =
+ GlueAccessibilityObject::CreateInstance(acc_obj);
+ acc_obj_to_int_map_[acc_obj] = acc_obj_id_;
+
+ return acc_obj_id_++;
+}
+
} // namespace webkit_glue
diff --git a/webkit/glue/webaccessibilitymanager_impl.h b/webkit/glue/webaccessibilitymanager_impl.h
index fe28e4e..1bc0607 100644
--- a/webkit/glue/webaccessibilitymanager_impl.h
+++ b/webkit/glue/webaccessibilitymanager_impl.h
@@ -10,10 +10,6 @@
class GlueAccessibilityObject;
-namespace webkit_glue {
-typedef base::hash_map<int, GlueAccessibilityObject*> IntToAccObjMap;
-typedef base::hash_map<GlueAccessibilityObject*, int> AccObjToIntMap;
-
////////////////////////////////////////////////////////////////////////////////
//
// WebAccessibilityManagerImpl
@@ -24,21 +20,23 @@ typedef base::hash_map<GlueAccessibilityObject*, int> AccObjToIntMap;
// the requested information from the active AccessibilityObject, through the
// GlueAccessibilityObject.
////////////////////////////////////////////////////////////////////////////////
+
+namespace webkit_glue {
+
class WebAccessibilityManagerImpl : public WebAccessibilityManager {
public:
// From WebAccessibilityManager.
bool GetAccObjInfo(WebView* view, const WebAccessibility::InParams& in_params,
WebAccessibility::OutParams* out_params);
-
- // From WebAccessibilityManager.
bool ClearAccObjMap(int acc_obj_id, bool clear_all);
+ int FocusAccObj(WebCore::AccessibilityObject* acc_obj);
protected:
// Needed so WebAccessibilityManager::Create can call our constructor.
friend class WebAccessibilityManager;
WebAccessibilityManagerImpl();
- ~WebAccessibilityManagerImpl() {}
+ ~WebAccessibilityManagerImpl();
private:
// From WebAccessibilityManager.
@@ -49,17 +47,21 @@ class WebAccessibilityManagerImpl : public WebAccessibilityManager {
struct GlueAccessibilityObjectRoot;
GlueAccessibilityObjectRoot* root_;
+ typedef base::hash_map<int, GlueAccessibilityObject*> IntToGlueAccObjMap;
+ typedef base::hash_map<WebCore::AccessibilityObject*, int> AccObjToIntMap;
+
// Hashmap for cashing of elements in use by the AT, mapping id (int) to a
// GlueAccessibilityObject pointer.
- IntToAccObjMap int_to_acc_obj_map_;
+ IntToGlueAccObjMap int_to_glue_acc_obj_map_;
// Hashmap for cashing of elements in use by the AT, mapping a
- // GlueAccessibilityObject pointer to its id (int). Needed for reverse lookup,
+ // AccessibilityObject pointer to its id (int). Needed for reverse lookup,
// to ensure unnecessary duplicate entries are not created in the
- // IntToAccObjMap (above).
+ // IntToGlueAccObjMap (above) and for focus changes in WebKit.
AccObjToIntMap acc_obj_to_int_map_;
- // Unique identifier for retrieving a GlueAccessibilityObject from the page's
- // hashmaps.
+ // Unique identifier for retrieving an accessibility object from the page's
+ // hashmaps. Id is always 0 for the root of the accessibility object
+ // hierarchy (on a per-renderer process basis).
int acc_obj_id_;
DISALLOW_COPY_AND_ASSIGN(WebAccessibilityManagerImpl);
diff --git a/webkit/glue/webview_delegate.h b/webkit/glue/webview_delegate.h
index 525f745..7d503ad 100644
--- a/webkit/glue/webview_delegate.h
+++ b/webkit/glue/webview_delegate.h
@@ -37,6 +37,10 @@ namespace webkit_glue {
class WebMediaPlayerDelegate;
}
+namespace WebCore {
+class AccessibilityObject;
+}
+
namespace WebKit {
class WebDragData;
class WebWorker;
@@ -169,6 +173,13 @@ class WebViewDelegate : virtual public WebWidgetDelegate {
return true;
}
+ // Called by ChromeClientImpl::focus() if accessibility on the renderer side
+ // is enabled, and a focus change has occurred. Will retrieve the id of the
+ // input AccessibilityObject and send it through IPC for handling on the
+ // browser side.
+ virtual void FocusAccessibilityObject(WebCore::AccessibilityObject* acc_obj) {
+ }
+
// FrameLoaderClient -------------------------------------------------------
// Notifies the delegate that a load has begun.
diff --git a/webkit/glue/webview_impl.h b/webkit/glue/webview_impl.h
index ae26890..caac1c8 100644
--- a/webkit/glue/webview_impl.h
+++ b/webkit/glue/webview_impl.h
@@ -138,6 +138,9 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> {
WebCore::Frame* GetFocusedWebCoreFrame();
+ // Returns the currently focused Node or NULL if no node has focus.
+ WebCore::Node* GetFocusedNode();
+
static WebViewImpl* FromPage(WebCore::Page* page);
WebViewDelegate* delegate() {
@@ -285,9 +288,6 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> {
WebCore::HitTestResult HitTestResultForWindowPos(
const WebCore::IntPoint& pos);
- // Returns the currently focused Node or NULL if no node has focus.
- WebCore::Node* GetFocusedNode();
-
// ImageResourceFetchers schedule via DownloadImage.
std::set<ImageResourceFetcher*> image_fetchers_;