From: Piotr Kosko Date: Tue, 30 Aug 2016 12:44:19 +0000 (+0200) Subject: [Push] Added stubs for second implementation for Tizen 3.0 apps X-Git-Tag: submit/tizen_3.0/20161102.040156~3^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6252e7a1ade1d13a56c54a8c60e46d94b8ff7e72;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Push] Added stubs for second implementation for Tizen 3.0 apps [Feature] Modifications in super class, added stubs for tizen 3.0 push implementation, renamed files for old implementation. Added using different PushManager depending on application version. [Verification] Code compiles without errors. TCT passrate was not changed. Change-Id: I253bace6364aa41d3834bb76886817cba3ee3640 Signed-off-by: Piotr Kosko --- diff --git a/src/common/tools.cc b/src/common/tools.cc index 9b468847..d961c50c 100644 --- a/src/common/tools.cc +++ b/src/common/tools.cc @@ -368,6 +368,46 @@ PlatformResult GetPkgApiVersion(std::string* api_version) { return PlatformResult(ErrorCode::NO_ERROR); } +std::vector SplitString(const std::string& str, const std::string& delim) { + std::vector tokens; + size_t prev = 0, pos = 0; + do + { + pos = str.find(delim, prev); + if (pos == std::string::npos) pos = str.length(); + std::string token = str.substr(prev, pos-prev); + if (!token.empty()) tokens.push_back(token); + prev = pos + delim.length(); + } + while (pos < str.length() && prev < str.length()); + return tokens; +} + +bool IsAppVersionEarlierThan(const std::string& ver) { + LoggerD("Enter"); + std::string app_ver; + auto res = GetPkgApiVersion(&app_ver); + if (!res) { + LoggerE("Failed to get application version, " + "assuming that application version is same as platform"); + return false; + } + std::vector vec_app = SplitString(app_ver, "."); + std::vector vec_ref = SplitString(ver, "."); + + size_t length = std::min(vec_app.size(), vec_ref.size()); + for (size_t i = 0; i < length; ++i) { + int num_ver = std::stoi(vec_ref[i]); + int num_app = std::stoi(vec_app[i]); + if (num_app < num_ver) { + return true; + } else if (num_app > num_ver) { + return false; + } + } + return false; +} + std::string GetErrorString(int error_code) { static const size_t kSize = 1024; char msg[kSize] = {0}; diff --git a/src/common/tools.h b/src/common/tools.h index f48e4fa1..5d8eec64 100644 --- a/src/common/tools.h +++ b/src/common/tools.h @@ -37,6 +37,8 @@ common::PlatformResult CheckAccess(const std::string& privilege); common::PlatformResult CheckAccess(const std::vector& privileges); common::PlatformResult GetPkgApiVersion(std::string* api_version); +bool IsAppVersionEarlierThan(const std::string& ver); + //it is used for modules which return TizenResult objects to JS layer #define CHECK_PRIVILEGE(privilege) \ do { \ diff --git a/src/push/push.gyp b/src/push/push.gyp index 5cdb2ad1..759949fc 100644 --- a/src/push/push.gyp +++ b/src/push/push.gyp @@ -17,6 +17,8 @@ 'push_instance.h', 'push_manager.cc', 'push_manager.h', + 'push_manager_old.cc', + 'push_manager_old.h', 'push_manager_common.cc', 'push_manager_common.h' ], diff --git a/src/push/push_instance.cc b/src/push/push_instance.cc index cb347f81..374850e7 100644 --- a/src/push/push_instance.cc +++ b/src/push/push_instance.cc @@ -20,6 +20,7 @@ #include "common/logger.h" #include "common/tools.h" #include "push/push_manager.h" +#include "push/push_manager_old.h" namespace extension { namespace push { @@ -30,7 +31,7 @@ const std::string kPrivilegePush = "http://tizen.org/privilege/push"; } // namespace -PushInstance::PushInstance(): m_ignoreNotificationEvents(true) { +PushInstance::PushInstance(){ LoggerD("Enter"); using std::placeholders::_1; using std::placeholders::_2; @@ -54,8 +55,14 @@ PushInstance::PushInstance(): m_ignoreNotificationEvents(true) { std::bind(&PushInstance::getUnreadNotifications, this, _1, _2)); REGISTER_SYNC("Push_getPushMessage", std::bind(&PushInstance::getPushMessage, this, _1, _2)); - impl = new PushManager(); - impl->setListener(this); + + if (common::tools::IsAppVersionEarlierThan("3.0")) { + LoggerD("Application version is earlier than 3.0, use previous API"); + impl = new PushManagerOld(this); + } else { + LoggerD("Application version is 3.0 or later, use new API"); + impl = new PushManager(this); + } #undef REGISTER_ASYNC #undef REGISTER_SYNC @@ -71,8 +78,7 @@ void PushInstance::registerApplication(const picojson::value& args, if (result.IsError()) { LogAndReportError(result, &out, ("Error occured")); } else { - picojson::value result; - ReportSuccess(result, out); + ReportSuccess(out); } } @@ -87,8 +93,7 @@ void PushInstance::unregisterApplication(const picojson::value& args, if (result.IsError()) { LogAndReportError(result, &out, ("Error occured")); } else { - picojson::value res; - ReportSuccess(res, out); + ReportSuccess(out); } } @@ -98,9 +103,12 @@ void PushInstance::connectService(const picojson::value& args, CHECK_PRIVILEGE_ACCESS(kPrivilegePush, &out); - m_ignoreNotificationEvents = false; - picojson::value result; - ReportSuccess(result, out); + common::PlatformResult result = impl->connectService(); + if (result.IsError()) { + LogAndReportError(result, &out, ("Error while connect service")); + } else { + ReportSuccess(out); + } } void PushInstance::disconnectService(const picojson::value& args, @@ -109,9 +117,13 @@ void PushInstance::disconnectService(const picojson::value& args, CHECK_PRIVILEGE_ACCESS(kPrivilegePush, &out); - m_ignoreNotificationEvents = true; - picojson::value result; - ReportSuccess(result, out); + common::PlatformResult result = impl->connectService(); + if (result.IsError()) { + LogAndReportError(result, &out, ("Error while disconnect service")); + } else { + ReportSuccess(out); + } + } void PushInstance::getRegistrationId(const picojson::value& args, @@ -142,8 +154,7 @@ void PushInstance::getUnreadNotifications(const picojson::value& args, if (result.IsError()) { LogAndReportError(result, &out, ("Error occured")); } else { - picojson::value res; - ReportSuccess(res, out); + ReportSuccess(out); } } @@ -180,9 +191,6 @@ void PushInstance::onPushRegister(double callbackId, void PushInstance::onPushNotify(push_service_notification_h noti) { LoggerD("Enter"); - if (m_ignoreNotificationEvents) { - LoggerD("Listener not set, ignoring event"); - } picojson::value::object dict; picojson::value::object pushMessage; impl->notificationToJson(noti, &pushMessage); @@ -207,7 +215,7 @@ void PushInstance::onDeregister(double callbackId, PushInstance::~PushInstance() { LoggerD("Enter"); - impl->setListener(nullptr); + delete impl; } } // namespace push diff --git a/src/push/push_instance.h b/src/push/push_instance.h index b2d03adc..9d342f38 100644 --- a/src/push/push_instance.h +++ b/src/push/push_instance.h @@ -42,7 +42,6 @@ class PushInstance: public common::ParsedInstance, public EventListener { void getUnreadNotifications(const picojson::value& args, picojson::object& out); void getPushMessage(const picojson::value& args, picojson::object& out); - bool m_ignoreNotificationEvents; IPushManager* impl; }; diff --git a/src/push/push_manager.cc b/src/push/push_manager.cc index f3e0aab7..ce6051b2 100644 --- a/src/push/push_manager.cc +++ b/src/push/push_manager.cc @@ -33,329 +33,70 @@ namespace push { using common::PlatformResult; using common::ErrorCode; -PushManager::PushManager() : - m_handle(NULL), - m_listener(NULL), - m_state(PUSH_SERVICE_STATE_UNREGISTERED), - app_control_(nullptr), - operation_(nullptr) { - LoggerD("Enter"); - - initAppId(); - InitAppControl(); - - int ret = push_service_connect(m_pkgId.c_str(), onPushState, onPushNotify, this, - &m_handle); - if (ret != PUSH_SERVICE_ERROR_NONE) { - LoggerE("Failed to connect to push (%d)", ret); - } +PushManager::PushManager(EventListener* listener) : + IPushManager(listener) { + LoggerD("Enter"); } PushManager::~PushManager() { - LoggerD("Enter"); - - if (m_handle) { - push_service_disconnect(m_handle); - } - - if (app_control_ && (APP_CONTROL_ERROR_NONE != app_control_destroy(app_control_))) { - LoggerE("Failed to destroy app control"); - } - - if (operation_) { - free(operation_); - } -} - -void PushManager::setListener(EventListener* listener) { - LoggerD("Enter"); - m_listener = listener; -} - -void PushManager::initAppId() { - LoggerD("Enter"); - int pid = getpid(); - char *temp = NULL; - int ret = app_manager_get_app_id(pid, &temp); - if (ret != APP_MANAGER_ERROR_NONE || temp == NULL) { - LoggerE("Failed to get appid (%d)", ret); - return; - } - - m_appId = temp; - free(temp); - temp = NULL; - - app_info_h info; - ret = app_manager_get_app_info(m_appId.c_str(), &info); - if (ret != APP_MANAGER_ERROR_NONE) { - LoggerE("Failed to get app info (%d)", ret); - return; - } - - ret = app_info_get_package(info, &temp); - if (ret == APP_MANAGER_ERROR_NONE && temp != NULL) { - m_pkgId = temp; - free(temp); - } else { - LoggerE("Failed to get pkg id (%d)", ret); - } - - app_info_destroy(info); + LoggerD("Enter"); } -void PushManager::InitAppControl() { - ScopeLogger(); - - const auto encoded_bundle = GetEncodedBundle(); - - auto bundle = bundle_decode((bundle_raw*) (encoded_bundle.c_str()), - encoded_bundle.length()); - if (nullptr == bundle) { - LoggerE("Failed to decode bundle"); - return; - } - - app_control_h app_control = nullptr; - int ret = app_control_create_event(bundle, &app_control); - bundle_free(bundle); +PlatformResult PushManager::connectService() { + LoggerD("Enter"); - if (APP_CONTROL_ERROR_NONE != ret) { - LoggerE("app_control_create_event() failed: %d (%s)", ret, get_error_message(ret)); - } else { - app_control_ = app_control; - ret = app_control_get_operation(app_control, &operation_); - if (APP_CONTROL_ERROR_NONE != ret) { - LoggerE("app_control_get_operation() failed: %d (%s)", ret, get_error_message(ret)); - } + int ret = push_service_connect(m_pkgId.c_str(), onPushState, onPushNotify, this, + &m_handle); + if (ret != PUSH_SERVICE_ERROR_NONE) { + LoggerE("Failed to connect to push (%d)", ret); } + return common::PlatformResult(ErrorCode::NO_ERROR); } -PlatformResult PushManager::registerApplication(double callbackId) { +PlatformResult PushManager::disconnectService() { LoggerD("Enter"); + return common::PlatformResult(ErrorCode::NO_ERROR); +} - PushManagerHolder* holder = new PushManagerHolder{this, callbackId}; - - int ret = push_service_register(m_handle, onApplicationRegister, static_cast(holder)); - if (ret != PUSH_SERVICE_ERROR_NONE) { - delete holder; - return LogAndCreateResult(PushManagerCommon::ConvertPushError(ret), - "Failed to register", ("push_service_register failed (%d)", ret)); - } +PlatformResult PushManager::registerApplication(double callbackId) { + LoggerD("Enter"); return common::PlatformResult(ErrorCode::NO_ERROR); } common::PlatformResult PushManager::unregisterApplication(double callbackId) { - LoggerD("Enter"); - PushManagerHolder* holder = new PushManagerHolder{this, callbackId}; - - if (m_state == PUSH_SERVICE_STATE_UNREGISTERED) { - LoggerD("Already unregister, call unregister callback"); - if (!g_idle_add(onFakeDeregister, holder)) { - delete holder; - return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, - "Unknown error", ("g_idle_add failed")); - } - } else { - int ret = push_service_deregister(m_handle, onDeregister, holder); - if (ret != PUSH_SERVICE_ERROR_NONE) { - delete holder; - if (ret == PUSH_SERVICE_ERROR_INVALID_PARAMETER) { - LoggerE("[push_service_deregister] PUSH_SERVICE_ERROR_INVALID_PARAMETER"); - } else if (ret == PUSH_SERVICE_ERROR_OUT_OF_MEMORY) { - LoggerE("[push_service_deregister] PUSH_SERVICE_ERROR_OUT_OF_MEMORY"); - } else if (ret == PUSH_SERVICE_ERROR_NOT_CONNECTED) { - LoggerE("[push_service_deregister] PUSH_SERVICE_ERROR_NOT_CONNECTED"); - } else if (ret == PUSH_SERVICE_ERROR_OPERATION_FAILED) { - LoggerE("[push_service_deregister] PUSH_SERVICE_ERROR_OPERATION_FAILED"); - } - return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, - "Unknown error", - ("Failed to deregister: push_service_deregister failed (%d)", ret)); - } - } - return common::PlatformResult(ErrorCode::NO_ERROR); + LoggerD("Enter"); + return common::PlatformResult(ErrorCode::NO_ERROR); } common::PlatformResult PushManager::getRegistrationId(std::string& id) { - LoggerD("Enter"); - char* temp = NULL; - int ret = push_service_get_registration_id(m_handle, &temp); - if (ret != PUSH_SERVICE_ERROR_NONE) { - if (ret == PUSH_SERVICE_ERROR_INVALID_PARAMETER) { - LoggerE("[push_service_get_registration_id] PUSH_SERVICE_ERROR_INVALID_PARAMETER"); - } else if (ret == PUSH_SERVICE_ERROR_OUT_OF_MEMORY) { - LoggerE("[push_service_get_registration_id] PUSH_SERVICE_ERROR_OUT_OF_MEMORY"); - } else if (ret == PUSH_SERVICE_ERROR_NO_DATA) { - LoggerE("[push_service_get_registration_id] PUSH_SERVICE_ERROR_NO_DATA"); - } - return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, - "Unknown error", - ("Failed to get id: push_service_get_registration_id failed (%d)", ret)); - } - id = temp; - free(temp); - return common::PlatformResult(ErrorCode::NO_ERROR); + LoggerD("Enter"); + return common::PlatformResult(ErrorCode::NO_ERROR); } common::PlatformResult PushManager::getUnreadNotifications() { - LoggerD("Enter"); - int ret = push_service_request_unread_notification(m_handle); - if (ret != PUSH_SERVICE_ERROR_NONE) { - return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, - "Unknown error", - ("Failed to send request: push_service_request_unread_notification failed (%d)", ret)); - } - return common::PlatformResult(ErrorCode::NO_ERROR); + LoggerD("Enter"); + return common::PlatformResult(ErrorCode::NO_ERROR); } PlatformResult PushManager::getPushMessage(picojson::value* out) { LoggerD("Enter"); - - push_service_notification_h handle = nullptr; - int ret = push_service_app_control_to_notification(app_control_, operation_, - &handle); - - if (ret != PUSH_SERVICE_ERROR_NONE) { - if (PUSH_SERVICE_ERROR_NO_DATA == ret || PUSH_SERVICE_ERROR_NOT_SUPPORTED == ret) { - // application was not started by push service, return null - *out = picojson::value{}; - return common::PlatformResult(ErrorCode::NO_ERROR); - } else { - return LogAndCreateResult( - PushManagerCommon::ConvertPushError(ret), "Failed to get message", - ("push_service_app_control_to_notification failed: (%d)", ret)); - } - } - - picojson::object notification; - notificationToJson(handle, ¬ification); - push_service_free_notification(handle); - - *out = picojson::value{notification}; - return common::PlatformResult(ErrorCode::NO_ERROR); } void PushManager::onPushState(push_service_state_e state, const char* err, - void* user_data) { - LoggerD("Enter %d, err: %s", state, err); - PushManager* impl = static_cast(user_data); - if (nullptr != impl) { - impl->m_state = state; - } + void* user_data) { + LoggerD("Enter %d, err: %s", state, err); } void PushManager::onPushNotify(push_service_notification_h noti, void* user_data) { - LoggerD("Enter"); - PushManager* impl = static_cast(user_data); - if (nullptr == impl || !impl->m_listener) { - LoggerW("Listener not set, ignoring"); - return; - } - - impl->m_listener->onPushNotify(noti); -} - -void PushManager::onApplicationRegister(push_service_result_e result, const char* msg, void* user_data) { LoggerD("Enter"); - - PushManagerHolder* holder = static_cast(user_data); - // automatically releases memory - std::unique_ptr holder_ptr(holder); - PushManager* impl = dynamic_cast(holder->impl); - double callbackId = holder->callbackId; - + PushManager* impl = static_cast(user_data); if (nullptr == impl || !impl->m_listener) { LoggerW("Listener not set, ignoring"); return; } - - std::string id; - PlatformResult res(ErrorCode::NO_ERROR); - - if (PUSH_SERVICE_RESULT_SUCCESS == result) { - LoggerD("Success"); - char *temp = nullptr; - int ret = push_service_get_registration_id(impl->m_handle, &temp); - if (PUSH_SERVICE_ERROR_NONE == ret) { - LoggerD("Registration id retrieved"); - id = temp; - free(temp); - } else { - res = LogAndCreateResult( - ErrorCode::UNKNOWN_ERR, "Failed to retrieve registration id", - ("Failed to retrieve registration id: push_service_get_registration_id(%d)", ret)); - } - } else { - if (PUSH_SERVICE_RESULT_TIMEOUT == result) { - LoggerE("PUSH_SERVICE_RESULT_TIMEOUT"); - } else if (PUSH_SERVICE_RESULT_SERVER_ERROR == result) { - LoggerE("PUSH_SERVICE_RESULT_SERVER_ERROR"); - } else if (PUSH_SERVICE_RESULT_SYSTEM_ERROR == result) { - LoggerE("PUSH_SERVICE_RESULT_SYSTEM_ERROR"); - } - res = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, msg == nullptr ? "Unknown error" : msg); - } - - // onPushState is not always called when onPushRegister is successful - impl->m_state = PUSH_SERVICE_STATE_REGISTERED; - impl->m_listener->onPushRegister(callbackId, res, id); -} - -gboolean PushManager::onFakeDeregister(gpointer user_data) { - LoggerD("Enter"); - PushManagerHolder* holder = static_cast(user_data); - // automatically releases memory - std::unique_ptr holder_ptr(holder); - PushManager* impl = dynamic_cast(holder->impl); - double callbackId = holder->callbackId; - - if (nullptr == impl || !impl->m_listener) { - LoggerW("Listener not set, ignoring"); - return G_SOURCE_REMOVE; - } - impl->m_listener->onDeregister(callbackId, PlatformResult(ErrorCode::NO_ERROR)); - return G_SOURCE_REMOVE; -} - -void PushManager::onDeregister(push_service_result_e result, const char* msg, - void* user_data) { - LoggerD("Enter"); - PushManagerHolder* holder = static_cast(user_data); - // automatically releases memory - PushManager* impl = dynamic_cast(holder->impl); - std::unique_ptr holder_ptr(holder); - double callbackId = holder->callbackId; - - if (nullptr == impl || !impl->m_listener) { - LoggerW("Listener not set, ignoring"); - return; - } - if (result == PUSH_SERVICE_RESULT_SUCCESS) { - impl->m_listener->onDeregister(callbackId, PlatformResult(ErrorCode::NO_ERROR)); - } else { - impl->m_listener->onDeregister(callbackId, LogAndCreateResult(ErrorCode::UNKNOWN_ERR, - msg == NULL ? "Unknown error" : msg)); - } -} - - -std::string PushManager::GetEncodedBundle() { - LoggerD("Entered"); - - std::string result; - std::size_t size = 512; - - // make sure we read the whole variable, if the length of read variable is equal - // to the size we were trying to obtain, the variable is likely to be longer - do { - size <<= 1; - result = common::GetCurrentExtension()->GetRuntimeVariable("encoded_bundle", size); - } while (strlen(result.c_str()) == size); - - return result; + impl->m_listener->onPushNotify(noti); } } // namespace push diff --git a/src/push/push_manager.h b/src/push/push_manager.h index ba4dbb8a..a91a1c4c 100644 --- a/src/push/push_manager.h +++ b/src/push/push_manager.h @@ -30,40 +30,20 @@ namespace push { class PushManager : public IPushManager { public: - PushManager(); - virtual ~PushManager(); - - void setListener(EventListener* listener); - - common::PlatformResult registerApplication(double callbackId); - common::PlatformResult unregisterApplication(double callbackId); - common::PlatformResult getRegistrationId(std::string &id); - common::PlatformResult getUnreadNotifications(); - common::PlatformResult getPushMessage(picojson::value* out); - + PushManager(EventListener* listener); + virtual ~PushManager(); + + common::PlatformResult connectService(); + common::PlatformResult disconnectService(); + common::PlatformResult registerApplication(double callbackId); + common::PlatformResult unregisterApplication(double callbackId); + common::PlatformResult getRegistrationId(std::string &id); + common::PlatformResult getUnreadNotifications(); + common::PlatformResult getPushMessage(picojson::value* out); private: - void initAppId(); - void InitAppControl(); - - static void onPushState(push_service_state_e state, const char *err, - void *user_data); - static void onPushNotify(push_service_notification_h noti, void *user_data); - static void onApplicationRegister(push_service_result_e result, const char *msg, - void *user_data); - static gboolean onFakeDeregister(gpointer user_data); - static void onDeregister(push_service_result_e result, const char *msg, - void *user_data); - - static std::string GetEncodedBundle(); - - push_service_connection_h m_handle; - EventListener* m_listener; - push_service_state_e m_state; - std::string m_appId; - std::string m_pkgId; - - app_control_h app_control_; - char* operation_; + static void onPushState(push_service_state_e state, const char *err, + void *user_data); + static void onPushNotify(push_service_notification_h noti, void *user_data); }; } // namespace push diff --git a/src/push/push_manager_common.cc b/src/push/push_manager_common.cc index d29c4641..d711ca33 100644 --- a/src/push/push_manager_common.cc +++ b/src/push/push_manager_common.cc @@ -55,12 +55,32 @@ ErrorCode PushManagerCommon::ConvertPushError(int e) { return error; } -IPushManager::IPushManager() { +std::string PushManagerCommon::GetEncodedBundle() { + LoggerD("Entered"); + + std::string result; + std::size_t size = 512; + + // make sure we read the whole variable, if the length of read variable is equal + // to the size we were trying to obtain, the variable is likely to be longer + do { + size <<= 1; + result = common::GetCurrentExtension()->GetRuntimeVariable("encoded_bundle", size); + } while (strlen(result.c_str()) == size); + + return result; +} + +IPushManager::IPushManager(EventListener* listener) : + m_listener (listener), + m_handle (nullptr) { LoggerD("Enter"); + initPkgId(); } IPushManager::~IPushManager() { LoggerD("Enter"); + m_listener = nullptr; } void IPushManager::notificationToJson(push_service_notification_h noti, picojson::object* obj) { @@ -138,6 +158,37 @@ void IPushManager::notificationToJson(push_service_notification_h noti, picojson (*obj)["type"] = picojson::value(static_cast(type)); } +void IPushManager::initPkgId() { + LoggerD("Enter"); + int pid = getpid(); + char *temp = nullptr; + int ret = app_manager_get_app_id(pid, &temp); + if (APP_MANAGER_ERROR_NONE != ret || nullptr == temp) { + LoggerE("Failed to get appid (%d)", ret); + return; + } + + std::string m_appId = temp; + free(temp); + temp = NULL; + + app_info_h info; + ret = app_manager_get_app_info(m_appId.c_str(), &info); + if (ret != APP_MANAGER_ERROR_NONE) { + LoggerE("Failed to get app info (%d)", ret); + return; + } + + ret = app_info_get_package(info, &temp); + if (ret == APP_MANAGER_ERROR_NONE && temp != NULL) { + m_pkgId = temp; + free(temp); + } else { + LoggerE("Failed to get pkg id (%d)", ret); + } + app_info_destroy(info); +} + } // namespace push } // namespace extension diff --git a/src/push/push_manager_common.h b/src/push/push_manager_common.h index 40dc8574..6d411167 100644 --- a/src/push/push_manager_common.h +++ b/src/push/push_manager_common.h @@ -39,11 +39,11 @@ class EventListener { class IPushManager { public: - IPushManager(); + IPushManager(EventListener* listener); virtual ~IPushManager(); - virtual void setListener(EventListener* listener) = 0; - + virtual common::PlatformResult connectService() = 0; + virtual common::PlatformResult disconnectService() = 0; virtual common::PlatformResult registerApplication(double callbackId) = 0; virtual common::PlatformResult unregisterApplication(double callbackId) = 0; virtual common::PlatformResult getRegistrationId(std::string &id) = 0; @@ -51,6 +51,12 @@ class IPushManager { virtual common::PlatformResult getPushMessage(picojson::value* out) = 0; void notificationToJson(push_service_notification_h noti, picojson::object* obj); + protected : + void initPkgId(); + + EventListener* m_listener; + push_service_connection_h m_handle; + std::string m_pkgId; }; struct PushManagerHolder { @@ -61,6 +67,7 @@ struct PushManagerHolder { class PushManagerCommon { public : static common::ErrorCode ConvertPushError(int e); + static std::string GetEncodedBundle(); }; } // namespace push diff --git a/src/push/push_manager_old.cc b/src/push/push_manager_old.cc new file mode 100644 index 00000000..1b67bfa9 --- /dev/null +++ b/src/push/push_manager_old.cc @@ -0,0 +1,325 @@ +/* + * Copyright (c) 2015 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. + */ + +#include "push/push_manager_old.h" +#include +#include +#include +#include +#include +#include +#include + +#include "push/push_manager_common.h" +#include "common/extension.h" +#include "common/logger.h" + +namespace extension { +namespace push { + +using common::PlatformResult; +using common::ErrorCode; + +PushManagerOld::PushManagerOld(EventListener* listener) : + IPushManager(listener), + m_state(PUSH_SERVICE_STATE_UNREGISTERED), + app_control_(nullptr), + operation_(nullptr), + m_ignoreNotificationEvents (true) { + LoggerD("Enter"); + + InitAppControl(); + + int ret = push_service_connect(m_pkgId.c_str(), onPushState, onPushNotify, this, + &m_handle); + if (ret != PUSH_SERVICE_ERROR_NONE) { + LoggerE("Failed to connect to push (%d)", ret); + } +} + +PushManagerOld::~PushManagerOld() { + LoggerD("Enter"); + + if (m_handle) { + push_service_disconnect(m_handle); + } + + if (app_control_ && (APP_CONTROL_ERROR_NONE != app_control_destroy(app_control_))) { + LoggerE("Failed to destroy app control"); + } + + if (operation_) { + free(operation_); + } +} + +void PushManagerOld::InitAppControl() { + ScopeLogger(); + + const auto encoded_bundle = PushManagerCommon::GetEncodedBundle(); + + auto bundle = bundle_decode((bundle_raw*) (encoded_bundle.c_str()), + encoded_bundle.length()); + if (nullptr == bundle) { + LoggerE("Failed to decode bundle"); + return; + } + + app_control_h app_control = nullptr; + int ret = app_control_create_event(bundle, &app_control); + bundle_free(bundle); + + if (APP_CONTROL_ERROR_NONE != ret) { + LoggerE("app_control_create_event() failed: %d (%s)", ret, get_error_message(ret)); + } else { + app_control_ = app_control; + ret = app_control_get_operation(app_control, &operation_); + if (APP_CONTROL_ERROR_NONE != ret) { + LoggerE("app_control_get_operation() failed: %d (%s)", ret, get_error_message(ret)); + } + } +} + +PlatformResult PushManagerOld::connectService() { + LoggerD("Enter"); + m_ignoreNotificationEvents = false; + return common::PlatformResult(ErrorCode::NO_ERROR); +} + +PlatformResult PushManagerOld::disconnectService() { + LoggerD("Enter"); + m_ignoreNotificationEvents = true; + return common::PlatformResult(ErrorCode::NO_ERROR); +} + + +PlatformResult PushManagerOld::registerApplication(double callbackId) { + LoggerD("Enter"); + + PushManagerHolder* holder = new PushManagerHolder{this, callbackId}; + + int ret = push_service_register(m_handle, onApplicationRegister, static_cast(holder)); + if (ret != PUSH_SERVICE_ERROR_NONE) { + delete holder; + + return LogAndCreateResult(PushManagerCommon::ConvertPushError(ret), + "Failed to register", ("push_service_register failed (%d)", ret)); + } + return common::PlatformResult(ErrorCode::NO_ERROR); +} + +common::PlatformResult PushManagerOld::unregisterApplication(double callbackId) { + LoggerD("Enter"); + PushManagerHolder* holder = new PushManagerHolder{this, callbackId}; + + if (m_state == PUSH_SERVICE_STATE_UNREGISTERED) { + LoggerD("Already unregister, call unregister callback"); + if (!g_idle_add(onFakeDeregister, holder)) { + delete holder; + return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, + "Unknown error", ("g_idle_add failed")); + } + } else { + int ret = push_service_deregister(m_handle, onDeregister, holder); + if (ret != PUSH_SERVICE_ERROR_NONE) { + delete holder; + if (ret == PUSH_SERVICE_ERROR_INVALID_PARAMETER) { + LoggerE("[push_service_deregister] PUSH_SERVICE_ERROR_INVALID_PARAMETER"); + } else if (ret == PUSH_SERVICE_ERROR_OUT_OF_MEMORY) { + LoggerE("[push_service_deregister] PUSH_SERVICE_ERROR_OUT_OF_MEMORY"); + } else if (ret == PUSH_SERVICE_ERROR_NOT_CONNECTED) { + LoggerE("[push_service_deregister] PUSH_SERVICE_ERROR_NOT_CONNECTED"); + } else if (ret == PUSH_SERVICE_ERROR_OPERATION_FAILED) { + LoggerE("[push_service_deregister] PUSH_SERVICE_ERROR_OPERATION_FAILED"); + } + return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, + "Unknown error", + ("Failed to deregister: push_service_deregister failed (%d)", ret)); + } + } + return common::PlatformResult(ErrorCode::NO_ERROR); +} + +common::PlatformResult PushManagerOld::getRegistrationId(std::string& id) { + LoggerD("Enter"); + char* temp = NULL; + int ret = push_service_get_registration_id(m_handle, &temp); + if (ret != PUSH_SERVICE_ERROR_NONE) { + if (ret == PUSH_SERVICE_ERROR_INVALID_PARAMETER) { + LoggerE("[push_service_get_registration_id] PUSH_SERVICE_ERROR_INVALID_PARAMETER"); + } else if (ret == PUSH_SERVICE_ERROR_OUT_OF_MEMORY) { + LoggerE("[push_service_get_registration_id] PUSH_SERVICE_ERROR_OUT_OF_MEMORY"); + } else if (ret == PUSH_SERVICE_ERROR_NO_DATA) { + LoggerE("[push_service_get_registration_id] PUSH_SERVICE_ERROR_NO_DATA"); + } + return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, + "Unknown error", + ("Failed to get id: push_service_get_registration_id failed (%d)", ret)); + } + id = temp; + free(temp); + return common::PlatformResult(ErrorCode::NO_ERROR); +} + +common::PlatformResult PushManagerOld::getUnreadNotifications() { + LoggerD("Enter"); + int ret = push_service_request_unread_notification(m_handle); + if (ret != PUSH_SERVICE_ERROR_NONE) { + return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, + "Unknown error", + ("Failed to send request: push_service_request_unread_notification failed (%d)", ret)); + } + return common::PlatformResult(ErrorCode::NO_ERROR); +} + +PlatformResult PushManagerOld::getPushMessage(picojson::value* out) { + LoggerD("Enter"); + + push_service_notification_h handle = nullptr; + int ret = push_service_app_control_to_notification(app_control_, operation_, + &handle); + + if (ret != PUSH_SERVICE_ERROR_NONE) { + if (PUSH_SERVICE_ERROR_NO_DATA == ret || PUSH_SERVICE_ERROR_NOT_SUPPORTED == ret) { + // application was not started by push service, return null + *out = picojson::value{}; + return common::PlatformResult(ErrorCode::NO_ERROR); + } else { + return LogAndCreateResult( + PushManagerCommon::ConvertPushError(ret), "Failed to get message", + ("push_service_app_control_to_notification failed: (%d)", ret)); + } + } + + picojson::object notification; + notificationToJson(handle, ¬ification); + push_service_free_notification(handle); + + *out = picojson::value{notification}; + + return common::PlatformResult(ErrorCode::NO_ERROR); +} + +void PushManagerOld::onPushState(push_service_state_e state, const char* err, + void* user_data) { + LoggerD("Enter %d, err: %s", state, err); + PushManagerOld* impl = static_cast(user_data); + if (nullptr != impl) { + impl->m_state = state; + } +} + +void PushManagerOld::onPushNotify(push_service_notification_h noti, void* user_data) { + LoggerD("Enter"); + PushManagerOld* impl = static_cast(user_data); + if (nullptr == impl || !impl->m_listener) { + LoggerW("Listener not set, ignoring"); + return; + } + + if (!impl->m_ignoreNotificationEvents) { + impl->m_listener->onPushNotify(noti); + } else { + LoggerD("Listener not set, ignoring event"); + } +} + +void PushManagerOld::onApplicationRegister(push_service_result_e result, const char* msg, void* user_data) { + LoggerD("Enter"); + + PushManagerHolder* holder = static_cast(user_data); + // automatically releases memory + std::unique_ptr holder_ptr(holder); + PushManagerOld* impl = dynamic_cast(holder->impl); + double callbackId = holder->callbackId; + + if (nullptr == impl || !impl->m_listener) { + LoggerW("Listener not set, ignoring"); + return; + } + + std::string id; + PlatformResult res(ErrorCode::NO_ERROR); + + if (PUSH_SERVICE_RESULT_SUCCESS == result) { + LoggerD("Success"); + char *temp = nullptr; + int ret = push_service_get_registration_id(impl->m_handle, &temp); + if (PUSH_SERVICE_ERROR_NONE == ret) { + LoggerD("Registration id retrieved"); + id = temp; + free(temp); + } else { + res = LogAndCreateResult( + ErrorCode::UNKNOWN_ERR, "Failed to retrieve registration id", + ("Failed to retrieve registration id: push_service_get_registration_id(%d)", ret)); + } + } else { + if (PUSH_SERVICE_RESULT_TIMEOUT == result) { + LoggerE("PUSH_SERVICE_RESULT_TIMEOUT"); + } else if (PUSH_SERVICE_RESULT_SERVER_ERROR == result) { + LoggerE("PUSH_SERVICE_RESULT_SERVER_ERROR"); + } else if (PUSH_SERVICE_RESULT_SYSTEM_ERROR == result) { + LoggerE("PUSH_SERVICE_RESULT_SYSTEM_ERROR"); + } + res = LogAndCreateResult(ErrorCode::UNKNOWN_ERR, msg == nullptr ? "Unknown error" : msg); + } + + // onPushState is not always called when onPushRegister is successful + impl->m_state = PUSH_SERVICE_STATE_REGISTERED; + impl->m_listener->onPushRegister(callbackId, res, id); +} + +gboolean PushManagerOld::onFakeDeregister(gpointer user_data) { + LoggerD("Enter"); + PushManagerHolder* holder = static_cast(user_data); + // automatically releases memory + std::unique_ptr holder_ptr(holder); + PushManagerOld* impl = dynamic_cast(holder->impl); + double callbackId = holder->callbackId; + + if (nullptr == impl || !impl->m_listener) { + LoggerW("Listener not set, ignoring"); + return G_SOURCE_REMOVE; + } + impl->m_listener->onDeregister(callbackId, PlatformResult(ErrorCode::NO_ERROR)); + return G_SOURCE_REMOVE; +} + +void PushManagerOld::onDeregister(push_service_result_e result, const char* msg, + void* user_data) { + LoggerD("Enter"); + PushManagerHolder* holder = static_cast(user_data); + // automatically releases memory + PushManagerOld* impl = dynamic_cast(holder->impl); + std::unique_ptr holder_ptr(holder); + double callbackId = holder->callbackId; + + if (nullptr == impl || !impl->m_listener) { + LoggerW("Listener not set, ignoring"); + return; + } + if (result == PUSH_SERVICE_RESULT_SUCCESS) { + impl->m_listener->onDeregister(callbackId, PlatformResult(ErrorCode::NO_ERROR)); + } else { + impl->m_listener->onDeregister(callbackId, LogAndCreateResult(ErrorCode::UNKNOWN_ERR, + msg == NULL ? "Unknown error" : msg)); + } +} + +} // namespace push +} // namespace extension + diff --git a/src/push/push_manager_old.h b/src/push/push_manager_old.h new file mode 100644 index 00000000..c5a2aae7 --- /dev/null +++ b/src/push/push_manager_old.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2015 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 SRC_PUSH_PUSH_MANAGER_OLD_H_ +#define SRC_PUSH_PUSH_MANAGER_OLD_H_ + +#include +#include +#include +#include +#include +#include "common/platform_result.h" +#include "push_manager_common.h" + +namespace extension { +namespace push { + +class PushManagerOld : public IPushManager { + public: + PushManagerOld(EventListener* listener); + virtual ~PushManagerOld(); + + common::PlatformResult connectService(); + common::PlatformResult disconnectService(); + common::PlatformResult registerApplication(double callbackId); + common::PlatformResult unregisterApplication(double callbackId); + common::PlatformResult getRegistrationId(std::string &id); + common::PlatformResult getUnreadNotifications(); + common::PlatformResult getPushMessage(picojson::value* out); + + private: + void initAppId(); + void InitAppControl(); + + static void onPushState(push_service_state_e state, const char *err, + void *user_data); + static void onPushNotify(push_service_notification_h noti, void *user_data); + static void onApplicationRegister(push_service_result_e result, const char *msg, + void *user_data); + static gboolean onFakeDeregister(gpointer user_data); + static void onDeregister(push_service_result_e result, const char *msg, + void *user_data); + + push_service_state_e m_state; + + app_control_h app_control_; + char* operation_; + bool m_ignoreNotificationEvents; +}; + +} // namespace push +} // namespace extension + +#endif // SRC_PUSH_PUSH_MANAGER_OLD_H_ +