From 3ac9da8cf9f5c72f7ce038cce3a1af18e9691904 Mon Sep 17 00:00:00 2001 From: Pawel Wasowski Date: Tue, 27 Apr 2021 08:38:10 +0200 Subject: [PATCH 1/7] [HapticFeedback] Implement vibrate() [Before] HapticFeedback.vibrate() was not implemented [After] The code below will cause a short vibration: HapticFeedback.vibrate() Signed-off-by: Pawel Wasowski --- .../tizen/channels/platform_channel.cc | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/shell/platform/tizen/channels/platform_channel.cc b/shell/platform/tizen/channels/platform_channel.cc index b79f780af3a52..97e02d7990e36 100644 --- a/shell/platform/tizen/channels/platform_channel.cc +++ b/shell/platform/tizen/channels/platform_channel.cc @@ -11,6 +11,17 @@ static constexpr char kChannelName[] = "flutter/platform"; +#if defined(MOBILE) || defined(WEARABLE) +static constexpr char kUnsupportedHapticFeedbackError[] = + "HapticFeedback.vibrate() is not supported"; +static constexpr char kPermissionDeniedHapticFeedbackError[] = + "No permission to run HapticFeedback.vibrate(). Add " + "\"http://tizen.org/privilege/feedback\" privilege to tizen-manifest.xml " + "to use this method"; +static constexpr char kUnknownHapticFeedbackError[] = + "An unknown error on HapticFeedback.vibrate()"; +#endif + PlatformChannel::PlatformChannel(flutter::BinaryMessenger* messenger) : channel_(std::make_unique>( messenger, kChannelName, &flutter::JsonMethodCodec::GetInstance())) { @@ -24,6 +35,94 @@ PlatformChannel::PlatformChannel(flutter::BinaryMessenger* messenger) PlatformChannel::~PlatformChannel() {} +#if defined(MOBILE) || defined(WEARABLE) +namespace { + +class FeedbackManager { + public: + enum class ResultCode { + OK, + NOT_SUPPORTED_ERROR, + PERMISSION_DENIED_ERROR, + UNKNOWN_ERROR + }; + + FeedbackManager() { + FT_LOGD("Enter FeedbackManager::FeedbackManager()"); + + auto ret = feedback_initialize(); + if (FEEDBACK_ERROR_NONE != ret) { + FT_LOGD("feedback_initialize() failed with error: [%d] (%s)", ret, + get_error_message(ret)); + return; + } + FT_LOGD("feedback_initialize() succeeded"); + properly_initialized_ = true; + + ret = feedback_is_supported_pattern( + FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_SIP, &vibration_supported_); + if (FEEDBACK_ERROR_NONE != ret) { + FT_LOGD("feedback_is_supported_pattern() failed with error: [%d] (%s)", + ret, get_error_message(ret)); + return; + } + FT_LOGD("feedback_is_supported_pattern() succeeded"); + } + + ~FeedbackManager() { + FT_LOGD("Enter FeedbackManager::~FeedbackManager"); + + if (!properly_initialized_) { + return; + } + + auto ret = feedback_deinitialize(); + if (FEEDBACK_ERROR_NONE != ret) { + FT_LOGD("feedback_deinitialize() failed with error: [%d] (%s)", ret, + get_error_message(ret)); + return; + } + FT_LOGD("feedback_deinitialize() succeeded"); + } + + ResultCode Vibrate() { + FT_LOGD("Enter FeedbackManager::Vibrate()"); + + if (!properly_initialized_) { + FT_LOGD( + "Cannot run Vibrate(): FeedbackManager.properly_initialized_ is " + "false"); + return ResultCode::UNKNOWN_ERROR; + } + + if (!vibration_supported_) { + FT_LOGD("HapticFeedback.Vibrate() is not supported"); + return ResultCode::NOT_SUPPORTED_ERROR; + } + + auto ret = + feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_SIP); + FT_LOGD("feedback_play_type() returned: [%d] (%s)", ret, + get_error_message(ret)); + if (FEEDBACK_ERROR_NONE == ret) { + return ResultCode::OK; + } else if (FEEDBACK_ERROR_PERMISSION_DENIED == ret) { + return ResultCode::UNKNOWN_ERROR; + } else if (FEEDBACK_ERROR_NOT_SUPPORTED) { + return ResultCode::NOT_SUPPORTED_ERROR; + } else { + return ResultCode::UNKNOWN_ERROR; + } + } + + private: + bool properly_initialized_ = false; + bool vibration_supported_ = false; +}; + +} // namespace +#endif + void PlatformChannel::HandleMethodCall( const flutter::MethodCall& call, std::unique_ptr> result) { @@ -35,7 +134,28 @@ void PlatformChannel::HandleMethodCall( } else if (method == "SystemSound.play") { result->NotImplemented(); } else if (method == "HapticFeedback.vibrate") { + FT_LOGD("HapticFeedback.vibrate() call received"); + +#if defined(MOBILE) || defined(WEARABLE) + static FeedbackManager feedback_mgr; + + auto ret = feedback_mgr.Vibrate(); + if (FeedbackManager::ResultCode::OK == ret) { + result->Success(); + return; + } + + const std::string error_message = "Could not vibrate"; + if (FeedbackManager::ResultCode::NOT_SUPPORTED_ERROR == ret) { + result->Error(kUnsupportedHapticFeedbackError, error_message); + } else if (FeedbackManager::ResultCode::PERMISSION_DENIED_ERROR == ret) { + result->Error(kPermissionDeniedHapticFeedbackError, error_message); + } else { + result->Error(kUnknownHapticFeedbackError, error_message); + } +#else result->NotImplemented(); +#endif } else if (method == "Clipboard.getData") { result->NotImplemented(); } else if (method == "Clipboard.setData") { From b86b01c3ce9c450f24d6aa56f8120f7f402e6f79 Mon Sep 17 00:00:00 2001 From: Pawel Wasowski Date: Tue, 27 Apr 2021 12:34:10 +0200 Subject: [PATCH 2/7] Make HapticFeedback.vibrate's dependencies dependent on profile HapticFeedback.vibrate will only work on mobile and wearable profiles so its dependencies should only be included in builds for these devices. Signed-off-by: Pawel Wasowski --- shell/platform/tizen/BUILD.gn | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index 1ea9bcf30bb00..73eb07f4d2247 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -64,6 +64,7 @@ config("tizen_rootstrap_include_dirs") { "$custom_sysroot/usr/include/elementary-1", "$custom_sysroot/usr/include/ethumb-1", "$custom_sysroot/usr/include/ethumb-client-1", + "$custom_sysroot/usr/include/feedback" ] lib_dirs = [ "$custom_sysroot/usr/lib" ] @@ -121,6 +122,20 @@ template("embedder_for_profile") { "wayland-client", ] + if (target_name == "mobile") { + libs += [ + "capi-base-common", + "feedback" + ] + } + + if (target_name == "wearable") { + libs += [ + "capi-base-common", + "feedback" + ] + } + defines = invoker.defines if (use_evas_gl_renderer) { From 23234d1c4e51751fc1e3dd599a964a61743c7b7c Mon Sep 17 00:00:00 2001 From: Pawel Wasowski Date: Tue, 27 Apr 2021 13:02:08 +0200 Subject: [PATCH 3/7] Make FeedbackManager a singleton --- .../tizen/channels/platform_channel.cc | 77 +++++++++++-------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/shell/platform/tizen/channels/platform_channel.cc b/shell/platform/tizen/channels/platform_channel.cc index 97e02d7990e36..8340b8ac7d5b8 100644 --- a/shell/platform/tizen/channels/platform_channel.cc +++ b/shell/platform/tizen/channels/platform_channel.cc @@ -5,6 +5,7 @@ #include "platform_channel.h" #include +#include #include "flutter/shell/platform/common/cpp/json_method_codec.h" #include "flutter/shell/platform/tizen/tizen_log.h" @@ -47,6 +48,47 @@ class FeedbackManager { UNKNOWN_ERROR }; + static FeedbackManager& GetInstance() { + FT_LOGD("Enter FeedbackManager::GetInstance()"); + + static FeedbackManager instance; + return instance; + } + + FeedbackManager(const FeedbackManager&) = delete; + FeedbackManager& operator=(const FeedbackManager&) = delete; + + ResultCode Vibrate() { + FT_LOGD("Enter FeedbackManager::Vibrate()"); + + if (!properly_initialized_) { + FT_LOGD( + "Cannot run Vibrate(): FeedbackManager.properly_initialized_ is " + "false"); + return ResultCode::UNKNOWN_ERROR; + } + + if (!vibration_supported_) { + FT_LOGD("HapticFeedback.Vibrate() is not supported"); + return ResultCode::NOT_SUPPORTED_ERROR; + } + + auto ret = + feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_SIP); + FT_LOGD("feedback_play_type() returned: [%d] (%s)", ret, + get_error_message(ret)); + if (FEEDBACK_ERROR_NONE == ret) { + return ResultCode::OK; + } else if (FEEDBACK_ERROR_PERMISSION_DENIED == ret) { + return ResultCode::UNKNOWN_ERROR; + } else if (FEEDBACK_ERROR_NOT_SUPPORTED) { + return ResultCode::NOT_SUPPORTED_ERROR; + } else { + return ResultCode::UNKNOWN_ERROR; + } + } + + private: FeedbackManager() { FT_LOGD("Enter FeedbackManager::FeedbackManager()"); @@ -85,37 +127,6 @@ class FeedbackManager { FT_LOGD("feedback_deinitialize() succeeded"); } - ResultCode Vibrate() { - FT_LOGD("Enter FeedbackManager::Vibrate()"); - - if (!properly_initialized_) { - FT_LOGD( - "Cannot run Vibrate(): FeedbackManager.properly_initialized_ is " - "false"); - return ResultCode::UNKNOWN_ERROR; - } - - if (!vibration_supported_) { - FT_LOGD("HapticFeedback.Vibrate() is not supported"); - return ResultCode::NOT_SUPPORTED_ERROR; - } - - auto ret = - feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_SIP); - FT_LOGD("feedback_play_type() returned: [%d] (%s)", ret, - get_error_message(ret)); - if (FEEDBACK_ERROR_NONE == ret) { - return ResultCode::OK; - } else if (FEEDBACK_ERROR_PERMISSION_DENIED == ret) { - return ResultCode::UNKNOWN_ERROR; - } else if (FEEDBACK_ERROR_NOT_SUPPORTED) { - return ResultCode::NOT_SUPPORTED_ERROR; - } else { - return ResultCode::UNKNOWN_ERROR; - } - } - - private: bool properly_initialized_ = false; bool vibration_supported_ = false; }; @@ -137,9 +148,7 @@ void PlatformChannel::HandleMethodCall( FT_LOGD("HapticFeedback.vibrate() call received"); #if defined(MOBILE) || defined(WEARABLE) - static FeedbackManager feedback_mgr; - - auto ret = feedback_mgr.Vibrate(); + auto ret = FeedbackManager::GetInstance().Vibrate(); if (FeedbackManager::ResultCode::OK == ret) { result->Success(); return; From 15f8f3de88ff72009fb6d4aad0e5abe2b7b293de Mon Sep 17 00:00:00 2001 From: Pawel Wasowski Date: Tue, 27 Apr 2021 16:29:17 +0200 Subject: [PATCH 4/7] [HapticFeedback.vibrate] Minfor fixes - use the proper "MOBILE_PROFILE" and "WEARABLE_PROFILE" names instead of "MOBILE" and "WEARABLE" - reorder lines in BUILD.gn Signed-off-by: Pawel Wasowski --- shell/platform/tizen/BUILD.gn | 2 +- shell/platform/tizen/channels/platform_channel.cc | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index 73eb07f4d2247..469dd09749b2b 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -52,6 +52,7 @@ config("tizen_rootstrap_include_dirs") { "$custom_sysroot/usr/include/emile-1", "$custom_sysroot/usr/include/eo-1", "$custom_sysroot/usr/include/evas-1", + "$custom_sysroot/usr/include/feedback", "$custom_sysroot/usr/include/system", "$custom_sysroot/usr/include/wayland-extension", # For Evas_GL. @@ -64,7 +65,6 @@ config("tizen_rootstrap_include_dirs") { "$custom_sysroot/usr/include/elementary-1", "$custom_sysroot/usr/include/ethumb-1", "$custom_sysroot/usr/include/ethumb-client-1", - "$custom_sysroot/usr/include/feedback" ] lib_dirs = [ "$custom_sysroot/usr/lib" ] diff --git a/shell/platform/tizen/channels/platform_channel.cc b/shell/platform/tizen/channels/platform_channel.cc index 8340b8ac7d5b8..6067945cc5195 100644 --- a/shell/platform/tizen/channels/platform_channel.cc +++ b/shell/platform/tizen/channels/platform_channel.cc @@ -12,7 +12,7 @@ static constexpr char kChannelName[] = "flutter/platform"; -#if defined(MOBILE) || defined(WEARABLE) +#if defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) static constexpr char kUnsupportedHapticFeedbackError[] = "HapticFeedback.vibrate() is not supported"; static constexpr char kPermissionDeniedHapticFeedbackError[] = @@ -21,7 +21,7 @@ static constexpr char kPermissionDeniedHapticFeedbackError[] = "to use this method"; static constexpr char kUnknownHapticFeedbackError[] = "An unknown error on HapticFeedback.vibrate()"; -#endif +#endif // defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) PlatformChannel::PlatformChannel(flutter::BinaryMessenger* messenger) : channel_(std::make_unique>( @@ -36,7 +36,7 @@ PlatformChannel::PlatformChannel(flutter::BinaryMessenger* messenger) PlatformChannel::~PlatformChannel() {} -#if defined(MOBILE) || defined(WEARABLE) +#if defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) namespace { class FeedbackManager { @@ -132,7 +132,7 @@ class FeedbackManager { }; } // namespace -#endif +#endif // defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) void PlatformChannel::HandleMethodCall( const flutter::MethodCall& call, @@ -147,7 +147,7 @@ void PlatformChannel::HandleMethodCall( } else if (method == "HapticFeedback.vibrate") { FT_LOGD("HapticFeedback.vibrate() call received"); -#if defined(MOBILE) || defined(WEARABLE) +#if defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) auto ret = FeedbackManager::GetInstance().Vibrate(); if (FeedbackManager::ResultCode::OK == ret) { result->Success(); @@ -164,7 +164,7 @@ void PlatformChannel::HandleMethodCall( } #else result->NotImplemented(); -#endif +#endif // defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) } else if (method == "Clipboard.getData") { result->NotImplemented(); } else if (method == "Clipboard.setData") { From ce529bc3485faca76f115e48a31f4ea5bd71d1ff Mon Sep 17 00:00:00 2001 From: Pawel Wasowski Date: Wed, 28 Apr 2021 14:12:30 +0200 Subject: [PATCH 5/7] Refactor implementation of HapticFeedback.vibrate() and BUILD.gn Signed-off-by: Pawel Wasowski --- shell/platform/tizen/BUILD.gn | 11 +- .../tizen/channels/platform_channel.cc | 123 ++++++++++++------ 2 files changed, 90 insertions(+), 44 deletions(-) diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index 469dd09749b2b..985b7dff10b2d 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -55,6 +55,7 @@ config("tizen_rootstrap_include_dirs") { "$custom_sysroot/usr/include/feedback", "$custom_sysroot/usr/include/system", "$custom_sysroot/usr/include/wayland-extension", + # For Evas_GL. "$custom_sysroot/usr/include/ecore-con-1", "$custom_sysroot/usr/include/ecore-file-1", @@ -78,6 +79,8 @@ config("tizen_rootstrap_include_dirs") { template("embedder_for_profile") { forward_variables_from(invoker, [ "use_evas_gl_renderer" ]) + profile = target_name + if (!defined(use_evas_gl_renderer)) { use_evas_gl_renderer = false } @@ -122,17 +125,17 @@ template("embedder_for_profile") { "wayland-client", ] - if (target_name == "mobile") { + if (profile == "mobile") { libs += [ "capi-base-common", - "feedback" + "feedback", ] } - if (target_name == "wearable") { + if (profile == "wearable") { libs += [ "capi-base-common", - "feedback" + "feedback", ] } diff --git a/shell/platform/tizen/channels/platform_channel.cc b/shell/platform/tizen/channels/platform_channel.cc index 6067945cc5195..9b5310771be22 100644 --- a/shell/platform/tizen/channels/platform_channel.cc +++ b/shell/platform/tizen/channels/platform_channel.cc @@ -12,17 +12,6 @@ static constexpr char kChannelName[] = "flutter/platform"; -#if defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) -static constexpr char kUnsupportedHapticFeedbackError[] = - "HapticFeedback.vibrate() is not supported"; -static constexpr char kPermissionDeniedHapticFeedbackError[] = - "No permission to run HapticFeedback.vibrate(). Add " - "\"http://tizen.org/privilege/feedback\" privilege to tizen-manifest.xml " - "to use this method"; -static constexpr char kUnknownHapticFeedbackError[] = - "An unknown error on HapticFeedback.vibrate()"; -#endif // defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) - PlatformChannel::PlatformChannel(flutter::BinaryMessenger* messenger) : channel_(std::make_unique>( messenger, kChannelName, &flutter::JsonMethodCodec::GetInstance())) { @@ -42,10 +31,10 @@ namespace { class FeedbackManager { public: enum class ResultCode { - OK, - NOT_SUPPORTED_ERROR, - PERMISSION_DENIED_ERROR, - UNKNOWN_ERROR + kOk, + kNotSupportedError, + kPermissionDeniedError, + kUnknownError }; static FeedbackManager& GetInstance() { @@ -65,26 +54,58 @@ class FeedbackManager { FT_LOGD( "Cannot run Vibrate(): FeedbackManager.properly_initialized_ is " "false"); - return ResultCode::UNKNOWN_ERROR; + return ResultCode::kUnknownError; + } + + if (!permission_granted_) { + FT_LOGD("Cannot run Vibrate(): permission denied"); + return ResultCode::kPermissionDeniedError; } if (!vibration_supported_) { FT_LOGD("HapticFeedback.Vibrate() is not supported"); - return ResultCode::NOT_SUPPORTED_ERROR; + return ResultCode::kNotSupportedError; } auto ret = feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_SIP); - FT_LOGD("feedback_play_type() returned: [%d] (%s)", ret, - get_error_message(ret)); if (FEEDBACK_ERROR_NONE == ret) { - return ResultCode::OK; - } else if (FEEDBACK_ERROR_PERMISSION_DENIED == ret) { - return ResultCode::UNKNOWN_ERROR; + FT_LOGD("feedback_play_type() succeeded"); + return ResultCode::kOk; + } + + FT_LOGD("feedback_play_type() failed with error: [%d] (%s)", ret, + get_error_message(ret)); + + if (FEEDBACK_ERROR_PERMISSION_DENIED == ret) { + permission_granted_ = false; + return ResultCode::kPermissionDeniedError; } else if (FEEDBACK_ERROR_NOT_SUPPORTED) { - return ResultCode::NOT_SUPPORTED_ERROR; + return ResultCode::kNotSupportedError; } else { - return ResultCode::UNKNOWN_ERROR; + return ResultCode::kUnknownError; + } + } + + static std::string GetErrorMessage(const std::string& method_name, + ResultCode result_code) { + FT_LOGD( + "Enter FeedbackManager::GetErrorMessage(): method_name: (%s), " + "result_code: [%d]", + method_name.c_str(), static_cast(result_code)); + + switch (result_code) { + case ResultCode::kNotSupportedError: + return method_name + "() is not supported"; + case ResultCode::kPermissionDeniedError: + return std::string{"No permission to run "} + method_name + + "(). Add " + "\"http://tizen.org/privilege/feedback\" privilege to " + "tizen-manifest.xml " + "to use this method"; + case ResultCode::kUnknownError: + default: + return std::string{"An unknown error on "} + method_name + "()"; } } @@ -103,12 +124,18 @@ class FeedbackManager { ret = feedback_is_supported_pattern( FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_SIP, &vibration_supported_); - if (FEEDBACK_ERROR_NONE != ret) { - FT_LOGD("feedback_is_supported_pattern() failed with error: [%d] (%s)", - ret, get_error_message(ret)); + if (FEEDBACK_ERROR_NONE == ret) { + FT_LOGD("feedback_is_supported_pattern() succeeded"); + return; + } + + FT_LOGD("feedback_is_supported_pattern() failed with error: [%d] (%s)", ret, + get_error_message(ret)); + if (FEEDBACK_ERROR_PERMISSION_DENIED == ret) { + permission_granted_ = false; + } else if (FEEDBACK_ERROR_NONE != ret) { return; } - FT_LOGD("feedback_is_supported_pattern() succeeded"); } ~FeedbackManager() { @@ -128,11 +155,16 @@ class FeedbackManager { } bool properly_initialized_ = false; + /* + * We need this flag to differentiate between feedback_is_supported_pattern() + * failure due to a missing privilege and other causes. + */ + bool permission_granted_ = true; bool vibration_supported_ = false; }; } // namespace -#endif // defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) +#endif // defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) void PlatformChannel::HandleMethodCall( const flutter::MethodCall& call, @@ -147,24 +179,35 @@ void PlatformChannel::HandleMethodCall( } else if (method == "HapticFeedback.vibrate") { FT_LOGD("HapticFeedback.vibrate() call received"); + const std::string error_message = "Could not vibrate"; + + const auto vibrate_variant_name = call.arguments()->GetString(); + #if defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) + /* + * We use a single type of vibration (FEEDBACK_PATTERN_SIP) to implement + * HapticFeedback's vibrate, lightImpact, mediumImpact, heavyImpact + * and selectionClick methods, because Tizen's "feedback" module + * has no dedicated vibration types for them. + * Thus, we ignore the "arguments" contents for "HapticFeedback.vibrate" + * calls. + */ + auto ret = FeedbackManager::GetInstance().Vibrate(); - if (FeedbackManager::ResultCode::OK == ret) { + if (FeedbackManager::ResultCode::kOk == ret) { result->Success(); return; } - const std::string error_message = "Could not vibrate"; - if (FeedbackManager::ResultCode::NOT_SUPPORTED_ERROR == ret) { - result->Error(kUnsupportedHapticFeedbackError, error_message); - } else if (FeedbackManager::ResultCode::PERMISSION_DENIED_ERROR == ret) { - result->Error(kPermissionDeniedHapticFeedbackError, error_message); - } else { - result->Error(kUnknownHapticFeedbackError, error_message); - } + const auto error_cause = + FeedbackManager::GetErrorMessage(vibrate_variant_name, ret); + FT_LOGE("%s: %s", error_cause.c_str(), error_message.c_str()); + result->Error(error_cause, error_message); #else - result->NotImplemented(); -#endif // defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) + const auto error_cause = + std::string{vibrate_variant_name} + "() is not supported"; + result->Error(error_cause.c_str(), error_message.c_str()); +#endif // defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) } else if (method == "Clipboard.getData") { result->NotImplemented(); } else if (method == "Clipboard.setData") { From d8ff0058aa726b9f0b9c12a883648dd4106c81b0 Mon Sep 17 00:00:00 2001 From: Pawel Wasowski Date: Thu, 6 May 2021 12:31:21 +0200 Subject: [PATCH 6/7] [HapticFeedback] Refactor FeedbackManager Signed-off-by: Pawel Wasowski --- .../tizen/channels/platform_channel.cc | 155 +++++++++--------- 1 file changed, 78 insertions(+), 77 deletions(-) diff --git a/shell/platform/tizen/channels/platform_channel.cc b/shell/platform/tizen/channels/platform_channel.cc index 9b5310771be22..0938d7bd18c35 100644 --- a/shell/platform/tizen/channels/platform_channel.cc +++ b/shell/platform/tizen/channels/platform_channel.cc @@ -25,7 +25,6 @@ PlatformChannel::PlatformChannel(flutter::BinaryMessenger* messenger) PlatformChannel::~PlatformChannel() {} -#if defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) namespace { class FeedbackManager { @@ -37,54 +36,24 @@ class FeedbackManager { kUnknownError }; - static FeedbackManager& GetInstance() { - FT_LOGD("Enter FeedbackManager::GetInstance()"); - - static FeedbackManager instance; - return instance; - } - - FeedbackManager(const FeedbackManager&) = delete; - FeedbackManager& operator=(const FeedbackManager&) = delete; - - ResultCode Vibrate() { - FT_LOGD("Enter FeedbackManager::Vibrate()"); - - if (!properly_initialized_) { - FT_LOGD( - "Cannot run Vibrate(): FeedbackManager.properly_initialized_ is " - "false"); - return ResultCode::kUnknownError; - } + static std::string GetVibrateVariantName(const char* haptic_feedback_type) { + FT_LOGD( + "Enter FeedbackManager::GetVibrateVariantName(): haptic_feedback_type: " + "(%s)", + haptic_feedback_type); - if (!permission_granted_) { - FT_LOGD("Cannot run Vibrate(): permission denied"); - return ResultCode::kPermissionDeniedError; + if (!haptic_feedback_type) { + return "HapticFeedback.vibrate"; } - if (!vibration_supported_) { - FT_LOGD("HapticFeedback.Vibrate() is not supported"); - return ResultCode::kNotSupportedError; - } + const size_t kPrefixToRemoveLen = strlen("HapticFeedbackType."); - auto ret = - feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_SIP); - if (FEEDBACK_ERROR_NONE == ret) { - FT_LOGD("feedback_play_type() succeeded"); - return ResultCode::kOk; - } + assert(strlen(haptic_feedback_type) >= kPrefixToRemoveLen); - FT_LOGD("feedback_play_type() failed with error: [%d] (%s)", ret, - get_error_message(ret)); + const std::string kHapticFeedbackPrefix = "HapticFeedback."; - if (FEEDBACK_ERROR_PERMISSION_DENIED == ret) { - permission_granted_ = false; - return ResultCode::kPermissionDeniedError; - } else if (FEEDBACK_ERROR_NOT_SUPPORTED) { - return ResultCode::kNotSupportedError; - } else { - return ResultCode::kUnknownError; - } + return kHapticFeedbackPrefix + + std::string{haptic_feedback_type + kPrefixToRemoveLen}; } static std::string GetErrorMessage(const std::string& method_name, @@ -105,11 +74,63 @@ class FeedbackManager { "to use this method"; case ResultCode::kUnknownError: default: - return std::string{"An unknown error on "} + method_name + "()"; + return std::string{"An unknown error on "} + method_name + "() call"; + } + } + +#if defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) + + static FeedbackManager& GetInstance() { + FT_LOGD("Enter FeedbackManager::GetInstance()"); + + static FeedbackManager instance; + return instance; + } + + FeedbackManager(const FeedbackManager&) = delete; + FeedbackManager& operator=(const FeedbackManager&) = delete; + + ResultCode Vibrate() { + FT_LOGD("Enter FeedbackManager::Vibrate()"); + + if (ResultCode::kOk != initialization_status_) { + FT_LOGD("Cannot run Vibrate(): initialization_status_: [%d]", + static_cast(initialization_status_)); + return initialization_status_; } + + auto ret = + feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_SIP); + if (FEEDBACK_ERROR_NONE == ret) { + FT_LOGD("feedback_play_type() succeeded"); + return ResultCode::kOk; + } + FT_LOGD("feedback_play_type() failed with error: [%d] (%s)", ret, + get_error_message(ret)); + + return NativeErrorToResultCode(ret); } private: + static ResultCode NativeErrorToResultCode(int native_error_code) { + FT_LOGD("Enter NativeErrorToResultCode: native_error_code: [%d]", + native_error_code); + + switch (native_error_code) { + case FEEDBACK_ERROR_NONE: + return ResultCode::kOk; + case FEEDBACK_ERROR_NOT_SUPPORTED: + return ResultCode::kNotSupportedError; + case FEEDBACK_ERROR_PERMISSION_DENIED: + return ResultCode::kPermissionDeniedError; + case FEEDBACK_ERROR_OPERATION_FAILED: + case FEEDBACK_ERROR_INVALID_PARAMETER: + case FEEDBACK_ERROR_NOT_INITIALIZED: + default: + return ResultCode::kUnknownError; + } + } + FeedbackManager() { FT_LOGD("Enter FeedbackManager::FeedbackManager()"); @@ -117,34 +138,17 @@ class FeedbackManager { if (FEEDBACK_ERROR_NONE != ret) { FT_LOGD("feedback_initialize() failed with error: [%d] (%s)", ret, get_error_message(ret)); + initialization_status_ = NativeErrorToResultCode(ret); return; } FT_LOGD("feedback_initialize() succeeded"); - properly_initialized_ = true; - - ret = feedback_is_supported_pattern( - FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_SIP, &vibration_supported_); - if (FEEDBACK_ERROR_NONE == ret) { - FT_LOGD("feedback_is_supported_pattern() succeeded"); - return; - } - FT_LOGD("feedback_is_supported_pattern() failed with error: [%d] (%s)", ret, - get_error_message(ret)); - if (FEEDBACK_ERROR_PERMISSION_DENIED == ret) { - permission_granted_ = false; - } else if (FEEDBACK_ERROR_NONE != ret) { - return; - } + initialization_status_ = ResultCode::kOk; } ~FeedbackManager() { FT_LOGD("Enter FeedbackManager::~FeedbackManager"); - if (!properly_initialized_) { - return; - } - auto ret = feedback_deinitialize(); if (FEEDBACK_ERROR_NONE != ret) { FT_LOGD("feedback_deinitialize() failed with error: [%d] (%s)", ret, @@ -154,17 +158,12 @@ class FeedbackManager { FT_LOGD("feedback_deinitialize() succeeded"); } - bool properly_initialized_ = false; - /* - * We need this flag to differentiate between feedback_is_supported_pattern() - * failure due to a missing privilege and other causes. - */ - bool permission_granted_ = true; - bool vibration_supported_ = false; + ResultCode initialization_status_ = ResultCode::kUnknownError; + +#endif // defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) }; } // namespace -#endif // defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) void PlatformChannel::HandleMethodCall( const flutter::MethodCall& call, @@ -181,8 +180,6 @@ void PlatformChannel::HandleMethodCall( const std::string error_message = "Could not vibrate"; - const auto vibrate_variant_name = call.arguments()->GetString(); - #if defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) /* * We use a single type of vibration (FEEDBACK_PATTERN_SIP) to implement @@ -199,15 +196,19 @@ void PlatformChannel::HandleMethodCall( return; } + const auto vibrate_variant_name = + FeedbackManager::GetVibrateVariantName(call.arguments()[0].GetString()); const auto error_cause = FeedbackManager::GetErrorMessage(vibrate_variant_name, ret); FT_LOGE("%s: %s", error_cause.c_str(), error_message.c_str()); - result->Error(error_cause, error_message); #else - const auto error_cause = - std::string{vibrate_variant_name} + "() is not supported"; - result->Error(error_cause.c_str(), error_message.c_str()); + const auto vibrate_variant_name = + FeedbackManager::GetVibrateVariantName(call.arguments()[0].GetString()); + const auto error_cause = FeedbackManager::GetErrorMessage( + vibrate_variant_name, FeedbackManager::ResultCode::kNotSupportedError); #endif // defined(MOBILE_PROFILE) || defined(WEARABLE_PROFILE) + + result->Error(error_cause, error_message); } else if (method == "Clipboard.getData") { result->NotImplemented(); } else if (method == "Clipboard.setData") { From 9fda56f266ba903a586e846b7cee622560543bb4 Mon Sep 17 00:00:00 2001 From: Pawel Wasowski Date: Fri, 7 May 2021 08:55:56 +0200 Subject: [PATCH 7/7] [HapticFeedback] Use FT_LOGE for all error logs --- shell/platform/tizen/channels/platform_channel.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shell/platform/tizen/channels/platform_channel.cc b/shell/platform/tizen/channels/platform_channel.cc index 0938d7bd18c35..25722c6f54dca 100644 --- a/shell/platform/tizen/channels/platform_channel.cc +++ b/shell/platform/tizen/channels/platform_channel.cc @@ -94,7 +94,7 @@ class FeedbackManager { FT_LOGD("Enter FeedbackManager::Vibrate()"); if (ResultCode::kOk != initialization_status_) { - FT_LOGD("Cannot run Vibrate(): initialization_status_: [%d]", + FT_LOGE("Cannot run Vibrate(): initialization_status_: [%d]", static_cast(initialization_status_)); return initialization_status_; } @@ -105,7 +105,7 @@ class FeedbackManager { FT_LOGD("feedback_play_type() succeeded"); return ResultCode::kOk; } - FT_LOGD("feedback_play_type() failed with error: [%d] (%s)", ret, + FT_LOGE("feedback_play_type() failed with error: [%d] (%s)", ret, get_error_message(ret)); return NativeErrorToResultCode(ret); @@ -136,7 +136,7 @@ class FeedbackManager { auto ret = feedback_initialize(); if (FEEDBACK_ERROR_NONE != ret) { - FT_LOGD("feedback_initialize() failed with error: [%d] (%s)", ret, + FT_LOGE("feedback_initialize() failed with error: [%d] (%s)", ret, get_error_message(ret)); initialization_status_ = NativeErrorToResultCode(ret); return; @@ -151,7 +151,7 @@ class FeedbackManager { auto ret = feedback_deinitialize(); if (FEEDBACK_ERROR_NONE != ret) { - FT_LOGD("feedback_deinitialize() failed with error: [%d] (%s)", ret, + FT_LOGE("feedback_deinitialize() failed with error: [%d] (%s)", ret, get_error_message(ret)); return; }