From 5d32754a11e781d4719d6ef6198fe034fb7a6661 Mon Sep 17 00:00:00 2001 From: Swift Kim Date: Fri, 8 Apr 2022 14:44:27 +0900 Subject: [PATCH 1/3] [image_picker] Refactor the C++ code --- .../tizen/src/image_picker_tizen_plugin.cc | 249 +++++++---------- .../image_picker/tizen/src/image_resize.cc | 253 ++++++++---------- .../image_picker/tizen/src/image_resize.h | 32 ++- .../tizen/src/permission_manager.cc | 87 ++++++ .../tizen/src/permission_manager.h | 26 ++ 5 files changed, 344 insertions(+), 303 deletions(-) create mode 100644 packages/image_picker/tizen/src/permission_manager.cc create mode 100644 packages/image_picker/tizen/src/permission_manager.h diff --git a/packages/image_picker/tizen/src/image_picker_tizen_plugin.cc b/packages/image_picker/tizen/src/image_picker_tizen_plugin.cc index 0c5481849..dfb275981 100644 --- a/packages/image_picker/tizen/src/image_picker_tizen_plugin.cc +++ b/packages/image_picker/tizen/src/image_picker_tizen_plugin.cc @@ -5,19 +5,19 @@ #include "image_picker_tizen_plugin.h" #include -#include #include #include #include -#ifndef TV_PROFILE -#include -#endif +#include #include #include +#include #include "image_resize.h" -#include "log.h" +#include "permission_manager.h" + +namespace { enum class ImageSource { // Opens up the device camera, letting the user to take a new picture. @@ -26,6 +26,19 @@ enum class ImageSource { kGallery, }; +template +static bool GetValueFromEncodableMap(const flutter::EncodableMap *map, + const char *key, T &out) { + auto iter = map->find(flutter::EncodableValue(key)); + if (iter != map->end() && !iter->second.IsNull()) { + if (auto *value = std::get_if(&iter->second)) { + out = *value; + return true; + } + } + return false; +} + class ImagePickerTizenPlugin : public flutter::Plugin { public: static void RegisterWithRegistrar(flutter::PluginRegistrar *registrar) { @@ -53,75 +66,55 @@ class ImagePickerTizenPlugin : public flutter::Plugin { const flutter::MethodCall &method_call, std::unique_ptr> result) { const auto &method_name = method_call.method_name(); - const auto &arguments = *method_call.arguments(); if (result_) { - SendResultWithError("Already active", "Cancelled by a second request."); + SendErrorResult("Already active", "Cancelled by a second request."); return; } result_ = std::move(result); - multi_image_ = method_name == "pickMultiImage"; - ImageSource source = ImageSource::kGallery; if (method_name == "pickImage" || method_name == "pickMultiImage") { - double width = 0.0, height = 0.0; + const auto *arguments = + std::get_if(method_call.arguments()); + assert(arguments); + + int source_index = static_cast(ImageSource::kGallery); + double max_width = 0.0, max_height = 0.0; int32_t quality = 0; - if (std::holds_alternative(arguments)) { - flutter::EncodableMap values = - std::get(arguments); - auto s = values[flutter::EncodableValue("source")]; - if (std::holds_alternative(s)) { - source = (ImageSource)std::get(s); - } - auto w = values[flutter::EncodableValue("maxWidth")]; - if (std::holds_alternative(w)) { - width = std::get(w); - } - auto h = values[flutter::EncodableValue("maxHeight")]; - if (std::holds_alternative(h)) { - height = std::get(h); - } - auto q = values[flutter::EncodableValue("imageQuality")]; - if (std::holds_alternative(q)) { - quality = std::get(q); - } - image_resize_.SetSize((unsigned int)width, (unsigned int)height, - quality); - } else { - SendResultWithError("Invalid arguments"); - return; - } + GetValueFromEncodableMap(arguments, "source", source_index); + GetValueFromEncodableMap(arguments, "maxWidth", max_width); + GetValueFromEncodableMap(arguments, "maxHeight", max_height); + GetValueFromEncodableMap(arguments, "imageQuality", quality); + image_resize_.SetSize(static_cast(max_width), + static_cast(max_height), quality); + + ImageSource source = ImageSource(source_index); if (source == ImageSource::kCamera) { // TODO: we need to check this feature after webcam is prepared - SendResultWithError("Not supported on this device"); + SendErrorResult("Not supported", "Not supported on this device."); } else if (source == ImageSource::kGallery) { - SetContentMimeType("image"); - CheckPermissionAndPickContent(); + multi_image_ = method_name == "pickMultiImage"; + PickContent("image/*"); } else { - SendResultWithError("Invalid image source"); + SendErrorResult("Invalid arguments", "Invalid image source."); } } else if (method_name == "pickVideo") { - if (std::holds_alternative(arguments)) { - flutter::EncodableMap values = - std::get(arguments); - auto s = values[flutter::EncodableValue("source")]; - if (std::holds_alternative(s)) { - source = (ImageSource)std::get(s); - } - } else { - SendResultWithError("Invalid arguments"); - return; - } + const auto *arguments = + std::get_if(method_call.arguments()); + assert(arguments); + + int source_index = static_cast(ImageSource::kGallery); + GetValueFromEncodableMap(arguments, "source", source_index); + ImageSource source = ImageSource(source_index); if (source == ImageSource::kCamera) { // TODO: we need to check this feature after webcam is prepared - SendResultWithError("Not supported on this device"); + SendErrorResult("Not supported", "Not supported on this device."); } else if (source == ImageSource::kGallery) { - SetContentMimeType("video"); - CheckPermissionAndPickContent(); + PickContent("video/*"); } else { - SendResultWithError("Invalid video source"); + SendErrorResult("Invalid arguments", "Invalid video source."); } } else { result_->NotImplemented(); @@ -129,100 +122,63 @@ class ImagePickerTizenPlugin : public flutter::Plugin { } } - void CheckPermissionAndPickContent() { -#ifndef TV_PROFILE - const char *privilege = "http://tizen.org/privilege/mediastorage"; - - ppm_check_result_e permission; - int ret = ppm_check_permission(privilege, &permission); - if (ret != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) { - LOG_ERROR("ppm_check_permission fail! [%d]", ret); - } else { - switch (permission) { - case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ALLOW: - LOG_INFO("ppm_check_permission success!"); - PickContent(); - return; - case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ASK: - ret = ppm_request_permission( - privilege, - [](ppm_call_cause_e cause, ppm_request_result_e result, - const char *privilege, void *data) -> void { - auto *plugin = (ImagePickerTizenPlugin *)data; - assert(plugin); - - if (cause == PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ERROR) { - LOG_ERROR("ppm_request_permission error! [%d]", result); - plugin->SendResultWithError("Permission denied"); - return; - } - if (result != - PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_ALLOW_FOREVER) { - LOG_ERROR("ppm_request_permission deny! [%d]", result); - plugin->SendResultWithError("Permission denied"); - return; - } - - plugin->PickContent(); - }, - this); - if (ret != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) { - LOG_ERROR("ppm_request_permission fail! [%d]", ret); - break; - } - return; - default: - LOG_ERROR("ppm_check_permission deny!"); - break; - } + bool CheckPermission() { + PermissionManager manager; + PermissionResult result = + manager.RequestPermssion("http://tizen.org/privilege/mediastorage"); + + if (result == PermissionResult::kDenyForever || + result == PermissionResult::kDenyOnce) { + SendErrorResult("Permission denied", "Permission denied by user."); + return false; + } else if (result == PermissionResult::kError) { + SendErrorResult("Operation failed", "Failed to request permission."); + return false; } - SendResultWithError("Permission denied"); -#else - PickContent(); -#endif + return true; } - void PickContent() { + void PickContent(std::string mime_type) { + if (!CheckPermission()) { + return; + } + app_control_h handle = nullptr; -#define RET_IF_ERROR(ret) \ - if (ret != APP_CONTROL_ERROR_NONE) { \ - SendResultWithError(std::to_string(ret), get_error_message(ret)); \ - if (handle) { \ - app_control_destroy(handle); \ - } \ - return; \ +#define RETURN_IF_ERROR(ret) \ + if (ret != APP_CONTROL_ERROR_NONE) { \ + SendErrorResult(std::to_string(ret), get_error_message(ret)); \ + if (handle) { \ + app_control_destroy(handle); \ + } \ + return; \ } int ret = app_control_create(&handle); - RET_IF_ERROR(ret); + RETURN_IF_ERROR(ret); ret = app_control_set_operation(handle, APP_CONTROL_OPERATION_PICK); - RET_IF_ERROR(ret); + RETURN_IF_ERROR(ret); ret = app_control_add_extra_data(handle, APP_CONTROL_DATA_SELECTION_MODE, multi_image_ ? "multiple" : "single"); - RET_IF_ERROR(ret); + RETURN_IF_ERROR(ret); - ret = app_control_set_mime(handle, mime_type_.c_str()); - RET_IF_ERROR(ret); + ret = app_control_set_mime(handle, mime_type.c_str()); + RETURN_IF_ERROR(ret); - ret = app_control_send_launch_request(handle, PickImageReplyCallback, this); - RET_IF_ERROR(ret); -#undef RET_IF_ERROR + ret = app_control_send_launch_request(handle, ReplyCallback, this); + RETURN_IF_ERROR(ret); +#undef RETURN_IF_ERROR app_control_destroy(handle); } - static void PickImageReplyCallback(app_control_h request, app_control_h reply, - app_control_result_e result, - void *user_data) { - LOG_INFO("PickImageReplyCallback called: %d", (int)result); - - auto *plugin = (ImagePickerTizenPlugin *)user_data; - assert(plugin != nullptr); - assert(plugin->result_ != nullptr); + static void ReplyCallback(app_control_h request, app_control_h reply, + app_control_result_e result, void *user_data) { + auto *self = static_cast(user_data); + assert(self->result_); if (result != APP_CONTROL_RESULT_SUCCEEDED) { - plugin->SendResultWithError("Operation failed"); + self->SendErrorResult("Operation failed", "Received an error response."); return; } @@ -231,32 +187,32 @@ class ImagePickerTizenPlugin : public flutter::Plugin { int ret = app_control_get_extra_data_array(reply, APP_CONTROL_DATA_SELECTED, &values, &count); if (ret != APP_CONTROL_ERROR_NONE) { - plugin->SendResultWithError(std::to_string(ret), get_error_message(ret)); + self->SendErrorResult(std::to_string(ret), get_error_message(ret)); return; } if (count == 0) { - plugin->SendResultWithError("No file selected"); - } else if (plugin->multi_image_) { + self->SendErrorResult("Operation cancelled", "No file selected."); + } else if (self->multi_image_) { flutter::EncodableList paths; for (int i = 0; i < count; i++) { std::string source_path = values[i]; std::string dest_path; - if (plugin->image_resize_.Resize(source_path, dest_path)) { + if (self->image_resize_.Resize(source_path, dest_path)) { paths.push_back(flutter::EncodableValue(dest_path)); } else { paths.push_back(flutter::EncodableValue(source_path)); } free(values[i]); } - plugin->SendResultWithSuccess(flutter::EncodableValue(paths)); + self->SendResult(flutter::EncodableValue(paths)); } else { std::string source_path = values[0]; std::string dest_path; - if (plugin->image_resize_.Resize(source_path, dest_path)) { - plugin->SendResultWithSuccess(flutter::EncodableValue(dest_path)); + if (self->image_resize_.Resize(source_path, dest_path)) { + self->SendResult(flutter::EncodableValue(dest_path)); } else { - plugin->SendResultWithSuccess(flutter::EncodableValue(source_path)); + self->SendResult(flutter::EncodableValue(source_path)); } free(values[0]); } @@ -266,33 +222,30 @@ class ImagePickerTizenPlugin : public flutter::Plugin { } } - void SendResultWithSuccess(const flutter::EncodableValue &result) { - if (result_ == nullptr) { + void SendResult(const flutter::EncodableValue &result) { + if (!result_) { return; } result_->Success(result); result_ = nullptr; } - void SendResultWithError(const std::string &error_code, - const std::string &error_message = "") { - if (result_ == nullptr) { + void SendErrorResult(const std::string &error_code, + const std::string &error_message) { + if (!result_) { return; } result_->Error(error_code, error_message); result_ = nullptr; } - void SetContentMimeType(const std::string &mime_type) { - mime_type_ = mime_type + "/*"; - } - - ImageResize image_resize_; std::unique_ptr> result_; - std::string mime_type_; + ImageResize image_resize_; bool multi_image_ = false; }; +} // namespace + void ImagePickerTizenPluginRegisterWithRegistrar( FlutterDesktopPluginRegistrarRef registrar) { ImagePickerTizenPlugin::RegisterWithRegistrar( diff --git a/packages/image_picker/tizen/src/image_resize.cc b/packages/image_picker/tizen/src/image_resize.cc index 5e5229425..e10ceff05 100644 --- a/packages/image_picker/tizen/src/image_resize.cc +++ b/packages/image_picker/tizen/src/image_resize.cc @@ -11,60 +11,68 @@ #include "log.h" -void ImageResize::SetSize(unsigned int w, unsigned int h, int q) { - max_width_ = w; - max_height_ = h; - quality_ = q; -} - -bool ImageResize::DecodeImage(image_util_decode_h decode_h, - image_util_image_h& src_image, - const std::string& src_file) { - int ret = image_util_decode_set_input_path(decode_h, src_file.c_str()); +bool ImageResize::DecodeImage(const std::string& path, + image_util_image_h* image) { + image_util_decode_h handle = nullptr; + int ret = image_util_decode_create(&handle); if (ret != IMAGE_UTIL_ERROR_NONE) { - LOG_ERROR("image_util_decode_set_input_path fail! [%s]", + LOG_ERROR("Failed to initialize image decode util: %s", get_error_message(ret)); return false; } - // TODO: we need to check this api later - // ret = image_util_decode_set_colorspace(decode_h, colorspace); + ret = image_util_decode_set_input_path(handle, path.c_str()); + if (ret != IMAGE_UTIL_ERROR_NONE) { + LOG_ERROR("Failed to set image path: %s", get_error_message(ret)); + image_util_decode_destroy(handle); + return false; + } - ret = image_util_decode_run2(decode_h, &src_image); + ret = image_util_decode_run2(handle, image); if (ret != IMAGE_UTIL_ERROR_NONE) { - LOG_ERROR("image_util_decode_run2 fail! [%s]", get_error_message(ret)); + LOG_ERROR("Failed to decode image: %s", get_error_message(ret)); + image_util_decode_destroy(handle); return false; } + image_util_decode_destroy(handle); return true; } -bool ImageResize::TransformImage(transformation_h transform_h, - image_util_image_h src_image, - image_util_image_h& dst_image) { - unsigned int org_width; - unsigned int org_height; - int ret = image_util_get_image(src_image, &org_width, &org_height, nullptr, - nullptr, nullptr); +bool ImageResize::TransformImage(image_util_image_h input, + image_util_image_h* output) { + transformation_h handle = nullptr; + int ret = image_util_transform_create(&handle); if (ret != IMAGE_UTIL_ERROR_NONE) { - LOG_ERROR("image_util_get_image fail! [%s]", get_error_message(ret)); + LOG_ERROR("Failed to initialize image transform util: %s", + get_error_message(ret)); + return false; + } + + uint32_t orig_width; + uint32_t orig_height; + ret = image_util_get_image(input, &orig_width, &orig_height, nullptr, nullptr, + nullptr); + if (ret != IMAGE_UTIL_ERROR_NONE) { + LOG_ERROR("Failed to get image size: %s", get_error_message(ret)); + image_util_transform_destroy(handle); return false; } bool has_max_width = max_width_ != 0; bool has_max_height = max_height_ != 0; - unsigned int width = - has_max_width ? std::min(org_width, max_width_) : org_width; - unsigned int height = - has_max_height ? std::min(org_height, max_height_) : org_height; + uint32_t width = + has_max_width ? std::min(orig_width, max_width_) : orig_width; + uint32_t height = + has_max_height ? std::min(orig_height, max_height_) : orig_height; - bool should_downscale_width = has_max_width && max_width_ < org_width; - bool should_downscale_height = has_max_height && max_height_ < org_height; + bool should_downscale_width = has_max_width && max_width_ < orig_width; + bool should_downscale_height = has_max_height && max_height_ < orig_height; if (should_downscale_width || should_downscale_height) { - unsigned int downscaled_width = (height / (float)org_height) * org_width; - unsigned int downscaled_height = (width / (float)org_width) * org_height; + uint32_t downscaled_width = (height / (float)orig_height) * orig_width; + uint32_t downscaled_height = (width / (float)orig_width) * orig_height; if (width < height) { if (!has_max_width) { @@ -79,164 +87,123 @@ bool ImageResize::TransformImage(transformation_h transform_h, width = downscaled_width; } } else { - if (org_width < org_height) { + if (orig_width < orig_height) { width = downscaled_width; - } else if (org_height < org_width) { + } else if (orig_height < orig_width) { height = downscaled_height; } } } - LOG_DEBUG("transform width:[%d], height:[%d]", width, height); - ret = image_util_transform_set_resolution(transform_h, width, height); + LOG_DEBUG("Target image resolution: %d x %d", width, height); + ret = image_util_transform_set_resolution(handle, width, height); if (ret != IMAGE_UTIL_ERROR_NONE) { - LOG_ERROR("image_util_transform_set_resolution fail! [%s]", - get_error_message(ret)); + LOG_ERROR("Failed to set image resolution: %s", get_error_message(ret)); + image_util_transform_destroy(handle); return false; } - ret = image_util_transform_run2(transform_h, src_image, &dst_image); + + ret = image_util_transform_run2(handle, input, output); if (ret != IMAGE_UTIL_ERROR_NONE) { - LOG_ERROR("image_util_transform_run2 fail! [%s]", get_error_message(ret)); + LOG_ERROR("Failed to transform image: %s", get_error_message(ret)); + image_util_transform_destroy(handle); return false; } + image_util_transform_destroy(handle); return true; } -bool ImageResize::EncodeImage(image_util_encode_h encode_h, - image_util_image_h dst_image, - image_util_type_e encoder_type, - const std::string& dst_file) { - if (encoder_type == IMAGE_UTIL_JPEG) { - if (quality_ > 0 && quality_ <= 100) { - LOG_DEBUG("quality_ [%d]", quality_); - int ret = image_util_encode_set_quality(encode_h, quality_); +bool ImageResize::EncodeImage(image_util_image_h image, + const std::string& path) { + // Determine the image type from the output file extension. + image_util_type_e type = IMAGE_UTIL_JPEG; + size_t pos = path.rfind("."); + if (pos != std::string::npos) { + std::string extension = path.substr(pos + 1); + std::transform(extension.begin(), extension.end(), extension.begin(), + [](unsigned char c) { return std::tolower(c); }); + if (extension == "png") { + type = IMAGE_UTIL_PNG; + } else if (extension == "gif") { + type = IMAGE_UTIL_GIF; + } else if (extension == "bmp") { + type = IMAGE_UTIL_BMP; + } + } + + image_util_encode_h handle = nullptr; + int ret = image_util_encode_create(type, &handle); + if (ret != IMAGE_UTIL_ERROR_NONE) { + LOG_ERROR("Failed to initialize image encode util: %s", + get_error_message(ret)); + return false; + } + + if (type == IMAGE_UTIL_JPEG) { + if (IsValidQuality()) { + LOG_DEBUG("Target image quality: %d", quality_); + int ret = image_util_encode_set_quality(handle, quality_); if (ret != IMAGE_UTIL_ERROR_NONE) { - LOG_ERROR("image_util_encode_set_quality fail! [%s]", - get_error_message(ret)); + LOG_ERROR("Failed to set image quality: %s", get_error_message(ret)); + image_util_encode_destroy(handle); return false; } } } else { - LOG_DEBUG( - "image_picker: image quality option supports only JPG type.. " - "Returning the image with original quality"); + LOG_INFO( + "image_picker: The image quality option only supports JPG type. " + "Returning the image with original quality."); } - LOG_DEBUG("dst_path : %s", dst_file.c_str()); - int ret = - image_util_encode_run_to_file(encode_h, dst_image, dst_file.c_str()); + LOG_DEBUG("Target image path: %s", path.c_str()); + ret = image_util_encode_run_to_file(handle, image, path.c_str()); if (ret != IMAGE_UTIL_ERROR_NONE) { - LOG_ERROR("image_util_encode_run_to_file fail! [%s]", - get_error_message(ret)); + LOG_ERROR("Failed to encode image: %s", get_error_message(ret)); + image_util_encode_destroy(handle); return false; } + image_util_encode_destroy(handle); return true; } -bool ImageResize::Resize(const std::string& src_file, std::string& dst_file) { - LOG_DEBUG("source image path: %s", src_file.c_str()); - - if (max_width_ == 0 && max_height_ == 0 && - (quality_ <= 0 || quality_ > 100)) { - return false; - } - - // =========================================================== - image_util_image_h src_image = nullptr; - image_util_image_h dst_image = nullptr; - image_util_decode_h decode_h = nullptr; - - int ret = image_util_decode_create(&decode_h); - if (ret != IMAGE_UTIL_ERROR_NONE) { - LOG_ERROR("image_util_decode_create fail! [%s]", get_error_message(ret)); - return false; - } - bool is_decoded = DecodeImage(decode_h, src_image, src_file); - image_util_decode_destroy(decode_h); - if (!is_decoded) { - if (src_image) { - image_util_destroy_image(src_image); - } +bool ImageResize::Resize(const std::string& source_path, + std::string& dest_path) { + bool should_scale = max_width_ != 0 || max_height_ != 0 || IsValidQuality(); + if (!should_scale) { return false; } - // =========================================================== - transformation_h transform_h = nullptr; - ret = image_util_transform_create(&transform_h); - if (ret != IMAGE_UTIL_ERROR_NONE) { - LOG_ERROR("image_util_transform_create fail! [%s]", get_error_message(ret)); - if (src_image) { - image_util_destroy_image(src_image); - } + image_util_image_h source_image = nullptr; + if (!DecodeImage(source_path, &source_image)) { return false; } - bool is_transformed = TransformImage(transform_h, src_image, dst_image); - image_util_transform_destroy(transform_h); - if (!is_transformed) { - if (src_image) { - image_util_destroy_image(src_image); - } - if (dst_image) { - image_util_destroy_image(dst_image); - } + image_util_image_h image = nullptr; + if (!TransformImage(source_image, &image)) { + image_util_destroy_image(source_image); return false; } + image_util_destroy_image(source_image); - image_util_destroy_image(src_image); - - // =========================================================== - char* temp = app_get_cache_path(); - dst_file = std::string(temp); - free(temp); + char* base_dir = app_get_cache_path(); + dest_path = std::string(base_dir); + free(base_dir); - size_t found = src_file.rfind("/"); - if (found != std::string::npos) { - dst_file += "scaled_" + src_file.substr(found + 1); - LOG_DEBUG("dest image path: %s", dst_file.c_str()); + size_t pos = source_path.rfind("/"); + if (pos != std::string::npos) { + dest_path += "scaled_" + source_path.substr(pos + 1); } else { - if (dst_image) { - image_util_destroy_image(dst_image); - } + image_util_destroy_image(image); return false; } - image_util_type_e encoder_type = IMAGE_UTIL_JPEG; - size_t pos = dst_file.rfind("."); - if (pos != std::string::npos) { - std::string ext = dst_file.substr(pos + 1); - std::transform(ext.begin(), ext.end(), ext.begin(), - [](unsigned char c) { return std::tolower(c); }); - if (ext == "png") { - encoder_type = IMAGE_UTIL_PNG; - } else if (ext == "gif") { - encoder_type = IMAGE_UTIL_GIF; - } else if (ext == "bmp") { - encoder_type = IMAGE_UTIL_BMP; - } - } - - image_util_encode_h encode_h = nullptr; - ret = image_util_encode_create(encoder_type, &encode_h); - if (ret != IMAGE_UTIL_ERROR_NONE) { - LOG_ERROR("image_util_encode_create fail! [%s]", get_error_message(ret)); - if (dst_image) { - image_util_destroy_image(dst_image); - } - return false; - } - bool is_encoded = EncodeImage(encode_h, dst_image, encoder_type, dst_file); - image_util_encode_destroy(encode_h); - if (!is_encoded) { - if (dst_image) { - image_util_destroy_image(dst_image); - } + if (!EncodeImage(image, dest_path)) { + image_util_destroy_image(image); return false; } - - image_util_destroy_image(dst_image); + image_util_destroy_image(image); return true; } diff --git a/packages/image_picker/tizen/src/image_resize.h b/packages/image_picker/tizen/src/image_resize.h index 9b3d51747..bfb5d46e5 100644 --- a/packages/image_picker/tizen/src/image_resize.h +++ b/packages/image_picker/tizen/src/image_resize.h @@ -8,20 +8,28 @@ class ImageResize { public: ImageResize() {} - bool Resize(const std::string& src_file, std::string& dst_file); - void SetSize(unsigned int w, unsigned int h, int q); + ~ImageResize() {} + + void SetSize(uint32_t max_width, uint32_t max_height, int32_t quality) { + max_width_ = max_width; + max_height_ = max_height; + quality_ = quality; + } + + bool Resize(const std::string& input_path, std::string& output_path); private: - bool DecodeImage(image_util_decode_h decode_h, image_util_image_h& src_image, - const std::string& src_file); - bool TransformImage(transformation_h transform_h, - image_util_image_h src_image, - image_util_image_h& dst_image); - bool EncodeImage(image_util_encode_h encode_h, image_util_image_h dst_image, - image_util_type_e encoder_type, const std::string& dst_file); - unsigned int max_width_ = 0; - unsigned int max_height_ = 0; - int quality_ = 0; + bool IsValidQuality() { return quality_ > 0 && quality_ < 100; } + + bool DecodeImage(const std::string& path, image_util_image_h* image); + + bool TransformImage(image_util_image_h input, image_util_image_h* output); + + bool EncodeImage(image_util_image_h image, const std::string& path); + + uint32_t max_width_ = 0; + uint32_t max_height_ = 0; + int32_t quality_ = 0; }; #endif diff --git a/packages/image_picker/tizen/src/permission_manager.cc b/packages/image_picker/tizen/src/permission_manager.cc new file mode 100644 index 000000000..435b362f9 --- /dev/null +++ b/packages/image_picker/tizen/src/permission_manager.cc @@ -0,0 +1,87 @@ +// Copyright 2022 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 "permission_manager.h" + +#ifndef TV_PROFILE +#include +#include +#include +#endif + +#include "log.h" + +PermissionStatus PermissionManager::CheckPermission( + const std::string &privilege) { +#ifdef TV_PROFILE + return PermissionStatus::kAllow; +#else + ppm_check_result_e result; + int ret = ppm_check_permission(privilege.c_str(), &result); + if (ret != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) { + LOG_ERROR("Permission check failed [%s]: %s", privilege.c_str(), + get_error_message(ret)); + return PermissionStatus::kError; + } + + switch (result) { + case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ALLOW: + return PermissionStatus::kAllow; + case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ASK: + return PermissionStatus::kAsk; + case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_DENY: + default: + return PermissionStatus::kDeny; + } +#endif +} + +PermissionResult PermissionManager::RequestPermssion( + const std::string &privilege) { +#ifdef TV_PROFILE + return PermissionResult::kAllowForever; +#else + struct Response { + bool received = false; + ppm_call_cause_e cause; + ppm_request_result_e result; + } response; + + int ret = ppm_request_permission( + privilege.c_str(), + [](ppm_call_cause_e cause, ppm_request_result_e result, + const char *privilege, void *user_data) { + auto *response = static_cast(user_data); + response->received = true; + response->cause = cause; + response->result = result; + }, + &response); + if (ret != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) { + LOG_ERROR("Permission request failed [%s]: %s", privilege.c_str(), + get_error_message(ret)); + return PermissionResult::kError; + } + + // Wait until ppm_request_permission() completes with a response. + while (!response.received) { + ecore_main_loop_iterate(); + } + + if (response.cause == PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ERROR) { + LOG_ERROR("Received an error response [%s].", privilege.c_str()); + return PermissionResult::kError; + } + + switch (response.result) { + case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_ALLOW_FOREVER: + return PermissionResult::kAllowForever; + case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_FOREVER: + return PermissionResult::kDenyForever; + case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_ONCE: + default: + return PermissionResult::kDenyOnce; + } +#endif // TV_PROFILE +} diff --git a/packages/image_picker/tizen/src/permission_manager.h b/packages/image_picker/tizen/src/permission_manager.h new file mode 100644 index 000000000..b14322fa7 --- /dev/null +++ b/packages/image_picker/tizen/src/permission_manager.h @@ -0,0 +1,26 @@ +// Copyright 2022 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 FLUTTER_PLUGIN_PERMISSION_MANAGER_H_ +#define FLUTTER_PLUGIN_PERMISSION_MANAGER_H_ + +#include + +// The result of permission check. +enum class PermissionStatus { kAllow, kDeny, kAsk, kError }; + +// The result of permission request. +enum class PermissionResult { kAllowForever, kDenyForever, kDenyOnce, kError }; + +class PermissionManager { + public: + PermissionManager() {} + ~PermissionManager() {} + + PermissionStatus CheckPermission(const std::string &privilege); + + PermissionResult RequestPermssion(const std::string &privilege); +}; + +#endif // FLUTTER_PLUGIN_PERMISSION_MANAGER_H_ From e1c807dcaa2bd889ed148427d946c6a10bb4aa9e Mon Sep 17 00:00:00 2001 From: Swift Kim Date: Thu, 14 Apr 2022 14:20:42 +0900 Subject: [PATCH 2/3] Use pointer type for output argument --- .../image_picker/tizen/src/image_picker_tizen_plugin.cc | 4 ++-- packages/image_picker/tizen/src/image_resize.cc | 8 ++++---- packages/image_picker/tizen/src/image_resize.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/image_picker/tizen/src/image_picker_tizen_plugin.cc b/packages/image_picker/tizen/src/image_picker_tizen_plugin.cc index dfb275981..3922c1406 100644 --- a/packages/image_picker/tizen/src/image_picker_tizen_plugin.cc +++ b/packages/image_picker/tizen/src/image_picker_tizen_plugin.cc @@ -198,7 +198,7 @@ class ImagePickerTizenPlugin : public flutter::Plugin { for (int i = 0; i < count; i++) { std::string source_path = values[i]; std::string dest_path; - if (self->image_resize_.Resize(source_path, dest_path)) { + if (self->image_resize_.Resize(source_path, &dest_path)) { paths.push_back(flutter::EncodableValue(dest_path)); } else { paths.push_back(flutter::EncodableValue(source_path)); @@ -209,7 +209,7 @@ class ImagePickerTizenPlugin : public flutter::Plugin { } else { std::string source_path = values[0]; std::string dest_path; - if (self->image_resize_.Resize(source_path, dest_path)) { + if (self->image_resize_.Resize(source_path, &dest_path)) { self->SendResult(flutter::EncodableValue(dest_path)); } else { self->SendResult(flutter::EncodableValue(source_path)); diff --git a/packages/image_picker/tizen/src/image_resize.cc b/packages/image_picker/tizen/src/image_resize.cc index e10ceff05..b1da41d65 100644 --- a/packages/image_picker/tizen/src/image_resize.cc +++ b/packages/image_picker/tizen/src/image_resize.cc @@ -169,7 +169,7 @@ bool ImageResize::EncodeImage(image_util_image_h image, } bool ImageResize::Resize(const std::string& source_path, - std::string& dest_path) { + std::string* dest_path) { bool should_scale = max_width_ != 0 || max_height_ != 0 || IsValidQuality(); if (!should_scale) { return false; @@ -188,18 +188,18 @@ bool ImageResize::Resize(const std::string& source_path, image_util_destroy_image(source_image); char* base_dir = app_get_cache_path(); - dest_path = std::string(base_dir); + *dest_path = std::string(base_dir); free(base_dir); size_t pos = source_path.rfind("/"); if (pos != std::string::npos) { - dest_path += "scaled_" + source_path.substr(pos + 1); + *dest_path += "scaled_" + source_path.substr(pos + 1); } else { image_util_destroy_image(image); return false; } - if (!EncodeImage(image, dest_path)) { + if (!EncodeImage(image, *dest_path)) { image_util_destroy_image(image); return false; } diff --git a/packages/image_picker/tizen/src/image_resize.h b/packages/image_picker/tizen/src/image_resize.h index bfb5d46e5..b59eba485 100644 --- a/packages/image_picker/tizen/src/image_resize.h +++ b/packages/image_picker/tizen/src/image_resize.h @@ -16,7 +16,7 @@ class ImageResize { quality_ = quality; } - bool Resize(const std::string& input_path, std::string& output_path); + bool Resize(const std::string& input_path, std::string* output_path); private: bool IsValidQuality() { return quality_ > 0 && quality_ < 100; } From aad865ef4f825ced53fc3fc7e1fd6df96cd7d460 Mon Sep 17 00:00:00 2001 From: Swift Kim Date: Thu, 14 Apr 2022 14:24:33 +0900 Subject: [PATCH 3/3] Do not abbreviate words --- .../image_picker/tizen/src/image_resize.cc | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/image_picker/tizen/src/image_resize.cc b/packages/image_picker/tizen/src/image_resize.cc index b1da41d65..811bce9ca 100644 --- a/packages/image_picker/tizen/src/image_resize.cc +++ b/packages/image_picker/tizen/src/image_resize.cc @@ -49,10 +49,10 @@ bool ImageResize::TransformImage(image_util_image_h input, return false; } - uint32_t orig_width; - uint32_t orig_height; - ret = image_util_get_image(input, &orig_width, &orig_height, nullptr, nullptr, - nullptr); + uint32_t original_width; + uint32_t original_height; + ret = image_util_get_image(input, &original_width, &original_height, nullptr, + nullptr, nullptr); if (ret != IMAGE_UTIL_ERROR_NONE) { LOG_ERROR("Failed to get image size: %s", get_error_message(ret)); image_util_transform_destroy(handle); @@ -63,16 +63,19 @@ bool ImageResize::TransformImage(image_util_image_h input, bool has_max_height = max_height_ != 0; uint32_t width = - has_max_width ? std::min(orig_width, max_width_) : orig_width; + has_max_width ? std::min(original_width, max_width_) : original_width; uint32_t height = - has_max_height ? std::min(orig_height, max_height_) : orig_height; + has_max_height ? std::min(original_height, max_height_) : original_height; - bool should_downscale_width = has_max_width && max_width_ < orig_width; - bool should_downscale_height = has_max_height && max_height_ < orig_height; + bool should_downscale_width = has_max_width && max_width_ < original_width; + bool should_downscale_height = + has_max_height && max_height_ < original_height; if (should_downscale_width || should_downscale_height) { - uint32_t downscaled_width = (height / (float)orig_height) * orig_width; - uint32_t downscaled_height = (width / (float)orig_width) * orig_height; + uint32_t downscaled_width = + (height / static_cast(original_height)) * original_width; + uint32_t downscaled_height = + (width / static_cast(original_width)) * original_height; if (width < height) { if (!has_max_width) { @@ -87,9 +90,9 @@ bool ImageResize::TransformImage(image_util_image_h input, width = downscaled_width; } } else { - if (orig_width < orig_height) { + if (original_width < original_height) { width = downscaled_width; - } else if (orig_height < orig_width) { + } else if (original_height < original_width) { height = downscaled_height; } }