diff --git a/.github/workflows/analyze.yml b/.github/workflows/analyze.yml index 6991a9a..22e9837 100644 --- a/.github/workflows/analyze.yml +++ b/.github/workflows/analyze.yml @@ -6,7 +6,7 @@ jobs: format: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: path: src diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index c7c08fd..0553d09 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -6,7 +6,7 @@ jobs: testbed: runs-on: ubuntu-latest steps: - - uses: docker/login-action@v2 + - uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.repository_owner }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b36029e..a13a914 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,11 +19,11 @@ jobs: triple: i686-linux-gnu steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: path: src - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: src/sysroot* key: sysroot-${{ matrix.api-version }} @@ -67,26 +67,26 @@ jobs: --target-dir build ninja -C src/out/build - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: tizen-${{ matrix.api-version }}-${{ matrix.arch }} path: src/out/build/libflutter_tizen*.so if-no-files-found: error - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: tizen-${{ matrix.api-version }}-${{ matrix.arch }}_unittests path: src/out/build/flutter_tizen_unittests if-no-files-found: error - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: ${{ github.event_name == 'push' }} with: name: tizen-${{ matrix.api-version }}-${{ matrix.arch }}_symbols path: src/out/build/so.unstripped/libflutter_tizen*.so if-no-files-found: error - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: ${{ matrix.arch == 'arm' && matrix.api-version == 5.5 }} with: name: tizen-common @@ -101,19 +101,19 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: docker/setup-qemu-action@v2 + - uses: docker/setup-qemu-action@v3 with: platforms: arm - - uses: docker/login-action@v2 + - uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: tizen-5.5-arm_unittests @@ -134,9 +134,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 - name: Create archives run: | @@ -148,7 +148,7 @@ jobs: - name: Set variable run: echo "SHORT_SHA=$(git rev-parse --short $GITHUB_SHA)" >> $GITHUB_ENV - - uses: softprops/action-gh-release@v1 + - uses: softprops/action-gh-release@v2 with: name: tizen-embedder-${{ env.SHORT_SHA }} tag_name: ${{ env.SHORT_SHA }} diff --git a/.github/workflows/check-symbols.yml b/.github/workflows/check-symbols.yml index 6ef18ed..a671e12 100644 --- a/.github/workflows/check-symbols.yml +++ b/.github/workflows/check-symbols.yml @@ -13,9 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: flutter-tizen/tizen_allowlist token: ${{ secrets.TIZENAPI_TOKEN }} diff --git a/flutter/shell/platform/common/client_wrapper/core_implementations.cc b/flutter/shell/platform/common/client_wrapper/core_implementations.cc index 1eb5a58..f682f1b 100644 --- a/flutter/shell/platform/common/client_wrapper/core_implementations.cc +++ b/flutter/shell/platform/common/client_wrapper/core_implementations.cc @@ -19,6 +19,8 @@ #include "binary_messenger_impl.h" #include "include/flutter/engine_method_result.h" +#include "include/flutter/method_channel.h" +#include "include/flutter/standard_method_codec.h" #include "texture_registrar_impl.h" namespace flutter { @@ -164,6 +166,46 @@ void ReplyManager::SendResponseData(const std::vector* data) { } // namespace internal +// ========== method_channel.h ========== + +namespace { + +constexpr char kControlChannelName[] = "dev.flutter/channel-buffers"; +constexpr char kResizeMethod[] = "resize"; +constexpr char kOverflowMethod[] = "overflow"; + +} // namespace + +namespace internal { + +void ResizeChannel(BinaryMessenger* messenger, std::string name, int new_size) { + auto control_channel = std::make_unique>( + messenger, kControlChannelName, &StandardMethodCodec::GetInstance()); + + // The deserialization logic handles only 32 bits values, see + // https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L495. + control_channel->InvokeMethod( + kResizeMethod, std::make_unique(EncodableList{ + EncodableValue(name), + EncodableValue(static_cast(new_size)), + })); +} + +void SetChannelWarnsOnOverflow(BinaryMessenger* messenger, + std::string name, + bool warns) { + auto control_channel = std::make_unique>( + messenger, kControlChannelName, &StandardMethodCodec::GetInstance()); + + control_channel->InvokeMethod(kOverflowMethod, + std::make_unique(EncodableList{ + EncodableValue(name), + EncodableValue(!warns), + })); +} + +} // namespace internal + // ========== texture_registrar_impl.h ========== TextureRegistrarImpl::TextureRegistrarImpl( diff --git a/flutter/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h b/flutter/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h index c081946..5ab7575 100644 --- a/flutter/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h +++ b/flutter/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h @@ -13,6 +13,26 @@ namespace flutter { +namespace internal { +// Internal helper functions used by BasicMessageChannel and MethodChannel. + +// Adjusts the number of messages that will get buffered when sending messages +// to channels that aren't fully set up yet. For example, the engine isn't +// running yet or the channel's message handler isn't set up on the Dart side +// yet. +void ResizeChannel(BinaryMessenger* messenger, std::string name, int new_size); + +// Defines whether the channel should show warning messages when discarding +// messages due to overflow. +// +// When |warns| is false, the channel is expected to overflow and warning +// messages will not be shown. +void SetChannelWarnsOnOverflow(BinaryMessenger* messenger, + std::string name, + bool warns); + +} // namespace internal + class EncodableValue; // A message reply callback. @@ -99,6 +119,23 @@ class BasicMessageChannel { messenger_->SetMessageHandler(name_, std::move(binary_handler)); } + // Adjusts the number of messages that will get buffered when sending messages + // to channels that aren't fully set up yet. For example, the engine isn't + // running yet or the channel's message handler isn't set up on the Dart side + // yet. + void Resize(int new_size) { + internal::ResizeChannel(messenger_, name_, new_size); + } + + // Defines whether the channel should show warning messages when discarding + // messages due to overflow. + // + // When |warns| is false, the channel is expected to overflow and warning + // messages will not be shown. + void SetWarnsOnOverflow(bool warns) { + internal::SetChannelWarnsOnOverflow(messenger_, name_, warns); + } + private: BinaryMessenger* messenger_; std::string name_; diff --git a/flutter/shell/platform/common/client_wrapper/include/flutter/method_call.h b/flutter/shell/platform/common/client_wrapper/include/flutter/method_call.h index f9a9c28..3ddf71c 100644 --- a/flutter/shell/platform/common/client_wrapper/include/flutter/method_call.h +++ b/flutter/shell/platform/common/client_wrapper/include/flutter/method_call.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_TYPED_METHOD_CALL_H_ -#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_TYPED_METHOD_CALL_H_ +#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CALL_H_ +#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CALL_H_ #include #include @@ -40,4 +40,4 @@ class MethodCall { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_TYPED_METHOD_CALL_H_ +#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CALL_H_ diff --git a/flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h b/flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h index 6e39a64..a4029fc 100644 --- a/flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h +++ b/flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h @@ -8,6 +8,7 @@ #include #include +#include "basic_message_channel.h" #include "binary_messenger.h" #include "engine_method_result.h" #include "method_call.h" @@ -122,6 +123,23 @@ class MethodChannel { messenger_->SetMessageHandler(name_, std::move(binary_handler)); } + // Adjusts the number of messages that will get buffered when sending messages + // to channels that aren't fully set up yet. For example, the engine isn't + // running yet or the channel's message handler isn't set up on the Dart side + // yet. + void Resize(int new_size) { + internal::ResizeChannel(messenger_, name_, new_size); + } + + // Defines whether the channel should show warning messages when discarding + // messages due to overflow. + // + // When |warns| is false, the channel is expected to overflow and warning + // messages will not be shown. + void SetWarnsOnOverflow(bool warns) { + internal::SetChannelWarnsOnOverflow(messenger_, name_, warns); + } + private: BinaryMessenger* messenger_; std::string name_; diff --git a/flutter/shell/platform/embedder/embedder.h b/flutter/shell/platform/embedder/embedder.h index f119740..d8adf5e 100644 --- a/flutter/shell/platform/embedder/embedder.h +++ b/flutter/shell/platform/embedder/embedder.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_EMBEDDER_H_ -#define FLUTTER_EMBEDDER_H_ +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_H_ #include #include @@ -25,9 +25,9 @@ // - Function signatures (names, argument counts, argument order, and argument // type) cannot change. // - The core behavior of existing functions cannot change. -// - Instead of nesting structures by value within another structure, prefer -// nesting by pointer. This ensures that adding members to the nested struct -// does not break the ABI of the parent struct. +// - Instead of nesting structures by value within another structure/union, +// prefer nesting by pointer. This ensures that adding members to the nested +// struct does not break the ABI of the parent struct/union. // - Instead of array of structures, prefer array of pointers to structures. // This ensures that array indexing does not break if members are added // to the structure. @@ -236,6 +236,11 @@ typedef enum { kFlutterSemanticsFlagIsKeyboardKey = 1 << 24, /// Whether the semantics node represents a tristate checkbox in mixed state. kFlutterSemanticsFlagIsCheckStateMixed = 1 << 25, + /// The semantics node has the quality of either being "expanded" or + /// "collapsed". + kFlutterSemanticsFlagHasExpandedState = 1 << 26, + /// Whether a semantic node that hasExpandedState is currently expanded. + kFlutterSemanticsFlagIsExpanded = 1 << 27, } FlutterSemanticsFlag; typedef enum { @@ -261,6 +266,12 @@ typedef enum { typedef struct _FlutterEngine* FLUTTER_API_SYMBOL(FlutterEngine); +/// Unique identifier for views. +/// +/// View IDs are generated by the embedder and are +/// opaque to the engine; the engine does not interpret view IDs in any way. +typedef int64_t FlutterViewId; + typedef struct { /// horizontal scale factor double scaleX; @@ -752,6 +763,11 @@ typedef struct { /// The queue family index of the VkQueue supplied in the next field. uint32_t queue_family_index; /// VkQueue handle. + /// The queue should not be used without protection from a mutex to make sure + /// it is not used simultaneously with other threads. That mutex should match + /// the one injected via the |get_instance_proc_address_callback|. + /// There is a proposal to remove the need for the mutex at + /// https://github.com/flutter/flutter/issues/134573. FlutterVulkanQueueHandle queue; /// The number of instance extensions available for enumerating in the next /// field. @@ -775,6 +791,12 @@ typedef struct { /// For example: VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME const char** enabled_device_extensions; /// The callback invoked when resolving Vulkan function pointers. + /// At a bare minimum this should be used to swap out any calls that operate + /// on vkQueue's for threadsafe variants that obtain locks for their duration. + /// The functions to swap out are "vkQueueSubmit" and "vkQueueWaitIdle". An + /// example of how to do that can be found in the test + /// "EmbedderTest.CanSwapOutVulkanCalls" unit-test in + /// //shell/platform/embedder/tests/embedder_vk_unittests.cc. FlutterVulkanInstanceProcAddressCallback get_instance_proc_address_callback; /// The callback invoked when the engine requests a VkImage from the embedder /// for rendering the next frame. @@ -945,6 +967,8 @@ typedef struct { double scale; /// The rotation of the pan/zoom in radians, where 0.0 is the initial angle. double rotation; + /// The identifier of the view that received the pointer event. + FlutterViewId view_id; } FlutterPointerEvent; typedef enum { @@ -953,6 +977,14 @@ typedef enum { kFlutterKeyEventTypeRepeat, } FlutterKeyEventType; +typedef enum { + kFlutterKeyEventDeviceTypeKeyboard = 1, + kFlutterKeyEventDeviceTypeDirectionalPad, + kFlutterKeyEventDeviceTypeGamepad, + kFlutterKeyEventDeviceTypeJoystick, + kFlutterKeyEventDeviceTypeHdmi, +} FlutterKeyEventDeviceType; + /// A structure to represent a key event. /// /// Sending `FlutterKeyEvent` via `FlutterEngineSendKeyEvent` results in a @@ -1016,6 +1048,8 @@ typedef struct { /// An event being synthesized means that the `timestamp` might greatly /// deviate from the actual time when the event occurs physically. bool synthesized; + /// The source device for the key event. + FlutterKeyEventDeviceType device_type; } FlutterKeyEvent; typedef void (*FlutterKeyEventCallback)(bool /* handled */, @@ -1059,6 +1093,57 @@ typedef int64_t FlutterPlatformViewIdentifier; FLUTTER_EXPORT extern const int32_t kFlutterSemanticsNodeIdBatchEnd; +// The enumeration of possible string attributes that affect how assistive +// technologies announce a string. +// +// See dart:ui's implementers of the StringAttribute abstract class. +typedef enum { + // Indicates the string should be announced character by character. + kSpellOut, + // Indicates the string should be announced using the specified locale. + kLocale, +} FlutterStringAttributeType; + +// Indicates the assistive technology should announce out the string character +// by character. +// +// See dart:ui's SpellOutStringAttribute. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterSpellOutStringAttribute). + size_t struct_size; +} FlutterSpellOutStringAttribute; + +// Indicates the assistive technology should announce the string using the +// specified locale. +// +// See dart:ui's LocaleStringAttribute. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterLocaleStringAttribute). + size_t struct_size; + // The locale of this attribute. + const char* locale; +} FlutterLocaleStringAttribute; + +// Indicates how the assistive technology should treat the string. +// +// See dart:ui's StringAttribute. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterStringAttribute). + size_t struct_size; + // The position this attribute starts. + size_t start; + // The next position after the attribute ends. + size_t end; + /// The type of the attribute described by the subsequent union. + FlutterStringAttributeType type; + union { + // Indicates the string should be announced character by character. + const FlutterSpellOutStringAttribute* spell_out; + // Indicates the string should be announced using the specified locale. + const FlutterLocaleStringAttribute* locale; + }; +} FlutterStringAttribute; + /// A node that represents some semantic data. /// /// The semantics tree is maintained during the semantics phase of the pipeline @@ -1210,6 +1295,31 @@ typedef struct { FlutterPlatformViewIdentifier platform_view_id; /// A textual tooltip attached to the node. const char* tooltip; + // The number of string attributes associated with the `label`. + size_t label_attribute_count; + // Array of string attributes associated with the `label`. + // Has length `label_attribute_count`. + const FlutterStringAttribute** label_attributes; + // The number of string attributes associated with the `hint`. + size_t hint_attribute_count; + // Array of string attributes associated with the `hint`. + // Has length `hint_attribute_count`. + const FlutterStringAttribute** hint_attributes; + // The number of string attributes associated with the `value`. + size_t value_attribute_count; + // Array of string attributes associated with the `value`. + // Has length `value_attribute_count`. + const FlutterStringAttribute** value_attributes; + // The number of string attributes associated with the `increased_value`. + size_t increased_value_attribute_count; + // Array of string attributes associated with the `increased_value`. + // Has length `increased_value_attribute_count`. + const FlutterStringAttribute** increased_value_attributes; + // The number of string attributes associated with the `decreased_value`. + size_t decreased_value_attribute_count; + // Array of string attributes associated with the `decreased_value`. + // Has length `decreased_value_attribute_count`. + const FlutterStringAttribute** decreased_value_attributes; } FlutterSemanticsNode2; /// `FlutterSemanticsCustomAction` ID used as a sentinel to signal the end of a @@ -1321,6 +1431,20 @@ typedef void (*FlutterUpdateSemanticsCallback2)( const FlutterSemanticsUpdate2* /* semantics update */, void* /* user data*/); +/// An update to whether a message channel has a listener set or not. +typedef struct { + // The size of the struct. Must be sizeof(FlutterChannelUpdate). + size_t struct_size; + /// The name of the channel. + const char* channel; + /// True if a listener has been set, false if one has been cleared. + bool listening; +} FlutterChannelUpdate; + +typedef void (*FlutterChannelUpdateCallback)( + const FlutterChannelUpdate* /* channel update */, + void* /* user data */); + typedef struct _FlutterTaskRunner* FlutterTaskRunner; typedef struct { @@ -1568,6 +1692,27 @@ typedef enum { kFlutterLayerContentTypePlatformView, } FlutterLayerContentType; +/// A region represented by a collection of non-overlapping rectangles. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterRegion). + size_t struct_size; + /// Number of rectangles in the region. + size_t rects_count; + /// The rectangles that make up the region. + FlutterRect* rects; +} FlutterRegion; + +/// Contains additional information about the backing store provided +/// during presentation to the embedder. +typedef struct { + size_t struct_size; + + /// The area of the backing store that contains Flutter contents. Pixels + /// outside of this area are transparent and the embedder may choose not + /// to render them. Coordinates are in physical pixels. + FlutterRegion* paint_region; +} FlutterBackingStorePresentInfo; + typedef struct { /// This size of this struct. Must be sizeof(FlutterLayer). size_t struct_size; @@ -1587,6 +1732,10 @@ typedef struct { FlutterPoint offset; /// The size of the layer (in physical pixels). FlutterSize size; + + /// Extra information for the backing store that the embedder may + /// use during presentation. + FlutterBackingStorePresentInfo* backing_store_present_info; } FlutterLayer; typedef bool (*FlutterBackingStoreCreateCallback)( @@ -2113,10 +2262,17 @@ typedef struct { /// and `update_semantics_callback2` may be provided; the others must be set /// to null. FlutterUpdateSemanticsCallback2 update_semantics_callback2; + + /// The callback invoked by the engine in response to a channel listener + /// being registered on the framework side. The callback is invoked from + /// a task posted to the platform thread. + FlutterChannelUpdateCallback channel_update_callback; } FlutterProjectArgs; #ifndef FLUTTER_ENGINE_NO_PROTOTYPES +// NOLINTBEGIN(google-objc-function-naming) + //------------------------------------------------------------------------------ /// @brief Creates the necessary data structures to launch a Flutter Dart /// application in AOT mode. The data may only be collected after @@ -2988,8 +3144,10 @@ FLUTTER_EXPORT FlutterEngineResult FlutterEngineGetProcAddresses( FlutterEngineProcTable* table); +// NOLINTEND(google-objc-function-naming) + #if defined(__cplusplus) } // extern "C" #endif -#endif // FLUTTER_EMBEDDER_H_ +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_H_