From 3543f93627aca59e07653bd4de8fbbbe93836f2d Mon Sep 17 00:00:00 2001 From: Swift Kim Date: Fri, 10 Sep 2021 10:50:44 +0900 Subject: [PATCH 1/3] Remove the app_control reply channel - Let the method channel directly return responses to the caller - Add NativeInitializeDartApi, NativeCreateAppControl - Create AppControlManager --- shell/platform/tizen/BUILD.gn | 1 + shell/platform/tizen/channels/app_control.cc | 96 ++++++++++----- shell/platform/tizen/channels/app_control.h | 58 ++++++--- .../tizen/channels/app_control_channel.cc | 110 ++++++++---------- .../tizen/channels/app_control_channel.h | 13 --- 5 files changed, 154 insertions(+), 124 deletions(-) diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index e207aba0a93f5..44ecd83653f7a 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -211,6 +211,7 @@ template("embedder") { "//flutter/shell/platform/common:common_cpp_input", "//flutter/shell/platform/common:common_cpp_library_headers", "//flutter/shell/platform/common/client_wrapper:client_wrapper", + "//third_party/dart/runtime:dart_api", "//third_party/rapidjson", ] } diff --git a/shell/platform/tizen/channels/app_control.cc b/shell/platform/tizen/channels/app_control.cc index becd351f05f90..253b68b41cf6b 100644 --- a/shell/platform/tizen/channels/app_control.cc +++ b/shell/platform/tizen/channels/app_control.cc @@ -4,18 +4,59 @@ #include "app_control.h" +#include "flutter/shell/platform/common/public/flutter_export.h" #include "flutter/shell/platform/tizen/channels/app_control_channel.h" +#include "flutter/shell/platform/tizen/logger.h" +#include "third_party/dart/runtime/include/dart_api_dl.h" + +DART_EXPORT FLUTTER_EXPORT intptr_t NativeInitializeDartApi(void* data) { + return Dart_InitializeApiDL(data); +} + +DART_EXPORT FLUTTER_EXPORT uint32_t NativeCreateAppControl(Dart_Handle handle) { + auto app_control = std::make_shared(); + if (!app_control->handle()) { + return -1; + } + auto id = app_control->id(); + Dart_NewFinalizableHandle_DL( + handle, app_control.get(), 64, + [](void* isolate_callback_data, void* peer) { + auto app_control = reinterpret_cast(peer); + flutter::AppControlManager::GetInstance().Remove(app_control->id()); + }); + flutter::AppControlManager::GetInstance().Insert(std::move(app_control)); + return id; +} namespace flutter { -int AppControl::next_id_ = 0; +int32_t AppControl::next_id_ = 0; -AppControl::AppControl(app_control_h app_control) : id_(next_id_++) { - handle_ = app_control; +AppControl::AppControl() : id_(next_id_++) { + app_control_h handle = nullptr; + AppControlResult ret = app_control_create(&handle); + if (!ret) { + FT_LOG(Error) << "app_control_create() failed: " << ret.message(); + return; + } + handle_ = handle; +} + +AppControl::AppControl(app_control_h handle) : id_(next_id_++) { + app_control_h clone = nullptr; + AppControlResult ret = app_control_clone(&clone, handle); + if (!ret) { + FT_LOG(Error) << "app_control_clone() failed: " << ret.message(); + return; + } + handle_ = clone; } AppControl::~AppControl() { - app_control_destroy(handle_); + if (handle_) { + app_control_destroy(handle_); + } } AppControlResult AppControl::GetString(std::string& str, @@ -109,14 +150,6 @@ AppControlResult AppControl::SetExtraData(const EncodableMap& map) { return AppControlResult(); } -void AppControl::SetManager(AppControlChannel* manager) { - manager_ = manager; -} - -AppControlChannel* AppControl::GetManager() { - return manager_; -} - AppControlResult AppControl::GetOperation(std::string& operation) { return GetString(operation, app_control_get_operation); } @@ -183,6 +216,12 @@ AppControlResult AppControl::SetLaunchMode(const std::string& launch_mode) { return AppControlResult(ret); } +bool AppControl::IsReplyRequested() { + bool requested = false; + app_control_is_reply_requested(handle_, &requested); + return requested; +} + EncodableValue AppControl::SerializeAppControlToMap() { std::string app_id, operation, mime, category, uri, caller_id, launch_mode; AppControlResult results[7]; @@ -202,31 +241,28 @@ EncodableValue AppControl::SerializeAppControlToMap() { } } EncodableMap map; - map[EncodableValue("id")] = EncodableValue(GetId()); + map[EncodableValue("id")] = EncodableValue(id()); map[EncodableValue("appId")] = EncodableValue(app_id); map[EncodableValue("operation")] = EncodableValue(operation); map[EncodableValue("mime")] = EncodableValue(mime); map[EncodableValue("category")] = EncodableValue(category); map[EncodableValue("uri")] = EncodableValue(uri); - map[EncodableValue("callerId")] = EncodableValue(caller_id); + map[EncodableValue("callerAppId")] = EncodableValue(caller_id); map[EncodableValue("launchMode")] = EncodableValue(launch_mode); map[EncodableValue("extraData")] = EncodableValue(extra_data); + map[EncodableValue("shouldReply")] = EncodableValue(IsReplyRequested()); return EncodableValue(map); } AppControlResult AppControl::SendLaunchRequest() { - AppControlResult ret = - app_control_send_launch_request(handle_, nullptr, nullptr); - return ret; + return app_control_send_launch_request(handle_, nullptr, nullptr); } AppControlResult AppControl::SendLaunchRequestWithReply( - std::shared_ptr> reply_sink, - AppControlChannel* manager) { - SetManager(manager); - auto on_reply = [](app_control_h request, app_control_h reply, - app_control_result_e result, void* user_data) { + ReplyCallback on_reply) { + auto reply_callback = [](app_control_h request, app_control_h reply, + app_control_result_e result, void* user_data) { AppControl* app_control = static_cast(user_data); app_control_h clone = nullptr; AppControlResult ret = app_control_clone(&clone, reply); @@ -238,7 +274,7 @@ AppControlResult AppControl::SendLaunchRequestWithReply( std::shared_ptr app_control_reply = std::make_shared(clone); EncodableMap map; - map[EncodableValue("id")] = EncodableValue(app_control->GetId()); + map[EncodableValue("id")] = EncodableValue(app_control->id()); map[EncodableValue("reply")] = app_control_reply->SerializeAppControlToMap(); if (result == APP_CONTROL_RESULT_APP_STARTED) { @@ -251,14 +287,12 @@ AppControlResult AppControl::SendLaunchRequestWithReply( map[EncodableValue("result")] = EncodableValue("canceled"); } - app_control->reply_sink_->Success(EncodableValue(map)); - app_control->GetManager()->AddExistingAppControl( - std::move(app_control_reply)); + app_control->on_reply_(EncodableValue(map)); + app_control->on_reply_ = nullptr; + AppControlManager::GetInstance().Insert(std::move(app_control_reply)); }; - reply_sink_ = std::move(reply_sink); - AppControlResult ret = - app_control_send_launch_request(handle_, on_reply, this); - return ret; + on_reply_ = on_reply; + return app_control_send_launch_request(handle_, reply_callback, this); } AppControlResult AppControl::SendTerminateRequest() { @@ -281,7 +315,7 @@ AppControlResult AppControl::Reply(std::shared_ptr reply, return AppControlResult(APP_CONTROL_ERROR_INVALID_PARAMETER); } AppControlResult ret = app_control_reply_to_launch_request( - reply->Handle(), this->handle_, result_e); + reply->handle(), this->handle_, result_e); return ret; } diff --git a/shell/platform/tizen/channels/app_control.h b/shell/platform/tizen/channels/app_control.h index 24258254c5aea..2aea054a79f39 100644 --- a/shell/platform/tizen/channels/app_control.h +++ b/shell/platform/tizen/channels/app_control.h @@ -7,9 +7,10 @@ #include +#include + #include "flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h" #include "flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h" -#include "flutter/shell/platform/tizen/logger.h" namespace flutter { @@ -29,11 +30,14 @@ class AppControlChannel; class AppControl { public: - AppControl(app_control_h app_control); - ~AppControl(); + using ReplyCallback = std::function; + + explicit AppControl(); + explicit AppControl(app_control_h handle); + virtual ~AppControl(); - int GetId() { return id_; } - app_control_h Handle() { return handle_; } + int32_t id() { return id_; } + app_control_h handle() { return handle_; } AppControlResult GetOperation(std::string& operation); AppControlResult SetOperation(const std::string& operation); @@ -48,13 +52,12 @@ class AppControl { AppControlResult GetCaller(std::string& caller); AppControlResult GetLaunchMode(std::string& launch_mode); AppControlResult SetLaunchMode(const std::string& launch_mode); + bool IsReplyRequested(); EncodableValue SerializeAppControlToMap(); AppControlResult SendLaunchRequest(); - AppControlResult SendLaunchRequestWithReply( - std::shared_ptr> reply_sink, - AppControlChannel* manager); + AppControlResult SendLaunchRequestWithReply(ReplyCallback on_reply); AppControlResult SendTerminateRequest(); AppControlResult Reply(std::shared_ptr reply, @@ -63,9 +66,6 @@ class AppControl { AppControlResult GetExtraData(EncodableMap& value); AppControlResult SetExtraData(const EncodableMap& value); - void SetManager(AppControlChannel* manager); - AppControlChannel* GetManager(); - private: AppControlResult GetString(std::string& str, int func(app_control_h, char**)); AppControlResult SetString(const std::string& str, @@ -74,12 +74,38 @@ class AppControl { AppControlResult AddExtraData(std::string key, EncodableValue value); AppControlResult AddExtraDataList(std::string& key, EncodableList& list); - app_control_h handle_; - int id_; - static int next_id_; - std::shared_ptr> reply_sink_; + app_control_h handle_ = nullptr; + int32_t id_; + static int32_t next_id_; + ReplyCallback on_reply_ = nullptr; +}; + +class AppControlManager { + public: + // Returns an instance of this class. + static AppControlManager& GetInstance() { + static AppControlManager instance; + return instance; + } + + void Insert(std::shared_ptr app_control) { + map_.insert({app_control->id(), std::move(app_control)}); + } + + void Remove(int32_t id) { map_.erase(id); } + + std::shared_ptr FindById(const int32_t id) { + if (map_.find(id) == map_.end()) { + return nullptr; + } + return map_[id]; + } + + private: + explicit AppControlManager() {} + ~AppControlManager() {} - AppControlChannel* manager_; + std::unordered_map> map_; }; } // namespace flutter diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index c94132a69ee18..07d5599078249 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -7,6 +7,7 @@ #include "flutter/shell/platform/common/client_wrapper/include/flutter/event_stream_handler_functions.h" #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 { @@ -14,7 +15,6 @@ namespace { constexpr char kChannelName[] = "tizen/internal/app_control_method"; constexpr char kEventChannelName[] = "tizen/internal/app_control_event"; -constexpr char kReplyChannelName[] = "tizen/internal/app_control_reply"; } // namespace @@ -43,44 +43,24 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { }); event_channel_->SetStreamHandler(std::move(event_channel_handler)); - - reply_channel_ = std::make_unique>( - messenger, kReplyChannelName, &StandardMethodCodec::GetInstance()); - - auto reply_channel_handler = std::make_unique>( - [this](const EncodableValue* arguments, - std::unique_ptr>&& events) - -> std::unique_ptr> { - RegisterReplyHandler(std::move(events)); - return nullptr; - }, - [this](const EncodableValue* arguments) - -> std::unique_ptr> { - UnregisterReplyHandler(); - return nullptr; - }); - - reply_channel_->SetStreamHandler(std::move(reply_channel_handler)); } AppControlChannel::~AppControlChannel() {} -void AppControlChannel::NotifyAppControl(void* app_control) { - app_control_h clone = nullptr; - app_control_h handle = static_cast(app_control); - AppControlResult ret = app_control_clone(&clone, handle); - if (!ret) { - FT_LOG(Error) << "Could not clone app control: " << ret.message(); +void AppControlChannel::NotifyAppControl(void* h) { + auto handle = static_cast(h); + auto app_control = std::make_shared(handle); + if (!app_control->handle()) { + FT_LOG(Error) << "Could not clone AppControl."; return; } - auto app = std::make_shared(clone); if (!event_sink_) { - queue_.push(app); FT_LOG(Info) << "EventChannel not set yet."; + queue_.push(app_control); } else { - SendAppControlDataEvent(app); + SendAppControlDataEvent(app_control); } - map_.insert({app->GetId(), app}); + AppControlManager::GetInstance().Insert(std::move(app_control)); } void AppControlChannel::HandleMethodCall( @@ -134,15 +114,6 @@ void AppControlChannel::SendAlreadyQueuedEvents() { } } -void AppControlChannel::RegisterReplyHandler( - std::unique_ptr> events) { - reply_sink_ = std::move(events); -} - -void AppControlChannel::UnregisterReplyHandler() { - reply_sink_.reset(); -} - std::shared_ptr AppControlChannel::GetAppControl( const EncodableValue* arguments) { auto map_ptr = std::get_if(arguments); @@ -151,36 +122,35 @@ std::shared_ptr AppControlChannel::GetAppControl( return nullptr; } - EncodableValueHolder id(map_ptr, "id"); + EncodableValueHolder id(map_ptr, "id"); if (!id) { FT_LOG(Error) << "Could not get proper id from arguments."; return nullptr; } - if (map_.find(*id) == map_.end()) { + auto app_control = AppControlManager::GetInstance().FindById(*id); + if (!app_control) { FT_LOG(Error) << "Could not find AppControl with id " << *id; return nullptr; } - return map_[*id]; + return app_control; } void AppControlChannel::CreateAppControl( std::unique_ptr> result) { - app_control_h app_control = nullptr; - AppControlResult ret = app_control_create(&app_control); - if (!ret) { - result->Error("Could not create AppControl", ret.message()); + auto app_control = std::make_unique(); + if (app_control->handle()) { + result->Success(EncodableValue(app_control->id())); + AppControlManager::GetInstance().Insert(std::move(app_control)); + } else { + result->Error("Internal error", "Could not create AppControl."); } - auto app = std::make_unique(app_control); - int id = app->GetId(); - map_.insert({id, std::move(app)}); - result->Success(EncodableValue(id)); } void AppControlChannel::Dispose( std::shared_ptr app_control, std::unique_ptr> result) { - map_.erase(app_control->GetId()); + AppControlManager::GetInstance().Remove(app_control->id()); result->Success(); } @@ -194,13 +164,19 @@ void AppControlChannel::Reply( return; } - EncodableValueHolder request_id(map_ptr, "requestId"); - if (!request_id || map_.find(*request_id) == map_.end()) { - result->Error("Could not reply", "Invalid request app control"); + EncodableValueHolder request_id(map_ptr, "requestId"); + if (!request_id) { + result->Error("Invalid arguments", "Invalid requestId parameter"); + return; + } + auto request_app_control = + AppControlManager::GetInstance().FindById(*request_id); + if (!request_app_control) { + result->Error("Invalid arguments", + "Could not find AppControl with the given ID."); return; } - auto request_app_control = map_[*request_id]; EncodableValueHolder result_str(map_ptr, "result"); if (!result_str) { result->Error("Could not reply", "Invalid result parameter"); @@ -225,18 +201,24 @@ void AppControlChannel::SendLaunchRequest( } EncodableValueHolder wait_for_reply(map_ptr, "waitForReply"); - - AppControlResult ret; if (wait_for_reply && *wait_for_reply) { - ret = app_control->SendLaunchRequestWithReply(std::move(reply_sink_), this); - } else { - ret = app_control->SendLaunchRequest(); - } - - if (ret) { - result->Success(); + auto result_ptr = result.release(); + auto on_reply = [result_ptr](const EncodableValue& response) { + result_ptr->Success(response); + delete result_ptr; + }; + AppControlResult ret = app_control->SendLaunchRequestWithReply(on_reply); + if (!ret) { + result_ptr->Error(ret.message()); + delete result_ptr; + } } else { - result->Error(ret.message()); + AppControlResult ret = app_control->SendLaunchRequest(); + if (ret) { + result->Success(); + } else { + result->Error(ret.message()); + } } } diff --git a/shell/platform/tizen/channels/app_control_channel.h b/shell/platform/tizen/channels/app_control_channel.h index cbaa40884e231..a3c7475c782df 100644 --- a/shell/platform/tizen/channels/app_control_channel.h +++ b/shell/platform/tizen/channels/app_control_channel.h @@ -7,14 +7,12 @@ #include #include -#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/event_channel.h" #include "flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h" #include "flutter/shell/platform/tizen/channels/app_control.h" -#include "flutter/shell/platform/tizen/logger.h" namespace flutter { @@ -25,10 +23,6 @@ class AppControlChannel { void NotifyAppControl(void* app_control); - void AddExistingAppControl(std::shared_ptr app_control) { - map_.insert({app_control->GetId(), app_control}); - } - private: void HandleMethodCall(const MethodCall& method_call, std::unique_ptr> result); @@ -36,9 +30,6 @@ class AppControlChannel { void UnregisterEventHandler(); void SendAlreadyQueuedEvents(); - void RegisterReplyHandler(std::unique_ptr> events); - void UnregisterReplyHandler(); - std::shared_ptr GetAppControl(const EncodableValue* arguments); void CreateAppControl(std::unique_ptr> result); @@ -62,16 +53,12 @@ class AppControlChannel { std::unique_ptr> method_channel_; std::unique_ptr> event_channel_; - std::unique_ptr> reply_channel_; std::unique_ptr> event_sink_; - std::shared_ptr> reply_sink_; // We need this queue, because there is no quarantee // that EventChannel on Dart side will be registered // before native OnAppControl event std::queue> queue_; - - std::unordered_map> map_; }; } // namespace flutter From cad45773f17352fa0cb1179404fd5e4b53b676ca Mon Sep 17 00:00:00 2001 From: Swift Kim Date: Sun, 12 Sep 2021 14:48:09 +0900 Subject: [PATCH 2/3] Convert shared_ptr to unique_ptr --- shell/platform/tizen/channels/app_control.cc | 16 +++--------- shell/platform/tizen/channels/app_control.h | 13 ++++------ .../tizen/channels/app_control_channel.cc | 26 +++++++++---------- .../tizen/channels/app_control_channel.h | 16 ++++++------ 4 files changed, 28 insertions(+), 43 deletions(-) diff --git a/shell/platform/tizen/channels/app_control.cc b/shell/platform/tizen/channels/app_control.cc index 253b68b41cf6b..8e6dc8e9d8094 100644 --- a/shell/platform/tizen/channels/app_control.cc +++ b/shell/platform/tizen/channels/app_control.cc @@ -14,7 +14,7 @@ DART_EXPORT FLUTTER_EXPORT intptr_t NativeInitializeDartApi(void* data) { } DART_EXPORT FLUTTER_EXPORT uint32_t NativeCreateAppControl(Dart_Handle handle) { - auto app_control = std::make_shared(); + auto app_control = std::make_unique(); if (!app_control->handle()) { return -1; } @@ -264,17 +264,8 @@ AppControlResult AppControl::SendLaunchRequestWithReply( auto reply_callback = [](app_control_h request, app_control_h reply, app_control_result_e result, void* user_data) { AppControl* app_control = static_cast(user_data); - app_control_h clone = nullptr; - AppControlResult ret = app_control_clone(&clone, reply); - if (!ret) { - FT_LOG(Error) << "Could not clone app_control: " << ret.message(); - return; - } - - std::shared_ptr app_control_reply = - std::make_shared(clone); + auto app_control_reply = std::make_unique(reply); EncodableMap map; - map[EncodableValue("id")] = EncodableValue(app_control->id()); map[EncodableValue("reply")] = app_control_reply->SerializeAppControlToMap(); if (result == APP_CONTROL_RESULT_APP_STARTED) { @@ -286,7 +277,6 @@ AppControlResult AppControl::SendLaunchRequestWithReply( } else if (result == APP_CONTROL_RESULT_CANCELED) { map[EncodableValue("result")] = EncodableValue("canceled"); } - app_control->on_reply_(EncodableValue(map)); app_control->on_reply_ = nullptr; AppControlManager::GetInstance().Insert(std::move(app_control_reply)); @@ -300,7 +290,7 @@ AppControlResult AppControl::SendTerminateRequest() { return ret; } -AppControlResult AppControl::Reply(std::shared_ptr reply, +AppControlResult AppControl::Reply(AppControl* reply, const std::string& result) { app_control_result_e result_e; if (result == "appStarted") { diff --git a/shell/platform/tizen/channels/app_control.h b/shell/platform/tizen/channels/app_control.h index 2aea054a79f39..2fb82296c5f0a 100644 --- a/shell/platform/tizen/channels/app_control.h +++ b/shell/platform/tizen/channels/app_control.h @@ -26,8 +26,6 @@ struct AppControlResult { int error_code; }; -class AppControlChannel; - class AppControl { public: using ReplyCallback = std::function; @@ -60,8 +58,7 @@ class AppControl { AppControlResult SendLaunchRequestWithReply(ReplyCallback on_reply); AppControlResult SendTerminateRequest(); - AppControlResult Reply(std::shared_ptr reply, - const std::string& result); + AppControlResult Reply(AppControl* reply, const std::string& result); AppControlResult GetExtraData(EncodableMap& value); AppControlResult SetExtraData(const EncodableMap& value); @@ -88,24 +85,24 @@ class AppControlManager { return instance; } - void Insert(std::shared_ptr app_control) { + void Insert(std::unique_ptr app_control) { map_.insert({app_control->id(), std::move(app_control)}); } void Remove(int32_t id) { map_.erase(id); } - std::shared_ptr FindById(const int32_t id) { + AppControl* FindById(const int32_t id) { if (map_.find(id) == map_.end()) { return nullptr; } - return map_[id]; + return map_[id].get(); } private: explicit AppControlManager() {} ~AppControlManager() {} - std::unordered_map> map_; + std::unordered_map> map_; }; } // namespace flutter diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index 07d5599078249..3d29f41364b13 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -47,18 +47,18 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { AppControlChannel::~AppControlChannel() {} -void AppControlChannel::NotifyAppControl(void* h) { - auto handle = static_cast(h); - auto app_control = std::make_shared(handle); +void AppControlChannel::NotifyAppControl(void* handle) { + auto app_control = + std::make_unique(static_cast(handle)); if (!app_control->handle()) { FT_LOG(Error) << "Could not clone AppControl."; return; } if (!event_sink_) { FT_LOG(Info) << "EventChannel not set yet."; - queue_.push(app_control); + queue_.push(app_control.get()); } else { - SendAppControlDataEvent(app_control); + SendAppControlDataEvent(app_control.get()); } AppControlManager::GetInstance().Insert(std::move(app_control)); } @@ -114,8 +114,7 @@ void AppControlChannel::SendAlreadyQueuedEvents() { } } -std::shared_ptr AppControlChannel::GetAppControl( - const EncodableValue* arguments) { +AppControl* AppControlChannel::GetAppControl(const EncodableValue* arguments) { auto map_ptr = std::get_if(arguments); if (!map_ptr) { FT_LOG(Error) << "Invalid arguments."; @@ -148,14 +147,14 @@ void AppControlChannel::CreateAppControl( } void AppControlChannel::Dispose( - std::shared_ptr app_control, + AppControl* app_control, std::unique_ptr> result) { AppControlManager::GetInstance().Remove(app_control->id()); result->Success(); } void AppControlChannel::Reply( - std::shared_ptr app_control, + AppControl* app_control, const EncodableValue* arguments, std::unique_ptr> result) { auto map_ptr = std::get_if(arguments); @@ -191,7 +190,7 @@ void AppControlChannel::Reply( } void AppControlChannel::SendLaunchRequest( - std::shared_ptr app_control, + AppControl* app_control, const EncodableValue* arguments, std::unique_ptr> result) { auto map_ptr = std::get_if(arguments); @@ -223,7 +222,7 @@ void AppControlChannel::SendLaunchRequest( } void AppControlChannel::SendTerminateRequest( - std::shared_ptr app_control, + AppControl* app_control, std::unique_ptr> result) { AppControlResult ret = app_control->SendTerminateRequest(); if (ret) { @@ -234,7 +233,7 @@ void AppControlChannel::SendTerminateRequest( } void AppControlChannel::SetAppControlData( - std::shared_ptr app_control, + AppControl* app_control, const EncodableValue* arguments, std::unique_ptr> result) { auto map_ptr = std::get_if(arguments); @@ -283,8 +282,7 @@ void AppControlChannel::SetAppControlData( result->Success(); } -void AppControlChannel::SendAppControlDataEvent( - std::shared_ptr app_control) { +void AppControlChannel::SendAppControlDataEvent(AppControl* app_control) { EncodableValue map = app_control->SerializeAppControlToMap(); if (!map.IsNull()) { event_sink_->Success(map); diff --git a/shell/platform/tizen/channels/app_control_channel.h b/shell/platform/tizen/channels/app_control_channel.h index a3c7475c782df..6663cbe261687 100644 --- a/shell/platform/tizen/channels/app_control_channel.h +++ b/shell/platform/tizen/channels/app_control_channel.h @@ -30,26 +30,26 @@ class AppControlChannel { void UnregisterEventHandler(); void SendAlreadyQueuedEvents(); - std::shared_ptr GetAppControl(const EncodableValue* arguments); + AppControl* GetAppControl(const EncodableValue* arguments); void CreateAppControl(std::unique_ptr> result); - void Dispose(std::shared_ptr app_control, + void Dispose(AppControl* app_control, std::unique_ptr> result); - void Reply(std::shared_ptr app_control, + void Reply(AppControl* app_control, const EncodableValue* arguments, std::unique_ptr> result); - void SendLaunchRequest(std::shared_ptr app_control, + void SendLaunchRequest(AppControl* app_control, const EncodableValue* arguments, std::unique_ptr> result); void SendTerminateRequest( - std::shared_ptr app_control, + AppControl* app_control, std::unique_ptr> result); - void SetAppControlData(std::shared_ptr app_control, + void SetAppControlData(AppControl* app_control, const EncodableValue* arguments, std::unique_ptr> result); - void SendAppControlDataEvent(std::shared_ptr app_control); + void SendAppControlDataEvent(AppControl* app_control); std::unique_ptr> method_channel_; std::unique_ptr> event_channel_; @@ -58,7 +58,7 @@ class AppControlChannel { // We need this queue, because there is no quarantee // that EventChannel on Dart side will be registered // before native OnAppControl event - std::queue> queue_; + std::queue queue_; }; } // namespace flutter From f3011db6cde273d42861e6a73b877984c8562c19 Mon Sep 17 00:00:00 2001 From: Swift Kim Date: Sun, 12 Sep 2021 20:57:29 +0900 Subject: [PATCH 3/3] Fix memory leaks - Add NativeAttachAppControl - Move definitions to the header --- shell/platform/tizen/channels/app_control.cc | 19 +++++++++++---- shell/platform/tizen/channels/app_control.h | 24 +++++++++++++++++++ .../tizen/channels/app_control_channel.cc | 2 +- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/shell/platform/tizen/channels/app_control.cc b/shell/platform/tizen/channels/app_control.cc index 8e6dc8e9d8094..4d08f9e2b1eef 100644 --- a/shell/platform/tizen/channels/app_control.cc +++ b/shell/platform/tizen/channels/app_control.cc @@ -4,16 +4,14 @@ #include "app_control.h" -#include "flutter/shell/platform/common/public/flutter_export.h" #include "flutter/shell/platform/tizen/channels/app_control_channel.h" #include "flutter/shell/platform/tizen/logger.h" -#include "third_party/dart/runtime/include/dart_api_dl.h" -DART_EXPORT FLUTTER_EXPORT intptr_t NativeInitializeDartApi(void* data) { +intptr_t NativeInitializeDartApi(void* data) { return Dart_InitializeApiDL(data); } -DART_EXPORT FLUTTER_EXPORT uint32_t NativeCreateAppControl(Dart_Handle handle) { +int32_t NativeCreateAppControl(Dart_Handle handle) { auto app_control = std::make_unique(); if (!app_control->handle()) { return -1; @@ -29,6 +27,19 @@ DART_EXPORT FLUTTER_EXPORT uint32_t NativeCreateAppControl(Dart_Handle handle) { return id; } +bool NativeAttachAppControl(int32_t id, Dart_Handle handle) { + auto app_control = flutter::AppControlManager::GetInstance().FindById(id); + if (!app_control || !app_control->handle()) { + return false; + } + Dart_NewFinalizableHandle_DL( + handle, app_control, 64, [](void* isolate_callback_data, void* peer) { + auto app_control = reinterpret_cast(peer); + flutter::AppControlManager::GetInstance().Remove(app_control->id()); + }); + return true; +} + namespace flutter { int32_t AppControl::next_id_ = 0; diff --git a/shell/platform/tizen/channels/app_control.h b/shell/platform/tizen/channels/app_control.h index 2fb82296c5f0a..94649d1b7451e 100644 --- a/shell/platform/tizen/channels/app_control.h +++ b/shell/platform/tizen/channels/app_control.h @@ -11,6 +11,30 @@ #include "flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h" #include "flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h" +#include "flutter/shell/platform/common/public/flutter_export.h" +#include "third_party/dart/runtime/include/dart_api_dl.h" + +// Called by Dart code through FFI to initialize dart_api_dl.h. +DART_EXPORT FLUTTER_EXPORT intptr_t NativeInitializeDartApi(void* data); + +// Creates an internally managed instance of AppControl and associates with +// |handle|. +// +// A finalizer is attached to the created instance and invoked when the +// associated |handle| is disposed by GC. +// +// Returns a unique AppControl ID on success, otherwise -1. +DART_EXPORT FLUTTER_EXPORT int32_t NativeCreateAppControl(Dart_Handle handle); + +// Finds an instance of AppControl with |id| and associates with |handle|. +// +// A finalizer is attached to the instance and invoked when the associated +// |handle| is disposed by GC. +// +// Returns false if an instance of AppControl with the given |id| could not +// be found, otherwise true. +DART_EXPORT FLUTTER_EXPORT bool NativeAttachAppControl(int32_t id, + Dart_Handle handle); namespace flutter { diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index 3d29f41364b13..9ba1f2a3f55bc 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -51,7 +51,7 @@ void AppControlChannel::NotifyAppControl(void* handle) { auto app_control = std::make_unique(static_cast(handle)); if (!app_control->handle()) { - FT_LOG(Error) << "Could not clone AppControl."; + FT_LOG(Error) << "Could not create an instance of AppControl."; return; } if (!event_sink_) {