From d47b635fe70f3bf3df5516c90a765ffb78142c1a Mon Sep 17 00:00:00 2001 From: Swift Kim Date: Wed, 18 May 2022 12:15:01 +0900 Subject: [PATCH] [permission_handler] Refactor the C++ code (#379) * [permission_handler] Refactor the C++ code * Update the device limitations section in README --- README.md | 6 +- packages/permission_handler/CHANGELOG.md | 4 + .../tizen/src/app_settings_manager.cc | 164 ++++----- .../tizen/src/app_settings_manager.h | 24 +- .../src/permission_handler_tizen_plugin.cc | 164 +++++---- .../tizen/src/permission_manager.cc | 339 ++++-------------- .../tizen/src/permission_manager.h | 58 ++- .../tizen/src/{type.h => permissions.h} | 29 +- .../tizen/src/service_manager.cc | 29 +- .../tizen/src/service_manager.h | 32 +- 10 files changed, 298 insertions(+), 551 deletions(-) rename packages/permission_handler/tizen/src/{type.h => permissions.h} (56%) diff --git a/README.md b/README.md index 65808a992..3bdd3caf8 100644 --- a/README.md +++ b/README.md @@ -60,10 +60,10 @@ The _"non-endorsed"_ status means that the plugin is not endorsed by the origina | [**image_picker_tizen**](packages/image_picker) | ⚠️ | ❌ | ❌ | ❌ | No camera
No file manager app | | [**integration_test_tizen**](packages/integration_test) | ✔️ | ✔️ | ✔️ | ✔️ | | [**messageport_tizen**](packages/messageport) | ✔️ | ✔️ | ✔️ | ✔️ | -| [**network_info_plus_tizen**](packages/network_info_plus) | ✔️ | ❌ | ✔️ | ❌ | API unsupported by emulators | +| [**network_info_plus_tizen**](packages/network_info_plus) | ✔️ | ❌ | ✔️ | ❌ | API not supported on emulator | | [**package_info_plus_tizen**](packages/package_info_plus) | ✔️ | ✔️ | ✔️ | ✔️ | -| [**path_provider_tizen**](packages/path_provider) | ⚠️ | ⚠️ | ⚠️ | ⚠️ | No external storage | -| [**permission_handler_tizen**](packages/permission_handler) | ✔️ | ✔️ | ❌ | ❌ | Not applicable for TV | +| [**path_provider_tizen**](packages/path_provider) | ✔️ | ✔️ | ✔️ | ✔️ | +| [**permission_handler_tizen**](packages/permission_handler) | ✔️ | ✔️ | ⚠️ | ⚠️ | Not applicable for TV | | [**sensors_plus_tizen**](packages/sensors_plus) | ✔️ | ✔️ | ❌ | ❌ | No sensor hardware | | [**share_plus_tizen**](packages/share_plus) | ⚠️ | ⚠️ | ❌ | ❌ | No SMS or e-mail app | | [**shared_preferences_tizen**](packages/shared_preferences) | ✔️ | ✔️ | ✔️ | ✔️ | diff --git a/packages/permission_handler/CHANGELOG.md b/packages/permission_handler/CHANGELOG.md index c3e85f43a..62bc4e624 100644 --- a/packages/permission_handler/CHANGELOG.md +++ b/packages/permission_handler/CHANGELOG.md @@ -1,3 +1,7 @@ +## NEXT + +* Code refactoring. + ## 1.2.0 * Update permission_handler to 8.3.0. diff --git a/packages/permission_handler/tizen/src/app_settings_manager.cc b/packages/permission_handler/tizen/src/app_settings_manager.cc index 82f786033..c3482a38c 100644 --- a/packages/permission_handler/tizen/src/app_settings_manager.cc +++ b/packages/permission_handler/tizen/src/app_settings_manager.cc @@ -1,126 +1,86 @@ +// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + #include "app_settings_manager.h" #include #include #include +#include + #include "log.h" namespace { -constexpr char kPackageID[] = "pkgId"; -constexpr char kSettingAppID[] = "com.samsung.clocksetting.apps"; - -class AppPermissions { - public: - AppPermissions() { Init(); } - - ~AppPermissions() { Deinit(); } - - bool Launch(const std::string& package_name) { - if (package_name.length() == 0) { - return false; - } - - int ret = app_control_add_extra_data(app_control_, kPackageID, - package_name.c_str()); - if (ret != APP_CONTROL_ERROR_NONE) { - LOG_ERROR("Failed to add key[%s]:value[%s]", kPackageID, - package_name.c_str()); - return false; - } - - ret = app_control_send_launch_request(app_control_, nullptr, nullptr); - if (ret != APP_CONTROL_ERROR_NONE) { - LOG_ERROR("Failed to send launch request setting"); - return false; - } - return true; + +constexpr char kSettingAppId[] = "com.samsung.clocksetting.apps"; + +std::string GetPackageName() { + char* app_id; + int ret = app_get_id(&app_id); + if (ret != APP_ERROR_NONE) { + LOG_ERROR("The app ID is not found."); + return ""; } - private: - void Init() { - int ret = app_control_create(&app_control_); - if (ret != APP_CONTROL_ERROR_NONE) { - LOG_ERROR("Failed to create app control handle"); - } - - ret = app_control_set_app_id(app_control_, kSettingAppID); - if (ret != APP_CONTROL_ERROR_NONE) { - LOG_ERROR("Failed to set app id[%s]", kSettingAppID); - } + package_info_h package_info; + ret = package_info_create(app_id, &package_info); + free(app_id); + if (ret != PACKAGE_MANAGER_ERROR_NONE) { + LOG_ERROR("Failed to create a package info handle."); + return ""; } - void Deinit() { - if (app_control_) { - app_control_destroy(app_control_); - app_control_ = nullptr; - } + char* package_name; + ret = package_info_get_package(package_info, &package_name); + package_info_destroy(package_info); + if (ret != PACKAGE_MANAGER_ERROR_NONE) { + LOG_ERROR("Failed to get the package name."); + return ""; } - app_control_h app_control_{nullptr}; -}; - -class PackageName { - public: - PackageName() { Init(); } - - ~PackageName() { Deinit(); } - - char* Get() { return package_name_; } - - private: - void Init() { - int ret = app_get_id(&app_id_); - if (ret != APP_ERROR_NONE || app_id_ == nullptr) { - LOG_ERROR("Failed to get app id"); - return; - } - - ret = package_info_create(app_id_, &package_info_); - if (ret != PACKAGE_MANAGER_ERROR_NONE || package_info_ == nullptr) { - LOG_ERROR("Failed to create package info handle"); - } - ret = package_info_get_package(package_info_, &package_name_); - if (ret != PACKAGE_MANAGER_ERROR_NONE || package_name_ == nullptr) { - LOG_ERROR("Failed to get package name"); - } + std::string result = std::string(package_name); + free(package_name); + + return result; +} + +} // namespace + +bool AppSettingsManager::OpenAppSettings() { + std::string package_name = GetPackageName(); + if (package_name.empty()) { + return false; } - void Deinit() { - if (app_id_) { - free(app_id_); - app_id_ = nullptr; - } - - if (package_info_) { - package_info_destroy(package_info_); - package_info_ = nullptr; - } - - if (package_name_) { - free(package_name_); - package_name_ = nullptr; - } + app_control_h app_control; + int ret = app_control_create(&app_control); + if (ret != APP_CONTROL_ERROR_NONE) { + LOG_ERROR("Failed to create an app control handle."); + return false; } - char* app_id_{nullptr}; - package_info_h package_info_{nullptr}; - char* package_name_{nullptr}; -}; -} // namespace + ret = app_control_set_app_id(app_control, kSettingAppId); + if (ret != APP_CONTROL_ERROR_NONE) { + LOG_ERROR("Failed to set an app ID."); + app_control_destroy(app_control); + return false; + } -AppSettingsManager::AppSettingsManager() { - app_permissions_ = std::make_unique(); - PackageName pkg_name; - char* name = pkg_name.Get(); - if (name == nullptr) { - return; + ret = app_control_add_extra_data(app_control, "pkgId", package_name.c_str()); + if (ret != APP_CONTROL_ERROR_NONE) { + LOG_ERROR("Failed to add extra data."); + app_control_destroy(app_control); + return false; } - package_name_ = std::string(name); -} -AppSettingsManager::~AppSettingsManager() {} + ret = app_control_send_launch_request(app_control, nullptr, nullptr); + app_control_destroy(app_control); + if (ret != APP_CONTROL_ERROR_NONE) { + LOG_ERROR("Failed to send a launch request."); + return false; + } -bool AppSettingsManager::OpenAppSettings() { - return app_permissions_->Launch(package_name_); + return true; } diff --git a/packages/permission_handler/tizen/src/app_settings_manager.h b/packages/permission_handler/tizen/src/app_settings_manager.h index 68a66cf70..cea2ab2aa 100644 --- a/packages/permission_handler/tizen/src/app_settings_manager.h +++ b/packages/permission_handler/tizen/src/app_settings_manager.h @@ -1,24 +1,16 @@ -#ifndef APP_SETTINGS_MANAGER_H_ -#define APP_SETTINGS_MANAGER_H_ +// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. -#include -#include -#include - -namespace { -class AppPermissions; -} +#ifndef FLUTTER_PLUGIN_APP_SETTINGS_MANAGER_H_ +#define FLUTTER_PLUGIN_APP_SETTINGS_MANAGER_H_ class AppSettingsManager { public: - AppSettingsManager(); - ~AppSettingsManager(); + AppSettingsManager() {} + ~AppSettingsManager() {} bool OpenAppSettings(); - - private: - std::unique_ptr app_permissions_; - std::string package_name_; }; -#endif // APP_SETTINGS_MANAGER_H_ +#endif // FLUTTER_PLUGIN_APP_SETTINGS_MANAGER_H_ diff --git a/packages/permission_handler/tizen/src/permission_handler_tizen_plugin.cc b/packages/permission_handler/tizen/src/permission_handler_tizen_plugin.cc index dde89c0e3..25f3dc6f0 100644 --- a/packages/permission_handler/tizen/src/permission_handler_tizen_plugin.cc +++ b/packages/permission_handler/tizen/src/permission_handler_tizen_plugin.cc @@ -1,16 +1,53 @@ +// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + #include "permission_handler_tizen_plugin.h" #include #include #include +#include +#include +#include + #include "app_settings_manager.h" -#include "log.h" #include "permission_manager.h" +#include "permissions.h" #include "service_manager.h" namespace { +std::string PermissionToPrivilege(Permission permission) { + switch (permission) { + case Permission::kCalendar: + return "http://tizen.org/privilege/calendar.read"; + case Permission::kCamera: + return "http://tizen.org/privilege/camera"; + case Permission::kContacts: + return "http://tizen.org/privilege/contact.read"; + case Permission::kLocation: + case Permission::kLocationAlways: + case Permission::kLocationWhenInUse: + return "http://tizen.org/privilege/location"; + case Permission::kMicrophone: + return "http://tizen.org/privilege/recorder"; + case Permission::kPhone: + return "http://tizen.org/privilege/call"; + case Permission::kSensors: + return "http://tizen.org/privilege/healthinfo"; + case Permission::kSMS: + return "http://tizen.org/privilege/message.read"; + case Permission::kStorage: + return "http://tizen.org/privilege/externalstorage"; + case Permission::kMediaLibrary: + return "http://tizen.org/privilege/mediastorage"; + default: + return ""; + } +} + class PermissionHandlerTizenPlugin : public flutter::Plugin { public: static void RegisterWithRegistrar(flutter::PluginRegistrar *registrar) { @@ -37,95 +74,76 @@ class PermissionHandlerTizenPlugin : public flutter::Plugin { void HandleMethodCall( const flutter::MethodCall &method_call, std::unique_ptr> result) { - auto method_name = method_call.method_name(); - LOG_INFO("method : %s", method_name.c_str()); + const std::string &method_name = method_call.method_name(); + const flutter::EncodableValue *arguments = method_call.arguments(); - if (method_name.compare("checkServiceStatus") == 0) { - const flutter::EncodableValue *arguments = method_call.arguments(); + if (method_name == "checkServiceStatus") { if (std::holds_alternative(*arguments)) { - int permission = std::get(*arguments); - auto reply = result.release(); - auto on_success = [reply](ServiceStatus status) { - reply->Success(flutter::EncodableValue(static_cast(status))); - delete reply; - }; - auto on_error = [reply](const std::string &code, - const std::string &message) { - reply->Error(code, message); - delete reply; - }; - service_manager_.CheckServiceStatus( - static_cast(permission), on_success, on_error); + Permission permission = Permission(std::get(*arguments)); + ServiceStatus status = service_manager_.CheckServiceStatus(permission); + result->Success(flutter::EncodableValue(static_cast(status))); } else { - result->Error("MethodCall - Invalid arguments", - "arguments type of method checkServiceStatus isn't int"); + result->Error("Invalid argument", "The argument must be an integer."); } - } else if (method_name.compare("checkPermissionStatus") == 0) { - const flutter::EncodableValue *arguments = method_call.arguments(); + } else if (method_name == "checkPermissionStatus") { if (std::holds_alternative(*arguments)) { - int permission = std::get(*arguments); - auto reply = result.release(); - auto on_success = [reply](PermissionStatus status) { - reply->Success(flutter::EncodableValue(static_cast(status))); - delete reply; - }; - auto on_error = [reply](const std::string &code, - const std::string &message) { - reply->Error(code, message); - delete reply; - }; - permission_manager_.CheckPermissionStatus( - static_cast(permission), on_success, on_error); + Permission permission = Permission(std::get(*arguments)); + std::string privilege = PermissionToPrivilege(permission); + + PermissionStatus status; + if (privilege.empty()) { + status = PermissionStatus::kGranted; + } else { + status = permission_manager_.CheckPermission(privilege); + } + + if (status != PermissionStatus::kError) { + result->Success( + flutter::EncodableValue(static_cast(status))); + } else { + result->Error("Operation failed", "Failed to check permission."); + } } else { - result->Error( - "MethodCall - Invalid arguments", - "arguments type of method checkPermissionStatus isn't int"); + result->Error("Invalid argument", "The argument must be an integer."); } - } else if (method_name.compare("requestPermissions") == 0) { - const flutter::EncodableValue *arguments = method_call.arguments(); + } else if (method_name == "requestPermissions") { if (std::holds_alternative(*arguments)) { - std::vector permissions; - for (auto iter : std::get(*arguments)) { - permissions.push_back( - static_cast(std::get(iter))); + flutter::EncodableMap results; + for (flutter::EncodableValue argument : + std::get(*arguments)) { + Permission permission = Permission(std::get(argument)); + std::string privilege = PermissionToPrivilege(permission); + + PermissionStatus status; + if (privilege.empty()) { + status = PermissionStatus::kGranted; + } else { + status = permission_manager_.RequestPermssion(privilege); + } + + if (status != PermissionStatus::kError) { + results[argument] = + flutter::EncodableValue(static_cast(status)); + } else { + result->Error("Operation failed", "Failed to request permission."); + return; + } } - auto reply = result.release(); - auto on_success = - [reply]( - const std::map &results) { - flutter::EncodableMap encodables; - for (auto [key, value] : results) { - encodables.emplace( - flutter::EncodableValue(static_cast(key)), - flutter::EncodableValue(static_cast(value))); - } - reply->Success(flutter::EncodableValue(encodables)); - delete reply; - }; - auto on_error = [reply](const std::string &code, - const std::string &message) { - reply->Error(code, message); - delete reply; - }; - permission_manager_.RequestPermissions(permissions, on_success, - on_error); + result->Success(flutter::EncodableValue(results)); } else { - result->Error("MethodCall - Invalid arguments", - "arguments type of method requestPermissions isn't " - "vector"); + result->Error("Invalid argument", "The argument must be a List."); } - } else if (method_name.compare("openAppSettings") == 0) { - bool ret = app_settings_manager_.OpenAppSettings(); - result->Success(flutter::EncodableValue(ret)); + } else if (method_name == "openAppSettings") { + bool opened = settings_manager_.OpenAppSettings(); + result->Success(flutter::EncodableValue(opened)); } else { result->NotImplemented(); - return; } } - PermissionManager permission_manager_; - AppSettingsManager app_settings_manager_; ServiceManager service_manager_; + PermissionManager permission_manager_; + AppSettingsManager settings_manager_; }; } // namespace diff --git a/packages/permission_handler/tizen/src/permission_manager.cc b/packages/permission_handler/tizen/src/permission_manager.cc index bf623dfe7..91462b469 100644 --- a/packages/permission_handler/tizen/src/permission_manager.cc +++ b/packages/permission_handler/tizen/src/permission_manager.cc @@ -1,297 +1,86 @@ +// 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" -#include "type.h" - -namespace { - -constexpr char kPrivilegeCalendarRead[] = - "http://tizen.org/privilege/calendar.read"; -constexpr char kPrivilegeCalendarWrite[] = - "http://tizen.org/privilege/calendar.write"; -constexpr char kPrivilegeCamera[] = "http://tizen.org/privilege/camera"; -constexpr char kPrivilegeContactRead[] = - "http://tizen.org/privilege/contact.read"; -constexpr char kPrivilegeContactWrite[] = - "http://tizen.org/privilege/contact.write"; -constexpr char kPrivilegeLocation[] = "http://tizen.org/privilege/location"; -constexpr char kPrivilegeLocationCoarse[] = - "http://tizen.org/privilege/location.coarse"; -constexpr char kPrivilegeRecorder[] = "http://tizen.org/privilege/recorder"; -constexpr char kPrivilegeCall[] = "http://tizen.org/privilege/call"; -constexpr char kPrivilegeSensors[] = "http://tizen.org/privilege/healthinfo"; -constexpr char kPrivilegeMessageRead[] = - "http://tizen.org/privilege/message.read"; -constexpr char kPrivilegeMessageWrite[] = - "http://tizen.org/privilege/message.write"; -constexpr char kPrivilegeExternalStorage[] = - "http://tizen.org/privilege/externalstorage"; -constexpr char kPrivilegeMediaStorage[] = - "http://tizen.org/privilege/mediastorage"; -struct Param { - PermissionManager* manager{nullptr}; - bool is_done{false}; - size_t remaining_request{0}; -}; +PermissionStatus PermissionManager::CheckPermission( + const std::string &privilege) { +#ifdef TV_PROFILE + return PermissionStatus::kGranted; +#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; + } -std::string CheckResultToString(int result) { switch (result) { case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ALLOW: - return "CHECK_RESULT_ALLOW"; - case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_DENY: - return "CHECK_RESULT_DENY"; + return PermissionStatus::kGranted; case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ASK: - return "CHECK_RESULT_ASK"; - default: - return "CHECK_RESULT_UNKNOWN"; - } -} - -bool ConvertToPermission(const std::string& privilege, - PermissionGroup* permission) { - if (privilege == kPrivilegeCalendarRead || - privilege == kPrivilegeCalendarWrite) { - *permission = PermissionGroup::kCalendar; - } else if (privilege == kPrivilegeCamera) { - *permission = PermissionGroup::kCamera; - } else if (privilege == kPrivilegeContactRead || - privilege == kPrivilegeContactWrite) { - *permission = PermissionGroup::kContacts; - } else if (privilege == kPrivilegeLocation || - privilege == kPrivilegeLocationCoarse) { - *permission = PermissionGroup::kLocation; - } else if (privilege == kPrivilegeRecorder) { - *permission = PermissionGroup::kMicrophone; - } else if (privilege == kPrivilegeCall) { - *permission = PermissionGroup::kPhone; - } else if (privilege == kPrivilegeSensors) { - *permission = PermissionGroup::kSensors; - } else if (privilege == kPrivilegeMessageRead || - privilege == kPrivilegeMessageWrite) { - *permission = PermissionGroup::kSMS; - } else if (privilege == kPrivilegeExternalStorage) { - *permission = PermissionGroup::kStorage; - } else if (privilege == kPrivilegeMediaStorage) { - *permission = PermissionGroup::kMediaLibrary; - } else { - LOG_WARN("Unknown Privilege!"); - return false; - } - return true; -} - -bool ConvertToPrivileges(PermissionGroup permission, - std::vector* privileges) { - switch (permission) { - case PermissionGroup::kCalendar: - privileges->push_back(kPrivilegeCalendarRead); - break; - case PermissionGroup::kCamera: - privileges->push_back(kPrivilegeCamera); - break; - case PermissionGroup::kContacts: - privileges->push_back(kPrivilegeContactRead); - break; - case PermissionGroup::kLocation: - case PermissionGroup::kLocationAlways: - case PermissionGroup::kLocationWhenInUse: - privileges->push_back(kPrivilegeLocation); - break; - case PermissionGroup::kMicrophone: - privileges->push_back(kPrivilegeRecorder); - break; - case PermissionGroup::kPhone: - privileges->push_back(kPrivilegeCall); - break; - case PermissionGroup::kSensors: - privileges->push_back(kPrivilegeSensors); - break; - case PermissionGroup::kSMS: - privileges->push_back(kPrivilegeMessageRead); - break; - case PermissionGroup::kStorage: - privileges->push_back(kPrivilegeExternalStorage); - break; - case PermissionGroup::kMediaLibrary: - privileges->push_back(kPrivilegeMediaStorage); - break; + case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_DENY: default: - LOG_WARN("Unknown Permission!"); - return false; - } - return true; -} - -int DeterminePermissionStatus(PermissionGroup permission, - PermissionStatus* status) { - std::vector privileges; - ConvertToPrivileges(permission, &privileges); - - if (privileges.size() == 0) { - LOG_DEBUG("No tizen specific privileges needed for permission %d", - permission); - *status = PermissionStatus::kGranted; - return PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE; - } - - int result; - ppm_check_result_e check_result; - for (auto iter : privileges) { - result = ppm_check_permission(iter, &check_result); - if (result != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) { - LOG_ERROR("ppm_check_permission (%s) error: %s", iter, - get_error_message(result)); - return result; - } else { - LOG_DEBUG("ppm_check_permission (%s) result: %s", iter, - CheckResultToString(check_result).c_str()); - switch (check_result) { - case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_DENY: - case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ASK: - *status = PermissionStatus::kDenied; - return result; - case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ALLOW: - default: - *status = PermissionStatus::kGranted; - break; - } - } - } - return result; -} - -void OnRequestPermissionResponse(ppm_call_cause_e cause, - ppm_request_result_e result, - const char* privilege, void* data) { - Param* param = (Param*)data; - PermissionManager* manager = param->manager; - PermissionGroup permission; - - if (cause != PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ANSWER || - !ConvertToPermission(privilege, &permission)) { - // abandon a request - LOG_ERROR("Privilege[%s] request failed with an error", privilege); - param->is_done = true; - return; - } - - if (manager->RequestResults().count(permission) == 0) { - switch (result) { - case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_ALLOW_FOREVER: - manager->RequestResults()[permission] = PermissionStatus::kGranted; - break; - case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_ONCE: - manager->RequestResults()[permission] = PermissionStatus::kDenied; - break; - case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_FOREVER: - manager->RequestResults()[permission] = - PermissionStatus::kPermanentlyDenied; - break; - } - } - LOG_DEBUG("permission %d status: %d", permission, - manager->RequestResults()[permission]); - auto location = manager->RequestResults().find(PermissionGroup::kLocation); - if (location != manager->RequestResults().end()) { - manager->RequestResults()[PermissionGroup::kLocationAlways] = - location->second; - manager->RequestResults()[PermissionGroup::kLocationWhenInUse] = - location->second; + return PermissionStatus::kDenied; } - - param->remaining_request--; - param->is_done = true; +#endif } -} // namespace - -PermissionManager::PermissionManager() : on_going_(false) {} - -PermissionManager::~PermissionManager() {} - -void PermissionManager::CheckPermissionStatus( - PermissionGroup permission, OnPermissionChecked success_callback, - OnPermissionError error_callback) { - LOG_DEBUG("Check permission %d status", permission); - - PermissionStatus status; - int result = DeterminePermissionStatus(permission, &status); - if (result != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) { - error_callback(get_error_message(result), - "An error occurred when call ppm_check_permission()"); - } else { - success_callback(status); +PermissionStatus PermissionManager::RequestPermssion( + const std::string &privilege) { +#ifdef TV_PROFILE + return PermissionStatus::kGranted; +#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 PermissionStatus::kError; } -} -void PermissionManager::RequestPermissions( - std::vector permissions, - OnPermissionRequested success_callback, OnPermissionError error_callback) { - if (on_going_) { - error_callback("RequestPermissions - error", - "A request for permissions is already running"); - return; + // Wait until ppm_request_permission() completes with a response. + while (!response.received) { + ecore_main_loop_iterate(); } - int result; - PermissionStatus status; - request_results_.clear(); - std::vector permissions_to_request; - for (auto permission : permissions) { - result = DeterminePermissionStatus(permission, &status); - if (result != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) { - error_callback(get_error_message(result), - "An error occurred when call ppm_check_permission()"); - return; - } - if (status == PermissionStatus::kGranted) { - if (request_results_.find(permission) == request_results_.end()) { - LOG_DEBUG("Request permission %d result: kGranted", permission); - request_results_[permission] = PermissionStatus::kGranted; - } - continue; - } - - ConvertToPrivileges(permission, &permissions_to_request); - } - - // no permission is needed to requested - if (permissions_to_request.size() == 0) { - success_callback(request_results_); - return; - } - - on_going_ = true; - - Param p; - p.manager = this; - p.remaining_request = permissions_to_request.size(); - - for (size_t i = 0; i < permissions_to_request.size(); i++) { - const char* permission = permissions_to_request[i]; - p.is_done = false; - result = - ppm_request_permission(permission, OnRequestPermissionResponse, &p); - - if (result != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) { - LOG_ERROR("Failed to call ppm_request_permission with [%s]", permission); - continue; - } - - // Wait until ppm_request_permission is done; - while (!p.is_done) { - ecore_main_loop_iterate(); - } + if (response.cause == PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ERROR) { + LOG_ERROR("Received an error response [%s].", privilege.c_str()); + return PermissionStatus::kError; } - if (p.remaining_request) { - error_callback(get_error_message(result), - "some error occurred when call ppm_request_permission"); - } else { - success_callback(request_results_); + switch (response.result) { + case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_ALLOW_FOREVER: + return PermissionStatus::kGranted; + case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_FOREVER: + return PermissionStatus::kPermanentlyDenied; + case PRIVACY_PRIVILEGE_MANAGER_REQUEST_RESULT_DENY_ONCE: + default: + return PermissionStatus::kDenied; } - on_going_ = false; +#endif // TV_PROFILE } diff --git a/packages/permission_handler/tizen/src/permission_manager.h b/packages/permission_handler/tizen/src/permission_manager.h index a40609e1f..be7ff1f1f 100644 --- a/packages/permission_handler/tizen/src/permission_manager.h +++ b/packages/permission_handler/tizen/src/permission_manager.h @@ -1,39 +1,33 @@ -#ifndef PERMISSION_MANAGER_H_ -#define PERMISSION_MANAGER_H_ - -#include - -#include -#include -#include -#include - -#include "type.h" - -using OnPermissionChecked = std::function; -using OnPermissionRequested = std::function &results)>; -using OnPermissionError = - std::function; +// 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 and request. +// +// Originally defined in permission_status.dart of the platform interface +// package. +enum class PermissionStatus { + kDenied = 0, + kGranted = 1, + kRestricted = 2, + kLimited = 3, + kPermanentlyDenied = 4, + kError = 5, +}; class PermissionManager { public: - PermissionManager(); - ~PermissionManager(); + PermissionManager() {} + ~PermissionManager() {} - void CheckPermissionStatus(PermissionGroup permission, - OnPermissionChecked success_callback, - OnPermissionError error_callback); - void RequestPermissions(std::vector permissions, - OnPermissionRequested success_callback, - OnPermissionError error_callback); - inline std::map &RequestResults() { - return request_results_; - } + PermissionStatus CheckPermission(const std::string &privilege); - private: - bool on_going_; - std::map request_results_; + PermissionStatus RequestPermssion(const std::string &privilege); }; -#endif // PERMISSION_MANAGER_H_ +#endif // FLUTTER_PLUGIN_PERMISSION_MANAGER_H_ diff --git a/packages/permission_handler/tizen/src/type.h b/packages/permission_handler/tizen/src/permissions.h similarity index 56% rename from packages/permission_handler/tizen/src/type.h rename to packages/permission_handler/tizen/src/permissions.h index 8af43eb0d..02afb7e90 100644 --- a/packages/permission_handler/tizen/src/type.h +++ b/packages/permission_handler/tizen/src/permissions.h @@ -1,9 +1,14 @@ -#ifndef PERMISSION_HANDLER_TYPE_H_ -#define PERMISSION_HANDLER_TYPE_H_ +// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. -// Keep in sync with the values defined in: -// https://github.com/Baseflow/flutter-permission-handler/blob/master/permission_handler_platform_interface/lib/src/permissions.dart -enum class PermissionGroup { +#ifndef FLUTTER_PLUGIN_PERMISSIONS_H_ +#define FLUTTER_PLUGIN_PERMISSIONS_H_ + +// Permissions that can be checked and requested. +// +// Originally defined in permissions.dart of the platform interface package. +enum class Permission { kCalendar = 0, kCamera = 1, kContacts = 2, @@ -37,16 +42,4 @@ enum class PermissionGroup { kBluetoothConnect = 30 }; -// permission status -enum class PermissionStatus { - kDenied = 0, - kGranted, - kRestricted, - kLimited, - kPermanentlyDenied -}; - -// service status -enum class ServiceStatus { kDisabled = 0, kEnabled, kNotApplicable }; - -#endif // PERMISSION_HANDLER_TYPE_H_ +#endif // FLUTTER_PLUGIN_PERMISSIONS_H_ diff --git a/packages/permission_handler/tizen/src/service_manager.cc b/packages/permission_handler/tizen/src/service_manager.cc index af000a671..fbbaf98aa 100644 --- a/packages/permission_handler/tizen/src/service_manager.cc +++ b/packages/permission_handler/tizen/src/service_manager.cc @@ -1,20 +1,15 @@ +// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + #include "service_manager.h" #include -#include "log.h" -#include "type.h" - -ServiceManager::ServiceManager() {} - -ServiceManager::~ServiceManager() {} - -void ServiceManager::CheckServiceStatus(PermissionGroup permission, - OnServiceChecked success_callback, - OnServiceError error_callback) { - if (permission == PermissionGroup::kLocation || - permission == PermissionGroup::kLocationAlways || - permission == PermissionGroup::kLocationWhenInUse) { +ServiceStatus ServiceManager::CheckServiceStatus(Permission permission) { + if (permission == Permission::kLocation || + permission == Permission::kLocationAlways || + permission == Permission::kLocationWhenInUse) { bool gps_enabled, wps_enabled; if (location_manager_is_enabled_method( LOCATIONS_METHOD_GPS, &gps_enabled) != LOCATIONS_ERROR_NONE) { @@ -26,12 +21,10 @@ void ServiceManager::CheckServiceStatus(PermissionGroup permission, } if (gps_enabled || wps_enabled) { - success_callback(ServiceStatus::kEnabled); + return ServiceStatus::kEnabled; } else { - success_callback(ServiceStatus::kDisabled); + return ServiceStatus::kDisabled; } - return; } - - success_callback(ServiceStatus::kNotApplicable); + return ServiceStatus::kNotApplicable; } diff --git a/packages/permission_handler/tizen/src/service_manager.h b/packages/permission_handler/tizen/src/service_manager.h index ea140cee6..b7ef70b05 100644 --- a/packages/permission_handler/tizen/src/service_manager.h +++ b/packages/permission_handler/tizen/src/service_manager.h @@ -1,23 +1,27 @@ -#ifndef SERVICE_MANAGER_H_ -#define SERVICE_MANAGER_H_ +// Copyright 2021 Samsung Electronics Co., Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. -#include -#include +#ifndef FLUTTER_PLUGIN_SERVICE_MANAGER_H_ +#define FLUTTER_PLUGIN_SERVICE_MANAGER_H_ -#include "type.h" +#include "permissions.h" -using OnServiceChecked = std::function; -using OnServiceError = - std::function; +// The status of a service associated with a specific permission. +// +// Originally defined in service_status.dart of the platform interface pacakge. +enum class ServiceStatus { + kDisabled = 0, + kEnabled = 1, + kNotApplicable = 2, +}; class ServiceManager { public: - ServiceManager(); - ~ServiceManager(); + ServiceManager() {} + ~ServiceManager() {} - void CheckServiceStatus(PermissionGroup permission, - OnServiceChecked success_callback, - OnServiceError error_callback); + ServiceStatus CheckServiceStatus(Permission permission); }; -#endif // SERVICE_MANAGER_H_ +#endif // FLUTTER_PLUGIN_SERVICE_MANAGER_H_