OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/accessibility/browser_accessibility_win.h" | 5 #include "content/browser/accessibility/browser_accessibility_win.h" |
6 | 6 |
7 #include <objbase.h> | 7 #include <objbase.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
11 #include <utility> | 11 #include <utility> |
12 | 12 |
13 #include "base/macros.h" | 13 #include "base/macros.h" |
14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
15 #include "base/win/scoped_bstr.h" | 15 #include "base/win/scoped_bstr.h" |
16 #include "base/win/scoped_comptr.h" | 16 #include "base/win/scoped_comptr.h" |
17 #include "base/win/scoped_variant.h" | 17 #include "base/win/scoped_variant.h" |
18 #include "content/browser/accessibility/browser_accessibility_manager.h" | 18 #include "content/browser/accessibility/browser_accessibility_manager.h" |
19 #include "content/browser/accessibility/browser_accessibility_manager_win.h" | 19 #include "content/browser/accessibility/browser_accessibility_manager_win.h" |
20 #include "content/browser/accessibility/browser_accessibility_state_impl.h" | 20 #include "content/browser/accessibility/browser_accessibility_state_impl.h" |
21 #include "content/browser/renderer_host/legacy_render_widget_host_win.h" | 21 #include "content/browser/renderer_host/legacy_render_widget_host_win.h" |
22 #include "content/common/accessibility_messages.h" | 22 #include "content/common/accessibility_messages.h" |
23 #include "content/public/test/test_browser_thread_bundle.h" | 23 #include "content/public/test/test_browser_thread_bundle.h" |
24 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
| 25 #include "ui/accessibility/platform/ax_platform_node_win.h" |
25 #include "ui/base/win/atl_module.h" | 26 #include "ui/base/win/atl_module.h" |
26 | 27 |
27 namespace content { | 28 namespace content { |
28 | 29 |
29 // BrowserAccessibilityTest --------------------------------------------------- | 30 // BrowserAccessibilityTest --------------------------------------------------- |
30 | 31 |
31 class BrowserAccessibilityTest : public testing::Test { | 32 class BrowserAccessibilityTest : public testing::Test { |
32 public: | 33 public: |
33 BrowserAccessibilityTest(); | 34 BrowserAccessibilityTest(); |
34 ~BrowserAccessibilityTest() override; | 35 ~BrowserAccessibilityTest() override; |
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 EXPECT_NE(root, manager->GetRoot()); | 698 EXPECT_NE(root, manager->GetRoot()); |
698 | 699 |
699 // And the new child exists. | 700 // And the new child exists. |
700 EXPECT_EQ(ui::AX_ROLE_BUTTON, acc2_2->GetRole()); | 701 EXPECT_EQ(ui::AX_ROLE_BUTTON, acc2_2->GetRole()); |
701 EXPECT_EQ(3, acc2_2->GetId()); | 702 EXPECT_EQ(3, acc2_2->GetId()); |
702 | 703 |
703 // Ensure we properly cleaned up. | 704 // Ensure we properly cleaned up. |
704 manager.reset(); | 705 manager.reset(); |
705 } | 706 } |
706 | 707 |
| 708 int32_t GetUniqueId(BrowserAccessibility* accessibility) { |
| 709 BrowserAccessibilityWin* win_root = ToBrowserAccessibilityWin(accessibility); |
| 710 return win_root->GetCOM()->unique_id(); |
| 711 } |
| 712 |
707 // This is a regression test for a bug where the initial empty document | 713 // This is a regression test for a bug where the initial empty document |
708 // loaded by a BrowserAccessibilityManagerWin couldn't be looked up by | 714 // loaded by a BrowserAccessibilityManagerWin couldn't be looked up by |
709 // its UniqueIDWin, because the AX Tree was loaded in | 715 // its UniqueIDWin, because the AX Tree was loaded in |
710 // BrowserAccessibilityManager code before BrowserAccessibilityManagerWin | 716 // BrowserAccessibilityManager code before BrowserAccessibilityManagerWin |
711 // was initialized. | 717 // was initialized. |
712 TEST_F(BrowserAccessibilityTest, EmptyDocHasUniqueIdWin) { | 718 TEST_F(BrowserAccessibilityTest, EmptyDocHasUniqueIdWin) { |
713 std::unique_ptr<BrowserAccessibilityManagerWin> manager( | 719 std::unique_ptr<BrowserAccessibilityManagerWin> manager( |
714 new BrowserAccessibilityManagerWin( | 720 new BrowserAccessibilityManagerWin( |
715 BrowserAccessibilityManagerWin::GetEmptyDocument(), nullptr, | 721 BrowserAccessibilityManagerWin::GetEmptyDocument(), nullptr, |
716 new BrowserAccessibilityFactory())); | 722 new BrowserAccessibilityFactory())); |
717 | 723 |
718 // Verify the root is as we expect by default. | 724 // Verify the root is as we expect by default. |
719 BrowserAccessibility* root = manager->GetRoot(); | 725 BrowserAccessibility* root = manager->GetRoot(); |
720 EXPECT_EQ(0, root->GetId()); | 726 EXPECT_EQ(0, root->GetId()); |
721 EXPECT_EQ(ui::AX_ROLE_ROOT_WEB_AREA, root->GetRole()); | 727 EXPECT_EQ(ui::AX_ROLE_ROOT_WEB_AREA, root->GetRole()); |
722 EXPECT_EQ(1 << ui::AX_STATE_BUSY, root->GetState()); | 728 EXPECT_EQ(1 << ui::AX_STATE_BUSY, root->GetState()); |
723 | 729 |
724 int32_t unique_id = ToBrowserAccessibilityWin(root)->unique_id(); | 730 BrowserAccessibilityWin* win_root = ToBrowserAccessibilityWin(root); |
725 ASSERT_EQ(root, BrowserAccessibility::GetFromUniqueID(unique_id)); | 731 |
| 732 ui::AXPlatformNode* node = static_cast<ui::AXPlatformNode*>( |
| 733 ui::AXPlatformNodeWin::GetFromUniqueId(GetUniqueId(win_root))); |
| 734 |
| 735 ui::AXPlatformNode* other_node = |
| 736 static_cast<ui::AXPlatformNode*>(win_root->GetCOM()); |
| 737 ASSERT_EQ(node, other_node); |
726 } | 738 } |
727 | 739 |
728 TEST_F(BrowserAccessibilityTest, TestIA2Attributes) { | 740 TEST_F(BrowserAccessibilityTest, TestIA2Attributes) { |
729 ui::AXNodeData pseudo_before; | 741 ui::AXNodeData pseudo_before; |
730 pseudo_before.id = 2; | 742 pseudo_before.id = 2; |
731 pseudo_before.role = ui::AX_ROLE_GENERIC_CONTAINER; | 743 pseudo_before.role = ui::AX_ROLE_GENERIC_CONTAINER; |
732 pseudo_before.AddStringAttribute(ui::AX_ATTR_HTML_TAG, "<pseudo:before>"); | 744 pseudo_before.AddStringAttribute(ui::AX_ATTR_HTML_TAG, "<pseudo:before>"); |
733 pseudo_before.AddStringAttribute(ui::AX_ATTR_DISPLAY, "none"); | 745 pseudo_before.AddStringAttribute(ui::AX_ATTR_DISPLAY, "none"); |
734 | 746 |
735 ui::AXNodeData checkbox; | 747 ui::AXNodeData checkbox; |
(...skipping 1434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2170 ui::AXNodeData child_node; | 2182 ui::AXNodeData child_node; |
2171 child_node.id = 2; | 2183 child_node.id = 2; |
2172 root_node.child_ids.push_back(2); | 2184 root_node.child_ids.push_back(2); |
2173 | 2185 |
2174 std::unique_ptr<BrowserAccessibilityManagerWin> manager( | 2186 std::unique_ptr<BrowserAccessibilityManagerWin> manager( |
2175 new BrowserAccessibilityManagerWin( | 2187 new BrowserAccessibilityManagerWin( |
2176 MakeAXTreeUpdate(root_node, child_node), nullptr, | 2188 MakeAXTreeUpdate(root_node, child_node), nullptr, |
2177 new BrowserAccessibilityFactory())); | 2189 new BrowserAccessibilityFactory())); |
2178 | 2190 |
2179 BrowserAccessibility* root = manager->GetRoot(); | 2191 BrowserAccessibility* root = manager->GetRoot(); |
2180 int32_t root_unique_id = root->unique_id(); | 2192 int32_t root_unique_id = GetUniqueId(root); |
2181 BrowserAccessibility* child = root->PlatformGetChild(0); | 2193 BrowserAccessibility* child = root->PlatformGetChild(0); |
2182 int32_t child_unique_id = child->unique_id(); | 2194 int32_t child_unique_id = GetUniqueId(child); |
2183 | 2195 |
2184 // Now destroy that original tree and create a new tree. | 2196 // Now destroy that original tree and create a new tree. |
2185 manager.reset(new BrowserAccessibilityManagerWin( | 2197 manager.reset(new BrowserAccessibilityManagerWin( |
2186 MakeAXTreeUpdate(root_node, child_node), nullptr, | 2198 MakeAXTreeUpdate(root_node, child_node), nullptr, |
2187 new BrowserAccessibilityFactory())); | 2199 new BrowserAccessibilityFactory())); |
2188 root = manager->GetRoot(); | 2200 root = manager->GetRoot(); |
2189 int32_t root_unique_id_2 = root->unique_id(); | 2201 int32_t root_unique_id_2 = GetUniqueId(root); |
2190 child = root->PlatformGetChild(0); | 2202 child = root->PlatformGetChild(0); |
2191 int32_t child_unique_id_2 = child->unique_id(); | 2203 int32_t child_unique_id_2 = GetUniqueId(child); |
2192 | 2204 |
2193 // The nodes in the new tree should not have the same ids. | 2205 // The nodes in the new tree should not have the same ids. |
2194 EXPECT_NE(root_unique_id, root_unique_id_2); | 2206 EXPECT_NE(root_unique_id, root_unique_id_2); |
2195 EXPECT_NE(child_unique_id, child_unique_id_2); | 2207 EXPECT_NE(child_unique_id, child_unique_id_2); |
2196 | 2208 |
2197 // Trying to access the unique IDs of the old, deleted objects should fail. | 2209 // Trying to access the unique IDs of the old, deleted objects should fail. |
2198 base::win::ScopedVariant old_root_variant(-root_unique_id); | 2210 base::win::ScopedVariant old_root_variant(-root_unique_id); |
2199 base::win::ScopedComPtr<IDispatch> old_root_dispatch; | 2211 base::win::ScopedComPtr<IDispatch> old_root_dispatch; |
2200 HRESULT hr = ToBrowserAccessibilityWin(root)->GetCOM()->get_accChild( | 2212 HRESULT hr = ToBrowserAccessibilityWin(root)->GetCOM()->get_accChild( |
2201 old_root_variant, old_root_dispatch.GetAddressOf()); | 2213 old_root_variant, old_root_dispatch.GetAddressOf()); |
(...skipping 29 matching lines...) Expand all Loading... |
2231 root_node.child_ids.push_back(2); | 2243 root_node.child_ids.push_back(2); |
2232 | 2244 |
2233 std::unique_ptr<BrowserAccessibilityManagerWin> manager( | 2245 std::unique_ptr<BrowserAccessibilityManagerWin> manager( |
2234 new BrowserAccessibilityManagerWin( | 2246 new BrowserAccessibilityManagerWin( |
2235 MakeAXTreeUpdate(root_node, child_node), nullptr, | 2247 MakeAXTreeUpdate(root_node, child_node), nullptr, |
2236 new BrowserAccessibilityFactory())); | 2248 new BrowserAccessibilityFactory())); |
2237 | 2249 |
2238 BrowserAccessibility* root = manager->GetRoot(); | 2250 BrowserAccessibility* root = manager->GetRoot(); |
2239 BrowserAccessibility* child = root->PlatformGetChild(0); | 2251 BrowserAccessibility* child = root->PlatformGetChild(0); |
2240 | 2252 |
2241 base::win::ScopedVariant root_unique_id_variant(-root->unique_id()); | 2253 base::win::ScopedVariant root_unique_id_variant(-GetUniqueId(root)); |
2242 base::win::ScopedComPtr<IDispatch> result; | 2254 base::win::ScopedComPtr<IDispatch> result; |
2243 EXPECT_EQ(E_INVALIDARG, | 2255 EXPECT_EQ(E_INVALIDARG, |
2244 ToBrowserAccessibilityWin(child)->GetCOM()->get_accChild( | 2256 ToBrowserAccessibilityWin(child)->GetCOM()->get_accChild( |
2245 root_unique_id_variant, result.GetAddressOf())); | 2257 root_unique_id_variant, result.GetAddressOf())); |
2246 | 2258 |
2247 base::win::ScopedVariant child_unique_id_variant(-child->unique_id()); | 2259 base::win::ScopedVariant child_unique_id_variant(-GetUniqueId(child)); |
2248 EXPECT_EQ(S_OK, ToBrowserAccessibilityWin(root)->GetCOM()->get_accChild( | 2260 EXPECT_EQ(S_OK, ToBrowserAccessibilityWin(root)->GetCOM()->get_accChild( |
2249 child_unique_id_variant, result.GetAddressOf())); | 2261 child_unique_id_variant, result.GetAddressOf())); |
2250 } | 2262 } |
2251 | 2263 |
2252 TEST_F(BrowserAccessibilityTest, TestIAccessible2Relations) { | 2264 TEST_F(BrowserAccessibilityTest, TestIAccessible2Relations) { |
2253 ui::AXNodeData root; | 2265 ui::AXNodeData root; |
2254 root.id = 1; | 2266 root.id = 1; |
2255 root.role = ui::AX_ROLE_ROOT_WEB_AREA; | 2267 root.role = ui::AX_ROLE_ROOT_WEB_AREA; |
2256 // Reflexive relations should be ignored. | 2268 // Reflexive relations should be ignored. |
2257 std::vector<int32_t> describedby_ids = {1, 2, 3}; | 2269 std::vector<int32_t> describedby_ids = {1, 2, 3}; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2301 EXPECT_EQ(L"describedBy", base::string16(relation_type)); | 2313 EXPECT_EQ(L"describedBy", base::string16(relation_type)); |
2302 relation_type.Reset(); | 2314 relation_type.Reset(); |
2303 | 2315 |
2304 EXPECT_HRESULT_SUCCEEDED(describedby_relation->get_nTargets(&n_targets)); | 2316 EXPECT_HRESULT_SUCCEEDED(describedby_relation->get_nTargets(&n_targets)); |
2305 EXPECT_EQ(2, n_targets); | 2317 EXPECT_EQ(2, n_targets); |
2306 | 2318 |
2307 EXPECT_HRESULT_SUCCEEDED( | 2319 EXPECT_HRESULT_SUCCEEDED( |
2308 describedby_relation->get_target(0, target.GetAddressOf())); | 2320 describedby_relation->get_target(0, target.GetAddressOf())); |
2309 target.CopyTo(ax_target.GetAddressOf()); | 2321 target.CopyTo(ax_target.GetAddressOf()); |
2310 EXPECT_HRESULT_SUCCEEDED(ax_target->get_uniqueID(&unique_id)); | 2322 EXPECT_HRESULT_SUCCEEDED(ax_target->get_uniqueID(&unique_id)); |
2311 EXPECT_EQ(-ax_child1->unique_id(), unique_id); | 2323 EXPECT_EQ(-GetUniqueId(ax_child1), unique_id); |
2312 ax_target.Reset(); | 2324 ax_target.Reset(); |
2313 target.Reset(); | 2325 target.Reset(); |
2314 | 2326 |
2315 EXPECT_HRESULT_SUCCEEDED( | 2327 EXPECT_HRESULT_SUCCEEDED( |
2316 describedby_relation->get_target(1, target.GetAddressOf())); | 2328 describedby_relation->get_target(1, target.GetAddressOf())); |
2317 target.CopyTo(ax_target.GetAddressOf()); | 2329 target.CopyTo(ax_target.GetAddressOf()); |
2318 EXPECT_HRESULT_SUCCEEDED(ax_target->get_uniqueID(&unique_id)); | 2330 EXPECT_HRESULT_SUCCEEDED(ax_target->get_uniqueID(&unique_id)); |
2319 EXPECT_EQ(-ax_child2->unique_id(), unique_id); | 2331 EXPECT_EQ(-GetUniqueId(ax_child2), unique_id); |
2320 ax_target.Reset(); | 2332 ax_target.Reset(); |
2321 target.Reset(); | 2333 target.Reset(); |
2322 describedby_relation.Reset(); | 2334 describedby_relation.Reset(); |
2323 | 2335 |
2324 // Test the reverse relations. | 2336 // Test the reverse relations. |
2325 EXPECT_HRESULT_SUCCEEDED(ax_child1->GetCOM()->get_nRelations(&n_relations)); | 2337 EXPECT_HRESULT_SUCCEEDED(ax_child1->GetCOM()->get_nRelations(&n_relations)); |
2326 EXPECT_EQ(1, n_relations); | 2338 EXPECT_EQ(1, n_relations); |
2327 | 2339 |
2328 EXPECT_HRESULT_SUCCEEDED(ax_child1->GetCOM()->get_relation( | 2340 EXPECT_HRESULT_SUCCEEDED(ax_child1->GetCOM()->get_relation( |
2329 0, description_for_relation.GetAddressOf())); | 2341 0, description_for_relation.GetAddressOf())); |
2330 EXPECT_HRESULT_SUCCEEDED( | 2342 EXPECT_HRESULT_SUCCEEDED( |
2331 description_for_relation->get_relationType(relation_type.Receive())); | 2343 description_for_relation->get_relationType(relation_type.Receive())); |
2332 EXPECT_EQ(L"descriptionFor", base::string16(relation_type)); | 2344 EXPECT_EQ(L"descriptionFor", base::string16(relation_type)); |
2333 relation_type.Reset(); | 2345 relation_type.Reset(); |
2334 | 2346 |
2335 EXPECT_HRESULT_SUCCEEDED(description_for_relation->get_nTargets(&n_targets)); | 2347 EXPECT_HRESULT_SUCCEEDED(description_for_relation->get_nTargets(&n_targets)); |
2336 EXPECT_EQ(1, n_targets); | 2348 EXPECT_EQ(1, n_targets); |
2337 | 2349 |
2338 EXPECT_HRESULT_SUCCEEDED( | 2350 EXPECT_HRESULT_SUCCEEDED( |
2339 description_for_relation->get_target(0, target.GetAddressOf())); | 2351 description_for_relation->get_target(0, target.GetAddressOf())); |
2340 target.CopyTo(ax_target.GetAddressOf()); | 2352 target.CopyTo(ax_target.GetAddressOf()); |
2341 EXPECT_HRESULT_SUCCEEDED(ax_target->get_uniqueID(&unique_id)); | 2353 EXPECT_HRESULT_SUCCEEDED(ax_target->get_uniqueID(&unique_id)); |
2342 EXPECT_EQ(-ax_root->unique_id(), unique_id); | 2354 EXPECT_EQ(-GetUniqueId(ax_root), unique_id); |
2343 ax_target.Reset(); | 2355 ax_target.Reset(); |
2344 target.Reset(); | 2356 target.Reset(); |
2345 description_for_relation.Reset(); | 2357 description_for_relation.Reset(); |
2346 | 2358 |
2347 EXPECT_HRESULT_SUCCEEDED(ax_child2->GetCOM()->get_nRelations(&n_relations)); | 2359 EXPECT_HRESULT_SUCCEEDED(ax_child2->GetCOM()->get_nRelations(&n_relations)); |
2348 EXPECT_EQ(1, n_relations); | 2360 EXPECT_EQ(1, n_relations); |
2349 | 2361 |
2350 EXPECT_HRESULT_SUCCEEDED(ax_child2->GetCOM()->get_relation( | 2362 EXPECT_HRESULT_SUCCEEDED(ax_child2->GetCOM()->get_relation( |
2351 0, description_for_relation.GetAddressOf())); | 2363 0, description_for_relation.GetAddressOf())); |
2352 EXPECT_HRESULT_SUCCEEDED( | 2364 EXPECT_HRESULT_SUCCEEDED( |
2353 description_for_relation->get_relationType(relation_type.Receive())); | 2365 description_for_relation->get_relationType(relation_type.Receive())); |
2354 EXPECT_EQ(L"descriptionFor", base::string16(relation_type)); | 2366 EXPECT_EQ(L"descriptionFor", base::string16(relation_type)); |
2355 relation_type.Reset(); | 2367 relation_type.Reset(); |
2356 | 2368 |
2357 EXPECT_HRESULT_SUCCEEDED(description_for_relation->get_nTargets(&n_targets)); | 2369 EXPECT_HRESULT_SUCCEEDED(description_for_relation->get_nTargets(&n_targets)); |
2358 EXPECT_EQ(1, n_targets); | 2370 EXPECT_EQ(1, n_targets); |
2359 | 2371 |
2360 EXPECT_HRESULT_SUCCEEDED( | 2372 EXPECT_HRESULT_SUCCEEDED( |
2361 description_for_relation->get_target(0, target.GetAddressOf())); | 2373 description_for_relation->get_target(0, target.GetAddressOf())); |
2362 target.CopyTo(ax_target.GetAddressOf()); | 2374 target.CopyTo(ax_target.GetAddressOf()); |
2363 EXPECT_HRESULT_SUCCEEDED(ax_target->get_uniqueID(&unique_id)); | 2375 EXPECT_HRESULT_SUCCEEDED(ax_target->get_uniqueID(&unique_id)); |
2364 EXPECT_EQ(-ax_root->unique_id(), unique_id); | 2376 EXPECT_EQ(-GetUniqueId(ax_root), unique_id); |
2365 ax_target.Reset(); | 2377 ax_target.Reset(); |
2366 target.Reset(); | 2378 target.Reset(); |
2367 | 2379 |
2368 // Try adding one more relation. | 2380 // Try adding one more relation. |
2369 std::vector<int32_t> labelledby_ids = {3}; | 2381 std::vector<int32_t> labelledby_ids = {3}; |
2370 child1.AddIntListAttribute(ui::AX_ATTR_LABELLEDBY_IDS, labelledby_ids); | 2382 child1.AddIntListAttribute(ui::AX_ATTR_LABELLEDBY_IDS, labelledby_ids); |
2371 AXEventNotificationDetails event; | 2383 AXEventNotificationDetails event; |
2372 event.event_type = ui::AX_EVENT_ARIA_ATTRIBUTE_CHANGED; | 2384 event.event_type = ui::AX_EVENT_ARIA_ATTRIBUTE_CHANGED; |
2373 event.update.nodes.push_back(child1); | 2385 event.update.nodes.push_back(child1); |
2374 event.id = child1.id; | 2386 event.id = child1.id; |
2375 std::vector<AXEventNotificationDetails> events = {event}; | 2387 std::vector<AXEventNotificationDetails> events = {event}; |
2376 manager->OnAccessibilityEvents(events); | 2388 manager->OnAccessibilityEvents(events); |
2377 | 2389 |
2378 EXPECT_HRESULT_SUCCEEDED(ax_child1->GetCOM()->get_nRelations(&n_relations)); | 2390 EXPECT_HRESULT_SUCCEEDED(ax_child1->GetCOM()->get_nRelations(&n_relations)); |
2379 EXPECT_EQ(2, n_relations); | 2391 EXPECT_EQ(2, n_relations); |
2380 EXPECT_HRESULT_SUCCEEDED(ax_child2->GetCOM()->get_nRelations(&n_relations)); | 2392 EXPECT_HRESULT_SUCCEEDED(ax_child2->GetCOM()->get_nRelations(&n_relations)); |
2381 EXPECT_EQ(2, n_relations); | 2393 EXPECT_EQ(2, n_relations); |
2382 } | 2394 } |
2383 | 2395 |
2384 } // namespace content | 2396 } // namespace content |
OLD | NEW |