Skip to content
This repository has been archived by the owner on Feb 25, 2025. It is now read-only.

Commit

Permalink
License
Browse files Browse the repository at this point in the history
  • Loading branch information
yaakovschectman committed Nov 18, 2022
1 parent 0564682 commit 7456610
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 44 deletions.
1 change: 1 addition & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -3197,6 +3197,7 @@ FILE: ../../../flutter/shell/platform/windows/windows_proc_table.cc
FILE: ../../../flutter/shell/platform/windows/windows_proc_table.h
FILE: ../../../flutter/shell/platform/windows/windows_registry.cc
FILE: ../../../flutter/shell/platform/windows/windows_registry.h
FILE: ../../../flutter/shell/platform/windows/windowsx_shim.h
FILE: ../../../flutter/shell/profiling/sampling_profiler.cc
FILE: ../../../flutter/shell/profiling/sampling_profiler.h
FILE: ../../../flutter/shell/profiling/sampling_profiler_unittest.cc
Expand Down
1 change: 1 addition & 0 deletions shell/platform/common/flutter_platform_node_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ class FlutterPlatformNodeDelegate : public ui::AXPlatformNodeDelegateBase {
/// platform node delegate. This pointer is only safe in the
/// platform thread.
std::weak_ptr<OwnerBridge> GetOwnerBridge() const;

private:
ui::AXNode* ax_node_;
std::weak_ptr<OwnerBridge> bridge_;
Expand Down
33 changes: 22 additions & 11 deletions shell/platform/windows/accessibility_bridge_windows.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@ void AccessibilityBridgeWindows::OnAccessibilityEvent(
DispatchWinAccessibilityEvent(win_delegate, ax::mojom::Event::kAlert);
break;
case ui::AXEventGenerator::Event::CHECKED_STATE_CHANGED:
DispatchWinAccessibilityEvent(win_delegate, ax::mojom::Event::kValueChanged);
DispatchWinAccessibilityEvent(win_delegate,
ax::mojom::Event::kValueChanged);
break;
case ui::AXEventGenerator::Event::CHILDREN_CHANGED:
DispatchWinAccessibilityEvent(win_delegate, ax::mojom::Event::kChildrenChanged);
DispatchWinAccessibilityEvent(win_delegate,
ax::mojom::Event::kChildrenChanged);
break;
case ui::AXEventGenerator::Event::DOCUMENT_SELECTION_CHANGED:
DispatchWinAccessibilityEvent(win_delegate, ax::mojom::Event::kDocumentSelectionChanged);
DispatchWinAccessibilityEvent(
win_delegate, ax::mojom::Event::kDocumentSelectionChanged);
break;
case ui::AXEventGenerator::Event::FOCUS_CHANGED:
DispatchWinAccessibilityEvent(win_delegate, ax::mojom::Event::kFocus);
Expand All @@ -52,35 +55,43 @@ void AccessibilityBridgeWindows::OnAccessibilityEvent(
}
break;
case ui::AXEventGenerator::Event::IMAGE_ANNOTATION_CHANGED:
DispatchWinAccessibilityEvent(win_delegate, ax::mojom::Event::kTextChanged);
DispatchWinAccessibilityEvent(win_delegate,
ax::mojom::Event::kTextChanged);
break;
case ui::AXEventGenerator::Event::LIVE_REGION_CHANGED:
DispatchWinAccessibilityEvent(win_delegate,
ax::mojom::Event::kLiveRegionChanged);
break;
case ui::AXEventGenerator::Event::NAME_CHANGED:
DispatchWinAccessibilityEvent(win_delegate, ax::mojom::Event::kTextChanged);
DispatchWinAccessibilityEvent(win_delegate,
ax::mojom::Event::kTextChanged);
break;
case ui::AXEventGenerator::Event::SCROLL_HORIZONTAL_POSITION_CHANGED:
DispatchWinAccessibilityEvent(win_delegate, ax::mojom::Event::kScrollPositionChanged);
DispatchWinAccessibilityEvent(win_delegate,
ax::mojom::Event::kScrollPositionChanged);
break;
case ui::AXEventGenerator::Event::SCROLL_VERTICAL_POSITION_CHANGED:
DispatchWinAccessibilityEvent(win_delegate, ax::mojom::Event::kScrollPositionChanged);
DispatchWinAccessibilityEvent(win_delegate,
ax::mojom::Event::kScrollPositionChanged);
break;
case ui::AXEventGenerator::Event::SELECTED_CHANGED:
DispatchWinAccessibilityEvent(win_delegate, ax::mojom::Event::kValueChanged);
DispatchWinAccessibilityEvent(win_delegate,
ax::mojom::Event::kValueChanged);
break;
case ui::AXEventGenerator::Event::SELECTED_CHILDREN_CHANGED:
DispatchWinAccessibilityEvent(win_delegate, ax::mojom::Event::kSelectedChildrenChanged);
DispatchWinAccessibilityEvent(win_delegate,
ax::mojom::Event::kSelectedChildrenChanged);
break;
case ui::AXEventGenerator::Event::SUBTREE_CREATED:
DispatchWinAccessibilityEvent(win_delegate, ax::mojom::Event::kShow);
break;
case ui::AXEventGenerator::Event::VALUE_CHANGED:
DispatchWinAccessibilityEvent(win_delegate, ax::mojom::Event::kValueChanged);
DispatchWinAccessibilityEvent(win_delegate,
ax::mojom::Event::kValueChanged);
break;
case ui::AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED:
DispatchWinAccessibilityEvent(win_delegate, ax::mojom::Event::kStateChanged);
DispatchWinAccessibilityEvent(win_delegate,
ax::mojom::Event::kStateChanged);
break;
case ui::AXEventGenerator::Event::ACCESS_KEY_CHANGED:
case ui::AXEventGenerator::Event::ACTIVE_DESCENDANT_CHANGED:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,8 @@ TEST(AccessibilityBridgeWindows, OnAccessibilityEventFocusChanged) {
ax::mojom::EventFrom::kNone,
{}}});
ASSERT_EQ(bridge->dispatched_events().size(), 1);
EXPECT_EQ(bridge->dispatched_events()[0].event_type, ax::mojom::Event::kFocus);
EXPECT_EQ(bridge->dispatched_events()[0].event_type,
ax::mojom::Event::kFocus);

ASSERT_EQ(bridge->focused_nodes().size(), 1);
EXPECT_EQ(bridge->focused_nodes()[0], 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ void FlutterPlatformNodeDelegateWindows::SetFocus() {
GetNativeViewAccessible()->accSelect(SELFLAG_TAKEFOCUS, varchild);
}

gfx::AcceleratedWidget FlutterPlatformNodeDelegateWindows::GetTargetForNativeAccessibilityEvent() {
gfx::AcceleratedWidget
FlutterPlatformNodeDelegateWindows::GetTargetForNativeAccessibilityEvent() {
return view_->GetPlatformWindow();
}

Expand Down
53 changes: 37 additions & 16 deletions shell/platform/windows/flutter_windows_view_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

#include "flutter/shell/platform/windows/flutter_windows_view.h"

#include <UIAutomation.h>
#include <comdef.h>
#include <comutil.h>
#include <oleacc.h>
#include <UIAutomation.h>

#include <future>
#include <iostream>
Expand Down Expand Up @@ -247,14 +247,16 @@ TEST(FlutterWindowsView, AddSemanticsNodeUpdate) {

// Verify value property matches our label.
VARIANT varvalue{};
ASSERT_EQ(uia_view->GetPropertyValue(UIA_ValueValuePropertyId, &varvalue), S_OK);
ASSERT_EQ(uia_view->GetPropertyValue(UIA_ValueValuePropertyId, &varvalue),
S_OK);
EXPECT_EQ(varvalue.vt, VT_BSTR);
value = _com_util::ConvertBSTRToString(varvalue.bstrVal);
EXPECT_EQ(value, "value");

// Verify node control type is text.
varrole = {};
ASSERT_EQ(uia_view->GetPropertyValue(UIA_ControlTypePropertyId, &varrole), S_OK);
ASSERT_EQ(uia_view->GetPropertyValue(UIA_ControlTypePropertyId, &varrole),
S_OK);
EXPECT_EQ(varrole.vt, VT_I4);
EXPECT_EQ(varrole.lVal, UIA_TextControlTypeId);
}
Expand Down Expand Up @@ -690,10 +692,12 @@ TEST(FlutterWindowsViewTest, CheckboxNativeState) {
// Perform similar tests for UIA value;
IRawElementProviderSimple* uia_node;
native_view->QueryInterface(IID_PPV_ARGS(&uia_node));
ASSERT_TRUE(SUCCEEDED(uia_node->GetPropertyValue(UIA_ToggleToggleStatePropertyId, &native_state)));
ASSERT_TRUE(SUCCEEDED(uia_node->GetPropertyValue(
UIA_ToggleToggleStatePropertyId, &native_state)));
EXPECT_EQ(native_state.lVal, ToggleState_On);

ASSERT_TRUE(SUCCEEDED(uia_node->GetPropertyValue(UIA_AriaPropertiesPropertyId, &native_state)));
ASSERT_TRUE(SUCCEEDED(uia_node->GetPropertyValue(
UIA_AriaPropertiesPropertyId, &native_state)));
EXPECT_NE(std::wcsstr(native_state.bstrVal, L"checked=true"), nullptr);
}

Expand Down Expand Up @@ -729,10 +733,12 @@ TEST(FlutterWindowsViewTest, CheckboxNativeState) {
// Perform similar tests for UIA value;
IRawElementProviderSimple* uia_node;
native_view->QueryInterface(IID_PPV_ARGS(&uia_node));
ASSERT_TRUE(SUCCEEDED(uia_node->GetPropertyValue(UIA_ToggleToggleStatePropertyId, &native_state)));
ASSERT_TRUE(SUCCEEDED(uia_node->GetPropertyValue(
UIA_ToggleToggleStatePropertyId, &native_state)));
EXPECT_EQ(native_state.lVal, ToggleState_Off);

ASSERT_TRUE(SUCCEEDED(uia_node->GetPropertyValue(UIA_AriaPropertiesPropertyId, &native_state)));
ASSERT_TRUE(SUCCEEDED(uia_node->GetPropertyValue(
UIA_AriaPropertiesPropertyId, &native_state)));
EXPECT_NE(std::wcsstr(native_state.bstrVal, L"checked=false"), nullptr);
}

Expand Down Expand Up @@ -769,10 +775,12 @@ TEST(FlutterWindowsViewTest, CheckboxNativeState) {
// Perform similar tests for UIA value;
IRawElementProviderSimple* uia_node;
native_view->QueryInterface(IID_PPV_ARGS(&uia_node));
ASSERT_TRUE(SUCCEEDED(uia_node->GetPropertyValue(UIA_ToggleToggleStatePropertyId, &native_state)));
ASSERT_TRUE(SUCCEEDED(uia_node->GetPropertyValue(
UIA_ToggleToggleStatePropertyId, &native_state)));
EXPECT_EQ(native_state.lVal, ToggleState_Indeterminate);

ASSERT_TRUE(SUCCEEDED(uia_node->GetPropertyValue(UIA_AriaPropertiesPropertyId, &native_state)));
ASSERT_TRUE(SUCCEEDED(uia_node->GetPropertyValue(
UIA_AriaPropertiesPropertyId, &native_state)));
EXPECT_NE(std::wcsstr(native_state.bstrVal, L"checked=mixed"), nullptr);
}
}
Expand Down Expand Up @@ -845,11 +853,16 @@ TEST(FlutterWindowsViewTest, SwitchNativeState) {
// Test similarly on UIA node.
IRawElementProviderSimple* uia_node;
native_view->QueryInterface(IID_PPV_ARGS(&uia_node));
ASSERT_EQ(uia_node->GetPropertyValue(UIA_ControlTypePropertyId, &varrole), S_OK);
ASSERT_EQ(uia_node->GetPropertyValue(UIA_ControlTypePropertyId, &varrole),
S_OK);
EXPECT_EQ(varrole.lVal, UIA_ButtonControlTypeId);
ASSERT_EQ(uia_node->GetPropertyValue(UIA_ToggleToggleStatePropertyId, &native_state), S_OK);
ASSERT_EQ(uia_node->GetPropertyValue(UIA_ToggleToggleStatePropertyId,
&native_state),
S_OK);
EXPECT_EQ(native_state.lVal, ToggleState_On);
ASSERT_EQ(uia_node->GetPropertyValue(UIA_AriaPropertiesPropertyId, &native_state), S_OK);
ASSERT_EQ(
uia_node->GetPropertyValue(UIA_AriaPropertiesPropertyId, &native_state),
S_OK);
EXPECT_NE(std::wcsstr(native_state.bstrVal, L"pressed=true"), nullptr);
}

Expand Down Expand Up @@ -885,9 +898,13 @@ TEST(FlutterWindowsViewTest, SwitchNativeState) {
// Test similarly on UIA node.
IRawElementProviderSimple* uia_node;
native_view->QueryInterface(IID_PPV_ARGS(&uia_node));
ASSERT_EQ(uia_node->GetPropertyValue(UIA_ToggleToggleStatePropertyId, &native_state), S_OK);
ASSERT_EQ(uia_node->GetPropertyValue(UIA_ToggleToggleStatePropertyId,
&native_state),
S_OK);
EXPECT_EQ(native_state.lVal, ToggleState_Off);
ASSERT_EQ(uia_node->GetPropertyValue(UIA_AriaPropertiesPropertyId, &native_state), S_OK);
ASSERT_EQ(
uia_node->GetPropertyValue(UIA_AriaPropertiesPropertyId, &native_state),
S_OK);
EXPECT_NE(std::wcsstr(native_state.bstrVal, L"pressed=false"), nullptr);
}
}
Expand Down Expand Up @@ -935,8 +952,12 @@ TEST(FlutterWindowsViewTest, TooltipNodeData) {
EXPECT_EQ(tooltip, "tooltip");

// Check that MSAA name contains the tooltip.
IAccessible* native_view = bridge->GetFlutterPlatformNodeDelegateFromID(AccessibilityBridge::kRootNodeId).lock()->GetNativeViewAccessible();
VARIANT varchild = {.vt=VT_I4, .lVal=CHILDID_SELF};
IAccessible* native_view = bridge
->GetFlutterPlatformNodeDelegateFromID(
AccessibilityBridge::kRootNodeId)
.lock()
->GetNativeViewAccessible();
VARIANT varchild = {.vt = VT_I4, .lVal = CHILDID_SELF};
BSTR bname;
ASSERT_EQ(native_view->get_accName(varchild, &bname), S_OK);
EXPECT_NE(std::wcsstr(bname, L"tooltip"), nullptr);
Expand Down
2 changes: 1 addition & 1 deletion shell/platform/windows/testing/test_keyboard.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
// found in the LICENSE file.

#include "flutter/shell/platform/windows/testing/test_keyboard.h"
#include "flutter/shell/platform/windows/windowsx_shim.h"
#include "flutter/shell/platform/common/json_message_codec.h"
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
#include "flutter/shell/platform/windows/windowsx_shim.h"

#include <rapidjson/document.h>

Expand Down
21 changes: 13 additions & 8 deletions shell/platform/windows/window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,21 +207,23 @@ LRESULT Window::OnGetObject(UINT const message,
if (is_uia_request && root_view) {
if (!ax_fragment_root_) {
if (!ax_fragment_delegate_) {
ax_fragment_delegate_ = std::make_unique<WindowAXFragmentRootDelegate>(*this);
ax_fragment_delegate_ =
std::make_unique<WindowAXFragmentRootDelegate>(*this);
}
ax_fragment_root_ = std::make_unique<ui::AXFragmentRootWin>(window_handle_, ax_fragment_delegate_.get());
ax_fragment_root_ = std::make_unique<ui::AXFragmentRootWin>(
window_handle_, ax_fragment_delegate_.get());
}

// TODO(cbracken): https://github.com/flutter/flutter/issues/94782
// Implement when we adopt UIA support.
// Retrieve UIA object for the root view.
Microsoft::WRL::ComPtr<IRawElementProviderSimple> root;
if (SUCCEEDED(ax_fragment_root_->GetNativeViewAccessible()->QueryInterface(
IID_PPV_ARGS(&root)))) {
IID_PPV_ARGS(&root)))) {
// Return the UIA object via UiaReturnRawElementProvider(). See:
// https://docs.microsoft.com/en-us/windows/win32/winauto/wm-getobject
reference_result =
UiaReturnRawElementProvider(window_handle_, wparam, lparam, root.Get());
reference_result = UiaReturnRawElementProvider(window_handle_, wparam,
lparam, root.Get());
} else {
FML_LOG(ERROR) << "Failed to query AX fragment root.";
}
Expand Down Expand Up @@ -682,18 +684,21 @@ void Window::CreateAccessibilityRootNode() {
accessibility_root_ = AccessibilityRootNode::Create();
}

gfx::NativeViewAccessible WindowAXFragmentRootDelegate::GetChildOfAXFragmentRoot() {
gfx::NativeViewAccessible
WindowAXFragmentRootDelegate::GetChildOfAXFragmentRoot() {
return window_.GetNativeViewAccessible();
}

gfx::NativeViewAccessible WindowAXFragmentRootDelegate::GetParentOfAXFragmentRoot() {
gfx::NativeViewAccessible
WindowAXFragmentRootDelegate::GetParentOfAXFragmentRoot() {
return nullptr;
}

bool WindowAXFragmentRootDelegate::IsAXFragmentRootAControlElement() {
return true;
}

WindowAXFragmentRootDelegate::WindowAXFragmentRootDelegate(Window& window) : window_(window) {}
WindowAXFragmentRootDelegate::WindowAXFragmentRootDelegate(Window& window)
: window_(window) {}

} // namespace flutter
2 changes: 1 addition & 1 deletion shell/platform/windows/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
#include "flutter/shell/platform/windows/text_input_manager.h"
#include "flutter/shell/platform/windows/windows_proc_table.h"
#include "flutter/shell/platform/windows/windowsx_shim.h"
#include "flutter/third_party/accessibility/gfx/native_widget_types.h"
#include "flutter/third_party/accessibility/ax/platform/ax_fragment_root_delegate_win.h"
#include "flutter/third_party/accessibility/ax/platform/ax_fragment_root_win.h"
#include "flutter/third_party/accessibility/gfx/native_widget_types.h"

namespace flutter {

Expand Down
9 changes: 5 additions & 4 deletions third_party/accessibility/ax/platform/ax_platform_node_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2465,7 +2465,7 @@ HRESULT AXPlatformNodeWin::GetPropertyValueImpl(PROPERTYID property_id,
result->intVal = static_cast<int>(ComputeExpandCollapseState());
break;

case UIA_ToggleToggleStatePropertyId:{
case UIA_ToggleToggleStatePropertyId: {
ToggleState state;
get_ToggleState(&state);
result->vt = VT_I4;
Expand Down Expand Up @@ -5601,9 +5601,10 @@ AXPlatformNodeWin::GetPatternProviderFactoryMethod(PATTERNID pattern_id) {
}
break;

// TODO(schectman): add implementations for ITextProvider and ITextRangeProvider interfaces.
// https://github.com/flutter/flutter/issues/114547 and
// https://github.com/flutter/flutter/issues/109804
// TODO(schectman): add implementations for ITextProvider and
// ITextRangeProvider interfaces.
// https://github.com/flutter/flutter/issues/114547 and
// https://github.com/flutter/flutter/issues/109804

case UIA_TogglePatternId:
if (SupportsToggle(data.role)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ class TestAXTreeObserver : public AXTreeObserver {
if (iter != g_node_id_to_wrapper_map.end()) {
TestAXNodeWrapper* wrapper = iter->second;
const auto& focus_iter = g_focused_node_in_tree.find(tree);
if (focus_iter != g_focused_node_in_tree.end() && focus_iter->second->id() == node_id) {
if (focus_iter != g_focused_node_in_tree.end() &&
focus_iter->second->id() == node_id) {
g_focused_node_in_tree.erase(tree);
}
delete wrapper;
Expand Down

0 comments on commit 7456610

Please sign in to comment.