From: Adam Banasiak Date: Wed, 14 Jan 2015 10:06:48 +0000 (+0100) Subject: [Badge] Fix tests for Badge X-Git-Tag: submit/tizen_tv/20150603.064601~1^2~598 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bef0c6c59c3ed5aa7a563e667a1a484f76f1ae38;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Badge] Fix tests for Badge [Verification] 1. Install api1badge0.WebAPITizenBadgeTests 2. Run tct the result should be 22/25 pass Change-Id: I77b55017c929f87c39a8f73166afeef9f16dee7f Signed-off-by: Adam Banasiak --- diff --git a/src/badge/badge_api.js b/src/badge/badge_api.js index c5126f93..1425bbe4 100644 --- a/src/badge/badge_api.js +++ b/src/badge/badge_api.js @@ -4,12 +4,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +//maximum value of badge as found in old plugin implementation +var MAX_BADGE_COUNT = 999; + var validator_ = xwalk.utils.validator; +var converter_ = xwalk.utils.converter; var types_ = validator_.Types; +var Type = xwalk.utils.type; var native_ = new xwalk.utils.NativeManager(extension); var _badgeListenerRegistered = false; var _badgeCallbackMap = {}; +var _currentWatchId = 1; +var _getNextWatchId = function() { + return _currentWatchId++; +}; + +var _badgeChangeListener = function(result) { + if (result.appId && result.count && _badgeCallbackMap.hasOwnProperty(result.appId)) { + for (var functionToCall in _badgeCallbackMap[result.appId]) { + native_.callIfPossible(_badgeCallbackMap[result.appId][functionToCall], + result.appId, converter_.toLong(result.count)); + } + } +} /** * This class provides functions to request and release badge resource. @@ -17,7 +35,7 @@ var _badgeCallbackMap = {}; */ function BadgeManager() { Object.defineProperties(this, { - 'maxBadgeCount': { value: 100, emumerable: true, writable: false} + 'maxBadgeCount': { value: MAX_BADGE_COUNT, emumerable: true, writable: false} }); } @@ -26,21 +44,28 @@ function BadgeManager() { * @param {!ApplicationId} ID of the application to update the badge * @param {!number} Number to display as the badge on the application icon */ - BadgeManager.prototype.setBadgeCount = function () { if(arguments.length < 2) throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR, - 'incorrect number of arguments'); + 'incorrect number of arguments'); var args = validator_.validateArgs(arguments, [ {name: 'appId', type: types_.STRING}, - {name: 'count', type: types_.UNSIGNED_LONG} + {name: 'count', type: types_.LONG} ]); - native_.callSync('Badge_setBadgeCount', { + if(args.count < 0) + throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR, + 'Count parameter is negative!'); + + var ret = native_.callSync('Badge_setBadgeCount', { appId: args.appId, count: args.count }); + + if (native_.isFailure(ret)) { + throw native_.getErrorObject(ret); + } } /** @@ -73,15 +98,75 @@ BadgeManager.prototype.getBadgeCount = function () { * @param {!function} Callback method to be invoked when a badge number change notification is received */ BadgeManager.prototype.addChangeListener = function () { - throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERROR, 'Not implemented'); + if(arguments.length < 2) + throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR, + 'incorrect number of arguments'); + var args = validator_.validateArgs(arguments, [ + { + name: 'appIdList', + type: types_.ARRAY, + values: types_.STRING, + optional: false, + nullable: false + }, + { + name: 'successCallback', + type: types_.FUNCTION, + optional: false, + nullable: false + } + ]); + + var result = native_.callSync('Badge_addChangeListener', args); + + if (native_.isFailure(result)) { + throw native_.getErrorObject(result); + } + if(!_badgeListenerRegistered) { + _badgeListenerRegistered = true; + native_.addListener('BadgeChangeListener', _badgeChangeListener); + } + for (var i = 0; i < args.appIdList.length; i++) { + if (!_badgeCallbackMap.hasOwnProperty(args.appIdList[i])) { + _badgeCallbackMap[args.appIdList[i]] = []; + } + _badgeCallbackMap[args.appIdList[i]].push(args.successCallback); + } + return; } /** * Gets the badge count for the designated application. * @param {!ApplicationId} Array of the ID of the designated application */ -BadgeManager.prototype.removeChangeListener = function () { - throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERROR, 'Not implemented'); +BadgeManager.prototype.removeChangeListener = function() { + if(arguments.length < 1) + throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR, + 'incorrect number of arguments'); + + var args = validator_.validateArgs(arguments, [ + { + name: 'appIdList', + type: types_.ARRAY, + values: types_.STRING, + optional: false, + nullable: false + } + ]); + + for (var i = 0; i < args.appIdList.length; i++) { + if (_badgeCallbackMap.hasOwnProperty(args.appIdList[i])) + delete _badgeCallbackMap[args.appIdList[i]]; + } + + if (Type.isEmptyObject(_badgeCallbackMap)) { + native_.removeListener('BadgeChangeListener', _badgeChangeListener); + _badgeListenerRegistered = false; + } + + var result = native_.callSync('Badge_removeChangeListener', args); + if (native_.isFailure(result)) + throw native_.getErrorObject(result); } -exports.badge = new BadgeManager(); +exports = new BadgeManager(); diff --git a/src/badge/badge_extension.cc b/src/badge/badge_extension.cc index ab96f974..409bf631 100644 --- a/src/badge/badge_extension.cc +++ b/src/badge/badge_extension.cc @@ -18,5 +18,5 @@ BadgeExtension::BadgeExtension() { BadgeExtension::~BadgeExtension() {} common::Instance* BadgeExtension::CreateInstance() { - return new extension::badge::BadgeInstance; + return &extension::badge::BadgeInstance::GetInstance(); } diff --git a/src/badge/badge_instance.cc b/src/badge/badge_instance.cc index edd32998..be5fcf82 100644 --- a/src/badge/badge_instance.cc +++ b/src/badge/badge_instance.cc @@ -18,6 +18,11 @@ const std::string kPrivilegeBadge = "http://tizen.org/privilege/badge"; using namespace common; using namespace extension::badge; +BadgeInstance& BadgeInstance::GetInstance() { + static BadgeInstance instance; + return instance; +} + BadgeInstance::BadgeInstance() { using namespace std::placeholders; #define REGISTER_SYNC(c, x) \ @@ -25,6 +30,8 @@ BadgeInstance::BadgeInstance() { REGISTER_SYNC("Badge_setBadgeCount", setBadgeCount); REGISTER_SYNC("Badge_getBadgeCount", getBadgeCount); + REGISTER_SYNC("Badge_addChangeListener", addChangeListener); + REGISTER_SYNC("Badge_removeChangeListener", removeChangeListener); #undef REGISTER_SYNC } @@ -32,17 +39,28 @@ BadgeInstance::BadgeInstance() { BadgeInstance::~BadgeInstance() {} void BadgeInstance::setBadgeCount(const JsonValue& args, JsonObject& out) { - std::string appId = common::FromJson(args.get(), "appId"); + std::string appId = + common::FromJson(args.get(), "appId"); const double count = args.get("count").get(); - BadgeManager::GetInstance()->setBadgeCount(appId, (unsigned int)count); + BadgeManager::GetInstance()->setBadgeCount(appId, static_cast(count)); ReportSuccess(out); } void BadgeInstance::getBadgeCount(const JsonValue& args, JsonObject& out) { - std::string appId = common::FromJson(args.get(), "appId"); + std::string appId = + common::FromJson(args.get(), "appId"); unsigned int count = BadgeManager::GetInstance()->getBadgeCount(appId); ReportSuccess(JsonValue(std::to_string(count)), out); } +void BadgeInstance::addChangeListener(const JsonValue& args, JsonObject& out) { + BadgeManager::GetInstance()->addChangeListener(args.get()); +} + +void BadgeInstance::removeChangeListener(const JsonValue& args, + JsonObject& out) { + BadgeManager::GetInstance()->removeChangeListener(args.get()); +} + } // namespace badge } // namespace extension diff --git a/src/badge/badge_instance.h b/src/badge/badge_instance.h index 45d84a3f..c2e3f9ae 100644 --- a/src/badge/badge_instance.h +++ b/src/badge/badge_instance.h @@ -16,6 +16,7 @@ class BadgeInstance : public common::ParsedInstance { public: BadgeInstance(); virtual ~BadgeInstance(); + static BadgeInstance& GetInstance(); private: /** @@ -45,8 +46,10 @@ class BadgeInstance : public common::ParsedInstance { * @endcode */ void getBadgeCount(const JsonValue& args, JsonObject& out); -}; + void addChangeListener(const JsonValue& args, JsonObject& out); + void removeChangeListener(const JsonValue& args, JsonObject& out); +}; } // namespace badge } // namespace extension diff --git a/src/badge/badge_manager.cc b/src/badge/badge_manager.cc index 93041ab5..e868144d 100644 --- a/src/badge/badge_manager.cc +++ b/src/badge/badge_manager.cc @@ -4,30 +4,38 @@ #include "badge_manager.h" -#include "common/logger.h" -#include "common/platform_exception.h" - #include #include #include -#include -#include +#include -#include -#include -#include -#include +#include "badge_instance.h" +#include "common/logger.h" +#include "common/converter.h" +#include "common/platform_exception.h" using namespace common; namespace extension { namespace badge { +std::set BadgeManager::watched_applications_; +bool BadgeManager::is_cb_registered_ = false; + BadgeManager::BadgeManager() {} -BadgeManager::~BadgeManager() {} +BadgeManager::~BadgeManager() { + if (is_cb_registered_) { + if (!watched_applications_.empty()) watched_applications_.clear(); + int ret = badge_unregister_changed_cb(badge_changed_cb); + if (ret != BADGE_ERROR_NONE) { + LoggerE("Unknown error : %d", ret); + } + is_cb_registered_ = false; + } +} -BadgeManager *BadgeManager::GetInstance() { +BadgeManager* BadgeManager::GetInstance() { static BadgeManager instance; return &instance; } @@ -35,7 +43,12 @@ BadgeManager *BadgeManager::GetInstance() { void BadgeManager::setBadgeCount(std::string appId, unsigned int count) { int ret = BADGE_ERROR_SERVICE_NOT_READY; bool badgeExist = false; - const char *app_id = appId.c_str(); + const char* app_id = appId.c_str(); + + if (!isAppInstalled(appId)) { + LoggerE("fail to get pkgId"); + throw InvalidValuesException("InvalidValues error : appId"); + } ret = badge_is_existing(app_id, &badgeExist); if (ret != BADGE_ERROR_NONE) { @@ -43,11 +56,7 @@ void BadgeManager::setBadgeCount(std::string appId, unsigned int count) { throw UnknownException("Unknown error"); } - if (badgeExist == false) { - if (!(checkPermisionForCreatingBadge(app_id))) { - throw SecurityException("The author signature is not match"); - } - + if (!badgeExist) { ret = badge_create(app_id, app_id); LoggerD("badge create : %", ret); @@ -91,6 +100,10 @@ unsigned int BadgeManager::getBadgeCount(std::string appId) { int ret = BADGE_ERROR_SERVICE_NOT_READY; bool badgeExist = false; + if (!isAppInstalled(appId)) { + LoggerE("fail to get pkgId"); + throw InvalidValuesException("InvalidValues error : appId"); + } ret = badge_is_existing(appId.c_str(), &badgeExist); if (ret != BADGE_ERROR_NONE) { LoggerE("Unknown error : %d", ret); @@ -124,178 +137,62 @@ unsigned int BadgeManager::getBadgeCount(std::string appId) { } } -void BadgeManager::CheckErrorCode(int err) { - switch (err) { - case BADGE_ERROR_NONE: - return; - case BADGE_ERROR_INVALID_PARAMETER: - throw InvalidValuesException("Invalid parameter"); - case BADGE_ERROR_PERMISSION_DENIED: - throw SecurityException( - "The application does not have the privilege to call this method"); - case BADGE_ERROR_IO_ERROR: - throw UnknownException("Error from I/O"); - case BADGE_ERROR_SERVICE_NOT_READY: - throw UnknownException("Service is not ready"); - case BADGE_ERROR_OUT_OF_MEMORY: - throw UnknownException("Out of memory"); - case BADGE_ERROR_FROM_DB: - throw UnknownException("Error from DB"); - case BADGE_ERROR_ALREADY_EXIST: - throw UnknownException("Already exist"); - case BADGE_ERROR_FROM_DBUS: - throw UnknownException("Error from DBus"); - case BADGE_ERROR_NOT_EXIST: - throw UnknownException("Not exist"); - default: - throw UnknownException("Unknown error"); - } -} - -bool BadgeManager::checkPermisionForCreatingBadge(const char *appId) { - if (!appId) { - LoggerE("InvalidValues error : appId"); - throw InvalidValuesException("InvalidValues error : appId"); +void BadgeManager::addChangeListener(const JsonObject& obj) { + LoggerD("entered here"); + auto& items = FromJson(obj, "appIdList"); + for (auto item : items) { + watched_applications_.insert(common::JsonCast(item)); } - - char *caller_appid = NULL; - caller_appid = _badge_get_pkgname_by_pid(); - - if (!caller_appid) { - LoggerE("fail to get caller pkgId"); - throw UnknownException("Platform error while getting caller pkgId."); - } - - char *caller_pkgname = NULL; - caller_pkgname = _badge_get_pkgname_by_appid(caller_appid); - if (!caller_pkgname) { - if (caller_appid) { - free(caller_appid); - } - LoggerE("fail to get caller pkgId"); - throw UnknownException("Platform error while getting caller pkgId."); - } - - char *pkgname = NULL; - pkgname = _badge_get_pkgname_by_appid(appId); - if (!pkgname) { - if (caller_appid) { - free(caller_appid); - } - if (caller_pkgname) { - free(caller_pkgname); + int ret = BADGE_ERROR_SERVICE_NOT_READY; + if (!is_cb_registered_) { + ret = badge_register_changed_cb(badge_changed_cb, this); + if (ret != BADGE_ERROR_NONE) { + LoggerE("Unknown error %d:", ret); + throw UnknownException("Platform error while adding listener."); } - LoggerE("fail to get pkgId"); - throw InvalidValuesException("InvalidValues error : appId"); - } - - bool flag = false; - if (_badge_is_same_certinfo(caller_pkgname, pkgname) == 1) { - flag = true; - } else { - LoggerE("The author signature is not match"); - flag = false; - } - - if (caller_appid) { - free(caller_appid); + is_cb_registered_ = true; } - if (caller_pkgname) { - free(caller_pkgname); - } - if (pkgname) { - free(pkgname); - } - - return flag; } -char *BadgeManager::_badge_get_pkgname_by_appid(const char *appId) { - char *pkgId = NULL; - int ret = PACKAGE_MANAGER_ERROR_NONE; - if (!appId) { - LoggerE("appId is null"); - return NULL; +void BadgeManager::removeChangeListener(const JsonObject& obj) { + auto& items = FromJson(obj, "appIdList"); + for (auto item : items) { + watched_applications_.erase(common::JsonCast(item)); } - - ret = package_manager_get_package_id_by_app_id(appId, &pkgId); - if (ret != PACKAGE_MANAGER_ERROR_NONE) { - LoggerE("fail to get caller pkgId : ", ret); - return NULL; - } - if (!pkgId) { - LoggerE("fail to get caller pkgId"); - return NULL; + if (watched_applications_.empty() && is_cb_registered_) { + int ret = badge_unregister_changed_cb(badge_changed_cb); + if (ret != BADGE_ERROR_NONE) { + LoggerE("Unknown error : %d", ret); + } + is_cb_registered_ = false; } - - return pkgId; } -char *BadgeManager::_badge_get_pkgname_by_pid() { - char *pkgname = NULL; - int pid = 0; - int ret = AUL_R_OK; - int fd = 0; - long max = 4096; - - pid = getpid(); - pkgname = static_cast(malloc(max)); - if (!pkgname) { - LoggerE("fail to alloc memory"); - return NULL; - } - memset(pkgname, 0x00, max); - - ret = aul_app_get_pkgname_bypid(pid, pkgname, max); - if (ret != AUL_R_OK) { - fd = open("/proc/self/cmdline", O_RDONLY); - if (fd < 0) { - free(pkgname); - return NULL; - } - - ret = read(fd, pkgname, max - 1); - if (ret <= 0) { - close(fd); - free(pkgname); - return NULL; - } - - close(fd); +void BadgeManager::badge_changed_cb(unsigned int action, const char* pkgname, + unsigned int count, void* user_data) { + if (action != BADGE_ACTION_SERVICE_READY && + watched_applications_.find(pkgname) != watched_applications_.end()) { + picojson::value response = picojson::value(picojson::object()); + picojson::object& response_obj = response.get(); + response_obj.insert( + std::make_pair("listenerId", std::string("BadgeChangeListener"))); + response_obj.insert(std::make_pair("appId", pkgname)); + response_obj.insert(std::make_pair("count", std::to_string(count))); + BadgeInstance::GetInstance().PostMessage(response.serialize().c_str()); } - - if (pkgname[0] == '\0') { - free(pkgname); - return NULL; - } else - return pkgname; } -int BadgeManager::_badge_is_same_certinfo(const char *caller, - const char *pkgname) { +bool BadgeManager::isAppInstalled(const std::string& appId) { int ret = PACKAGE_MANAGER_ERROR_NONE; - package_manager_compare_result_type_e compare_result = - PACKAGE_MANAGER_COMPARE_MISMATCH; - - if (!caller) { - return 0; + pkgmgrinfo_appinfo_h pkgmgrinfo_appinfo; + if (appId.empty()) { + return false; } - if (!pkgname) { - return 0; + ret = pkgmgrinfo_appinfo_get_appinfo(appId.c_str(), &pkgmgrinfo_appinfo); + if (ret != PMINFO_R_OK) { + return false; } - - LoggerE("pkgname : %d caller : ", pkgname, caller); - - ret = package_manager_compare_package_cert_info(pkgname, caller, - &compare_result); - - LoggerE("result : %d %d", ret, compare_result); - if (ret == PACKAGE_MANAGER_ERROR_NONE && - compare_result == PACKAGE_MANAGER_COMPARE_MATCH) { - return 1; - } - - return 0; + return true; } } // namespace badge diff --git a/src/badge/badge_manager.h b/src/badge/badge_manager.h index a5339524..64a6f03a 100644 --- a/src/badge/badge_manager.h +++ b/src/badge/badge_manager.h @@ -6,6 +6,7 @@ #define BADGE_BADGE_MANAGER_H_ #include +#include #include "common/logger.h" #include "common/picojson.h" @@ -24,17 +25,17 @@ class BadgeManager { void setBadgeCount(std::string appId, unsigned int count); unsigned int getBadgeCount(std::string appId); + void addChangeListener(const JsonObject& obj); + void removeChangeListener(const JsonObject& obj); + static void badge_changed_cb(unsigned int, const char*, unsigned int, void*); private: BadgeManager(); virtual ~BadgeManager(); - void CheckErrorCode(int err); - char* _badge_get_pkgname_by_appid(const char* appId); - bool checkPermisionForCreatingBadge(const char* appId); - char* _badge_get_pkgname_by_pid(); - int _badge_is_same_certinfo(const char *caller, const char *pkgname); - + bool isAppInstalled(const std::string& appId); + static bool is_cb_registered_; + static std::set watched_applications_; }; } // namespace badge