[Push] registerService implementation
authorPrzemyslaw Ciezkowski <p.ciezkowski@samsung.com>
Thu, 12 Feb 2015 08:37:07 +0000 (09:37 +0100)
committerPawel Andruszkiewicz <p.andruszkie@samsung.com>
Fri, 20 Feb 2015 12:34:17 +0000 (21:34 +0900)
[Verification]
var service = new tizen.ApplicationControl(
    "http://tizen.org/appcontrol/operation/push_test");
tizen.push.registerService(service,
    function(){console.log(arguments);},
    function(){console.log(arguments);});

Change-Id: Ibd390d27e9805abe0b5a0985419be339037aba51
Signed-off-by: Przemyslaw Ciezkowski <p.ciezkowski@samsung.com>
src/push/push_api.js
src/push/push_instance.cc
src/push/push_instance.h
src/push/push_manager.cc
src/push/push_manager.h

index 0e936d7..3c632b0 100644 (file)
@@ -61,6 +61,7 @@ PushManager.prototype.registerService = function(appControl, successCallback, er
     operation: data.appControl.operation,
     uri: data.appControl.uri,
     mime: data.appControl.mime,
+    category: data.appControl.category,
     data: data.appControl.data
   }, function(msg) {
     if (msg.error) {
index 0f01aec..e01de2d 100644 (file)
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "common/logger.h"
-
 #include "push/push_instance.h"
+#include <string>
+#include <vector>
+#include "common/logger.h"
 #include "push/push_manager.h"
 
 namespace extension {
@@ -26,13 +27,45 @@ PushInstance::PushInstance() {
             std::bind(&PushInstance::getRegistrationId, this, _1, _2));
     RegisterSyncHandler("Push_getUnreadNotifications",
             std::bind(&PushInstance::getUnreadNotifications, this, _1, _2));
+    PushManager::getInstance().setListener(this);
 }
 
 void PushInstance::registerService(const picojson::value& args,
         picojson::object& out) {
     LoggerD("Enter");
-    picojson::value result;
-    ReportSuccess(result, out);
+    PushManager::ApplicationControl appControl;
+    appControl.operation = args.get("operation").get<std::string>();
+    if (args.get("uri").is<std::string>()) {
+        appControl.uri = args.get("uri").get<std::string>();
+    }
+    if (args.get("mime").is<std::string>()) {
+        appControl.mime = args.get("mime").get<std::string>();
+    }
+    if (args.get("category").is<std::string>()) {
+        appControl.category = args.get("category").get<std::string>();
+    }
+    if (args.get("data").is<picojson::null>() == false) {
+        std::vector<picojson::value> dataArray =
+                args.get("data").get<picojson::array>();
+        for (auto &item : dataArray) {
+            std::string key = item.get("key").get<std::string>();
+            std::vector<picojson::value> values =
+                    item.get("value").get<picojson::array>();
+            for (auto &value : values) {
+                appControl.data[key].push_back(value.to_str());
+            }
+        }
+    }
+    common::PlatformResult result = PushManager::getInstance().registerService(
+            appControl,
+            args.get("callbackId").get<double>());
+    if (result.IsError()) {
+        LoggerE("Error occured");
+        ReportError(result, &out);
+    } else {
+        picojson::value result;
+        ReportSuccess(result, out);
+    }
 }
 
 void PushInstance::unregisterService(const picojson::value& args,
@@ -70,6 +103,20 @@ void PushInstance::getUnreadNotifications(const picojson::value& args,
     ReportSuccess(result, out);
 }
 
+void PushInstance::onPushRegister(double callbackId,
+        common::PlatformResult result, const std::string& id) {
+    LoggerD("Enter");
+    picojson::value::object dict;
+    dict["callbackId"] = picojson::value(callbackId);
+    if (result.IsError()) {
+        dict["error"] = result.ToJSON();
+    } else {
+        dict["registrationId"] = picojson::value(id);
+    }
+    picojson::value res(dict);
+    PostMessage(res.serialize().c_str());
+}
+
 PushInstance::~PushInstance() {
     LoggerD("Enter");
 }
index 3f4b4c0..d110630 100644 (file)
@@ -5,18 +5,19 @@
 #ifndef SRC_PUSH_PUSH_INSTANCE_H_
 #define SRC_PUSH_PUSH_INSTANCE_H_
 
+#include <string>
 #include "common/extension.h"
-
 #include "push/push_manager.h"
 
 namespace extension {
 namespace push {
 
-class PushInstance: public common::ParsedInstance {
+class PushInstance: public common::ParsedInstance, public EventListener {
  public:
     PushInstance();
     virtual ~PushInstance();
-
+    virtual void onPushRegister(double callbackId,
+            common::PlatformResult result, const std::string& id);
  private:
      void registerService(const picojson::value& args, picojson::object& out);
      void unregisterService(const picojson::value& args, picojson::object& out);
index d53ffe9..3b3d733 100644 (file)
@@ -2,18 +2,69 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "common/logger.h"
 #include "push/push_manager.h"
+#include <unistd.h>
+#include <app_control.h>
+#include <app_manager.h>
+#include "common/logger.h"
 
 namespace extension {
 namespace push {
 
-PushManager::PushManager() {
+using common::PlatformResult;
+using common::ErrorCode;
+
+PushManager::PushManager() :
+    m_handle(NULL),
+    m_listener(NULL) {
     LoggerD("Enter");
+    initAppId();
+
+    int ret = push_connect(m_pkgId.c_str(), onPushState, onPushNotify, NULL,
+        &m_handle);
+    if (ret != PUSH_ERROR_NONE) {
+        LoggerE("Failed to connect to push");
+    }
 }
 
 PushManager::~PushManager() {
     LoggerD("Enter");
+    push_disconnect(m_handle);
+}
+
+void PushManager::setListener(EventListener* listener) {
+    m_listener = listener;
+}
+
+void PushManager::initAppId() {
+    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");
+        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");
+        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");
+    }
+
+    app_info_destroy(info);
 }
 
 PushManager& PushManager::getInstance() {
@@ -21,6 +72,141 @@ PushManager& PushManager::getInstance() {
   return instance;
 }
 
+PlatformResult PushManager::registerService(
+        const ApplicationControl &appControl, double callbackId) {
+    LoggerD("Enter");
+    app_control_h service;
+    int ret = app_control_create(&service);
+    if (ret != APP_CONTROL_ERROR_NONE) {
+        LoggerE("Failed to create service: app_control_create failed");
+        return common::PlatformResult(ErrorCode::UNKNOWN_ERR,
+            "Failed to create service");
+    }
+
+    if (appControl.operation.empty()) {
+        LoggerE("Operation is empty");
+        app_control_destroy(service);
+        return common::PlatformResult(ErrorCode::INVALID_VALUES_ERR,
+            "Operation is empty");
+    }
+    ret = app_control_set_operation(service, appControl.operation.c_str());
+    if (ret != APP_CONTROL_ERROR_NONE) {
+        LoggerE("Failed to set operation: app_control_set_operation failed");
+        app_control_destroy(service);
+        return common::PlatformResult(ErrorCode::UNKNOWN_ERR,
+            "Failed to set operation");
+    }
+
+    if (!appControl.uri.empty()) {
+        ret = app_control_set_uri(service, appControl.uri.c_str());
+        if (ret != APP_CONTROL_ERROR_NONE) {
+            LoggerE("Failed to set uri: app_control_set_uri failed");
+            app_control_destroy(service);
+            return common::PlatformResult(ErrorCode::UNKNOWN_ERR,
+                "Failed to set uri");
+        }
+    }
+
+    if (!appControl.mime.empty()) {
+        ret = app_control_set_mime(service, appControl.mime.c_str());
+        if (ret != APP_CONTROL_ERROR_NONE) {
+            LoggerE("Failed to set mime: app_control_set_mime failed");
+            app_control_destroy(service);
+            return common::PlatformResult(ErrorCode::UNKNOWN_ERR,
+                "Failed to set mime");
+        }
+    }
+
+    if (!appControl.category.empty()) {
+        ret = app_control_set_category(service, appControl.category.c_str());
+        if (ret != APP_CONTROL_ERROR_NONE) {
+            LoggerE("Failed to set category: app_control_set_category failed");
+            app_control_destroy(service);
+            return common::PlatformResult(ErrorCode::UNKNOWN_ERR,
+                "Failed to set category");
+        }
+    }
+
+    ret = app_control_set_app_id(service, m_appId.c_str());
+    if (ret != APP_CONTROL_ERROR_NONE) {
+        LoggerE("Failed to set app id: app_control_set_app_id failed");
+        app_control_destroy(service);
+        return common::PlatformResult(ErrorCode::UNKNOWN_ERR,
+            "Failed to set app id");
+    }
+
+    for (auto &item : appControl.data) {
+        if (item.second.size() == 1) {
+            ret = app_control_add_extra_data(service, item.first.c_str(),
+                item.second.front().c_str());
+        } else {
+            const char *values[item.second.size()];
+            for (size_t i = 0; i < item.second.size(); ++i) {
+                values[i] = item.second.at(i).c_str();
+            }
+            ret = app_control_add_extra_data_array(service,
+                item.first.c_str(), values, item.second.size());
+        }
+        if (ret != APP_CONTROL_ERROR_NONE) {
+            LoggerE(
+                "Failed to set extra data: app_control_add_extra_data failed");
+            app_control_destroy(service);
+            return common::PlatformResult(ErrorCode::UNKNOWN_ERR,
+                "Failed to set extra data");
+        }
+    }
+
+    double* pcallback = new double(callbackId);
+    ret = push_register(m_handle, service, onPushRegister, pcallback);
+    app_control_destroy(service);
+    if (ret != PUSH_ERROR_NONE) {
+        delete pcallback;
+        LoggerE("Failed to register push: push_register failed");
+        return common::PlatformResult(ErrorCode::UNKNOWN_ERR,
+            "Failed to register");
+    }
+    return common::PlatformResult(ErrorCode::NO_ERROR);
+}
+
+void PushManager::onPushState(push_state_e state, const char* err,
+        void* user_data) {
+    LoggerD("Enter %d", state);
+}
+
+void PushManager::onPushNotify(push_notification_h noti, void* user_data) {
+    LoggerD("Enter");
+}
+
+void PushManager::onPushRegister(push_result_e result, const char* msg,
+        void* user_data) {
+    LoggerD("Enter");
+    if (!getInstance().m_listener) {
+        LoggerW("Listener not set, ignoring");
+        return;
+    }
+    double* callbackId = static_cast<double*>(user_data);
+    std::string id;
+    PlatformResult res(ErrorCode::NO_ERROR);
+    if (result == PUSH_RESULT_SUCCESS) {
+        LoggerD("Success");
+        char *temp = NULL;
+        int ret = push_get_registration_id(getInstance().m_handle, &temp);
+        if (ret == PUSH_ERROR_NONE) {
+            LoggerD("Registration id retrieved");
+            id = temp;
+            free(temp);
+        } else {
+            res = PlatformResult(ErrorCode::UNKNOWN_ERR,
+                "Failed to retrieve registration id");
+        }
+    } else {
+        res = PlatformResult(ErrorCode::UNKNOWN_ERR,
+                msg == NULL ? "Unknown error" : msg);
+    }
+    getInstance().m_listener->onPushRegister(*callbackId, res, id);
+    delete callbackId;
+}
+
 }  // namespace push
 }  // namespace extension
 
index 30f5510..58819fc 100644 (file)
@@ -5,17 +5,51 @@
 #ifndef SRC_PUSH_PUSH_MANAGER_H_
 #define SRC_PUSH_PUSH_MANAGER_H_
 
+#include <push.h>
+#include <string>
+#include <vector>
+#include <map>
+#include "common/platform_result.h"
+
 namespace extension {
 namespace push {
 
+class EventListener {
+ public:
+    virtual void onPushRegister(double callbackId,
+            common::PlatformResult result, const std::string& id) = 0;
+    virtual ~EventListener() {}
+};
 
 class PushManager {
  public:
     static PushManager& getInstance();
     virtual ~PushManager();
 
+    void setListener(EventListener* listener);
+    struct ApplicationControl {
+        std::string operation;
+        std::string uri;
+        std::string mime;
+        std::string category;
+        std::map<std::string, std::vector<std::string> > data;
+    };
+    common::PlatformResult registerService(const ApplicationControl &appControl,
+        double callbackId);
+
  private:
     PushManager();
+    void initAppId();
+    static void onPushState(push_state_e state, const char *err,
+        void *user_data);
+    static void onPushNotify(push_notification_h noti, void *user_data);
+    static void onPushRegister(push_result_e result, const char *msg,
+        void *user_data);
+
+    push_connection_h m_handle;
+    EventListener* m_listener;
+    std::string m_appId;
+    std::string m_pkgId;
 };
 
 }  // namespace push