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

Commit 74f6924

Browse files
Unit test announcement message
1 parent 806c5fe commit 74f6924

File tree

6 files changed

+115
-11
lines changed

6 files changed

+115
-11
lines changed

shell/platform/windows/accessibility_root_node.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "flutter/shell/platform/windows/accessibility_root_node.h"
66

77
#include "flutter/fml/logging.h"
8+
#include "flutter/third_party/accessibility/base/win/atl_module.h"
89

910
namespace flutter {
1011

@@ -270,4 +271,16 @@ AccessibilityAlert* AccessibilityRootNode::GetOrCreateAlert() {
270271
return alert_accessible_;
271272
}
272273

274+
// static
275+
AccessibilityRootNode* AccessibilityRootNode::Create() {
276+
ui::win::CreateATLModuleIfNeeded();
277+
CComObject<AccessibilityRootNode>* instance = nullptr;
278+
HRESULT hr = CComObject<AccessibilityRootNode>::CreateInstance(&instance);
279+
if (!SUCCEEDED(hr) || !instance) {
280+
FML_LOG(FATAL) << "Failed to create accessibility root node";
281+
}
282+
instance->AddRef();
283+
return instance;
284+
}
285+
273286
} // namespace flutter

shell/platform/windows/accessibility_root_node.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,16 @@ class AccessibilityRootNode : public CComObjectRootEx<CComMultiThreadModel>,
9999
IFACEMETHODIMP put_accName(VARIANT var_id, BSTR put_name) override;
100100

101101
AccessibilityRootNode();
102-
~AccessibilityRootNode();
102+
virtual ~AccessibilityRootNode();
103103

104104
void SetWindow(IAccessible* window);
105105

106106
void SetAlert(AccessibilityAlert* alert);
107107

108108
AccessibilityAlert* GetOrCreateAlert();
109109

110+
static AccessibilityRootNode* Create();
111+
110112
private:
111113
// Helper method to redirect method calls to the contained window or alert.
112114
IAccessible* GetTargetAndChildID(VARIANT* var_id);

shell/platform/windows/fixtures/main.dart

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'dart:async';
56
import 'dart:io' as io;
6-
import 'dart:typed_data' show ByteData;
7+
import 'dart:typed_data' show ByteData, Uint8List;
78
import 'dart:ui' as ui;
89

910
// Signals a waiting latch in the native test.
@@ -36,6 +37,46 @@ void hiPlatformChannels() {
3637
});
3738
}
3839

40+
@pragma('vm:entry-point')
41+
void alertPlatformChannel() async {
42+
// Serializers for data types are in the framework, so this will be hardcoded.
43+
Uint8List data = Uint8List.fromList([
44+
13, // _valueMap
45+
2, // Size
46+
// key: "type"
47+
7, // _valueString
48+
'type'.length,
49+
...'type'.codeUnits,
50+
// value: "announce"
51+
7,
52+
'announce'.length,
53+
...'announce'.codeUnits,
54+
// key: "data"
55+
7, // _valueString
56+
'data'.length,
57+
...'data'.codeUnits,
58+
// value: map
59+
13, // _valueMap
60+
1, // Size
61+
// key: "message"
62+
7, // _valueString
63+
'message'.length,
64+
...'message'.codeUnits,
65+
// value: ""
66+
7, // _valueString
67+
0
68+
]);
69+
ByteData byteData = data.buffer.asByteData();
70+
71+
final Completer<ByteData?> enabled = Completer<ByteData?>();
72+
ui.PlatformDispatcher.instance.sendPlatformMessage('semantics', ByteData(0), (ByteData? reply){
73+
enabled.complete(reply);
74+
});
75+
await enabled.future;
76+
77+
ui.PlatformDispatcher.instance.sendPlatformMessage('flutter/accessibility', byteData, (ByteData? _){});
78+
}
79+
3980
@pragma('vm:entry-point')
4081
void customEntrypoint() {}
4182

shell/platform/windows/flutter_windows_engine_unittests.cc

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66

77
#include "flutter/shell/platform/embedder/embedder.h"
88
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
9+
#include "flutter/shell/platform/windows/flutter_windows_view.h"
910
#include "flutter/shell/platform/windows/testing/engine_modifier.h"
11+
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
1012
#include "flutter/shell/platform/windows/testing/test_keyboard.h"
1113
#include "flutter/shell/platform/windows/testing/windows_test.h"
1214
#include "fml/synchronization/waitable_event.h"
15+
#include "gmock/gmock.h"
1316
#include "gtest/gtest.h"
1417

1518
// winbase.h defines GetCurrentTime as a macro.
@@ -516,5 +519,57 @@ TEST_F(FlutterWindowsEngineTest, PostRasterThreadTask) {
516519
EXPECT_TRUE(called);
517520
}
518521

522+
class MockFlutterWindowsView : public FlutterWindowsView {
523+
public:
524+
MockFlutterWindowsView(std::unique_ptr<WindowBindingHandler> wbh) : FlutterWindowsView(std::move(wbh)) {}
525+
~MockFlutterWindowsView() {}
526+
527+
MOCK_METHOD4(NotifyWinEventWrapper, void(DWORD, HWND, LONG, LONG));
528+
};
529+
530+
TEST_F(FlutterWindowsEngineTest, AlertPlatformMessage) {
531+
FlutterDesktopEngineProperties properties = {};
532+
properties.assets_path = GetContext().GetAssetsPath().c_str();
533+
properties.icu_data_path = GetContext().GetIcuDataPath().c_str();
534+
properties.dart_entrypoint = "alertPlatformChannel";
535+
536+
FlutterProjectBundle project(properties);
537+
538+
auto window_binding_handler = std::make_unique<::testing::NiceMock<MockWindowBindingHandler>>();
539+
AccessibilityRootNode* root_node = AccessibilityRootNode::Create();
540+
ON_CALL(*window_binding_handler, GetAccessibilityRootNode).WillByDefault(::testing::Return(root_node));
541+
MockFlutterWindowsView view(std::move(window_binding_handler));
542+
view.SetEngine(std::make_unique<FlutterWindowsEngine>(project));
543+
FlutterWindowsEngine* engine = view.GetEngine();
544+
545+
EngineModifier modifier(engine);
546+
modifier.embedder_api().RunsAOTCompiledDartCode = []() { return false; };
547+
548+
auto binary_messenger =
549+
std::make_unique<BinaryMessengerImpl>(engine->messenger());
550+
binary_messenger->SetMessageHandler(
551+
"semantics",
552+
[&engine](
553+
const uint8_t* message, size_t message_size, BinaryReply reply) {
554+
engine->UpdateSemanticsEnabled(true);
555+
char response[] = "";
556+
reply(reinterpret_cast<uint8_t*>(response), 0);
557+
});
558+
559+
bool did_call = false;
560+
ON_CALL(view, NotifyWinEventWrapper).WillByDefault([&did_call](DWORD event, HWND hwnd, LONG obj, LONG child) {
561+
did_call = true;
562+
});
563+
564+
565+
engine->UpdateSemanticsEnabled(true);
566+
engine->Run();
567+
568+
// Rely on timeout mechanism in CI.
569+
while (!did_call) {
570+
engine->task_runner()->ProcessTasks();
571+
}
572+
}
573+
519574
} // namespace testing
520575
} // namespace flutter

shell/platform/windows/flutter_windows_view.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,7 @@ FlutterWindowsEngine* FlutterWindowsView::GetEngine() {
637637
}
638638

639639
void FlutterWindowsView::AnnounceAlert(const std::wstring& text) {
640+
AccessibilityRootNode* root_node = binding_handler_->GetAccessibilityRootNode();
640641
AccessibilityAlert* alert =
641642
binding_handler_->GetAccessibilityRootNode()->GetOrCreateAlert();
642643
alert->SetText(text);

shell/platform/windows/window.cc

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include <cstring>
1616

1717
#include "flutter/shell/platform/windows/dpi_utils.h"
18-
#include "flutter/third_party/accessibility/base/win/atl_module.h"
1918

2019
namespace flutter {
2120

@@ -663,14 +662,7 @@ bool Window::GetHighContrastEnabled() {
663662
}
664663

665664
void Window::CreateAccessibilityRootNode() {
666-
ui::win::CreateATLModuleIfNeeded();
667-
CComObject<AccessibilityRootNode>* instance = nullptr;
668-
HRESULT hr = CComObject<AccessibilityRootNode>::CreateInstance(&instance);
669-
if (!SUCCEEDED(hr) || !instance) {
670-
FML_LOG(FATAL) << "Failed to create accessibility root node";
671-
}
672-
instance->AddRef();
673-
accessibility_root_ = instance;
665+
accessibility_root_ = AccessibilityRootNode::Create();
674666
}
675667

676668
} // namespace flutter

0 commit comments

Comments
 (0)