diff options
author | klink@chromium.org <klink@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-20 00:53:06 +0000 |
---|---|---|
committer | klink@chromium.org <klink@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-20 00:53:06 +0000 |
commit | e846d0dba2bf9506a929c9e16294997e37014039 (patch) | |
tree | 5ac70d2216fd450b3d4f164a26f752504c8cb220 /chrome | |
parent | fabd89f6aa700cb0e59b04e92ce54e729cbd0c66 (diff) | |
download | chromium_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
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/browser_accessibility.cc | 83 | ||||
-rw-r--r-- | chrome/browser/browser_accessibility.h | 50 | ||||
-rw-r--r-- | chrome/browser/browser_accessibility_manager.cc | 152 | ||||
-rw-r--r-- | chrome/browser/browser_accessibility_manager.h | 78 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.cc | 16 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.h | 1 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_win.cc | 41 | ||||
-rw-r--r-- | chrome/common/render_messages.h | 4 | ||||
-rw-r--r-- | chrome/common/render_messages_internal.h | 9 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 26 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 2 |
11 files changed, 244 insertions, 218 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, |