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..3922c1406 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..811bce9ca 100644 --- a/packages/image_picker/tizen/src/image_resize.cc +++ b/packages/image_picker/tizen/src/image_resize.cc @@ -11,60 +11,71 @@ #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 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); 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(original_width, max_width_) : original_width; + uint32_t height = + has_max_height ? std::min(original_height, max_height_) : original_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_ < original_width; + bool should_downscale_height = + has_max_height && max_height_ < original_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 / static_cast(original_height)) * original_width; + uint32_t downscaled_height = + (width / static_cast(original_width)) * original_height; if (width < height) { if (!has_max_width) { @@ -79,164 +90,123 @@ bool ImageResize::TransformImage(transformation_h transform_h, width = downscaled_width; } } else { - if (org_width < org_height) { + if (original_width < original_height) { width = downscaled_width; - } else if (org_height < org_width) { + } else if (original_height < original_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..b59eba485 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_