1.20 CP: fix FlutterViewUpdateCustomAccessibilityActions uses correct string list (#20238)
* fix FlutterViewUpdateCustomAccessibilityActions uses correct string list (#19623)
* fix FlutterViewUpdateCustomAccessibilityActions uses correct string list
* add test to ci
* format
* add license file
* fix test
* fix lint
* fix bad merge for BUILD.gn
* fix build.gn formatting
Co-authored-by: chunhtai <47866232+chunhtai@users.noreply.github.com>
diff --git a/BUILD.gn b/BUILD.gn
index edac93a..24c5925 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -86,6 +86,7 @@
"//flutter/shell/common:shell_benchmarks",
"//flutter/shell/platform/android/external_view_embedder:android_external_view_embedder_unittests",
"//flutter/shell/platform/android/jni:jni_unittests",
+ "//flutter/shell/platform/android/platform_view_android_delegate:platform_view_android_delegate_unittests",
"//flutter/third_party/txt:txt_benchmarks",
]
}
diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter
index bf97ba8..6cae668 100755
--- a/ci/licenses_golden/licenses_flutter
+++ b/ci/licenses_golden/licenses_flutter
@@ -801,6 +801,9 @@
FILE: ../../../flutter/shell/platform/android/platform_message_response_android.h
FILE: ../../../flutter/shell/platform/android/platform_view_android.cc
FILE: ../../../flutter/shell/platform/android/platform_view_android.h
+FILE: ../../../flutter/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate.cc
+FILE: ../../../flutter/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate.h
+FILE: ../../../flutter/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate_unittests.cc
FILE: ../../../flutter/shell/platform/android/platform_view_android_jni_impl.cc
FILE: ../../../flutter/shell/platform/android/platform_view_android_jni_impl.h
FILE: ../../../flutter/shell/platform/android/robolectric.properties
diff --git a/shell/platform/android/BUILD.gn b/shell/platform/android/BUILD.gn
index 93e6b14..6d55b3c 100644
--- a/shell/platform/android/BUILD.gn
+++ b/shell/platform/android/BUILD.gn
@@ -64,6 +64,7 @@
"//flutter/shell/platform/android/context",
"//flutter/shell/platform/android/external_view_embedder",
"//flutter/shell/platform/android/jni",
+ "//flutter/shell/platform/android/platform_view_android_delegate",
"//flutter/shell/platform/android/surface",
"//flutter/shell/platform/android/surface:native_window",
"//third_party/skia",
diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc
index 9253e8e..5969946 100644
--- a/shell/platform/android/platform_view_android.cc
+++ b/shell/platform/android/platform_view_android.cc
@@ -52,7 +52,9 @@
flutter::TaskRunners task_runners,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
bool use_software_rendering)
- : PlatformView(delegate, std::move(task_runners)), jni_facade_(jni_facade) {
+ : PlatformView(delegate, std::move(task_runners)),
+ jni_facade_(jni_facade),
+ platform_view_android_delegate_(jni_facade) {
std::shared_ptr<AndroidContext> android_context;
if (use_software_rendering) {
android_context =
@@ -81,7 +83,8 @@
flutter::TaskRunners task_runners,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
: PlatformView(delegate, std::move(task_runners)),
- jni_facade_(jni_facade) {}
+ jni_facade_(jni_facade),
+ platform_view_android_delegate_(jni_facade) {}
PlatformViewAndroid::~PlatformViewAndroid() = default;
@@ -260,143 +263,7 @@
void PlatformViewAndroid::UpdateSemantics(
flutter::SemanticsNodeUpdates update,
flutter::CustomAccessibilityActionUpdates actions) {
- constexpr size_t kBytesPerNode = 41 * sizeof(int32_t);
- constexpr size_t kBytesPerChild = sizeof(int32_t);
- constexpr size_t kBytesPerAction = 4 * sizeof(int32_t);
-
- {
- size_t num_bytes = 0;
- for (const auto& value : update) {
- num_bytes += kBytesPerNode;
- num_bytes +=
- value.second.childrenInTraversalOrder.size() * kBytesPerChild;
- num_bytes += value.second.childrenInHitTestOrder.size() * kBytesPerChild;
- num_bytes +=
- value.second.customAccessibilityActions.size() * kBytesPerChild;
- }
-
- // The encoding defined here is used in:
- //
- // * AccessibilityBridge.java
- // * AccessibilityBridgeTest.java
- // * accessibility_bridge.mm
- //
- // If any of the encoding structure or length is changed, those locations
- // must be updated (at a minimum).
- std::vector<uint8_t> buffer(num_bytes);
- int32_t* buffer_int32 = reinterpret_cast<int32_t*>(&buffer[0]);
- float* buffer_float32 = reinterpret_cast<float*>(&buffer[0]);
-
- std::vector<std::string> strings;
- size_t position = 0;
- for (const auto& value : update) {
- // If you edit this code, make sure you update kBytesPerNode
- // and/or kBytesPerChild above to match the number of values you are
- // sending.
- const flutter::SemanticsNode& node = value.second;
- buffer_int32[position++] = node.id;
- buffer_int32[position++] = node.flags;
- buffer_int32[position++] = node.actions;
- buffer_int32[position++] = node.maxValueLength;
- buffer_int32[position++] = node.currentValueLength;
- buffer_int32[position++] = node.textSelectionBase;
- buffer_int32[position++] = node.textSelectionExtent;
- buffer_int32[position++] = node.platformViewId;
- buffer_int32[position++] = node.scrollChildren;
- buffer_int32[position++] = node.scrollIndex;
- buffer_float32[position++] = (float)node.scrollPosition;
- buffer_float32[position++] = (float)node.scrollExtentMax;
- buffer_float32[position++] = (float)node.scrollExtentMin;
- if (node.label.empty()) {
- buffer_int32[position++] = -1;
- } else {
- buffer_int32[position++] = strings.size();
- strings.push_back(node.label);
- }
- if (node.value.empty()) {
- buffer_int32[position++] = -1;
- } else {
- buffer_int32[position++] = strings.size();
- strings.push_back(node.value);
- }
- if (node.increasedValue.empty()) {
- buffer_int32[position++] = -1;
- } else {
- buffer_int32[position++] = strings.size();
- strings.push_back(node.increasedValue);
- }
- if (node.decreasedValue.empty()) {
- buffer_int32[position++] = -1;
- } else {
- buffer_int32[position++] = strings.size();
- strings.push_back(node.decreasedValue);
- }
- if (node.hint.empty()) {
- buffer_int32[position++] = -1;
- } else {
- buffer_int32[position++] = strings.size();
- strings.push_back(node.hint);
- }
- buffer_int32[position++] = node.textDirection;
- buffer_float32[position++] = node.rect.left();
- buffer_float32[position++] = node.rect.top();
- buffer_float32[position++] = node.rect.right();
- buffer_float32[position++] = node.rect.bottom();
- node.transform.getColMajor(&buffer_float32[position]);
- position += 16;
-
- buffer_int32[position++] = node.childrenInTraversalOrder.size();
- for (int32_t child : node.childrenInTraversalOrder)
- buffer_int32[position++] = child;
-
- for (int32_t child : node.childrenInHitTestOrder)
- buffer_int32[position++] = child;
-
- buffer_int32[position++] = node.customAccessibilityActions.size();
- for (int32_t child : node.customAccessibilityActions)
- buffer_int32[position++] = child;
- }
-
- // custom accessibility actions.
- size_t num_action_bytes = actions.size() * kBytesPerAction;
- std::vector<uint8_t> actions_buffer(num_action_bytes);
- int32_t* actions_buffer_int32 =
- reinterpret_cast<int32_t*>(&actions_buffer[0]);
-
- std::vector<std::string> action_strings;
- size_t actions_position = 0;
- for (const auto& value : actions) {
- // If you edit this code, make sure you update kBytesPerAction
- // to match the number of values you are
- // sending.
- const flutter::CustomAccessibilityAction& action = value.second;
- actions_buffer_int32[actions_position++] = action.id;
- actions_buffer_int32[actions_position++] = action.overrideId;
- if (action.label.empty()) {
- actions_buffer_int32[actions_position++] = -1;
- } else {
- actions_buffer_int32[actions_position++] = action_strings.size();
- action_strings.push_back(action.label);
- }
- if (action.hint.empty()) {
- actions_buffer_int32[actions_position++] = -1;
- } else {
- actions_buffer_int32[actions_position++] = action_strings.size();
- action_strings.push_back(action.hint);
- }
- }
-
- // Calling NewDirectByteBuffer in API level 22 and below with a size of zero
- // will cause a JNI crash.
- if (actions_buffer.size() > 0) {
- jni_facade_->FlutterViewUpdateCustomAccessibilityActions(actions_buffer,
- strings);
- }
-
- if (buffer.size() > 0) {
- jni_facade_->FlutterViewUpdateSemantics(buffer, strings);
- }
- }
+ platform_view_android_delegate_.UpdateSemantics(update, actions);
}
void PlatformViewAndroid::RegisterExternalTexture(
diff --git a/shell/platform/android/platform_view_android.h b/shell/platform/android/platform_view_android.h
index f0c7bfa..34475dd 100644
--- a/shell/platform/android/platform_view_android.h
+++ b/shell/platform/android/platform_view_android.h
@@ -16,6 +16,7 @@
#include "flutter/lib/ui/window/platform_message.h"
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
+#include "flutter/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate.h"
#include "flutter/shell/platform/android/surface/android_native_window.h"
#include "flutter/shell/platform/android/surface/android_surface.h"
@@ -80,6 +81,8 @@
private:
const std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;
+ PlatformViewAndroidDelegate platform_view_android_delegate_;
+
std::unique_ptr<AndroidSurface> android_surface_;
// We use id 0 to mean that no response is expected.
int next_response_id_ = 1;
diff --git a/shell/platform/android/platform_view_android_delegate/BUILD.gn b/shell/platform/android/platform_view_android_delegate/BUILD.gn
new file mode 100644
index 0000000..61f2019
--- /dev/null
+++ b/shell/platform/android/platform_view_android_delegate/BUILD.gn
@@ -0,0 +1,45 @@
+# Copyright 2013 The Flutter Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//flutter/common/config.gni")
+import("//flutter/testing/testing.gni")
+
+source_set("platform_view_android_delegate") {
+ sources = [
+ "platform_view_android_delegate.cc",
+ "platform_view_android_delegate.h",
+ ]
+
+ public_configs = [ "//flutter:config" ]
+
+ deps = [
+ "//flutter/common",
+ "//flutter/fml",
+ "//flutter/lib/ui",
+ "//flutter/shell/common",
+ "//flutter/shell/platform/android/jni",
+ "//third_party/skia",
+ ]
+}
+
+test_fixtures("platform_view_android_delegate_fixtures") {
+ fixtures = []
+}
+
+executable("platform_view_android_delegate_unittests") {
+ testonly = true
+
+ sources = [
+ "platform_view_android_delegate_unittests.cc",
+ ]
+
+ deps = [
+ ":platform_view_android_delegate",
+ ":platform_view_android_delegate_fixtures",
+ "//flutter/shell/platform/android/jni:jni_mock",
+ "//flutter/testing",
+ "//flutter/testing:dart",
+ "//flutter/third_party/txt",
+ ]
+}
diff --git a/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate.cc b/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate.cc
new file mode 100644
index 0000000..9570d72
--- /dev/null
+++ b/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate.cc
@@ -0,0 +1,157 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "flutter/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate.h"
+
+namespace flutter {
+
+PlatformViewAndroidDelegate::PlatformViewAndroidDelegate(
+ std::shared_ptr<PlatformViewAndroidJNI> jni_facade)
+ : jni_facade_(jni_facade){};
+
+void PlatformViewAndroidDelegate::UpdateSemantics(
+ flutter::SemanticsNodeUpdates update,
+ flutter::CustomAccessibilityActionUpdates actions) {
+ constexpr size_t kBytesPerNode = 41 * sizeof(int32_t);
+ constexpr size_t kBytesPerChild = sizeof(int32_t);
+ constexpr size_t kBytesPerAction = 4 * sizeof(int32_t);
+
+ {
+ size_t num_bytes = 0;
+ for (const auto& value : update) {
+ num_bytes += kBytesPerNode;
+ num_bytes +=
+ value.second.childrenInTraversalOrder.size() * kBytesPerChild;
+ num_bytes += value.second.childrenInHitTestOrder.size() * kBytesPerChild;
+ num_bytes +=
+ value.second.customAccessibilityActions.size() * kBytesPerChild;
+ }
+ // The encoding defined here is used in:
+ //
+ // * AccessibilityBridge.java
+ // * AccessibilityBridgeTest.java
+ // * accessibility_bridge.mm
+ //
+ // If any of the encoding structure or length is changed, those locations
+ // must be updated (at a minimum).
+ std::vector<uint8_t> buffer(num_bytes);
+ int32_t* buffer_int32 = reinterpret_cast<int32_t*>(&buffer[0]);
+ float* buffer_float32 = reinterpret_cast<float*>(&buffer[0]);
+
+ std::vector<std::string> strings;
+ size_t position = 0;
+ for (const auto& value : update) {
+ // If you edit this code, make sure you update kBytesPerNode
+ // and/or kBytesPerChild above to match the number of values you are
+ // sending.
+ const flutter::SemanticsNode& node = value.second;
+ buffer_int32[position++] = node.id;
+ buffer_int32[position++] = node.flags;
+ buffer_int32[position++] = node.actions;
+ buffer_int32[position++] = node.maxValueLength;
+ buffer_int32[position++] = node.currentValueLength;
+ buffer_int32[position++] = node.textSelectionBase;
+ buffer_int32[position++] = node.textSelectionExtent;
+ buffer_int32[position++] = node.platformViewId;
+ buffer_int32[position++] = node.scrollChildren;
+ buffer_int32[position++] = node.scrollIndex;
+ buffer_float32[position++] = static_cast<float>(node.scrollPosition);
+ buffer_float32[position++] = static_cast<float>(node.scrollExtentMax);
+ buffer_float32[position++] = static_cast<float>(node.scrollExtentMin);
+ if (node.label.empty()) {
+ buffer_int32[position++] = -1;
+ } else {
+ buffer_int32[position++] = strings.size();
+ strings.push_back(node.label);
+ }
+ if (node.value.empty()) {
+ buffer_int32[position++] = -1;
+ } else {
+ buffer_int32[position++] = strings.size();
+ strings.push_back(node.value);
+ }
+ if (node.increasedValue.empty()) {
+ buffer_int32[position++] = -1;
+ } else {
+ buffer_int32[position++] = strings.size();
+ strings.push_back(node.increasedValue);
+ }
+ if (node.decreasedValue.empty()) {
+ buffer_int32[position++] = -1;
+ } else {
+ buffer_int32[position++] = strings.size();
+ strings.push_back(node.decreasedValue);
+ }
+ if (node.hint.empty()) {
+ buffer_int32[position++] = -1;
+ } else {
+ buffer_int32[position++] = strings.size();
+ strings.push_back(node.hint);
+ }
+ buffer_int32[position++] = node.textDirection;
+ buffer_float32[position++] = node.rect.left();
+ buffer_float32[position++] = node.rect.top();
+ buffer_float32[position++] = node.rect.right();
+ buffer_float32[position++] = node.rect.bottom();
+ node.transform.getColMajor(&buffer_float32[position]);
+ position += 16;
+
+ buffer_int32[position++] = node.childrenInTraversalOrder.size();
+ for (int32_t child : node.childrenInTraversalOrder) {
+ buffer_int32[position++] = child;
+ }
+
+ for (int32_t child : node.childrenInHitTestOrder) {
+ buffer_int32[position++] = child;
+ }
+
+ buffer_int32[position++] = node.customAccessibilityActions.size();
+ for (int32_t child : node.customAccessibilityActions) {
+ buffer_int32[position++] = child;
+ }
+ }
+
+ // custom accessibility actions.
+ size_t num_action_bytes = actions.size() * kBytesPerAction;
+ std::vector<uint8_t> actions_buffer(num_action_bytes);
+ int32_t* actions_buffer_int32 =
+ reinterpret_cast<int32_t*>(&actions_buffer[0]);
+
+ std::vector<std::string> action_strings;
+ size_t actions_position = 0;
+ for (const auto& value : actions) {
+ // If you edit this code, make sure you update kBytesPerAction
+ // to match the number of values you are
+ // sending.
+ const flutter::CustomAccessibilityAction& action = value.second;
+ actions_buffer_int32[actions_position++] = action.id;
+ actions_buffer_int32[actions_position++] = action.overrideId;
+ if (action.label.empty()) {
+ actions_buffer_int32[actions_position++] = -1;
+ } else {
+ actions_buffer_int32[actions_position++] = action_strings.size();
+ action_strings.push_back(action.label);
+ }
+ if (action.hint.empty()) {
+ actions_buffer_int32[actions_position++] = -1;
+ } else {
+ actions_buffer_int32[actions_position++] = action_strings.size();
+ action_strings.push_back(action.hint);
+ }
+ }
+
+ // Calling NewDirectByteBuffer in API level 22 and below with a size of zero
+ // will cause a JNI crash.
+ if (actions_buffer.size() > 0) {
+ jni_facade_->FlutterViewUpdateCustomAccessibilityActions(actions_buffer,
+ action_strings);
+ }
+
+ if (buffer.size() > 0) {
+ jni_facade_->FlutterViewUpdateSemantics(buffer, strings);
+ }
+ }
+}
+
+} // namespace flutter
diff --git a/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate.h b/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate.h
new file mode 100644
index 0000000..3f76f34
--- /dev/null
+++ b/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate.h
@@ -0,0 +1,29 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_DELEGATE_H_
+#define SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_DELEGATE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "flutter/shell/common/platform_view.h"
+#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
+
+namespace flutter {
+
+class PlatformViewAndroidDelegate {
+ public:
+ PlatformViewAndroidDelegate(
+ std::shared_ptr<PlatformViewAndroidJNI> jni_facade);
+ void UpdateSemantics(flutter::SemanticsNodeUpdates update,
+ flutter::CustomAccessibilityActionUpdates actions);
+
+ private:
+ const std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;
+};
+} // namespace flutter
+
+#endif // SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_H_
diff --git a/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate_unittests.cc b/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate_unittests.cc
new file mode 100644
index 0000000..56371ff
--- /dev/null
+++ b/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate_unittests.cc
@@ -0,0 +1,96 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "flutter/shell/platform/android/jni/jni_mock.h"
+#include "flutter/shell/platform/android/platform_view_android_delegate/platform_view_android_delegate.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace flutter {
+namespace testing {
+
+TEST(PlatformViewShell, UpdateSemanticsDoesFlutterViewUpdateSemantics) {
+ auto jni_mock = std::make_shared<JNIMock>();
+ auto delegate = std::make_unique<PlatformViewAndroidDelegate>(jni_mock);
+
+ flutter::SemanticsNodeUpdates update;
+ flutter::SemanticsNode node0;
+ node0.id = 0;
+ node0.label = "label";
+ update.insert(std::make_pair(0, std::move(node0)));
+
+ std::vector<uint8_t> expected_buffer(164);
+ size_t position = 0;
+ int32_t* buffer_int32 = reinterpret_cast<int32_t*>(&expected_buffer[0]);
+ float* buffer_float32 = reinterpret_cast<float*>(&expected_buffer[0]);
+ std::vector<std::string> expected_strings;
+ buffer_int32[position++] = node0.id;
+ buffer_int32[position++] = node0.flags;
+ buffer_int32[position++] = node0.actions;
+ buffer_int32[position++] = node0.maxValueLength;
+ buffer_int32[position++] = node0.currentValueLength;
+ buffer_int32[position++] = node0.textSelectionBase;
+ buffer_int32[position++] = node0.textSelectionExtent;
+ buffer_int32[position++] = node0.platformViewId;
+ buffer_int32[position++] = node0.scrollChildren;
+ buffer_int32[position++] = node0.scrollIndex;
+ buffer_float32[position++] = static_cast<float>(node0.scrollPosition);
+ buffer_float32[position++] = static_cast<float>(node0.scrollExtentMax);
+ buffer_float32[position++] = static_cast<float>(node0.scrollExtentMin);
+ buffer_int32[position++] = expected_strings.size(); // node0.label
+ expected_strings.push_back(node0.label);
+ buffer_int32[position++] = -1; // node0.value
+ buffer_int32[position++] = -1; // node0.increasedValue
+ buffer_int32[position++] = -1; // node0.decreasedValue
+ buffer_int32[position++] = -1; // node0.hint
+ buffer_int32[position++] = node0.textDirection;
+ buffer_float32[position++] = node0.rect.left();
+ buffer_float32[position++] = node0.rect.top();
+ buffer_float32[position++] = node0.rect.right();
+ buffer_float32[position++] = node0.rect.bottom();
+ node0.transform.getColMajor(&buffer_float32[position]);
+ position += 16;
+ buffer_int32[position++] = 0; // node0.childrenInTraversalOrder.size();
+ buffer_int32[position++] = 0; // node0.customAccessibilityActions.size();
+
+ EXPECT_CALL(*jni_mock,
+ FlutterViewUpdateSemantics(expected_buffer, expected_strings));
+ // Creates empty custom actions.
+ flutter::CustomAccessibilityActionUpdates actions;
+ delegate->UpdateSemantics(update, actions);
+}
+
+TEST(PlatformViewShell,
+ UpdateSemanticsDoesFlutterViewUpdateCustomAccessibilityActions) {
+ auto jni_mock = std::make_shared<JNIMock>();
+ auto delegate = std::make_unique<PlatformViewAndroidDelegate>(jni_mock);
+
+ flutter::CustomAccessibilityActionUpdates actions;
+ flutter::CustomAccessibilityAction action0;
+ action0.id = 0;
+ action0.overrideId = 1;
+ action0.label = "label";
+ action0.hint = "hint";
+ actions.insert(std::make_pair(0, std::move(action0)));
+
+ std::vector<uint8_t> expected_actions_buffer(16);
+ int32_t* actions_buffer_int32 =
+ reinterpret_cast<int32_t*>(&expected_actions_buffer[0]);
+ std::vector<std::string> expected_action_strings;
+ actions_buffer_int32[0] = action0.id;
+ actions_buffer_int32[1] = action0.overrideId;
+ actions_buffer_int32[2] = expected_action_strings.size();
+ expected_action_strings.push_back(action0.label);
+ actions_buffer_int32[3] = expected_action_strings.size();
+ expected_action_strings.push_back(action0.hint);
+
+ EXPECT_CALL(*jni_mock, FlutterViewUpdateCustomAccessibilityActions(
+ expected_actions_buffer, expected_action_strings));
+ // Creates empty update.
+ flutter::SemanticsNodeUpdates update;
+ delegate->UpdateSemantics(update, actions);
+}
+
+} // namespace testing
+} // namespace flutter
diff --git a/testing/run_tests.py b/testing/run_tests.py
index b799030..bdad851 100755
--- a/testing/run_tests.py
+++ b/testing/run_tests.py
@@ -137,6 +137,7 @@
# https://github.com/google/googletest/issues/2490
RunEngineExecutable(build_dir, 'android_external_view_embedder_unittests', filter, shuffle_flags)
RunEngineExecutable(build_dir, 'jni_unittests', filter, shuffle_flags)
+ RunEngineExecutable(build_dir, 'platform_view_android_delegate_unittests', filter, shuffle_flags)
RunEngineExecutable(build_dir, 'ui_unittests', filter, shuffle_flags)