[Badge] setBadgeCount and getBadgeCound implementation
authorAdam Banasiak <a.banasiak@samsung.com>
Mon, 12 Jan 2015 07:33:45 +0000 (08:33 +0100)
committerAdam Banasiak <a.banasiak@samsung.com>
Tue, 13 Jan 2015 14:46:48 +0000 (15:46 +0100)
[DependsOn] http://168.219.209.56/gerrit/#/c/13547/

Signed-off-by: Adam Banasiak <a.banasiak@samsung.com>
Change-Id: I54af56cfdf588b7990d6af95f79d45a71d28453a

packaging/webapi-plugins.spec
src/badge/badge.gyp
src/badge/badge_api.js
src/badge/badge_extension.cc
src/badge/badge_extension.h
src/badge/badge_instance.cc
src/badge/badge_instance.h
src/badge/badge_manager.cc
src/badge/badge_manager.h

index 9921072..6b39dd4 100644 (file)
@@ -162,6 +162,7 @@ BuildRequires: pkgconfig(pkgmgr)
 BuildRequires: pkgconfig(pkgmgr-info)
 BuildRequires: pkgconfig(tapi)
 BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(badge)
 BuildRequires: pkgconfig(x11)
 BuildRequires: pkgconfig(xrandr)
 BuildRequires: pkgconfig(ecore)
index 3819d43..d8cdb7f 100644 (file)
@@ -19,6 +19,9 @@
         ['tizen == 1', {
           'variables': {
             'packages': [
+              'aul',
+              'badge',
+              'capi-appfw-package-manager',
               'vconf',
             ]
           },
index c62e856..c5126f9 100644 (file)
@@ -1,6 +1,6 @@
 /* global xwalk, extension, tizen */
 
-// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -8,11 +8,17 @@ var validator_ = xwalk.utils.validator;
 var types_ = validator_.Types;
 var native_ = new xwalk.utils.NativeManager(extension);
 
+var _badgeListenerRegistered = false;
+var _badgeCallbackMap = {};
+
 /**
  * This class provides functions to request and release badge resource.
  * @constructor
  */
 function BadgeManager() {
+  Object.defineProperties(this, {
+    'maxBadgeCount': { value: 100, emumerable: true, writable: false}
+  });
 }
 
 /**
@@ -20,8 +26,21 @@ 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() {
-  throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERROR, 'Not implemented');
+
+BadgeManager.prototype.setBadgeCount = function () {
+  if(arguments.length < 2)
+    throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR,
+                                    'incorrect number of arguments');
+
+  var args = validator_.validateArgs(arguments, [
+    {name: 'appId', type: types_.STRING},
+    {name: 'count', type: types_.UNSIGNED_LONG}
+  ]);
+
+  native_.callSync('Badge_setBadgeCount', {
+    appId: args.appId,
+    count: args.count
+  });
 }
 
 /**
@@ -29,8 +48,23 @@ BadgeManager.prototype.setBadgeCount = function() {
  * @param {!ApplicationId} ID of the designated application
  * @return {number} long Count of the badge
  */
-BadgeManager.prototype.getBadgeCount = function() {
-  throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERROR, 'Not implemented');
+BadgeManager.prototype.getBadgeCount = function () {
+  if(arguments.length < 1)
+    throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR,
+                                    'incorrect number of arguments');
+  var args = validator_.validateArgs(arguments, [
+    {name: 'appId', type: types_.STRING}
+  ]);
+
+  var ret = native_.callSync('Badge_getBadgeCount', {
+    appId: args.appId,
+  });
+
+  if (native_.isFailure(ret)) {
+    throw native_.getErrorObject(ret);
+  }
+
+  return parseInt(native_.getResultObject(ret));
 }
 
 /**
@@ -38,7 +72,7 @@ BadgeManager.prototype.getBadgeCount = function() {
  * @param {!ApplicationId} Array of the ID of the designated application
  * @param {!function} Callback method to be invoked when a badge number change notification is received
  */
-BadgeManager.prototype.addChangeListener = function() {
+BadgeManager.prototype.addChangeListener = function () {
   throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERROR, 'Not implemented');
 }
 
@@ -46,7 +80,7 @@ BadgeManager.prototype.addChangeListener = function() {
  * Gets the badge count for the designated application.
  * @param {!ApplicationId} Array of the ID of the designated application
  */
-BadgeManager.prototype.removeChangeListener = function() {
+BadgeManager.prototype.removeChangeListener = function () {
   throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERROR, 'Not implemented');
 }
 
index 919cea5..ab96f97 100644 (file)
@@ -1,9 +1,8 @@
-// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "badge/badge_extension.h"
-
 #include "badge/badge_instance.h"
 
 // This will be generated from badge_api.js
index ecb1f95..be8150f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
index d0394bc..edd3299 100644 (file)
@@ -1,12 +1,10 @@
-// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "badge/badge_instance.h"
 
-#include "common/picojson.h"
-#include "common/logger.h"
-#include "common/platform_exception.h"
+#include "common/converter.h"
 
 namespace extension {
 namespace badge {
@@ -25,10 +23,26 @@ BadgeInstance::BadgeInstance() {
 #define REGISTER_SYNC(c, x) \
   RegisterSyncHandler(c, std::bind(&BadgeInstance::x, this, _1, _2));
 
+  REGISTER_SYNC("Badge_setBadgeCount", setBadgeCount);
+  REGISTER_SYNC("Badge_getBadgeCount", getBadgeCount);
+
 #undef REGISTER_SYNC
 }
 
 BadgeInstance::~BadgeInstance() {}
 
+void BadgeInstance::setBadgeCount(const JsonValue& args, JsonObject& out) {
+  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);
+  ReportSuccess(out);
+}
+
+void BadgeInstance::getBadgeCount(const JsonValue& args, JsonObject& out) {
+  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);
+}
+
 }  // namespace badge
 }  // namespace extension
index c04a5c3..45d84a3 100644 (file)
@@ -1,10 +1,12 @@
-// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #ifndef BADGE_BADGE_INSTANCE_H_
 #define BADGE_BADGE_INSTANCE_H_
 
+#include "badge/badge_manager.h"
+
 #include "common/extension.h"
 
 namespace extension {
@@ -15,6 +17,34 @@ class BadgeInstance : public common::ParsedInstance {
   BadgeInstance();
   virtual ~BadgeInstance();
 
+ private:
+  /**
+   * Signature: @code void setBadgeCount(appId, count);
+   * @endcode
+   * JSON: @code data: {method: 'Badge_setBadgeCount',
+   *                    args: {ApplicationId: appId, long: count}} @endcode
+   * Invocation: @code native.callSync(request) @endcode
+   * Return:
+   * @code
+   * {status: 'error', error: {name, message}}
+   * {status: 'success'}
+   * @endcode
+   */
+  void setBadgeCount(const JsonValue& args, JsonObject& out);
+
+  /**
+   * Signature: @code void getBadgeCount(appId);
+   * @endcode
+   * JSON: @code data: {method: 'Badge_getBadgeCount',
+   *                    args: {ApplicationId: appId}} @endcode
+   * Invocation: @code native.callSync(request) @endcode
+   * Return:
+   * @code
+   * {status: 'error', error: {name, message}}
+   * {status: 'success', result: {count}}
+   * @endcode
+   */
+  void getBadgeCount(const JsonValue& args, JsonObject& out);
 };
 
 }  // namespace badge
index 353b5de..93041ab 100644 (file)
@@ -1,14 +1,23 @@
-// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "badge_manager.h"
 
-#include <cstring>
-
 #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 <cstring>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
 using namespace common;
 
 namespace extension {
@@ -18,17 +27,275 @@ BadgeManager::BadgeManager() {}
 
 BadgeManager::~BadgeManager() {}
 
-BadgeManagerBadgeManager::GetInstance() {
+BadgeManager *BadgeManager::GetInstance() {
   static BadgeManager instance;
   return &instance;
 }
 
-void setBadgeCount(std::string appId, long count) {
-  throw UnknownException("Not implemented.");
+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();
+
+  ret = badge_is_existing(app_id, &badgeExist);
+  if (ret != BADGE_ERROR_NONE) {
+    LoggerE("Unknown error : %d", ret);
+    throw UnknownException("Unknown error");
+  }
+
+  if (badgeExist == false) {
+    if (!(checkPermisionForCreatingBadge(app_id))) {
+      throw SecurityException("The author signature is not match");
+    }
+
+    ret = badge_create(app_id, app_id);
+    LoggerD("badge create : %", ret);
+
+    if (ret == BADGE_ERROR_PERMISSION_DENIED) {
+      LoggerE("Security error");
+      throw SecurityException("Security error");
+#ifdef PROFILE_WEARABLE
+    } else if (ret == BADGE_ERROR_INVALID_DATA) {
+#else
+    } else if (ret == BADGE_ERROR_INVALID_PARAMETER) {
+#endif
+      LoggerE("Invalid values error");
+      throw InvalidValuesException("Invalid values error");
+    } else if (ret != BADGE_ERROR_NONE && ret != BADGE_ERROR_ALREADY_EXIST) {
+      LoggerE("Unknown error");
+      throw InvalidValuesException("Unknown error");
+    }
+  }
+
+  ret = badge_set_count(app_id, count);
+  LoggerE("set ret : %d count :%d ", ret, count);
+
+  if (ret == BADGE_ERROR_PERMISSION_DENIED) {
+    LoggerE("Security error");
+    throw SecurityException("Security error");
+#ifdef PROFILE_WEARABLE
+  } else if (ret == BADGE_ERROR_INVALID_DATA) {
+#else
+  } else if (ret == BADGE_ERROR_INVALID_PARAMETER) {
+#endif
+    LoggerE("Invalid values error");
+    throw InvalidValuesException("Invalid values error");
+  } else if (ret != BADGE_ERROR_NONE) {
+    LoggerE("Unknown error : %d", ret);
+    throw InvalidValuesException("Unknown error");
+  }
+}
+
+unsigned int BadgeManager::getBadgeCount(std::string appId) {
+  LoggerD("Enter");
+
+  int ret = BADGE_ERROR_SERVICE_NOT_READY;
+  bool badgeExist = false;
+  ret = badge_is_existing(appId.c_str(), &badgeExist);
+  if (ret != BADGE_ERROR_NONE) {
+    LoggerE("Unknown error : %d", ret);
+    throw UnknownException("Platform error while checking badge.");
+  }
+  LoggerD("badge exist : %d", badgeExist);
+  unsigned int count = 0;
+
+  if (!badgeExist) {
+    throw UnknownException("badge not exist. appId: " + appId);
+  }
+
+  ret = badge_get_count(appId.c_str(), &count);
+
+  if (ret == BADGE_ERROR_NONE) {
+    LoggerD("success get ret : %d count : ", count);
+    return count;
+  } else if (ret == BADGE_ERROR_PERMISSION_DENIED) {
+    LoggerE("Security error");
+    throw SecurityException("Security error.");
+#ifdef PROFILE_WEARABLE
+  } else if (ret == BADGE_ERROR_INVALID_DATA) {
+#else
+  } else if (ret == BADGE_ERROR_INVALID_PARAMETER) {
+#endif
+    LoggerE("Invalid values error");
+    throw InvalidValuesException("InvalidValues error : appId");
+  } else {
+    LoggerE("Unknown error : %d", ret);
+    throw UnknownException("Unknown error");
+  }
+}
+
+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");
+  }
+
+  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);
+    }
+    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);
+  }
+  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;
+  }
+
+  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;
+  }
+
+  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);
+  }
+
+  if (pkgname[0] == '\0') {
+    free(pkgname);
+    return NULL;
+  } else
+    return pkgname;
 }
 
-long getBadgeCount(std::string appId) {
-  throw UnknownException("Not implemented.");
+int BadgeManager::_badge_is_same_certinfo(const char *caller,
+                                          const char *pkgname) {
+  int ret = PACKAGE_MANAGER_ERROR_NONE;
+  package_manager_compare_result_type_e compare_result =
+      PACKAGE_MANAGER_COMPARE_MISMATCH;
+
+  if (!caller) {
+    return 0;
+  }
+  if (!pkgname) {
+    return 0;
+  }
+
+  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;
 }
 
 }  // namespace badge
index 795c5bc..a533952 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -7,17 +7,34 @@
 
 #include <string>
 
+#include "common/logger.h"
+#include "common/picojson.h"
+
 namespace extension {
 namespace badge {
 
+typedef picojson::value JsonValue;
+typedef picojson::object JsonObject;
+typedef picojson::array JsonArray;
+typedef std::string JsonString;
+
 class BadgeManager {
  public:
+  static BadgeManager* GetInstance();
+
+  void setBadgeCount(std::string appId, unsigned int count);
+  unsigned int getBadgeCount(std::string appId);
+
+ private:
   BadgeManager();
-  ~BadgeManager();
-  BadgeManager* GetInstance();
+  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);
 
-  void setBadgeCount(std::string appId, long count);
-  long getBadgeCount(std::string appId);
 };
 
 }  // namespace badge