Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Unit test alert node
  • Loading branch information
yaakovschectman committed Oct 26, 2022
commit 1873b2d136c29acf241b5edaac8f448829c4c80c
3 changes: 3 additions & 0 deletions shell/platform/windows/flutter_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,9 @@ void FlutterWindow::SendInitialAccessibilityFeatures() {
}

AccessibilityRootNode* FlutterWindow::GetAccessibilityRootNode() {
if (!accessibility_root_) {
CreateAccessibilityRootNode();
}
return accessibility_root_;
}

Expand Down
28 changes: 28 additions & 0 deletions shell/platform/windows/flutter_window_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ class MockFlutterWindow : public FlutterWindow {
MOCK_METHOD3(Win32DispatchMessage, UINT(UINT, WPARAM, LPARAM));
MOCK_METHOD4(Win32PeekMessage, BOOL(LPMSG, UINT, UINT, UINT));
MOCK_METHOD1(Win32MapVkToChar, uint32_t(uint32_t));
MOCK_METHOD0(GetPlatformWindow, HWND());

protected:
// |KeyboardManager::WindowDelegate|
Expand Down Expand Up @@ -400,5 +401,32 @@ TEST(FlutterWindowTest, InitialAccessibilityFeatures) {
win32window.SendInitialAccessibilityFeatures();
}

// Ensure that announcing the alert propagates the message to the alert node.
// Different screen readers use different properties for alerts.
TEST(FlutterWindowTest, AlertNode) {
std::unique_ptr<MockFlutterWindow> win32window = std::make_unique<MockFlutterWindow>();;
ON_CALL(*win32window, GetPlatformWindow()).WillByDefault(Return(nullptr));
AccessibilityRootNode* root_node = win32window->GetAccessibilityRootNode();
TestFlutterWindowsView view(std::move(win32window));
std::wstring message = L"Test alert";
view.AnnounceAlert(message);
IAccessible* alert = root_node->GetOrCreateAlert();
VARIANT self{.vt=VT_I4, .lVal=CHILDID_SELF};
BSTR strptr;
alert->get_accName(self, &strptr);
EXPECT_EQ(message, strptr);

alert->get_accDescription(self, &strptr);
EXPECT_EQ(message, strptr);

alert->get_accValue(self, &strptr);
EXPECT_EQ(message, strptr);

VARIANT role;
alert->get_accRole(self, &role);
EXPECT_EQ(role.vt, VT_I4);
EXPECT_EQ(role.lVal, ROLE_SYSTEM_ALERT);
}

} // namespace testing
} // namespace flutter
4 changes: 3 additions & 1 deletion shell/platform/windows/flutter_windows_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,9 @@ void FlutterWindowsView::AnnounceAlert(const std::wstring& text) {
AccessibilityAlert* alert = binding_handler_->GetAccessibilityRootNode()->GetOrCreateAlert();
alert->SetText(text);
HWND hwnd = GetPlatformWindow();
NotifyWinEvent(EVENT_SYSTEM_ALERT, hwnd, OBJID_CLIENT, AccessibilityRootNode::kAlertChildId);
if (hwnd) {
NotifyWinEvent(EVENT_SYSTEM_ALERT, hwnd, OBJID_CLIENT, AccessibilityRootNode::kAlertChildId);
}
}

} // namespace flutter
20 changes: 12 additions & 8 deletions shell/platform/windows/window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -214,14 +214,7 @@ LRESULT Window::OnGetObject(UINT const message,
} else if (is_msaa_request && root_view) {
// Create the accessibility root if it does not already exist.
if (!accessibility_root_) {
ui::win::CreateATLModuleIfNeeded();
CComObject<AccessibilityRootNode>* instance = nullptr;
HRESULT hr = CComObject<AccessibilityRootNode>::CreateInstance(&instance);
if (!SUCCEEDED(hr)) {
FML_LOG(FATAL) << "Failed to create accessibility root node";
}
instance->AddRef();
accessibility_root_ = instance;
CreateAccessibilityRootNode();
}
// Return the IAccessible for the root view.
//Microsoft::WRL::ComPtr<IAccessible> root(root_view);
Expand Down Expand Up @@ -669,4 +662,15 @@ bool Window::GetHighContrastEnabled() {
}
}

void Window::CreateAccessibilityRootNode() {
ui::win::CreateATLModuleIfNeeded();
CComObject<AccessibilityRootNode>* instance = nullptr;
HRESULT hr = CComObject<AccessibilityRootNode>::CreateInstance(&instance);
if (!SUCCEEDED(hr)) {
FML_LOG(FATAL) << "Failed to create accessibility root node";
}
instance->AddRef();
accessibility_root_ = instance;
}

} // namespace flutter
3 changes: 3 additions & 0 deletions shell/platform/windows/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ class Window : public KeyboardManager::WindowDelegate {
// Returns the root view accessibility node, or nullptr if none.
virtual gfx::NativeViewAccessible GetNativeViewAccessible() = 0;

// Create the wrapper node.
void CreateAccessibilityRootNode();

// Handles running DirectManipulation on the window to receive trackpad
// gestures.
std::unique_ptr<DirectManipulationOwner> direct_manipulation_owner_;
Expand Down