[Badge] Fix tests for Badge
authorAdam Banasiak <a.banasiak@samsung.com>
Wed, 14 Jan 2015 10:06:48 +0000 (11:06 +0100)
committerPawel Sikorski <p.sikorski@samsung.com>
Mon, 19 Jan 2015 10:17:11 +0000 (19:17 +0900)
[Verification] 1. Install api1badge0.WebAPITizenBadgeTests
               2. Run tct the result should be 22/25 pass

Change-Id: I77b55017c929f87c39a8f73166afeef9f16dee7f
Signed-off-by: Adam Banasiak <a.banasiak@samsung.com>
src/badge/badge_api.js
src/badge/badge_extension.cc
src/badge/badge_instance.cc
src/badge/badge_instance.h
src/badge/badge_manager.cc
src/badge/badge_manager.h

index c5126f939fc0f3893a44d96895b9eec563dd418f..1425bbe4ed9dfcd8bf17ef15eea63fed9528aa67 100644 (file)
@@ -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();
index ab96f974ca5ca55bf1714da9cbe4dc43e972206e..409bf631257d29327b36b508af4f32ac6a2766ed 100644 (file)
@@ -18,5 +18,5 @@ BadgeExtension::BadgeExtension() {
 BadgeExtension::~BadgeExtension() {}
 
 common::Instance* BadgeExtension::CreateInstance() {
-  return new extension::badge::BadgeInstance;
+  return &extension::badge::BadgeInstance::GetInstance();
 }
index edd32998c816ab27d51454eae901dff009f7d805..be5fcf82d3b7eae9826ee91e7c793a90b1b168be 100644 (file)
@@ -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<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
index 45d84a3fb2f0eed7844f0574b71a331cf9a584e3..c2e3f9aee89a4f6ff23e30416afdc994ccf4e929 100644 (file)
@@ -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
 
index 93041ab5b592829b2625bb06d278a9058a0050aa..e868144d440447976d91295c564bae7ddfb8a3d7 100644 (file)
@@ -4,30 +4,38 @@
 
 #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() {
+BadgeManagerBadgeManager::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<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
index a53395245db1a1726e7c7e34c92c3976cc968051..64a6f03a78ef52d62170d5b71ff5387d1c0d01c1 100644 (file)
@@ -6,6 +6,7 @@
 #define BADGE_BADGE_MANAGER_H_
 
 #include <string>
+#include <set>
 
 #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<std::string> watched_applications_;
 };
 
 }  // namespace badge