// 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.
*/
function BadgeManager() {
Object.defineProperties(this, {
- 'maxBadgeCount': { value: 100, emumerable: true, writable: false}
+ 'maxBadgeCount': { value: MAX_BADGE_COUNT, emumerable: true, writable: false}
});
}
* @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);
+ }
}
/**
* @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();
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) \
REGISTER_SYNC("Badge_setBadgeCount", setBadgeCount);
REGISTER_SYNC("Badge_getBadgeCount", getBadgeCount);
+ REGISTER_SYNC("Badge_addChangeListener", addChangeListener);
+ REGISTER_SYNC("Badge_removeChangeListener", removeChangeListener);
#undef REGISTER_SYNC
}
BadgeInstance::~BadgeInstance() {}
void BadgeInstance::setBadgeCount(const JsonValue& args, JsonObject& out) {
- std::string appId = common::FromJson<std::string>(args.get<JsonObject>(), "appId");
+ std::string appId =
+ common::FromJson<std::string>(args.get<JsonObject>(), "appId");
const double count = args.get("count").get<double>();
- BadgeManager::GetInstance()->setBadgeCount(appId, (unsigned int)count);
+ BadgeManager::GetInstance()->setBadgeCount(appId, static_cast<unsigned int>(count));
ReportSuccess(out);
}
void BadgeInstance::getBadgeCount(const JsonValue& args, JsonObject& out) {
- std::string appId = common::FromJson<std::string>(args.get<JsonObject>(), "appId");
+ std::string appId =
+ common::FromJson<std::string>(args.get<JsonObject>(), "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<JsonObject>());
+}
+
+void BadgeInstance::removeChangeListener(const JsonValue& args,
+ JsonObject& out) {
+ BadgeManager::GetInstance()->removeChangeListener(args.get<JsonObject>());
+}
+
} // namespace badge
} // namespace extension
#include "badge_manager.h"
-#include "common/logger.h"
-#include "common/platform_exception.h"
-
#include <badge.h>
#include <badge_internal.h>
#include <package_manager.h>
-#include <aul.h>
-#include <glib.h>
+#include <pkgmgr-info.h>
-#include <cstring>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#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<std::string> 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;
}
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) {
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);
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);
}
}
-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<picojson::array>(obj, "appIdList");
+ for (auto item : items) {
+ watched_applications_.insert(common::JsonCast<std::string>(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<picojson::array>(obj, "appIdList");
+ for (auto item : items) {
+ watched_applications_.erase(common::JsonCast<std::string>(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<char *>(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<picojson::object>();
+ 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