| OLD | NEW | 
|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "base/scoped_ptr.h" | 5 #include "base/scoped_ptr.h" | 
| 6 #include "base/scoped_comptr_win.h" | 6 #include "base/scoped_comptr_win.h" | 
| 7 #include "chrome/browser/accessibility/browser_accessibility_manager.h" | 7 #include "chrome/browser/accessibility/browser_accessibility_manager_win.h" | 
| 8 #include "chrome/browser/accessibility/browser_accessibility_win.h" | 8 #include "chrome/browser/accessibility/browser_accessibility_win.h" | 
| 9 #include "chrome/common/render_messages_params.h" | 9 #include "chrome/common/render_messages_params.h" | 
| 10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" | 
| 11 | 11 | 
| 12 using webkit_glue::WebAccessibility; | 12 using webkit_glue::WebAccessibility; | 
| 13 | 13 | 
| 14 // Subclass of BrowserAccessibilityWin that counts the number of instances. | 14 // Subclass of BrowserAccessibility that counts the number of instances. | 
| 15 class CountedBrowserAccessibility : public BrowserAccessibilityWin { | 15 class CountedBrowserAccessibilityWin : public BrowserAccessibilityWin { | 
| 16  public: | 16  public: | 
| 17   CountedBrowserAccessibility() { global_obj_count_++; } | 17   CountedBrowserAccessibilityWin() { global_obj_count_++; } | 
| 18   virtual ~CountedBrowserAccessibility() { global_obj_count_--; } | 18   virtual ~CountedBrowserAccessibilityWin() { global_obj_count_--; } | 
| 19   static int global_obj_count_; | 19   static int global_obj_count_; | 
| 20 }; | 20 }; | 
| 21 | 21 | 
| 22 int CountedBrowserAccessibility::global_obj_count_ = 0; | 22 int CountedBrowserAccessibilityWin::global_obj_count_ = 0; | 
| 23 | 23 | 
| 24 // Factory that creates a CountedBrowserAccessibility. | 24 // Factory that creates a CountedBrowserAccessibilityWin. | 
| 25 class CountedBrowserAccessibilityFactory | 25 class CountedBrowserAccessibilityWinFactory | 
| 26     : public BrowserAccessibilityFactory { | 26     : public BrowserAccessibilityWinFactory { | 
| 27  public: | 27  public: | 
| 28   virtual ~CountedBrowserAccessibilityFactory() {} | 28   virtual ~CountedBrowserAccessibilityWinFactory() {} | 
| 29   virtual BrowserAccessibility* Create() { | 29   virtual BrowserAccessibilityWin* Create() { | 
| 30     CComObject<CountedBrowserAccessibility>* instance; | 30     CComObject<CountedBrowserAccessibilityWin>* instance; | 
| 31     HRESULT hr = CComObject<CountedBrowserAccessibility>::CreateInstance( | 31     HRESULT hr = CComObject<CountedBrowserAccessibilityWin>::CreateInstance( | 
| 32         &instance); | 32         &instance); | 
| 33     DCHECK(SUCCEEDED(hr)); | 33     DCHECK(SUCCEEDED(hr)); | 
| 34     instance->AddRef(); | 34     return instance->NewReference(); | 
| 35     return instance; |  | 
| 36   } | 35   } | 
| 37 }; | 36 }; | 
| 38 | 37 | 
| 39 VARIANT CreateI4Variant(LONG value) { | 38 VARIANT CreateI4Variant(LONG value) { | 
| 40   VARIANT variant = {0}; | 39   VARIANT variant = {0}; | 
| 41 | 40 | 
| 42   V_VT(&variant) = VT_I4; | 41   V_VT(&variant) = VT_I4; | 
| 43   V_I4(&variant) = value; | 42   V_I4(&variant) = value; | 
| 44 | 43 | 
| 45   return variant; | 44   return variant; | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 84   root.name = L"Document"; | 83   root.name = L"Document"; | 
| 85   root.role = WebAccessibility::ROLE_DOCUMENT; | 84   root.role = WebAccessibility::ROLE_DOCUMENT; | 
| 86   root.state = 0; | 85   root.state = 0; | 
| 87   root.children.push_back(button); | 86   root.children.push_back(button); | 
| 88   root.children.push_back(checkbox); | 87   root.children.push_back(checkbox); | 
| 89 | 88 | 
| 90   // Construct a BrowserAccessibilityManager with this WebAccessibility tree | 89   // Construct a BrowserAccessibilityManager with this WebAccessibility tree | 
| 91   // and a factory for an instance-counting BrowserAccessibility, and ensure | 90   // and a factory for an instance-counting BrowserAccessibility, and ensure | 
| 92   // that exactly 3 instances were created. Note that the manager takes | 91   // that exactly 3 instances were created. Note that the manager takes | 
| 93   // ownership of the factory. | 92   // ownership of the factory. | 
| 94   CountedBrowserAccessibility::global_obj_count_ = 0; | 93   CountedBrowserAccessibilityWin::global_obj_count_ = 0; | 
|  | 94   // TODO: Use BrowserAccessibilityManager::Create instead of new below. | 
| 95   BrowserAccessibilityManager* manager = | 95   BrowserAccessibilityManager* manager = | 
| 96       BrowserAccessibilityManager::Create( | 96       new BrowserAccessibilityManagerWin( | 
| 97           GetDesktopWindow(), | 97           GetDesktopWindow(), root, NULL, | 
| 98           root, | 98           new CountedBrowserAccessibilityWinFactory()); | 
| 99           NULL, | 99   ASSERT_EQ(3, CountedBrowserAccessibilityWin::global_obj_count_); | 
| 100           new CountedBrowserAccessibilityFactory()); |  | 
| 101   ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_); |  | 
| 102 | 100 | 
| 103   // Delete the manager and test that all 3 instances are deleted. | 101   // Delete the manager and test that all 3 instances are deleted. | 
| 104   delete manager; | 102   delete manager; | 
| 105   ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_); | 103   ASSERT_EQ(0, CountedBrowserAccessibilityWin::global_obj_count_); | 
| 106 | 104 | 
| 107   // Construct a manager again, and this time use the IAccessible interface | 105   // Construct a manager again, and this time use the IAccessible interface | 
| 108   // to get new references to two of the three nodes in the tree. | 106   // to get new references to two of the three nodes in the tree. | 
| 109   manager = | 107   manager = new BrowserAccessibilityManagerWin( | 
| 110       BrowserAccessibilityManager::Create( | 108       GetDesktopWindow(), root, NULL, | 
| 111           GetDesktopWindow(), | 109       new CountedBrowserAccessibilityWinFactory()); | 
| 112           root, | 110   ASSERT_EQ(3, CountedBrowserAccessibilityWin::global_obj_count_); | 
| 113           NULL, | 111   IAccessible* root_accessible = manager->GetRootAccessible(); | 
| 114           new CountedBrowserAccessibilityFactory()); |  | 
| 115   ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_); |  | 
| 116   IAccessible* root_accessible = |  | 
| 117       manager->GetRoot()->toBrowserAccessibilityWin(); |  | 
| 118   IDispatch* root_iaccessible = NULL; | 112   IDispatch* root_iaccessible = NULL; | 
| 119   IDispatch* child1_iaccessible = NULL; | 113   IDispatch* child1_iaccessible = NULL; | 
| 120   VARIANT var_child; | 114   VARIANT var_child; | 
| 121   var_child.vt = VT_I4; | 115   var_child.vt = VT_I4; | 
| 122   var_child.lVal = CHILDID_SELF; | 116   var_child.lVal = CHILDID_SELF; | 
| 123   HRESULT hr = root_accessible->get_accChild(var_child, &root_iaccessible); | 117   HRESULT hr = root_accessible->get_accChild(var_child, &root_iaccessible); | 
| 124   ASSERT_EQ(S_OK, hr); | 118   ASSERT_EQ(S_OK, hr); | 
| 125   var_child.lVal = 1; | 119   var_child.lVal = 1; | 
| 126   hr = root_accessible->get_accChild(var_child, &child1_iaccessible); | 120   hr = root_accessible->get_accChild(var_child, &child1_iaccessible); | 
| 127   ASSERT_EQ(S_OK, hr); | 121   ASSERT_EQ(S_OK, hr); | 
| 128 | 122 | 
| 129   // Now delete the manager, and only one of the three nodes in the tree | 123   // Now delete the manager, and only one of the three nodes in the tree | 
| 130   // should be released. | 124   // should be released. | 
| 131   delete manager; | 125   delete manager; | 
| 132   ASSERT_EQ(2, CountedBrowserAccessibility::global_obj_count_); | 126   ASSERT_EQ(2, CountedBrowserAccessibilityWin::global_obj_count_); | 
| 133 | 127 | 
| 134   // Release each of our references and make sure that each one results in | 128   // Release each of our references and make sure that each one results in | 
| 135   // the instance being deleted as its reference count hits zero. | 129   // the instance being deleted as its reference count hits zero. | 
| 136   root_iaccessible->Release(); | 130   root_iaccessible->Release(); | 
| 137   ASSERT_EQ(1, CountedBrowserAccessibility::global_obj_count_); | 131   ASSERT_EQ(1, CountedBrowserAccessibilityWin::global_obj_count_); | 
| 138   child1_iaccessible->Release(); | 132   child1_iaccessible->Release(); | 
| 139   ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_); | 133   ASSERT_EQ(0, CountedBrowserAccessibilityWin::global_obj_count_); | 
| 140 } | 134 } | 
| 141 | 135 | 
| 142 TEST_F(BrowserAccessibilityTest, TestChildrenChange) { | 136 TEST_F(BrowserAccessibilityTest, TestChildrenChange) { | 
| 143   // Create WebAccessibility objects for a simple document tree, | 137   // Create WebAccessibility objects for a simple document tree, | 
| 144   // representing the accessibility information used to initialize | 138   // representing the accessibility information used to initialize | 
| 145   // BrowserAccessibilityManager. | 139   // BrowserAccessibilityManager. | 
| 146   WebAccessibility text; | 140   WebAccessibility text; | 
| 147   text.id = 2; | 141   text.id = 2; | 
| 148   text.role = WebAccessibility::ROLE_STATIC_TEXT; | 142   text.role = WebAccessibility::ROLE_STATIC_TEXT; | 
| 149   text.value = L"old text"; | 143   text.value = L"old text"; | 
| 150   text.state = 0; | 144   text.state = 0; | 
| 151 | 145 | 
| 152   WebAccessibility root; | 146   WebAccessibility root; | 
| 153   root.id = 1; | 147   root.id = 1; | 
| 154   root.name = L"Document"; | 148   root.name = L"Document"; | 
| 155   root.role = WebAccessibility::ROLE_DOCUMENT; | 149   root.role = WebAccessibility::ROLE_DOCUMENT; | 
| 156   root.state = 0; | 150   root.state = 0; | 
| 157   root.children.push_back(text); | 151   root.children.push_back(text); | 
| 158 | 152 | 
| 159   // Construct a BrowserAccessibilityManager with this WebAccessibility tree | 153   // Construct a BrowserAccessibilityManager with this WebAccessibility tree | 
| 160   // and a factory for an instance-counting BrowserAccessibility. | 154   // and a factory for an instance-counting BrowserAccessibility. | 
| 161   CountedBrowserAccessibility::global_obj_count_ = 0; | 155   CountedBrowserAccessibilityWin::global_obj_count_ = 0; | 
| 162   BrowserAccessibilityManager* manager = | 156   BrowserAccessibilityManager* manager = | 
| 163       BrowserAccessibilityManager::Create( | 157       new BrowserAccessibilityManagerWin( | 
| 164           GetDesktopWindow(), | 158           GetDesktopWindow(), root, NULL, | 
| 165           root, | 159           new CountedBrowserAccessibilityWinFactory()); | 
| 166           NULL, |  | 
| 167           new CountedBrowserAccessibilityFactory()); |  | 
| 168 | 160 | 
| 169   // Query for the text IAccessible and verify that it returns "old text" as its | 161   // Query for the text IAccessible and verify that it returns "old text" as its | 
| 170   // value. | 162   // value. | 
| 171   ScopedComPtr<IDispatch> text_dispatch; | 163   ScopedComPtr<IDispatch> text_dispatch; | 
| 172   HRESULT hr = manager->GetRoot()->toBrowserAccessibilityWin()->get_accChild( | 164   HRESULT hr = manager->GetRootAccessible()->get_accChild( | 
| 173       CreateI4Variant(1), text_dispatch.Receive()); | 165       CreateI4Variant(1), text_dispatch.Receive()); | 
| 174   ASSERT_EQ(S_OK, hr); | 166   ASSERT_EQ(S_OK, hr); | 
| 175 | 167 | 
| 176   ScopedComPtr<IAccessible> text_accessible; | 168   ScopedComPtr<IAccessible> text_accessible; | 
| 177   hr = text_dispatch.QueryInterface(text_accessible.Receive()); | 169   hr = text_dispatch.QueryInterface(text_accessible.Receive()); | 
| 178   ASSERT_EQ(S_OK, hr); | 170   ASSERT_EQ(S_OK, hr); | 
| 179 | 171 | 
| 180   CComBSTR value; | 172   CComBSTR value; | 
| 181   hr = text_accessible->get_accValue(CreateI4Variant(CHILDID_SELF), &value); | 173   hr = text_accessible->get_accValue(CreateI4Variant(CHILDID_SELF), &value); | 
| 182   ASSERT_EQ(S_OK, hr); | 174   ASSERT_EQ(S_OK, hr); | 
| 183   EXPECT_STREQ(L"old text", value.m_str); | 175   EXPECT_STREQ(L"old text", value.m_str); | 
| 184 | 176 | 
| 185   text_dispatch.Release(); | 177   text_dispatch.Release(); | 
| 186   text_accessible.Release(); | 178   text_accessible.Release(); | 
| 187 | 179 | 
| 188   // Notify the BrowserAccessibilityManager that the text child has changed. | 180   // Notify the BrowserAccessibilityManager that the text child has changed. | 
| 189   text.value = L"new text"; | 181   text.value = L"new text"; | 
| 190   ViewHostMsg_AccessibilityNotification_Params param; | 182   ViewHostMsg_AccessibilityNotification_Params param; | 
| 191   param.notification_type = | 183   param.notification_type = | 
| 192       ViewHostMsg_AccessibilityNotification_Params:: | 184       ViewHostMsg_AccessibilityNotification_Params:: | 
| 193         NOTIFICATION_TYPE_CHILDREN_CHANGED; | 185         NOTIFICATION_TYPE_CHILDREN_CHANGED; | 
| 194   param.acc_obj = text; | 186   param.acc_obj = text; | 
| 195   std::vector<ViewHostMsg_AccessibilityNotification_Params> notifications; | 187   std::vector<ViewHostMsg_AccessibilityNotification_Params> notifications; | 
| 196   notifications.push_back(param); | 188   notifications.push_back(param); | 
| 197   manager->OnAccessibilityNotifications(notifications); | 189   manager->OnAccessibilityNotifications(notifications); | 
| 198 | 190 | 
| 199   // Query for the text IAccessible and verify that it now returns "new text" | 191   // Query for the text IAccessible and verify that it now returns "new text" | 
| 200   // as its value. | 192   // as its value. | 
| 201   hr = manager->GetRoot()->toBrowserAccessibilityWin()->get_accChild( | 193   hr = manager->GetRootAccessible()->get_accChild( | 
| 202       CreateI4Variant(1), | 194       CreateI4Variant(1), | 
| 203       text_dispatch.Receive()); | 195       text_dispatch.Receive()); | 
| 204   ASSERT_EQ(S_OK, hr); | 196   ASSERT_EQ(S_OK, hr); | 
| 205 | 197 | 
| 206   hr = text_dispatch.QueryInterface(text_accessible.Receive()); | 198   hr = text_dispatch.QueryInterface(text_accessible.Receive()); | 
| 207   ASSERT_EQ(S_OK, hr); | 199   ASSERT_EQ(S_OK, hr); | 
| 208 | 200 | 
| 209   hr = text_accessible->get_accValue(CreateI4Variant(CHILDID_SELF), &value); | 201   hr = text_accessible->get_accValue(CreateI4Variant(CHILDID_SELF), &value); | 
| 210   ASSERT_EQ(S_OK, hr); | 202   ASSERT_EQ(S_OK, hr); | 
| 211   EXPECT_STREQ(L"new text", value.m_str); | 203   EXPECT_STREQ(L"new text", value.m_str); | 
| 212 | 204 | 
| 213   text_dispatch.Release(); | 205   text_dispatch.Release(); | 
| 214   text_accessible.Release(); | 206   text_accessible.Release(); | 
| 215 | 207 | 
| 216   // Delete the manager and test that all BrowserAccessibility instances are | 208   // Delete the manager and test that all BrowserAccessibility instances are | 
| 217   // deleted. | 209   // deleted. | 
| 218   delete manager; | 210   delete manager; | 
| 219   ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_); | 211   ASSERT_EQ(0, CountedBrowserAccessibilityWin::global_obj_count_); | 
| 220 } | 212 } | 
| 221 | 213 | 
| 222 TEST_F(BrowserAccessibilityTest, TestChildrenChangeNoLeaks) { | 214 TEST_F(BrowserAccessibilityTest, TestChildrenChangeNoLeaks) { | 
| 223   // Create WebAccessibility objects for a simple document tree, | 215   // Create WebAccessibility objects for a simple document tree, | 
| 224   // representing the accessibility information used to initialize | 216   // representing the accessibility information used to initialize | 
| 225   // BrowserAccessibilityManager. | 217   // BrowserAccessibilityManager. | 
| 226   WebAccessibility text; | 218   WebAccessibility text; | 
| 227   text.id = 3; | 219   text.id = 3; | 
| 228   text.role = WebAccessibility::ROLE_STATIC_TEXT; | 220   text.role = WebAccessibility::ROLE_STATIC_TEXT; | 
| 229   text.state = 0; | 221   text.state = 0; | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 240   WebAccessibility root; | 232   WebAccessibility root; | 
| 241   root.id = 1; | 233   root.id = 1; | 
| 242   root.role = WebAccessibility::ROLE_DOCUMENT; | 234   root.role = WebAccessibility::ROLE_DOCUMENT; | 
| 243   root.state = 0; | 235   root.state = 0; | 
| 244   root.children.push_back(div); | 236   root.children.push_back(div); | 
| 245 | 237 | 
| 246   // Construct a BrowserAccessibilityManager with this WebAccessibility tree | 238   // Construct a BrowserAccessibilityManager with this WebAccessibility tree | 
| 247   // and a factory for an instance-counting BrowserAccessibility and ensure | 239   // and a factory for an instance-counting BrowserAccessibility and ensure | 
| 248   // that exactly 4 instances were created. Note that the manager takes | 240   // that exactly 4 instances were created. Note that the manager takes | 
| 249   // ownership of the factory. | 241   // ownership of the factory. | 
| 250   CountedBrowserAccessibility::global_obj_count_ = 0; | 242   CountedBrowserAccessibilityWin::global_obj_count_ = 0; | 
| 251   BrowserAccessibilityManager* manager = | 243   BrowserAccessibilityManager* manager = | 
| 252       BrowserAccessibilityManager::Create( | 244       new BrowserAccessibilityManagerWin( | 
| 253           GetDesktopWindow(), | 245           GetDesktopWindow(), root, NULL, | 
| 254           root, | 246           new CountedBrowserAccessibilityWinFactory()); | 
| 255           NULL, | 247   ASSERT_EQ(4, CountedBrowserAccessibilityWin::global_obj_count_); | 
| 256           new CountedBrowserAccessibilityFactory()); |  | 
| 257   ASSERT_EQ(4, CountedBrowserAccessibility::global_obj_count_); |  | 
| 258 | 248 | 
| 259   // Notify the BrowserAccessibilityManager that the div node and its children | 249   // Notify the BrowserAccessibilityManager that the div node and its children | 
| 260   // were removed and ensure that only one BrowserAccessibility instance exists. | 250   // were removed and ensure that only one BrowserAccessibility instance exists. | 
| 261   root.children.clear(); | 251   root.children.clear(); | 
| 262   ViewHostMsg_AccessibilityNotification_Params param; | 252   ViewHostMsg_AccessibilityNotification_Params param; | 
| 263   param.notification_type = | 253   param.notification_type = | 
| 264       ViewHostMsg_AccessibilityNotification_Params:: | 254       ViewHostMsg_AccessibilityNotification_Params:: | 
| 265         NOTIFICATION_TYPE_CHILDREN_CHANGED; | 255         NOTIFICATION_TYPE_CHILDREN_CHANGED; | 
| 266   param.acc_obj = root; | 256   param.acc_obj = root; | 
| 267   std::vector<ViewHostMsg_AccessibilityNotification_Params> notifications; | 257   std::vector<ViewHostMsg_AccessibilityNotification_Params> notifications; | 
| 268   notifications.push_back(param); | 258   notifications.push_back(param); | 
| 269   manager->OnAccessibilityNotifications(notifications); | 259   manager->OnAccessibilityNotifications(notifications); | 
| 270   ASSERT_EQ(1, CountedBrowserAccessibility::global_obj_count_); | 260   ASSERT_EQ(1, CountedBrowserAccessibilityWin::global_obj_count_); | 
| 271 | 261 | 
| 272   // Delete the manager and test that all BrowserAccessibility instances are | 262   // Delete the manager and test that all BrowserAccessibility instances are | 
| 273   // deleted. | 263   // deleted. | 
| 274   delete manager; | 264   delete manager; | 
| 275   ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_); | 265   ASSERT_EQ(0, CountedBrowserAccessibilityWin::global_obj_count_); | 
| 276 } | 266 } | 
| OLD | NEW | 
|---|