From 7260efe2d11fcaac6d28368a8658c564f3f37462 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Thu, 24 Jun 2021 16:04:18 +0200 Subject: [PATCH 01/18] [AppControl] Add support for reading operation from app_control Signed-off-by: Rafal Walczyna --- shell/platform/tizen/BUILD.gn | 2 + .../tizen/channels/app_control_channel.cc | 60 +++++++++++++++++++ .../tizen/channels/app_control_channel.h | 37 ++++++++++++ shell/platform/tizen/flutter_tizen.cc | 5 ++ shell/platform/tizen/flutter_tizen_engine.cc | 2 + shell/platform/tizen/flutter_tizen_engine.h | 2 + shell/platform/tizen/public/flutter_tizen.h | 5 ++ 7 files changed, 113 insertions(+) create mode 100644 shell/platform/tizen/channels/app_control_channel.cc create mode 100644 shell/platform/tizen/channels/app_control_channel.h diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index 2f9f9199b4e6f..14198e748f5f9 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -112,6 +112,7 @@ template("embedder") { public = _public_headers sources = [ + "channels/app_control_channel.cc", "channels/key_event_channel.cc", "channels/lifecycle_channel.cc", "channels/navigation_channel.cc", @@ -162,6 +163,7 @@ template("embedder") { "base-utils-i18n", "capi-appfw-application", "capi-appfw-app-common", + "capi-appfw-app-control", "capi-base-common", "capi-system-info", "capi-system-system-settings", diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc new file mode 100644 index 0000000000000..dcf57774c8abd --- /dev/null +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -0,0 +1,60 @@ +// 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. + +#include "app_control_channel.h" + +#include "flutter/shell/platform/tizen/tizen_log.h" + +namespace flutter { + +static constexpr char kChannelName[] = "tizen/app_control"; + +AppControlChannel::AppControlChannel(BinaryMessenger* messenger) + : app_control_(nullptr) { + FT_LOGD("AppControlChannel"); + method_channel_ = std::make_unique>( + messenger, kChannelName, &StandardMethodCodec::GetInstance()); + + method_channel_->SetMethodCallHandler([this](const auto& call, auto result) { + this->HandleMethodCall(call, std::move(result)); + }); +} + +AppControlChannel::~AppControlChannel() {} + +void AppControlChannel::NotifyAppControl(app_control_h app_control) { + FT_LOGD("NotifyAppControl"); + int ret = app_control_clone(&app_control_, app_control); + if (ret != APP_CONTROL_ERROR_NONE) { + FT_LOGE("Could not clone app control handle"); + return; + } +} + +void AppControlChannel::HandleMethodCall( + const MethodCall& method_call, + std::unique_ptr> result) { + FT_LOGD("HandleMethodCall : %s", method_call.method_name().data()); + // const auto& arguments = *method_call.arguments(); + + if (method_call.method_name().compare("getOperation") == 0) { + getOperation(std::move(result)); + } else { + result->NotImplemented(); + } +} + +void AppControlChannel::getOperation( + std::unique_ptr> result) { + char* op; + int ret = app_control_get_operation(app_control_, &op); + if (ret != APP_CONTROL_ERROR_NONE) { + result->Error("Could not get operation"); + return; + } + result->Success(EncodableValue(std::string(op))); + free(op); +} + +} // namespace flutter diff --git a/shell/platform/tizen/channels/app_control_channel.h b/shell/platform/tizen/channels/app_control_channel.h new file mode 100644 index 0000000000000..6844a8fb9de2a --- /dev/null +++ b/shell/platform/tizen/channels/app_control_channel.h @@ -0,0 +1,37 @@ +// 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_APP_CONTROL_CHANNEL_H_ +#define EMBEDDER_APP_CONTROL_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/common/client_wrapper/include/flutter/standard_method_codec.h" + +class FlutterTizenEngine; + +namespace flutter { + +class AppControlChannel { + public: + explicit AppControlChannel(BinaryMessenger* messenger); + virtual ~AppControlChannel(); + + void NotifyAppControl(app_control_h app_control); + + private: + void HandleMethodCall(const MethodCall& method_call, + std::unique_ptr> result); + + void getOperation(std::unique_ptr> result); + + app_control_h app_control_; + std::unique_ptr> method_channel_; +}; + +} // namespace flutter +#endif // EMBEDDER_APP_CONTROL_CHANNEL_H_ diff --git a/shell/platform/tizen/flutter_tizen.cc b/shell/platform/tizen/flutter_tizen.cc index 1cc45c85cf144..bd4308a566390 100644 --- a/shell/platform/tizen/flutter_tizen.cc +++ b/shell/platform/tizen/flutter_tizen.cc @@ -118,6 +118,11 @@ void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger, user_data); } +void FlutterDesktopNotifyAppControl(FlutterDesktopEngineRef engine, + app_control_h app_control) { + EngineFromHandle(engine)->app_control_channel->NotifyAppControl(app_control); +} + void FlutterDesktopNotifyLocaleChange(FlutterDesktopEngineRef engine) { EngineFromHandle(engine)->SetupLocales(); } diff --git a/shell/platform/tizen/flutter_tizen_engine.cc b/shell/platform/tizen/flutter_tizen_engine.cc index 91b112b044d98..1b4a05ac87b95 100644 --- a/shell/platform/tizen/flutter_tizen_engine.cc +++ b/shell/platform/tizen/flutter_tizen_engine.cc @@ -243,6 +243,8 @@ bool FlutterTizenEngine::RunEngine(const char* entrypoint) { internal_plugin_registrar_ = std::make_unique(plugin_registrar_.get()); + app_control_channel = std::make_unique( + internal_plugin_registrar_->messenger()); platform_channel = std::make_unique( internal_plugin_registrar_->messenger(), renderer.get()); settings_channel = std::make_unique( diff --git a/shell/platform/tizen/flutter_tizen_engine.h b/shell/platform/tizen/flutter_tizen_engine.h index 92294e5bf88b9..5ac57f0b853e1 100644 --- a/shell/platform/tizen/flutter_tizen_engine.h +++ b/shell/platform/tizen/flutter_tizen_engine.h @@ -11,6 +11,7 @@ #include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h" #include "flutter/shell/platform/common/incoming_message_dispatcher.h" #include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/tizen/channels/app_control_channel.h" #include "flutter/shell/platform/tizen/channels/key_event_channel.h" #include "flutter/shell/platform/tizen/channels/lifecycle_channel.h" #include "flutter/shell/platform/tizen/channels/navigation_channel.h" @@ -137,6 +138,7 @@ class FlutterTizenEngine : public TizenRenderer::Delegate { std::unique_ptr renderer; // The system channels for communicating between Flutter and the platform. + std::unique_ptr app_control_channel; std::unique_ptr key_event_channel; std::unique_ptr lifecycle_channel; std::unique_ptr navigation_channel; diff --git a/shell/platform/tizen/public/flutter_tizen.h b/shell/platform/tizen/public/flutter_tizen.h index a0a70da83c47a..079c5d137106f 100644 --- a/shell/platform/tizen/public/flutter_tizen.h +++ b/shell/platform/tizen/public/flutter_tizen.h @@ -8,6 +8,7 @@ #include #include +#include #include "flutter_export.h" #include "flutter_messenger.h" @@ -89,6 +90,10 @@ FlutterDesktopGetPluginRegistrar(FlutterDesktopEngineRef engine, FLUTTER_EXPORT FlutterDesktopMessengerRef FlutterDesktopEngineGetMessenger(FlutterDesktopEngineRef engine); +// Posts an app control to the engine instance. +FLUTTER_EXPORT void FlutterDesktopNotifyAppControl( + FlutterDesktopEngineRef engine, app_control_h app_control); + // Posts a locale change notification to the engine instance. FLUTTER_EXPORT void FlutterDesktopNotifyLocaleChange( FlutterDesktopEngineRef engine); From 8fb16b79a6ad172b9f23fef9fecc9bf72163a812 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Mon, 28 Jun 2021 15:38:42 +0200 Subject: [PATCH 02/18] [AppControl] Add EventChannel and queue for app controls Signed-off-by: Rafal Walczyna --- .../tizen/channels/app_control_channel.cc | 75 +++++++++++++++---- .../tizen/channels/app_control_channel.h | 55 +++++++++++++- 2 files changed, 111 insertions(+), 19 deletions(-) diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index dcf57774c8abd..b5c4eaccd40c3 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -3,15 +3,15 @@ // found in the LICENSE file. #include "app_control_channel.h" - -#include "flutter/shell/platform/tizen/tizen_log.h" +#include "flutter/shell/platform/common/client_wrapper/include/flutter/event_stream_handler_functions.h" namespace flutter { static constexpr char kChannelName[] = "tizen/app_control"; +static constexpr char kEventChannelName[] = "tizen/app_control_event"; +int AppControl::next_id_ = 0; -AppControlChannel::AppControlChannel(BinaryMessenger* messenger) - : app_control_(nullptr) { +AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { FT_LOGD("AppControlChannel"); method_channel_ = std::make_unique>( messenger, kChannelName, &StandardMethodCodec::GetInstance()); @@ -19,16 +19,39 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) method_channel_->SetMethodCallHandler([this](const auto& call, auto result) { this->HandleMethodCall(call, std::move(result)); }); + + event_channel_ = std::make_unique>( + messenger, kEventChannelName, &StandardMethodCodec::GetInstance()); + + auto event_channel_handler = + std::make_unique>( + [this](const flutter::EncodableValue* arguments, + std::unique_ptr>&& events) + -> std::unique_ptr> { + FT_LOGD("OnListen"); + RegisterEventHandler(std::move(events)); + return nullptr; + }, + [this](const flutter::EncodableValue* arguments) + -> std::unique_ptr> { + FT_LOGD("OnCancel"); + UnregisterEventHandler(); + return nullptr; + }); + + event_channel_->SetStreamHandler(std::move(event_channel_handler)); } AppControlChannel::~AppControlChannel() {} void AppControlChannel::NotifyAppControl(app_control_h app_control) { FT_LOGD("NotifyAppControl"); - int ret = app_control_clone(&app_control_, app_control); - if (ret != APP_CONTROL_ERROR_NONE) { - FT_LOGE("Could not clone app control handle"); - return; + auto app = std::make_unique(app_control); + if (!events_) { + queue_.push(std::move(app)); + FT_LOGE("EventChannel not set yet"); + } else { + events_->Success(EncodableValue(app->GetOperation())); } } @@ -38,23 +61,43 @@ void AppControlChannel::HandleMethodCall( FT_LOGD("HandleMethodCall : %s", method_call.method_name().data()); // const auto& arguments = *method_call.arguments(); - if (method_call.method_name().compare("getOperation") == 0) { - getOperation(std::move(result)); + if (method_call.method_name().compare("GetOperation") == 0) { + GetOperation(std::move(result)); } else { result->NotImplemented(); } } -void AppControlChannel::getOperation( +void AppControlChannel::RegisterEventHandler( + std::unique_ptr> events) { + events_ = std::move(events); + SendAlreadyQueuedEvents(); +} + +void AppControlChannel::UnregisterEventHandler() { + events_.reset(); +} + +void AppControlChannel::SendAlreadyQueuedEvents() { + while (!queue_.empty()) { + events_->Success(EncodableValue(queue_.front()->GetOperation())); + queue_.pop(); + } +} + +void AppControlChannel::GetOperation( std::unique_ptr> result) { - char* op; - int ret = app_control_get_operation(app_control_, &op); - if (ret != APP_CONTROL_ERROR_NONE) { + if (queue_.empty()) { + result->Error("No app_control"); + return; + } + std::string operation = queue_.front()->GetOperation(); + if (operation.empty()) { result->Error("Could not get operation"); return; } - result->Success(EncodableValue(std::string(op))); - free(op); + result->Success(EncodableValue(operation)); + return; } } // namespace flutter diff --git a/shell/platform/tizen/channels/app_control_channel.h b/shell/platform/tizen/channels/app_control_channel.h index 6844a8fb9de2a..2c80f9dd3bd8c 100644 --- a/shell/platform/tizen/channels/app_control_channel.h +++ b/shell/platform/tizen/channels/app_control_channel.h @@ -6,16 +6,55 @@ #define EMBEDDER_APP_CONTROL_CHANNEL_H_ #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/common/client_wrapper/include/flutter/standard_method_codec.h" +#include "flutter/shell/platform/tizen/tizen_log.h" class FlutterTizenEngine; namespace flutter { +class AppControl { + public: + AppControl(app_control_h app_control) : id_(next_id_++) { + FT_LOGD("AppControl construct: %d", id_); + int ret = app_control_clone(&app_control_, app_control); + if (ret != APP_CONTROL_ERROR_NONE) { + FT_LOGE("Could not clone app control handle"); + app_control_ = nullptr; + return; + } + } + + ~AppControl() { + FT_LOGD("AppControl destruct: %d", id_); + app_control_destroy(app_control_); + } + + std::string GetOperation() { + FT_LOGD("AppControl::GetOperation"); + char* op; + int ret = app_control_get_operation(app_control_, &op); + if (ret != APP_CONTROL_ERROR_NONE) { + FT_LOGE("Could not get operation"); + return ""; + } + std::string operation{op}; + free(op); + return operation; + } + + private: + app_control_h app_control_; + int id_; + static int next_id_; +}; + class AppControlChannel { public: explicit AppControlChannel(BinaryMessenger* messenger); @@ -26,11 +65,21 @@ class AppControlChannel { private: void HandleMethodCall(const MethodCall& method_call, std::unique_ptr> result); + void RegisterEventHandler( + std::unique_ptr> events); + void UnregisterEventHandler(); + void SendAlreadyQueuedEvents(); + void GetOperation(std::unique_ptr> result); - void getOperation(std::unique_ptr> result); - - app_control_h app_control_; std::unique_ptr> method_channel_; + std::unique_ptr> event_channel_; + std::unique_ptr> events_; + + // We need this queue, because there is no quarantee + // that EventChannel on Dart side will be registered + // before native OnAppControl event + // TODO: Add limit for queue elements + std::queue> queue_; }; } // namespace flutter From 4803e5a2dffa7a891c005c5c9394e371b19ec806 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Thu, 1 Jul 2021 14:43:31 +0200 Subject: [PATCH 03/18] [AppControl] Add basic operations for AppControl Signed-off-by: Rafal Walczyna --- .../tizen/channels/app_control_channel.cc | 184 ++++++++++++++++-- .../tizen/channels/app_control_channel.h | 124 +++++++++--- 2 files changed, 272 insertions(+), 36 deletions(-) diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index b5c4eaccd40c3..4134e544efe50 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -12,7 +12,7 @@ static constexpr char kEventChannelName[] = "tizen/app_control_event"; int AppControl::next_id_ = 0; AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { - FT_LOGD("AppControlChannel"); + FT_LOGE("AppControlChannel"); method_channel_ = std::make_unique>( messenger, kChannelName, &StandardMethodCodec::GetInstance()); @@ -28,13 +28,13 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { [this](const flutter::EncodableValue* arguments, std::unique_ptr>&& events) -> std::unique_ptr> { - FT_LOGD("OnListen"); + FT_LOGE("OnListen"); RegisterEventHandler(std::move(events)); return nullptr; }, [this](const flutter::EncodableValue* arguments) -> std::unique_ptr> { - FT_LOGD("OnCancel"); + FT_LOGE("OnCancel"); UnregisterEventHandler(); return nullptr; }); @@ -45,20 +45,21 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { AppControlChannel::~AppControlChannel() {} void AppControlChannel::NotifyAppControl(app_control_h app_control) { - FT_LOGD("NotifyAppControl"); + FT_LOGE("NotifyAppControl"); auto app = std::make_unique(app_control); if (!events_) { - queue_.push(std::move(app)); + queue_.push(app->GetId()); FT_LOGE("EventChannel not set yet"); } else { - events_->Success(EncodableValue(app->GetOperation())); + events_->Success(EncodableValue(app->GetId())); } + map_.insert({app->GetId(), std::move(app)}); } void AppControlChannel::HandleMethodCall( const MethodCall& method_call, std::unique_ptr> result) { - FT_LOGD("HandleMethodCall : %s", method_call.method_name().data()); + FT_LOGE("HandleMethodCall : %s", method_call.method_name().data()); // const auto& arguments = *method_call.arguments(); if (method_call.method_name().compare("GetOperation") == 0) { @@ -70,17 +71,20 @@ void AppControlChannel::HandleMethodCall( void AppControlChannel::RegisterEventHandler( std::unique_ptr> events) { + FT_LOGE("RegisterEventHandler"); events_ = std::move(events); SendAlreadyQueuedEvents(); } void AppControlChannel::UnregisterEventHandler() { + FT_LOGE("UnregisterEventHandler"); events_.reset(); } void AppControlChannel::SendAlreadyQueuedEvents() { + FT_LOGE("HandleMethodCall: %d", queue_.size()); while (!queue_.empty()) { - events_->Success(EncodableValue(queue_.front()->GetOperation())); + events_->Success(EncodableValue(queue_.front())); queue_.pop(); } } @@ -91,13 +95,167 @@ void AppControlChannel::GetOperation( result->Error("No app_control"); return; } - std::string operation = queue_.front()->GetOperation(); - if (operation.empty()) { - result->Error("Could not get operation"); + result->Success(EncodableValue(queue_.size())); + return; +} + +AppControl::AppControl(app_control_h app_control) : id_(next_id_++) { + FT_LOGE("AppControl construct: %d", id_); + int ret = app_control_clone(&handle_, app_control); + if (ret != APP_CONTROL_ERROR_NONE) { + FT_LOGE("Could not clone app control handle"); + handle_ = nullptr; return; } - result->Success(EncodableValue(operation)); - return; +} + +AppControl::~AppControl() { + FT_LOGE("AppControl destruct: %d", id_); + app_control_destroy(handle_); +} + +AppControlResult AppControl::GetString(std::string& str, + int func(app_control_h, char**)) { + FT_LOGD("AppControl::GetString"); + char* op; + int ret = func(handle_, &op); + if (ret != APP_CONTROL_ERROR_NONE) { + return AppControlResult(ret); + } + str = std::string{op}; + free(op); + return AppControlResult(APP_CONTROL_ERROR_NONE); +} + +AppControlResult AppControl::SetString(const std::string& str, + int func(app_control_h, const char*)) { + FT_LOGD("AppControl::SetString"); + int ret = func(handle_, str.c_str()); + return AppControlResult(ret); +} + +bool _app_control_extra_data_cb(app_control_h app, + const char* key, + void* user_data) { + auto extra_data = static_cast(user_data); + bool is_array = false; + int ret = app_control_is_extra_data_array(app, key, &is_array); + if (ret != APP_CONTROL_ERROR_NONE) { + FT_LOGE("app_control_is_extra_data_array() failed at key %s", key); + return false; + } + + if (is_array) { + char** strings = NULL; + int length = 0; + ret = app_control_get_extra_data_array(app, key, &strings, &length); + if (ret != APP_CONTROL_ERROR_NONE) { + FT_LOGE("app_control_get_extra_data() failed at key %s", key); + return false; + } + std::vector vec; + for (int i = 0; i < length; i++) { + vec.push_back(strings[i]); + free(strings[i]); + } + free(strings); + extra_data->Add(key, vec); + } else { + char* value; + ret = app_control_get_extra_data(app, key, &value); + if (ret != APP_CONTROL_ERROR_NONE) { + FT_LOGE("app_control_get_extra_data() failed at key %s", key); + return false; + } + extra_data->Add(key, value); + free(value); + } + + return true; +} + +AppControlResult AppControl::ReadExtraData() { + int ret = app_control_foreach_extra_data(handle_, _app_control_extra_data_cb, + &extra_data_); + return AppControlResult(ret); +} + +AppControlResult AppControl::GetOperation(std::string& operation) { + return GetString(operation, app_control_get_operation); +} + +AppControlResult AppControl::SetOperation(const std::string& operation) { + return SetString(operation, app_control_set_operation); +} + +AppControlResult AppControl::GetUri(std::string& uri) { + return GetString(uri, app_control_get_uri); +} + +AppControlResult AppControl::SetUri(const std::string& uri) { + return SetString(uri, app_control_set_uri); +} + +AppControlResult AppControl::GetMime(std::string& mime) { + return GetString(mime, app_control_get_mime); +} + +AppControlResult AppControl::SetMime(const std::string& mime) { + return SetString(mime, app_control_set_mime); +} + +AppControlResult AppControl::GetCategory(std::string& category) { + return GetString(category, app_control_get_category); +} + +AppControlResult AppControl::SetCategory(const std::string& category) { + return SetString(category, app_control_set_category); +} + +AppControlResult AppControl::GetAppId(std::string& app_id) { + return GetString(app_id, app_control_get_app_id); +} + +AppControlResult AppControl::SetAppId(const std::string& app_id) { + return SetString(app_id, app_control_set_app_id); +} + +AppControlResult AppControl::GetComponentId(std::string& component_id) { + // Since 5.5 + return GetString(component_id, app_control_get_component_id); +} + +AppControlResult AppControl::SetComponentId(const std::string& component_id) { + // Since 5.5 + return SetString(component_id, app_control_set_component_id); +} + +AppControlResult AppControl::GetCaller(std::string& caller) { + return GetString(caller, app_control_get_caller); +} + +AppControlResult AppControl::GetLaunchMode(LaunchMode& launch_mode) { + app_control_launch_mode_e launch_mode_e; + int ret = app_control_get_launch_mode(handle_, &launch_mode_e); + if (ret != APP_CONTROL_ERROR_NONE) { + return AppControlResult(ret); + } + launch_mode = static_cast(launch_mode_e); + return AppControlResult(APP_CONTROL_ERROR_NONE); +} + +AppControlResult AppControl::SetLaunchMode(const LaunchMode launch_mode) { + app_control_launch_mode_e launch_mode_e = + static_cast(launch_mode); + int ret = app_control_set_launch_mode(handle_, launch_mode_e); + return AppControlResult(ret); +} + +AppControlResult AppControl::Reply(AppControl* reply, Result result) { + app_control_result_e result_e = static_cast(result); + int ret = app_control_reply_to_launch_request(reply->Handle(), this->handle_, + result_e); + return AppControlResult(ret); } } // namespace flutter diff --git a/shell/platform/tizen/channels/app_control_channel.h b/shell/platform/tizen/channels/app_control_channel.h index 2c80f9dd3bd8c..eee6b7068eb93 100644 --- a/shell/platform/tizen/channels/app_control_channel.h +++ b/shell/platform/tizen/channels/app_control_channel.h @@ -7,6 +7,7 @@ #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" @@ -19,38 +20,113 @@ class FlutterTizenEngine; namespace flutter { -class AppControl { +using EncodableList = std::vector; +using EncodableMap = std::map; + +struct AppControlResult { + AppControlResult() : error_code(APP_CONTROL_ERROR_NONE){}; + AppControlResult(int code) : error_code(code) {} + + // Returns false on error + operator bool() const { return APP_CONTROL_ERROR_NONE == error_code; } + + std::string message() { return get_error_message(error_code); } + + int error_code; +}; + +class AppControlExtraData { public: - AppControl(app_control_h app_control) : id_(next_id_++) { - FT_LOGD("AppControl construct: %d", id_); - int ret = app_control_clone(&app_control_, app_control); - if (ret != APP_CONTROL_ERROR_NONE) { - FT_LOGE("Could not clone app control handle"); - app_control_ = nullptr; - return; + AppControlExtraData() {} + ~AppControlExtraData() {} + + void Add(std::string key, std::string value) { + if (strings_lists_.find(key) != strings_lists_.end()) { + strings_lists_.erase(key); + } + strings_[key] = value; + } + + void Add(std::string key, std::vector value) { + if (strings_.find(key) != strings_.end()) { + strings_.erase(key); } + strings_lists_[key] = value; } - ~AppControl() { - FT_LOGD("AppControl destruct: %d", id_); - app_control_destroy(app_control_); + void Remove(std::string key) { + strings_.erase(key); + strings_lists_.erase(key); } - std::string GetOperation() { - FT_LOGD("AppControl::GetOperation"); - char* op; - int ret = app_control_get_operation(app_control_, &op); - if (ret != APP_CONTROL_ERROR_NONE) { - FT_LOGE("Could not get operation"); - return ""; + bool Has(std::string key) { + if (strings_.find(key) != strings_.end()) { + return true; } - std::string operation{op}; - free(op); - return operation; + if (strings_lists_.find(key) != strings_lists_.end()) { + return true; + } + return false; + } + + std::vector& GetList(std::string key) { + return strings_lists_[key]; } + std::string& GetString(std::string key) { return strings_[key]; } + + size_t Size() { return strings_.size() + strings_lists_.size(); } + + private: + std::unordered_map strings_; + std::unordered_map> strings_lists_; +}; + +class AppControl { + public: + enum LaunchMode { + Single = APP_CONTROL_LAUNCH_MODE_SINGLE, + Group = APP_CONTROL_LAUNCH_MODE_GROUP + }; + enum Result { + Started = APP_CONTROL_RESULT_APP_STARTED, + Succeeded = APP_CONTROL_RESULT_SUCCEEDED, + Failed = APP_CONTROL_RESULT_FAILED, + Cancelled = APP_CONTROL_RESULT_CANCELED + }; + + AppControl(app_control_h app_control); + ~AppControl(); + + int GetId() { return id_; } + app_control_h Handle() { return handle_; } + + AppControlResult GetOperation(std::string& operation); + AppControlResult SetOperation(const std::string& operation); + AppControlResult GetUri(std::string& uri); + AppControlResult SetUri(const std::string& uri); + AppControlResult GetMime(std::string& mime); + AppControlResult SetMime(const std::string& mime); + AppControlResult GetCategory(std::string& category); + AppControlResult SetCategory(const std::string& category); + AppControlResult GetAppId(std::string& app_id); + AppControlResult SetAppId(const std::string& app_id); + AppControlResult GetComponentId(std::string& component_id); + AppControlResult SetComponentId(const std::string& component_id); + AppControlResult GetCaller(std::string& caller); + AppControlResult GetLaunchMode(LaunchMode& launch_mode); + AppControlResult SetLaunchMode(const LaunchMode launch_mode); + + AppControlResult Reply(AppControl* reply, Result result); + private: - app_control_h app_control_; + AppControlResult GetString(std::string& str, int func(app_control_h, char**)); + AppControlResult SetString(const std::string& str, + int func(app_control_h, const char*)); + AppControlResult ReadExtraData(); + + AppControlExtraData extra_data_; + app_control_h handle_; int id_; static int next_id_; }; @@ -79,7 +155,9 @@ class AppControlChannel { // that EventChannel on Dart side will be registered // before native OnAppControl event // TODO: Add limit for queue elements - std::queue> queue_; + std::queue queue_; + + std::unordered_map> map_; }; } // namespace flutter From cc9ac62938744bc452e1f4f1542dc33915033415 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Fri, 2 Jul 2021 14:45:43 +0200 Subject: [PATCH 04/18] [AppControl] Refactor extra data to use EncodableValue Signed-off-by: Rafal Walczyna --- .../tizen/channels/app_control_channel.cc | 322 ++++++++++++++++-- .../tizen/channels/app_control_channel.h | 59 +++- 2 files changed, 337 insertions(+), 44 deletions(-) diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index 4134e544efe50..a58b032e10fce 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -7,12 +7,12 @@ namespace flutter { -static constexpr char kChannelName[] = "tizen/app_control"; -static constexpr char kEventChannelName[] = "tizen/app_control_event"; +static constexpr char kChannelName[] = "tizen/internal/app_control_method"; +static constexpr char kEventChannelName[] = "tizen/internal/app_control_event"; int AppControl::next_id_ = 0; AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { - FT_LOGE("AppControlChannel"); + FT_LOGI("AppControlChannel"); method_channel_ = std::make_unique>( messenger, kChannelName, &StandardMethodCodec::GetInstance()); @@ -28,13 +28,13 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { [this](const flutter::EncodableValue* arguments, std::unique_ptr>&& events) -> std::unique_ptr> { - FT_LOGE("OnListen"); + FT_LOGI("OnListen"); RegisterEventHandler(std::move(events)); return nullptr; }, [this](const flutter::EncodableValue* arguments) -> std::unique_ptr> { - FT_LOGE("OnCancel"); + FT_LOGI("OnCancel"); UnregisterEventHandler(); return nullptr; }); @@ -45,11 +45,11 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { AppControlChannel::~AppControlChannel() {} void AppControlChannel::NotifyAppControl(app_control_h app_control) { - FT_LOGE("NotifyAppControl"); + FT_LOGI("NotifyAppControl"); auto app = std::make_unique(app_control); if (!events_) { queue_.push(app->GetId()); - FT_LOGE("EventChannel not set yet"); + FT_LOGI("EventChannel not set yet"); } else { events_->Success(EncodableValue(app->GetId())); } @@ -59,11 +59,29 @@ void AppControlChannel::NotifyAppControl(app_control_h app_control) { void AppControlChannel::HandleMethodCall( const MethodCall& method_call, std::unique_ptr> result) { - FT_LOGE("HandleMethodCall : %s", method_call.method_name().data()); - // const auto& arguments = *method_call.arguments(); - - if (method_call.method_name().compare("GetOperation") == 0) { - GetOperation(std::move(result)); + FT_LOGI("HandleMethodCall : %s", method_call.method_name().c_str()); + const auto arguments = method_call.arguments(); + const auto& method_name = method_call.method_name(); + // AppControl not needed + if (method_name.compare("CreateAppControl") == 0) { + CreateAppControl(arguments, std::move(result)); + } + // AppControl needed + if (method_name.compare("SendLaunchRequest") == 0) { + SendLaunchRequest(arguments, std::move(result)); + } else if (method_name.compare("SendTerminateRequest") == 0) { + SendTerminateRequest(arguments, std::move(result)); + } + // Getters Setters + if (method_name.compare("GetAppId") == 0) { + GetAppId(arguments, std::move(result)); + } else if (method_name.compare("SetAppId") == 0) { + SetAppId(arguments, std::move(result)); + } else if (method_name.compare("GetOperation") == 0) { + GetOperation(arguments, std::move(result)); + } else if (method_name.compare("SetOperation") == 0) { + SetOperation(arguments, std::move(result)); + } else if (method_name.compare("ASDF") == 0) { } else { result->NotImplemented(); } @@ -71,36 +89,212 @@ void AppControlChannel::HandleMethodCall( void AppControlChannel::RegisterEventHandler( std::unique_ptr> events) { - FT_LOGE("RegisterEventHandler"); + FT_LOGI("RegisterEventHandler"); events_ = std::move(events); SendAlreadyQueuedEvents(); } void AppControlChannel::UnregisterEventHandler() { - FT_LOGE("UnregisterEventHandler"); + FT_LOGI("UnregisterEventHandler"); events_.reset(); } void AppControlChannel::SendAlreadyQueuedEvents() { - FT_LOGE("HandleMethodCall: %d", queue_.size()); + FT_LOGI("SendAlreadyQueuedEvents: %d", queue_.size()); while (!queue_.empty()) { events_->Success(EncodableValue(queue_.front())); queue_.pop(); } } +template +bool AppControlChannel::GetValueFromArgs(const flutter::EncodableValue* args, + const char* key, + T& out) { + if (std::holds_alternative(*args)) { + flutter::EncodableMap map = std::get(*args); + if (map.find(flutter::EncodableValue(key)) != map.end()) { + flutter::EncodableValue value = map[flutter::EncodableValue(key)]; + if (std::holds_alternative(value)) { + out = std::get(value); + return true; + } + } + FT_LOGI("Key %s not found", key); + } + return false; +} + +bool AppControlChannel::GetEncodableValueFromArgs( + const flutter::EncodableValue* args, + const char* key, + flutter::EncodableValue& out) { + if (std::holds_alternative(*args)) { + flutter::EncodableMap map = std::get(*args); + if (map.find(flutter::EncodableValue(key)) != map.end()) { + out = map[flutter::EncodableValue(key)]; + return true; + } + } + return false; +} + +std::shared_ptr AppControlChannel::GetAppControl( + const EncodableValue* args) { + int id; + if (!GetValueFromArgs(args, "id", id)) { + FT_LOGE("Could not find AppControl with id %d", id); + return nullptr; + } + + if (map_.find(id) == map_.end()) { + FT_LOGE("Could not find AppControl with id %d", id); + return nullptr; + } + FT_LOGI("Found AppControl: %d", id); + return map_[id]; +} + +bool AppControlChannel::ValidateAppControlResult( + AppControlResult app_control_result, + std::unique_ptr> result) { + if (app_control_result) { + return true; + } + return false; +} + +void AppControlChannel::CreateAppControl( + const EncodableValue* args, + std::unique_ptr> result) { + FT_LOGI("AppControlChannel::CreateAppControl"); + 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 = std::make_unique(app_control); + int id = app->GetId(); + map_.insert({app->GetId(), std::move(app)}); + result->Success(EncodableValue(id)); +} + void AppControlChannel::GetOperation( + const EncodableValue* args, + std::unique_ptr> result) { + FT_LOGI("AppControlChannel::GetOperation"); + auto app_control = GetAppControl(args); + if (app_control == nullptr) { + result->Error("Could not execute GetOperation", "Invalid parameter"); + return; + } + std::string str; + auto ret = app_control->GetOperation(str); + if (ret) { + result->Success(EncodableValue(str)); + } else { + result->Error(ret.message()); + } +} + +void AppControlChannel::SetOperation( + const EncodableValue* args, std::unique_ptr> result) { - if (queue_.empty()) { - result->Error("No app_control"); + FT_LOGI("AppControlChannel::SetOperation"); + auto app_control = GetAppControl(args); + if (app_control == nullptr) { + result->Error("Could not execute SetOperation", "Invalid parameter"); return; } - result->Success(EncodableValue(queue_.size())); - return; + std::string str; + if (!GetValueFromArgs(args, "argument", str)) { + result->Error("Invalid argument"); + return; + } + auto ret = app_control->SetOperation(str); + if (ret) { + result->Success(EncodableValue(str)); + } else { + result->Error(ret.message()); + } +} + +void AppControlChannel::SendLaunchRequest( + const EncodableValue* args, + std::unique_ptr> result) { + FT_LOGI("AppControlChannel::SendLaunchRequest"); + auto app_control = GetAppControl(args); + if (app_control == nullptr) { + result->Error("Could not execute GetAppId", "Invalid parameter"); + return; + } + auto ret = app_control->SendLaunchRequest(); + if (ret) { + result->Success(); + } else { + result->Error(ret.message()); + } +} + +void AppControlChannel::SendTerminateRequest( + const EncodableValue* args, + std::unique_ptr> result) { + FT_LOGI("AppControlChannel::SendTerminateRequest"); + auto app_control = GetAppControl(args); + if (app_control == nullptr) { + result->Error("Could not execute GetAppId", "Invalid parameter"); + return; + } + auto ret = app_control->SendTerminateRequest(); + if (ret) { + result->Success(); + } else { + result->Error(ret.message()); + } +} + +void AppControlChannel::GetAppId( + const EncodableValue* args, + std::unique_ptr> result) { + FT_LOGI("AppControlChannel::GetAppId"); + auto app_control = GetAppControl(args); + if (app_control == nullptr) { + result->Error("Could not execute GetAppId", "Invalid parameter"); + return; + } + std::string str; + auto ret = app_control->GetAppId(str); + if (ret) { + result->Success(EncodableValue(str)); + } else { + result->Error(ret.message()); + } +} + +void AppControlChannel::SetAppId( + const EncodableValue* args, + std::unique_ptr> result) { + FT_LOGI("AppControlChannel::SetAppId"); + auto app_control = GetAppControl(args); + if (app_control == nullptr) { + result->Error("Could not execute SetAppId", "Invalid parameter"); + return; + } + std::string str; + if (!GetValueFromArgs(args, "argument", str)) { + result->Error("Invalid argument"); + return; + } + auto ret = app_control->SetAppId(str); + if (ret) { + result->Success(EncodableValue(str)); + } else { + result->Error(ret.message()); + } } AppControl::AppControl(app_control_h app_control) : id_(next_id_++) { - FT_LOGE("AppControl construct: %d", id_); + FT_LOGI("AppControl construct: %d", id_); int ret = app_control_clone(&handle_, app_control); if (ret != APP_CONTROL_ERROR_NONE) { FT_LOGE("Could not clone app control handle"); @@ -110,26 +304,30 @@ AppControl::AppControl(app_control_h app_control) : id_(next_id_++) { } AppControl::~AppControl() { - FT_LOGE("AppControl destruct: %d", id_); + FT_LOGI("AppControl destruct: %d", id_); app_control_destroy(handle_); } AppControlResult AppControl::GetString(std::string& str, int func(app_control_h, char**)) { - FT_LOGD("AppControl::GetString"); + FT_LOGI("AppControl::GetString"); char* op; - int ret = func(handle_, &op); - if (ret != APP_CONTROL_ERROR_NONE) { - return AppControlResult(ret); + AppControlResult ret = func(handle_, &op); + if (!ret) { + return ret; + } + if (op != nullptr) { + str = std::string{op}; + free(op); + } else { + str = ""; } - str = std::string{op}; - free(op); return AppControlResult(APP_CONTROL_ERROR_NONE); } AppControlResult AppControl::SetString(const std::string& str, int func(app_control_h, const char*)) { - FT_LOGD("AppControl::SetString"); + FT_LOGI("AppControl::SetString: %s", str.c_str()); int ret = func(handle_, str.c_str()); return AppControlResult(ret); } @@ -137,7 +335,7 @@ AppControlResult AppControl::SetString(const std::string& str, bool _app_control_extra_data_cb(app_control_h app, const char* key, void* user_data) { - auto extra_data = static_cast(user_data); + auto extra_data = static_cast(user_data); bool is_array = false; int ret = app_control_is_extra_data_array(app, key, &is_array); if (ret != APP_CONTROL_ERROR_NONE) { @@ -153,13 +351,14 @@ bool _app_control_extra_data_cb(app_control_h app, FT_LOGE("app_control_get_extra_data() failed at key %s", key); return false; } - std::vector vec; + EncodableList list; for (int i = 0; i < length; i++) { - vec.push_back(strings[i]); + list.push_back(EncodableValue(std::string(strings[i]))); free(strings[i]); } free(strings); - extra_data->Add(key, vec); + extra_data->insert( + {EncodableValue(std::string(key)), EncodableValue(list)}); } else { char* value; ret = app_control_get_extra_data(app, key, &value); @@ -167,16 +366,21 @@ bool _app_control_extra_data_cb(app_control_h app, FT_LOGE("app_control_get_extra_data() failed at key %s", key); return false; } - extra_data->Add(key, value); + extra_data->insert( + {EncodableValue(std::string(key)), EncodableValue(std::string(value))}); free(value); } return true; } -AppControlResult AppControl::ReadExtraData() { +AppControlResult AppControl::ReadAllExtraData(EncodableValue& value) { + EncodableMap extra_data; int ret = app_control_foreach_extra_data(handle_, _app_control_extra_data_cb, - &extra_data_); + &extra_data); + if (ret == APP_CONTROL_ERROR_NONE) { + value = EncodableValue(extra_data); + } return AppControlResult(ret); } @@ -251,6 +455,17 @@ AppControlResult AppControl::SetLaunchMode(const LaunchMode launch_mode) { return AppControlResult(ret); } +AppControlResult AppControl::SendLaunchRequest() { + AppControlResult ret = + app_control_send_launch_request(handle_, nullptr, nullptr); + return ret; +} + +AppControlResult AppControl::SendTerminateRequest() { + AppControlResult ret = app_control_send_terminate_request(handle_); + return ret; +} + AppControlResult AppControl::Reply(AppControl* reply, Result result) { app_control_result_e result_e = static_cast(result); int ret = app_control_reply_to_launch_request(reply->Handle(), this->handle_, @@ -258,4 +473,41 @@ AppControlResult AppControl::Reply(AppControl* reply, Result result) { return AppControlResult(ret); } +AppControlResult AppControl::AddExtraData(std::string key, + EncodableValue value) { + bool is_array = std::holds_alternative(value); + if (is_array) { + EncodableList& list = std::get(value); + return AddExtraDataList(key, list); + } else { + bool is_string = std::holds_alternative(value); + if (is_string) { + int ret = app_control_add_extra_data( + handle_, key.c_str(), std::get(value).c_str()); + return AppControlResult(ret); + } else { + return AppControlResult(APP_ERROR_INVALID_PARAMETER); + } + } + return AppControlResult(APP_CONTROL_ERROR_NONE); +} + +AppControlResult AppControl::AddExtraDataList(std::string& key, + EncodableList& list) { + size_t length = list.size(); + auto strings = new const char*[length]; + for (size_t i = 0; i < length; i++) { + bool is_string = std::holds_alternative(list[i]); + if (is_string) { + strings[i] = std::get(list[i]).c_str(); + } else { + delete[] strings; + return AppControlResult(APP_ERROR_INVALID_PARAMETER); + } + } + int ret = + app_control_add_extra_data_array(handle_, key.c_str(), strings, length); + delete[] strings; + return AppControlResult(ret); +} } // namespace flutter diff --git a/shell/platform/tizen/channels/app_control_channel.h b/shell/platform/tizen/channels/app_control_channel.h index eee6b7068eb93..f220b3c046bc9 100644 --- a/shell/platform/tizen/channels/app_control_channel.h +++ b/shell/platform/tizen/channels/app_control_channel.h @@ -20,9 +20,6 @@ class FlutterTizenEngine; namespace flutter { -using EncodableList = std::vector; -using EncodableMap = std::map; - struct AppControlResult { AppControlResult() : error_code(APP_CONTROL_ERROR_NONE){}; AppControlResult(int code) : error_code(code) {} @@ -69,7 +66,7 @@ class AppControlExtraData { return false; } - std::vector& GetList(std::string key) { + std::vector& GetVec(std::string key) { return strings_lists_[key]; } @@ -117,15 +114,28 @@ class AppControl { AppControlResult GetLaunchMode(LaunchMode& launch_mode); AppControlResult SetLaunchMode(const LaunchMode launch_mode); + AppControlResult SendLaunchRequest(); + AppControlResult SendTerminateRequest(); + AppControlResult Reply(AppControl* reply, Result result); + // AppControlResult AddExtraData(std::string key, std::string value); + AppControlResult AddExtraData(std::string key, EncodableValue value); + // AppControlResult AddExtraData(std::string key, + // std::vector value); + AppControlResult ReadAllExtraData(std::string key, EncodableValue& value); + private: AppControlResult GetString(std::string& str, int func(app_control_h, char**)); AppControlResult SetString(const std::string& str, int func(app_control_h, const char*)); - AppControlResult ReadExtraData(); + AppControlResult ReadAllExtraData(EncodableValue& value); + AppControlResult WriteExtraDataStringToHandle(); + AppControlResult WriteExtraDataToHandle(); - AppControlExtraData extra_data_; + AppControlResult AddExtraDataList(std::string& key, EncodableList& list); + + EncodableMap extra_data_; app_control_h handle_; int id_; static int next_id_; @@ -145,11 +155,42 @@ class AppControlChannel { std::unique_ptr> events); void UnregisterEventHandler(); void SendAlreadyQueuedEvents(); - void GetOperation(std::unique_ptr> result); + + template + bool GetValueFromArgs(const flutter::EncodableValue* args, + const char* key, + T& out); + bool GetEncodableValueFromArgs(const flutter::EncodableValue* args, + const char* key, + flutter::EncodableValue& out); + + std::shared_ptr GetAppControl(const EncodableValue* args); + bool ValidateAppControlResult( + AppControlResult app_control_result, + std::unique_ptr> result); + + void CreateAppControl(const EncodableValue* args, + std::unique_ptr> result); + + void SendLaunchRequest(const EncodableValue* args, + std::unique_ptr> result); + void SendTerminateRequest( + const EncodableValue* args, + std::unique_ptr> result); + + void GetOperation(const EncodableValue* args, + std::unique_ptr> result); + void SetOperation(const EncodableValue* args, + std::unique_ptr> result); + + void GetAppId(const EncodableValue* args, + std::unique_ptr> result); + void SetAppId(const EncodableValue* args, + std::unique_ptr> result); std::unique_ptr> method_channel_; std::unique_ptr> event_channel_; - std::unique_ptr> events_; + std::unique_ptr> events_; // We need this queue, because there is no quarantee // that EventChannel on Dart side will be registered @@ -157,7 +198,7 @@ class AppControlChannel { // TODO: Add limit for queue elements std::queue queue_; - std::unordered_map> map_; + std::unordered_map> map_; }; } // namespace flutter From 68811adfd24d700ad68be1b67ef60005a9eb26c5 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Fri, 2 Jul 2021 16:16:56 +0200 Subject: [PATCH 05/18] [AppControl] Refactor HandleMethodCall Signed-off-by: Rafal Walczyna --- .../tizen/channels/app_control_channel.cc | 226 ++++++++---------- .../tizen/channels/app_control_channel.h | 34 +-- 2 files changed, 104 insertions(+), 156 deletions(-) diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index a58b032e10fce..6f1386121a901 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -62,28 +62,94 @@ void AppControlChannel::HandleMethodCall( FT_LOGI("HandleMethodCall : %s", method_call.method_name().c_str()); const auto arguments = method_call.arguments(); const auto& method_name = method_call.method_name(); + // AppControl not needed if (method_name.compare("CreateAppControl") == 0) { CreateAppControl(arguments, std::move(result)); + return; } + // AppControl needed + auto app_control = GetAppControl(arguments); + if (app_control == nullptr) { + result->Error("Could not find app_control", "Invalid parameter"); + return; + } + + AppControlResult ret; + // Common if (method_name.compare("SendLaunchRequest") == 0) { - SendLaunchRequest(arguments, std::move(result)); + ret = app_control->SendLaunchRequest(); } else if (method_name.compare("SendTerminateRequest") == 0) { - SendTerminateRequest(arguments, std::move(result)); + ret = app_control->SendTerminateRequest(); } - // Getters Setters + + if (ret.valid) { + if (ret) { + result->Success(); + } else { + result->Error(ret.message()); + } + return; + } + + // Getters + std::string str; if (method_name.compare("GetAppId") == 0) { - GetAppId(arguments, std::move(result)); - } else if (method_name.compare("SetAppId") == 0) { - SetAppId(arguments, std::move(result)); + ret = app_control->GetAppId(str); } else if (method_name.compare("GetOperation") == 0) { - GetOperation(arguments, std::move(result)); + ret = app_control->GetOperation(str); + } else if (method_name.compare("GetUri") == 0) { + ret = app_control->GetUri(str); + } else if (method_name.compare("GetMime") == 0) { + ret = app_control->GetMime(str); + } else if (method_name.compare("GetCategory") == 0) { + ret = app_control->GetMime(str); + } else if (method_name.compare("GetCaller") == 0) { + ret = app_control->GetMime(str); + } else if (method_name.compare("GetLaunchMode") == 0) { + ret = app_control->GetLaunchMode(str); + } + + if (ret.valid) { + if (ret) { + result->Success(EncodableValue(str)); + } else { + result->Error(ret.message()); + } + return; + } + + // Setters + if (!GetValueFromArgs(arguments, "argument", str)) { + result->Error("Invalid argument"); + return; + } + + if (method_name.compare("SetAppId") == 0) { + ret = app_control->SetAppId(str); } else if (method_name.compare("SetOperation") == 0) { - SetOperation(arguments, std::move(result)); - } else if (method_name.compare("ASDF") == 0) { - } else { + ret = app_control->SetOperation(str); + } else if (method_name.compare("SetUri") == 0) { + ret = app_control->SetUri(str); + } else if (method_name.compare("SetMime") == 0) { + ret = app_control->SetMime(str); + } else if (method_name.compare("SetCategory") == 0) { + ret = app_control->SetMime(str); + } else if (method_name.compare("SetCaller") == 0) { + ret = app_control->SetMime(str); + } else if (method_name.compare("SetLaunchMode") == 0) { + ret = app_control->SetLaunchMode(str); + } + + if (ret.valid) { + if (ret) { + result->Success(); + } else { + result->Error(ret.message()); + } result->NotImplemented(); + return; } } @@ -156,9 +222,14 @@ std::shared_ptr AppControlChannel::GetAppControl( } bool AppControlChannel::ValidateAppControlResult( - AppControlResult app_control_result, - std::unique_ptr> result) { - if (app_control_result) { + AppControlResult ret, + MethodResult* result) { + if (ret.valid) { + if (ret) { + result->Success(); + } else { + result->Error(ret.message()); + } return true; } return false; @@ -179,120 +250,6 @@ void AppControlChannel::CreateAppControl( result->Success(EncodableValue(id)); } -void AppControlChannel::GetOperation( - const EncodableValue* args, - std::unique_ptr> result) { - FT_LOGI("AppControlChannel::GetOperation"); - auto app_control = GetAppControl(args); - if (app_control == nullptr) { - result->Error("Could not execute GetOperation", "Invalid parameter"); - return; - } - std::string str; - auto ret = app_control->GetOperation(str); - if (ret) { - result->Success(EncodableValue(str)); - } else { - result->Error(ret.message()); - } -} - -void AppControlChannel::SetOperation( - const EncodableValue* args, - std::unique_ptr> result) { - FT_LOGI("AppControlChannel::SetOperation"); - auto app_control = GetAppControl(args); - if (app_control == nullptr) { - result->Error("Could not execute SetOperation", "Invalid parameter"); - return; - } - std::string str; - if (!GetValueFromArgs(args, "argument", str)) { - result->Error("Invalid argument"); - return; - } - auto ret = app_control->SetOperation(str); - if (ret) { - result->Success(EncodableValue(str)); - } else { - result->Error(ret.message()); - } -} - -void AppControlChannel::SendLaunchRequest( - const EncodableValue* args, - std::unique_ptr> result) { - FT_LOGI("AppControlChannel::SendLaunchRequest"); - auto app_control = GetAppControl(args); - if (app_control == nullptr) { - result->Error("Could not execute GetAppId", "Invalid parameter"); - return; - } - auto ret = app_control->SendLaunchRequest(); - if (ret) { - result->Success(); - } else { - result->Error(ret.message()); - } -} - -void AppControlChannel::SendTerminateRequest( - const EncodableValue* args, - std::unique_ptr> result) { - FT_LOGI("AppControlChannel::SendTerminateRequest"); - auto app_control = GetAppControl(args); - if (app_control == nullptr) { - result->Error("Could not execute GetAppId", "Invalid parameter"); - return; - } - auto ret = app_control->SendTerminateRequest(); - if (ret) { - result->Success(); - } else { - result->Error(ret.message()); - } -} - -void AppControlChannel::GetAppId( - const EncodableValue* args, - std::unique_ptr> result) { - FT_LOGI("AppControlChannel::GetAppId"); - auto app_control = GetAppControl(args); - if (app_control == nullptr) { - result->Error("Could not execute GetAppId", "Invalid parameter"); - return; - } - std::string str; - auto ret = app_control->GetAppId(str); - if (ret) { - result->Success(EncodableValue(str)); - } else { - result->Error(ret.message()); - } -} - -void AppControlChannel::SetAppId( - const EncodableValue* args, - std::unique_ptr> result) { - FT_LOGI("AppControlChannel::SetAppId"); - auto app_control = GetAppControl(args); - if (app_control == nullptr) { - result->Error("Could not execute SetAppId", "Invalid parameter"); - return; - } - std::string str; - if (!GetValueFromArgs(args, "argument", str)) { - result->Error("Invalid argument"); - return; - } - auto ret = app_control->SetAppId(str); - if (ret) { - result->Success(EncodableValue(str)); - } else { - result->Error(ret.message()); - } -} - AppControl::AppControl(app_control_h app_control) : id_(next_id_++) { FT_LOGI("AppControl construct: %d", id_); int ret = app_control_clone(&handle_, app_control); @@ -438,19 +395,24 @@ AppControlResult AppControl::GetCaller(std::string& caller) { return GetString(caller, app_control_get_caller); } -AppControlResult AppControl::GetLaunchMode(LaunchMode& launch_mode) { +AppControlResult AppControl::GetLaunchMode(std::string& launch_mode) { app_control_launch_mode_e launch_mode_e; int ret = app_control_get_launch_mode(handle_, &launch_mode_e); if (ret != APP_CONTROL_ERROR_NONE) { return AppControlResult(ret); } - launch_mode = static_cast(launch_mode_e); + launch_mode = + (launch_mode_e == APP_CONTROL_LAUNCH_MODE_SINGLE ? "Single" : "Group"); return AppControlResult(APP_CONTROL_ERROR_NONE); } -AppControlResult AppControl::SetLaunchMode(const LaunchMode launch_mode) { - app_control_launch_mode_e launch_mode_e = - static_cast(launch_mode); +AppControlResult AppControl::SetLaunchMode(const std::string& launch_mode) { + app_control_launch_mode_e launch_mode_e; + if (launch_mode.compare("Single")) { + launch_mode_e = APP_CONTROL_LAUNCH_MODE_SINGLE; + } else { + launch_mode_e = APP_CONTROL_LAUNCH_MODE_GROUP; + } int ret = app_control_set_launch_mode(handle_, launch_mode_e); return AppControlResult(ret); } diff --git a/shell/platform/tizen/channels/app_control_channel.h b/shell/platform/tizen/channels/app_control_channel.h index f220b3c046bc9..063ecb546a091 100644 --- a/shell/platform/tizen/channels/app_control_channel.h +++ b/shell/platform/tizen/channels/app_control_channel.h @@ -21,15 +21,18 @@ class FlutterTizenEngine; namespace flutter { struct AppControlResult { - AppControlResult() : error_code(APP_CONTROL_ERROR_NONE){}; - AppControlResult(int code) : error_code(code) {} + AppControlResult() : valid(false){}; + AppControlResult(int code) : error_code(code), valid(true) {} // Returns false on error - operator bool() const { return APP_CONTROL_ERROR_NONE == error_code; } + operator bool() const { + return valid && (APP_CONTROL_ERROR_NONE == error_code); + } std::string message() { return get_error_message(error_code); } int error_code; + bool valid; }; class AppControlExtraData { @@ -111,8 +114,8 @@ class AppControl { AppControlResult GetComponentId(std::string& component_id); AppControlResult SetComponentId(const std::string& component_id); AppControlResult GetCaller(std::string& caller); - AppControlResult GetLaunchMode(LaunchMode& launch_mode); - AppControlResult SetLaunchMode(const LaunchMode launch_mode); + AppControlResult GetLaunchMode(std::string& launch_mode); + AppControlResult SetLaunchMode(const std::string& launch_mode); AppControlResult SendLaunchRequest(); AppControlResult SendTerminateRequest(); @@ -155,6 +158,8 @@ class AppControlChannel { std::unique_ptr> events); void UnregisterEventHandler(); void SendAlreadyQueuedEvents(); + bool ValidateAppControlResult(AppControlResult ret, + MethodResult* result); template bool GetValueFromArgs(const flutter::EncodableValue* args, @@ -165,29 +170,10 @@ class AppControlChannel { flutter::EncodableValue& out); std::shared_ptr GetAppControl(const EncodableValue* args); - bool ValidateAppControlResult( - AppControlResult app_control_result, - std::unique_ptr> result); void CreateAppControl(const EncodableValue* args, std::unique_ptr> result); - void SendLaunchRequest(const EncodableValue* args, - std::unique_ptr> result); - void SendTerminateRequest( - const EncodableValue* args, - std::unique_ptr> result); - - void GetOperation(const EncodableValue* args, - std::unique_ptr> result); - void SetOperation(const EncodableValue* args, - std::unique_ptr> result); - - void GetAppId(const EncodableValue* args, - std::unique_ptr> result); - void SetAppId(const EncodableValue* args, - std::unique_ptr> result); - std::unique_ptr> method_channel_; std::unique_ptr> event_channel_; std::unique_ptr> events_; From 3d157467d6e36693389731da154e0f8c5f5eeefd Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Fri, 2 Jul 2021 17:49:18 +0200 Subject: [PATCH 06/18] [AppControl] Refactor Event, Send and Terminate logic Signed-off-by: Rafal Walczyna --- .../tizen/channels/app_control_channel.cc | 155 ++++++++---------- .../tizen/channels/app_control_channel.h | 26 +-- 2 files changed, 80 insertions(+), 101 deletions(-) diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index 6f1386121a901..a088e41b0b600 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -46,14 +46,14 @@ AppControlChannel::~AppControlChannel() {} void AppControlChannel::NotifyAppControl(app_control_h app_control) { FT_LOGI("NotifyAppControl"); - auto app = std::make_unique(app_control); + auto app = std::make_shared(app_control); if (!events_) { - queue_.push(app->GetId()); + queue_.push(app); FT_LOGI("EventChannel not set yet"); } else { - events_->Success(EncodableValue(app->GetId())); + SendAppControlDataEvent(app); } - map_.insert({app->GetId(), std::move(app)}); + map_.insert({app->GetId(), app}); } void AppControlChannel::HandleMethodCall( @@ -76,80 +76,13 @@ void AppControlChannel::HandleMethodCall( return; } - AppControlResult ret; // Common if (method_name.compare("SendLaunchRequest") == 0) { - ret = app_control->SendLaunchRequest(); + SendLaunchRequest(app_control, std::move(result)); } else if (method_name.compare("SendTerminateRequest") == 0) { - ret = app_control->SendTerminateRequest(); - } - - if (ret.valid) { - if (ret) { - result->Success(); - } else { - result->Error(ret.message()); - } - return; - } - - // Getters - std::string str; - if (method_name.compare("GetAppId") == 0) { - ret = app_control->GetAppId(str); - } else if (method_name.compare("GetOperation") == 0) { - ret = app_control->GetOperation(str); - } else if (method_name.compare("GetUri") == 0) { - ret = app_control->GetUri(str); - } else if (method_name.compare("GetMime") == 0) { - ret = app_control->GetMime(str); - } else if (method_name.compare("GetCategory") == 0) { - ret = app_control->GetMime(str); - } else if (method_name.compare("GetCaller") == 0) { - ret = app_control->GetMime(str); - } else if (method_name.compare("GetLaunchMode") == 0) { - ret = app_control->GetLaunchMode(str); - } - - if (ret.valid) { - if (ret) { - result->Success(EncodableValue(str)); - } else { - result->Error(ret.message()); - } - return; - } - - // Setters - if (!GetValueFromArgs(arguments, "argument", str)) { - result->Error("Invalid argument"); - return; - } - - if (method_name.compare("SetAppId") == 0) { - ret = app_control->SetAppId(str); - } else if (method_name.compare("SetOperation") == 0) { - ret = app_control->SetOperation(str); - } else if (method_name.compare("SetUri") == 0) { - ret = app_control->SetUri(str); - } else if (method_name.compare("SetMime") == 0) { - ret = app_control->SetMime(str); - } else if (method_name.compare("SetCategory") == 0) { - ret = app_control->SetMime(str); - } else if (method_name.compare("SetCaller") == 0) { - ret = app_control->SetMime(str); - } else if (method_name.compare("SetLaunchMode") == 0) { - ret = app_control->SetLaunchMode(str); - } - - if (ret.valid) { - if (ret) { - result->Success(); - } else { - result->Error(ret.message()); - } + SendTerminateRequest(app_control, std::move(result)); + } else { result->NotImplemented(); - return; } } @@ -168,7 +101,7 @@ void AppControlChannel::UnregisterEventHandler() { void AppControlChannel::SendAlreadyQueuedEvents() { FT_LOGI("SendAlreadyQueuedEvents: %d", queue_.size()); while (!queue_.empty()) { - events_->Success(EncodableValue(queue_.front())); + SendAppControlDataEvent(queue_.front()); queue_.pop(); } } @@ -221,20 +154,6 @@ std::shared_ptr AppControlChannel::GetAppControl( return map_[id]; } -bool AppControlChannel::ValidateAppControlResult( - AppControlResult ret, - MethodResult* result) { - if (ret.valid) { - if (ret) { - result->Success(); - } else { - result->Error(ret.message()); - } - return true; - } - return false; -} - void AppControlChannel::CreateAppControl( const EncodableValue* args, std::unique_ptr> result) { @@ -250,6 +169,64 @@ void AppControlChannel::CreateAppControl( result->Success(EncodableValue(id)); } +void AppControlChannel::SendLaunchRequest( + std::shared_ptr app_control, + std::unique_ptr> result) { + // TODO:: Run SetAppControlData + AppControlResult ret = app_control->SendLaunchRequest(); + if (ret) { + result->Success(); + } else { + result->Error(ret.message()); + } +} + +void AppControlChannel::SendTerminateRequest( + std::shared_ptr app_control, + std::unique_ptr> result) { + // TODO:: Run SetAppControlData + AppControlResult ret = app_control->SendTerminateRequest(); + if (ret) { + result->Success(); + } else { + result->Error(ret.message()); + } +} + +void AppControlChannel::SetAppControlData( + std::shared_ptr app_control, + std::unique_ptr> result) { + // TODO: Read all +} + +void AppControlChannel::SendAppControlDataEvent( + std::shared_ptr app_control) { + std::string app_id, operation, mime, category, uri, caller_id; + AppControlResult results[7]; + results[0] = app_control->GetAppId(app_id); + results[1] = app_control->GetOperation(operation); + results[3] = app_control->GetMime(mime); + results[4] = app_control->GetCategory(category); + results[5] = app_control->GetUri(uri); + // Caller Id is optional + app_control->GetCaller(caller_id); + // TODO: Read extra data + for (int i = 0; i < 7; i++) { + if (!results[i]) { + return; + } + } + EncodableMap map; + 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); + + events_->Success(EncodableValue(map)); +} + AppControl::AppControl(app_control_h app_control) : id_(next_id_++) { FT_LOGI("AppControl construct: %d", id_); int ret = app_control_clone(&handle_, app_control); diff --git a/shell/platform/tizen/channels/app_control_channel.h b/shell/platform/tizen/channels/app_control_channel.h index 063ecb546a091..ca35f5cc9c0e1 100644 --- a/shell/platform/tizen/channels/app_control_channel.h +++ b/shell/platform/tizen/channels/app_control_channel.h @@ -21,18 +21,15 @@ class FlutterTizenEngine; namespace flutter { struct AppControlResult { - AppControlResult() : valid(false){}; - AppControlResult(int code) : error_code(code), valid(true) {} + AppControlResult() : error_code(APP_CONTROL_ERROR_NONE){}; + AppControlResult(int code) : error_code(code) {} // Returns false on error - operator bool() const { - return valid && (APP_CONTROL_ERROR_NONE == error_code); - } + operator bool() const { return (APP_CONTROL_ERROR_NONE == error_code); } std::string message() { return get_error_message(error_code); } int error_code; - bool valid; }; class AppControlExtraData { @@ -122,10 +119,7 @@ class AppControl { AppControlResult Reply(AppControl* reply, Result result); - // AppControlResult AddExtraData(std::string key, std::string value); AppControlResult AddExtraData(std::string key, EncodableValue value); - // AppControlResult AddExtraData(std::string key, - // std::vector value); AppControlResult ReadAllExtraData(std::string key, EncodableValue& value); private: @@ -158,8 +152,6 @@ class AppControlChannel { std::unique_ptr> events); void UnregisterEventHandler(); void SendAlreadyQueuedEvents(); - bool ValidateAppControlResult(AppControlResult ret, - MethodResult* result); template bool GetValueFromArgs(const flutter::EncodableValue* args, @@ -174,6 +166,16 @@ class AppControlChannel { void CreateAppControl(const EncodableValue* args, std::unique_ptr> result); + void SendLaunchRequest(std::shared_ptr app_control, + std::unique_ptr> result); + void SendTerminateRequest( + std::shared_ptr app_control, + std::unique_ptr> result); + + void SetAppControlData(std::shared_ptr app_control, + std::unique_ptr> result); + void SendAppControlDataEvent(std::shared_ptr app_control); + std::unique_ptr> method_channel_; std::unique_ptr> event_channel_; std::unique_ptr> events_; @@ -182,7 +184,7 @@ class AppControlChannel { // that EventChannel on Dart side will be registered // before native OnAppControl event // TODO: Add limit for queue elements - std::queue queue_; + std::queue> queue_; std::unordered_map> map_; }; From 80926c7a2898726024d9d1f2b91bd5138389a2c1 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Mon, 19 Jul 2021 16:02:58 +0200 Subject: [PATCH 07/18] [AppControl] Add support for extra data and dispose Signed-off-by: Rafal Walczyna --- .../tizen/channels/app_control_channel.cc | 132 ++++++++++++++---- .../tizen/channels/app_control_channel.h | 17 ++- 2 files changed, 119 insertions(+), 30 deletions(-) diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index a088e41b0b600..a1625cb3a89b5 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -46,7 +46,13 @@ AppControlChannel::~AppControlChannel() {} void AppControlChannel::NotifyAppControl(app_control_h app_control) { FT_LOGI("NotifyAppControl"); - auto app = std::make_shared(app_control); + app_control_h clone = nullptr; + AppControlResult ret = app_control_clone(&clone, app_control); + if (!ret) { + FT_LOGE("Could not clone app_control: %s", ret.message().c_str()); + return; + } + auto app = std::make_shared(clone); if (!events_) { queue_.push(app); FT_LOGI("EventChannel not set yet"); @@ -77,10 +83,12 @@ void AppControlChannel::HandleMethodCall( } // Common - if (method_name.compare("SendLaunchRequest") == 0) { - SendLaunchRequest(app_control, std::move(result)); - } else if (method_name.compare("SendTerminateRequest") == 0) { - SendTerminateRequest(app_control, std::move(result)); + if (method_name.compare("dispose") == 0) { + Dispose(app_control, std::move(result)); + } else if (method_name.compare("sendLaunchRequest") == 0) { + SendLaunchRequest(app_control, arguments, std::move(result)); + } else if (method_name.compare("sendTerminateRequest") == 0) { + SendTerminateRequest(app_control, arguments, std::move(result)); } else { result->NotImplemented(); } @@ -169,10 +177,20 @@ void AppControlChannel::CreateAppControl( result->Success(EncodableValue(id)); } +void AppControlChannel::Dispose( + std::shared_ptr app_control, + std::unique_ptr> result) { + map_.erase(app_control->GetId()); + result->Success(); +} + void AppControlChannel::SendLaunchRequest( std::shared_ptr app_control, + const flutter::EncodableValue* arguments, std::unique_ptr> result) { - // TODO:: Run SetAppControlData + if (!SetAppControlData(app_control, arguments, result.get())) { + return; + } AppControlResult ret = app_control->SendLaunchRequest(); if (ret) { result->Success(); @@ -183,35 +201,77 @@ void AppControlChannel::SendLaunchRequest( void AppControlChannel::SendTerminateRequest( std::shared_ptr app_control, + const flutter::EncodableValue* arguments, std::unique_ptr> result) { - // TODO:: Run SetAppControlData + if (!SetAppControlData(app_control, arguments, result.get())) { + return; + } AppControlResult ret = app_control->SendTerminateRequest(); if (ret) { result->Success(); } else { - result->Error(ret.message()); + result->Error("Could not terminate", ret.message()); } } -void AppControlChannel::SetAppControlData( +bool AppControlChannel::SetAppControlData( std::shared_ptr app_control, - std::unique_ptr> result) { - // TODO: Read all + const flutter::EncodableValue* arguments, + MethodResult* result) { + std::string app_id, operation, mime, category, uri; + EncodableValue extra_data; + GetValueFromArgs(arguments, "appId", app_id); + GetValueFromArgs(arguments, "operation", operation); + GetValueFromArgs(arguments, "mime", mime); + GetValueFromArgs(arguments, "category", category); + GetValueFromArgs(arguments, "uri", uri); + if (std::holds_alternative(*arguments)) { + flutter::EncodableMap map = std::get(*arguments); + EncodableValue key = EncodableValue("extraData"); + if (map.find(key) != map.end()) { + extra_data = map[key]; + } + } + AppControlResult results[5]; + results[0] = app_control->SetAppId(app_id); + if (!operation.empty()) { + results[1] = app_control->SetOperation(operation); + } + if (!mime.empty()) { + results[2] = app_control->SetMime(mime); + } + if (!category.empty()) { + results[3] = app_control->SetCategory(category); + } + if (!uri.empty()) { + results[4] = app_control->SetUri(uri); + } + app_control->SetExtraData(extra_data); + for (int i = 0; i < 5; i++) { + if (!results[i]) { + result->Error("Could not set value for app control", + results[i].message()); + return false; + } + } + return true; } void AppControlChannel::SendAppControlDataEvent( std::shared_ptr app_control) { std::string app_id, operation, mime, category, uri, caller_id; - AppControlResult results[7]; + AppControlResult results[6]; results[0] = app_control->GetAppId(app_id); results[1] = app_control->GetOperation(operation); - results[3] = app_control->GetMime(mime); - results[4] = app_control->GetCategory(category); - results[5] = app_control->GetUri(uri); + results[2] = app_control->GetMime(mime); + results[3] = app_control->GetCategory(category); + results[4] = app_control->GetUri(uri); // Caller Id is optional app_control->GetCaller(caller_id); - // TODO: Read extra data - for (int i = 0; i < 7; i++) { + EncodableValue extra_data; + // TODO: verify ret + app_control->GetExtraData(extra_data); + for (int i = 0; i < 5; i++) { if (!results[i]) { return; } @@ -223,18 +283,14 @@ void AppControlChannel::SendAppControlDataEvent( map[EncodableValue("category")] = EncodableValue(category); map[EncodableValue("uri")] = EncodableValue(uri); map[EncodableValue("callerId")] = EncodableValue(caller_id); + map[EncodableValue("extraData")] = extra_data; events_->Success(EncodableValue(map)); } AppControl::AppControl(app_control_h app_control) : id_(next_id_++) { FT_LOGI("AppControl construct: %d", id_); - int ret = app_control_clone(&handle_, app_control); - if (ret != APP_CONTROL_ERROR_NONE) { - FT_LOGE("Could not clone app control handle"); - handle_ = nullptr; - return; - } + handle_ = app_control; } AppControl::~AppControl() { @@ -308,7 +364,7 @@ bool _app_control_extra_data_cb(app_control_h app, return true; } -AppControlResult AppControl::ReadAllExtraData(EncodableValue& value) { +AppControlResult AppControl::GetExtraData(EncodableValue& value) { EncodableMap extra_data; int ret = app_control_foreach_extra_data(handle_, _app_control_extra_data_cb, &extra_data); @@ -318,6 +374,33 @@ AppControlResult AppControl::ReadAllExtraData(EncodableValue& value) { return AppControlResult(ret); } +AppControlResult AppControl::SetExtraData(EncodableValue& value) { + if (std::holds_alternative(value)) { + EncodableMap map = std::get(value); + for (const auto& v : map) { + if (!std::holds_alternative(v.first)) { + FT_LOGE("Key for extra data has to be string, omitting"); + continue; + } + std::string key = std::get(v.first); + // if (std::holds_alternative(v.second)) { + // std::string string_value = std::get(v.second); + // AddExtraData(key, string_value); + // } else if (std::holds_alternative(v.second)) { + // EncodableList list_value = std::get(v.second); + // AddExtraDataList(key, list_value); + // } else { + // FT_LOGE("Invalid type, omitting"); + // continue; + // } + AddExtraData(key, v.second); + } + } else { + return AppControlResult(APP_ERROR_INVALID_PARAMETER); + } + return AppControlResult(); +} + AppControlResult AppControl::GetOperation(std::string& operation) { return GetString(operation, app_control_get_operation); } @@ -401,6 +484,7 @@ AppControlResult AppControl::SendLaunchRequest() { } AppControlResult AppControl::SendTerminateRequest() { + FT_LOGI("AppControlChannel::SendTerminateRequest"); AppControlResult ret = app_control_send_terminate_request(handle_); return ret; } diff --git a/shell/platform/tizen/channels/app_control_channel.h b/shell/platform/tizen/channels/app_control_channel.h index ca35f5cc9c0e1..3c18b9aa53094 100644 --- a/shell/platform/tizen/channels/app_control_channel.h +++ b/shell/platform/tizen/channels/app_control_channel.h @@ -119,20 +119,20 @@ class AppControl { AppControlResult Reply(AppControl* reply, Result result); - AppControlResult AddExtraData(std::string key, EncodableValue value); - AppControlResult ReadAllExtraData(std::string key, EncodableValue& value); + AppControlResult GetExtraData(EncodableValue& value); + AppControlResult SetExtraData(EncodableValue& value); private: AppControlResult GetString(std::string& str, int func(app_control_h, char**)); AppControlResult SetString(const std::string& str, int func(app_control_h, const char*)); - AppControlResult ReadAllExtraData(EncodableValue& value); AppControlResult WriteExtraDataStringToHandle(); AppControlResult WriteExtraDataToHandle(); + AppControlResult AddExtraData(std::string key, EncodableValue value); AppControlResult AddExtraDataList(std::string& key, EncodableList& list); - EncodableMap extra_data_; + // EncodableMap extra_data_; app_control_h handle_; int id_; static int next_id_; @@ -166,14 +166,19 @@ class AppControlChannel { void CreateAppControl(const EncodableValue* args, std::unique_ptr> result); + void Dispose(std::shared_ptr app_control, + std::unique_ptr> result); void SendLaunchRequest(std::shared_ptr app_control, + const flutter::EncodableValue* arguments, std::unique_ptr> result); void SendTerminateRequest( std::shared_ptr app_control, + const flutter::EncodableValue* arguments, std::unique_ptr> result); - void SetAppControlData(std::shared_ptr app_control, - std::unique_ptr> result); + bool SetAppControlData(std::shared_ptr app_control, + const flutter::EncodableValue* arguments, + MethodResult* result); void SendAppControlDataEvent(std::shared_ptr app_control); std::unique_ptr> method_channel_; From 0c1d5499744e28460fada6c949240a1ff8dceee5 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Tue, 20 Jul 2021 16:37:17 +0200 Subject: [PATCH 08/18] [AppControl] Add support for reply Signed-off-by: Rafal Walczyna --- .../tizen/channels/app_control_channel.cc | 210 ++++++++++++++---- .../tizen/channels/app_control_channel.h | 76 ++----- 2 files changed, 189 insertions(+), 97 deletions(-) diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index a1625cb3a89b5..f48396db5617c 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -9,6 +9,7 @@ namespace flutter { static constexpr char kChannelName[] = "tizen/internal/app_control_method"; static constexpr char kEventChannelName[] = "tizen/internal/app_control_event"; +static constexpr char kReplyChannelName[] = "tizen/internal/app_control_reply"; int AppControl::next_id_ = 0; AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { @@ -40,6 +41,27 @@ 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 flutter::EncodableValue* arguments, + std::unique_ptr>&& events) + -> std::unique_ptr> { + FT_LOGI("OnListen"); + RegisterReplyHandler(std::move(events)); + return nullptr; + }, + [this](const flutter::EncodableValue* arguments) + -> std::unique_ptr> { + FT_LOGI("OnCancel"); + UnregisterReplyHandler(); + return nullptr; + }); + + reply_channel_->SetStreamHandler(std::move(reply_channel_handler)); } AppControlChannel::~AppControlChannel() {} @@ -53,7 +75,7 @@ void AppControlChannel::NotifyAppControl(app_control_h app_control) { return; } auto app = std::make_shared(clone); - if (!events_) { + if (!event_sink_) { queue_.push(app); FT_LOGI("EventChannel not set yet"); } else { @@ -85,8 +107,12 @@ void AppControlChannel::HandleMethodCall( // Common if (method_name.compare("dispose") == 0) { Dispose(app_control, std::move(result)); + } else if (method_name.compare("reply") == 0) { + Reply(app_control, arguments, std::move(result)); } else if (method_name.compare("sendLaunchRequest") == 0) { SendLaunchRequest(app_control, arguments, std::move(result)); + } else if (method_name.compare("setAppControlData") == 0) { + SetAppControlData(app_control, arguments, std::move(result)); } else if (method_name.compare("sendTerminateRequest") == 0) { SendTerminateRequest(app_control, arguments, std::move(result)); } else { @@ -97,13 +123,13 @@ void AppControlChannel::HandleMethodCall( void AppControlChannel::RegisterEventHandler( std::unique_ptr> events) { FT_LOGI("RegisterEventHandler"); - events_ = std::move(events); + event_sink_ = std::move(events); SendAlreadyQueuedEvents(); } void AppControlChannel::UnregisterEventHandler() { FT_LOGI("UnregisterEventHandler"); - events_.reset(); + event_sink_.reset(); } void AppControlChannel::SendAlreadyQueuedEvents() { @@ -114,6 +140,17 @@ void AppControlChannel::SendAlreadyQueuedEvents() { } } +void AppControlChannel::RegisterReplyHandler( + std::unique_ptr> events) { + FT_LOGI("RegisterEventHandler"); + reply_sink_ = std::move(events); +} + +void AppControlChannel::UnregisterReplyHandler() { + FT_LOGI("UnregisterReplyHandler"); + reply_sink_.reset(); +} + template bool AppControlChannel::GetValueFromArgs(const flutter::EncodableValue* args, const char* key, @@ -184,14 +221,26 @@ void AppControlChannel::Dispose( result->Success(); } -void AppControlChannel::SendLaunchRequest( +void AppControlChannel::Reply( std::shared_ptr app_control, const flutter::EncodableValue* arguments, std::unique_ptr> result) { - if (!SetAppControlData(app_control, arguments, result.get())) { + FT_LOGI("AppControlChannel::Reply"); + + int request_id; + if (!GetValueFromArgs(arguments, "requestId", request_id) || + map_.find(request_id) == map_.end()) { + result->Error("Could not reply", "Invalid request app control"); return; } - AppControlResult ret = app_control->SendLaunchRequest(); + + auto request_app_control = map_[request_id]; + std::string result_str; + if (!GetValueFromArgs(arguments, "result", result_str)) { + result->Error("Could not reply", "Invalid result parameter"); + return; + } + AppControlResult ret = app_control->Reply(request_app_control, result_str); if (ret) { result->Success(); } else { @@ -199,13 +248,33 @@ void AppControlChannel::SendLaunchRequest( } } -void AppControlChannel::SendTerminateRequest( +void AppControlChannel::SendLaunchRequest( std::shared_ptr app_control, const flutter::EncodableValue* arguments, std::unique_ptr> result) { - if (!SetAppControlData(app_control, arguments, result.get())) { - return; + FT_LOGI("AppControlChannel::SendLaunchRequest"); + + bool wait_for_reply = false; + GetValueFromArgs(arguments, "waitForReply", wait_for_reply); + AppControlResult ret; + if (wait_for_reply) { + ret = app_control->SendLaunchRequestWithReply(std::move(reply_sink_)); + } + + ret = app_control->SendLaunchRequest(); + if (ret) { + result->Success(); + } else { + result->Error(ret.message()); } +} + +void AppControlChannel::SendTerminateRequest( + std::shared_ptr app_control, + const flutter::EncodableValue* arguments, + std::unique_ptr> result) { + FT_LOGI("AppControlChannel::SendTerminateRequest"); + AppControlResult ret = app_control->SendTerminateRequest(); if (ret) { result->Success(); @@ -214,10 +283,11 @@ void AppControlChannel::SendTerminateRequest( } } -bool AppControlChannel::SetAppControlData( +void AppControlChannel::SetAppControlData( std::shared_ptr app_control, const flutter::EncodableValue* arguments, - MethodResult* result) { + std::unique_ptr> result) { + FT_LOGI("AppControlChannel::SetAppControlData"); std::string app_id, operation, mime, category, uri; EncodableValue extra_data; GetValueFromArgs(arguments, "appId", app_id); @@ -251,41 +321,18 @@ bool AppControlChannel::SetAppControlData( if (!results[i]) { result->Error("Could not set value for app control", results[i].message()); - return false; } } - return true; + result->Success(); } void AppControlChannel::SendAppControlDataEvent( std::shared_ptr app_control) { - std::string app_id, operation, mime, category, uri, caller_id; - AppControlResult results[6]; - results[0] = app_control->GetAppId(app_id); - results[1] = app_control->GetOperation(operation); - results[2] = app_control->GetMime(mime); - results[3] = app_control->GetCategory(category); - results[4] = app_control->GetUri(uri); - // Caller Id is optional - app_control->GetCaller(caller_id); - EncodableValue extra_data; - // TODO: verify ret - app_control->GetExtraData(extra_data); - for (int i = 0; i < 5; i++) { - if (!results[i]) { - return; - } + FT_LOGI("AppControlChannel::SendAppControlDataEvent"); + EncodableValue map = app_control->SerializeAppControlToMap(); + if (!map.IsNull()) { + event_sink_->Success(map); } - EncodableMap map; - 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("extraData")] = extra_data; - - events_->Success(EncodableValue(map)); } AppControl::AppControl(app_control_h app_control) : id_(next_id_++) { @@ -477,20 +524,101 @@ AppControlResult AppControl::SetLaunchMode(const std::string& launch_mode) { return AppControlResult(ret); } +EncodableValue AppControl::SerializeAppControlToMap() { + FT_LOGI("AppControl::SerializeAppControlToMap"); + std::string app_id, operation, mime, category, uri, caller_id; + AppControlResult results[6]; + results[0] = GetAppId(app_id); + results[1] = GetOperation(operation); + results[2] = GetMime(mime); + results[3] = GetCategory(category); + results[4] = GetUri(uri); + // Caller Id is optional + GetCaller(caller_id); + EncodableValue extra_data; + // TODO: verify ret + GetExtraData(extra_data); + for (int i = 0; i < 5; i++) { + if (!results[i]) { + return EncodableValue(); + } + } + EncodableMap map; + map[EncodableValue("id")] = EncodableValue(GetId()); + 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("extraData")] = extra_data; + + return EncodableValue(map); +} + AppControlResult AppControl::SendLaunchRequest() { AppControlResult ret = app_control_send_launch_request(handle_, nullptr, nullptr); return ret; } +AppControlResult AppControl::SendLaunchRequestWithReply( + std::shared_ptr> reply_sink) { + auto on_reply = [](app_control_h request, app_control_h reply, + app_control_result_e result, void* user_data) { + AppControl* app_control = static_cast(user_data); + FT_LOGI("OnAppControlReplyReceived"); + app_control_h clone = nullptr; + AppControlResult ret = app_control_clone(&clone, reply); + if (!ret) { + FT_LOGE("Could not clone app_control: %s", ret.message().c_str()); + return; + } + + AppControl app_control_reply = AppControl(clone); + EncodableMap map; + map[EncodableValue("id")] = EncodableValue(app_control->GetId()); + // TODO: put appcontrol into map_ of AppControlChannel or disable using + // reply app control on dart side + map[EncodableValue("reply")] = app_control_reply.SerializeAppControlToMap(); + if (result == APP_CONTROL_RESULT_APP_STARTED) { + map[EncodableValue("result")] = EncodableValue("AppStarted"); + } else if (result == APP_CONTROL_RESULT_SUCCEEDED) { + map[EncodableValue("result")] = EncodableValue("Succeeded"); + } else if (result == APP_CONTROL_RESULT_FAILED) { + map[EncodableValue("result")] = EncodableValue("Failed"); + } else if (result == APP_CONTROL_RESULT_CANCELED) { + map[EncodableValue("result")] = EncodableValue("Cancelled"); + } + + app_control->reply_sink_->Success(EncodableValue(map)); + }; + reply_sink_ = std::move(reply_sink); + AppControlResult ret = + app_control_send_launch_request(handle_, on_reply, this); + return ret; +} + AppControlResult AppControl::SendTerminateRequest() { FT_LOGI("AppControlChannel::SendTerminateRequest"); AppControlResult ret = app_control_send_terminate_request(handle_); return ret; } -AppControlResult AppControl::Reply(AppControl* reply, Result result) { - app_control_result_e result_e = static_cast(result); +AppControlResult AppControl::Reply(std::shared_ptr reply, + const std::string& result) { + app_control_result_e result_e; + if (result == "AppStarted") { + result_e = APP_CONTROL_RESULT_APP_STARTED; + } else if (result == "Succeeded") { + result_e = APP_CONTROL_RESULT_SUCCEEDED; + } else if (result == "Failed") { + result_e = APP_CONTROL_RESULT_FAILED; + } else if (result == "Cancelled") { + result_e = APP_CONTROL_RESULT_CANCELED; + } else { + return AppControlResult(APP_CONTROL_ERROR_INVALID_PARAMETER); + } int ret = app_control_reply_to_launch_request(reply->Handle(), this->handle_, result_e); return AppControlResult(ret); diff --git a/shell/platform/tizen/channels/app_control_channel.h b/shell/platform/tizen/channels/app_control_channel.h index 3c18b9aa53094..21280ce32e1c0 100644 --- a/shell/platform/tizen/channels/app_control_channel.h +++ b/shell/platform/tizen/channels/app_control_channel.h @@ -32,60 +32,9 @@ struct AppControlResult { int error_code; }; -class AppControlExtraData { - public: - AppControlExtraData() {} - ~AppControlExtraData() {} - - void Add(std::string key, std::string value) { - if (strings_lists_.find(key) != strings_lists_.end()) { - strings_lists_.erase(key); - } - strings_[key] = value; - } - - void Add(std::string key, std::vector value) { - if (strings_.find(key) != strings_.end()) { - strings_.erase(key); - } - strings_lists_[key] = value; - } - - void Remove(std::string key) { - strings_.erase(key); - strings_lists_.erase(key); - } - - bool Has(std::string key) { - if (strings_.find(key) != strings_.end()) { - return true; - } - if (strings_lists_.find(key) != strings_lists_.end()) { - return true; - } - return false; - } - - std::vector& GetVec(std::string key) { - return strings_lists_[key]; - } - - std::string& GetString(std::string key) { return strings_[key]; } - - size_t Size() { return strings_.size() + strings_lists_.size(); } - - private: - std::unordered_map strings_; - std::unordered_map> strings_lists_; -}; - class AppControl { public: - enum LaunchMode { - Single = APP_CONTROL_LAUNCH_MODE_SINGLE, - Group = APP_CONTROL_LAUNCH_MODE_GROUP - }; - enum Result { + enum AppControlReplyResult { Started = APP_CONTROL_RESULT_APP_STARTED, Succeeded = APP_CONTROL_RESULT_SUCCEEDED, Failed = APP_CONTROL_RESULT_FAILED, @@ -114,10 +63,15 @@ class AppControl { AppControlResult GetLaunchMode(std::string& launch_mode); AppControlResult SetLaunchMode(const std::string& launch_mode); + EncodableValue SerializeAppControlToMap(); + AppControlResult SendLaunchRequest(); + AppControlResult SendLaunchRequestWithReply( + std::shared_ptr> reply_sink); AppControlResult SendTerminateRequest(); - AppControlResult Reply(AppControl* reply, Result result); + AppControlResult Reply(std::shared_ptr reply, + const std::string& result); AppControlResult GetExtraData(EncodableValue& value); AppControlResult SetExtraData(EncodableValue& value); @@ -136,6 +90,7 @@ class AppControl { app_control_h handle_; int id_; static int next_id_; + std::shared_ptr> reply_sink_; }; class AppControlChannel { @@ -153,6 +108,10 @@ class AppControlChannel { void UnregisterEventHandler(); void SendAlreadyQueuedEvents(); + void RegisterReplyHandler( + std::unique_ptr> events); + void UnregisterReplyHandler(); + template bool GetValueFromArgs(const flutter::EncodableValue* args, const char* key, @@ -168,6 +127,9 @@ class AppControlChannel { void Dispose(std::shared_ptr app_control, std::unique_ptr> result); + void Reply(std::shared_ptr app_control, + const flutter::EncodableValue* arguments, + std::unique_ptr> result); void SendLaunchRequest(std::shared_ptr app_control, const flutter::EncodableValue* arguments, std::unique_ptr> result); @@ -176,14 +138,16 @@ class AppControlChannel { const flutter::EncodableValue* arguments, std::unique_ptr> result); - bool SetAppControlData(std::shared_ptr app_control, + void SetAppControlData(std::shared_ptr app_control, const flutter::EncodableValue* arguments, - MethodResult* result); + std::unique_ptr> result); void SendAppControlDataEvent(std::shared_ptr app_control); std::unique_ptr> method_channel_; std::unique_ptr> event_channel_; - std::unique_ptr> events_; + 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 From f656400c28e11b73c6cf4bd5ffda8df4b757fbd7 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Wed, 21 Jul 2021 17:09:50 +0200 Subject: [PATCH 09/18] [AppControl] Add support for launch mode and organize logs Signed-off-by: Rafal Walczyna --- .../tizen/channels/app_control_channel.cc | 70 ++++++------------- 1 file changed, 21 insertions(+), 49 deletions(-) diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index f48396db5617c..a9999f4f2126e 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -10,10 +10,10 @@ namespace flutter { static constexpr char kChannelName[] = "tizen/internal/app_control_method"; static constexpr char kEventChannelName[] = "tizen/internal/app_control_event"; static constexpr char kReplyChannelName[] = "tizen/internal/app_control_reply"; + int AppControl::next_id_ = 0; AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { - FT_LOGI("AppControlChannel"); method_channel_ = std::make_unique>( messenger, kChannelName, &StandardMethodCodec::GetInstance()); @@ -29,13 +29,11 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { [this](const flutter::EncodableValue* arguments, std::unique_ptr>&& events) -> std::unique_ptr> { - FT_LOGI("OnListen"); RegisterEventHandler(std::move(events)); return nullptr; }, [this](const flutter::EncodableValue* arguments) -> std::unique_ptr> { - FT_LOGI("OnCancel"); UnregisterEventHandler(); return nullptr; }); @@ -50,13 +48,11 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { [this](const flutter::EncodableValue* arguments, std::unique_ptr>&& events) -> std::unique_ptr> { - FT_LOGI("OnListen"); RegisterReplyHandler(std::move(events)); return nullptr; }, [this](const flutter::EncodableValue* arguments) -> std::unique_ptr> { - FT_LOGI("OnCancel"); UnregisterReplyHandler(); return nullptr; }); @@ -67,11 +63,10 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { AppControlChannel::~AppControlChannel() {} void AppControlChannel::NotifyAppControl(app_control_h app_control) { - FT_LOGI("NotifyAppControl"); app_control_h clone = nullptr; AppControlResult ret = app_control_clone(&clone, app_control); if (!ret) { - FT_LOGE("Could not clone app_control: %s", ret.message().c_str()); + FT_LOGE("Could not clone app control: %s", ret.message().c_str()); return; } auto app = std::make_shared(clone); @@ -122,18 +117,15 @@ void AppControlChannel::HandleMethodCall( void AppControlChannel::RegisterEventHandler( std::unique_ptr> events) { - FT_LOGI("RegisterEventHandler"); event_sink_ = std::move(events); SendAlreadyQueuedEvents(); } void AppControlChannel::UnregisterEventHandler() { - FT_LOGI("UnregisterEventHandler"); event_sink_.reset(); } void AppControlChannel::SendAlreadyQueuedEvents() { - FT_LOGI("SendAlreadyQueuedEvents: %d", queue_.size()); while (!queue_.empty()) { SendAppControlDataEvent(queue_.front()); queue_.pop(); @@ -142,12 +134,10 @@ void AppControlChannel::SendAlreadyQueuedEvents() { void AppControlChannel::RegisterReplyHandler( std::unique_ptr> events) { - FT_LOGI("RegisterEventHandler"); reply_sink_ = std::move(events); } void AppControlChannel::UnregisterReplyHandler() { - FT_LOGI("UnregisterReplyHandler"); reply_sink_.reset(); } @@ -195,14 +185,12 @@ std::shared_ptr AppControlChannel::GetAppControl( FT_LOGE("Could not find AppControl with id %d", id); return nullptr; } - FT_LOGI("Found AppControl: %d", id); return map_[id]; } void AppControlChannel::CreateAppControl( const EncodableValue* args, std::unique_ptr> result) { - FT_LOGI("AppControlChannel::CreateAppControl"); app_control_h app_control = nullptr; AppControlResult ret = app_control_create(&app_control); if (!ret) { @@ -225,8 +213,6 @@ void AppControlChannel::Reply( std::shared_ptr app_control, const flutter::EncodableValue* arguments, std::unique_ptr> result) { - FT_LOGI("AppControlChannel::Reply"); - int request_id; if (!GetValueFromArgs(arguments, "requestId", request_id) || map_.find(request_id) == map_.end()) { @@ -252,8 +238,6 @@ void AppControlChannel::SendLaunchRequest( std::shared_ptr app_control, const flutter::EncodableValue* arguments, std::unique_ptr> result) { - FT_LOGI("AppControlChannel::SendLaunchRequest"); - bool wait_for_reply = false; GetValueFromArgs(arguments, "waitForReply", wait_for_reply); AppControlResult ret; @@ -273,8 +257,6 @@ void AppControlChannel::SendTerminateRequest( std::shared_ptr app_control, const flutter::EncodableValue* arguments, std::unique_ptr> result) { - FT_LOGI("AppControlChannel::SendTerminateRequest"); - AppControlResult ret = app_control->SendTerminateRequest(); if (ret) { result->Success(); @@ -287,13 +269,13 @@ void AppControlChannel::SetAppControlData( std::shared_ptr app_control, const flutter::EncodableValue* arguments, std::unique_ptr> result) { - FT_LOGI("AppControlChannel::SetAppControlData"); - std::string app_id, operation, mime, category, uri; + std::string app_id, operation, mime, category, uri, launch_mode; EncodableValue extra_data; GetValueFromArgs(arguments, "appId", app_id); GetValueFromArgs(arguments, "operation", operation); GetValueFromArgs(arguments, "mime", mime); GetValueFromArgs(arguments, "category", category); + GetValueFromArgs(arguments, "launchMode", launch_mode); GetValueFromArgs(arguments, "uri", uri); if (std::holds_alternative(*arguments)) { flutter::EncodableMap map = std::get(*arguments); @@ -302,7 +284,7 @@ void AppControlChannel::SetAppControlData( extra_data = map[key]; } } - AppControlResult results[5]; + AppControlResult results[7]; results[0] = app_control->SetAppId(app_id); if (!operation.empty()) { results[1] = app_control->SetOperation(operation); @@ -316,8 +298,11 @@ void AppControlChannel::SetAppControlData( if (!uri.empty()) { results[4] = app_control->SetUri(uri); } - app_control->SetExtraData(extra_data); - for (int i = 0; i < 5; i++) { + if (!launch_mode.empty()) { + results[5] = app_control->SetLaunchMode(launch_mode); + } + results[6] = app_control->SetExtraData(extra_data); + for (int i = 0; i < 7; i++) { if (!results[i]) { result->Error("Could not set value for app control", results[i].message()); @@ -328,7 +313,6 @@ void AppControlChannel::SetAppControlData( void AppControlChannel::SendAppControlDataEvent( std::shared_ptr app_control) { - FT_LOGI("AppControlChannel::SendAppControlDataEvent"); EncodableValue map = app_control->SerializeAppControlToMap(); if (!map.IsNull()) { event_sink_->Success(map); @@ -336,18 +320,15 @@ void AppControlChannel::SendAppControlDataEvent( } AppControl::AppControl(app_control_h app_control) : id_(next_id_++) { - FT_LOGI("AppControl construct: %d", id_); handle_ = app_control; } AppControl::~AppControl() { - FT_LOGI("AppControl destruct: %d", id_); app_control_destroy(handle_); } AppControlResult AppControl::GetString(std::string& str, int func(app_control_h, char**)) { - FT_LOGI("AppControl::GetString"); char* op; AppControlResult ret = func(handle_, &op); if (!ret) { @@ -364,7 +345,6 @@ AppControlResult AppControl::GetString(std::string& str, AppControlResult AppControl::SetString(const std::string& str, int func(app_control_h, const char*)) { - FT_LOGI("AppControl::SetString: %s", str.c_str()); int ret = func(handle_, str.c_str()); return AppControlResult(ret); } @@ -430,17 +410,11 @@ AppControlResult AppControl::SetExtraData(EncodableValue& value) { continue; } std::string key = std::get(v.first); - // if (std::holds_alternative(v.second)) { - // std::string string_value = std::get(v.second); - // AddExtraData(key, string_value); - // } else if (std::holds_alternative(v.second)) { - // EncodableList list_value = std::get(v.second); - // AddExtraDataList(key, list_value); - // } else { - // FT_LOGE("Invalid type, omitting"); - // continue; - // } - AddExtraData(key, v.second); + AppControlResult ret = AddExtraData(key, v.second); + if (!ret) { + FT_LOGE("Invalid data at %s, omitting", key.c_str()); + continue; + } } } else { return AppControlResult(APP_ERROR_INVALID_PARAMETER); @@ -525,20 +499,19 @@ AppControlResult AppControl::SetLaunchMode(const std::string& launch_mode) { } EncodableValue AppControl::SerializeAppControlToMap() { - FT_LOGI("AppControl::SerializeAppControlToMap"); - std::string app_id, operation, mime, category, uri, caller_id; - AppControlResult results[6]; + std::string app_id, operation, mime, category, uri, caller_id, launch_mode; + AppControlResult results[7]; results[0] = GetAppId(app_id); results[1] = GetOperation(operation); results[2] = GetMime(mime); results[3] = GetCategory(category); results[4] = GetUri(uri); + results[5] = GetLaunchMode(launch_mode); // Caller Id is optional GetCaller(caller_id); EncodableValue extra_data; - // TODO: verify ret - GetExtraData(extra_data); - for (int i = 0; i < 5; i++) { + results[6] = GetExtraData(extra_data); + for (int i = 0; i < 7; i++) { if (!results[i]) { return EncodableValue(); } @@ -551,6 +524,7 @@ EncodableValue AppControl::SerializeAppControlToMap() { map[EncodableValue("category")] = EncodableValue(category); map[EncodableValue("uri")] = EncodableValue(uri); map[EncodableValue("callerId")] = EncodableValue(caller_id); + map[EncodableValue("launchMode")] = EncodableValue(launch_mode); map[EncodableValue("extraData")] = extra_data; return EncodableValue(map); @@ -567,7 +541,6 @@ AppControlResult AppControl::SendLaunchRequestWithReply( auto on_reply = [](app_control_h request, app_control_h reply, app_control_result_e result, void* user_data) { AppControl* app_control = static_cast(user_data); - FT_LOGI("OnAppControlReplyReceived"); app_control_h clone = nullptr; AppControlResult ret = app_control_clone(&clone, reply); if (!ret) { @@ -600,7 +573,6 @@ AppControlResult AppControl::SendLaunchRequestWithReply( } AppControlResult AppControl::SendTerminateRequest() { - FT_LOGI("AppControlChannel::SendTerminateRequest"); AppControlResult ret = app_control_send_terminate_request(handle_); return ret; } From d1331c0a4523b42af6fea7f40f8f98253e05a937 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Thu, 22 Jul 2021 17:06:59 +0200 Subject: [PATCH 10/18] [AppControl] Fix bugs with not saving app control on reply and with double launch Signed-off-by: Rafal Walczyna --- .../tizen/channels/app_control_channel.cc | 36 +++++++++++++------ .../tizen/channels/app_control_channel.h | 21 ++++++----- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index a9999f4f2126e..2f98933f27e46 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -63,6 +63,7 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { AppControlChannel::~AppControlChannel() {} void AppControlChannel::NotifyAppControl(app_control_h app_control) { + FT_LOGE("AppControlChannel::NotifyAppControl"); app_control_h clone = nullptr; AppControlResult ret = app_control_clone(&clone, app_control); if (!ret) { @@ -230,7 +231,7 @@ void AppControlChannel::Reply( if (ret) { result->Success(); } else { - result->Error(ret.message()); + result->Error("Could not reply to app control", ret.message()); } } @@ -242,10 +243,11 @@ void AppControlChannel::SendLaunchRequest( GetValueFromArgs(arguments, "waitForReply", wait_for_reply); AppControlResult ret; if (wait_for_reply) { - ret = app_control->SendLaunchRequestWithReply(std::move(reply_sink_)); + ret = app_control->SendLaunchRequestWithReply(std::move(reply_sink_), this); + } else { + ret = app_control->SendLaunchRequest(); } - ret = app_control->SendLaunchRequest(); if (ret) { result->Success(); } else { @@ -422,6 +424,14 @@ AppControlResult AppControl::SetExtraData(EncodableValue& value) { return AppControlResult(); } +void AppControl::SetManager(AppControlChannel* m) { + manager_ = m; +} + +AppControlChannel* AppControl::GetManager() { + return manager_; +} + AppControlResult AppControl::GetOperation(std::string& operation) { return GetString(operation, app_control_get_operation); } @@ -537,7 +547,9 @@ AppControlResult AppControl::SendLaunchRequest() { } AppControlResult AppControl::SendLaunchRequestWithReply( - std::shared_ptr> reply_sink) { + 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) { AppControl* app_control = static_cast(user_data); @@ -548,12 +560,12 @@ AppControlResult AppControl::SendLaunchRequestWithReply( return; } - AppControl app_control_reply = AppControl(clone); + std::shared_ptr app_control_reply = + std::make_shared(clone); EncodableMap map; map[EncodableValue("id")] = EncodableValue(app_control->GetId()); - // TODO: put appcontrol into map_ of AppControlChannel or disable using - // reply app control on dart side - map[EncodableValue("reply")] = app_control_reply.SerializeAppControlToMap(); + map[EncodableValue("reply")] = + app_control_reply->SerializeAppControlToMap(); if (result == APP_CONTROL_RESULT_APP_STARTED) { map[EncodableValue("result")] = EncodableValue("AppStarted"); } else if (result == APP_CONTROL_RESULT_SUCCEEDED) { @@ -565,6 +577,8 @@ AppControlResult AppControl::SendLaunchRequestWithReply( } app_control->reply_sink_->Success(EncodableValue(map)); + app_control->GetManager()->AddExistingAppControl( + std::move(app_control_reply)); }; reply_sink_ = std::move(reply_sink); AppControlResult ret = @@ -591,9 +605,9 @@ AppControlResult AppControl::Reply(std::shared_ptr reply, } else { return AppControlResult(APP_CONTROL_ERROR_INVALID_PARAMETER); } - int ret = app_control_reply_to_launch_request(reply->Handle(), this->handle_, - result_e); - return AppControlResult(ret); + AppControlResult ret = app_control_reply_to_launch_request( + reply->Handle(), this->handle_, result_e); + return ret; } AppControlResult AppControl::AddExtraData(std::string key, diff --git a/shell/platform/tizen/channels/app_control_channel.h b/shell/platform/tizen/channels/app_control_channel.h index 21280ce32e1c0..59041bc404dee 100644 --- a/shell/platform/tizen/channels/app_control_channel.h +++ b/shell/platform/tizen/channels/app_control_channel.h @@ -32,15 +32,10 @@ struct AppControlResult { int error_code; }; +class AppControlChannel; + class AppControl { public: - enum AppControlReplyResult { - Started = APP_CONTROL_RESULT_APP_STARTED, - Succeeded = APP_CONTROL_RESULT_SUCCEEDED, - Failed = APP_CONTROL_RESULT_FAILED, - Cancelled = APP_CONTROL_RESULT_CANCELED - }; - AppControl(app_control_h app_control); ~AppControl(); @@ -67,7 +62,8 @@ class AppControl { AppControlResult SendLaunchRequest(); AppControlResult SendLaunchRequestWithReply( - std::shared_ptr> reply_sink); + std::shared_ptr> reply_sink, + AppControlChannel* manager); AppControlResult SendTerminateRequest(); AppControlResult Reply(std::shared_ptr reply, @@ -76,6 +72,9 @@ class AppControl { AppControlResult GetExtraData(EncodableValue& value); AppControlResult SetExtraData(EncodableValue& value); + void SetManager(AppControlChannel* m); + AppControlChannel* GetManager(); + private: AppControlResult GetString(std::string& str, int func(app_control_h, char**)); AppControlResult SetString(const std::string& str, @@ -91,6 +90,8 @@ class AppControl { int id_; static int next_id_; std::shared_ptr> reply_sink_; + + AppControlChannel* manager_; }; class AppControlChannel { @@ -100,6 +101,10 @@ class AppControlChannel { void NotifyAppControl(app_control_h 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); From 596fb8f501f41eb4580e7462fede771b10f1fed0 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Fri, 23 Jul 2021 14:33:24 +0200 Subject: [PATCH 11/18] [AppControl] Update logs and comments Signed-off-by: Rafal Walczyna --- .../tizen/channels/app_control_channel.cc | 27 +++++++++---------- .../tizen/channels/app_control_channel.h | 4 +-- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index 2f98933f27e46..763d038e96edb 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -63,17 +63,16 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { AppControlChannel::~AppControlChannel() {} void AppControlChannel::NotifyAppControl(app_control_h app_control) { - FT_LOGE("AppControlChannel::NotifyAppControl"); app_control_h clone = nullptr; AppControlResult ret = app_control_clone(&clone, app_control); if (!ret) { - FT_LOGE("Could not clone app control: %s", ret.message().c_str()); + FT_LOG(Error) << "Could not clone app control " << ret.message(); return; } auto app = std::make_shared(clone); if (!event_sink_) { queue_.push(app); - FT_LOGI("EventChannel not set yet"); + FT_LOG(Info) << "EventChannel not set yet "; } else { SendAppControlDataEvent(app); } @@ -83,7 +82,7 @@ void AppControlChannel::NotifyAppControl(app_control_h app_control) { void AppControlChannel::HandleMethodCall( const MethodCall& method_call, std::unique_ptr> result) { - FT_LOGI("HandleMethodCall : %s", method_call.method_name().c_str()); + FT_LOG(Info) << "HandleMethodCall " << method_call.method_name(); const auto arguments = method_call.arguments(); const auto& method_name = method_call.method_name(); @@ -155,7 +154,7 @@ bool AppControlChannel::GetValueFromArgs(const flutter::EncodableValue* args, return true; } } - FT_LOGI("Key %s not found", key); + FT_LOG(Info) << "Key " << key << "not found"; } return false; } @@ -178,12 +177,12 @@ std::shared_ptr AppControlChannel::GetAppControl( const EncodableValue* args) { int id; if (!GetValueFromArgs(args, "id", id)) { - FT_LOGE("Could not find AppControl with id %d", id); + FT_LOG(Error) << "Could not find AppControl with id " << id; return nullptr; } if (map_.find(id) == map_.end()) { - FT_LOGE("Could not find AppControl with id %d", id); + FT_LOG(Error) << "Could not find AppControl with id " << id; return nullptr; } return map_[id]; @@ -358,7 +357,7 @@ bool _app_control_extra_data_cb(app_control_h app, bool is_array = false; int ret = app_control_is_extra_data_array(app, key, &is_array); if (ret != APP_CONTROL_ERROR_NONE) { - FT_LOGE("app_control_is_extra_data_array() failed at key %s", key); + FT_LOG(Error) << "app_control_is_extra_data_array() failed at key " << key; return false; } @@ -367,7 +366,7 @@ bool _app_control_extra_data_cb(app_control_h app, int length = 0; ret = app_control_get_extra_data_array(app, key, &strings, &length); if (ret != APP_CONTROL_ERROR_NONE) { - FT_LOGE("app_control_get_extra_data() failed at key %s", key); + FT_LOG(Error) << "app_control_get_extra_data() failed at key " << key; return false; } EncodableList list; @@ -382,7 +381,7 @@ bool _app_control_extra_data_cb(app_control_h app, char* value; ret = app_control_get_extra_data(app, key, &value); if (ret != APP_CONTROL_ERROR_NONE) { - FT_LOGE("app_control_get_extra_data() failed at key %s", key); + FT_LOG(Error) << "app_control_get_extra_data() failed at key " << key; return false; } extra_data->insert( @@ -408,14 +407,14 @@ AppControlResult AppControl::SetExtraData(EncodableValue& value) { EncodableMap map = std::get(value); for (const auto& v : map) { if (!std::holds_alternative(v.first)) { - FT_LOGE("Key for extra data has to be string, omitting"); + FT_LOG(Error) << "Key for extra data has to be string, omitting"; continue; } std::string key = std::get(v.first); AppControlResult ret = AddExtraData(key, v.second); if (!ret) { - FT_LOGE("Invalid data at %s, omitting", key.c_str()); - continue; + FT_LOG(Error) << "Invalid data at " << key << ", omitting"; + continue; } } } else { @@ -556,7 +555,7 @@ AppControlResult AppControl::SendLaunchRequestWithReply( app_control_h clone = nullptr; AppControlResult ret = app_control_clone(&clone, reply); if (!ret) { - FT_LOGE("Could not clone app_control: %s", ret.message().c_str()); + FT_LOG(Error) << "Could not clone app_control: " << ret.message(); return; } diff --git a/shell/platform/tizen/channels/app_control_channel.h b/shell/platform/tizen/channels/app_control_channel.h index 59041bc404dee..465fd29eaf3dc 100644 --- a/shell/platform/tizen/channels/app_control_channel.h +++ b/shell/platform/tizen/channels/app_control_channel.h @@ -14,7 +14,7 @@ #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/common/client_wrapper/include/flutter/standard_method_codec.h" -#include "flutter/shell/platform/tizen/tizen_log.h" +#include "flutter/shell/platform/tizen/logger.h" class FlutterTizenEngine; @@ -85,7 +85,6 @@ class AppControl { AppControlResult AddExtraData(std::string key, EncodableValue value); AppControlResult AddExtraDataList(std::string& key, EncodableList& list); - // EncodableMap extra_data_; app_control_h handle_; int id_; static int next_id_; @@ -157,7 +156,6 @@ class AppControlChannel { // We need this queue, because there is no quarantee // that EventChannel on Dart side will be registered // before native OnAppControl event - // TODO: Add limit for queue elements std::queue> queue_; std::unordered_map> map_; From ed790323e05d9bf1e7db82ed4d7f657d76115952 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Fri, 23 Jul 2021 16:37:32 +0200 Subject: [PATCH 12/18] Run code formatter Signed-off-by: Rafal Walczyna --- shell/platform/tizen/channels/app_control_channel.cc | 4 ++-- shell/platform/tizen/public/flutter_tizen.h | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index 763d038e96edb..60b211d7ab1d4 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -413,8 +413,8 @@ AppControlResult AppControl::SetExtraData(EncodableValue& value) { std::string key = std::get(v.first); AppControlResult ret = AddExtraData(key, v.second); if (!ret) { - FT_LOG(Error) << "Invalid data at " << key << ", omitting"; - continue; + FT_LOG(Error) << "Invalid data at " << key << ", omitting"; + continue; } } } else { diff --git a/shell/platform/tizen/public/flutter_tizen.h b/shell/platform/tizen/public/flutter_tizen.h index 079c5d137106f..1334f93da8f17 100644 --- a/shell/platform/tizen/public/flutter_tizen.h +++ b/shell/platform/tizen/public/flutter_tizen.h @@ -6,9 +6,9 @@ #ifndef FLUTTER_SHELL_PLATFORM_TIZEN_PUBLIC_FLUTTER_TIZEN_H_ #define FLUTTER_SHELL_PLATFORM_TIZEN_PUBLIC_FLUTTER_TIZEN_H_ +#include #include #include -#include #include "flutter_export.h" #include "flutter_messenger.h" @@ -92,7 +92,8 @@ FlutterDesktopEngineGetMessenger(FlutterDesktopEngineRef engine); // Posts an app control to the engine instance. FLUTTER_EXPORT void FlutterDesktopNotifyAppControl( - FlutterDesktopEngineRef engine, app_control_h app_control); + FlutterDesktopEngineRef engine, + app_control_h app_control); // Posts a locale change notification to the engine instance. FLUTTER_EXPORT void FlutterDesktopNotifyLocaleChange( From 9925268b149e8f7f061b22be368b81837da59113 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Mon, 26 Jul 2021 13:59:07 +0200 Subject: [PATCH 13/18] [AppControl] Fixes after code review Signed-off-by: Rafal Walczyna --- shell/platform/tizen/BUILD.gn | 1 + .../tizen/channels/app_control_channel.cc | 406 ++---------------- .../tizen/channels/app_control_channel.h | 97 +---- shell/platform/tizen/flutter_tizen.cc | 2 +- shell/platform/tizen/public/flutter_tizen.h | 2 +- 5 files changed, 43 insertions(+), 465 deletions(-) diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index 14198e748f5f9..4d41cf1b49131 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -112,6 +112,7 @@ template("embedder") { public = _public_headers sources = [ + "channels/app_control.cc", "channels/app_control_channel.cc", "channels/key_event_channel.cc", "channels/lifecycle_channel.cc", diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index 60b211d7ab1d4..367d72daf2b4a 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -2,7 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include + +#include "app_control.h" #include "app_control_channel.h" + #include "flutter/shell/platform/common/client_wrapper/include/flutter/event_stream_handler_functions.h" namespace flutter { @@ -11,8 +15,6 @@ static constexpr char kChannelName[] = "tizen/internal/app_control_method"; static constexpr char kEventChannelName[] = "tizen/internal/app_control_event"; static constexpr char kReplyChannelName[] = "tizen/internal/app_control_reply"; -int AppControl::next_id_ = 0; - AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { method_channel_ = std::make_unique>( messenger, kChannelName, &StandardMethodCodec::GetInstance()); @@ -26,13 +28,13 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { auto event_channel_handler = std::make_unique>( - [this](const flutter::EncodableValue* arguments, + [this](const EncodableValue* arguments, std::unique_ptr>&& events) -> std::unique_ptr> { RegisterEventHandler(std::move(events)); return nullptr; }, - [this](const flutter::EncodableValue* arguments) + [this](const EncodableValue* arguments) -> std::unique_ptr> { UnregisterEventHandler(); return nullptr; @@ -45,13 +47,13 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { auto reply_channel_handler = std::make_unique>( - [this](const flutter::EncodableValue* arguments, + [this](const EncodableValue* arguments, std::unique_ptr>&& events) -> std::unique_ptr> { RegisterReplyHandler(std::move(events)); return nullptr; }, - [this](const flutter::EncodableValue* arguments) + [this](const EncodableValue* arguments) -> std::unique_ptr> { UnregisterReplyHandler(); return nullptr; @@ -62,17 +64,18 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { AppControlChannel::~AppControlChannel() {} -void AppControlChannel::NotifyAppControl(app_control_h app_control) { +void AppControlChannel::NotifyAppControl(void* app_control) { app_control_h clone = nullptr; - AppControlResult ret = app_control_clone(&clone, app_control); + 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(); + FT_LOG(Error) << "Could not clone app control: " << ret.message(); return; } auto app = std::make_shared(clone); if (!event_sink_) { queue_.push(app); - FT_LOG(Info) << "EventChannel not set yet "; + FT_LOG(Info) << "EventChannel not set yet."; } else { SendAppControlDataEvent(app); } @@ -82,24 +85,22 @@ void AppControlChannel::NotifyAppControl(app_control_h app_control) { void AppControlChannel::HandleMethodCall( const MethodCall& method_call, std::unique_ptr> result) { - FT_LOG(Info) << "HandleMethodCall " << method_call.method_name(); const auto arguments = method_call.arguments(); const auto& method_name = method_call.method_name(); - // AppControl not needed - if (method_name.compare("CreateAppControl") == 0) { + // AppControl is not needed. + if (method_name.compare("create") == 0) { CreateAppControl(arguments, std::move(result)); return; } - // AppControl needed + // AppControl is needed. auto app_control = GetAppControl(arguments); if (app_control == nullptr) { - result->Error("Could not find app_control", "Invalid parameter"); + result->Error("Could not find app_control", "Invalid id provided"); return; } - // Common if (method_name.compare("dispose") == 0) { Dispose(app_control, std::move(result)); } else if (method_name.compare("reply") == 0) { @@ -116,7 +117,7 @@ void AppControlChannel::HandleMethodCall( } void AppControlChannel::RegisterEventHandler( - std::unique_ptr> events) { + std::unique_ptr> events) { event_sink_ = std::move(events); SendAlreadyQueuedEvents(); } @@ -133,7 +134,7 @@ void AppControlChannel::SendAlreadyQueuedEvents() { } void AppControlChannel::RegisterReplyHandler( - std::unique_ptr> events) { + std::unique_ptr> events) { reply_sink_ = std::move(events); } @@ -142,33 +143,19 @@ void AppControlChannel::UnregisterReplyHandler() { } template -bool AppControlChannel::GetValueFromArgs(const flutter::EncodableValue* args, +bool AppControlChannel::GetValueFromArgs(const EncodableValue* args, const char* key, T& out) { if (std::holds_alternative(*args)) { flutter::EncodableMap map = std::get(*args); - if (map.find(flutter::EncodableValue(key)) != map.end()) { - flutter::EncodableValue value = map[flutter::EncodableValue(key)]; + if (map.find(EncodableValue(key)) != map.end()) { + EncodableValue value = map[EncodableValue(key)]; if (std::holds_alternative(value)) { out = std::get(value); return true; } } - FT_LOG(Info) << "Key " << key << "not found"; - } - return false; -} - -bool AppControlChannel::GetEncodableValueFromArgs( - const flutter::EncodableValue* args, - const char* key, - flutter::EncodableValue& out) { - if (std::holds_alternative(*args)) { - flutter::EncodableMap map = std::get(*args); - if (map.find(flutter::EncodableValue(key)) != map.end()) { - out = map[flutter::EncodableValue(key)]; - return true; - } + FT_LOG(Info) << "Key " << key << " not found."; } return false; } @@ -177,7 +164,7 @@ std::shared_ptr AppControlChannel::GetAppControl( const EncodableValue* args) { int id; if (!GetValueFromArgs(args, "id", id)) { - FT_LOG(Error) << "Could not find AppControl with id " << id; + FT_LOG(Error) << "Could not get proper id from arguments."; return nullptr; } @@ -211,7 +198,7 @@ void AppControlChannel::Dispose( void AppControlChannel::Reply( std::shared_ptr app_control, - const flutter::EncodableValue* arguments, + const EncodableValue* arguments, std::unique_ptr> result) { int request_id; if (!GetValueFromArgs(arguments, "requestId", request_id) || @@ -236,7 +223,7 @@ void AppControlChannel::Reply( void AppControlChannel::SendLaunchRequest( std::shared_ptr app_control, - const flutter::EncodableValue* arguments, + const EncodableValue* arguments, std::unique_ptr> result) { bool wait_for_reply = false; GetValueFromArgs(arguments, "waitForReply", wait_for_reply); @@ -256,7 +243,7 @@ void AppControlChannel::SendLaunchRequest( void AppControlChannel::SendTerminateRequest( std::shared_ptr app_control, - const flutter::EncodableValue* arguments, + const EncodableValue* arguments, std::unique_ptr> result) { AppControlResult ret = app_control->SendTerminateRequest(); if (ret) { @@ -268,23 +255,18 @@ void AppControlChannel::SendTerminateRequest( void AppControlChannel::SetAppControlData( std::shared_ptr app_control, - const flutter::EncodableValue* arguments, + const EncodableValue* arguments, std::unique_ptr> result) { std::string app_id, operation, mime, category, uri, launch_mode; - EncodableValue extra_data; + EncodableMap extra_data; GetValueFromArgs(arguments, "appId", app_id); GetValueFromArgs(arguments, "operation", operation); GetValueFromArgs(arguments, "mime", mime); GetValueFromArgs(arguments, "category", category); GetValueFromArgs(arguments, "launchMode", launch_mode); GetValueFromArgs(arguments, "uri", uri); - if (std::holds_alternative(*arguments)) { - flutter::EncodableMap map = std::get(*arguments); - EncodableValue key = EncodableValue("extraData"); - if (map.find(key) != map.end()) { - extra_data = map[key]; - } - } + GetValueFromArgs(arguments, "extraData", extra_data); + AppControlResult results[7]; results[0] = app_control->SetAppId(app_id); if (!operation.empty()) { @@ -320,330 +302,4 @@ void AppControlChannel::SendAppControlDataEvent( } } -AppControl::AppControl(app_control_h app_control) : id_(next_id_++) { - handle_ = app_control; -} - -AppControl::~AppControl() { - app_control_destroy(handle_); -} - -AppControlResult AppControl::GetString(std::string& str, - int func(app_control_h, char**)) { - char* op; - AppControlResult ret = func(handle_, &op); - if (!ret) { - return ret; - } - if (op != nullptr) { - str = std::string{op}; - free(op); - } else { - str = ""; - } - return AppControlResult(APP_CONTROL_ERROR_NONE); -} - -AppControlResult AppControl::SetString(const std::string& str, - int func(app_control_h, const char*)) { - int ret = func(handle_, str.c_str()); - return AppControlResult(ret); -} - -bool _app_control_extra_data_cb(app_control_h app, - const char* key, - void* user_data) { - auto extra_data = static_cast(user_data); - bool is_array = false; - int ret = app_control_is_extra_data_array(app, key, &is_array); - if (ret != APP_CONTROL_ERROR_NONE) { - FT_LOG(Error) << "app_control_is_extra_data_array() failed at key " << key; - return false; - } - - if (is_array) { - char** strings = NULL; - int length = 0; - ret = app_control_get_extra_data_array(app, key, &strings, &length); - if (ret != APP_CONTROL_ERROR_NONE) { - FT_LOG(Error) << "app_control_get_extra_data() failed at key " << key; - return false; - } - EncodableList list; - for (int i = 0; i < length; i++) { - list.push_back(EncodableValue(std::string(strings[i]))); - free(strings[i]); - } - free(strings); - extra_data->insert( - {EncodableValue(std::string(key)), EncodableValue(list)}); - } else { - char* value; - ret = app_control_get_extra_data(app, key, &value); - if (ret != APP_CONTROL_ERROR_NONE) { - FT_LOG(Error) << "app_control_get_extra_data() failed at key " << key; - return false; - } - extra_data->insert( - {EncodableValue(std::string(key)), EncodableValue(std::string(value))}); - free(value); - } - - return true; -} - -AppControlResult AppControl::GetExtraData(EncodableValue& value) { - EncodableMap extra_data; - int ret = app_control_foreach_extra_data(handle_, _app_control_extra_data_cb, - &extra_data); - if (ret == APP_CONTROL_ERROR_NONE) { - value = EncodableValue(extra_data); - } - return AppControlResult(ret); -} - -AppControlResult AppControl::SetExtraData(EncodableValue& value) { - if (std::holds_alternative(value)) { - EncodableMap map = std::get(value); - for (const auto& v : map) { - if (!std::holds_alternative(v.first)) { - FT_LOG(Error) << "Key for extra data has to be string, omitting"; - continue; - } - std::string key = std::get(v.first); - AppControlResult ret = AddExtraData(key, v.second); - if (!ret) { - FT_LOG(Error) << "Invalid data at " << key << ", omitting"; - continue; - } - } - } else { - return AppControlResult(APP_ERROR_INVALID_PARAMETER); - } - return AppControlResult(); -} - -void AppControl::SetManager(AppControlChannel* m) { - manager_ = m; -} - -AppControlChannel* AppControl::GetManager() { - return manager_; -} - -AppControlResult AppControl::GetOperation(std::string& operation) { - return GetString(operation, app_control_get_operation); -} - -AppControlResult AppControl::SetOperation(const std::string& operation) { - return SetString(operation, app_control_set_operation); -} - -AppControlResult AppControl::GetUri(std::string& uri) { - return GetString(uri, app_control_get_uri); -} - -AppControlResult AppControl::SetUri(const std::string& uri) { - return SetString(uri, app_control_set_uri); -} - -AppControlResult AppControl::GetMime(std::string& mime) { - return GetString(mime, app_control_get_mime); -} - -AppControlResult AppControl::SetMime(const std::string& mime) { - return SetString(mime, app_control_set_mime); -} - -AppControlResult AppControl::GetCategory(std::string& category) { - return GetString(category, app_control_get_category); -} - -AppControlResult AppControl::SetCategory(const std::string& category) { - return SetString(category, app_control_set_category); -} - -AppControlResult AppControl::GetAppId(std::string& app_id) { - return GetString(app_id, app_control_get_app_id); -} - -AppControlResult AppControl::SetAppId(const std::string& app_id) { - return SetString(app_id, app_control_set_app_id); -} - -AppControlResult AppControl::GetComponentId(std::string& component_id) { - // Since 5.5 - return GetString(component_id, app_control_get_component_id); -} - -AppControlResult AppControl::SetComponentId(const std::string& component_id) { - // Since 5.5 - return SetString(component_id, app_control_set_component_id); -} - -AppControlResult AppControl::GetCaller(std::string& caller) { - return GetString(caller, app_control_get_caller); -} - -AppControlResult AppControl::GetLaunchMode(std::string& launch_mode) { - app_control_launch_mode_e launch_mode_e; - int ret = app_control_get_launch_mode(handle_, &launch_mode_e); - if (ret != APP_CONTROL_ERROR_NONE) { - return AppControlResult(ret); - } - launch_mode = - (launch_mode_e == APP_CONTROL_LAUNCH_MODE_SINGLE ? "Single" : "Group"); - return AppControlResult(APP_CONTROL_ERROR_NONE); -} - -AppControlResult AppControl::SetLaunchMode(const std::string& launch_mode) { - app_control_launch_mode_e launch_mode_e; - if (launch_mode.compare("Single")) { - launch_mode_e = APP_CONTROL_LAUNCH_MODE_SINGLE; - } else { - launch_mode_e = APP_CONTROL_LAUNCH_MODE_GROUP; - } - int ret = app_control_set_launch_mode(handle_, launch_mode_e); - return AppControlResult(ret); -} - -EncodableValue AppControl::SerializeAppControlToMap() { - std::string app_id, operation, mime, category, uri, caller_id, launch_mode; - AppControlResult results[7]; - results[0] = GetAppId(app_id); - results[1] = GetOperation(operation); - results[2] = GetMime(mime); - results[3] = GetCategory(category); - results[4] = GetUri(uri); - results[5] = GetLaunchMode(launch_mode); - // Caller Id is optional - GetCaller(caller_id); - EncodableValue extra_data; - results[6] = GetExtraData(extra_data); - for (int i = 0; i < 7; i++) { - if (!results[i]) { - return EncodableValue(); - } - } - EncodableMap map; - map[EncodableValue("id")] = EncodableValue(GetId()); - 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("launchMode")] = EncodableValue(launch_mode); - map[EncodableValue("extraData")] = extra_data; - - return EncodableValue(map); -} - -AppControlResult AppControl::SendLaunchRequest() { - AppControlResult ret = - app_control_send_launch_request(handle_, nullptr, nullptr); - return ret; -} - -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) { - 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); - EncodableMap map; - map[EncodableValue("id")] = EncodableValue(app_control->GetId()); - map[EncodableValue("reply")] = - app_control_reply->SerializeAppControlToMap(); - if (result == APP_CONTROL_RESULT_APP_STARTED) { - map[EncodableValue("result")] = EncodableValue("AppStarted"); - } else if (result == APP_CONTROL_RESULT_SUCCEEDED) { - map[EncodableValue("result")] = EncodableValue("Succeeded"); - } else if (result == APP_CONTROL_RESULT_FAILED) { - map[EncodableValue("result")] = EncodableValue("Failed"); - } else if (result == APP_CONTROL_RESULT_CANCELED) { - map[EncodableValue("result")] = EncodableValue("Cancelled"); - } - - app_control->reply_sink_->Success(EncodableValue(map)); - app_control->GetManager()->AddExistingAppControl( - std::move(app_control_reply)); - }; - reply_sink_ = std::move(reply_sink); - AppControlResult ret = - app_control_send_launch_request(handle_, on_reply, this); - return ret; -} - -AppControlResult AppControl::SendTerminateRequest() { - AppControlResult ret = app_control_send_terminate_request(handle_); - return ret; -} - -AppControlResult AppControl::Reply(std::shared_ptr reply, - const std::string& result) { - app_control_result_e result_e; - if (result == "AppStarted") { - result_e = APP_CONTROL_RESULT_APP_STARTED; - } else if (result == "Succeeded") { - result_e = APP_CONTROL_RESULT_SUCCEEDED; - } else if (result == "Failed") { - result_e = APP_CONTROL_RESULT_FAILED; - } else if (result == "Cancelled") { - result_e = APP_CONTROL_RESULT_CANCELED; - } else { - return AppControlResult(APP_CONTROL_ERROR_INVALID_PARAMETER); - } - AppControlResult ret = app_control_reply_to_launch_request( - reply->Handle(), this->handle_, result_e); - return ret; -} - -AppControlResult AppControl::AddExtraData(std::string key, - EncodableValue value) { - bool is_array = std::holds_alternative(value); - if (is_array) { - EncodableList& list = std::get(value); - return AddExtraDataList(key, list); - } else { - bool is_string = std::holds_alternative(value); - if (is_string) { - int ret = app_control_add_extra_data( - handle_, key.c_str(), std::get(value).c_str()); - return AppControlResult(ret); - } else { - return AppControlResult(APP_ERROR_INVALID_PARAMETER); - } - } - return AppControlResult(APP_CONTROL_ERROR_NONE); -} - -AppControlResult AppControl::AddExtraDataList(std::string& key, - EncodableList& list) { - size_t length = list.size(); - auto strings = new const char*[length]; - for (size_t i = 0; i < length; i++) { - bool is_string = std::holds_alternative(list[i]); - if (is_string) { - strings[i] = std::get(list[i]).c_str(); - } else { - delete[] strings; - return AppControlResult(APP_ERROR_INVALID_PARAMETER); - } - } - int ret = - app_control_add_extra_data_array(handle_, key.c_str(), strings, length); - delete[] strings; - return AppControlResult(ret); -} } // namespace flutter diff --git a/shell/platform/tizen/channels/app_control_channel.h b/shell/platform/tizen/channels/app_control_channel.h index 465fd29eaf3dc..51fd2c071a116 100644 --- a/shell/platform/tizen/channels/app_control_channel.h +++ b/shell/platform/tizen/channels/app_control_channel.h @@ -5,7 +5,6 @@ #ifndef EMBEDDER_APP_CONTROL_CHANNEL_H_ #define EMBEDDER_APP_CONTROL_CHANNEL_H_ -#include #include #include @@ -16,89 +15,16 @@ #include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h" #include "flutter/shell/platform/tizen/logger.h" -class FlutterTizenEngine; +#include "app_control.h" namespace flutter { -struct AppControlResult { - AppControlResult() : error_code(APP_CONTROL_ERROR_NONE){}; - AppControlResult(int code) : error_code(code) {} - - // Returns false on error - operator bool() const { return (APP_CONTROL_ERROR_NONE == error_code); } - - std::string message() { return get_error_message(error_code); } - - int error_code; -}; - -class AppControlChannel; - -class AppControl { - public: - AppControl(app_control_h app_control); - ~AppControl(); - - int GetId() { return id_; } - app_control_h Handle() { return handle_; } - - AppControlResult GetOperation(std::string& operation); - AppControlResult SetOperation(const std::string& operation); - AppControlResult GetUri(std::string& uri); - AppControlResult SetUri(const std::string& uri); - AppControlResult GetMime(std::string& mime); - AppControlResult SetMime(const std::string& mime); - AppControlResult GetCategory(std::string& category); - AppControlResult SetCategory(const std::string& category); - AppControlResult GetAppId(std::string& app_id); - AppControlResult SetAppId(const std::string& app_id); - AppControlResult GetComponentId(std::string& component_id); - AppControlResult SetComponentId(const std::string& component_id); - AppControlResult GetCaller(std::string& caller); - AppControlResult GetLaunchMode(std::string& launch_mode); - AppControlResult SetLaunchMode(const std::string& launch_mode); - - EncodableValue SerializeAppControlToMap(); - - AppControlResult SendLaunchRequest(); - AppControlResult SendLaunchRequestWithReply( - std::shared_ptr> reply_sink, - AppControlChannel* manager); - AppControlResult SendTerminateRequest(); - - AppControlResult Reply(std::shared_ptr reply, - const std::string& result); - - AppControlResult GetExtraData(EncodableValue& value); - AppControlResult SetExtraData(EncodableValue& value); - - void SetManager(AppControlChannel* m); - AppControlChannel* GetManager(); - - private: - AppControlResult GetString(std::string& str, int func(app_control_h, char**)); - AppControlResult SetString(const std::string& str, - int func(app_control_h, const char*)); - AppControlResult WriteExtraDataStringToHandle(); - AppControlResult WriteExtraDataToHandle(); - - 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_; - - AppControlChannel* manager_; -}; - class AppControlChannel { public: explicit AppControlChannel(BinaryMessenger* messenger); virtual ~AppControlChannel(); - void NotifyAppControl(app_control_h app_control); + void NotifyAppControl(void* app_control); void AddExistingAppControl(std::shared_ptr app_control) { map_.insert({app_control->GetId(), app_control}); @@ -108,21 +34,16 @@ class AppControlChannel { void HandleMethodCall(const MethodCall& method_call, std::unique_ptr> result); void RegisterEventHandler( - std::unique_ptr> events); + std::unique_ptr> events); void UnregisterEventHandler(); void SendAlreadyQueuedEvents(); void RegisterReplyHandler( - std::unique_ptr> events); + std::unique_ptr> events); void UnregisterReplyHandler(); template - bool GetValueFromArgs(const flutter::EncodableValue* args, - const char* key, - T& out); - bool GetEncodableValueFromArgs(const flutter::EncodableValue* args, - const char* key, - flutter::EncodableValue& out); + bool GetValueFromArgs(const EncodableValue* args, const char* key, T& out); std::shared_ptr GetAppControl(const EncodableValue* args); @@ -132,18 +53,18 @@ class AppControlChannel { void Dispose(std::shared_ptr app_control, std::unique_ptr> result); void Reply(std::shared_ptr app_control, - const flutter::EncodableValue* arguments, + const EncodableValue* arguments, std::unique_ptr> result); void SendLaunchRequest(std::shared_ptr app_control, - const flutter::EncodableValue* arguments, + const EncodableValue* arguments, std::unique_ptr> result); void SendTerminateRequest( std::shared_ptr app_control, - const flutter::EncodableValue* arguments, + const EncodableValue* arguments, std::unique_ptr> result); void SetAppControlData(std::shared_ptr app_control, - const flutter::EncodableValue* arguments, + const EncodableValue* arguments, std::unique_ptr> result); void SendAppControlDataEvent(std::shared_ptr app_control); diff --git a/shell/platform/tizen/flutter_tizen.cc b/shell/platform/tizen/flutter_tizen.cc index bd4308a566390..76e2300f326d9 100644 --- a/shell/platform/tizen/flutter_tizen.cc +++ b/shell/platform/tizen/flutter_tizen.cc @@ -119,7 +119,7 @@ void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger, } void FlutterDesktopNotifyAppControl(FlutterDesktopEngineRef engine, - app_control_h app_control) { + void* app_control) { EngineFromHandle(engine)->app_control_channel->NotifyAppControl(app_control); } diff --git a/shell/platform/tizen/public/flutter_tizen.h b/shell/platform/tizen/public/flutter_tizen.h index 1334f93da8f17..db98da2748dfe 100644 --- a/shell/platform/tizen/public/flutter_tizen.h +++ b/shell/platform/tizen/public/flutter_tizen.h @@ -93,7 +93,7 @@ FlutterDesktopEngineGetMessenger(FlutterDesktopEngineRef engine); // Posts an app control to the engine instance. FLUTTER_EXPORT void FlutterDesktopNotifyAppControl( FlutterDesktopEngineRef engine, - app_control_h app_control); + void* app_control); // Posts a locale change notification to the engine instance. FLUTTER_EXPORT void FlutterDesktopNotifyLocaleChange( From 71bd4dc825836c82e00f19672e54f812aa973950 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Mon, 26 Jul 2021 14:14:46 +0200 Subject: [PATCH 14/18] [AppControl] Add missing files Signed-off-by: Rafal Walczyna --- shell/platform/tizen/channels/app_control.cc | 325 +++++++++++++++++++ shell/platform/tizen/channels/app_control.h | 93 ++++++ 2 files changed, 418 insertions(+) create mode 100644 shell/platform/tizen/channels/app_control.cc create mode 100644 shell/platform/tizen/channels/app_control.h diff --git a/shell/platform/tizen/channels/app_control.cc b/shell/platform/tizen/channels/app_control.cc new file mode 100644 index 0000000000000..51283b2d7b373 --- /dev/null +++ b/shell/platform/tizen/channels/app_control.cc @@ -0,0 +1,325 @@ +// 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. + +#include "app_control.h" +#include "app_control_channel.h" + +#include "flutter/shell/platform/common/client_wrapper/include/flutter/event_stream_handler_functions.h" + +namespace flutter { + +int AppControl::next_id_ = 0; + +AppControl::AppControl(app_control_h app_control) : id_(next_id_++) { + handle_ = app_control; +} + +AppControl::~AppControl() { + app_control_destroy(handle_); +} + +AppControlResult AppControl::GetString(std::string& str, + int func(app_control_h, char**)) { + char* op; + AppControlResult ret = func(handle_, &op); + if (!ret) { + return ret; + } + if (op != nullptr) { + str = std::string{op}; + free(op); + } else { + str = ""; + } + return AppControlResult(APP_CONTROL_ERROR_NONE); +} + +AppControlResult AppControl::SetString(const std::string& str, + int func(app_control_h, const char*)) { + int ret = func(handle_, str.c_str()); + return AppControlResult(ret); +} + +bool OnAppControlExtraDataCallback(app_control_h app, + const char* key, + void* user_data) { + auto extra_data = static_cast(user_data); + bool is_array = false; + int ret = app_control_is_extra_data_array(app, key, &is_array); + if (ret != APP_CONTROL_ERROR_NONE) { + FT_LOG(Error) << "app_control_is_extra_data_array() failed at key " << key; + return false; + } + + if (is_array) { + char** strings = NULL; + int length = 0; + ret = app_control_get_extra_data_array(app, key, &strings, &length); + if (ret != APP_CONTROL_ERROR_NONE) { + FT_LOG(Error) << "app_control_get_extra_data_array() failed at key " + << key; + return false; + } + EncodableList list; + for (int i = 0; i < length; i++) { + list.push_back(EncodableValue(std::string(strings[i]))); + free(strings[i]); + } + free(strings); + extra_data->insert( + {EncodableValue(std::string(key)), EncodableValue(list)}); + } else { + char* value; + ret = app_control_get_extra_data(app, key, &value); + if (ret != APP_CONTROL_ERROR_NONE) { + FT_LOG(Error) << "app_control_get_extra_data() failed at key " << key; + return false; + } + extra_data->insert( + {EncodableValue(std::string(key)), EncodableValue(std::string(value))}); + free(value); + } + + return true; +} + +AppControlResult AppControl::GetExtraData(EncodableValue& value) { + EncodableMap extra_data; + int ret = app_control_foreach_extra_data( + handle_, OnAppControlExtraDataCallback, &extra_data); + if (ret == APP_CONTROL_ERROR_NONE) { + value = EncodableValue(extra_data); + } + return AppControlResult(ret); +} + +AppControlResult AppControl::SetExtraData(EncodableMap& map) { + for (const auto& v : map) { + if (!std::holds_alternative(v.first)) { + FT_LOG(Error) << "Key for extra data has to be string, omitting"; + continue; + } + std::string key = std::get(v.first); + AppControlResult ret = AddExtraData(key, v.second); + if (!ret) { + FT_LOG(Error) << "Invalid data at " << key << ", omitting"; + continue; + } + } + return AppControlResult(); +} + +void AppControl::SetManager(AppControlChannel* m) { + manager_ = m; +} + +AppControlChannel* AppControl::GetManager() { + return manager_; +} + +AppControlResult AppControl::GetOperation(std::string& operation) { + return GetString(operation, app_control_get_operation); +} + +AppControlResult AppControl::SetOperation(const std::string& operation) { + return SetString(operation, app_control_set_operation); +} + +AppControlResult AppControl::GetUri(std::string& uri) { + return GetString(uri, app_control_get_uri); +} + +AppControlResult AppControl::SetUri(const std::string& uri) { + return SetString(uri, app_control_set_uri); +} + +AppControlResult AppControl::GetMime(std::string& mime) { + return GetString(mime, app_control_get_mime); +} + +AppControlResult AppControl::SetMime(const std::string& mime) { + return SetString(mime, app_control_set_mime); +} + +AppControlResult AppControl::GetCategory(std::string& category) { + return GetString(category, app_control_get_category); +} + +AppControlResult AppControl::SetCategory(const std::string& category) { + return SetString(category, app_control_set_category); +} + +AppControlResult AppControl::GetAppId(std::string& app_id) { + return GetString(app_id, app_control_get_app_id); +} + +AppControlResult AppControl::SetAppId(const std::string& app_id) { + return SetString(app_id, app_control_set_app_id); +} + +AppControlResult AppControl::GetCaller(std::string& caller) { + return GetString(caller, app_control_get_caller); +} + +AppControlResult AppControl::GetLaunchMode(std::string& launch_mode) { + app_control_launch_mode_e launch_mode_e; + int ret = app_control_get_launch_mode(handle_, &launch_mode_e); + if (ret != APP_CONTROL_ERROR_NONE) { + return AppControlResult(ret); + } + launch_mode = + (launch_mode_e == APP_CONTROL_LAUNCH_MODE_SINGLE ? "Single" : "Group"); + return AppControlResult(APP_CONTROL_ERROR_NONE); +} + +AppControlResult AppControl::SetLaunchMode(const std::string& launch_mode) { + app_control_launch_mode_e launch_mode_e; + if (launch_mode.compare("Single")) { + launch_mode_e = APP_CONTROL_LAUNCH_MODE_SINGLE; + } else { + launch_mode_e = APP_CONTROL_LAUNCH_MODE_GROUP; + } + int ret = app_control_set_launch_mode(handle_, launch_mode_e); + return AppControlResult(ret); +} + +EncodableValue AppControl::SerializeAppControlToMap() { + std::string app_id, operation, mime, category, uri, caller_id, launch_mode; + AppControlResult results[7]; + results[0] = GetAppId(app_id); + results[1] = GetOperation(operation); + results[2] = GetMime(mime); + results[3] = GetCategory(category); + results[4] = GetUri(uri); + results[5] = GetLaunchMode(launch_mode); + // Caller Id is optional + GetCaller(caller_id); + EncodableValue extra_data; + results[6] = GetExtraData(extra_data); + for (int i = 0; i < 7; i++) { + if (!results[i]) { + return EncodableValue(); + } + } + EncodableMap map; + map[EncodableValue("id")] = EncodableValue(GetId()); + 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("launchMode")] = EncodableValue(launch_mode); + map[EncodableValue("extraData")] = extra_data; + + return EncodableValue(map); +} + +AppControlResult AppControl::SendLaunchRequest() { + AppControlResult ret = + app_control_send_launch_request(handle_, nullptr, nullptr); + return ret; +} + +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) { + 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); + EncodableMap map; + map[EncodableValue("id")] = EncodableValue(app_control->GetId()); + map[EncodableValue("reply")] = + app_control_reply->SerializeAppControlToMap(); + if (result == APP_CONTROL_RESULT_APP_STARTED) { + map[EncodableValue("result")] = EncodableValue("AppStarted"); + } else if (result == APP_CONTROL_RESULT_SUCCEEDED) { + map[EncodableValue("result")] = EncodableValue("Succeeded"); + } else if (result == APP_CONTROL_RESULT_FAILED) { + map[EncodableValue("result")] = EncodableValue("Failed"); + } else if (result == APP_CONTROL_RESULT_CANCELED) { + map[EncodableValue("result")] = EncodableValue("Cancelled"); + } + + app_control->reply_sink_->Success(EncodableValue(map)); + app_control->GetManager()->AddExistingAppControl( + std::move(app_control_reply)); + }; + reply_sink_ = std::move(reply_sink); + AppControlResult ret = + app_control_send_launch_request(handle_, on_reply, this); + return ret; +} + +AppControlResult AppControl::SendTerminateRequest() { + AppControlResult ret = app_control_send_terminate_request(handle_); + return ret; +} + +AppControlResult AppControl::Reply(std::shared_ptr reply, + const std::string& result) { + app_control_result_e result_e; + if (result == "AppStarted") { + result_e = APP_CONTROL_RESULT_APP_STARTED; + } else if (result == "Succeeded") { + result_e = APP_CONTROL_RESULT_SUCCEEDED; + } else if (result == "Failed") { + result_e = APP_CONTROL_RESULT_FAILED; + } else if (result == "Cancelled") { + result_e = APP_CONTROL_RESULT_CANCELED; + } else { + return AppControlResult(APP_CONTROL_ERROR_INVALID_PARAMETER); + } + AppControlResult ret = app_control_reply_to_launch_request( + reply->Handle(), this->handle_, result_e); + return ret; +} + +AppControlResult AppControl::AddExtraData(std::string key, + EncodableValue value) { + bool is_array = std::holds_alternative(value); + if (is_array) { + EncodableList& list = std::get(value); + return AddExtraDataList(key, list); + } else { + bool is_string = std::holds_alternative(value); + if (is_string) { + int ret = app_control_add_extra_data( + handle_, key.c_str(), std::get(value).c_str()); + return AppControlResult(ret); + } else { + return AppControlResult(APP_ERROR_INVALID_PARAMETER); + } + } + return AppControlResult(APP_CONTROL_ERROR_NONE); +} + +AppControlResult AppControl::AddExtraDataList(std::string& key, + EncodableList& list) { + size_t length = list.size(); + auto strings = std::vector(length); + for (size_t i = 0; i < length; i++) { + bool is_string = std::holds_alternative(list[i]); + if (is_string) { + strings[i] = std::get(list[i]).c_str(); + } else { + return AppControlResult(APP_ERROR_INVALID_PARAMETER); + } + } + int ret = app_control_add_extra_data_array(handle_, key.c_str(), + strings.data(), length); + return AppControlResult(ret); +} + +} // namespace flutter diff --git a/shell/platform/tizen/channels/app_control.h b/shell/platform/tizen/channels/app_control.h new file mode 100644 index 0000000000000..07dd9894f2e0e --- /dev/null +++ b/shell/platform/tizen/channels/app_control.h @@ -0,0 +1,93 @@ +// 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_APP_CONTROL_H_ +#define EMBEDDER_APP_CONTROL_H_ + +#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/common/client_wrapper/include/flutter/standard_method_codec.h" +#include "flutter/shell/platform/tizen/logger.h" + +namespace flutter { + +struct AppControlResult { + AppControlResult() : error_code(APP_CONTROL_ERROR_NONE){}; + AppControlResult(int code) : error_code(code) {} + + // Returns false on error + operator bool() const { return (APP_CONTROL_ERROR_NONE == error_code); } + + std::string message() { return get_error_message(error_code); } + + int error_code; +}; + +class AppControlChannel; + +class AppControl { + public: + AppControl(app_control_h app_control); + ~AppControl(); + + int GetId() { return id_; } + app_control_h Handle() { return handle_; } + + AppControlResult GetOperation(std::string& operation); + AppControlResult SetOperation(const std::string& operation); + AppControlResult GetUri(std::string& uri); + AppControlResult SetUri(const std::string& uri); + AppControlResult GetMime(std::string& mime); + AppControlResult SetMime(const std::string& mime); + AppControlResult GetCategory(std::string& category); + AppControlResult SetCategory(const std::string& category); + AppControlResult GetAppId(std::string& app_id); + AppControlResult SetAppId(const std::string& app_id); + AppControlResult GetCaller(std::string& caller); + AppControlResult GetLaunchMode(std::string& launch_mode); + AppControlResult SetLaunchMode(const std::string& launch_mode); + + EncodableValue SerializeAppControlToMap(); + + AppControlResult SendLaunchRequest(); + AppControlResult SendLaunchRequestWithReply( + std::shared_ptr> reply_sink, + AppControlChannel* manager); + AppControlResult SendTerminateRequest(); + + AppControlResult Reply(std::shared_ptr reply, + const std::string& result); + + AppControlResult GetExtraData(EncodableValue& value); + AppControlResult SetExtraData(EncodableMap& value); + + void SetManager(AppControlChannel* m); + AppControlChannel* GetManager(); + + private: + AppControlResult GetString(std::string& str, int func(app_control_h, char**)); + AppControlResult SetString(const std::string& str, + int func(app_control_h, const char*)); + AppControlResult WriteExtraDataStringToHandle(); + AppControlResult WriteExtraDataToHandle(); + + 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_; + + AppControlChannel* manager_; +}; + +} // namespace flutter +#endif // EMBEDDER_APP_CONTROL_H_ From 4aa4185be7131ef60c9dfe38428fe39551091682 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Mon, 26 Jul 2021 14:41:52 +0200 Subject: [PATCH 15/18] [AppControl] Changel enums to lowerCase Signed-off-by: Rafal Walczyna --- shell/platform/tizen/channels/app_control.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/shell/platform/tizen/channels/app_control.cc b/shell/platform/tizen/channels/app_control.cc index 51283b2d7b373..55b35330b7300 100644 --- a/shell/platform/tizen/channels/app_control.cc +++ b/shell/platform/tizen/channels/app_control.cc @@ -169,13 +169,13 @@ AppControlResult AppControl::GetLaunchMode(std::string& launch_mode) { return AppControlResult(ret); } launch_mode = - (launch_mode_e == APP_CONTROL_LAUNCH_MODE_SINGLE ? "Single" : "Group"); + (launch_mode_e == APP_CONTROL_LAUNCH_MODE_SINGLE ? "single" : "group"); return AppControlResult(APP_CONTROL_ERROR_NONE); } AppControlResult AppControl::SetLaunchMode(const std::string& launch_mode) { app_control_launch_mode_e launch_mode_e; - if (launch_mode.compare("Single")) { + if (launch_mode.compare("single")) { launch_mode_e = APP_CONTROL_LAUNCH_MODE_SINGLE; } else { launch_mode_e = APP_CONTROL_LAUNCH_MODE_GROUP; @@ -243,13 +243,13 @@ AppControlResult AppControl::SendLaunchRequestWithReply( map[EncodableValue("reply")] = app_control_reply->SerializeAppControlToMap(); if (result == APP_CONTROL_RESULT_APP_STARTED) { - map[EncodableValue("result")] = EncodableValue("AppStarted"); + map[EncodableValue("result")] = EncodableValue("appStarted"); } else if (result == APP_CONTROL_RESULT_SUCCEEDED) { - map[EncodableValue("result")] = EncodableValue("Succeeded"); + map[EncodableValue("result")] = EncodableValue("succeeded"); } else if (result == APP_CONTROL_RESULT_FAILED) { - map[EncodableValue("result")] = EncodableValue("Failed"); + map[EncodableValue("result")] = EncodableValue("failed"); } else if (result == APP_CONTROL_RESULT_CANCELED) { - map[EncodableValue("result")] = EncodableValue("Cancelled"); + map[EncodableValue("result")] = EncodableValue("cancelled"); } app_control->reply_sink_->Success(EncodableValue(map)); @@ -270,13 +270,13 @@ AppControlResult AppControl::SendTerminateRequest() { AppControlResult AppControl::Reply(std::shared_ptr reply, const std::string& result) { app_control_result_e result_e; - if (result == "AppStarted") { + if (result == "appStarted") { result_e = APP_CONTROL_RESULT_APP_STARTED; - } else if (result == "Succeeded") { + } else if (result == "succeeded") { result_e = APP_CONTROL_RESULT_SUCCEEDED; - } else if (result == "Failed") { + } else if (result == "failed") { result_e = APP_CONTROL_RESULT_FAILED; - } else if (result == "Cancelled") { + } else if (result == "cancelled") { result_e = APP_CONTROL_RESULT_CANCELED; } else { return AppControlResult(APP_CONTROL_ERROR_INVALID_PARAMETER); From 3dd8c3fd0f269e8b68634f333f6f7277cd728b9e Mon Sep 17 00:00:00 2001 From: "Piotr Kosko/Tizen API (PLT) /SRPOL/Engineer/Samsung Electronics" Date: Wed, 28 Jul 2021 08:53:18 +0200 Subject: [PATCH 16/18] [appcontrol] Fixes after review * renamings * missing empty lines or dots * changed way of returning extra data * masking of app_control in flutter_tizen_engine.* and flutter_tizen.* files --- shell/platform/tizen/BUILD.gn | 4 +- shell/platform/tizen/channels/app_control.cc | 14 ++--- shell/platform/tizen/channels/app_control.h | 7 ++- .../tizen/channels/app_control_channel.cc | 58 +++++++++---------- .../tizen/channels/app_control_channel.h | 1 + shell/platform/tizen/flutter_tizen.cc | 2 + shell/platform/tizen/flutter_tizen_engine.cc | 2 + shell/platform/tizen/flutter_tizen_engine.h | 8 ++- shell/platform/tizen/public/flutter_tizen.h | 3 +- 9 files changed, 55 insertions(+), 44 deletions(-) diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index 4d41cf1b49131..6fa61355bb865 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -112,8 +112,6 @@ template("embedder") { public = _public_headers sources = [ - "channels/app_control.cc", - "channels/app_control_channel.cc", "channels/key_event_channel.cc", "channels/lifecycle_channel.cc", "channels/navigation_channel.cc", @@ -152,6 +150,8 @@ template("embedder") { if (embedder_for_target) { sources += [ + "channels/app_control.cc", + "channels/app_control_channel.cc", "channels/platform_channel.cc", "channels/settings_channel.cc", "channels/settings_channel_tizen.cc", diff --git a/shell/platform/tizen/channels/app_control.cc b/shell/platform/tizen/channels/app_control.cc index 55b35330b7300..9e9be413b3e03 100644 --- a/shell/platform/tizen/channels/app_control.cc +++ b/shell/platform/tizen/channels/app_control.cc @@ -3,7 +3,7 @@ // found in the LICENSE file. #include "app_control.h" -#include "app_control_channel.h" +#include "flutter/shell/platform/tizen/channels/app_control_channel.h" #include "flutter/shell/platform/common/client_wrapper/include/flutter/event_stream_handler_functions.h" @@ -84,17 +84,17 @@ bool OnAppControlExtraDataCallback(app_control_h app, return true; } -AppControlResult AppControl::GetExtraData(EncodableValue& value) { +AppControlResult AppControl::GetExtraData(EncodableMap& value) { EncodableMap extra_data; int ret = app_control_foreach_extra_data( handle_, OnAppControlExtraDataCallback, &extra_data); if (ret == APP_CONTROL_ERROR_NONE) { - value = EncodableValue(extra_data); + value = std::move(extra_data); } return AppControlResult(ret); } -AppControlResult AppControl::SetExtraData(EncodableMap& map) { +AppControlResult AppControl::SetExtraData(const EncodableMap& map) { for (const auto& v : map) { if (!std::holds_alternative(v.first)) { FT_LOG(Error) << "Key for extra data has to be string, omitting"; @@ -193,9 +193,9 @@ EncodableValue AppControl::SerializeAppControlToMap() { results[3] = GetCategory(category); results[4] = GetUri(uri); results[5] = GetLaunchMode(launch_mode); - // Caller Id is optional + // Caller Id is optional. GetCaller(caller_id); - EncodableValue extra_data; + EncodableMap extra_data; results[6] = GetExtraData(extra_data); for (int i = 0; i < 7; i++) { if (!results[i]) { @@ -211,7 +211,7 @@ EncodableValue AppControl::SerializeAppControlToMap() { map[EncodableValue("uri")] = EncodableValue(uri); map[EncodableValue("callerId")] = EncodableValue(caller_id); map[EncodableValue("launchMode")] = EncodableValue(launch_mode); - map[EncodableValue("extraData")] = extra_data; + map[EncodableValue("extraData")] = EncodableValue(extra_data); return EncodableValue(map); } diff --git a/shell/platform/tizen/channels/app_control.h b/shell/platform/tizen/channels/app_control.h index 07dd9894f2e0e..e47791abf0954 100644 --- a/shell/platform/tizen/channels/app_control.h +++ b/shell/platform/tizen/channels/app_control.h @@ -22,7 +22,7 @@ struct AppControlResult { AppControlResult() : error_code(APP_CONTROL_ERROR_NONE){}; AppControlResult(int code) : error_code(code) {} - // Returns false on error + // Returns false on error. operator bool() const { return (APP_CONTROL_ERROR_NONE == error_code); } std::string message() { return get_error_message(error_code); } @@ -65,8 +65,8 @@ class AppControl { AppControlResult Reply(std::shared_ptr reply, const std::string& result); - AppControlResult GetExtraData(EncodableValue& value); - AppControlResult SetExtraData(EncodableMap& value); + AppControlResult GetExtraData(EncodableMap& value); + AppControlResult SetExtraData(const EncodableMap& value); void SetManager(AppControlChannel* m); AppControlChannel* GetManager(); @@ -90,4 +90,5 @@ class AppControl { }; } // namespace flutter + #endif // EMBEDDER_APP_CONTROL_H_ diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index 367d72daf2b4a..4bf13e3559e74 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -26,38 +26,36 @@ AppControlChannel::AppControlChannel(BinaryMessenger* messenger) { event_channel_ = std::make_unique>( messenger, kEventChannelName, &StandardMethodCodec::GetInstance()); - auto event_channel_handler = - std::make_unique>( - [this](const EncodableValue* arguments, - std::unique_ptr>&& events) - -> std::unique_ptr> { - RegisterEventHandler(std::move(events)); - return nullptr; - }, - [this](const EncodableValue* arguments) - -> std::unique_ptr> { - UnregisterEventHandler(); - return nullptr; - }); + auto event_channel_handler = std::make_unique>( + [this](const EncodableValue* arguments, + std::unique_ptr>&& events) + -> std::unique_ptr> { + RegisterEventHandler(std::move(events)); + return nullptr; + }, + [this](const EncodableValue* arguments) + -> std::unique_ptr> { + UnregisterEventHandler(); + return nullptr; + }); 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; - }); + 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)); } @@ -117,7 +115,7 @@ void AppControlChannel::HandleMethodCall( } void AppControlChannel::RegisterEventHandler( - std::unique_ptr> events) { + std::unique_ptr> events) { event_sink_ = std::move(events); SendAlreadyQueuedEvents(); } @@ -134,7 +132,7 @@ void AppControlChannel::SendAlreadyQueuedEvents() { } void AppControlChannel::RegisterReplyHandler( - std::unique_ptr> events) { + std::unique_ptr> events) { reply_sink_ = std::move(events); } @@ -146,8 +144,8 @@ template bool AppControlChannel::GetValueFromArgs(const EncodableValue* args, const char* key, T& out) { - if (std::holds_alternative(*args)) { - flutter::EncodableMap map = std::get(*args); + if (std::holds_alternative(*args)) { + EncodableMap map = std::get(*args); if (map.find(EncodableValue(key)) != map.end()) { EncodableValue value = map[EncodableValue(key)]; if (std::holds_alternative(value)) { diff --git a/shell/platform/tizen/channels/app_control_channel.h b/shell/platform/tizen/channels/app_control_channel.h index 51fd2c071a116..c94bd3de3c70b 100644 --- a/shell/platform/tizen/channels/app_control_channel.h +++ b/shell/platform/tizen/channels/app_control_channel.h @@ -83,4 +83,5 @@ class AppControlChannel { }; } // namespace flutter + #endif // EMBEDDER_APP_CONTROL_CHANNEL_H_ diff --git a/shell/platform/tizen/flutter_tizen.cc b/shell/platform/tizen/flutter_tizen.cc index 76e2300f326d9..cd3b2e89e4b77 100644 --- a/shell/platform/tizen/flutter_tizen.cc +++ b/shell/platform/tizen/flutter_tizen.cc @@ -118,10 +118,12 @@ void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger, user_data); } +#ifndef __X64_SHELL__ void FlutterDesktopNotifyAppControl(FlutterDesktopEngineRef engine, void* app_control) { EngineFromHandle(engine)->app_control_channel->NotifyAppControl(app_control); } +#endif void FlutterDesktopNotifyLocaleChange(FlutterDesktopEngineRef engine) { EngineFromHandle(engine)->SetupLocales(); diff --git a/shell/platform/tizen/flutter_tizen_engine.cc b/shell/platform/tizen/flutter_tizen_engine.cc index 1b4a05ac87b95..e298df89166fd 100644 --- a/shell/platform/tizen/flutter_tizen_engine.cc +++ b/shell/platform/tizen/flutter_tizen_engine.cc @@ -243,8 +243,10 @@ bool FlutterTizenEngine::RunEngine(const char* entrypoint) { internal_plugin_registrar_ = std::make_unique(plugin_registrar_.get()); +#ifndef __X64_SHELL__ app_control_channel = std::make_unique( internal_plugin_registrar_->messenger()); +#endif platform_channel = std::make_unique( internal_plugin_registrar_->messenger(), renderer.get()); settings_channel = std::make_unique( diff --git a/shell/platform/tizen/flutter_tizen_engine.h b/shell/platform/tizen/flutter_tizen_engine.h index 5ac57f0b853e1..d02b050d407ec 100644 --- a/shell/platform/tizen/flutter_tizen_engine.h +++ b/shell/platform/tizen/flutter_tizen_engine.h @@ -11,7 +11,6 @@ #include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h" #include "flutter/shell/platform/common/incoming_message_dispatcher.h" #include "flutter/shell/platform/embedder/embedder.h" -#include "flutter/shell/platform/tizen/channels/app_control_channel.h" #include "flutter/shell/platform/tizen/channels/key_event_channel.h" #include "flutter/shell/platform/tizen/channels/lifecycle_channel.h" #include "flutter/shell/platform/tizen/channels/navigation_channel.h" @@ -25,6 +24,11 @@ #include "flutter/shell/platform/tizen/public/flutter_tizen.h" #include "flutter/shell/platform/tizen/tizen_event_loop.h" #include "flutter/shell/platform/tizen/tizen_renderer.h" + +#ifndef __X64_SHELL__ +#include "flutter/shell/platform/tizen/channels/app_control_channel.h" +#endif + #ifdef TIZEN_RENDERER_EVAS_GL #include "flutter/shell/platform/tizen/tizen_renderer_evas_gl.h" #else @@ -138,7 +142,9 @@ class FlutterTizenEngine : public TizenRenderer::Delegate { std::unique_ptr renderer; // The system channels for communicating between Flutter and the platform. +#ifndef __X64_SHELL__ std::unique_ptr app_control_channel; +#endif std::unique_ptr key_event_channel; std::unique_ptr lifecycle_channel; std::unique_ptr navigation_channel; diff --git a/shell/platform/tizen/public/flutter_tizen.h b/shell/platform/tizen/public/flutter_tizen.h index db98da2748dfe..b1c2217bc2385 100644 --- a/shell/platform/tizen/public/flutter_tizen.h +++ b/shell/platform/tizen/public/flutter_tizen.h @@ -6,7 +6,6 @@ #ifndef FLUTTER_SHELL_PLATFORM_TIZEN_PUBLIC_FLUTTER_TIZEN_H_ #define FLUTTER_SHELL_PLATFORM_TIZEN_PUBLIC_FLUTTER_TIZEN_H_ -#include #include #include @@ -90,10 +89,12 @@ FlutterDesktopGetPluginRegistrar(FlutterDesktopEngineRef engine, FLUTTER_EXPORT FlutterDesktopMessengerRef FlutterDesktopEngineGetMessenger(FlutterDesktopEngineRef engine); +#ifndef __X64_SHELL__ // Posts an app control to the engine instance. FLUTTER_EXPORT void FlutterDesktopNotifyAppControl( FlutterDesktopEngineRef engine, void* app_control); +#endif // Posts a locale change notification to the engine instance. FLUTTER_EXPORT void FlutterDesktopNotifyLocaleChange( From e83f94617b47a1734bde4283935ae6dda20916f3 Mon Sep 17 00:00:00 2001 From: "Piotr Kosko/Tizen API (PLT) /SRPOL/Engineer/Samsung Electronics" Date: Mon, 2 Aug 2021 06:44:20 +0200 Subject: [PATCH 17/18] [appcontrol] Few more fixes for review --- shell/platform/tizen/channels/app_control.cc | 3 +-- shell/platform/tizen/flutter_tizen.cc | 4 ++-- shell/platform/tizen/flutter_tizen_engine.h | 8 +++----- shell/platform/tizen/public/flutter_tizen.h | 2 -- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/shell/platform/tizen/channels/app_control.cc b/shell/platform/tizen/channels/app_control.cc index 9e9be413b3e03..7eaa0c86e5709 100644 --- a/shell/platform/tizen/channels/app_control.cc +++ b/shell/platform/tizen/channels/app_control.cc @@ -3,9 +3,8 @@ // found in the LICENSE file. #include "app_control.h" -#include "flutter/shell/platform/tizen/channels/app_control_channel.h" - #include "flutter/shell/platform/common/client_wrapper/include/flutter/event_stream_handler_functions.h" +#include "flutter/shell/platform/tizen/channels/app_control_channel.h" namespace flutter { diff --git a/shell/platform/tizen/flutter_tizen.cc b/shell/platform/tizen/flutter_tizen.cc index cd3b2e89e4b77..e08b7f182888f 100644 --- a/shell/platform/tizen/flutter_tizen.cc +++ b/shell/platform/tizen/flutter_tizen.cc @@ -118,12 +118,12 @@ void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger, user_data); } -#ifndef __X64_SHELL__ void FlutterDesktopNotifyAppControl(FlutterDesktopEngineRef engine, void* app_control) { +#ifndef __X64_SHELL__ EngineFromHandle(engine)->app_control_channel->NotifyAppControl(app_control); -} #endif +} void FlutterDesktopNotifyLocaleChange(FlutterDesktopEngineRef engine) { EngineFromHandle(engine)->SetupLocales(); diff --git a/shell/platform/tizen/flutter_tizen_engine.h b/shell/platform/tizen/flutter_tizen_engine.h index d02b050d407ec..5fe82def58503 100644 --- a/shell/platform/tizen/flutter_tizen_engine.h +++ b/shell/platform/tizen/flutter_tizen_engine.h @@ -11,6 +11,9 @@ #include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h" #include "flutter/shell/platform/common/incoming_message_dispatcher.h" #include "flutter/shell/platform/embedder/embedder.h" +#ifndef __X64_SHELL__ +#include "flutter/shell/platform/tizen/channels/app_control_channel.h" +#endif #include "flutter/shell/platform/tizen/channels/key_event_channel.h" #include "flutter/shell/platform/tizen/channels/lifecycle_channel.h" #include "flutter/shell/platform/tizen/channels/navigation_channel.h" @@ -24,11 +27,6 @@ #include "flutter/shell/platform/tizen/public/flutter_tizen.h" #include "flutter/shell/platform/tizen/tizen_event_loop.h" #include "flutter/shell/platform/tizen/tizen_renderer.h" - -#ifndef __X64_SHELL__ -#include "flutter/shell/platform/tizen/channels/app_control_channel.h" -#endif - #ifdef TIZEN_RENDERER_EVAS_GL #include "flutter/shell/platform/tizen/tizen_renderer_evas_gl.h" #else diff --git a/shell/platform/tizen/public/flutter_tizen.h b/shell/platform/tizen/public/flutter_tizen.h index b1c2217bc2385..f7e1f90024765 100644 --- a/shell/platform/tizen/public/flutter_tizen.h +++ b/shell/platform/tizen/public/flutter_tizen.h @@ -89,12 +89,10 @@ FlutterDesktopGetPluginRegistrar(FlutterDesktopEngineRef engine, FLUTTER_EXPORT FlutterDesktopMessengerRef FlutterDesktopEngineGetMessenger(FlutterDesktopEngineRef engine); -#ifndef __X64_SHELL__ // Posts an app control to the engine instance. FLUTTER_EXPORT void FlutterDesktopNotifyAppControl( FlutterDesktopEngineRef engine, void* app_control); -#endif // Posts a locale change notification to the engine instance. FLUTTER_EXPORT void FlutterDesktopNotifyLocaleChange( From 3ebdb2d3bf29bfaa2d627548822b9e3e500a2aa3 Mon Sep 17 00:00:00 2001 From: "Piotr Kosko/Tizen API (PLT) /SRPOL/Engineer/Samsung Electronics" Date: Tue, 3 Aug 2021 13:16:22 +0200 Subject: [PATCH 18/18] [appcontrol] Removed unnecessary code and initialized poiters with nullptr --- shell/platform/tizen/channels/app_control.cc | 4 ++-- shell/platform/tizen/channels/app_control.h | 4 +--- shell/platform/tizen/channels/app_control_channel.cc | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/shell/platform/tizen/channels/app_control.cc b/shell/platform/tizen/channels/app_control.cc index 7eaa0c86e5709..b16a7bd0e0fe4 100644 --- a/shell/platform/tizen/channels/app_control.cc +++ b/shell/platform/tizen/channels/app_control.cc @@ -52,7 +52,7 @@ bool OnAppControlExtraDataCallback(app_control_h app, } if (is_array) { - char** strings = NULL; + char** strings = nullptr; int length = 0; ret = app_control_get_extra_data_array(app, key, &strings, &length); if (ret != APP_CONTROL_ERROR_NONE) { @@ -69,7 +69,7 @@ bool OnAppControlExtraDataCallback(app_control_h app, extra_data->insert( {EncodableValue(std::string(key)), EncodableValue(list)}); } else { - char* value; + char* value = nullptr; ret = app_control_get_extra_data(app, key, &value); if (ret != APP_CONTROL_ERROR_NONE) { FT_LOG(Error) << "app_control_get_extra_data() failed at key " << key; diff --git a/shell/platform/tizen/channels/app_control.h b/shell/platform/tizen/channels/app_control.h index e47791abf0954..ac6c55fd9a4cc 100644 --- a/shell/platform/tizen/channels/app_control.h +++ b/shell/platform/tizen/channels/app_control.h @@ -68,15 +68,13 @@ class AppControl { AppControlResult GetExtraData(EncodableMap& value); AppControlResult SetExtraData(const EncodableMap& value); - void SetManager(AppControlChannel* m); + void SetManager(AppControlChannel* manager); AppControlChannel* GetManager(); private: AppControlResult GetString(std::string& str, int func(app_control_h, char**)); AppControlResult SetString(const std::string& str, int func(app_control_h, const char*)); - AppControlResult WriteExtraDataStringToHandle(); - AppControlResult WriteExtraDataToHandle(); AppControlResult AddExtraData(std::string key, EncodableValue value); AppControlResult AddExtraDataList(std::string& key, EncodableList& list); diff --git a/shell/platform/tizen/channels/app_control_channel.cc b/shell/platform/tizen/channels/app_control_channel.cc index 4bf13e3559e74..5b85193d2317a 100644 --- a/shell/platform/tizen/channels/app_control_channel.cc +++ b/shell/platform/tizen/channels/app_control_channel.cc @@ -183,7 +183,7 @@ void AppControlChannel::CreateAppControl( } auto app = std::make_unique(app_control); int id = app->GetId(); - map_.insert({app->GetId(), std::move(app)}); + map_.insert({id, std::move(app)}); result->Success(EncodableValue(id)); }