From 97550907b70f4f3b328b6c1600df21fac1a1889a Mon Sep 17 00:00:00 2001 From: Kevin Chisholm Date: Tue, 2 Apr 2024 18:11:17 -0500 Subject: [PATCH 01/16] [flutter_releases] Flutter beta 3.22.0-0.0.pre Engine Cherrypicks (#51851) # Flutter beta 3.22.0-0.0.pre Engine ## Scheduled Cherrypicks - Roll dart revision: dart-lang/sdk@9bf485fe0 --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 26f76ef350e77..e3ab0fd07eca5 100644 --- a/DEPS +++ b/DEPS @@ -62,7 +62,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': 'bb65648e20e29abc47acf3dd984518d29fd625c3', + 'dart_revision': '9bf485fe0152511517d4123583088cd16fa468b2', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py From 82478f3e1c688bf5afb0e300783b4ea834ca2207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20S=20Guerrero?= Date: Thu, 4 Apr 2024 12:02:02 -0700 Subject: [PATCH 02/16] =?UTF-8?q?[CP]=20Return=20an=20empty=20optional=20i?= =?UTF-8?q?n=20HardwareBuffer::GetSystemUniqueID=20if=20the=20=E2=80=A6=20?= =?UTF-8?q?(#51911)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit b/332811967 …underlying NDK API is unavailable (#51839) --- impeller/toolkit/android/BUILD.gn | 2 ++ impeller/toolkit/android/hardware_buffer.cc | 2 +- impeller/toolkit/android/proc_table.cc | 5 +++++ impeller/toolkit/android/proc_table.h | 4 ++++ .../android/toolkit_android_unittests.cc | 17 +++++++++++++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/impeller/toolkit/android/BUILD.gn b/impeller/toolkit/android/BUILD.gn index e0f83d652b573..758a5a9e9911f 100644 --- a/impeller/toolkit/android/BUILD.gn +++ b/impeller/toolkit/android/BUILD.gn @@ -50,6 +50,8 @@ source_set("unittests_lib") { ":unittests_fixtures", "//flutter/testing", ] + + defines = [ "TESTING" ] } executable("unittests") { diff --git a/impeller/toolkit/android/hardware_buffer.cc b/impeller/toolkit/android/hardware_buffer.cc index b3e6e5afc485d..a9ec935e95900 100644 --- a/impeller/toolkit/android/hardware_buffer.cc +++ b/impeller/toolkit/android/hardware_buffer.cc @@ -108,7 +108,7 @@ std::optional HardwareBuffer::GetSystemUniqueID() const { std::optional HardwareBuffer::GetSystemUniqueID( AHardwareBuffer* buffer) { if (!GetProcTable().AHardwareBuffer_getId) { - return false; + return std::nullopt; } uint64_t out_id = 0u; if (GetProcTable().AHardwareBuffer_getId(buffer, &out_id) != 0) { diff --git a/impeller/toolkit/android/proc_table.cc b/impeller/toolkit/android/proc_table.cc index 71e6ce5c4d14d..24f9f99008a3d 100644 --- a/impeller/toolkit/android/proc_table.cc +++ b/impeller/toolkit/android/proc_table.cc @@ -14,6 +14,11 @@ const ProcTable& GetProcTable() { return gProcTable; } +// Only used by tests. +ProcTable& GetMutableProcTable() { + return const_cast(GetProcTable()); +} + template void ResolveAndroidProc( AndroidProc& proc, diff --git a/impeller/toolkit/android/proc_table.h b/impeller/toolkit/android/proc_table.h index 83b38a1293c79..af398fd396bf9 100644 --- a/impeller/toolkit/android/proc_table.h +++ b/impeller/toolkit/android/proc_table.h @@ -124,6 +124,10 @@ struct ProcTable { const ProcTable& GetProcTable(); +#ifdef TESTING +ProcTable& GetMutableProcTable(); +#endif + } // namespace impeller::android #endif // FLUTTER_IMPELLER_TOOLKIT_ANDROID_PROC_TABLE_H_ diff --git a/impeller/toolkit/android/toolkit_android_unittests.cc b/impeller/toolkit/android/toolkit_android_unittests.cc index 4d26b0bfb2a1e..c0086d4d264eb 100644 --- a/impeller/toolkit/android/toolkit_android_unittests.cc +++ b/impeller/toolkit/android/toolkit_android_unittests.cc @@ -12,6 +12,18 @@ namespace impeller::android::testing { +#define DISABLE_ANDROID_PROC(name) \ + struct Disable##name { \ + Disable##name() { \ + real_proc = GetMutableProcTable().name.proc; \ + GetMutableProcTable().name.proc = nullptr; \ + } \ + ~Disable##name() { \ + GetMutableProcTable().name.proc = real_proc; \ + } \ + decltype(name)* real_proc; \ + } disable##name; + TEST(ToolkitAndroidTest, CanCreateProcTable) { ProcTable proc_table; ASSERT_TRUE(proc_table.IsValid()); @@ -49,6 +61,11 @@ TEST(ToolkitAndroidTest, CanGetHardwareBufferIDs) { ASSERT_TRUE(buffer.GetSystemUniqueID().has_value()); } +TEST(ToolkitAndroidTest, HardwareBufferNullIDIfAPIUnavailable) { + DISABLE_ANDROID_PROC(AHardwareBuffer_getId); + ASSERT_FALSE(HardwareBuffer::GetSystemUniqueID(nullptr).has_value()); +} + TEST(ToolkitAndroidTest, CanDescribeHardwareBufferHandles) { if (!HardwareBuffer::IsAvailableOnPlatform()) { GTEST_SKIP() << "Hardware buffers are not supported on this platform."; From eac479ff0ecae37b575a385469fb53a0a5ed4954 Mon Sep 17 00:00:00 2001 From: Chinmay Garde Date: Mon, 8 Apr 2024 14:32:04 -0700 Subject: [PATCH 03/16] [CP][Impeller] Enable logging a warning when the user opts out of using Impeller. (#51849) (#51914) Part of https://github.com/flutter/flutter/issues/144439 This does two things: * Logs a warning when the embedder requests a non-Impeller preference when creating a shell. * Makes the iOS embedder request a warning be logged when Impeller is not used. I decided to put the warning logs in the shell so that as we get more opinionated about Impeller on other platforms, those platforms can just flip a flag with common log origin. --- common/settings.h | 3 +++ shell/common/shell.cc | 8 +++++++ shell/common/shell_unittests.cc | 24 ++++++++++++++++++- .../framework/Source/FlutterDartProject.mm | 2 ++ .../Source/FlutterDartProjectTest.mm | 5 ++++ 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/common/settings.h b/common/settings.h index a62f1b44a82cb..0145f705b6aa1 100644 --- a/common/settings.h +++ b/common/settings.h @@ -229,6 +229,9 @@ struct Settings { bool enable_impeller = false; #endif + // Log a warning during shell initialization if Impeller is not enabled. + bool warn_on_impeller_opt_out = false; + // The selected Android rendering API. AndroidRenderingAPI android_rendering_api = AndroidRenderingAPI::kSkiaOpenGLES; diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 0228f2744f72d..e53ca5f3e3ad0 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -450,6 +450,14 @@ Shell::Shell(DartVMRef vm, weak_factory_(this) { FML_CHECK(!settings.enable_software_rendering || !settings.enable_impeller) << "Software rendering is incompatible with Impeller."; + if (!settings.enable_impeller && settings.warn_on_impeller_opt_out) { + FML_LOG(IMPORTANT) + << "[Action Required] The application opted out of Impeller by either " + "using the --no-enable-impeller flag or FLTEnableImpeller=false " + "plist flag. This option is going to go away in an upcoming Flutter " + "release. Remove the explicit opt-out. If you need to opt-out, " + "report a bug describing the issue."; + } FML_CHECK(vm_) << "Must have access to VM to create a shell."; FML_DCHECK(task_runners_.IsValid()); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index c145f2b8b6da7..70dfdb4da95b2 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include #define FML_USED_ON_EMBEDDER #include @@ -10,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -4689,6 +4689,28 @@ TEST_F(ShellTest, RuntimeStageBackendWithImpeller) { } #endif // IMPELLER_SUPPORTS_RENDERING +TEST_F(ShellTest, WillLogWarningWhenImpellerIsOptedOut) { +#if !IMPELLER_SUPPORTS_RENDERING + GTEST_SKIP() << "This platform doesn't support Impeller."; +#endif + ASSERT_FALSE(DartVMRef::IsInstanceRunning()); + Settings settings = CreateSettingsForFixture(); + settings.enable_impeller = false; + settings.warn_on_impeller_opt_out = true; + // Log captures are thread specific. Just put the shell in single threaded + // configuration. + const auto& runner = fml::MessageLoop::GetCurrent().GetTaskRunner(); + TaskRunners task_runners("test", runner, runner, runner, runner); + std::ostringstream stream; + fml::LogMessage::CaptureNextLog(&stream); + std::unique_ptr shell = CreateShell(settings, task_runners); + ASSERT_TRUE(stream.str().find( + "[Action Required] The application opted out of Impeller") != + std::string::npos); + ASSERT_TRUE(shell); + DestroyShell(std::move(shell), task_runners); +} + } // namespace testing } // namespace flutter diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm b/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm index 70c1ac7a4742d..2eaf9c359ce7d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm @@ -200,6 +200,8 @@ static BOOL DoesHardwareSupportWideGamut() { } } + settings.warn_on_impeller_opt_out = true; + NSNumber* enableTraceSystrace = [mainBundle objectForInfoDictionaryKey:@"FLTTraceSystrace"]; // Change the default only if the option is present. if (enableTraceSystrace != nil) { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm index 7de95d4771ae8..c68018bbdeb5f 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm @@ -235,6 +235,11 @@ - (void)testDisableImpellerSettingIsCorrectlyParsed { [mockMainBundle stopMocking]; } +- (void)testRequestsWarningWhenImpellerOptOut { + auto settings = FLTDefaultSettingsForBundle(); + XCTAssertEqual(settings.warn_on_impeller_opt_out, YES); +} + - (void)testEnableImpellerSettingIsCorrectlyParsed { id mockMainBundle = OCMPartialMock([NSBundle mainBundle]); OCMStub([mockMainBundle objectForInfoDictionaryKey:@"FLTEnableImpeller"]).andReturn(@"YES"); From 41d578d082a232f06e7a1e06fc1c6e13b3e545ab Mon Sep 17 00:00:00 2001 From: flutteractionsbot <154381524+flutteractionsbot@users.noreply.github.com> Date: Tue, 16 Apr 2024 13:26:22 -0700 Subject: [PATCH 04/16] [CP-beta][Impeller] handle fill polylines with zero area. (#51948) This pull request is created by [automatic cherry pick workflow](https://github.com/flutter/flutter/wiki/Flutter-Cherrypick-Process#automatically-creates-a-cherry-pick-request) Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request. ### Issue Link: What is the link to the issue this cherry-pick is addressing? https://github.com/flutter/flutter/issues/146362 ### Changelog Description: Explain this cherry pick in one line that is accessible to most Flutter developers. See [best practices](https://github.com/flutter/flutter/wiki/Hotfix-Documentation-Best-Practices) for examples Fixes Impeller crash when rendering zero area filled shapes. ### Impact Description: What is the impact (ex. visual jank on Samsung phones, app crash, cannot ship an iOS app)? Does it impact development (ex. flutter doctor crashes when Android Studio is installed), or the shipping production app (the app crashes on launch) Native crash in Impeller renderer. ### Workaround: Is there a workaround for this issue? No ### Risk: What is the risk level of this cherry-pick? ### Test Coverage: Are you confident that your fix is well-tested by automated tests? ### Validation Steps: What are the steps to validate that this fix works? Run the included test --- impeller/tessellator/tessellator.cc | 3 +++ impeller/tessellator/tessellator_unittests.cc | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/impeller/tessellator/tessellator.cc b/impeller/tessellator/tessellator.cc index 665a6248217cb..afbf01da90f83 100644 --- a/impeller/tessellator/tessellator.cc +++ b/impeller/tessellator/tessellator.cc @@ -187,6 +187,9 @@ std::vector Tessellator::TessellateConvex(const Path& path, [this](Path::Polyline::PointBufferPtr point_buffer) { point_buffer_ = std::move(point_buffer); }); + if (polyline.points->size() == 0) { + return output; + } output.reserve(polyline.points->size() + (4 * (polyline.contours.size() - 1))); diff --git a/impeller/tessellator/tessellator_unittests.cc b/impeller/tessellator/tessellator_unittests.cc index 772a794b85f87..fcc2849571571 100644 --- a/impeller/tessellator/tessellator_unittests.cc +++ b/impeller/tessellator/tessellator_unittests.cc @@ -480,6 +480,19 @@ TEST(TessellatorTest, FilledRoundRectTessellationVertices) { Rect::MakeXYWH(5000, 10000, 2000, 3000), {50, 70}); } +TEST(TessellatorTest, EarlyReturnEmptyConvexShape) { + // This path is not technically empty (it has a size in one dimension), + // but is otherwise completely flat. + auto tessellator = std::make_shared(); + PathBuilder builder; + builder.MoveTo({0, 0}); + builder.MoveTo({10, 10}, /*relative=*/true); + + auto points = tessellator->TessellateConvex(builder.TakePath(), 3.0); + + EXPECT_TRUE(points.empty()); +} + #if !NDEBUG TEST(TessellatorTest, ChecksConcurrentPolylineUsage) { auto tessellator = std::make_shared(); From 1deeac84b56450d33fa4be9c7f4f4deb081c6aa8 Mon Sep 17 00:00:00 2001 From: flutteractionsbot <154381524+flutteractionsbot@users.noreply.github.com> Date: Thu, 18 Apr 2024 09:25:03 -0700 Subject: [PATCH 05/16] [CP-beta][Android] post image task to main handler. (#52166) This pull request is created by [automatic cherry pick workflow](https://github.com/flutter/flutter/wiki/Flutter-Cherrypick-Process#automatically-creates-a-cherry-pick-request) Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request. ### Issue Link: What is the link to the issue this cherry-pick is addressing? Test failures in Impeller migration PR: https://github.com/flutter/packages/pull/6461 ### Changelog Description: Explain this cherry pick in one line that is accessible to most Flutter developers. See [best practices](https://github.com/flutter/flutter/wiki/Hotfix-Documentation-Best-Practices) for examples Ensure that Android platform view updates are posted on correct thread when platform view is created on background handler. ### Impact Description: What is the impact (ex. visual jank on Samsung phones, app crash, cannot ship an iOS app)? Does it impact development (ex. flutter doctor crashes when Android Studio is installed), or the shipping production app (the app crashes on launch) Migration to Impeller plugin APIs is blocked. ### Workaround: Is there a workaround for this issue? Disable impeller ### Risk: What is the risk level of this cherry-pick? ### Test Coverage: Are you confident that your fix is well-tested by automated tests? However the tests are in flutter/packages and not flutter/engine. ### Validation Steps: What are the steps to validate that this fix works? Run the unit tests on the linked PR in flutter/packages --- .../io/flutter/embedding/engine/renderer/FlutterRenderer.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java index 3f920cf126b34..673f58bb25d6b 100644 --- a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java +++ b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java @@ -17,6 +17,7 @@ import android.media.ImageReader; import android.os.Build; import android.os.Handler; +import android.os.Looper; import android.view.Surface; import androidx.annotation.Keep; import androidx.annotation.NonNull; @@ -479,7 +480,8 @@ private class PerImageReader { public PerImageReader(ImageReader reader) { this.reader = reader; - reader.setOnImageAvailableListener(onImageAvailableListener, new Handler()); + reader.setOnImageAvailableListener( + onImageAvailableListener, new Handler(Looper.getMainLooper())); } PerImage queueImage(Image image) { From a86e74cf06f7a7f5f3a52a9d6c1e8f62ef1253dc Mon Sep 17 00:00:00 2001 From: godofredoc Date: Thu, 18 Apr 2024 11:47:49 -0700 Subject: [PATCH 06/16] [flutter_releases] Flutter beta 3.22.0-0.2.pre Engine Cherrypicks (#52225) # Flutter beta 3.22.0-0.2.pre Engine ## Scheduled Cherrypicks - Roll dart revision: dart-lang/sdk@58b6ebc2c --- DEPS | 2 +- ci/licenses_golden/licenses_dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index e3ab0fd07eca5..399a4197c3537 100644 --- a/DEPS +++ b/DEPS @@ -62,7 +62,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': '9bf485fe0152511517d4123583088cd16fa468b2', + 'dart_revision': '58b6ebc2c0b637c9c41c6b7fd35a380aa4f856e3', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py diff --git a/ci/licenses_golden/licenses_dart b/ci/licenses_golden/licenses_dart index 7506325a7aff7..ece337df138dc 100644 --- a/ci/licenses_golden/licenses_dart +++ b/ci/licenses_golden/licenses_dart @@ -1,4 +1,4 @@ -Signature: 436d820942d64c56e10183515883c9b6 +Signature: 4f1220293023cdec5a6af5bd69bcb0ab ==================================================================================================== LIBRARY: dart From b4bfd459865a8d636f26aca0d330ae297c006c3c Mon Sep 17 00:00:00 2001 From: Kevin Chisholm Date: Tue, 23 Apr 2024 14:26:01 -0500 Subject: [PATCH 07/16] [flutter_releases] Flutter beta 3.22.0-0.3.pre Engine Cherrypicks (#52328) # Flutter beta 3.22.0-0.3.pre Engine ## Scheduled Cherrypicks - Roll dart revision: dart-lang/sdk@c11d54ec3 --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 399a4197c3537..97852b4f7a042 100644 --- a/DEPS +++ b/DEPS @@ -62,7 +62,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': '58b6ebc2c0b637c9c41c6b7fd35a380aa4f856e3', + 'dart_revision': 'c11d54ec31f06fec07ef8f5d7fd7809546aac9f1', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py From 379386938a92e332abf9ad8cb21d67308c11fefe Mon Sep 17 00:00:00 2001 From: Reid Baker Date: Wed, 1 May 2024 17:13:55 -0400 Subject: [PATCH 08/16] I52370 3.22.cp attempt2 (#52491) - **Replace LinkedLists that are used as a queue in android FlutterRenderer with ArrayDeques (#51494)** - **Workaround HardwareRenderer breakage in Android 14 (#52370)** Fixes https://github.com/flutter/flutter/issues/147644 Includes #51494 to avoid merge conflicts and have a cleaner merge. --- .../FlutterActivityAndFragmentDelegate.java | 2 + .../engine/renderer/FlutterRenderer.java | 30 +++++++++++-- .../platform/PlatformViewsController.java | 19 ++++++++ .../platform/VirtualDisplayController.java | 43 +++++++++++++++++++ .../engine/renderer/FlutterRendererTest.java | 31 ++++++++++++- 5 files changed, 121 insertions(+), 4 deletions(-) diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java b/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java index 2f1156704b982..1f6118bfe56c4 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterActivityAndFragmentDelegate.java @@ -583,6 +583,7 @@ void onPostResume() { ensureAlive(); if (flutterEngine != null) { updateSystemUiOverlays(); + flutterEngine.getPlatformViewsController().onResume(); } else { Log.w(TAG, "onPostResume() invoked before FlutterFragment was attached to an Activity."); } @@ -1020,6 +1021,7 @@ void onTrimMemory(int level) { flutterEngine.getSystemChannel().sendMemoryPressureWarning(); } flutterEngine.getRenderer().onTrimMemory(level); + flutterEngine.getPlatformViewsController().onTrimMemory(level); } } diff --git a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java index 673f58bb25d6b..ee1f633275b46 100644 --- a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java +++ b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java @@ -7,6 +7,7 @@ import static io.flutter.Build.API_LEVELS; import android.annotation.TargetApi; +import android.content.ComponentCallbacks2; import android.graphics.Bitmap; import android.graphics.ImageFormat; import android.graphics.Rect; @@ -29,11 +30,11 @@ import java.io.IOException; import java.lang.ref.WeakReference; import java.nio.ByteBuffer; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; @@ -415,12 +416,18 @@ final class ImageReaderSurfaceProducer // Flip when debugging to see verbose logs. private static final boolean VERBOSE_LOGS = false; + // We must always cleanup on memory pressure on Android 14 due to a bug in Android. + // It is safe to do on all versions so we unconditionally have this set to true. + private static final boolean CLEANUP_ON_MEMORY_PRESSURE = true; + private final long id; private boolean released; // Will be true in tests and on Android API < 33. private boolean ignoringFence = false; + private boolean trimOnMemoryPressure = CLEANUP_ON_MEMORY_PRESSURE; + // The requested width and height are updated by setSize. private int requestedWidth = 1; private int requestedHeight = 1; @@ -434,10 +441,11 @@ final class ImageReaderSurfaceProducer private long lastDequeueTime = 0; private long lastQueueTime = 0; private long lastScheduleTime = 0; + private int numTrims = 0; private Object lock = new Object(); // REQUIRED: The following fields must only be accessed when lock is held. - private final LinkedList imageReaderQueue = new LinkedList(); + private final ArrayDeque imageReaderQueue = new ArrayDeque(); private final HashMap perImageReaders = new HashMap(); private PerImage lastDequeuedImage = null; @@ -457,7 +465,7 @@ public PerImage(Image image, long queuedTime) { /** Internal class: state held per ImageReader. */ private class PerImageReader { public final ImageReader reader; - private final LinkedList imageQueue = new LinkedList(); + private final ArrayDeque imageQueue = new ArrayDeque(); private boolean closed = false; private final ImageReader.OnImageAvailableListener onImageAvailableListener = @@ -651,6 +659,15 @@ PerImage dequeueImage() { @Override public void onTrimMemory(int level) { + if (!trimOnMemoryPressure) { + return; + } + if (level < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { + return; + } + synchronized (lock) { + numTrims++; + } cleanup(); createNewReader = true; } @@ -867,6 +884,13 @@ public int numImageReaders() { } } + @VisibleForTesting + public int numTrims() { + synchronized (lock) { + return numTrims; + } + } + @VisibleForTesting public int numImages() { int r = 0; diff --git a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java index 6e2b2ab250f82..093be1566cb4e 100644 --- a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java +++ b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java @@ -9,6 +9,7 @@ import static io.flutter.Build.API_LEVELS; import android.annotation.TargetApi; +import android.content.ComponentCallbacks2; import android.content.Context; import android.content.MutableContextWrapper; import android.os.Build; @@ -1053,6 +1054,24 @@ private void diposeAllViews() { } } + // Invoked when the Android system is requesting we reduce memory usage. + public void onTrimMemory(int level) { + if (level < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { + return; + } + for (VirtualDisplayController vdc : vdControllers.values()) { + vdc.clearSurface(); + } + } + + // Called after the application has been resumed. + // This is where we undo whatever may have been done in onTrimMemory. + public void onResume() { + for (VirtualDisplayController vdc : vdControllers.values()) { + vdc.resetSurface(); + } + } + /** * Disposes a single * diff --git a/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java b/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java index 5de42299e00c4..cdde0687a4a99 100644 --- a/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java +++ b/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java @@ -284,6 +284,49 @@ public void dispatchTouchEvent(MotionEvent event) { presentation.dispatchTouchEvent(event); } + public void clearSurface() { + virtualDisplay.setSurface(null); + } + + public void resetSurface() { + final int width = getRenderTargetWidth(); + final int height = getRenderTargetHeight(); + final boolean isFocused = getView().isFocused(); + final SingleViewPresentation.PresentationState presentationState = presentation.detachState(); + + // We detach the surface to prevent it being destroyed when releasing the vd. + virtualDisplay.setSurface(null); + virtualDisplay.release(); + final DisplayManager displayManager = + (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); + int flags = 0; + virtualDisplay = + displayManager.createVirtualDisplay( + "flutter-vd#" + viewId, + width, + height, + densityDpi, + renderTarget.getSurface(), + flags, + callback, + null /* handler */); + // Create a new SingleViewPresentation and show() it before we cancel() the existing + // presentation. Calling show() and cancel() in this order fixes + // https://github.com/flutter/flutter/issues/26345 and maintains seamless transition + // of the contents of the presentation. + SingleViewPresentation newPresentation = + new SingleViewPresentation( + context, + virtualDisplay.getDisplay(), + accessibilityEventsDelegate, + presentationState, + focusChangeListener, + isFocused); + newPresentation.show(); + presentation.cancel(); + presentation = newPresentation; + } + static class OneTimeOnDrawListener implements ViewTreeObserver.OnDrawListener { static void schedule(View view, Runnable runnable) { OneTimeOnDrawListener listener = new OneTimeOnDrawListener(view, runnable); diff --git a/shell/platform/android/test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java b/shell/platform/android/test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java index 50f83d5fb8e0a..f19da788d3759 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/renderer/FlutterRendererTest.java @@ -647,12 +647,41 @@ public void ImageReaderSurfaceProducerTrimMemoryCallback() { assertEquals(1, texture.numImageReaders()); assertEquals(1, texture.numImages()); - // Invoke the onTrimMemory callback. + // Invoke the onTrimMemory callback with level 0. + // This should do nothing. texture.onTrimMemory(0); shadowOf(Looper.getMainLooper()).idle(); + assertEquals(1, texture.numImageReaders()); + assertEquals(1, texture.numImages()); + assertEquals(0, texture.numTrims()); + + // Invoke the onTrimMemory callback with level 40. + // This should result in a trim. + texture.onTrimMemory(40); + shadowOf(Looper.getMainLooper()).idle(); + assertEquals(0, texture.numImageReaders()); assertEquals(0, texture.numImages()); + assertEquals(1, texture.numTrims()); + + // Request the surface, this should result in a new image reader. + surface = texture.getSurface(); + assertEquals(1, texture.numImageReaders()); + assertEquals(0, texture.numImages()); + assertEquals(1, texture.numTrims()); + + // Render an image. + canvas = surface.lockHardwareCanvas(); + canvas.drawARGB(255, 255, 0, 0); + surface.unlockCanvasAndPost(canvas); + + // Let callbacks run, this will produce a single frame. + shadowOf(Looper.getMainLooper()).idle(); + + assertEquals(1, texture.numImageReaders()); + assertEquals(1, texture.numImages()); + assertEquals(1, texture.numTrims()); } // A 0x0 ImageReader is a runtime error. From f6344b75dcf861d8bf1f1322780b8811f982e31a Mon Sep 17 00:00:00 2001 From: Kevin Chisholm Date: Tue, 7 May 2024 15:34:58 -0500 Subject: [PATCH 09/16] [flutter_releases] Flutter stable 3.22.0 Engine Cherrypicks (#52625) # Flutter stable 3.22.0 Engine ## Scheduled Cherrypicks - Roll dart revision: dart-lang/sdk@a210745c4 --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 97852b4f7a042..cec3f632f4a05 100644 --- a/DEPS +++ b/DEPS @@ -62,7 +62,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': 'c11d54ec31f06fec07ef8f5d7fd7809546aac9f1', + 'dart_revision': 'a210745c4f35d47009c415ca9e087427ce19f85a', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py From 8c2843102f4b1ec6c65ba47ed535f0cddfee26c4 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 21 May 2024 05:46:20 -0700 Subject: [PATCH 10/16] [Impeller] Vulkan validation off by default. (#52397) (#52904) Fixes https://github.com/flutter/flutter/issues/142659 can be turned on via --enable-vulkan-validation cmd line flag. Cherry pick request to unbreak android emulators. --- .../embedding/engine/loader/FlutterLoader.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java index 5e800e80f327a..b540c20e14caf 100644 --- a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java +++ b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java @@ -4,15 +4,12 @@ package io.flutter.embedding.engine.loader; -import static io.flutter.Build.API_LEVELS; - import android.app.ActivityManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.hardware.display.DisplayManager; -import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -237,13 +234,6 @@ public InitResult call() { } } - private static boolean areValidationLayersOnByDefault() { - if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= API_LEVELS.API_26) { - return Build.SUPPORTED_ABIS[0].equals("arm64-v8a"); - } - return false; - } - /** * Blocks until initialization of the native system has completed. * @@ -353,8 +343,7 @@ public void ensureInitializationComplete( if (metaData.getBoolean(ENABLE_IMPELLER_META_DATA_KEY, false)) { shellArgs.add("--enable-impeller"); } - if (metaData.getBoolean( - ENABLE_VULKAN_VALIDATION_META_DATA_KEY, areValidationLayersOnByDefault())) { + if (metaData.getBoolean(ENABLE_VULKAN_VALIDATION_META_DATA_KEY, false)) { shellArgs.add("--enable-vulkan-validation"); } if (metaData.getBoolean(IMPELLER_OPENGL_GPU_TRACING_DATA_KEY, false)) { From 55eae6864b296dd9f43b2cc7577ec256e5c32a8d Mon Sep 17 00:00:00 2001 From: Kevin Chisholm Date: Tue, 21 May 2024 18:44:20 -0500 Subject: [PATCH 11/16] [flutter_releases] Flutter stable 3.22.1 Engine Cherrypicks (#52969) # Flutter stable 3.22.1 Engine ## Scheduled Cherrypicks - Roll dart revision: dart-lang/sdk@b0e7f171c --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index cec3f632f4a05..cf799245e4197 100644 --- a/DEPS +++ b/DEPS @@ -62,7 +62,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/main/DEPS # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': 'a210745c4f35d47009c415ca9e087427ce19f85a', + 'dart_revision': 'b0e7f171c7c9ab82944ffd6918b80a0df36e0549', # WARNING: DO NOT EDIT MANUALLY # The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py From bc389176a7467d0e14a8317c47864cd6c32cd33d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20P=C3=89RON?= Date: Wed, 19 Jun 2024 16:25:06 +0200 Subject: [PATCH 12/16] expose Smantics.identifier as Windows AutomationId --- shell/platform/common/accessibility_bridge.cc | 9 +++++++++ shell/platform/common/accessibility_bridge.h | 2 ++ shell/platform/common/flutter_platform_node_delegate.cc | 6 ++++++ shell/platform/common/flutter_platform_node_delegate.h | 3 +++ shell/platform/embedder/embedder.h | 2 ++ shell/platform/embedder/embedder_semantics_update.cc | 1 + shell/platform/windows/flutter_window.cc | 4 ---- shell/platform/windows/window_unittests.cc | 2 -- third_party/accessibility/ax/ax_enum_util.cc | 2 ++ third_party/accessibility/ax/ax_enums.h | 1 + third_party/accessibility/ax/ax_node_data.cc | 3 +++ 11 files changed, 29 insertions(+), 6 deletions(-) diff --git a/shell/platform/common/accessibility_bridge.cc b/shell/platform/common/accessibility_bridge.cc index 9a6e02065ee64..9e813e0072f7b 100644 --- a/shell/platform/common/accessibility_bridge.cc +++ b/shell/platform/common/accessibility_bridge.cc @@ -280,6 +280,7 @@ void AccessibilityBridge::ConvertFlutterUpdate(const SemanticsNode& node, SetIntAttributesFromFlutterUpdate(node_data, node); SetIntListAttributesFromFlutterUpdate(node_data, node); SetStringListAttributesFromFlutterUpdate(node_data, node); + SetIdentifierFromFlutterUpdate(node_data, node); SetNameFromFlutterUpdate(node_data, node); SetValueFromFlutterUpdate(node_data, node); SetTooltipFromFlutterUpdate(node_data, node); @@ -519,6 +520,11 @@ void AccessibilityBridge::SetStringListAttributesFromFlutterUpdate( } } +void AccessibilityBridge::SetIdentifierFromFlutterUpdate(ui::AXNodeData& node_data, + const SemanticsNode& node) { + node_data.AddStringAttribute(ax::mojom::StringAttribute::kAuthorUniqueId, node.identifier); +} + void AccessibilityBridge::SetNameFromFlutterUpdate(ui::AXNodeData& node_data, const SemanticsNode& node) { node_data.SetName(node.label); @@ -587,6 +593,9 @@ AccessibilityBridge::FromFlutterSemanticsNode( result.scroll_extent_min = flutter_node.scroll_extent_min; result.elevation = flutter_node.elevation; result.thickness = flutter_node.thickness; + if (flutter_node.identifier) { + result.identifier = std::string(flutter_node.identifier); + } if (flutter_node.label) { result.label = std::string(flutter_node.label); } diff --git a/shell/platform/common/accessibility_bridge.h b/shell/platform/common/accessibility_bridge.h index 7e6698021b726..dd8df537a41f0 100644 --- a/shell/platform/common/accessibility_bridge.h +++ b/shell/platform/common/accessibility_bridge.h @@ -172,6 +172,7 @@ class AccessibilityBridge double scroll_extent_min; double elevation; double thickness; + std::string identifier; std::string label; std::string hint; std::string value; @@ -227,6 +228,7 @@ class AccessibilityBridge const SemanticsNode& node); void SetStringListAttributesFromFlutterUpdate(ui::AXNodeData& node_data, const SemanticsNode& node); + void SetIdentifierFromFlutterUpdate(ui::AXNodeData& node_data, const SemanticsNode& node); void SetNameFromFlutterUpdate(ui::AXNodeData& node_data, const SemanticsNode& node); void SetValueFromFlutterUpdate(ui::AXNodeData& node_data, diff --git a/shell/platform/common/flutter_platform_node_delegate.cc b/shell/platform/common/flutter_platform_node_delegate.cc index 9e4e8a4a2b111..871b1e6418d2c 100644 --- a/shell/platform/common/flutter_platform_node_delegate.cc +++ b/shell/platform/common/flutter_platform_node_delegate.cc @@ -5,6 +5,7 @@ #include "flutter_platform_node_delegate.h" #include +#include #include "flutter/shell/platform/common/accessibility_bridge.h" #include "flutter/third_party/accessibility/ax/ax_action_data.h" @@ -61,6 +62,11 @@ const ui::AXNodeData& FlutterPlatformNodeDelegate::GetData() const { return ax_node_->data(); } +std::u16string FlutterPlatformNodeDelegate::GetAuthorUniqueId() const { + std::wstring_convert, char16_t> convert; + return convert.from_bytes(GetData().GetStringAttribute(ax::mojom::StringAttribute::kAuthorUniqueId)); +} + gfx::NativeViewAccessible FlutterPlatformNodeDelegate::GetParent() { if (!ax_node_->parent()) { return nullptr; diff --git a/shell/platform/common/flutter_platform_node_delegate.h b/shell/platform/common/flutter_platform_node_delegate.h index 6172f4f86b9f2..bad838cb6ec5b 100644 --- a/shell/platform/common/flutter_platform_node_delegate.h +++ b/shell/platform/common/flutter_platform_node_delegate.h @@ -101,6 +101,9 @@ class FlutterPlatformNodeDelegate : public ui::AXPlatformNodeDelegateBase { // |ui::AXPlatformNodeDelegateBase| const ui::AXUniqueId& GetUniqueId() const override { return unique_id_; } + // |ui::AXPlatformNodeDelegateBase| + std::u16string GetAuthorUniqueId() const override; + // |ui::AXPlatformNodeDelegateBase| const ui::AXNodeData& GetData() const override; diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index d26e2215adf3a..95e2c04da0d43 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -1308,6 +1308,8 @@ typedef struct { double elevation; /// Describes how much space the semantics node takes up along the z-axis. double thickness; + /// A technical identifier for the node. + const char* identifier; /// A textual description of the node. const char* label; /// A brief description of the result of performing an action on the node. diff --git a/shell/platform/embedder/embedder_semantics_update.cc b/shell/platform/embedder/embedder_semantics_update.cc index 1670d7c7341e6..a47b679bf0194 100644 --- a/shell/platform/embedder/embedder_semantics_update.cc +++ b/shell/platform/embedder/embedder_semantics_update.cc @@ -153,6 +153,7 @@ void EmbedderSemanticsUpdate2::AddNode(const SemanticsNode& node) { node.scrollExtentMin, node.elevation, node.thickness, + node.identifier.c_str(), node.label.c_str(), node.hint.c_str(), node.value.c_str(), diff --git a/shell/platform/windows/flutter_window.cc b/shell/platform/windows/flutter_window.cc index 82e6cd9c486e5..3fb6121d68f9e 100644 --- a/shell/platform/windows/flutter_window.cc +++ b/shell/platform/windows/flutter_window.cc @@ -806,12 +806,9 @@ LRESULT FlutterWindow::OnGetObject(UINT const message, } gfx::NativeViewAccessible root_view = GetNativeViewAccessible(); - // TODO(schectman): UIA is currently disabled by default. - // https://github.com/flutter/flutter/issues/114547 if (root_view) { CreateAxFragmentRoot(); if (is_uia_request) { -#ifdef FLUTTER_ENGINE_USE_UIA // Retrieve UIA object for the root view. Microsoft::WRL::ComPtr root; if (SUCCEEDED( @@ -824,7 +821,6 @@ LRESULT FlutterWindow::OnGetObject(UINT const message, } else { FML_LOG(ERROR) << "Failed to query AX fragment root."; } -#endif // FLUTTER_ENGINE_USE_UIA } else if (is_msaa_request) { // Create the accessibility root if it does not already exist. // Return the IAccessible for the root view. diff --git a/shell/platform/windows/window_unittests.cc b/shell/platform/windows/window_unittests.cc index 97b3f70c55127..d1a77cfeb3334 100644 --- a/shell/platform/windows/window_unittests.cc +++ b/shell/platform/windows/window_unittests.cc @@ -366,9 +366,7 @@ TEST(MockWindow, DISABLED_GetObjectUia) { bool uia_called = false; ON_CALL(window, OnGetObject) .WillByDefault(Invoke([&uia_called](UINT msg, WPARAM wpar, LPARAM lpar) { -#ifdef FLUTTER_ENGINE_USE_UIA uia_called = true; -#endif // FLUTTER_ENGINE_USE_UIA return static_cast(0); })); EXPECT_CALL(window, OnGetObject).Times(1); diff --git a/third_party/accessibility/ax/ax_enum_util.cc b/third_party/accessibility/ax/ax_enum_util.cc index daa93b61bbc3e..bfea23a962c95 100644 --- a/third_party/accessibility/ax/ax_enum_util.cc +++ b/third_party/accessibility/ax/ax_enum_util.cc @@ -1461,6 +1461,8 @@ const char* ToString(ax::mojom::StringAttribute string_attribute) { return "url"; case ax::mojom::StringAttribute::kValue: return "value"; + case ax::mojom::StringAttribute::kAuthorUniqueId: + return "authorUniqueId"; } return ""; diff --git a/third_party/accessibility/ax/ax_enums.h b/third_party/accessibility/ax/ax_enums.h index 1a444cdeea54e..04fdcb949abbd 100644 --- a/third_party/accessibility/ax/ax_enums.h +++ b/third_party/accessibility/ax/ax_enums.h @@ -555,6 +555,7 @@ enum class StringAttribute { kValue, kMinValue = kNone, kMaxValue = kValue, + kAuthorUniqueId, }; enum class IntAttribute { diff --git a/third_party/accessibility/ax/ax_node_data.cc b/third_party/accessibility/ax/ax_node_data.cc index f13be3d2e6ef9..e70ce3e68e2e4 100644 --- a/third_party/accessibility/ax/ax_node_data.cc +++ b/third_party/accessibility/ax/ax_node_data.cc @@ -1520,6 +1520,9 @@ std::string AXNodeData::ToString() const { break; case ax::mojom::StringAttribute::kNone: break; + case ax::mojom::StringAttribute::kAuthorUniqueId: + result += " author_unique_id=" + value; + break; } } From 74e80337a38284ea23f0af8c91d4ab73bb2eea1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20P=C3=89RON?= Date: Wed, 19 Jun 2024 16:34:26 +0200 Subject: [PATCH 13/16] fix format --- shell/platform/common/accessibility_bridge.cc | 8 +++++--- shell/platform/common/accessibility_bridge.h | 3 ++- shell/platform/common/flutter_platform_node_delegate.cc | 5 +++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/shell/platform/common/accessibility_bridge.cc b/shell/platform/common/accessibility_bridge.cc index 9e813e0072f7b..0987986ad3c88 100644 --- a/shell/platform/common/accessibility_bridge.cc +++ b/shell/platform/common/accessibility_bridge.cc @@ -520,9 +520,11 @@ void AccessibilityBridge::SetStringListAttributesFromFlutterUpdate( } } -void AccessibilityBridge::SetIdentifierFromFlutterUpdate(ui::AXNodeData& node_data, - const SemanticsNode& node) { - node_data.AddStringAttribute(ax::mojom::StringAttribute::kAuthorUniqueId, node.identifier); +void AccessibilityBridge::SetIdentifierFromFlutterUpdate( + ui::AXNodeData& node_data, + const SemanticsNode& node) { + node_data.AddStringAttribute(ax::mojom::StringAttribute::kAuthorUniqueId, + node.identifier); } void AccessibilityBridge::SetNameFromFlutterUpdate(ui::AXNodeData& node_data, diff --git a/shell/platform/common/accessibility_bridge.h b/shell/platform/common/accessibility_bridge.h index dd8df537a41f0..5877207ea5087 100644 --- a/shell/platform/common/accessibility_bridge.h +++ b/shell/platform/common/accessibility_bridge.h @@ -228,7 +228,8 @@ class AccessibilityBridge const SemanticsNode& node); void SetStringListAttributesFromFlutterUpdate(ui::AXNodeData& node_data, const SemanticsNode& node); - void SetIdentifierFromFlutterUpdate(ui::AXNodeData& node_data, const SemanticsNode& node); + void SetIdentifierFromFlutterUpdate(ui::AXNodeData& node_data, + const SemanticsNode& node); void SetNameFromFlutterUpdate(ui::AXNodeData& node_data, const SemanticsNode& node); void SetValueFromFlutterUpdate(ui::AXNodeData& node_data, diff --git a/shell/platform/common/flutter_platform_node_delegate.cc b/shell/platform/common/flutter_platform_node_delegate.cc index 871b1e6418d2c..4a8dcffb6c803 100644 --- a/shell/platform/common/flutter_platform_node_delegate.cc +++ b/shell/platform/common/flutter_platform_node_delegate.cc @@ -4,8 +4,8 @@ #include "flutter_platform_node_delegate.h" -#include #include +#include #include "flutter/shell/platform/common/accessibility_bridge.h" #include "flutter/third_party/accessibility/ax/ax_action_data.h" @@ -64,7 +64,8 @@ const ui::AXNodeData& FlutterPlatformNodeDelegate::GetData() const { std::u16string FlutterPlatformNodeDelegate::GetAuthorUniqueId() const { std::wstring_convert, char16_t> convert; - return convert.from_bytes(GetData().GetStringAttribute(ax::mojom::StringAttribute::kAuthorUniqueId)); + return convert.from_bytes(GetData().GetStringAttribute( + ax::mojom::StringAttribute::kAuthorUniqueId)); } gfx::NativeViewAccessible FlutterPlatformNodeDelegate::GetParent() { From 08d00d5814279f460b7ee52642d45351a4b5aad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20P=C3=89RON?= Date: Fri, 21 Jun 2024 06:25:15 +0200 Subject: [PATCH 14/16] fix enum --- third_party/accessibility/ax/ax_enum_util.cc | 2 ++ third_party/accessibility/ax/ax_enums.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/third_party/accessibility/ax/ax_enum_util.cc b/third_party/accessibility/ax/ax_enum_util.cc index bfea23a962c95..b925f16300228 100644 --- a/third_party/accessibility/ax/ax_enum_util.cc +++ b/third_party/accessibility/ax/ax_enum_util.cc @@ -1523,6 +1523,8 @@ ax::mojom::StringAttribute ParseStringAttribute(const char* string_attribute) { return ax::mojom::StringAttribute::kUrl; if (0 == strcmp(string_attribute, "value")) return ax::mojom::StringAttribute::kValue; + if (0 == strcmp(string_attribute, "authorUniqueId")) + return ax::mojom::StringAttribute::kAuthorUniqueId; return ax::mojom::StringAttribute::kNone; } diff --git a/third_party/accessibility/ax/ax_enums.h b/third_party/accessibility/ax/ax_enums.h index 04fdcb949abbd..454c529cb1019 100644 --- a/third_party/accessibility/ax/ax_enums.h +++ b/third_party/accessibility/ax/ax_enums.h @@ -523,6 +523,7 @@ enum class StringAttribute { kAccessKey, // Only used when invalid_state == invalid_state_other. kAriaInvalidValue, + kAuthorUniqueId, kAutoComplete, kChildTreeId, kClassName, @@ -555,7 +556,6 @@ enum class StringAttribute { kValue, kMinValue = kNone, kMaxValue = kValue, - kAuthorUniqueId, }; enum class IntAttribute { From eeaf0b50a8333784016a4c9af4911687faf73b90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20P=C3=89RON?= Date: Fri, 21 Jun 2024 06:25:31 +0200 Subject: [PATCH 15/16] fix unittest --- .../platform/common/flutter_platform_node_delegate_unittests.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/platform/common/flutter_platform_node_delegate_unittests.cc b/shell/platform/common/flutter_platform_node_delegate_unittests.cc index 00e3240fa4f6c..c158c5bbc342c 100644 --- a/shell/platform/common/flutter_platform_node_delegate_unittests.cc +++ b/shell/platform/common/flutter_platform_node_delegate_unittests.cc @@ -46,6 +46,7 @@ TEST(FlutterPlatformNodeDelegateTest, canPerfomActions) { root.actions = static_cast(0); root.text_selection_base = -1; root.text_selection_extent = -1; + root.identifier = ""; root.label = "root"; root.hint = ""; root.value = ""; From 99a5a458568c5d04b0ee8951d8bbe60776c04b42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20P=C3=89RON?= Date: Thu, 4 Jul 2024 14:38:36 +0200 Subject: [PATCH 16/16] Use string conversions functions in fml/platform/win/wstring_conversion.h --- shell/platform/common/flutter_platform_node_delegate.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shell/platform/common/flutter_platform_node_delegate.cc b/shell/platform/common/flutter_platform_node_delegate.cc index 4a8dcffb6c803..32a0824fc31a2 100644 --- a/shell/platform/common/flutter_platform_node_delegate.cc +++ b/shell/platform/common/flutter_platform_node_delegate.cc @@ -4,9 +4,9 @@ #include "flutter_platform_node_delegate.h" -#include #include +#include "flutter/fml/platform/win/wstring_conversion.h" #include "flutter/shell/platform/common/accessibility_bridge.h" #include "flutter/third_party/accessibility/ax/ax_action_data.h" #include "flutter/third_party/accessibility/ax/ax_tree_manager_map.h" @@ -63,9 +63,9 @@ const ui::AXNodeData& FlutterPlatformNodeDelegate::GetData() const { } std::u16string FlutterPlatformNodeDelegate::GetAuthorUniqueId() const { - std::wstring_convert, char16_t> convert; - return convert.from_bytes(GetData().GetStringAttribute( - ax::mojom::StringAttribute::kAuthorUniqueId)); + return fml::WideStringToUtf16( + fml::Utf8ToWideString(GetData().GetStringAttribute( + ax::mojom::StringAttribute::kAuthorUniqueId))); } gfx::NativeViewAccessible FlutterPlatformNodeDelegate::GetParent() {