diff options
author | dmazzoni@chromium.org <dmazzoni@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-15 11:07:35 +0000 |
---|---|---|
committer | dmazzoni@chromium.org <dmazzoni@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-15 11:07:35 +0000 |
commit | a6120e3f4a8c3ab5a85edd52f74e3d603642247a (patch) | |
tree | db81f40cc1a07c89c016c7b85ee0124e9515e027 | |
parent | 599aeffdcddcd73fc4dff854631016438fd922c2 (diff) | |
download | chromium_src-a6120e3f4a8c3ab5a85edd52f74e3d603642247a.zip chromium_src-a6120e3f4a8c3ab5a85edd52f74e3d603642247a.tar.gz chromium_src-a6120e3f4a8c3ab5a85edd52f74e3d603642247a.tar.bz2 |
Connect RenderWidgetHostViewAura to BrowserAccessibilityManager.
This change doesn't completely make Aura/Win accessible, it just
refactors BrowserAccessibilityManager a bit so that it can be
used by both Win and AuraWin without convoluted typecasting.
Specifically, the assumption before was that
BrowserAccessibilityManager could be initialized with a
parent gfx::NativeView that's the accessibility parent.
That abstraction doesn't work in Aura - the
parent accessible object is not the same as the parent HWND
(and BrowserAccessibilityManagerWin needs both). So rather than
trying to have the parent accessible object be a
cross-platform concept, I just made it a platform-specific
concept that the base class doesn't know about now.
BUG=175156
Review URL: https://chromiumcodereview.appspot.com/12555004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@188335 0039d316-1c4b-4281-b951-d872f2087c98
24 files changed, 375 insertions, 238 deletions
diff --git a/content/browser/accessibility/accessibility_tree_formatter.cc b/content/browser/accessibility/accessibility_tree_formatter.cc index 876db8a..f8b4cc7 100644 --- a/content/browser/accessibility/accessibility_tree_formatter.cc +++ b/content/browser/accessibility/accessibility_tree_formatter.cc @@ -68,7 +68,7 @@ void AccessibilityTreeFormatter::RecursiveFormatAccessibilityTree( } } -#if (!defined(OS_WIN) && !defined(OS_MACOSX)) || defined(USE_AURA) +#if (!defined(OS_WIN) && !defined(OS_MACOSX)) string16 AccessibilityTreeFormatter::ToString(BrowserAccessibility* node, char* prefix) { return UTF8ToUTF16(prefix) + base::IntToString16(node->renderer_id()) + diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc index 69ddddb9..82bee25 100644 --- a/content/browser/accessibility/browser_accessibility.cc +++ b/content/browser/accessibility/browser_accessibility.cc @@ -18,10 +18,10 @@ typedef AccessibilityNodeData::IntAttribute IntAttribute; typedef AccessibilityNodeData::StringAttribute StringAttribute; #if !defined(OS_MACOSX) && \ - !(defined(OS_WIN) && !defined(USE_AURA)) && \ + !defined(OS_WIN) && \ !defined(TOOLKIT_GTK) // We have subclassess of BrowserAccessibility on Mac, Linux/GTK, -// and non-Aura Win. For any other platform, instantiate the base class. +// and Win. For any other platform, instantiate the base class. // static BrowserAccessibility* BrowserAccessibility::Create() { return new BrowserAccessibility(); diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index 81c1ee9..a728c5a 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm @@ -13,6 +13,7 @@ #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" #include "content/browser/accessibility/browser_accessibility_manager.h" +#include "content/browser/accessibility/browser_accessibility_manager_mac.h" #include "content/public/common/content_client.h" #include "grit/webkit_strings.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebRect.h" @@ -25,6 +26,7 @@ extern "C" void NSAccessibilityUnregisterUniqueIdForUIElement(id element); using content::AccessibilityNodeData; using content::BrowserAccessibility; using content::BrowserAccessibilityManager; +using content::BrowserAccessibilityManagerMac; using content::ContentClient; typedef AccessibilityNodeData::StringAttribute StringAttribute; @@ -595,7 +597,10 @@ NSDictionary* attributeToMethodNameMap = nil; browserAccessibility_->parent()->ToBrowserAccessibilityCocoa()); } else { // Hook back up to RenderWidgetHostViewCocoa. - return browserAccessibility_->manager()->GetParentView(); + BrowserAccessibilityManagerMac* manager = + static_cast<BrowserAccessibilityManagerMac*>( + browserAccessibility_->manager()); + return manager->parent_view(); } } diff --git a/content/browser/accessibility/browser_accessibility_gtk.cc b/content/browser/accessibility/browser_accessibility_gtk.cc index fb6d99d..2c338db 100644 --- a/content/browser/accessibility/browser_accessibility_gtk.cc +++ b/content/browser/accessibility/browser_accessibility_gtk.cc @@ -56,8 +56,10 @@ static AtkObject* browser_accessibility_get_parent(AtkObject* atk_object) { return NULL; if (obj->parent()) return obj->parent()->ToBrowserAccessibilityGtk()->GetAtkObject(); - else - return gtk_widget_get_accessible(obj->manager()->GetParentView()); + + BrowserAccessibilityManagerGtk* manager = + static_cast<BrowserAccessibilityManagerGtk*>(obj->manager()); + return gtk_widget_get_accessible(manager->parent_widget()); } static gint browser_accessibility_get_n_children(AtkObject* atk_object) { diff --git a/content/browser/accessibility/browser_accessibility_mac.mm b/content/browser/accessibility/browser_accessibility_mac.mm index 9d049b5..0725e91 100644 --- a/content/browser/accessibility/browser_accessibility_mac.mm +++ b/content/browser/accessibility/browser_accessibility_mac.mm @@ -8,7 +8,7 @@ #import "content/browser/accessibility/browser_accessibility_cocoa.h" #import "content/browser/accessibility/browser_accessibility_delegate_mac.h" -#include "content/browser/accessibility/browser_accessibility_manager.h" +#include "content/browser/accessibility/browser_accessibility_manager_mac.h" namespace content { @@ -28,10 +28,12 @@ void BrowserAccessibilityMac::PreInitialize() { return; // We take ownership of the cocoa obj here. + BrowserAccessibilityManagerMac* manager = + static_cast<BrowserAccessibilityManagerMac*>(manager_); browser_accessibility_cocoa_ = [[BrowserAccessibilityCocoa alloc] initWithObject:this delegate: - (id<BrowserAccessibilityDelegateCocoa>)manager_->GetParentView()]; + (id<BrowserAccessibilityDelegateCocoa>)manager->parent_view()]; } void BrowserAccessibilityMac::NativeReleaseReference() { diff --git a/content/browser/accessibility/browser_accessibility_mac_unittest.mm b/content/browser/accessibility/browser_accessibility_mac_unittest.mm index d047e33..19ba552 100644 --- a/content/browser/accessibility/browser_accessibility_mac_unittest.mm +++ b/content/browser/accessibility/browser_accessibility_mac_unittest.mm @@ -9,6 +9,7 @@ #include "base/utf_string_conversions.h" #include "content/browser/accessibility/browser_accessibility_cocoa.h" #include "content/browser/accessibility/browser_accessibility_manager.h" +#include "content/browser/accessibility/browser_accessibility_manager_mac.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" #import "ui/base/test/ui_cocoa_test_helper.h" @@ -83,7 +84,7 @@ class BrowserAccessibilityTest : public ui::CocoaTest { delegate_.reset([[MockAccessibilityDelegate alloc] init]); manager_.reset( - BrowserAccessibilityManager::Create(delegate_, root, NULL)); + new BrowserAccessibilityManagerMac(delegate_, root, NULL)); manager_->UpdateNodesForTesting(child1, child2); accessibility_.reset([manager_->GetRoot()->ToBrowserAccessibilityCocoa() retain]); diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc index 549ba73..ca02fa5 100644 --- a/content/browser/accessibility/browser_accessibility_manager.cc +++ b/content/browser/accessibility/browser_accessibility_manager.cc @@ -23,43 +23,24 @@ BrowserAccessibility* BrowserAccessibilityFactory::Create() { int32 BrowserAccessibilityManager::next_child_id_ = -1; #if !defined(OS_MACOSX) && \ - !(defined(OS_WIN) && !defined(USE_AURA)) && \ + !defined(OS_WIN) && \ !defined(TOOLKIT_GTK) // We have subclassess of BrowserAccessibilityManager on Mac, Linux/GTK, -// and non-Aura Win. For any other platform, instantiate the base class. +// and Win. For any other platform, instantiate the base class. // static BrowserAccessibilityManager* BrowserAccessibilityManager::Create( - gfx::NativeView parent_view, const AccessibilityNodeData& src, BrowserAccessibilityDelegate* delegate, BrowserAccessibilityFactory* factory) { - return new BrowserAccessibilityManager( - parent_view, src, delegate, factory); + return new BrowserAccessibilityManager(src, delegate, factory); } #endif -// static -BrowserAccessibilityManager* BrowserAccessibilityManager::CreateEmptyDocument( - gfx::NativeView parent_view, - AccessibilityNodeData::State state, - BrowserAccessibilityDelegate* delegate, - BrowserAccessibilityFactory* factory) { - // Use empty document to process notifications - AccessibilityNodeData empty_document; - empty_document.id = 0; - empty_document.role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA; - empty_document.state = state | (1 << AccessibilityNodeData::STATE_READONLY); - return BrowserAccessibilityManager::Create( - parent_view, empty_document, delegate, factory); -} - BrowserAccessibilityManager::BrowserAccessibilityManager( - gfx::NativeView parent_view, const AccessibilityNodeData& src, BrowserAccessibilityDelegate* delegate, BrowserAccessibilityFactory* factory) - : parent_view_(parent_view), - delegate_(delegate), + : delegate_(delegate), factory_(factory), root_(NULL), focus_(NULL), @@ -199,10 +180,6 @@ void BrowserAccessibilityManager::OnAccessibilityNotifications( } } -gfx::NativeView BrowserAccessibilityManager::GetParentView() { - return parent_view_; -} - BrowserAccessibility* BrowserAccessibilityManager::GetFocus( BrowserAccessibility* root) { if (focus_ && (!root || focus_->IsDescendantOf(root))) diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h index 08010bf..a9e7a64 100644 --- a/content/browser/accessibility/browser_accessibility_manager.h +++ b/content/browser/accessibility/browser_accessibility_manager.h @@ -52,21 +52,12 @@ class CONTENT_EXPORT BrowserAccessibilityFactory { // Manages a tree of BrowserAccessibility objects. class CONTENT_EXPORT BrowserAccessibilityManager { public: - // Creates the platform specific BrowserAccessibilityManager. Ownership passes - // to the caller. + // Creates the platform-specific BrowserAccessibilityManager, but + // with no parent window pointer. Only useful for unit tests. static BrowserAccessibilityManager* Create( - gfx::NativeView parent_view, - const AccessibilityNodeData& src, - BrowserAccessibilityDelegate* delegate, - BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory()); - - // Creates the platform specific BrowserAccessibilityManager. Ownership passes - // to the caller. - static BrowserAccessibilityManager* CreateEmptyDocument( - gfx::NativeView parent_view, - AccessibilityNodeData::State state, - BrowserAccessibilityDelegate* delegate, - BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory()); + const AccessibilityNodeData& src, + BrowserAccessibilityDelegate* delegate, + BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory()); virtual ~BrowserAccessibilityManager(); @@ -141,8 +132,6 @@ class CONTENT_EXPORT BrowserAccessibilityManager { void OnAccessibilityNotifications( const std::vector<AccessibilityHostMsg_NotificationParams>& params); - gfx::NativeView GetParentView(); - #if defined(OS_WIN) BrowserAccessibilityManagerWin* ToBrowserAccessibilityManagerWin(); #endif @@ -170,7 +159,6 @@ class CONTENT_EXPORT BrowserAccessibilityManager { protected: BrowserAccessibilityManager( - gfx::NativeView parent_view, const AccessibilityNodeData& src, BrowserAccessibilityDelegate* delegate, BrowserAccessibilityFactory* factory); @@ -215,9 +203,6 @@ class CONTENT_EXPORT BrowserAccessibilityManager { // The next unique id for a BrowserAccessibility instance. static int32 next_child_id_; - // The parent view. - gfx::NativeView parent_view_; - // The object that can perform actions on our behalf. BrowserAccessibilityDelegate* delegate_; diff --git a/content/browser/accessibility/browser_accessibility_manager_gtk.cc b/content/browser/accessibility/browser_accessibility_manager_gtk.cc index 6613121..d637425b 100644 --- a/content/browser/accessibility/browser_accessibility_manager_gtk.cc +++ b/content/browser/accessibility/browser_accessibility_manager_gtk.cc @@ -11,28 +11,38 @@ namespace content { // static BrowserAccessibilityManager* BrowserAccessibilityManager::Create( - gfx::NativeView parent_view, - const AccessibilityNodeData& src, + const AccessibilityNodeData& src, BrowserAccessibilityDelegate* delegate, BrowserAccessibilityFactory* factory) { return new BrowserAccessibilityManagerGtk( - parent_view, + NULL, src, delegate, factory); } BrowserAccessibilityManagerGtk::BrowserAccessibilityManagerGtk( - GtkWidget* parent_view, + GtkWidget* parent_widget, const AccessibilityNodeData& src, BrowserAccessibilityDelegate* delegate, BrowserAccessibilityFactory* factory) - : BrowserAccessibilityManager(parent_view, src, delegate, factory) { + : BrowserAccessibilityManager(src, delegate, factory), + parent_widget_(parent_widget) { } BrowserAccessibilityManagerGtk::~BrowserAccessibilityManagerGtk() { } +// static +AccessibilityNodeData BrowserAccessibilityManagerGtk::GetEmptyDocument() { + AccessibilityNodeData empty_document; + empty_document.id = 0; + empty_document.role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA; + empty_document.state = + 1 << AccessibilityNodeData::STATE_READONLY; + return empty_document; +} + void BrowserAccessibilityManagerGtk::NotifyAccessibilityEvent( int type, BrowserAccessibility* node) { diff --git a/content/browser/accessibility/browser_accessibility_manager_gtk.h b/content/browser/accessibility/browser_accessibility_manager_gtk.h index bb736f7..eedae7c 100644 --- a/content/browser/accessibility/browser_accessibility_manager_gtk.h +++ b/content/browser/accessibility/browser_accessibility_manager_gtk.h @@ -13,23 +13,30 @@ namespace content { class BrowserAccessibilityGtk; // Manages a tree of BrowserAccessibilityGtk objects. -class BrowserAccessibilityManagerGtk : public BrowserAccessibilityManager { +class CONTENT_EXPORT BrowserAccessibilityManagerGtk + : public BrowserAccessibilityManager { public: + BrowserAccessibilityManagerGtk( + GtkWidget* parent_widget, + const AccessibilityNodeData& src, + BrowserAccessibilityDelegate* delegate, + BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory()); + virtual ~BrowserAccessibilityManagerGtk(); + static AccessibilityNodeData GetEmptyDocument(); + // BrowserAccessibilityManager methods virtual void NotifyAccessibilityEvent(int type, BrowserAccessibility* node) OVERRIDE; - private: - BrowserAccessibilityManagerGtk( - GtkWidget* parent_window, - const AccessibilityNodeData& src, - BrowserAccessibilityDelegate* delegate, - BrowserAccessibilityFactory* factory); + GtkWidget* parent_widget() { return parent_widget_; } + private: void RecursivelySendChildrenChanged(BrowserAccessibilityGtk* node); + GtkWidget* parent_widget_; + // Give BrowserAccessibilityManager::Create access to our constructor. friend class BrowserAccessibilityManager; diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.h b/content/browser/accessibility/browser_accessibility_manager_mac.h index 01553f8..d94c2c7 100644 --- a/content/browser/accessibility/browser_accessibility_manager_mac.h +++ b/content/browser/accessibility/browser_accessibility_manager_mac.h @@ -11,21 +11,29 @@ namespace content { -class BrowserAccessibilityManagerMac : public BrowserAccessibilityManager { +class CONTENT_EXPORT BrowserAccessibilityManagerMac + : public BrowserAccessibilityManager { public: + BrowserAccessibilityManagerMac( + NSView* parent_view, + const AccessibilityNodeData& src, + BrowserAccessibilityDelegate* delegate, + BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory()); + + static AccessibilityNodeData GetEmptyDocument(); + // Implementation of BrowserAccessibilityManager. virtual void NotifyAccessibilityEvent(int type, BrowserAccessibility* node) OVERRIDE; + NSView* parent_view() { return parent_view_; } + private: // This gives BrowserAccessibilityManager::Create access to the class // constructor. friend class BrowserAccessibilityManager; - BrowserAccessibilityManagerMac(gfx::NativeView parent_view, - const AccessibilityNodeData& src, - BrowserAccessibilityDelegate* delegate, - BrowserAccessibilityFactory* factory); + NSView* parent_view_; DISALLOW_COPY_AND_ASSIGN(BrowserAccessibilityManagerMac); }; diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm index 06d380a..e328099 100644 --- a/content/browser/accessibility/browser_accessibility_manager_mac.mm +++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm @@ -12,20 +12,29 @@ namespace content { // static BrowserAccessibilityManager* BrowserAccessibilityManager::Create( - gfx::NativeView parent_view, const AccessibilityNodeData& src, BrowserAccessibilityDelegate* delegate, BrowserAccessibilityFactory* factory) { - return new BrowserAccessibilityManagerMac( - parent_view, src, delegate, factory); + return new BrowserAccessibilityManagerMac(NULL, src, delegate, factory); } BrowserAccessibilityManagerMac::BrowserAccessibilityManagerMac( - gfx::NativeView parent_window, + NSView* parent_view, const AccessibilityNodeData& src, BrowserAccessibilityDelegate* delegate, BrowserAccessibilityFactory* factory) - : BrowserAccessibilityManager(parent_window, src, delegate, factory) { + : BrowserAccessibilityManager(src, delegate, factory), + parent_view_(parent_view) { +} + +// static +AccessibilityNodeData BrowserAccessibilityManagerMac::GetEmptyDocument() { + AccessibilityNodeData empty_document; + empty_document.id = 0; + empty_document.role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA; + empty_document.state = + 1 << AccessibilityNodeData::STATE_READONLY; + return empty_document; } void BrowserAccessibilityManagerMac::NotifyAccessibilityEvent( diff --git a/content/browser/accessibility/browser_accessibility_manager_unittest.cc b/content/browser/accessibility/browser_accessibility_manager_unittest.cc index dfcc738..c59c098 100644 --- a/content/browser/accessibility/browser_accessibility_manager_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_manager_unittest.cc @@ -117,7 +117,6 @@ TEST(BrowserAccessibilityManagerTest, TestNoLeaks) { CountedBrowserAccessibility::global_obj_count_ = 0; BrowserAccessibilityManager* manager = BrowserAccessibilityManager::Create( - NULL, root, NULL, new CountedBrowserAccessibilityFactory()); @@ -133,7 +132,6 @@ TEST(BrowserAccessibilityManagerTest, TestNoLeaks) { // the three nodes in the tree. manager = BrowserAccessibilityManager::Create( - NULL, root, NULL, new CountedBrowserAccessibilityFactory()); @@ -224,7 +222,6 @@ TEST(BrowserAccessibilityManagerTest, TestReuseBrowserAccessibilityObjects) { CountedBrowserAccessibility::global_obj_count_ = 0; BrowserAccessibilityManager* manager = BrowserAccessibilityManager::Create( - NULL, tree1_root, NULL, new CountedBrowserAccessibilityFactory()); @@ -396,7 +393,6 @@ TEST(BrowserAccessibilityManagerTest, TestReuseBrowserAccessibilityObjects2) { CountedBrowserAccessibility::global_obj_count_ = 0; BrowserAccessibilityManager* manager = BrowserAccessibilityManager::Create( - NULL, tree1_root, NULL, new CountedBrowserAccessibilityFactory()); @@ -528,7 +524,6 @@ TEST(BrowserAccessibilityManagerTest, TestMoveChildUp) { CountedBrowserAccessibility::global_obj_count_ = 0; BrowserAccessibilityManager* manager = BrowserAccessibilityManager::Create( - NULL, tree1_1, NULL, new CountedBrowserAccessibilityFactory()); @@ -555,86 +550,6 @@ TEST(BrowserAccessibilityManagerTest, TestMoveChildUp) { ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_); } -TEST(BrowserAccessibilityManagerTest, TestCreateEmptyDocument) { - // Try creating an empty document with busy state. Readonly is - // set automatically. - const int32 busy_state = 1 << AccessibilityNodeData::STATE_BUSY; - const int32 readonly_state = 1 << AccessibilityNodeData::STATE_READONLY; - scoped_ptr<BrowserAccessibilityManager> manager; - manager.reset(BrowserAccessibilityManager::CreateEmptyDocument( - NULL, - static_cast<AccessibilityNodeData::State>(busy_state), - NULL, - new CountedBrowserAccessibilityFactory())); - - // Verify the root is as we expect by default. - BrowserAccessibility* root = manager->GetRoot(); - EXPECT_EQ(0, root->renderer_id()); - EXPECT_EQ(AccessibilityNodeData::ROLE_ROOT_WEB_AREA, root->role()); - EXPECT_EQ(busy_state | readonly_state, root->state()); - - // Tree with a child textfield. - AccessibilityNodeData tree1_1; - tree1_1.id = 1; - tree1_1.role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA; - tree1_1.child_ids.push_back(2); - - AccessibilityNodeData tree1_2; - tree1_2.id = 2; - tree1_2.role = AccessibilityNodeData::ROLE_TEXT_FIELD; - - // Process a load complete. - std::vector<AccessibilityHostMsg_NotificationParams> params; - params.push_back(AccessibilityHostMsg_NotificationParams()); - AccessibilityHostMsg_NotificationParams* msg = ¶ms[0]; - msg->notification_type = AccessibilityNotificationLoadComplete; - msg->nodes.push_back(tree1_1); - msg->nodes.push_back(tree1_2); - msg->id = tree1_1.id; - manager->OnAccessibilityNotifications(params); - - // Save for later comparison. - BrowserAccessibility* acc1_2 = manager->GetFromRendererID(2); - - // Verify the root has changed. - EXPECT_NE(root, manager->GetRoot()); - - // And the proper child remains. - EXPECT_EQ(AccessibilityNodeData::ROLE_TEXT_FIELD, acc1_2->role()); - EXPECT_EQ(2, acc1_2->renderer_id()); - - // Tree with a child button. - AccessibilityNodeData tree2_1; - tree2_1.id = 1; - tree2_1.role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA; - tree2_1.child_ids.push_back(3); - - AccessibilityNodeData tree2_2; - tree2_2.id = 3; - tree2_2.role = AccessibilityNodeData::ROLE_BUTTON; - - msg->nodes.clear(); - msg->nodes.push_back(tree2_1); - msg->nodes.push_back(tree2_2); - msg->id = tree2_1.id; - - // Fire another load complete. - manager->OnAccessibilityNotifications(params); - - BrowserAccessibility* acc2_2 = manager->GetFromRendererID(3); - - // Verify the root has changed. - EXPECT_NE(root, manager->GetRoot()); - - // And the new child exists. - EXPECT_EQ(AccessibilityNodeData::ROLE_BUTTON, acc2_2->role()); - EXPECT_EQ(3, acc2_2->renderer_id()); - - // Ensure we properly cleaned up. - manager.reset(); - ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_); -} - TEST(BrowserAccessibilityManagerTest, TestFatalError) { // Test that BrowserAccessibilityManager raises a fatal error // (which will crash the renderer) if the same id is used in @@ -653,7 +568,6 @@ TEST(BrowserAccessibilityManagerTest, TestFatalError) { scoped_ptr<BrowserAccessibilityManager> manager; ASSERT_FALSE(delegate->got_fatal_error()); manager.reset(BrowserAccessibilityManager::Create( - NULL, root, delegate.get(), factory)); @@ -678,7 +592,6 @@ TEST(BrowserAccessibilityManagerTest, TestFatalError) { delegate->reset_got_fatal_error(); factory = new CountedBrowserAccessibilityFactory(); manager.reset(BrowserAccessibilityManager::Create( - NULL, root2, delegate.get(), factory)); diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc index 59327f2..6fbf69a 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.cc +++ b/content/browser/accessibility/browser_accessibility_manager_win.cc @@ -11,15 +11,11 @@ namespace content { // static BrowserAccessibilityManager* BrowserAccessibilityManager::Create( - gfx::NativeView parent_view, const AccessibilityNodeData& src, BrowserAccessibilityDelegate* delegate, BrowserAccessibilityFactory* factory) { return new BrowserAccessibilityManagerWin( - parent_view, - src, - delegate, - factory); + GetDesktopWindow(), NULL, src, delegate, factory); } BrowserAccessibilityManagerWin* @@ -28,22 +24,15 @@ BrowserAccessibilityManager::ToBrowserAccessibilityManagerWin() { } BrowserAccessibilityManagerWin::BrowserAccessibilityManagerWin( - HWND parent_view, + HWND parent_hwnd, + IAccessible* parent_iaccessible, const AccessibilityNodeData& src, BrowserAccessibilityDelegate* delegate, BrowserAccessibilityFactory* factory) - : BrowserAccessibilityManager(parent_view, src, delegate, factory), + : BrowserAccessibilityManager(src, delegate, factory), + parent_hwnd_(parent_hwnd), + parent_iaccessible_(parent_iaccessible), tracked_scroll_object_(NULL) { - // Allow NULL parent_view for unit testing. - if (parent_view == NULL) { - window_iaccessible_ = NULL; - return; - } - - HRESULT hr = ::CreateStdAccessibleObject( - parent_view, OBJID_WINDOW, IID_IAccessible, - reinterpret_cast<void **>(&window_iaccessible_)); - DCHECK(SUCCEEDED(hr)); } BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() { @@ -53,8 +42,23 @@ BrowserAccessibilityManagerWin::~BrowserAccessibilityManagerWin() { } } -IAccessible* BrowserAccessibilityManagerWin::GetParentWindowIAccessible() { - return window_iaccessible_; +// static +AccessibilityNodeData BrowserAccessibilityManagerWin::GetEmptyDocument() { + AccessibilityNodeData empty_document; + empty_document.id = 0; + empty_document.role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA; + empty_document.state = + (1 << AccessibilityNodeData::STATE_READONLY) | + (1 << AccessibilityNodeData::STATE_BUSY); + return empty_document; +} + +IAccessible* BrowserAccessibilityManagerWin::parent_iaccessible() { + return parent_iaccessible_; +} + +HWND BrowserAccessibilityManagerWin::parent_hwnd() { + return parent_hwnd_; } void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( @@ -137,7 +141,7 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( } if (event_id != EVENT_MIN) - NotifyWinEvent(event_id, GetParentView(), OBJID_CLIENT, node->child_id()); + NotifyWinEvent(event_id, parent_hwnd(), OBJID_CLIENT, node->child_id()); // If this is a layout complete notification (sent when a container scrolls) // and there is a descendant tracked object, send a notification on it. @@ -146,7 +150,7 @@ void BrowserAccessibilityManagerWin::NotifyAccessibilityEvent( tracked_scroll_object_ && tracked_scroll_object_->IsDescendantOf(node)) { NotifyWinEvent(IA2_EVENT_VISIBLE_DATA_CHANGED, - GetParentView(), + parent_hwnd(), OBJID_CLIENT, tracked_scroll_object_->child_id()); tracked_scroll_object_->Release(); diff --git a/content/browser/accessibility/browser_accessibility_manager_win.h b/content/browser/accessibility/browser_accessibility_manager_win.h index 9acaf71..d2860ad 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.h +++ b/content/browser/accessibility/browser_accessibility_manager_win.h @@ -14,13 +14,26 @@ namespace content { class BrowserAccessibilityWin; // Manages a tree of BrowserAccessibilityWin objects. -class BrowserAccessibilityManagerWin : public BrowserAccessibilityManager { +class CONTENT_EXPORT BrowserAccessibilityManagerWin + : public BrowserAccessibilityManager { public: + BrowserAccessibilityManagerWin( + HWND parent_hwnd, + IAccessible* parent_iaccessible, + const AccessibilityNodeData& src, + BrowserAccessibilityDelegate* delegate, + BrowserAccessibilityFactory* factory = new BrowserAccessibilityFactory()); + virtual ~BrowserAccessibilityManagerWin(); + static AccessibilityNodeData GetEmptyDocument(); + + // Get the closest containing HWND. + HWND parent_hwnd(); + // Get a the default IAccessible for the parent window, does not make a // new reference. - IAccessible* GetParentWindowIAccessible(); + IAccessible* parent_iaccessible(); // BrowserAccessibilityManager methods virtual void NotifyAccessibilityEvent(int type, BrowserAccessibility* node); @@ -31,14 +44,11 @@ class BrowserAccessibilityManagerWin : public BrowserAccessibilityManager { void TrackScrollingObject(BrowserAccessibilityWin* node); private: - BrowserAccessibilityManagerWin( - HWND parent_window, - const AccessibilityNodeData& src, - BrowserAccessibilityDelegate* delegate, - BrowserAccessibilityFactory* factory); + // The closest ancestor HWND. + HWND parent_hwnd_; - // A default IAccessible instance for the parent window. - base::win::ScopedComPtr<IAccessible> window_iaccessible_; + // The accessibility instance for the parent window. + IAccessible* parent_iaccessible_; // Give BrowserAccessibilityManager::Create access to our constructor. friend class BrowserAccessibilityManager; diff --git a/content/browser/accessibility/browser_accessibility_win.cc b/content/browser/accessibility/browser_accessibility_win.cc index 75124fd..92e2016 100644 --- a/content/browser/accessibility/browser_accessibility_win.cc +++ b/content/browser/accessibility/browser_accessibility_win.cc @@ -474,8 +474,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_accParent(IDispatch** disp_parent) { if (parent == NULL) { // This happens if we're the root of the tree; // return the IAccessible for the window. - parent = manager_->ToBrowserAccessibilityManagerWin()-> - GetParentWindowIAccessible(); + parent = manager_->ToBrowserAccessibilityManagerWin()->parent_iaccessible(); } parent->AddRef(); @@ -680,7 +679,7 @@ STDMETHODIMP BrowserAccessibilityWin::get_windowHandle(HWND* window_handle) { if (!window_handle) return E_INVALIDARG; - *window_handle = manager_->GetParentView(); + *window_handle = manager_->ToBrowserAccessibilityManagerWin()->parent_hwnd(); return S_OK; } @@ -863,7 +862,8 @@ STDMETHODIMP BrowserAccessibilityWin::get_imagePosition( return E_INVALIDARG; if (coordinate_type == IA2_COORDTYPE_SCREEN_RELATIVE) { - HWND parent_hwnd = manager_->GetParentView(); + HWND parent_hwnd = + manager_->ToBrowserAccessibilityManagerWin()->parent_hwnd(); POINT top_left = {0, 0}; ::ClientToScreen(parent_hwnd, &top_left); *x = location_.x() + top_left.x; @@ -2859,6 +2859,8 @@ void BrowserAccessibilityWin::PostInitialize() { previous_text_ = text; } + HWND hwnd = manager_->ToBrowserAccessibilityManagerWin()->parent_hwnd(); + // Fire events if the state has changed. if (!first_time_ && ia_state_ != old_ia_state_) { // Normally focus events are handled elsewhere, however @@ -2870,17 +2872,17 @@ void BrowserAccessibilityWin::PostInitialize() { (ia_state_ & STATE_SYSTEM_SELECTABLE) && (ia_state_ & STATE_SYSTEM_FOCUSED) && !(old_ia_state_ & STATE_SYSTEM_FOCUSED)) { - ::NotifyWinEvent(EVENT_OBJECT_FOCUS, manager_->GetParentView(), + ::NotifyWinEvent(EVENT_OBJECT_FOCUS, hwnd, OBJID_CLIENT, child_id()); } if ((ia_state_ & STATE_SYSTEM_SELECTED) && !(old_ia_state_ & STATE_SYSTEM_SELECTED)) { - ::NotifyWinEvent(EVENT_OBJECT_SELECTIONADD, manager_->GetParentView(), + ::NotifyWinEvent(EVENT_OBJECT_SELECTIONADD, hwnd, OBJID_CLIENT, child_id()); } else if (!(ia_state_ & STATE_SYSTEM_SELECTED) && (old_ia_state_ & STATE_SYSTEM_SELECTED)) { - ::NotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE, manager_->GetParentView(), + ::NotifyWinEvent(EVENT_OBJECT_SELECTIONREMOVE, hwnd, OBJID_CLIENT, child_id()); } diff --git a/content/browser/accessibility/browser_accessibility_win_unittest.cc b/content/browser/accessibility/browser_accessibility_win_unittest.cc index 17b2cbd..cbf5b82a 100644 --- a/content/browser/accessibility/browser_accessibility_win_unittest.cc +++ b/content/browser/accessibility/browser_accessibility_win_unittest.cc @@ -5,6 +5,7 @@ #include "base/memory/scoped_ptr.h" #include "base/win/scoped_comptr.h" #include "content/browser/accessibility/browser_accessibility_manager.h" +#include "content/browser/accessibility/browser_accessibility_manager_win.h" #include "content/browser/accessibility/browser_accessibility_win.h" #include "content/common/accessibility_messages.h" #include "testing/gtest/include/gtest/gtest.h" @@ -94,7 +95,6 @@ TEST_F(BrowserAccessibilityTest, TestNoLeaks) { CountedBrowserAccessibility::global_obj_count_ = 0; BrowserAccessibilityManager* manager = BrowserAccessibilityManager::Create( - GetDesktopWindow(), root, NULL, new CountedBrowserAccessibilityFactory()); @@ -109,7 +109,6 @@ TEST_F(BrowserAccessibilityTest, TestNoLeaks) { // to get new references to two of the three nodes in the tree. manager = BrowserAccessibilityManager::Create( - GetDesktopWindow(), root, NULL, new CountedBrowserAccessibilityFactory()); @@ -164,7 +163,6 @@ TEST_F(BrowserAccessibilityTest, TestChildrenChange) { CountedBrowserAccessibility::global_obj_count_ = 0; BrowserAccessibilityManager* manager = BrowserAccessibilityManager::Create( - GetDesktopWindow(), root, NULL, new CountedBrowserAccessibilityFactory()); @@ -257,7 +255,6 @@ TEST_F(BrowserAccessibilityTest, TestChildrenChangeNoLeaks) { CountedBrowserAccessibility::global_obj_count_ = 0; BrowserAccessibilityManager* manager = BrowserAccessibilityManager::Create( - GetDesktopWindow(), root, NULL, new CountedBrowserAccessibilityFactory()); @@ -298,7 +295,7 @@ TEST_F(BrowserAccessibilityTest, TestTextBoundaries) { CountedBrowserAccessibility::global_obj_count_ = 0; BrowserAccessibilityManager* manager = BrowserAccessibilityManager::Create( - GetDesktopWindow(), root, NULL, + root, NULL, new CountedBrowserAccessibilityFactory()); manager->UpdateNodesForTesting(text1); ASSERT_EQ(2, CountedBrowserAccessibility::global_obj_count_); @@ -395,7 +392,7 @@ TEST_F(BrowserAccessibilityTest, TestSimpleHypertext) { CountedBrowserAccessibility::global_obj_count_ = 0; BrowserAccessibilityManager* manager = BrowserAccessibilityManager::Create( - GetDesktopWindow(), root, NULL, + root, NULL, new CountedBrowserAccessibilityFactory()); manager->UpdateNodesForTesting(root, text1, text2); ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_); @@ -482,7 +479,7 @@ TEST_F(BrowserAccessibilityTest, TestComplexHypertext) { CountedBrowserAccessibility::global_obj_count_ = 0; BrowserAccessibilityManager* manager = BrowserAccessibilityManager::Create( - GetDesktopWindow(), root, NULL, + root, NULL, new CountedBrowserAccessibilityFactory()); manager->UpdateNodesForTesting(root, text1, button1, button1_text, @@ -547,4 +544,85 @@ TEST_F(BrowserAccessibilityTest, TestComplexHypertext) { ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_); } +TEST_F(BrowserAccessibilityTest, TestCreateEmptyDocument) { + // Try creating an empty document with busy state. Readonly is + // set automatically. + const int32 busy_state = 1 << AccessibilityNodeData::STATE_BUSY; + const int32 readonly_state = 1 << AccessibilityNodeData::STATE_READONLY; + scoped_ptr<BrowserAccessibilityManager> manager; + manager.reset(new BrowserAccessibilityManagerWin( + GetDesktopWindow(), + NULL, + BrowserAccessibilityManagerWin::GetEmptyDocument(), + NULL, + new CountedBrowserAccessibilityFactory())); + + // Verify the root is as we expect by default. + BrowserAccessibility* root = manager->GetRoot(); + EXPECT_EQ(0, root->renderer_id()); + EXPECT_EQ(AccessibilityNodeData::ROLE_ROOT_WEB_AREA, root->role()); + EXPECT_EQ(busy_state | readonly_state, root->state()); + + // Tree with a child textfield. + AccessibilityNodeData tree1_1; + tree1_1.id = 1; + tree1_1.role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA; + tree1_1.child_ids.push_back(2); + + AccessibilityNodeData tree1_2; + tree1_2.id = 2; + tree1_2.role = AccessibilityNodeData::ROLE_TEXT_FIELD; + + // Process a load complete. + std::vector<AccessibilityHostMsg_NotificationParams> params; + params.push_back(AccessibilityHostMsg_NotificationParams()); + AccessibilityHostMsg_NotificationParams* msg = ¶ms[0]; + msg->notification_type = AccessibilityNotificationLoadComplete; + msg->nodes.push_back(tree1_1); + msg->nodes.push_back(tree1_2); + msg->id = tree1_1.id; + manager->OnAccessibilityNotifications(params); + + // Save for later comparison. + BrowserAccessibility* acc1_2 = manager->GetFromRendererID(2); + + // Verify the root has changed. + EXPECT_NE(root, manager->GetRoot()); + + // And the proper child remains. + EXPECT_EQ(AccessibilityNodeData::ROLE_TEXT_FIELD, acc1_2->role()); + EXPECT_EQ(2, acc1_2->renderer_id()); + + // Tree with a child button. + AccessibilityNodeData tree2_1; + tree2_1.id = 1; + tree2_1.role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA; + tree2_1.child_ids.push_back(3); + + AccessibilityNodeData tree2_2; + tree2_2.id = 3; + tree2_2.role = AccessibilityNodeData::ROLE_BUTTON; + + msg->nodes.clear(); + msg->nodes.push_back(tree2_1); + msg->nodes.push_back(tree2_2); + msg->id = tree2_1.id; + + // Fire another load complete. + manager->OnAccessibilityNotifications(params); + + BrowserAccessibility* acc2_2 = manager->GetFromRendererID(3); + + // Verify the root has changed. + EXPECT_NE(root, manager->GetRoot()); + + // And the new child exists. + EXPECT_EQ(AccessibilityNodeData::ROLE_BUTTON, acc2_2->role()); + EXPECT_EQ(3, acc2_2->renderer_id()); + + // Ensure we properly cleaned up. + manager.reset(); + ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_); +} + } // namespace content diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 475d489..e7416cc 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -13,6 +13,8 @@ #include "base/string_number_conversions.h" #include "cc/compositor_frame.h" #include "cc/compositor_frame_ack.h" +#include "content/browser/accessibility/browser_accessibility_manager.h" +#include "content/browser/accessibility/browser_accessibility_state_impl.h" #include "content/browser/renderer_host/backing_store_aura.h" #include "content/browser/renderer_host/dip_util.h" #include "content/browser/renderer_host/overscroll_controller.h" @@ -62,6 +64,8 @@ #include "ui/gfx/skia_util.h" #if defined(OS_WIN) +#include "content/browser/accessibility/browser_accessibility_manager_win.h" +#include "content/browser/accessibility/browser_accessibility_win.h" #include "ui/base/win/hidden_window.h" #include "ui/gfx/gdi_util.h" #endif @@ -767,10 +771,49 @@ gfx::NativeViewId RenderWidgetHostViewAura::GetNativeViewId() const { } gfx::NativeViewAccessible RenderWidgetHostViewAura::GetNativeViewAccessible() { +#if defined(OS_WIN) + aura::RootWindow* root_window = window_->GetRootWindow(); + if (!root_window) + return static_cast<gfx::NativeViewAccessible>(NULL); + HWND hwnd = root_window->GetAcceleratedWidget(); + + BrowserAccessibilityManager* manager = + GetOrCreateBrowserAccessibilityManager(); + if (manager) + return manager->GetRoot()->ToBrowserAccessibilityWin(); +#endif + NOTIMPLEMENTED(); return static_cast<gfx::NativeViewAccessible>(NULL); } +BrowserAccessibilityManager* +RenderWidgetHostViewAura::GetOrCreateBrowserAccessibilityManager() { + BrowserAccessibilityManager* manager = GetBrowserAccessibilityManager(); + if (manager) + return NULL; + +#if defined(OS_WIN) + aura::RootWindow* root_window = window_->GetRootWindow(); + if (!root_window) + return NULL; + HWND hwnd = root_window->GetAcceleratedWidget(); + + // TODO: this should be the accessible of the parent View, for example + // GetNativeViewAccessible() called on this tab's ContentsContainer. + IAccessible* parent_iaccessible = NULL; + + manager = new BrowserAccessibilityManagerWin( + hwnd, parent_iaccessible, + BrowserAccessibilityManagerWin::GetEmptyDocument(), this); +#else + manager = BrowserAccessibilityManager::Create(AccessibilityNodeData(), this); +#endif + + SetBrowserAccessibilityManager(manager); + return manager; +} + void RenderWidgetHostViewAura::MovePluginWindows( const gfx::Vector2d& scroll_offset, const std::vector<webkit::npapi::WebPluginGeometry>& plugin_window_moves) { @@ -1513,6 +1556,10 @@ void RenderWidgetHostViewAura::SetScrollOffsetPinning( void RenderWidgetHostViewAura::OnAccessibilityNotifications( const std::vector<AccessibilityHostMsg_NotificationParams>& params) { + BrowserAccessibilityManager* manager = + GetOrCreateBrowserAccessibilityManager(); + if (manager) + manager->OnAccessibilityNotifications(params); } gfx::GLSurfaceHandle RenderWidgetHostViewAura::GetCompositingSurface() { @@ -2272,6 +2319,58 @@ void RenderWidgetHostViewAura::OnUpdateVSyncParameters( } //////////////////////////////////////////////////////////////////////////////// +// RenderWidgetHostViewAura, BrowserAccessibilityDelegate implementation: + +void RenderWidgetHostViewAura::SetAccessibilityFocus(int acc_obj_id) { + if (!host_) + return; + + host_->AccessibilitySetFocus(acc_obj_id); +} + +void RenderWidgetHostViewAura::AccessibilityDoDefaultAction(int acc_obj_id) { + if (!host_) + return; + + host_->AccessibilityDoDefaultAction(acc_obj_id); +} + +void RenderWidgetHostViewAura::AccessibilityScrollToMakeVisible( + int acc_obj_id, gfx::Rect subfocus) { + if (!host_) + return; + + host_->AccessibilityScrollToMakeVisible(acc_obj_id, subfocus); +} + +void RenderWidgetHostViewAura::AccessibilityScrollToPoint( + int acc_obj_id, gfx::Point point) { + if (!host_) + return; + + host_->AccessibilityScrollToPoint(acc_obj_id, point); +} + +void RenderWidgetHostViewAura::AccessibilitySetTextSelection( + int acc_obj_id, int start_offset, int end_offset) { + if (!host_) + return; + + host_->AccessibilitySetTextSelection( + acc_obj_id, start_offset, end_offset); +} + +gfx::Point RenderWidgetHostViewAura::GetLastTouchEventLocation() const { + // Only needed for Win 8 non-aura. + return gfx::Point(); +} + +void RenderWidgetHostViewAura::FatalAccessibilityTreeError() { + host_->FatalAccessibilityTreeError(); + SetBrowserAccessibilityManager(NULL); +} + +//////////////////////////////////////////////////////////////////////////////// // RenderWidgetHostViewAura, ImageTransportFactoryObserver implementation: void RenderWidgetHostViewAura::OnLostResources() { diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index 95601ab..5040221 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h @@ -15,6 +15,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" +#include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/renderer_host/image_transport_factory.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/common/content_export.h" @@ -66,6 +67,7 @@ class RenderWidgetHostViewAura public aura::client::ActivationChangeObserver, public aura::client::FocusChangeObserver, public ImageTransportFactoryObserver, + public BrowserAccessibilityDelegate, public base::SupportsWeakPtr<RenderWidgetHostViewAura> { public: // Used to notify whenever the paint-content of the view changes. @@ -295,6 +297,18 @@ class RenderWidgetHostViewAura // Overridden from ImageTransportFactoryObserver: virtual void OnLostResources() OVERRIDE; + // Overridden from BrowserAccessibilityDelegate: + virtual void SetAccessibilityFocus(int acc_obj_id) OVERRIDE; + virtual void AccessibilityDoDefaultAction(int acc_obj_id) OVERRIDE; + virtual void AccessibilityScrollToMakeVisible( + int acc_obj_id, gfx::Rect subfocus) OVERRIDE; + virtual void AccessibilityScrollToPoint( + int acc_obj_id, gfx::Point point) OVERRIDE; + virtual void AccessibilitySetTextSelection( + int acc_obj_id, int start_offset, int end_offset) OVERRIDE; + virtual gfx::Point GetLastTouchEventLocation() const OVERRIDE; + virtual void FatalAccessibilityTreeError() OVERRIDE; + virtual ~RenderWidgetHostViewAura(); void UpdateCursorIfOverSelf(); @@ -376,6 +390,9 @@ class RenderWidgetHostViewAura scoped_ptr<cc::DelegatedFrameData> frame, float device_scale_factor); void SendDelegatedFrameAck(); + + BrowserAccessibilityManager* GetOrCreateBrowserAccessibilityManager(); + #if defined(OS_WIN) // Sets the cutout rects from transient windows. These are rectangles that // windowed NPAPI plugins shouldn't paint in. Overwrites any previous cutout diff --git a/content/browser/renderer_host/render_widget_host_view_gtk.cc b/content/browser/renderer_host/render_widget_host_view_gtk.cc index 6f525f3..7a9ff55 100644 --- a/content/browser/renderer_host/render_widget_host_view_gtk.cc +++ b/content/browser/renderer_host/render_widget_host_view_gtk.cc @@ -29,6 +29,7 @@ #include "base/time.h" #include "base/utf_string_conversions.h" #include "content/browser/accessibility/browser_accessibility_gtk.h" +#include "content/browser/accessibility/browser_accessibility_manager_gtk.h" #include "content/browser/renderer_host/backing_store_gtk.h" #include "content/browser/renderer_host/gtk_im_context_wrapper.h" #include "content/browser/renderer_host/gtk_key_bindings_handler.h" @@ -1585,9 +1586,9 @@ void RenderWidgetHostViewGtk::OnAccessibilityNotifications( if (!browser_accessibility_manager_.get()) { GtkWidget* parent = gtk_widget_get_parent(view_.get()); browser_accessibility_manager_.reset( - BrowserAccessibilityManager::CreateEmptyDocument( + new BrowserAccessibilityManagerGtk( parent, - static_cast<AccessibilityNodeData::State>(0), + BrowserAccessibilityManagerGtk::GetEmptyDocument(), this)); } browser_accessibility_manager_->OnAccessibilityNotifications(params); @@ -1597,9 +1598,9 @@ AtkObject* RenderWidgetHostViewGtk::GetAccessible() { if (!browser_accessibility_manager_.get()) { GtkWidget* parent = gtk_widget_get_parent(view_.get()); browser_accessibility_manager_.reset( - BrowserAccessibilityManager::CreateEmptyDocument( + new BrowserAccessibilityManagerGtk( parent, - static_cast<AccessibilityNodeData::State>(0), + BrowserAccessibilityManagerGtk::GetEmptyDocument(), this)); } BrowserAccessibilityGtk* root = diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index f4131bf..a90526f 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm @@ -23,7 +23,7 @@ #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" #import "content/browser/accessibility/browser_accessibility_cocoa.h" -#include "content/browser/accessibility/browser_accessibility_manager.h" +#include "content/browser/accessibility/browser_accessibility_manager_mac.h" #include "content/browser/plugin_process_host.h" #import "content/browser/renderer_host/accelerated_plugin_view_mac.h" #include "content/browser/renderer_host/backing_store_mac.h" @@ -1620,9 +1620,9 @@ void RenderWidgetHostViewMac::OnAccessibilityNotifications( const std::vector<AccessibilityHostMsg_NotificationParams>& params) { if (!GetBrowserAccessibilityManager()) { SetBrowserAccessibilityManager( - BrowserAccessibilityManager::CreateEmptyDocument( + new BrowserAccessibilityManagerMac( cocoa_view_, - static_cast<AccessibilityNodeData::State>(0), + BrowserAccessibilityManagerMac::GetEmptyDocument(), NULL)); } GetBrowserAccessibilityManager()->OnAccessibilityNotifications(params); diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc index 746672f..c982cc3 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.cc +++ b/content/browser/renderer_host/render_widget_host_view_win.cc @@ -26,6 +26,7 @@ #include "base/win/win_util.h" #include "base/win/windows_version.h" #include "base/win/wrapped_window_proc.h" +#include "content/browser/accessibility/browser_accessibility_manager_win.h" #include "content/browser/accessibility/browser_accessibility_state_impl.h" #include "content/browser/accessibility/browser_accessibility_win.h" #include "content/browser/gpu/gpu_data_manager_impl.h" @@ -515,20 +516,29 @@ RenderWidgetHostViewWin::GetNativeViewAccessible() { NotifyWinEvent(EVENT_SYSTEM_ALERT, m_hWnd, kIdCustom, CHILDID_SELF); } - if (!GetBrowserAccessibilityManager()) { - // Return busy document tree while renderer accessibility tree loads. - AccessibilityNodeData::State busy_state = - static_cast<AccessibilityNodeData::State>( - 1 << AccessibilityNodeData::STATE_BUSY); - SetBrowserAccessibilityManager( - BrowserAccessibilityManager::CreateEmptyDocument( - m_hWnd, busy_state, this)); - } + CreateBrowserAccessibilityManagerIfNeeded(); return GetBrowserAccessibilityManager()->GetRoot()-> ToBrowserAccessibilityWin(); } +void RenderWidgetHostViewWin::CreateBrowserAccessibilityManagerIfNeeded() { + if (GetBrowserAccessibilityManager()) + return; + + HRESULT hr = ::CreateStdAccessibleObject( + m_hWnd, OBJID_WINDOW, IID_IAccessible, + reinterpret_cast<void **>(&window_iaccessible_)); + DCHECK(SUCCEEDED(hr)); + + SetBrowserAccessibilityManager( + new BrowserAccessibilityManagerWin( + m_hWnd, + window_iaccessible_.get(), + BrowserAccessibilityManagerWin::GetEmptyDocument(), + this)); +} + void RenderWidgetHostViewWin::MovePluginWindows( const gfx::Vector2d& scroll_offset, const std::vector<webkit::npapi::WebPluginGeometry>& plugin_window_moves) { @@ -1779,8 +1789,9 @@ LRESULT RenderWidgetHostViewWin::OnMouseEvent(UINT message, WPARAM wparam, } if (message == WM_LBUTTONDOWN && pointer_down_context_ && - GetBrowserAccessibilityManager()) + GetBrowserAccessibilityManager()) { GetBrowserAccessibilityManager()->GotMouseDown(); + } if (message == WM_LBUTTONUP && ui::IsMouseEventFromTouch(message) && base::win::IsMetroProcess()) @@ -2277,13 +2288,7 @@ LRESULT RenderWidgetHostViewWin::OnMoveOrSize( void RenderWidgetHostViewWin::OnAccessibilityNotifications( const std::vector<AccessibilityHostMsg_NotificationParams>& params) { - if (!GetBrowserAccessibilityManager()) { - SetBrowserAccessibilityManager( - BrowserAccessibilityManager::CreateEmptyDocument( - m_hWnd, - static_cast<AccessibilityNodeData::State>(0), - this)); - } + CreateBrowserAccessibilityManagerIfNeeded(); GetBrowserAccessibilityManager()->OnAccessibilityNotifications(params); } diff --git a/content/browser/renderer_host/render_widget_host_view_win.h b/content/browser/renderer_host/render_widget_host_view_win.h index 6f8c236..46df7f6 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.h +++ b/content/browser/renderer_host/render_widget_host_view_win.h @@ -438,6 +438,10 @@ class RenderWidgetHostViewWin // take effect on Vista+. void UpdateInputScopeIfNecessary(ui::TextInputType text_input_type); + // Create a BrowserAccessibilityManager with an empty document if it + // doesn't already exist. + void CreateBrowserAccessibilityManagerIfNeeded(); + // The associated Model. While |this| is being Destroyed, // |render_widget_host_| is NULL and the Windows message loop is run one last // time. Message handlers must check for a NULL |render_widget_host_|. @@ -585,6 +589,9 @@ class RenderWidgetHostViewWin scoped_ptr<ui::GestureRecognizer> gesture_recognizer_; + // The OS-provided default IAccessible instance for our hwnd. + base::win::ScopedComPtr<IAccessible> window_iaccessible_; + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewWin); }; diff --git a/content/content_browser.gypi b/content/content_browser.gypi index c7f6bb8..b82d96e 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -1195,11 +1195,6 @@ '../ui/compositor/compositor.gyp:compositor', ], 'sources/': [ - ['exclude', '^browser/accessibility/accessibility_tree_formatter_win.cc'], - ['exclude', '^browser/accessibility/browser_accessibility_manager_win.cc'], - ['exclude', '^browser/accessibility/browser_accessibility_manager_win.h'], - ['exclude', '^browser/accessibility/browser_accessibility_win.cc'], - ['exclude', '^browser/accessibility/browser_accessibility_win.h'], ['exclude', '^browser/renderer_host/gtk_im_context_wrapper.cc'], ['exclude', '^browser/renderer_host/gtk_im_context_wrapper.h'], ['exclude', '^browser/renderer_host/native_web_keyboard_event_win.cc'], |