diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index ddd3dd6809cd1..e98a0a6e0c6da 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -157,6 +157,7 @@ template("embedder") { "channels/app_control_channel.cc", "channels/platform_channel_tizen.cc", "channels/settings_channel_tizen.cc", + "channels/window_channel.cc", "external_texture_surface_gl_tizen.cc", "system_utils_tizen.cc", ] diff --git a/shell/platform/tizen/channels/window_channel.cc b/shell/platform/tizen/channels/window_channel.cc new file mode 100644 index 0000000000000..9bf430af56d3e --- /dev/null +++ b/shell/platform/tizen/channels/window_channel.cc @@ -0,0 +1,81 @@ +// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-private-field" +#include "window_channel.h" +#pragma clang diagnostic pop + +#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h" +#include "flutter/shell/platform/tizen/channels/encodable_value_holder.h" +#include "flutter/shell/platform/tizen/logger.h" + +namespace flutter { + +namespace { + +constexpr char kChannelName[] = "tizen/internal/window"; + +} // namespace + +WindowChannel::WindowChannel(BinaryMessenger* messenger, + TizenRenderer* renderer, + TizenRenderer::Delegate* delegate) + : renderer_(renderer), delegate_(delegate) { + channel_ = std::make_unique>( + messenger, kChannelName, &StandardMethodCodec::GetInstance()); + channel_->SetMethodCallHandler([this](const auto& call, auto result) { + this->HandleMethodCall(call, std::move(result)); + }); +} + +WindowChannel::~WindowChannel() {} + +void WindowChannel::HandleMethodCall( + const MethodCall& method_call, + std::unique_ptr> result) { + const auto& method_name = method_call.method_name(); + + if (method_name == "getWindowGeometry") { + TizenRenderer::Geometry geometry = renderer_->GetWindowGeometry(); + EncodableMap map; + map[EncodableValue("x")] = EncodableValue(geometry.x); + map[EncodableValue("y")] = EncodableValue(geometry.y); + map[EncodableValue("width")] = EncodableValue(geometry.w); + map[EncodableValue("height")] = EncodableValue(geometry.h); + result->Success(EncodableValue(map)); + } else if (method_name == "setWindowGeometry") { +#ifdef TIZEN_RENDERER_EVAS_GL + FT_LOG(Error) << "setWindowGeometry is not supported on evas_gl."; + result->NotImplemented(); +#else + auto arguments = std::get_if(method_call.arguments()); + if (!arguments) { + result->Error("Invalid arguments"); + return; + } + EncodableValueHolder x(arguments, "x"); + EncodableValueHolder y(arguments, "y"); + EncodableValueHolder width(arguments, "width"); + EncodableValueHolder height(arguments, "height"); + + TizenRenderer::Geometry geometry = renderer_->GetWindowGeometry(); + + delegate_->OnGeometryChange(x ? *x : geometry.x, y ? *y : geometry.y, + width ? *width : geometry.w, + height ? *height : geometry.h); + result->Success(); +#endif + } else if (method_name == "getScreenGeometry") { + TizenRenderer::Geometry geometry = renderer_->GetScreenGeometry(); + EncodableMap map; + map[EncodableValue("width")] = EncodableValue(geometry.w); + map[EncodableValue("height")] = EncodableValue(geometry.h); + result->Success(EncodableValue(map)); + } else { + result->NotImplemented(); + } +} + +} // namespace flutter diff --git a/shell/platform/tizen/channels/window_channel.h b/shell/platform/tizen/channels/window_channel.h new file mode 100644 index 0000000000000..a052f47c6f232 --- /dev/null +++ b/shell/platform/tizen/channels/window_channel.h @@ -0,0 +1,38 @@ +// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EMBEDDER_WINDOW_CHANNEL_H_ +#define EMBEDDER_WINDOW_CHANNEL_H_ + +#include + +#include "flutter/shell/platform/common/client_wrapper/include/flutter/binary_messenger.h" +#include "flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h" +#include "flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h" +#include "flutter/shell/platform/tizen/tizen_renderer.h" + +namespace flutter { + +class WindowChannel { + public: + explicit WindowChannel(BinaryMessenger* messenger, + TizenRenderer* renderer, + TizenRenderer::Delegate* delegate); + virtual ~WindowChannel(); + + private: + void HandleMethodCall(const MethodCall& method_call, + std::unique_ptr> result); + + std::unique_ptr> channel_; + + // A reference to the renderer object managed by FlutterTizenEngine. + // This can be nullptr if the engine is running in headless mode. + TizenRenderer* renderer_; + TizenRenderer::Delegate* delegate_; +}; + +} // namespace flutter + +#endif // EMBEDDER_WINDOW_CHANNEL_H_ diff --git a/shell/platform/tizen/flutter_tizen_engine.cc b/shell/platform/tizen/flutter_tizen_engine.cc index 24832dfdc49da..b5abfa2bbef90 100644 --- a/shell/platform/tizen/flutter_tizen_engine.cc +++ b/shell/platform/tizen/flutter_tizen_engine.cc @@ -92,7 +92,7 @@ void FlutterTizenEngine::InitializeRenderer(int32_t x, bool transparent, bool focusable, bool top_level) { - TizenRenderer::WindowGeometry geometry = {x, y, width, height}; + TizenRenderer::Geometry geometry = {x, y, width, height}; #ifdef TIZEN_RENDERER_EVAS_GL renderer_ = std::make_unique( @@ -267,6 +267,10 @@ bool FlutterTizenEngine::RunEngine(const char* entrypoint) { text_input_channel_ = std::make_unique( internal_plugin_registrar_->messenger(), std::make_unique(this)); +#ifndef __X64_SHELL__ + window_channel_ = std::make_unique( + internal_plugin_registrar_->messenger(), renderer_.get(), this); +#endif key_event_handler_ = std::make_unique(this); touch_event_handler_ = std::make_unique(this); @@ -343,11 +347,15 @@ void FlutterTizenEngine::SendPointerEvent(const FlutterPointerEvent& event) { embedder_api_.SendPointerEvent(engine_, &event, 1); } -void FlutterTizenEngine::SendWindowMetrics(int32_t width, +void FlutterTizenEngine::SendWindowMetrics(int32_t x, + int32_t y, + int32_t width, int32_t height, double pixel_ratio) { FlutterWindowMetricsEvent event = {}; event.struct_size = sizeof(FlutterWindowMetricsEvent); + event.left = static_cast(x); + event.top = static_cast(y); event.width = static_cast(width); event.height = static_cast(height); if (pixel_ratio == 0.0) { @@ -377,7 +385,7 @@ void FlutterTizenEngine::SetWindowOrientation(int32_t degree) { renderer_->SetRotate(degree); // Compute renderer transformation based on the angle of rotation. double rad = (360 - degree) * M_PI / 180; - auto geometry = renderer_->GetCurrentGeometry(); + auto geometry = renderer_->GetWindowGeometry(); double width = geometry.w; double height = geometry.h; @@ -397,20 +405,33 @@ void FlutterTizenEngine::SetWindowOrientation(int32_t degree) { }; touch_event_handler_->rotation = degree; if (degree == 90 || degree == 270) { - renderer_->ResizeWithRotation(geometry.x, geometry.y, height, width, - degree); - SendWindowMetrics(height, width, 0.0); - } else { - renderer_->ResizeWithRotation(geometry.x, geometry.y, width, height, - degree); - SendWindowMetrics(width, height, 0.0); + std::swap(width, height); } + renderer_->ResizeWithRotation(geometry.x, geometry.y, width, height, degree); + // Window position does not change on rotation regardless of its orientation. + SendWindowMetrics(geometry.x, geometry.y, width, height, 0.0); } void FlutterTizenEngine::OnOrientationChange(int32_t degree) { SetWindowOrientation(degree); } +void FlutterTizenEngine::OnGeometryChange(int32_t x, + int32_t y, + int32_t width, + int32_t height) { +#ifdef TIZEN_RENDERER_EVAS_GL + FT_UNIMPLEMENTED(); +#else + if (!renderer_->IsValid()) { + return; + } + renderer_->SetGeometry(x, y, width, height); + renderer_->ResizeWithRotation(x, y, width, height, 0); + SendWindowMetrics(x, y, width, height, 0.0); +#endif +} + void FlutterTizenEngine::OnVsync(intptr_t baton, uint64_t frame_start_time_nanos, uint64_t frame_target_time_nanos) { @@ -456,8 +477,8 @@ bool FlutterTizenEngine::MarkExternalTextureFrameAvailable(int64_t texture_id) { engine_, texture_id) == kSuccess); } -// The Flutter Engine calls out to this function when new platform messages are -// available. +// The Flutter Engine calls out to this function when new platform messages +// are available. // Converts a FlutterPlatformMessage to an equivalent FlutterDesktopMessage. FlutterDesktopMessage FlutterTizenEngine::ConvertToDesktopMessage( diff --git a/shell/platform/tizen/flutter_tizen_engine.h b/shell/platform/tizen/flutter_tizen_engine.h index 51bd0f9b3a6e6..4423053e0a831 100644 --- a/shell/platform/tizen/flutter_tizen_engine.h +++ b/shell/platform/tizen/flutter_tizen_engine.h @@ -21,6 +21,7 @@ #include "flutter/shell/platform/tizen/channels/platform_view_channel.h" #include "flutter/shell/platform/tizen/channels/settings_channel.h" #include "flutter/shell/platform/tizen/channels/text_input_channel.h" +#include "flutter/shell/platform/tizen/channels/window_channel.h" #include "flutter/shell/platform/tizen/flutter_project_bundle.h" #include "flutter/shell/platform/tizen/flutter_tizen_texture_registrar.h" #include "flutter/shell/platform/tizen/key_event_handler.h" @@ -136,10 +137,18 @@ class FlutterTizenEngine : public TizenRenderer::Delegate { // Sends a window metrics update to the Flutter engine using current window // dimensions in physical - void SendWindowMetrics(int32_t width, int32_t height, double pixel_ratio); + void SendWindowMetrics(int32_t x, + int32_t y, + int32_t width, + int32_t height, + double pixel_ratio); void SetWindowOrientation(int32_t degree); void OnOrientationChange(int32_t degree) override; + void OnGeometryChange(int32_t x, + int32_t y, + int32_t width, + int32_t height) override; void OnVsync(intptr_t baton, uint64_t frame_start_time_nanos, uint64_t frame_target_time_nanos); @@ -239,6 +248,11 @@ class FlutterTizenEngine : public TizenRenderer::Delegate { // A plugin that implements the Flutter textinput channel. std::unique_ptr text_input_channel_; +#ifndef __X64_SHELL__ + // A plugin that implements the Tizen window channel. + std::unique_ptr window_channel_; +#endif + // The event loop for the main thread that allows for delayed task execution. std::unique_ptr event_loop_; diff --git a/shell/platform/tizen/tizen_renderer.cc b/shell/platform/tizen/tizen_renderer.cc index e04082634fb84..314f75f05adac 100644 --- a/shell/platform/tizen/tizen_renderer.cc +++ b/shell/platform/tizen/tizen_renderer.cc @@ -6,7 +6,7 @@ namespace flutter { -TizenRenderer::TizenRenderer(WindowGeometry geometry, +TizenRenderer::TizenRenderer(Geometry geometry, bool transparent, bool focusable, bool top_level, diff --git a/shell/platform/tizen/tizen_renderer.h b/shell/platform/tizen/tizen_renderer.h index c8dc232cb9d37..89cf5157152ca 100644 --- a/shell/platform/tizen/tizen_renderer.h +++ b/shell/platform/tizen/tizen_renderer.h @@ -12,13 +12,17 @@ namespace flutter { class TizenRenderer { public: - struct WindowGeometry { + struct Geometry { int32_t x{0}, y{0}, w{0}, h{0}; }; class Delegate { public: virtual void OnOrientationChange(int32_t degree) = 0; + virtual void OnGeometryChange(int32_t x, + int32_t y, + int32_t width, + int32_t height) = 0; }; virtual ~TizenRenderer(); @@ -32,12 +36,21 @@ class TizenRenderer { virtual uint32_t OnGetFBO() = 0; virtual void* OnProcResolver(const char* name) = 0; - virtual WindowGeometry GetCurrentGeometry() = 0; + // Returns the geometry of the current window. + virtual Geometry GetWindowGeometry() = 0; + + // Returns the geometry of the display screen. + virtual Geometry GetScreenGeometry() = 0; + virtual int32_t GetDpi() = 0; virtual uintptr_t GetWindowId() = 0; virtual void* GetWindowHandle() = 0; virtual void SetRotate(int angle) = 0; + virtual void SetGeometry(int32_t x, + int32_t y, + int32_t width, + int32_t height) = 0; virtual void ResizeWithRotation(int32_t x, int32_t y, int32_t width, @@ -47,13 +60,13 @@ class TizenRenderer { virtual bool IsSupportedExtention(const char* name) = 0; protected: - explicit TizenRenderer(WindowGeometry geometry, + explicit TizenRenderer(Geometry geometry, bool transparent, bool focusable, bool top_level, Delegate& delegate); - WindowGeometry initial_geometry_; + Geometry initial_geometry_; bool transparent_; bool focusable_; bool top_level_; diff --git a/shell/platform/tizen/tizen_renderer_ecore_wl2.cc b/shell/platform/tizen/tizen_renderer_ecore_wl2.cc index 852cbd55926af..89d72425bad00 100644 --- a/shell/platform/tizen/tizen_renderer_ecore_wl2.cc +++ b/shell/platform/tizen/tizen_renderer_ecore_wl2.cc @@ -11,7 +11,7 @@ namespace flutter { -TizenRendererEcoreWl2::TizenRendererEcoreWl2(WindowGeometry geometry, +TizenRendererEcoreWl2::TizenRendererEcoreWl2(Geometry geometry, bool transparent, bool focusable, bool top_level, @@ -206,13 +206,19 @@ void* TizenRendererEcoreWl2::OnProcResolver(const char* name) { return nullptr; } -TizenRenderer::WindowGeometry TizenRendererEcoreWl2::GetCurrentGeometry() { - WindowGeometry result; +TizenRenderer::Geometry TizenRendererEcoreWl2::GetWindowGeometry() { + Geometry result; ecore_wl2_window_geometry_get(ecore_wl2_window_, &result.x, &result.y, &result.w, &result.h); return result; } +TizenRenderer::Geometry TizenRendererEcoreWl2::GetScreenGeometry() { + Geometry result = {}; + ecore_wl2_display_screen_size_get(ecore_wl2_display_, &result.w, &result.h); + return result; +} + int32_t TizenRendererEcoreWl2::GetDpi() { auto* output = ecore_wl2_window_output_find(ecore_wl2_window_); if (!output) { @@ -553,6 +559,14 @@ void TizenRendererEcoreWl2::SetRotate(int angle) { received_rotation_ = true; } +void TizenRendererEcoreWl2::SetGeometry(int32_t x, + int32_t y, + int32_t width, + int32_t height) { + ecore_wl2_window_geometry_set(ecore_wl2_window_, x, y, width, height); + ecore_wl2_window_position_set(ecore_wl2_window_, x, y); +} + void TizenRendererEcoreWl2::ResizeWithRotation(int32_t x, int32_t y, int32_t width, diff --git a/shell/platform/tizen/tizen_renderer_ecore_wl2.h b/shell/platform/tizen/tizen_renderer_ecore_wl2.h index df4b0c35f83c5..c9316d68b533e 100644 --- a/shell/platform/tizen/tizen_renderer_ecore_wl2.h +++ b/shell/platform/tizen/tizen_renderer_ecore_wl2.h @@ -18,7 +18,7 @@ namespace flutter { class TizenRendererEcoreWl2 : public TizenRenderer { public: - explicit TizenRendererEcoreWl2(WindowGeometry geometry, + explicit TizenRendererEcoreWl2(Geometry geometry, bool transparent, bool focusable, bool top_level, @@ -32,17 +32,22 @@ class TizenRendererEcoreWl2 : public TizenRenderer { uint32_t OnGetFBO() override; void* OnProcResolver(const char* name) override; - WindowGeometry GetCurrentGeometry() override; + Geometry GetWindowGeometry() override; + Geometry GetScreenGeometry() override; int32_t GetDpi() override; uintptr_t GetWindowId() override; void* GetWindowHandle() override; + void SetRotate(int angle) override; + void SetGeometry(int32_t x, + int32_t y, + int32_t width, + int32_t height) override; void ResizeWithRotation(int32_t x, int32_t y, int32_t width, int32_t height, int32_t angle) override; - void SetRotate(int angle) override; void SetPreferredOrientations(const std::vector& rotations) override; bool IsSupportedExtention(const char* name) override; diff --git a/shell/platform/tizen/tizen_renderer_evas_gl.cc b/shell/platform/tizen/tizen_renderer_evas_gl.cc index 3454555fe998c..445c8d6bcd2ec 100644 --- a/shell/platform/tizen/tizen_renderer_evas_gl.cc +++ b/shell/platform/tizen/tizen_renderer_evas_gl.cc @@ -16,7 +16,7 @@ EVAS_GL_GLOBAL_GLES3_DEFINE(); namespace flutter { -TizenRendererEvasGL::TizenRendererEvasGL(WindowGeometry geometry, +TizenRendererEvasGL::TizenRendererEvasGL(Geometry geometry, bool transparent, bool focusable, bool top_level, @@ -546,13 +546,22 @@ void* TizenRendererEvasGL::OnProcResolver(const char* name) { return nullptr; } -TizenRenderer::WindowGeometry TizenRendererEvasGL::GetCurrentGeometry() { - WindowGeometry result; +TizenRenderer::Geometry TizenRendererEvasGL::GetWindowGeometry() { + Geometry result; evas_object_geometry_get(evas_window_, &result.x, &result.y, &result.w, &result.h); return result; } +TizenRenderer::Geometry TizenRendererEvasGL::GetScreenGeometry() { + Geometry result; + auto* ecore_evas = + ecore_evas_ecore_evas_get(evas_object_evas_get(evas_window_)); + ecore_evas_screen_geometry_get(ecore_evas, nullptr, nullptr, &result.w, + &result.h); + return result; +} + int32_t TizenRendererEvasGL::GetDpi() { auto* ecore_evas = ecore_evas_ecore_evas_get(evas_object_evas_get(evas_window_)); @@ -730,6 +739,13 @@ void TizenRendererEvasGL::SetRotate(int angle) { received_rotation_ = true; } +void TizenRendererEvasGL::SetGeometry(int32_t x, + int32_t y, + int32_t width, + int32_t height) { + FT_UNIMPLEMENTED(); +} + void TizenRendererEvasGL::ResizeWithRotation(int32_t x, int32_t y, int32_t width, diff --git a/shell/platform/tizen/tizen_renderer_evas_gl.h b/shell/platform/tizen/tizen_renderer_evas_gl.h index 07a6e28b00f01..22f868cc44173 100644 --- a/shell/platform/tizen/tizen_renderer_evas_gl.h +++ b/shell/platform/tizen/tizen_renderer_evas_gl.h @@ -16,7 +16,7 @@ namespace flutter { class TizenRendererEvasGL : public TizenRenderer { public: - explicit TizenRendererEvasGL(WindowGeometry geometry, + explicit TizenRendererEvasGL(Geometry geometry, bool transparent, bool focusable, bool top_level, @@ -30,17 +30,22 @@ class TizenRendererEvasGL : public TizenRenderer { uint32_t OnGetFBO() override; void* OnProcResolver(const char* name) override; - WindowGeometry GetCurrentGeometry() override; + Geometry GetWindowGeometry() override; + Geometry GetScreenGeometry() override; int32_t GetDpi() override; uintptr_t GetWindowId() override; void* GetWindowHandle() override; + void SetRotate(int angle) override; + void SetGeometry(int32_t x, + int32_t y, + int32_t width, + int32_t height) override; void ResizeWithRotation(int32_t x, int32_t y, int32_t width, int32_t height, int32_t angle) override; - void SetRotate(int angle) override; void SetPreferredOrientations(const std::vector& rotations) override; bool IsSupportedExtention(const char* name) override; diff --git a/shell/platform/tizen/touch_event_handler.cc b/shell/platform/tizen/touch_event_handler.cc index 70b8276e93a20..f684411187d4d 100644 --- a/shell/platform/tizen/touch_event_handler.cc +++ b/shell/platform/tizen/touch_event_handler.cc @@ -39,7 +39,7 @@ void TouchEventHandler::SendFlutterPointerEvent(FlutterPointerPhase phase, size_t timestamp, int device_id = 0) { // Correct errors caused by window rotation. - auto geometry = engine_->renderer()->GetCurrentGeometry(); + auto geometry = engine_->renderer()->GetWindowGeometry(); double width = geometry.w; double height = geometry.h; double new_x = x, new_y = y;