From: Piotr Kosko/Native/Web API (PLT) /SRPOL/Engineer/Samsung Electronics Date: Thu, 5 Dec 2019 14:18:12 +0000 (+0100) Subject: Merge branch 'tizen_4.0' into tizen_5.0 X-Git-Tag: submit/tizen_5.0/20200225.093921~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a512ea92f1623ab2a9353d2b2ed0cc050e8c5f17;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git Merge branch 'tizen_4.0' into tizen_5.0 Change-Id: I6272ee91b469df02a70c0ddea192ef9cc46b0123 --- a512ea92f1623ab2a9353d2b2ed0cc050e8c5f17 diff --cc packaging/webapi-plugins.spec index 8614f0b,11ce4ce..46a3a04 --- a/packaging/webapi-plugins.spec +++ b/packaging/webapi-plugins.spec @@@ -8,7 -8,7 +8,7 @@@ %define crosswalk_extensions_path %{_libdir}/%{crosswalk_extensions} Name: webapi-plugins - Version: 2.43 -Version: 2.39 ++Version: 2.44 Release: 0 License: Apache-2.0 and BSD-3-Clause and MIT Group: Development/Libraries diff --cc src/application/application_manager.cc index 840faaf,69e2a55..a4b3057 --- a/src/application/application_manager.cc +++ b/src/application/application_manager.cc @@@ -480,182 -534,111 +480,183 @@@ void ApplicationManager::LaunchAppContr return; } - int ret = app_control_set_launch_mode(app_control_ptr.get(), launch_mode); - if (APP_CONTROL_ERROR_NONE != ret) { - LogAndReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Setting launch mode failed."), - &response->get(), - ("Setting launch mode failed: %d (%s)", ret, get_error_message(ret))); - return; + picojson::value return_value = picojson::value(picojson::object()); + picojson::object& return_value_obj = return_value.get(); + return_value_obj.insert( + std::make_pair(kListenerId, picojson::value(callback_data->reply_callback_id))); + + if (APP_CONTROL_RESULT_SUCCEEDED == result) { + LoggerD("App started"); + return_value_obj.insert(std::make_pair("data", picojson::value(picojson::array()))); + if (!ApplicationUtils::ServiceToApplicationControlDataArray( + reply, &return_value_obj.find("data")->second.get())) { + return_value_obj.erase("data"); + } + ReportSuccess(return_value_obj); + } else { + ReportError(return_value_obj); } - } - app_control_reply_cb callback = nullptr; - struct ReplayCallbackData { - ApplicationInstance* app_instance; - std::string reply_callback; + Instance::PostMessage(callback_data->instance, return_value.serialize().c_str()); + delete callback_data; }; + } - ReplayCallbackData* user_data = nullptr; - - if (!reply_callback.empty()) { - user_data = new ReplayCallbackData(); - user_data->app_instance = &this->instance_; - user_data->reply_callback = reply_callback; - - callback = [](app_control_h request, app_control_h reply, app_control_result_e result, - void* user_data) { - LoggerD("send_launch_request callback"); - - picojson::value return_value = picojson::value(picojson::object()); - picojson::object& return_value_obj = return_value.get(); - ReplayCallbackData* reply_callback = static_cast(user_data); - - if (APP_CONTROL_RESULT_SUCCEEDED == result) { - const std::string data = "data"; - return_value_obj.insert(std::make_pair(data, picojson::value(picojson::array()))); - if (!ApplicationUtils::ServiceToApplicationControlDataArray( - reply, &return_value_obj.find(data)->second.get())) { - return_value_obj.erase(data); - } - ReportSuccess(return_value_obj); - } else { - ReportError(return_value_obj); - } + app_control_result_cb result_callback = [](app_control_h launch_request, + app_control_error_e launch_result, void* user_data) { + ScopeLogger("LaunchAppControl result_callback"); - return_value_obj.insert( - std::make_pair("listenerId", picojson::value(reply_callback->reply_callback))); - Instance::PostMessage(reply_callback->app_instance, return_value.serialize().c_str()); - delete reply_callback; - }; + LaunchAppControlCallbackData* callback_data = + static_cast(user_data); + + auto result = ApplicationUtils::TranslateAppControlError(launch_result); + + if (result.IsError()) { + LogAndReportError(result, &(callback_data->response->get())); + } else { + ReportSuccess(callback_data->response->get()); } - const int retry_count = 3; + Instance::PostMessage(callback_data->instance, callback_data->response->serialize().c_str()); - int retry = 0; - int ret = 0; + if (result.IsError() || (callback_data->reply_callback_id).empty()) { + delete callback_data; + } + }; - while (retry < retry_count) { - LoggerD("Calling launch request. Attempt number: %d", retry); + /* + * TODO: Observe how often app_control_send_launch_request_async tries to launch the application. + * Previous implementation, using synchronous app_control_send_launch_request, + * tries to launch the application 3 times, before reporting an error. + * New implementation, using app_control_send_launch_request_async makes only one attempt. + * If problems, such as failed application start occur, multiple attempts may solve the problem. + */ - auto launch_result = - ApplicationUtils::TranslateAppControlError(static_cast(app_control_send_launch_request_async( ++ auto launch_result = ApplicationUtils::TranslateAppControlError( ++ static_cast(app_control_send_launch_request_async( + app_control_ptr.get(), result_callback, reply_callback, launch_app_user_data))); + + if (launch_result.IsError()) { + delete launch_app_user_data; + AsyncResponse(launch_result, &response); + } else { + LoggerD("App launched"); + } +} - ret = app_control_send_launch_request(app_control_ptr.get(), callback, user_data); - LoggerD("App control launch request returned: %d, %s", ret, get_error_message(ret)); - if (APP_CONTROL_ERROR_NONE == ret) { - break; - } +namespace { - // delay 300ms for each retry - struct timespec sleep_time = {0, 300L * 1000L * 1000L}; - nanosleep(&sleep_time, nullptr); - ++retry; - } +PlatformResult TranslateLaunchError(app_control_error_e return_code) { + ScopeLogger(); + + auto result = ApplicationUtils::TranslateAppControlError(return_code); + if (ErrorCode::SECURITY_ERR == result.error_code()) { + result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."); + } + + return result; +} + +PlatformResult PrepareAppControlForLaunch(const picojson::value& args, app_control_h* app_control) { + ScopeLogger(); + + const auto& app_id = args.get("id"); + if (!app_id.is()) { + return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."); + } + const auto app_id_str = app_id.get(); + + app_control_h tmp_app_control = nullptr; + int result = app_control_create(&tmp_app_control); + if (APP_CONTROL_ERROR_NONE != result) { + LoggerD("app_control_create() failed: %d (%s)", result, get_error_message(result)); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error occurred."); + } + + std::unique_ptr::type, decltype(&app_control_destroy)> + app_control_ptr(tmp_app_control, &app_control_destroy); + + if (!app_id_str.empty()) { + LoggerD("app_id: %s", app_id_str.c_str()); + + int ret = app_control_set_app_id(app_control_ptr.get(), app_id_str.c_str()); if (APP_CONTROL_ERROR_NONE != ret) { - delete user_data; - - switch (ret) { - case APP_CONTROL_ERROR_INVALID_PARAMETER: - LogAndReportError( - PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter returned."), - &response->get(), - ("app_control_send_launch_request returns APP_CONTROL_ERROR_INVALID_PARAMETER")); - return; - case APP_CONTROL_ERROR_OUT_OF_MEMORY: - LogAndReportError( - PlatformResult(ErrorCode::UNKNOWN_ERR, "Out of memory."), - &response->get(), - ("app_control_send_launch_request returns APP_CONTROL_ERROR_OUT_OF_MEMORY")); - return; - case APP_CONTROL_ERROR_LAUNCH_REJECTED: - case APP_CONTROL_ERROR_APP_NOT_FOUND: - LogAndReportError( - PlatformResult(ErrorCode::NOT_FOUND_ERR, "No matched application found."), - &response->get(), - ("app_control_send_launch_request returns APP_CONTROL_ERROR_APP_NOT_FOUND")); - return; - default: - LogAndReportError( - PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), - &response->get(), - ("app_control_send_launch_request returns: %d (%s)", ret, get_error_message(ret))); - return; - } + LoggerE("Failed to set app id: %d (%s)", ret, get_error_message(ret)); + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."); } - ReportSuccess(response->get()); + } + + *app_control = app_control_ptr.release(); + + return PlatformResult(ErrorCode::NO_ERROR); +} + +} // namespace +void ApplicationManager::Launch(const picojson::value& args) { + ScopeLogger(); + + int callback_id = -1; + const auto& callback = args.get(kCallbackId); + if (callback.is()) { + callback_id = static_cast(callback.get()); + } + + std::shared_ptr response(new picojson::value(picojson::object())); + picojson::object& response_obj = response->get(); + response_obj.insert( + std::make_pair(kCallbackId, picojson::value(static_cast(callback_id)))); + + app_control_h app_control = nullptr; + auto prepare_app_control_result = PrepareAppControlForLaunch(args, &app_control); + if (prepare_app_control_result.IsError()) { + AsyncResponse(LogAndCreateResult(prepare_app_control_result), &response); + return; + } + + std::unique_ptr::type, decltype(&app_control_destroy)> + app_control_ptr(app_control, &app_control_destroy); + + struct LaunchCallbackData { + ApplicationInstance* instance; + std::shared_ptr response; + }* launch_user_data = new (std::nothrow) LaunchCallbackData{&this->instance_, response}; + + app_control_result_cb result_callback = [](app_control_h launch_request, + app_control_error_e launch_result, void* user_data) { + ScopeLogger("Launch result_callback"); + + LaunchCallbackData* callback_data = static_cast(user_data); + + auto result = TranslateLaunchError(launch_result); + + if (result.IsError()) { + LogAndReportError(result, &(callback_data->response->get())); + } else { + ReportSuccess(callback_data->response->get()); + } + + Instance::PostMessage(callback_data->instance, callback_data->response->serialize().c_str()); + + delete callback_data; }; - launch(response); - Instance::PostMessage(&this->instance_, response->serialize().c_str()); + /* + * TODO: Observe how often app_control_send_launch_request_async tries to launch the application. + * Previous implementation, using synchronous app_control_send_launch_request, + * tries to launch the application 3 times, before reporting an error. + * New implementation, using app_control_send_launch_request_async makes only one attempt. + * If problems, such as failed application start occur, multiple attempts may solve the problem. + */ - auto launch_result = TranslateLaunchError(static_cast(app_control_send_launch_request_async( - app_control_ptr.get(), result_callback, nullptr, launch_user_data))); ++ auto launch_result = ++ TranslateLaunchError(static_cast(app_control_send_launch_request_async( ++ app_control_ptr.get(), result_callback, nullptr, launch_user_data))); + + if (launch_result.IsError()) { + delete launch_user_data; + AsyncResponse(launch_result, &response); + } else { + LoggerD("App launched"); + } } // internal impl of app_control_foreach_app_matched() for handling APP_CONTROL_ERROR_APP_NOT_FOUND diff --cc src/application/application_utils.cc index 3fbeeba,596d292..27dfa61 --- a/src/application/application_utils.cc +++ b/src/application/application_utils.cc @@@ -383,37 -265,21 +383,38 @@@ PlatformResult ApplicationUtils::Applic const std::string& key = it_key->second.get(); const picojson::array& value = it_value->second.get(); - const size_t size = value.size(); - const char** arr = new const char*[size]; - size_t i = 0; + std::vector value_data; - for (auto iter = value.begin(); iter != value.end(); ++iter, ++i) { - arr[i] = iter->get().c_str(); + for (auto& v : value) { + value_data.push_back(v.get().c_str()); } - if (1 == size) { - app_control_add_extra_data(app_control, key.c_str(), arr[0]); + int result = APP_CONTROL_ERROR_NONE; + /* + * Native applications handle single extra data objects and arrays in a different ways, + * hence they have to be packed with different native API functions. + */ + if (1 == value_data.size()) { + result = app_control_add_extra_data(app_control, key.c_str(), value_data[0]); } else { - result = app_control_add_extra_data_array(app_control, key.c_str(), value_data.data(), value_data.size()); - app_control_add_extra_data_array(app_control, key.c_str(), arr, size); ++ result = app_control_add_extra_data_array(app_control, key.c_str(), value_data.data(), ++ value_data.size()); + } + + if (APP_CONTROL_ERROR_INVALID_PARAMETER == result) { + if (0 == key.length()) { + LoggerD("app_control_add_extra_data_array failed: zero-length key"); + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, + "Invalid AppControlData key: key length is 0."); + } + LoggerD("app_control_add_extra_data_array failed: invalid parameter passed"); + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, + "Invalid AppControlData value, associated with key: " + key); + } else if (APP_CONTROL_ERROR_KEY_REJECTED == result) { + LoggerD("app_control_add_extra_data_array failed: key rejected"); + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid AppControlData's key: " + key); } - delete[] arr; return PlatformResult(ErrorCode::NO_ERROR); } diff --cc src/common/platform_enum.h index 6c62695,0000000..a7e22ca mode 100644,000000..100644 --- a/src/common/platform_enum.h +++ b/src/common/platform_enum.h @@@ -1,81 -1,0 +1,77 @@@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COMMON_PLATFORM_ENUM_H_ +#define COMMON_PLATFORM_ENUM_H_ + +#include "platform_result.h" + - #include ++#include +#include ++#include +#include - #include - + +namespace common { + ++template ++class PlatformEnum { ++ using MapType = std::map; ++ using RevMapType = std::map; + - template - class PlatformEnum - { - using MapType = std::map; - using RevMapType = std::map; - - using MapTypeConstIter = typename MapType::const_iterator; ++ using MapTypeConstIter = typename MapType::const_iterator; + - public: - PlatformEnum(std::initializer_list> m) : mapping_(m) { - for (auto it: mapping_) { ++ public: ++ PlatformEnum(std::initializer_list> m) ++ : mapping_(m) { ++ for (auto it : mapping_) { + rev_mapping_[it.second] = it.first; + } + } + + PlatformResult getName(NativeEnumType value, std::string* name) const { + auto it = rev_mapping_.find(value); + if (it != rev_mapping_.end()) { + *name = it->second; + return PlatformResult(ErrorCode::NO_ERROR); + } + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "enum value not registered"); + } + + PlatformResult getValue(std::string name, NativeEnumType* value) const { + auto it = mapping_.find(name); + if (it != mapping_.end()) { + *value = it->second; + return PlatformResult(ErrorCode::NO_ERROR); + } + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "enum name not registered"); + } + + MapTypeConstIter begin() const { + return mapping_.cbegin(); + } + + MapTypeConstIter end() const { + return mapping_.cend(); + } + - private: ++ private: + MapType mapping_; + RevMapType rev_mapping_; +}; + ++} // common + - } // common - - - #endif // COMMON_PLATFORM_ENUM_H_ ++#endif // COMMON_PLATFORM_ENUM_H_ diff --cc src/mediacontroller/mediacontroller_client.cc index 05effb8,cce90a2..cee9325 --- a/src/mediacontroller/mediacontroller_client.cc +++ b/src/mediacontroller/mediacontroller_client.cc @@@ -41,12 -38,6 +41,12 @@@ MediaControllerClient::MediaControllerC MediaControllerClient::~MediaControllerClient() { ScopeLogger(); + int ret = mc_client_unset_cmd_reply_received_cb(handle_); + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { - LoggerE("Failed to unset cmd reply callback. Error code: %d; Error message: %s", - ret, get_error_message(ret)); ++ LoggerE("Failed to unset cmd reply callback. Error code: %d; Error message: %s", ret, ++ get_error_message(ret)); + } + if (nullptr != server_status_listener_ && !UnsetServerStatusChangeListener()) { LoggerE("Failed to unset server status change listener"); } @@@ -69,13 -60,6 +69,14 @@@ PlatformResult MediaControllerClient::I ("mc_client_create() error: %d, message: %s", ret, get_error_message(ret))); } + ret = mc_client_set_cmd_reply_received_cb(handle_, OnCommandReply, this); + if (MEDIA_CONTROLLER_ERROR_NONE != ret) { - return LogAndCreateResult( - ErrorCode::UNKNOWN_ERR, "Unable to register cmd reply received callback", - ("mc_client_set_cmd_reply_received_cb() error: %d, message: %s", ret, get_error_message(ret))); ++ return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, ++ "Unable to register cmd reply received callback", ++ ("mc_client_set_cmd_reply_received_cb() error: %d, message: %s", ret, ++ get_error_message(ret))); + } + return PlatformResult(ErrorCode::NO_ERROR); } @@@ -471,8 -457,8 +472,7 @@@ void MediaControllerClient::OnMetadataU PlatformResult MediaControllerClient::SendCommand(const std::string& server_name, const std::string& command, const picojson::value& data, - const JsonCallback& reply_cb, - char** request_id) { - const std::string& reply_id, - const JsonCallback& reply_cb) { ++ const JsonCallback& reply_cb, char** request_id) { ScopeLogger(); bundle* bundle = bundle_create(); SCOPE_EXIT { @@@ -487,7 -480,8 +487,8 @@@ ("bundle_add(data) error: %d, message: %s", ret, get_error_message(ret))); } - ret = mc_client_send_custom_cmd(handle_, server_name.c_str(), command.c_str(), bundle, request_id); - ret = mc_client_send_custom_command(handle_, server_name.c_str(), command.c_str(), bundle, - OnCommandReply, this); ++ ret = ++ mc_client_send_custom_cmd(handle_, server_name.c_str(), command.c_str(), bundle, request_id); if (MEDIA_CONTROLLER_ERROR_NONE != ret) { return LogAndCreateResult( ErrorCode::UNKNOWN_ERR, "Error sending custom command", diff --cc src/mediacontroller/mediacontroller_client.h index e0e669d,bb7cb8a..d226e3f --- a/src/mediacontroller/mediacontroller_client.h +++ b/src/mediacontroller/mediacontroller_client.h @@@ -66,8 -66,8 +66,8 @@@ class MediaControllerClient static void OnServerStatusUpdate(const char* server_name, mc_server_state_e state, void* user_data); - static void OnCommandReply(const char* server_name, const char* request_id, - int result_code, bundle* bundle, void* user_data); - static void OnCommandReply(const char* server_name, int result_code, bundle* bundle, - void* user_data); ++ static void OnCommandReply(const char* server_name, const char* request_id, int result_code, ++ bundle* bundle, void* user_data); static void OnPlaybackUpdate(const char* server_name, mc_playback_h playback, void* user_data); static void OnShuffleModeUpdate(const char* server_name, mc_shuffle_mode_e mode, void* user_data); static void OnRepeatModeUpdate(const char* server_name, mc_repeat_mode_e mode, void* user_data); diff --cc src/mediacontroller/mediacontroller_instance.cc index ab7d8aa,350c4d6..1bf4a74 --- a/src/mediacontroller/mediacontroller_instance.cc +++ b/src/mediacontroller/mediacontroller_instance.cc @@@ -19,9 -19,8 +19,9 @@@ #include "common/logger.h" #include "common/picojson.h" #include "common/platform_result.h" ++#include "common/scope_exit.h" #include "common/task-queue.h" #include "common/tools.h" - #include "common/scope_exit.h" #include "mediacontroller/mediacontroller_types.h" @@@ -318,18 -317,11 +318,16 @@@ void MediaControllerInstance::MediaCont } CHECK_EXIST(args, "clientName", out) - CHECK_EXIST(args, "replyId", out) + CHECK_EXIST(args, "requestId", out) CHECK_EXIST(args, "data", out) - auto result = server_->CommandReply( - args.get("clientName").get(), - args.get("requestId").get(), - args.get("data")); - server_->CommandReply(args.get("clientName").get(), args.get("replyId").to_str(), - args.get("data")); ++ auto result = server_->CommandReply(args.get("clientName").get(), ++ args.get("requestId").get(), args.get("data")); + + if (!result) { + LogAndReportError(result, &out); + return; + } ReportSuccess(out); } @@@ -608,17 -602,10 +606,14 @@@ void MediaControllerInstance::MediaCont Instance::PostMessage(this, reply->serialize().c_str()); }; - PlatformResult result = client_->SendCommand( - args.get("name").get(), args.get("command").get(), args.get("data"), - args.get("replyId").to_str(), reply_cb); + char* request_id = nullptr; + SCOPE_EXIT { + free(request_id); + }; + - PlatformResult result = client_->SendCommand( - args.get("name").get(), - args.get("command").get(), - args.get("data"), - reply_cb, - &request_id); ++ PlatformResult result = client_->SendCommand(args.get("name").get(), ++ args.get("command").get(), ++ args.get("data"), reply_cb, &request_id); if (result) { ReportSuccess(out); diff --cc src/mediacontroller/mediacontroller_server.cc index dc82787,b2a3e83..622bfa7 --- a/src/mediacontroller/mediacontroller_server.cc +++ b/src/mediacontroller/mediacontroller_server.cc @@@ -203,8 -207,8 +203,9 @@@ PlatformResult MediaControllerServer::S return PlatformResult(ErrorCode::NO_ERROR); } -void MediaControllerServer::OnCommandReceived(const char* client_name, const char* command, - bundle* bundle, void* user_data) { +void MediaControllerServer::OnCommandReceived(const char* client_name, const char* request_id, - const char* command, bundle* bundle, void* user_data) { ++ const char* command, bundle* bundle, ++ void* user_data) { ScopeLogger(); MediaControllerServer* server = static_cast(user_data); @@@ -271,11 -291,11 +272,11 @@@ PlatformResult MediaControllerServer::C PlatformResult MediaControllerServer::SetCommandListener(const JsonCallback& callback) { ScopeLogger(); - int ret = mc_server_set_custom_command_received_cb(handle_, OnCommandReceived, this); + int ret = mc_server_set_custom_cmd_received_cb(handle_, OnCommandReceived, this); if (MEDIA_CONTROLLER_ERROR_NONE != ret) { return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Unable to set command callback", - ("mc_server_set_custom_cmd_received_cb() error: %d, message: %s", - ("mc_server_set_custom_command_received_cb() error: %d, message: %s", -- ret, get_error_message(ret))); ++ ("mc_server_set_custom_cmd_received_cb() error: %d, message: %s", ret, ++ get_error_message(ret))); } command_listener_ = callback; @@@ -407,23 -425,16 +408,25 @@@ void MediaControllerServer::OnPlaybackA MediaControllerServer* server = static_cast(user_data); - if (server->playback_state_ == state_e) { - LoggerD("The media playback state did not change, skipping"); + // Here, we need to convert mc_playback_action_e enum to mc_playback_states_e enum. + std::string action_str; + PlatformResult result = types::MediaControllerPlaybackActionEnum.getName(action, &action_str); + if (!result) { - LoggerW("MediaControllerPlaybackActionEnum.getName() failed, error: %s", result.message().c_str()); ++ LoggerW("MediaControllerPlaybackActionEnum.getName() failed, error: %s", ++ result.message().c_str()); return; } - std::string state; - PlatformResult result = Types::PlatformEnumToString(Types::kMediaControllerPlaybackState, - static_cast(state_e), &state); + mc_playback_states_e state_e; + result = types::MediaControllerPlaybackStateEnum.getValue(action_str, &state_e); if (!result) { - LoggerE("MediaControllerPlaybackStateEnum.getValue() failed, error: %s", result.message().c_str()); - LoggerE("PlatformEnumToString failed, error: %s", result.message().c_str()); ++ LoggerE("MediaControllerPlaybackStateEnum.getValue() failed, error: %s", ++ result.message().c_str()); + return; + } + + if (server->playback_state_ == state_e) { + LoggerD("The media playback state did not change, skipping"); return; } diff --cc src/mediacontroller/mediacontroller_types.cc index 4e9cde1,f56c431..eb93147 --- a/src/mediacontroller/mediacontroller_types.cc +++ b/src/mediacontroller/mediacontroller_types.cc @@@ -28,77 -28,104 +28,66 @@@ namespace mediacontroller using common::PlatformResult; using common::ErrorCode; -const std::string Types::kMediaControllerServerState = "MediaControllerServerState"; -const std::string Types::kMediaControllerPlaybackState = "MediaControllerPlaybackState"; -const std::string Types::kMediaControllerMetadataAttribute = "MediaControllerMetadataAttribute"; - -const PlatformEnumMap Types::platform_enum_map_ = {{kMediaControllerServerState, - {{"NONE", MC_SERVER_STATE_NONE}, - {"ACTIVE", MC_SERVER_STATE_ACTIVATE}, - {"INACTIVE", MC_SERVER_STATE_DEACTIVATE}}}, - {kMediaControllerPlaybackState, - {{"PLAY", MC_PLAYBACK_STATE_PLAYING}, - {"PAUSE", MC_PLAYBACK_STATE_PAUSED}, - {"STOP", MC_PLAYBACK_STATE_STOPPED}, - {"NEXT", MC_PLAYBACK_STATE_NEXT_FILE}, - {"PREV", MC_PLAYBACK_STATE_PREV_FILE}, - {"FORWARD", MC_PLAYBACK_STATE_FAST_FORWARD}, - {"REWIND", MC_PLAYBACK_STATE_REWIND}}}, - {kMediaControllerMetadataAttribute, - {{"title", MC_META_MEDIA_TITLE}, - {"artist", MC_META_MEDIA_ARTIST}, - {"album", MC_META_MEDIA_ALBUM}, - {"author", MC_META_MEDIA_AUTHOR}, - {"genre", MC_META_MEDIA_GENRE}, - {"duration", MC_META_MEDIA_DURATION}, - {"date", MC_META_MEDIA_DATE}, - {"copyright", MC_META_MEDIA_COPYRIGHT}, - {"description", MC_META_MEDIA_DESCRIPTION}, - {"trackNum", MC_META_MEDIA_TRACK_NUM}, - {"picture", MC_META_MEDIA_PICTURE}}}}; - -PlatformEnumReverseMap Types::platform_enum_reverse_map_ = {}; - -PlatformResult Types::GetPlatformEnumMap(const std::string& type, - std::map* enum_map) { - ScopeLogger(); - - auto iter = platform_enum_map_.find(type); - if (iter == platform_enum_map_.end()) { - return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, - std::string("Undefined platform enum type ") + type); - } - - *enum_map = platform_enum_map_.at(type); - - return PlatformResult(ErrorCode::NO_ERROR); -} - -PlatformResult Types::StringToPlatformEnum(const std::string& type, const std::string& value, - int* platform_enum) { - ScopeLogger(); - - std::map def; - PlatformResult result = GetPlatformEnumMap(type, &def); - if (!result) { - return result; - } - - auto def_iter = def.find(value); - if (def_iter != def.end()) { - *platform_enum = def_iter->second; - return PlatformResult(ErrorCode::NO_ERROR); - } - - std::string message = "Platform enum value " + value + " not found for " + type; - return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, message); -} - -PlatformResult Types::PlatformEnumToString(const std::string& type, int value, - std::string* platform_str) { - ScopeLogger(); - - if (platform_enum_reverse_map_.empty()) { - for (auto& def : platform_enum_map_) { - platform_enum_reverse_map_[def.first] = {}; - - for (auto& key : def.second) { - platform_enum_reverse_map_[def.first][key.second] = key.first; - } - } - } - - auto it = platform_enum_reverse_map_.find(type); - if (it == platform_enum_reverse_map_.end()) { - return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, - std::string("Undefined platform enum type ") + type); - } - - auto def = platform_enum_reverse_map_.at(type); - auto def_it = def.find(value); - if (def_it != def.end()) { - *platform_str = def_it->second; - return PlatformResult(ErrorCode::NO_ERROR); - } - - std::string message = "Platform enum value " + std::to_string(value) + " not found for " + type; - return LogAndCreateResult(ErrorCode::INVALID_VALUES_ERR, message); -} - -PlatformResult Types::ConvertPlaybackState(mc_playback_h playback_h, std::string* state) { +namespace types { + - const common::PlatformEnum MediaControllerServerStateEnum { ++const common::PlatformEnum MediaControllerServerStateEnum{ + {"NONE", MC_SERVER_STATE_NONE}, + {"ACTIVE", MC_SERVER_STATE_ACTIVATE}, - {"INACTIVE", MC_SERVER_STATE_DEACTIVATE} - }; ++ {"INACTIVE", MC_SERVER_STATE_DEACTIVATE}}; + - const common::PlatformEnum MediaControllerPlaybackStateEnum { ++const common::PlatformEnum MediaControllerPlaybackStateEnum{ + {"PLAY", MC_PLAYBACK_STATE_PLAYING}, + {"PAUSE", MC_PLAYBACK_STATE_PAUSED}, + {"STOP", MC_PLAYBACK_STATE_STOPPED}, + {"NEXT", MC_PLAYBACK_STATE_MOVING_TO_NEXT}, + {"PREV", MC_PLAYBACK_STATE_MOVING_TO_PREVIOUS}, + {"FORWARD", MC_PLAYBACK_STATE_FAST_FORWARDING}, - {"REWIND", MC_PLAYBACK_STATE_REWINDING} - }; - - const common::PlatformEnum MediaControllerPlaybackActionEnum { - {"PLAY", MC_PLAYBACK_ACTION_PLAY}, - {"PAUSE", MC_PLAYBACK_ACTION_PAUSE}, - {"STOP", MC_PLAYBACK_ACTION_STOP}, - {"NEXT", MC_PLAYBACK_ACTION_NEXT}, - {"PREV", MC_PLAYBACK_ACTION_PREV}, - {"FORWARD", MC_PLAYBACK_ACTION_FAST_FORWARD}, - {"REWIND", MC_PLAYBACK_ACTION_REWIND} - }; - - const common::PlatformEnum MediaControllerMetadataAttributeEnum { ++ {"REWIND", MC_PLAYBACK_STATE_REWINDING}}; ++ ++const common::PlatformEnum MediaControllerPlaybackActionEnum{ ++ {"PLAY", MC_PLAYBACK_ACTION_PLAY}, {"PAUSE", MC_PLAYBACK_ACTION_PAUSE}, ++ {"STOP", MC_PLAYBACK_ACTION_STOP}, {"NEXT", MC_PLAYBACK_ACTION_NEXT}, ++ {"PREV", MC_PLAYBACK_ACTION_PREV}, {"FORWARD", MC_PLAYBACK_ACTION_FAST_FORWARD}, ++ {"REWIND", MC_PLAYBACK_ACTION_REWIND}}; ++ ++const common::PlatformEnum MediaControllerMetadataAttributeEnum{ + {"title", MC_META_MEDIA_TITLE}, + {"artist", MC_META_MEDIA_ARTIST}, + {"album", MC_META_MEDIA_ALBUM}, + {"author", MC_META_MEDIA_AUTHOR}, + {"genre", MC_META_MEDIA_GENRE}, + {"duration", MC_META_MEDIA_DURATION}, + {"date", MC_META_MEDIA_DATE}, + {"copyright", MC_META_MEDIA_COPYRIGHT}, + {"description", MC_META_MEDIA_DESCRIPTION}, + {"trackNum", MC_META_MEDIA_TRACK_NUM}, - {"picture", MC_META_MEDIA_PICTURE} - }; ++ {"picture", MC_META_MEDIA_PICTURE}}; + - const common::PlatformEnum MediaControllerRepeatModeEnum { ++const common::PlatformEnum MediaControllerRepeatModeEnum{ + {"REPEAT_OFF", MC_REPEAT_MODE_OFF}, + {"REPEAT_ONE", MC_REPEAT_MODE_ONE_MEDIA}, - {"REPEAT_ALL", MC_REPEAT_MODE_ON} - }; - - const common::PlatformEnum MediaControllerContentAgeRatingEnum { - {"ALL", MC_CONTENT_RATING_ALL}, {"1", MC_CONTENT_RATING_1_PLUS}, - {"2", MC_CONTENT_RATING_2_PLUS}, {"3", MC_CONTENT_RATING_3_PLUS}, - {"4", MC_CONTENT_RATING_4_PLUS}, {"5", MC_CONTENT_RATING_5_PLUS}, - {"6", MC_CONTENT_RATING_6_PLUS}, {"7", MC_CONTENT_RATING_7_PLUS}, - {"8", MC_CONTENT_RATING_8_PLUS}, {"9", MC_CONTENT_RATING_9_PLUS}, - {"10", MC_CONTENT_RATING_10_PLUS}, {"11", MC_CONTENT_RATING_11_PLUS}, - {"12", MC_CONTENT_RATING_12_PLUS}, {"13", MC_CONTENT_RATING_13_PLUS}, - {"14", MC_CONTENT_RATING_14_PLUS}, {"15", MC_CONTENT_RATING_15_PLUS}, - {"16", MC_CONTENT_RATING_16_PLUS}, {"17", MC_CONTENT_RATING_17_PLUS}, - {"18", MC_CONTENT_RATING_18_PLUS}, {"19", MC_CONTENT_RATING_19_PLUS} - }; - - const common::PlatformEnum MediaControllerContentTypeEnum { ++ {"REPEAT_ALL", MC_REPEAT_MODE_ON}}; ++ ++const common::PlatformEnum MediaControllerContentAgeRatingEnum{ ++ {"ALL", MC_CONTENT_RATING_ALL}, {"1", MC_CONTENT_RATING_1_PLUS}, ++ {"2", MC_CONTENT_RATING_2_PLUS}, {"3", MC_CONTENT_RATING_3_PLUS}, ++ {"4", MC_CONTENT_RATING_4_PLUS}, {"5", MC_CONTENT_RATING_5_PLUS}, ++ {"6", MC_CONTENT_RATING_6_PLUS}, {"7", MC_CONTENT_RATING_7_PLUS}, ++ {"8", MC_CONTENT_RATING_8_PLUS}, {"9", MC_CONTENT_RATING_9_PLUS}, ++ {"10", MC_CONTENT_RATING_10_PLUS}, {"11", MC_CONTENT_RATING_11_PLUS}, ++ {"12", MC_CONTENT_RATING_12_PLUS}, {"13", MC_CONTENT_RATING_13_PLUS}, ++ {"14", MC_CONTENT_RATING_14_PLUS}, {"15", MC_CONTENT_RATING_15_PLUS}, ++ {"16", MC_CONTENT_RATING_16_PLUS}, {"17", MC_CONTENT_RATING_17_PLUS}, ++ {"18", MC_CONTENT_RATING_18_PLUS}, {"19", MC_CONTENT_RATING_19_PLUS}}; ++ ++const common::PlatformEnum MediaControllerContentTypeEnum{ + {"IMAGE", MC_CONTENT_TYPE_IMAGE}, + {"MUSIC", MC_CONTENT_TYPE_MUSIC}, + {"VIDEO", MC_CONTENT_TYPE_VIDEO}, + {"OTHER", MC_CONTENT_TYPE_OTHER}, - {"UNDECIDED", MC_CONTENT_TYPE_UNDECIDED} - }; - ++ {"UNDECIDED", MC_CONTENT_TYPE_UNDECIDED}}; + +PlatformResult ConvertPlaybackState(mc_playback_h playback_h, std::string* state) { ScopeLogger(); int ret; @@@ -113,9 -140,10 +102,10 @@@ state_e = MC_PLAYBACK_STATE_STOPPED; } - PlatformResult result = Types::PlatformEnumToString(Types::kMediaControllerPlaybackState, - static_cast(state_e), state); + PlatformResult result = MediaControllerPlaybackStateEnum.getName(state_e, state); if (!result) { - LoggerE("MediaControllerPlaybackStateEnum.getName() failed, error: %s", result.message().c_str()); - LoggerE("PlatformEnumToString failed, error: %s", result.message().c_str()); ++ LoggerE("MediaControllerPlaybackStateEnum.getName() failed, error: %s", ++ result.message().c_str()); return result; } @@@ -148,22 -184,19 +138,21 @@@ PlatformResult ConvertMetadata(mc_metad free(value); }; - for (auto entry: MediaControllerMetadataAttributeEnum) { - for (auto& field : metadata_fields) { - int ret = mc_client_get_metadata(metadata_h, static_cast(field.second), &value); ++ for (auto entry : MediaControllerMetadataAttributeEnum) { + int ret = mc_metadata_get(metadata_h, entry.second, &value); if (ret != MEDIA_CONTROLLER_ERROR_NONE) { return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error getting metadata", - ("mc_client_get_metadata(%s) error: %d, message: %s", - field.first.c_str(), ret, get_error_message(ret))); + ("mc_metadata_get(%s) error: %d, message: %s", entry.first.c_str(), + ret, get_error_message(ret))); } - (*metadata)[field.first] = picojson::value(std::string(value ? value : "")); + (*metadata)[entry.first] = picojson::value(std::string(value ? value : "")); } return PlatformResult(ErrorCode::NO_ERROR); } - } // types - ++} // types + } // namespace mediacontroller } // namespace extension diff --cc src/mediacontroller/mediacontroller_types.h index 6b9eeab,20966aa..51de289 --- a/src/mediacontroller/mediacontroller_types.h +++ b/src/mediacontroller/mediacontroller_types.h @@@ -22,33 -22,39 +22,31 @@@ #include #include - #include "common/platform_result.h" +#include "common/platform_enum.h" - + #include "common/platform_result.h" namespace extension { namespace mediacontroller { -typedef std::map> PlatformEnumMap; -typedef std::map> PlatformEnumReverseMap; typedef std::function JsonCallback; -class Types { - public: - static const std::string kMediaControllerServerState; - static const std::string kMediaControllerPlaybackState; - static const std::string kMediaControllerMetadataAttribute; +namespace types { - static common::PlatformResult GetPlatformEnumMap(const std::string& type, - std::map* platform_str); +common::PlatformResult ConvertPlaybackState(mc_playback_h playback_h, std::string* state); +common::PlatformResult ConvertContentAgeRating(mc_playback_h playback_h, std::string* state); +common::PlatformResult ConvertPlaybackPosition(mc_playback_h playback_h, double* position); +common::PlatformResult ConvertMetadata(mc_metadata_h metadata_h, picojson::object* metadata); +common::PlatformResult ConvertContentType(mc_playback_h playback_h, std::string* contentType); - static common::PlatformResult StringToPlatformEnum(const std::string& type, - const std::string& value, int* platform_enum); +extern const common::PlatformEnum MediaControllerServerStateEnum; +extern const common::PlatformEnum MediaControllerPlaybackStateEnum; +extern const common::PlatformEnum MediaControllerPlaybackActionEnum; +extern const common::PlatformEnum MediaControllerMetadataAttributeEnum; +extern const common::PlatformEnum MediaControllerRepeatModeEnum; +extern const common::PlatformEnum MediaControllerContentAgeRatingEnum; +extern const common::PlatformEnum MediaControllerContentTypeEnum; - } // namespace types - static common::PlatformResult PlatformEnumToString(const std::string& type, int value, - std::string* platform_str); - - static common::PlatformResult ConvertPlaybackState(mc_playback_h playback_h, std::string* state); - static common::PlatformResult ConvertPlaybackPosition(mc_playback_h playback_h, double* position); - static common::PlatformResult ConvertMetadata(mc_metadata_h metadata_h, - picojson::object* metadata); -- - private: - static const PlatformEnumMap platform_enum_map_; - static PlatformEnumReverseMap platform_enum_reverse_map_; -}; ++} // namespace types } // namespace mediacontroller } // namespace extension