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