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