Remove TIDL for signal transmission 11/308611/1
authorIlho Kim <ilho159.kim@samsung.com>
Wed, 27 Mar 2024 10:58:28 +0000 (19:58 +0900)
committerIlho Kim <ilho159.kim@samsung.com>
Thu, 28 Mar 2024 06:42:29 +0000 (15:42 +0900)
Change-Id: I0878a9560fc9ba954a6d3ad3ade6fa3b6bf8d962
Signed-off-by: Ilho Kim <ilho159.kim@samsung.com>
19 files changed:
client/include/package-manager.h
client/src/api_stub.cc
client/src/connector.cc
client/src/connector.hh
client/src/pkgmgr_client_connection.c [new file with mode: 0644]
client/src/pkgmgr_client_debug.h [new file with mode: 0644]
client/src/pkgmgr_client_internal.c [new file with mode: 0644]
client/src/pkgmgr_client_internal.h [new file with mode: 0644]
installer/CMakeLists.txt
installer/pkgmgr_installer_config.h [new file with mode: 0644]
installer/pkgmgr_installer_signal_agent.c [new file with mode: 0644]
installer/pkgmgr_installer_signal_agent.cc [deleted file]
installer/src/api_stub.cc [deleted file]
installer/src/control.cc [deleted file]
installer/src/control.hh [deleted file]
installer/src/pkgmgr_installer.c [new file with mode: 0644]
installer/src/pkgmgr_installer.h
installer/src/pkgmgr_installer_debug.h
installer/src/request.hh

index 5f26051..9c0604a 100644 (file)
@@ -193,7 +193,7 @@ typedef struct {
 
 typedef struct _pkgmgr_res_event_info_t {
        int error_code;
-       void *path_states;
+       GList *path_states;
 } pkgmgr_res_event_info_t;
 
 typedef struct _res_event_path_state_t {
index a6760cf..04eb2c0 100644 (file)
@@ -25,6 +25,7 @@
 #include "client/src/connector.hh"
 #include "client/src/log.hh"
 #include "client/src/internal.hh"
+#include "client/src/pkgmgr_client_internal.h"
 
 #ifdef API
 #undef API
@@ -40,6 +41,9 @@ using pkgmgr::client::Connector;
 
 namespace {
 
+static GList *jobs_to_free;
+static pthread_mutex_t __mutex = PTHREAD_MUTEX_INITIALIZER;
+
 static int GetDelayedResult(pkgmgr_client *pc, const std::string& req_key) {
   if (pc == nullptr) {
     _E("invalid parameter");
@@ -160,6 +164,194 @@ static inline uid_t GetUid() {
     return uid;
 }
 
+static int __jobs_to_free_add(gpointer data)
+{
+  pthread_mutex_lock(&__mutex);
+  if (g_list_find(jobs_to_free, data)) {
+    pthread_mutex_unlock(&__mutex);
+    return -1;
+  }
+
+  jobs_to_free = g_list_append(jobs_to_free, data);
+  pthread_mutex_unlock(&__mutex);
+  return 0;
+}
+
+static void __jobs_to_free_remove(gpointer data)
+{
+  pthread_mutex_lock(&__mutex);
+  jobs_to_free = g_list_remove(jobs_to_free, data);
+  pthread_mutex_unlock(&__mutex);
+}
+
+static void __do_free_cb_info(gpointer data)
+{
+  struct cb_info *cb_info = (struct cb_info *)data;
+
+  g_list_free(cb_info->sid_list);
+  free(cb_info->req_key);
+  free(cb_info);
+}
+
+static gboolean __free_cb_info_at_idle(gpointer data)
+{
+  __jobs_to_free_remove(data);
+  __do_free_cb_info(data);
+
+  return G_SOURCE_REMOVE;
+}
+
+static void __free_cb_info(struct cb_info *cb_info)
+{
+  if (__jobs_to_free_add(cb_info) < 0)
+    return;
+
+  g_idle_add(__free_cb_info_at_idle, cb_info);
+}
+
+static int _get_internal_request_id()
+{
+  static int internal_req_id = 1;
+
+  return internal_req_id++;
+}
+
+static struct cb_info *__create_event_cb_info(struct pkgmgr_client_t *client,
+    pkgmgr_handler event_cb, void *data, const char *req_key) {
+  struct cb_info *ci;
+
+  ci = static_cast<cb_info*>(calloc(1, sizeof(struct cb_info)));
+  if (ci == NULL) {
+    _E("out of memory");
+    return NULL;
+  }
+  ci->client = client;
+  ci->event_cb = event_cb;
+  ci->data = data;
+  ci->req_id = _get_internal_request_id();
+  if (req_key != NULL) {
+    ci->req_key = strdup(req_key);
+    if (ci->req_key == NULL) {
+      _E("out of memory");
+      free(ci);
+      return NULL;
+    }
+  }
+
+  return ci;
+}
+
+static struct cb_info *__create_app_event_cb_info(
+    struct pkgmgr_client_t *client, pkgmgr_app_handler app_event_cb,
+    void *data, const char *req_key) {
+  cb_info *ci;
+
+  ci = static_cast<cb_info*>(calloc(1, sizeof(cb_info)));
+  if (ci == NULL) {
+    _E("out of memory");
+    return NULL;
+  }
+  ci->client = client;
+  ci->app_event_cb = app_event_cb;
+  ci->data = data;
+  ci->req_id = _get_internal_request_id();
+  if (req_key != NULL) {
+    ci->req_key = strdup(req_key);
+    if (ci->req_key == NULL) {
+      _E("out of memory");
+      free(ci);
+      return NULL;
+    }
+  }
+
+  return ci;
+}
+
+static struct cb_info *__create_res_event_cb_info(
+    struct pkgmgr_client_t *client,
+    pkgmgr_res_handler res_event_cb,
+    void *data, const char *req_key) {
+  struct cb_info *ci;
+
+  ci = static_cast<cb_info*>(calloc(1, sizeof(cb_info)));
+  if (ci == NULL) {
+    _E("out of memory");
+    return NULL;
+  }
+
+  ci->client = client;
+  ci->res_event_cb = res_event_cb;
+  ci->data = data;
+  ci->req_id = _get_internal_request_id();
+  if (req_key == NULL)
+    return ci;
+
+  ci->req_key = strdup(req_key);
+  if (ci->req_key == NULL) {
+    _E("out of memory");
+    free(ci);
+    return NULL;
+  }
+
+  return ci;
+}
+
+static struct cb_info *__create_upgrade_event_cb_info(
+    struct pkgmgr_client_t *client,
+    pkgmgr_pkg_upgrade_handler upgrade_event_cb,
+    void *data, const char *req_key) {
+  struct cb_info *ci;
+
+  ci = static_cast<cb_info*>(calloc(1, sizeof(cb_info)));
+  if (ci == NULL) {
+    _E("out of memory");
+    return NULL;
+  }
+
+  ci->client = client;
+  ci->upgrade_event_cb = upgrade_event_cb;
+  ci->data = data;
+  ci->req_id = _get_internal_request_id();
+  if (req_key == NULL)
+    return ci;
+
+  ci->req_key = strdup(req_key);
+  if (ci->req_key == NULL) {
+    _E("out of memory");
+    free(ci);
+    return NULL;
+  }
+
+  return ci;
+}
+
+static struct cb_info *__create_size_info_cb_info(
+    struct pkgmgr_client_t *client,
+    pkgmgr_pkg_size_info_receive_cb size_info_cb,
+    void *data, const char *req_key) {
+  struct cb_info *ci;
+
+  ci = static_cast<cb_info*>(calloc(1, sizeof(cb_info)));
+  if (ci == NULL) {
+    _E("out of memory");
+    return NULL;
+  }
+  ci->client = client;
+  ci->size_info_cb = size_info_cb;
+  ci->data = data;
+  ci->req_id = _get_internal_request_id();
+  if (req_key != NULL) {
+    ci->req_key = strdup(req_key);
+    if (ci->req_key == NULL) {
+      _E("out of memory");
+      free(ci);
+      return NULL;
+    }
+  }
+
+  return ci;
+}
+
 }
 
 API pkgmgr_client* pkgmgr_client_new(pkgmgr_client_type pc_type) {
@@ -168,7 +360,23 @@ API pkgmgr_client* pkgmgr_client_new(pkgmgr_client_type pc_type) {
     return nullptr;
   }
 
-  return new Connector(pc_type);
+  pkgmgr_client_t* raw_pc =
+      static_cast<pkgmgr_client_t*>(calloc(1, sizeof(pkgmgr_client_t)));
+  if (raw_pc == nullptr) {
+    _E("out of memory");
+    return nullptr;
+  }
+
+  raw_pc->pc_type = pc_type;
+  raw_pc->status_type = PKGMGR_CLIENT_STATUS_ALL;
+
+  if (pkgmgr_client_connection_connect(raw_pc) != PKGMGR_R_OK) {
+    _E("pkgmgr_client_connection_connect fail");
+    free(raw_pc);
+    return nullptr;
+  }
+
+  return new Connector(pc_type, raw_pc);
 }
 
 API int pkgmgr_client_free(pkgmgr_client* pc) {
@@ -178,6 +386,20 @@ API int pkgmgr_client_free(pkgmgr_client* pc) {
   }
 
   Connector* con = static_cast<Connector*>(pc);
+  pkgmgr_client_t* raw_pc = con->GetRawPc();
+  if (raw_pc) {
+    pkgmgr_client_remove_listen_status(raw_pc);
+    pkgmgr_client_connection_disconnect(raw_pc);
+    if (raw_pc->tep_path)
+      free(raw_pc->tep_path);
+    if (raw_pc->res_copy_builder)
+      g_variant_builder_unref(raw_pc->res_copy_builder);
+    if (raw_pc->res_remove_builder)
+      g_variant_builder_unref(raw_pc->res_remove_builder);
+    if (raw_pc->res_create_dir_builder)
+      g_variant_builder_unref(raw_pc->res_create_dir_builder);
+    free(raw_pc);
+  }
   delete con;
 
   return PKGMGR_R_OK;
@@ -218,13 +440,24 @@ API int pkgmgr_client_usr_install_packages(pkgmgr_client *pc,
   for (int i = 0; i < n_pkgs; i++)
     pkgs.push_back(pkg_paths[i]);
 
-  const auto& receiver = con->GetSignalReceiver();
   int ret = proxy->InstallPkgs(uid, pkgs, con->GetArgv(),
       con->GenerateRequestId(), req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_event_cb_info(client, event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_install_packages(pkgmgr_client *pc,
@@ -275,14 +508,25 @@ API int pkgmgr_client_usr_install(pkgmgr_client *pc, const char *pkg_type,
   if (proxy == nullptr)
     return PKGMGR_R_EIO;
 
-  const auto& receiver = con->GetSignalReceiver();
   std::string req_key;
   int ret = proxy->Install(uid, pkg_type ? pkg_type : "", pkg_path, con->GetArgv(),
       con->GenerateRequestId(), req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_event_cb_info(client, event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_reinstall(pkgmgr_client *pc, const char *pkg_type,
@@ -310,13 +554,24 @@ API int pkgmgr_client_usr_reinstall(pkgmgr_client *pc, const char *pkg_type,
   if (proxy == nullptr)
     return PKGMGR_R_EIO;
 
-  const auto& receiver = con->GetSignalReceiver();
   std::string req_key;
   int ret = proxy->Reinstall(uid, pkgid, req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_event_cb_info(client, event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_uninstall_packages(pkgmgr_client *pc,
@@ -349,12 +604,23 @@ API int pkgmgr_client_usr_uninstall_packages(pkgmgr_client *pc,
   for (int i = 0; i < n_pkgs; i++)
     pkgs.push_back(pkgids[i]);
 
-  const auto& receiver = con->GetSignalReceiver();
   int ret = proxy->UninstallPkgs(uid, pkgs, req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_event_cb_info(client, event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_uninstall(pkgmgr_client *pc, const char *pkg_type,
@@ -382,13 +648,24 @@ API int pkgmgr_client_usr_uninstall(pkgmgr_client *pc, const char *pkg_type,
   if (proxy == nullptr)
     return PKGMGR_R_EIO;
 
-  const auto& receiver = con->GetSignalReceiver();
   std::string req_key;
   int ret = proxy->Uninstall(uid, pkgid, req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_event_cb_info(client, event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_listen_res_status(pkgmgr_client *pc,
@@ -399,19 +676,42 @@ API int pkgmgr_client_listen_res_status(pkgmgr_client *pc,
     return PKGMGR_R_EINVAL;
   }
 
-  try {
-    const auto& receiver = con->GetSignalReceiver();
-    return receiver->AddEventHandler("", event_cb, data);
-  } catch (...) {
-    _E("exception occured");
-    return PKGMGR_R_ERROR;
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_res_event_cb_info(client, event_cb, data, nullptr);
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  int ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
   }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_listen_pkg_upgrade_status(pkgmgr_client *pc,
     pkgmgr_pkg_upgrade_handler event_cb, void *data) {
-  //TODO
-  return PKGMGR_R_OK;
+  Connector* con = static_cast<Connector*>(pc);
+  if (con->GetPcType() != PC_LISTENING) {
+    _E("client->pc_type is not PC_LISTENING");
+    return PKGMGR_R_EINVAL;
+  }
+
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_upgrade_event_cb_info(client, event_cb, data, nullptr);
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  int ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_usr_mount_install_packages(pkgmgr_client *pc,
@@ -443,13 +743,24 @@ API int pkgmgr_client_usr_mount_install_packages(pkgmgr_client *pc,
     pkgs.push_back(pkg_paths[i]);
   }
 
-  const auto& receiver = con->GetSignalReceiver();
   int ret = proxy->MountInstallPkgs(uid, pkgs, con->GenerateRequestId(),
       req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_event_cb_info(client, event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_mount_install_packages(pkgmgr_client *pc,
@@ -501,14 +812,25 @@ API int pkgmgr_client_usr_mount_install(pkgmgr_client *pc, const char *pkg_type,
   if (proxy == nullptr)
     return PKGMGR_R_EIO;
 
-  const auto& receiver = con->GetSignalReceiver();
   std::string req_key;
   int ret = proxy->MountInstall(uid, pkg_type ? pkg_type : "", pkg_path,
       con->GetArgv(), con->GenerateRequestId(), req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_event_cb_info(client, event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_move(pkgmgr_client *pc, const char *pkg_type,
@@ -540,13 +862,24 @@ API int pkgmgr_client_usr_move(pkgmgr_client *pc, const char *pkg_type,
   if (proxy == nullptr)
     return PKGMGR_R_EIO;
 
-  const auto& receiver = con->GetSignalReceiver();
   std::string req_key;
   int ret = proxy->Move(uid, pkgid, move_type, req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_event_cb_info(client, event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_register_pkg_update_info(pkgmgr_client *pc,
@@ -686,12 +1019,23 @@ API int pkgmgr_client_usr_activate_packages(pkgmgr_client *pc,
     vec.push_back(pkgids[i]);
   }
 
-  const auto& receiver = con->GetSignalReceiver();
   int ret = proxy->EnablePkgs(uid, std::move(vec), req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_event_cb_info(client, event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_activate_packages(pkgmgr_client *pc,
@@ -745,12 +1089,23 @@ API int pkgmgr_client_usr_deactivate_packages(pkgmgr_client *pc,
   for (int i = 0; i < n_pkgs; i++) {
     vec.push_back(pkgids[i]);
   }
-  const auto& receiver = con->GetSignalReceiver();
   int ret = proxy->DisablePkgs(uid, std::move(vec), req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_event_cb_info(client, event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_deactivate_packages(pkgmgr_client *pc,
@@ -772,13 +1127,24 @@ API int pkgmgr_client_usr_activate_app(pkgmgr_client *pc, const char *appid,
   if (proxy == nullptr)
     return PKGMGR_R_EIO;
 
-  const auto& receiver = con->GetSignalReceiver();
   std::string req_key;
   int ret = proxy->EnableApp(uid, appid, req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, app_event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_app_event_cb_info(client, app_event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_activate_app(pkgmgr_client *pc, const char *appid,
@@ -810,12 +1176,23 @@ API int pkgmgr_client_usr_activate_apps(pkgmgr_client *pc, const char **appids,
     vec.push_back(appids[i]);
   }
 
-  const auto& receiver = con->GetSignalReceiver();
   int ret = proxy->EnableApps(uid, std::move(vec), req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, app_event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_app_event_cb_info(client, app_event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_activate_apps(pkgmgr_client *pc, const char **appids,
@@ -836,13 +1213,24 @@ API int pkgmgr_client_activate_global_app_for_uid(pkgmgr_client *pc,
   if (proxy == nullptr)
     return PKGMGR_R_EIO;
 
-  const auto& receiver = con->GetSignalReceiver();
   std::string req_key;
   int ret = proxy->EnableGlobalAppForUid(uid, appid, req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, app_event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_app_event_cb_info(client, app_event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_usr_deactivate_app(pkgmgr_client *pc, const char *appid,
@@ -857,13 +1245,24 @@ API int pkgmgr_client_usr_deactivate_app(pkgmgr_client *pc, const char *appid,
   if (proxy == nullptr)
     return PKGMGR_R_EIO;
 
-  const auto& receiver = con->GetSignalReceiver();
   std::string req_key;
   int ret = proxy->DisableApp(uid, appid, req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, app_event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_app_event_cb_info(client, app_event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_deactivate_app(pkgmgr_client *pc, const char *appid,
@@ -896,12 +1295,23 @@ API int pkgmgr_client_usr_deactivate_apps(pkgmgr_client *pc,
     vec.push_back(appids[i]);
   }
 
-  const auto& receiver = con->GetSignalReceiver();
   int ret = proxy->DisableApps(uid, std::move(vec), req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, app_event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_app_event_cb_info(client, app_event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_deactivate_apps(pkgmgr_client *pc, const char **appids,
@@ -922,13 +1332,24 @@ API int pkgmgr_client_deactivate_global_app_for_uid(pkgmgr_client *pc,
   if (proxy == nullptr)
     return PKGMGR_R_EIO;
 
-  const auto& receiver = con->GetSignalReceiver();
   std::string req_key;
   int ret = proxy->DisableGlobalAppForUid(uid, appid, req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, app_event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_app_event_cb_info(client, app_event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_clear_user_data(pkgmgr_client *pc, const char *pkg_type,
@@ -988,7 +1409,21 @@ API int pkgmgr_client_clear_user_data_with_path(pkgmgr_client *pc, const char *p
 }
 
 API int pkgmgr_client_set_status_type(pkgmgr_client *pc, int status_type) {
-  //TODO
+  if (pc == NULL) {
+    _E("invalid parameter");
+    return PKGMGR_R_EINVAL;
+  }
+
+  auto* con = static_cast<Connector*>(pc);
+  pkgmgr_client_t* client = static_cast<pkgmgr_client_t*>(con->GetRawPc());
+
+  if (client == NULL) {
+    _E("invalid parameter");
+    return PKGMGR_R_EINVAL;
+  }
+
+  client->status_type = status_type;
+
   return PKGMGR_R_OK;
 }
 
@@ -1005,13 +1440,20 @@ API int pkgmgr_client_listen_status(pkgmgr_client *pc, pkgmgr_handler event_cb,
     return PKGMGR_R_EINVAL;
   }
 
-  try {
-    const auto& receiver = con->GetSignalReceiver();
-    return receiver->AddEventHandler("", event_cb, data);
-  } catch (...) {
-    _E("exception occured");
-    return PKGMGR_R_ERROR;
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_event_cb_info(client, event_cb, data, nullptr);
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ci->status_type = client->status_type;
+  int ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
   }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_listen_app_status(pkgmgr_client *pc,
@@ -1027,17 +1469,45 @@ API int pkgmgr_client_listen_app_status(pkgmgr_client *pc,
     return PKGMGR_R_EINVAL;
   }
 
-  try {
-    const auto& receiver = con->GetSignalReceiver();
-    return receiver->AddEventHandler("", app_event_cb, data);
-  } catch (...) {
-    _E("exception occured");
-    return PKGMGR_R_ERROR;
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_app_event_cb_info(client, app_event_cb, data, nullptr);
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ci->status_type = client->status_type;
+  int ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
   }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_remove_listen_status(pkgmgr_client *pc) {
-  //TODO
+  struct pkgmgr_client_t *client = (struct pkgmgr_client_t *)pc;
+  GList *tmp;
+  GList *next;
+  struct cb_info *ci;
+
+  if (pc == NULL) {
+    _E("invalid parameter");
+    return PKGMGR_R_EINVAL;
+  }
+
+  /* unset all callback */
+  tmp = client->cb_info_list;
+  while (tmp != NULL) {
+    next = tmp->next;
+    ci = (struct cb_info *)tmp->data;
+    pkgmgr_client_connection_unset_callback(client, ci);
+    client->cb_info_list = g_list_delete_link(client->cb_info_list,
+        tmp);
+    __free_cb_info(ci);
+    tmp = next;
+  }
+
   return PKGMGR_R_OK;
 }
 
@@ -1164,13 +1634,24 @@ API int pkgmgr_client_usr_get_size(pkgmgr_client *pc, const char *pkgid,
   if (proxy == nullptr)
     return PKGMGR_R_EIO;
 
-  const auto& receiver = con->GetSignalReceiver();
   std::string req_key;
   int ret = proxy->GetSize(uid, pkgid, get_type, req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, event_cb, data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_event_cb_info(client, event_cb, data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return PKGMGR_R_OK;
 }
 
 API int pkgmgr_client_get_package_size_info(pkgmgr_client *pc,
@@ -1219,13 +1700,22 @@ API int pkgmgr_client_usr_get_package_size_info(pkgmgr_client *pc,
   if (proxy == nullptr)
     return PKGMGR_R_EIO;
 
-  const auto& receiver = con->GetSignalReceiver();
   std::string req_key;
   int ret = proxy->GetSize(uid, pkgid, get_type, req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  receiver->AddEventHandler(req_key, event_cb, pc, user_data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_size_info_cb_info(client, event_cb, user_data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
 
   return PKGMGR_R_OK;
 }
@@ -1623,14 +2113,24 @@ API int pkgmgr_client_res_copy(pkgmgr_client *pc,
   if (proxy == nullptr)
     return PKGMGR_R_EIO;
 
-  const auto& receiver = con->GetSignalReceiver();
-
   std::string req_key;
   int ret = proxy->ResCopy(con->GetResCopyPath(), req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, event_cb, user_data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_res_event_cb_info(client, event_cb, user_data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_add_res_create_dir_path(pkgmgr_client *pc,
@@ -1658,14 +2158,24 @@ API int pkgmgr_client_res_create_dir(pkgmgr_client *pc,
   if (proxy == nullptr)
     return PKGMGR_R_EIO;
 
-  const auto& receiver = con->GetSignalReceiver();
-
   std::string req_key;
   int ret = proxy->ResCreateDir(con->GetResCreateDir(), req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, event_cb, user_data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_res_event_cb_info(client, event_cb, user_data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_add_res_remove_path(pkgmgr_client *pc,
@@ -1693,14 +2203,24 @@ API int pkgmgr_client_res_remove(pkgmgr_client *pc,
   if (proxy == nullptr)
     return PKGMGR_R_EIO;
 
-  const auto& receiver = con->GetSignalReceiver();
-
   std::string req_key;
   int ret = proxy->ResRemove(con->GetResRemovePath(), req_key);
   if (ret != PKGMGR_R_OK)
     return ret;
 
-  return receiver->AddEventHandler(req_key, event_cb, user_data);
+  pkgmgr_client_t* client = con->GetRawPc();
+
+  cb_info* ci = __create_res_event_cb_info(client, event_cb, user_data, req_key.c_str());
+  if (ci == NULL)
+    return PKGMGR_R_ENOMEM;
+  ret = pkgmgr_client_connection_set_callback(client, ci);
+  if (ret != PKGMGR_R_OK) {
+    __free_cb_info(ci);
+    return ret;
+  }
+  client->cb_info_list = g_list_append(client->cb_info_list, ci);
+
+  return ci->req_id;
 }
 
 API int pkgmgr_client_res_uninstall(pkgmgr_client *pc, const char *pkgid) {
@@ -1724,84 +2244,109 @@ API int pkgmgr_client_res_usr_uninstall(pkgmgr_client *pc, const char *pkgid,
 }
 
 API pkgmgr_res_event_info *pkgmgr_res_event_info_new() {
-  pkgmgr_res_event_info* info =
-      reinterpret_cast<pkgmgr_res_event_info*>(
-          new rpc_port::PkgSignal::ExtraData);
-  if (!info) {
-    _E("Out of memory");
-    return nullptr;
+  pkgmgr_res_event_info_t *info;
+
+  info = static_cast<pkgmgr_res_event_info_t*>(calloc(1, sizeof(pkgmgr_res_event_info_t)));
+  if (info == NULL) {
+    _E("out of memory");
+    return NULL;
   }
-  return info;
+
+  return (pkgmgr_res_event_info *)info;
+}
+
+static void __free_path_states(gpointer data)
+{
+       res_event_path_state_t *path_state = (res_event_path_state_t *)data;
+
+       if (path_state == NULL)
+               return;
+       if (path_state->path)
+               free(path_state->path);
+       free(path_state);
 }
 
 API int pkgmgr_res_event_info_free(pkgmgr_res_event_info *info) {
-  if (!info) {
-    _E("invalid parameter");
+  pkgmgr_res_event_info_t *event_info =
+      (pkgmgr_res_event_info_t *)info;
+
+  if (event_info == NULL) {
+    _E("invalid argument");
     return PKGMGR_R_EINVAL;
   }
-  rpc_port::PkgSignal::ExtraData* event_info =
-      reinterpret_cast<rpc_port::PkgSignal::ExtraData*>(info);
-  delete event_info;
+
+  if (event_info->path_states)
+    g_list_free_full(event_info->path_states, __free_path_states);
+  free(event_info);
 
   return PKGMGR_R_OK;
 }
 
 API int pkgmgr_res_event_info_set_error_code(pkgmgr_res_event_info *handle, int error_code) {
-  if (!handle) {
+  pkgmgr_res_event_info_t *info = static_cast<pkgmgr_res_event_info_t*>(handle);
+  if (info == NULL) {
     _E("invalid parameter");
     return PKGMGR_R_EINVAL;
   }
 
-  rpc_port::PkgSignal::ExtraData* event_info =
-      reinterpret_cast<rpc_port::PkgSignal::ExtraData*>(handle);
-  event_info->SetErrCode(error_code);
-
+  info->error_code = error_code;
   return PKGMGR_R_OK;
 }
 
 API int pkgmgr_res_event_info_get_error_code(pkgmgr_res_event_info *handle, int *error_code) {
-  if (!handle) {
+  pkgmgr_res_event_info_t *info = static_cast<pkgmgr_res_event_info_t*>(handle);
+  if (info == NULL || error_code == NULL) {
     _E("invalid parameter");
     return PKGMGR_R_EINVAL;
   }
 
-  rpc_port::PkgSignal::ExtraData* event_info =
-      reinterpret_cast<rpc_port::PkgSignal::ExtraData*>(handle);
-  *error_code = event_info->GetErrCode();
-
+  *error_code = info->error_code;
   return PKGMGR_R_OK;
 }
 
 API int pkgmgr_res_event_info_add_path_state(pkgmgr_res_event_info *handle,
     const char *path, pkgmgr_res_event_path_state state) {
-  if (!handle || !path) {
+  pkgmgr_res_event_info_t *info = static_cast<pkgmgr_res_event_info_t*>(handle);
+  res_event_path_state_t *path_state;
+
+  if (info == NULL || path == NULL) {
     _E("invalid parameter");
     return PKGMGR_R_EINVAL;
   }
 
-  rpc_port::PkgSignal::ExtraData* event_info =
-      reinterpret_cast<rpc_port::PkgSignal::ExtraData*>(handle);
+  path_state = static_cast<res_event_path_state_t*>(calloc(1, sizeof(res_event_path_state_t)));
+  if (path_state == NULL) {
+    _E("out of memory");
+    return PKGMGR_R_ENOMEM;
+  }
 
-  auto paths = event_info->GetPaths();
-  paths.emplace_back(path, state);
-  event_info->SetPaths(std::move(paths));
+  path_state->path = strdup(path);
+  if (path_state->path == NULL) {
+    _E("out of memory");
+    free(path_state);
+    return PKGMGR_R_ENOMEM;
+  }
+  path_state->state = state;
 
+  info->path_states = g_list_prepend(info->path_states , path_state);
   return PKGMGR_R_OK;
 }
 
 API int pkgmgr_res_event_info_foreach_path(pkgmgr_res_event_info *handle,
     pkgmgr_res_event_path_cb callback, void *user_data) {
-  if (!handle || !callback) {
+  pkgmgr_res_event_info_t *info = static_cast<pkgmgr_res_event_info_t*>(handle);
+  GList *list;
+  res_event_path_state_t *path_state;
+
+  if (info == NULL) {
     _E("invalid parameter");
     return PKGMGR_R_EINVAL;
   }
 
-  rpc_port::PkgSignal::ExtraData* event_info =
-      reinterpret_cast<rpc_port::PkgSignal::ExtraData*>(handle);
-
-  for (const auto& p : event_info->GetPaths()) {
-    if (callback(p.GetPath().c_str(),
-        static_cast<pkgmgr_res_event_path_state>(p.GetState()), user_data) < 0)
+  for (list = info->path_states; list != NULL; list = list->next) {
+    path_state = (res_event_path_state_t *)list->data;
+    if (callback(path_state->path, path_state->state,
+        user_data) < 0)
       return PKGMGR_R_OK;
   }
 
index a7a950f..eb8ffae 100644 (file)
@@ -199,12 +199,12 @@ bool Connector::ConnectForDelayedResult() {
   return true;
 }
 
-const std::unique_ptr<SignalReceiver>& Connector::GetSignalReceiver() {
-  if (!signal_receiver_)
-    signal_receiver_.reset(new SignalReceiver(__is_system_type(pc_type_)));
-
-  return signal_receiver_;
-}
+//const std::unique_ptr<SignalReceiver>& Connector::GetSignalReceiver() {
+//  if (!signal_receiver_)
+//    signal_receiver_.reset(new SignalReceiver(__is_system_type(pc_type_)));
+//
+//  return signal_receiver_;
+//}
 
 pkgmgr_client_type Connector::GetPcType() const {
   return pc_type_;
@@ -230,6 +230,10 @@ bool Connector::GetTepMove() {
   return tep_move_;
 }
 
+pkgmgr_client_t* Connector::GetRawPc() {
+  return raw_pc_;
+}
+
 bool Connector::Activator::Connect() {
   if (!Create())
     return false;
index aa359a4..29236b3 100644 (file)
 #include <string>
 #include <vector>
 
+#include "package-manager.h"
 #include "PkgMgrProxy.h"
+#include "pkgmgr_client_internal.h"
 
 #include "connection_event_listener.hh"
-#include "signal_receiver.hh"
+//#include "signal_receiver.hh"
 
 namespace pkgmgr {
 namespace client {
@@ -37,14 +39,14 @@ namespace pp = rpc_port::PkgMgrProxy;
 
 class Connector {
  public:
-  Connector(pkgmgr_client_type pc_type) : pc_type_(pc_type) {}
+  Connector(pkgmgr_client_type pc_type, pkgmgr_client_t* raw_pc = nullptr) : pc_type_(pc_type), raw_pc_(raw_pc) {}
   virtual ~Connector();
 
   virtual pkg_proxy::PkgMgrAdmin* GetAdminProxy();
   virtual pkg_proxy::PkgMgr* GetInfoProxy();
   virtual pkg_proxy::PkgMgrForClearCache* GetCacheProxy();
   virtual pkg_proxy::DelayedResult* GetDelayedResultProxy();
-  virtual const std::unique_ptr<SignalReceiver>& GetSignalReceiver();
+//  virtual const std::unique_ptr<SignalReceiver>& GetSignalReceiver();
   std::string GenerateRequestId() const;
   void SetTep(std::string tep_path, bool tep_move);
   void SetTepArgs();
@@ -57,6 +59,7 @@ class Connector {
   std::vector<pp::ResPath>& GetResCopyPath();
   const std::string& GetTepPath();
   bool GetTepMove();
+  pkgmgr_client_t* GetRawPc();
 
  private:
   bool ConnectForAdmin();
@@ -90,11 +93,12 @@ class Connector {
   ConnectionEventListener<pkg_proxy::PkgMgr> conn_info_listener_;
   ConnectionEventListener<pkg_proxy::PkgMgrForClearCache> conn_cache_listener_;
   ConnectionEventListener<pkg_proxy::DelayedResult> conn_delayed_result_listener_;
-  std::unique_ptr<SignalReceiver> signal_receiver_;
+//  std::unique_ptr<SignalReceiver> signal_receiver_;
   std::vector<std::string> res_remove_path_;
   std::vector<std::string> res_create_dir_;
   std::vector<pp::ResPath> res_copy_path_;
   std::string tep_path_;
+  pkgmgr_client_t *raw_pc_;
   bool tep_move_ = false;
   Activator activator_;
 };
diff --git a/client/src/pkgmgr_client_connection.c b/client/src/pkgmgr_client_connection.c
new file mode 100644 (file)
index 0000000..5703d77
--- /dev/null
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "package-manager.h"
+#include "pkgmgr_client_debug.h"
+#include "pkgmgr_client_internal.h"
+#include "../../installer/src/pkgmgr_installer.h"
+#include "../../installer/pkgmgr_installer_config.h"
+
+#define CONNECTION_RETRY_MAX 5
+#define CONNECTION_WAIT_USEC (1000000 / 2) /* 0.5 sec */
+#define CONNECTION_TIMEOUT_MSEC 5000 /* 5 sec */
+#define REGULAR_USER 5000
+
+static int _is_system_user(void)
+{
+       uid_t uid = getuid();
+
+       if (uid < REGULAR_USER)
+               return 1;
+       else
+               return 0;
+}
+
+static GBusType __get_bus_type(pkgmgr_client_type type)
+{
+       if (type == PC_REQUEST || _is_system_user())
+               return G_BUS_TYPE_SYSTEM;
+       else
+               return G_BUS_TYPE_SESSION;
+}
+
+int pkgmgr_client_connection_connect(struct pkgmgr_client_t *pc)
+{
+       GError *error = NULL;
+       GBusType bus_type;
+
+#if !GLIB_CHECK_VERSION(2, 35, 0)
+       g_type_init();
+#endif
+       bus_type = __get_bus_type(pc->pc_type);
+       pc->conn = g_bus_get_sync(bus_type, NULL, &error);
+       if (error) {
+               ERR("gdbus connection error (%s)", error->message);
+               g_error_free(error);
+               return PKGMGR_R_ECOMM;
+       }
+
+       return PKGMGR_R_OK;
+}
+
+void pkgmgr_client_connection_disconnect(struct pkgmgr_client_t *pc)
+{
+       /* flush remaining buffer: blocking mode */
+       g_dbus_connection_flush_sync(pc->conn, NULL, NULL);
+       g_object_unref(pc->conn);
+       pc->conn = NULL;
+}
+
+struct signal_map {
+       const char *signal_str;
+       int signal_type;
+};
+
+struct signal_map map[] = {
+       {PKGMGR_INSTALLER_INSTALL_EVENT_STR, PKGMGR_CLIENT_STATUS_INSTALL},
+       {PKGMGR_INSTALLER_UNINSTALL_EVENT_STR, PKGMGR_CLIENT_STATUS_UNINSTALL},
+       {PKGMGR_INSTALLER_UPGRADE_EVENT_STR, PKGMGR_CLIENT_STATUS_UPGRADE},
+       {PKGMGR_INSTALLER_CLEAR_EVENT_STR, PKGMGR_CLIENT_STATUS_CLEAR_DATA},
+       {PKGMGR_INSTALLER_MOVE_EVENT_STR, PKGMGR_CLIENT_STATUS_MOVE},
+       {PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR,
+               PKGMGR_CLIENT_STATUS_INSTALL_PROGRESS},
+       {PKGMGR_INSTALLER_GET_SIZE_KEY_STR, PKGMGR_CLIENT_STATUS_GET_SIZE},
+       {PKGMGR_INSTALLER_CLEAR_CACHE_KEY_STR,
+               PKGMGR_CLIENT_STATUS_CLEAR_CACHE},
+       {PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR,
+               PKGMGR_CLIENT_STATUS_ENABLE_APP},
+       {PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR,
+               PKGMGR_CLIENT_STATUS_DISABLE_APP},
+       {PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR,
+               PKGMGR_CLIENT_STATUS_ENABLE_APP_SPLASH_SCREEN},
+       {PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR,
+               PKGMGR_CLIENT_STATUS_DISABLE_APP_SPLASH_SCREEN},
+       {PKGMGR_INSTALLER_RES_COPY_EVENT_STR, PKGMGR_CLIENT_STATUS_RES_COPY},
+       {PKGMGR_INSTALLER_RES_CREATE_DIR_EVENT_STR,
+               PKGMGR_CLIENT_STATUS_RES_CREATE_DIR},
+       {PKGMGR_INSTALLER_RES_REMOVE_EVENT_STR,
+               PKGMGR_CLIENT_STATUS_RES_REMOVE},
+       {PKGMGR_INSTALLER_RES_UNINSTALL_EVENT_STR,
+               PKGMGR_CLIENT_STATUS_RES_UNINSTALL},
+       {NULL, -1}
+};
+
+static int __get_signal_type(const char *name)
+{
+       int i;
+
+       if (name == NULL)
+               return -1;
+
+       for (i = 0; map[i].signal_str != NULL; i++) {
+               if (strcmp(map[i].signal_str, name) == 0)
+                       return map[i].signal_type;
+       }
+
+       return -1;
+}
+
+static void __handle_size_info_callback(struct cb_info *cb_info,
+               const char *pkgid, const char *val)
+{
+       pkg_size_info_t size_info;
+       char buf[BUFMAX];
+       char *saveptr;
+       char *token;
+       pkgmgr_total_pkg_size_info_receive_cb callback;
+
+       snprintf(buf, sizeof(buf), "%s", val);
+
+       DBG("%s, %s", pkgid, val);
+
+       token = strtok_r(buf, ":", &saveptr);
+       if (token == NULL) {
+               ERR("failed to parse size info");
+               return;
+       }
+       size_info.data_size = atoll(token);
+       token = strtok_r(NULL, ":", &saveptr);
+       if (token == NULL) {
+               ERR("failed to parse size info");
+               return;
+       }
+       size_info.cache_size = atoll(token);
+       token = strtok_r(NULL, ":", &saveptr);
+       if (token == NULL) {
+               ERR("failed to parse size info");
+               return;
+       }
+       size_info.app_size = atoll(token);
+       token = strtok_r(NULL, ":", &saveptr);
+       if (token == NULL) {
+               ERR("failed to parse size info");
+               return;
+       }
+       size_info.ext_data_size = atoll(token);
+       token = strtok_r(NULL, ":", &saveptr);
+       if (token == NULL) {
+               ERR("failed to parse size info");
+               return;
+       }
+       size_info.ext_cache_size = atoll(token);
+       token = strtok_r(NULL, ":", &saveptr);
+       if (token == NULL) {
+               ERR("failed to parse size info");
+               return;
+       }
+       size_info.ext_app_size = atoll(token);
+
+       DBG("data: %lld, cache: %lld, app: %lld, ext_data: %lld, "
+                       "ext_cache: %lld, ext_app: %lld",
+                       size_info.data_size, size_info.cache_size,
+                       size_info.app_size, size_info.ext_data_size,
+                       size_info.ext_cache_size, size_info.ext_app_size);
+
+       if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0) {
+               callback = (pkgmgr_total_pkg_size_info_receive_cb)
+                       cb_info->size_info_cb;
+               callback(cb_info->client, &size_info, cb_info->data);
+       } else {
+               cb_info->size_info_cb(cb_info->client, pkgid, &size_info,
+                               cb_info->data);
+       }
+}
+
+static void __handle_pkg_signal(const gchar *signal_name,
+               GVariant *parameters, gpointer user_data)
+{
+       uid_t target_uid;
+       char *req_id;
+       char *pkg_type = NULL;
+       char *appid = NULL;
+       char *pkgid = NULL;
+       char *key = NULL;
+       char *val = NULL;
+       struct cb_info *cb_info = (struct cb_info *)user_data;
+       GVariantIter *iter = NULL;
+       int signal_type;
+
+       g_variant_get(parameters, "(u&sa(sss)&s&s)", &target_uid, &req_id, &iter,
+                       &key, &val);
+       while (g_variant_iter_loop(iter, "(&s&s&s)", &pkgid, &appid, &pkg_type)) {
+               if (cb_info->req_key) {
+                       if (strcmp(cb_info->req_key, req_id) != 0)
+                               continue;
+               } else {
+                       signal_type = __get_signal_type(signal_name);
+                       if (signal_type < 0 || !(cb_info->status_type & signal_type)) {
+                               g_variant_iter_free(iter);
+                               return;
+                       }
+               }
+
+               /* each cb_data can only has one callback */
+               if (cb_info->event_cb) {
+                       cb_info->event_cb(target_uid, cb_info->req_id,
+                                       pkg_type, pkgid, key, val, NULL, cb_info->data);
+               } else if (cb_info->app_event_cb && strcmp(appid, "") != 0) {
+                       cb_info->app_event_cb(target_uid, cb_info->req_id,
+                                       pkg_type, pkgid, appid, key, val, NULL,
+                                       cb_info->data);
+               } else if (cb_info->size_info_cb) {
+                       __handle_size_info_callback(cb_info, pkgid, val);
+               }
+
+               /* TODO: unsubscribe request callback */
+       }
+       g_variant_iter_free(iter);
+}
+
+static void __handle_res_event_signal(const gchar *signal_name,
+               GVariant *parameters, gpointer user_data)
+{
+       uid_t target_uid;
+       char *req_id;
+       char *pkgid = NULL;
+       char *status = NULL;
+       char *path = NULL;
+       pkgmgr_res_event_path_state state;
+       struct cb_info *cb_info = (struct cb_info *)user_data;
+       int signal_type;
+       GVariant *extra_param = NULL;
+       pkgmgr_res_event_info_t *event_info;
+       GVariantIter *iter;
+
+       if (!cb_info->res_event_cb)
+               return;
+
+       g_variant_get(parameters, "(u&s&s&sv)", &target_uid, &req_id, &pkgid, &status, &extra_param);
+       if (!g_variant_type_equal(G_VARIANT_TYPE("(ia(si))"),
+                       g_variant_get_type(extra_param))) {
+               ERR("invalid extra parameter");
+               g_variant_unref(extra_param);
+               return;
+       }
+       if (cb_info->req_key) {
+               if (strcmp(cb_info->req_key, req_id) != 0) {
+                       g_variant_unref(extra_param);
+                       return;
+               }
+       } else {
+               signal_type = __get_signal_type(signal_name);
+               if (signal_type < 0 || !(cb_info->status_type & signal_type)) {
+                       g_variant_unref(extra_param);
+                       return;
+               }
+       }
+
+       event_info = pkgmgr_res_event_info_new();
+       if (event_info == NULL) {
+               ERR("out of memory");
+               g_variant_unref(extra_param);
+               return;
+       }
+
+       g_variant_get(extra_param, "(ia(si))", &event_info->error_code, &iter);
+
+       while (g_variant_iter_loop(iter, "(&si)", &path, &state)) {
+               if (pkgmgr_res_event_info_add_path_state(event_info,
+                               path, state) != PKGMGR_R_OK) {
+                       ERR("Fail to add path state");
+                       g_variant_unref(extra_param);
+                       g_variant_iter_free(iter);
+                       pkgmgr_res_event_info_free(event_info);
+                       return;
+               }
+       }
+       cb_info->res_event_cb(target_uid, cb_info->req_id, pkgid, signal_name,
+                       status, event_info, cb_info->data);
+       g_variant_unref(extra_param);
+       g_variant_iter_free(iter);
+       pkgmgr_res_event_info_free(event_info);
+}
+
+static void __handle_pkg_upgrade_event_signal(const gchar *signal_name,
+               GVariant *parameters, gpointer user_data)
+{
+       guint32 progress;
+       struct cb_info *cb_info = (struct cb_info *)user_data;
+
+       if (!cb_info->upgrade_event_cb)
+               return;
+
+       if (strcmp(signal_name, PKGMGR_INSTALLER_PKG_UPGRADE_EVENT_STR) != 0) {
+               return;
+       }
+
+       g_variant_get(parameters, "(u)", &progress);
+       cb_info->upgrade_event_cb(progress, cb_info->data);
+}
+
+static void __signal_handler(GDBusConnection *conn, const gchar *sender_name,
+               const gchar *object_path, const gchar *interface_name,
+               const gchar *signal_name, GVariant *parameters,
+               gpointer user_data)
+{
+       if (g_variant_type_equal(G_VARIANT_TYPE("(usa(sss)ss)"),
+                       g_variant_get_type(parameters))) {
+               __handle_pkg_signal(signal_name, parameters, user_data);
+       } else if (!strcmp(signal_name, PKGMGR_INSTALLER_RES_COPY_EVENT_STR) ||
+                       !strcmp(signal_name, PKGMGR_INSTALLER_RES_REMOVE_EVENT_STR) ||
+                       !strcmp(signal_name, PKGMGR_INSTALLER_RES_UNINSTALL_EVENT_STR) ||
+                       !strcmp(signal_name, PKGMGR_INSTALLER_RES_CREATE_DIR_EVENT_STR)) {
+               __handle_res_event_signal(signal_name, parameters, user_data);
+       } else if (!strcmp(signal_name, PKGMGR_INSTALLER_PKG_UPGRADE_EVENT_STR)) {
+               __handle_pkg_upgrade_event_signal(signal_name, parameters, user_data);
+       }
+}
+
+static void __set_signal_list(int event, GList **signal_list)
+{
+       int i;
+       if (event == PKGMGR_CLIENT_STATUS_ALL)
+               return;
+
+       for (i = 0; map[i].signal_str != NULL; i++) {
+               if (event & map[i].signal_type)
+                       *signal_list = g_list_append(*signal_list,
+                                       (char *)map[i].signal_str);
+       }
+}
+
+static int __subscribe_signal(struct pkgmgr_client_t *pc,
+               struct cb_info *cb_info, const char *signal)
+{
+       guint sid = g_dbus_connection_signal_subscribe(pc->conn, NULL,
+                       PKGMGR_INSTALLER_DBUS_INTERFACE, signal,
+                       PKGMGR_INSTALLER_DBUS_OBJECT_PATH, NULL,
+                       G_DBUS_SIGNAL_FLAGS_NONE, __signal_handler,
+                       (gpointer)cb_info, NULL);
+       if (!sid) {
+               ERR("failed to subscribe singal");
+               return PKGMGR_R_ERROR;
+       }
+       cb_info->sid_list = g_list_append(cb_info->sid_list,
+                       GUINT_TO_POINTER(sid));
+
+       return PKGMGR_R_OK;
+}
+
+int pkgmgr_client_connection_set_callback(struct pkgmgr_client_t *pc,
+               struct cb_info *cb_info)
+{
+       GList *signal_list = NULL;
+       GList *tmp_list = NULL;
+       int ret;
+       char *signal_type;
+       __set_signal_list(pc->status_type, &signal_list);
+
+       if (g_list_length(signal_list) == 0)
+               return __subscribe_signal(pc, cb_info, NULL);
+
+       for (tmp_list = signal_list; tmp_list != NULL;
+                       tmp_list = g_list_next(tmp_list)) {
+               signal_type = (char *)tmp_list->data;
+               ret = __subscribe_signal(pc, cb_info, signal_type);
+               if (ret != 0) {
+                       g_list_free(signal_list);
+                       return PKGMGR_R_ERROR;
+               }
+       }
+
+       g_list_free(signal_list);
+       return PKGMGR_R_OK;
+}
+
+void pkgmgr_client_connection_unset_callback(struct pkgmgr_client_t *pc,
+               struct cb_info *cb_info)
+{
+       GList *tmp = NULL;
+       guint tmp_sid;
+       for (tmp = cb_info->sid_list; tmp != NULL; tmp = g_list_next(tmp)) {
+               tmp_sid = GPOINTER_TO_UINT(tmp->data);
+               g_dbus_connection_signal_unsubscribe(pc->conn, tmp_sid);
+       }
+}
+
+int pkgmgr_client_connection_send_request(struct pkgmgr_client_t *pc,
+               const char *method, GVariant *params, GVariant **result)
+{
+       GError *error = NULL;
+       GDBusProxy *proxy;
+       GVariant *r = NULL;
+       int retry_cnt = 0;
+       int ret = PKGMGR_R_ECOMM;
+
+       /* convert floating ref into normal ref */
+       g_variant_ref_sink(params);
+
+       do {
+               proxy = g_dbus_proxy_new_sync(pc->conn,
+                               G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+                               NULL, PKGMGR_DBUS_SERVICE,
+                               PKGMGR_DBUS_OBJECT_PATH,
+                               PKGMGR_DBUS_INTERFACE, NULL, &error);
+               if (proxy == NULL) {
+                       ERR("failed to get proxy object, sleep and retry[%s]",
+                                       error->message);
+                       g_error_free(error);
+                       error = NULL;
+                       usleep(CONNECTION_WAIT_USEC);
+                       retry_cnt++;
+                       continue;
+               }
+
+               r = g_dbus_proxy_call_sync(proxy, method, params,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               CONNECTION_TIMEOUT_MSEC, NULL, &error);
+               g_object_unref(proxy);
+               if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) {
+                       ERR("failed to send request, privilege denied[%s]",
+                                       error->message);
+                       g_error_free(error);
+                       ret = PKGMGR_R_EPRIV;
+                       break;
+               }
+               if (r) {
+                       *result = r;
+                       ret = PKGMGR_R_OK;
+                       break;
+               }
+
+               ERR("failed to send request, sleep and retry[%s]",
+                               error->message);
+               g_error_free(error);
+               error = NULL;
+               usleep(CONNECTION_WAIT_USEC);
+               retry_cnt++;
+       } while (retry_cnt <= CONNECTION_RETRY_MAX);
+
+       /* decrease ref count to 0 to free resource */
+       g_variant_unref(params);
+
+       return ret;
+}
diff --git a/client/src/pkgmgr_client_debug.h b/client/src/pkgmgr_client_debug.h
new file mode 100644 (file)
index 0000000..b81f948
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+  * Contact: junsuk. oh <junsuk77.oh@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __PKGMGR_CLIENT_DEBUG_H__
+#define __PKGMGR_CLIENT_DEBUG_H__
+
+#include <dlog.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif /* LOG_TAG */
+#define LOG_TAG "PKGMGR"
+
+#ifndef ERR
+#define ERR(fmt, args...) LOGE("[%s:%d] "fmt"\n", __func__, __LINE__, ##args)
+#endif
+
+#ifndef DBG
+#define DBG(fmt, args...) LOGD("[%s:%d] "fmt"\n", __func__, __LINE__, ##args)
+#endif
+
+#ifndef INFO
+#define INFO(fmt, args...) LOGI("[%s:%d] "fmt"\n", __func__, __LINE__, ##args)
+#endif
+
+#define ret_if(expr) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) ", #expr); \
+                       return; \
+               } \
+       } while (0)
+
+#define retm_if(expr, fmt, arg...) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) "fmt, #expr, ##arg); \
+                       return; \
+               } \
+       } while (0)
+
+#define retv_if(expr, val) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) ", #expr); \
+                       return (val); \
+               } \
+       } while (0)
+
+#define retvm_if(expr, val, fmt, arg...) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) "fmt, #expr, ##arg); \
+                       return (val); \
+               } \
+       } while (0)
+
+#define trym_if(expr, fmt, arg...) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) "fmt, #expr, ##arg); \
+                       goto catch; \
+               } \
+       } while (0)
+
+#define tryvm_if(expr, val, fmt, arg...) \
+       do { \
+               if (expr) { \
+                       ERR("(%s) "fmt, #expr, ##arg); \
+                       val; \
+                       goto catch; \
+               } \
+       } while (0)
+
+#endif  /* __PKGMGR_CLIENT_DEBUG_H__ */
diff --git a/client/src/pkgmgr_client_internal.c b/client/src/pkgmgr_client_internal.c
new file mode 100644 (file)
index 0000000..da4d5a7
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * slp-pkgmgr
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
+ * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <xdgmime.h>
+
+#include <unistd.h>
+#include <dlfcn.h>
+#include <sys/time.h>
+#include <tzplatform_config.h>
+#include <pkgmgr-info.h>
+
+#include "package-manager.h"
+#include "pkgmgr_client_debug.h"
+#include "pkgmgr_client_internal.h"
+
+#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
+
+#define IS_WHITESPACE(CHAR) \
+       ((CHAR == ' ' || CHAR == '\t' || CHAR == '\r' || CHAR == '\n') ? \
+       true : false)
+
+void _app_str_trim(char *input)
+{
+       char *trim_str = input;
+
+       if (input == NULL)
+               return;
+
+       while (*input != 0) {
+               if (!IS_WHITESPACE(*input)) {
+                       *trim_str = *input;
+                       trim_str++;
+               }
+               input++;
+       }
+
+       *trim_str = 0;
+       return;
+}
+
+static pkg_plugin_set *plugin_set_list[24] = { 0, };
+
+pkg_plugin_set *_pkg_plugin_load_library(const char *pkg_type,
+               const char *library_path)
+{
+       void *library_handle;
+       int i;
+       bool (*on_load)(pkg_plugin_set *plugin);
+
+       if (library_path == NULL || pkg_type == NULL) {
+               ERR("invalid parameter");
+               return NULL;
+       }
+
+       for (i = 0; plugin_set_list[i]; i++) {
+               if (strcmp(plugin_set_list[i]->pkg_type, pkg_type) == 0) {
+                       DBG("already loaded [%s]", library_path);
+                       return plugin_set_list[i];
+               }
+       }
+
+       if ((library_handle = dlopen(library_path, RTLD_LAZY)) == NULL) {
+               ERR("dlopen is failed library_path[%s]", library_path);
+               return NULL;
+       }
+
+       if ((on_load = dlsym(library_handle, "pkg_plugin_on_load")) == NULL ||
+                       dlerror() != NULL) {
+               ERR("can not find symbol");
+               dlclose(library_handle);
+               return NULL;
+       }
+
+       plugin_set_list[i] = (pkg_plugin_set *)calloc(1, sizeof(pkg_plugin_set));
+       if (plugin_set_list[i] == NULL) {
+               ERR("malloc of the plugin_set_list element is failed");
+               dlclose(library_handle);
+               return NULL;
+       }
+
+       if (on_load(plugin_set_list[i]) != 0) {
+               ERR("pkg_plugin_on_load failed");
+               free(plugin_set_list[i]);
+               dlclose(library_handle);
+               plugin_set_list[i] = NULL;
+               return NULL;
+       }
+
+       plugin_set_list[i]->plugin_handle = library_handle;
+       snprintf(plugin_set_list[i]->pkg_type,
+                       sizeof(plugin_set_list[i]->pkg_type), "%s", pkg_type);
+
+       DBG("library [%s] is loaded", library_path);
+
+       return plugin_set_list[i];
+}
+
+int _pkg_plugin_get_library_path(const char *pkg_type, char *library_path)
+{
+       FILE *fp = NULL;
+       char buffer[1024] = { 0 };
+
+       if (pkg_type == NULL || library_path == NULL) {
+               ERR("invalid argument\n");
+               return -1;
+       }
+
+       fp = fopen(PKG_CONF_PATH, "r");
+       if (fp == NULL) {
+               ERR("no matching backendlib\n");
+               return PKGMGR_R_ERROR;
+       }
+
+       char *path = NULL;
+       while (fgets(buffer, 1024, fp) != NULL) {
+               if (buffer[0] == '#')
+                       continue;
+
+               _app_str_trim(buffer);
+
+               if ((path = strstr(buffer, PKG_BACKENDLIB)) != NULL) {
+                       DBG("[%s]\n", buffer);
+                       DBG("[%s]\n", path);
+                       path = path + strlen(PKG_BACKENDLIB);
+                       DBG("[%s]\n", path);
+
+                       break;
+               }
+
+               memset(buffer, 0x00, 1024);
+       }
+
+       if (fp != NULL)
+               fclose(fp);
+
+       if (path == NULL) {
+               ERR("no matching backendlib\n");
+               return PKGMGR_R_ERROR;
+       }
+
+       snprintf(library_path, 1024, "%slib%s.so", path, pkg_type);
+
+       return PKGMGR_R_OK;
+
+}
+
+pkg_plugin_set *_package_manager_load_library(const char *pkg_type)
+{
+       char package_path[1024] = { 0, };
+       pkg_plugin_set *plugin_set;
+
+       if (pkg_type == NULL) {
+               ERR("cannot load library - pkg_type is null");
+               return NULL;
+       }
+
+       if (_pkg_plugin_get_library_path(pkg_type, package_path) !=
+                       PKGMGR_R_OK) {
+               ERR("cannot find path");
+               return NULL;
+       }
+
+       plugin_set = _pkg_plugin_load_library(pkg_type, package_path);
+       if (plugin_set == NULL) {
+               ERR("cannot load library");
+               return NULL;
+       }
+
+       return plugin_set;
+}
diff --git a/client/src/pkgmgr_client_internal.h b/client/src/pkgmgr_client_internal.h
new file mode 100644 (file)
index 0000000..90ec62f
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * slp-pkgmgr
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
+ * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __PKGMGR_CLIENT_INTERNAL_H__
+#define __PKGMGR_CLIENT_INTERNAL_H__
+
+#include <unistd.h>
+#include <ctype.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "package-manager-plugin.h"
+#include "package-manager.h"
+
+#define BUFMAX 4096
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct cb_info {
+       int req_id;
+       char *req_key;
+       int status_type;
+       pkgmgr_handler event_cb;
+       pkgmgr_app_handler app_event_cb;
+       pkgmgr_pkg_size_info_receive_cb size_info_cb;
+       pkgmgr_res_handler res_event_cb;
+       pkgmgr_pkg_upgrade_handler upgrade_event_cb;
+       void *data;
+       struct pkgmgr_client_t *client;
+       GList *sid_list;
+};
+
+struct pkgmgr_client_t {
+       pkgmgr_client_type pc_type;
+       int status_type;
+       GDBusConnection *conn;
+       GList *cb_info_list;
+       GVariantBuilder *res_copy_builder;
+       GVariantBuilder *res_remove_builder;
+       GVariantBuilder *res_create_dir_builder;
+       char *tep_path;
+       bool tep_move;
+       bool debug_mode;
+       bool skip_optimization;
+};
+
+struct manifest_and_type {
+       const char *manifest;
+       const char *type;
+};
+
+int pkgmgr_client_connection_connect(struct pkgmgr_client_t *pc);
+void pkgmgr_client_connection_disconnect(struct pkgmgr_client_t *pc);
+int pkgmgr_client_connection_set_callback(struct pkgmgr_client_t *pc,
+               struct cb_info *cb_info);
+void pkgmgr_client_connection_unset_callback(struct pkgmgr_client_t *pc,
+               struct cb_info *cb_info);
+int pkgmgr_client_connection_send_request(struct pkgmgr_client_t *pc,
+               const char *method, GVariant *params, GVariant **result);
+
+pkg_plugin_set *_pkg_plugin_load_library(const char *pkg_type,
+                                        const char *library_path);
+
+int _pkg_plugin_get_library_path(const char *pkg_type, char *library_path);
+
+pkg_plugin_set *_package_manager_load_library(const char *pkg_type);
+
+#define PKG_BACKENDLIB "backendlib:"
+#define PKG_CONF_PATH  "/etc/package-manager/pkg_path.conf"
+
+void _app_str_trim(char *input);
+
+#ifdef __cplusplus
+}
+#endif
+#endif                         /* __PKGMGR_CLIENT_INTERNAL_H__ */
index 8e3c230..b667763 100644 (file)
@@ -50,7 +50,7 @@ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/pkgmgr_installer_type.h DESTINATIO
 INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgmgr-installer.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
 
 ## pkgmgr_installer_signal_agent
-ADD_EXECUTABLE(pkgmgr-installer-signal-agent pkgmgr_installer_signal_agent.cc)
+ADD_EXECUTABLE(pkgmgr-installer-signal-agent pkgmgr_installer_signal_agent.c)
 SET_TARGET_PROPERTIES(pkgmgr-installer-signal-agent PROPERTIES COMPILE_FLAGS "${AGENT_CFLAGS} -fPIE")
 TARGET_LINK_LIBRARIES(pkgmgr-installer-signal-agent PRIVATE pkgmgr_installer)
 TARGET_LINK_LIBRARIES(pkgmgr-installer-signal-agent ${AGENT_DEPS_LDFLAGS} "-pie")
diff --git a/installer/pkgmgr_installer_config.h b/installer/pkgmgr_installer_config.h
new file mode 100644 (file)
index 0000000..320620b
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * slp-pkgmgr
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
+ * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __PACKAGE_INSTALLER_CONFIG_H__
+#define __PACKAGE_INSTALLER_CONFIG_H__
+
+#define PKGMGR_DBUS_SERVICE "org.tizen.pkgmgr"
+#define PKGMGR_DBUS_INTERFACE "org.tizen.pkgmgr"
+#define PKGMGR_DBUS_OBJECT_PATH "/org/tizen/pkgmgr"
+
+#define PKGMGR_INSTALLER_DBUS_INTERFACE "org.tizen.pkgmgr.signal"
+#define PKGMGR_INSTALLER_DBUS_OBJECT_PATH "/org/tizen/pkgmgr/signal"
+
+#endif                         /* __PACKAGE_INSTALLER_CONFIG_H__ */
diff --git a/installer/pkgmgr_installer_signal_agent.c b/installer/pkgmgr_installer_signal_agent.c
new file mode 100644 (file)
index 0000000..bb82be1
--- /dev/null
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <linux/limits.h>
+#include <pwd.h>
+
+#include <glib.h>
+#include <glib-unix.h>
+#include <gio/gio.h>
+#include <systemd/sd-daemon.h>
+
+#include <dlog.h>
+
+#include "pkgmgr_installer_config.h"
+#include "src/pkgmgr_installer_type.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "PKGMGR_INSTALLER_SIGNAL_AGENT"
+
+#define BUFMAX 4096
+#define PWBUFSIZE sysconf(_SC_GETPW_R_SIZE_MAX)
+#define APPFW_USERNAME "app_fw"
+
+static int server_fd = -1;
+static GMainLoop *loop;
+static guint sid;
+static guint tid;
+static GDBusConnection *conn;
+
+static int __create_server_socket(const char *path)
+{
+       int r;
+       int fd;
+       struct sockaddr_un sa;
+
+       fd = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (fd == -1) {
+               LOGE("socket create failed: %d", errno);
+               return -1;
+       }
+
+       memset(&sa, 0, sizeof(sa));
+       sa.sun_family = AF_UNIX;
+       snprintf(sa.sun_path, sizeof(sa.sun_path), "%s", path);
+
+       r = unlink(sa.sun_path);
+       if (r == -1 && errno != ENOENT) {
+               LOGE("unlink(%s) failed: %d", sa.sun_path, errno);
+               close(fd);
+               return -1;
+       }
+
+       r = bind(fd, (struct sockaddr *)&sa, sizeof(sa));
+       if (r == -1) {
+               LOGE("bind(%s) failed: %d", sa.sun_path, errno);
+               close(fd);
+               return -1;
+       }
+
+       r = chmod(sa.sun_path, 0660);
+       if (r == -1)
+               LOGW("chmod(%s) failed: %d", sa.sun_path, errno);
+
+       r = listen(fd, SOMAXCONN);
+       if (r == -1) {
+               LOGE("listen(%s) failed: %d", sa.sun_path, errno);
+               close(fd);
+               return -1;
+       }
+
+       return fd;
+}
+
+static int __get_server_socket(const char *path)
+{
+       int i;
+       int n;
+       int r;
+       int fd = -1;
+
+       n = sd_listen_fds(0);
+       if (n < 0) {
+               LOGE("sd_listen_fds: %d", n);
+               return -1;
+       } else if (n == 0) {
+               return __create_server_socket(path);
+       }
+
+       for (i = SD_LISTEN_FDS_START; i < SD_LISTEN_FDS_START + n; i++) {
+               r = sd_is_socket_unix(i, SOCK_STREAM, -1, path, 0);
+               if (r > 0) {
+                       fd = i;
+                       break;
+               }
+       }
+
+       if (fd == -1) {
+               LOGE("socket is not passed, create server socket");
+               return __create_server_socket(path);
+       }
+
+       return fd;
+}
+
+static void __emit_signal(const char *name, GVariant *gv)
+{
+       GError *err = NULL;
+
+       if (g_dbus_connection_emit_signal(conn, NULL,
+                               PKGMGR_INSTALLER_DBUS_OBJECT_PATH,
+                               PKGMGR_INSTALLER_DBUS_INTERFACE,
+                               name, gv, &err) != TRUE) {
+               LOGE("g_dbus_connection_emit_signal failed: %s", err->message);
+               g_error_free(err);
+       }
+}
+
+static gboolean __quit(gpointer user_data)
+{
+       g_main_loop_quit(loop);
+       return FALSE;
+}
+
+static int __check_authority(int fd)
+{
+       int r;
+       struct ucred cr;
+       socklen_t len;
+       struct passwd pwd;
+       struct passwd *pwd_r;
+       char buf[PWBUFSIZE];
+
+       len = sizeof(struct ucred);
+       r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
+       if (r != 0) {
+               LOGE("getsockopt failed: %d", errno);
+               return -1;
+       }
+
+       /* allow root user */
+       if (cr.uid == 0)
+               return 0;
+
+       r = getpwuid_r(cr.uid, &pwd, buf, sizeof(buf), &pwd_r);
+       if (r != 0 || pwd_r == NULL) {
+               LOGE("getpwuid failed: %d", r);
+               return -1;
+       }
+
+       /* only app_fw user can send signal to agent */
+       if (strcmp(pwd_r->pw_name, APPFW_USERNAME) != 0) {
+               LOGE("unauthorized client");
+               return -1;
+       }
+
+       return 0;
+}
+
+/**
+ * packet format:
+ * +----------------+-------------+-----------+-------------------+
+ * |signal name size|GVariant size|signal name|serialized GVariant|
+ * +----------------+-------------+-----------+-------------------+
+ */
+static gboolean __handle_signal(gint fd, GIOCondition cond, gpointer user_data)
+{
+       int r;
+       unsigned char buf[BUFMAX];
+       int clifd;
+       struct sockaddr_un sa;
+       socklen_t s = sizeof(sa);
+       size_t type_len;
+       char *type_name;
+       gsize data_len;
+       gpointer data;
+       GVariant *gv;
+
+       clifd = accept(fd, (struct sockaddr *)&sa, &s);
+       if (clifd == -1) {
+               LOGE("accept failed: %d", errno);
+               return FALSE;
+       }
+
+       if (__check_authority(clifd)) {
+               close(clifd);
+               return TRUE;
+       }
+
+       r = recv(clifd, buf, sizeof(size_t) + sizeof(gsize), 0);
+       if (r < 0) {
+               LOGE("recv failed: %d", errno);
+               close(clifd);
+               return FALSE;
+       } else if (r == 0) {
+               LOGE("client fd already closed");
+               close(clifd);
+               return FALSE;
+       }
+
+       memcpy(&type_len, buf, sizeof(size_t));
+       memcpy(&data_len, buf + sizeof(size_t), sizeof(gsize));
+
+       if (type_len > BUFMAX || data_len > BUFMAX ||
+                       (type_len + data_len) > BUFMAX) {
+               LOGE("received size is too large: %zu %zu", type_len, data_len);
+               close(clifd);
+               return FALSE;
+       }
+
+       r = recv(clifd, buf, type_len + data_len, 0);
+       if (r < 0) {
+               LOGE("recv failed: %d", errno);
+               close(clifd);
+               return FALSE;
+       } else if (r == 0) {
+               LOGE("client fd already closed");
+               close(clifd);
+               return FALSE;
+       }
+
+       if (type_len == 0) {
+               LOGE("invalid type_len");
+               close(clifd);
+               return FALSE;
+       }
+
+       /* get signal name (including terminating null byte) */
+       type_name = malloc(type_len);
+       memcpy(type_name, buf, type_len);
+
+       /* get data */
+       data = malloc(data_len);
+       memcpy(data, buf + type_len, data_len);
+
+       /* floating type GVariant instance */
+       if (!strcmp(type_name, PKGMGR_INSTALLER_RES_COPY_EVENT_STR) ||
+               !strcmp(type_name, PKGMGR_INSTALLER_RES_CREATE_DIR_EVENT_STR) ||
+               !strcmp(type_name, PKGMGR_INSTALLER_RES_REMOVE_EVENT_STR) ||
+               !strcmp(type_name, PKGMGR_INSTALLER_RES_UNINSTALL_EVENT_STR)) {
+               gv = g_variant_new_from_data(G_VARIANT_TYPE("(usssv)"),
+                               data, data_len, TRUE, NULL, NULL);
+       } else {
+               gv = g_variant_new_from_data(G_VARIANT_TYPE("(usa(sss)ss)"),
+                               data, data_len, TRUE, NULL, NULL);
+       }
+       __emit_signal(type_name, gv);
+
+       free(data);
+       free(type_name);
+       close(clifd);
+
+       /* renew timeout */
+       g_source_remove(tid);
+       tid = g_timeout_add_seconds(10, __quit, NULL);
+
+       return TRUE;
+}
+
+static int __init(void)
+{
+       char path[PATH_MAX];
+       GError *err = NULL;
+
+       snprintf(path, sizeof(path), "/run/pkgmgr/agent/%d", getuid());
+       server_fd = __get_server_socket(path);
+       if (server_fd < 0) {
+               LOGE("server init failed");
+               return -1;
+       }
+
+       conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &err);
+       if (conn == NULL) {
+               LOGE("g_bus_get_sync failed: %s", err->message);
+               g_error_free(err);
+               close(server_fd);
+               return -1;
+       }
+
+       loop = g_main_loop_new(NULL, FALSE);
+       sid = g_unix_fd_add(server_fd, G_IO_IN, __handle_signal, NULL);
+       tid = g_timeout_add_seconds(10, __quit, NULL);
+
+       return 0;
+}
+
+static void __fini(void)
+{
+       if (sid > 0)
+               g_source_remove(sid);
+       if (loop)
+               g_main_loop_unref(loop);
+       if (conn)
+               g_object_unref(conn);
+       if (server_fd > 0)
+               close(server_fd);
+}
+
+int main(int argc, char *argv[])
+{
+       int r;
+
+       r = __init();
+       if (r < 0)
+               return -1;
+
+       g_main_loop_run(loop);
+
+       __fini();
+
+       return 0;
+}
diff --git a/installer/pkgmgr_installer_signal_agent.cc b/installer/pkgmgr_installer_signal_agent.cc
deleted file mode 100644 (file)
index be1d656..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <linux/limits.h>
-#include <pwd.h>
-
-#include <glib.h>
-#include <glib-unix.h>
-#include <gio/gio.h>
-#include <systemd/sd-daemon.h>
-
-#include <aul_proc.h>
-#include <dlog.h>
-
-#include <memory>
-#include <vector>
-
-#include "src/pkgmgr_installer_type.h"
-#include "src/PkgSignal.h"
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "PKGMGR_INSTALLER_SIGNAL_AGENT"
-
-#define BUFMAX 4096
-#define PWBUFSIZE sysconf(_SC_GETPW_R_SIZE_MAX)
-#define APPFW_USERNAME "app_fw"
-#define AGENT_APPID "signal_agent"
-
-namespace pkg_group = rpc_port::PkgSignal::group;
-namespace pkg_signal = rpc_port::PkgSignal;
-
-static int server_fd = -1;
-static GMainLoop* loop;
-static guint sid;
-static guint tid;
-static std::unique_ptr<pkg_group::PkgSignal> signal_sender;
-
-static int __create_server_socket(const char* path) {
-  int r;
-  int fd;
-  struct sockaddr_un sa;
-
-  fd = socket(AF_UNIX, SOCK_STREAM, 0);
-  if (fd == -1) {
-    LOGE("socket create failed: %d", errno);
-    return -1;
-  }
-
-  memset(&sa, 0, sizeof(sa));
-  sa.sun_family = AF_UNIX;
-  snprintf(sa.sun_path, sizeof(sa.sun_path), "%s", path);
-
-  r = unlink(sa.sun_path);
-  if (r == -1 && errno != ENOENT) {
-    LOGE("unlink(%s) failed: %d", sa.sun_path, errno);
-    close(fd);
-    return -1;
-  }
-
-  r = bind(fd, (struct sockaddr*)&sa, sizeof(sa));
-  if (r == -1) {
-    LOGE("bind(%s) failed: %d", sa.sun_path, errno);
-    close(fd);
-    return -1;
-  }
-
-  r = chmod(sa.sun_path, 0660);
-  if (r == -1)
-    LOGW("chmod(%s) failed: %d", sa.sun_path, errno);
-
-  r = listen(fd, SOMAXCONN);
-  if (r == -1) {
-    LOGE("listen(%s) failed: %d", sa.sun_path, errno);
-    close(fd);
-    return -1;
-  }
-
-  return fd;
-}
-
-static int __get_server_socket(const char* path) {
-  int i;
-  int n;
-  int r;
-  int fd = -1;
-
-  n = sd_listen_fds(0);
-  if (n < 0) {
-    LOGE("sd_listen_fds: %d", n);
-    return -1;
-  } else if (n == 0) {
-    return __create_server_socket(path);
-  }
-
-  for (i = SD_LISTEN_FDS_START; i < SD_LISTEN_FDS_START + n; i++) {
-    r = sd_is_socket_unix(i, SOCK_STREAM, -1, path, 0);
-    if (r > 0) {
-      fd = i;
-      break;
-    }
-  }
-
-  if (fd == -1) {
-    LOGE("socket is not passed, create server socket");
-    return __create_server_socket(path);
-  }
-
-  return fd;
-}
-
-static void __emit_signal_for_res_event(const char* signal, GVariant* gv) {
-  uid_t target_uid;
-  char* req_id;
-  char* pkgid = NULL;
-  char* status = NULL;
-  char* path = NULL;
-  int state;
-  int signal_type;
-  int error_code;
-  GVariant* extra_param = NULL;
-  GVariantIter* iter;
-
-  g_variant_get(gv, "(u&s&s&sv)", &target_uid, &req_id, &pkgid, &status, &extra_param);
-  if (!g_variant_type_equal(G_VARIANT_TYPE("(ia(si))"),
-      g_variant_get_type(extra_param))) {
-    LOGE("invalid extra parameter");
-    g_variant_unref(extra_param);
-    return;
-  }
-
-  std::vector<pkg_signal::PathInfo> path_info;
-
-  g_variant_get(extra_param, "(ia(si))", &error_code, &iter);
-  while (g_variant_iter_loop(iter, "(&si)", &path, &state))
-    path_info.emplace_back(path, state);
-
-  signal_sender->AsyncResultForResource(signal, target_uid, req_id, pkgid, status,
-      pkg_signal::ExtraData(error_code, std::move(path_info)));
-  g_variant_unref(extra_param);
-  g_variant_iter_free(iter);
-}
-
-static void __emit_signal_for_pkg_event(GVariant* gv) {
-  uid_t target_uid;
-  char* req_id;
-  char* pkg_type = NULL;
-  char* appid = NULL;
-  char* pkgid = NULL;
-  char* key = NULL;
-  char* val = NULL;
-  GVariantIter* iter = NULL;
-  int signal_type;
-
-  g_variant_get(gv, "(u&sa(sss)&s&s)", &target_uid, &req_id, &iter,
-      &key, &val);
-  std::vector<pkg_signal::PkgInfo> pkgs;
-  while (g_variant_iter_loop(iter, "(&s&s&s)", &pkgid, &appid, &pkg_type))
-    pkgs.emplace_back(pkg_signal::PkgInfo(pkgid, appid, pkg_type));
-  signal_sender->AsyncResult("", target_uid, req_id, std::move(pkgs), key, val);
-  g_variant_iter_free(iter);
-}
-
-static gboolean __quit(gpointer user_data) {
-  g_main_loop_quit(loop);
-  return FALSE;
-}
-
-static int __check_authority(int fd) {
-  int r;
-  struct ucred cr;
-  socklen_t len;
-  struct passwd pwd;
-  struct passwd* pwd_r;
-  char buf[PWBUFSIZE];
-
-  len = sizeof(struct ucred);
-  r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
-  if (r != 0) {
-    LOGE("getsockopt failed: %d", errno);
-    return -1;
-  }
-
-  /* allow root user */
-  if (cr.uid == 0)
-    return 0;
-
-  r = getpwuid_r(cr.uid, &pwd, buf, sizeof(buf), &pwd_r);
-  if (r != 0 || pwd_r == NULL) {
-    LOGE("getpwuid failed: %d", r);
-    return -1;
-  }
-
-  /* only app_fw user can send signal to agent */
-  if (strcmp(pwd_r->pw_name, APPFW_USERNAME) != 0) {
-    LOGE("unauthorized client");
-    return -1;
-  }
-
-  return 0;
-}
-
-/**
- * packet format:
- * +----------------+-------------+-----------+-------------------+
- * |signal name size|GVariant size|signal name|serialized GVariant|
- * +----------------+-------------+-----------+-------------------+
- */
-static gboolean __handle_signal(gint fd,
-    GIOCondition cond, gpointer user_data) {
-  int r;
-  unsigned char buf[BUFMAX];
-  int clifd;
-  struct sockaddr_un sa;
-  socklen_t s = sizeof(sa);
-  size_t type_len;
-  char* type_name;
-  gsize data_len;
-  gpointer data;
-  GVariant* gv;
-
-  clifd = accept(fd, (struct sockaddr*)&sa, &s);
-  if (clifd == -1) {
-    LOGE("accept failed: %d", errno);
-    return FALSE;
-  }
-
-  if (__check_authority(clifd)) {
-    close(clifd);
-    return TRUE;
-  }
-
-  r = recv(clifd, buf, sizeof(size_t) + sizeof(gsize), 0);
-  if (r < 0) {
-    LOGE("recv failed: %d", errno);
-    close(clifd);
-    return FALSE;
-  } else if (r == 0) {
-    LOGE("client fd already closed");
-    close(clifd);
-    return FALSE;
-  }
-
-  memcpy(&type_len, buf, sizeof(size_t));
-  memcpy(&data_len, buf + sizeof(size_t), sizeof(gsize));
-
-  if (type_len > BUFMAX || data_len > BUFMAX ||
-      (type_len + data_len) > BUFMAX) {
-    LOGE("received size is too large: %zu %zu", type_len, data_len);
-    close(clifd);
-    return FALSE;
-  }
-
-  r = recv(clifd, buf, type_len + data_len, 0);
-  if (r < 0) {
-    LOGE("recv failed: %d", errno);
-    close(clifd);
-    return FALSE;
-  } else if (r == 0) {
-    LOGE("client fd already closed");
-    close(clifd);
-    return FALSE;
-  }
-
-  if (type_len == 0) {
-    LOGE("invalid type_len");
-    close(clifd);
-    return FALSE;
-  }
-
-  /* get signal name (including terminating null byte) */
-  type_name = static_cast<char*>(malloc(type_len));
-  memcpy(type_name, buf, type_len);
-
-  /* get data */
-  data = malloc(data_len);
-  memcpy(data, buf + type_len, data_len);
-
-  /* floating type GVariant instance */
-  if (!strcmp(type_name, PKGMGR_INSTALLER_RES_COPY_EVENT_STR) ||
-    !strcmp(type_name, PKGMGR_INSTALLER_RES_CREATE_DIR_EVENT_STR) ||
-    !strcmp(type_name, PKGMGR_INSTALLER_RES_REMOVE_EVENT_STR) ||
-    !strcmp(type_name, PKGMGR_INSTALLER_RES_UNINSTALL_EVENT_STR)) {
-    gv = g_variant_new_from_data(G_VARIANT_TYPE("(usssv)"),
-        data, data_len, TRUE, NULL, NULL);
-    __emit_signal_for_res_event(type_name, gv);
-  } else {
-    gv = g_variant_new_from_data(G_VARIANT_TYPE("(usa(sss)ss)"),
-        data, data_len, TRUE, NULL, NULL);
-    __emit_signal_for_pkg_event(gv);
-  }
-  g_variant_unref(gv);
-
-  free(data);
-  free(type_name);
-  close(clifd);
-
-  /* renew timeout */
-  g_source_remove(tid);
-  tid = g_timeout_add_seconds(10, __quit, NULL);
-
-  return TRUE;
-}
-
-static int __init(void) {
-  char path[PATH_MAX];
-  GError* err = NULL;
-
-  snprintf(path, sizeof(path), "/run/pkgmgr/agent/%d", getuid());
-  server_fd = __get_server_socket(path);
-  if (server_fd < 0) {
-    LOGE("server init failed");
-    return -1;
-  }
-
-  if (aul_proc_register(AGENT_APPID, NULL) != AUL_R_OK) {
-    LOGE("aul_proc_register fail");
-    return -1;
-  }
-
-  try {
-    signal_sender = std::make_unique<pkg_group::PkgSignal>(AGENT_APPID, false);
-  } catch(...) {
-    LOGE("Exception occured");
-    return -1;
-  }
-
-  loop = g_main_loop_new(NULL, FALSE);
-  sid = g_unix_fd_add(server_fd, G_IO_IN, __handle_signal, NULL);
-  tid = g_timeout_add_seconds(10, __quit, NULL);
-
-  return 0;
-}
-
-static void __fini(void) {
-  if (sid > 0)
-    g_source_remove(sid);
-  if (loop)
-    g_main_loop_unref(loop);
-  if (server_fd > 0)
-    close(server_fd);
-  aul_proc_deregister();
-}
-
-int main(int argc, char* argv[]) {
-  int r;
-
-  r = __init();
-  if (r < 0)
-    return -1;
-
-  g_main_loop_run(loop);
-
-  __fini();
-
-  return 0;
-}
diff --git a/installer/src/api_stub.cc b/installer/src/api_stub.cc
deleted file mode 100644 (file)
index 8925d28..0000000
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
-* Copyright (c) 2022 Samsung Electronics Co., Ltd.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-
-#include "pkgmgr_installer.h"
-#include "pkgmgr_installer_debug.h"
-#include "pkgmgr_installer_info.h"
-
-#include <tzplatform_config.h>
-#include <unistd.h>
-
-#include "control.hh"
-
-#include <pkgmgr-info.h>
-
-#ifdef API
-#undef API
-#endif
-#define API __attribute__ ((visibility("default")))
-
-#define CHK_PI_RET(r) \
-  do { if (nullptr == pi) return (r); } while (0)
-
-static uid_t g_target_uid;
-
-API pkgmgr_installer* pkgmgr_installer_new() {
-  try {
-    return new pkgmgr::installer::Control();
-  } catch (...) {
-    _E("pkgmgr_installer_new fail");
-    return nullptr;
-  }
-
-  return nullptr;
-}
-
-API pkgmgr_installer* pkgmgr_installer_offline_new() {
-  return new pkgmgr::installer::Control(true);
-}
-
-API int pkgmgr_installer_free(pkgmgr_installer* pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  delete cls;
-  return 0;
-}
-
-API int pkgmgr_installer_receive_request(pkgmgr_installer *pi,
-    const int argc, char **argv) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-
-  int ret = cls->SetRequestFromArgv(argc, argv);
-  if (ret < 0)
-    return ret;
-
-  /* if target user is not set, set as tizenglobalapp user */
-  if (cls->GetRequest()->GetUid() == 0)
-    cls->GetRequest()->SetUid(tzplatform_getuid(TZ_SYS_GLOBALAPP_USER));
-
-  g_target_uid = cls->GetRequest()->GetUid();
-
-  return 0;
-}
-
-API int pkgmgr_installer_get_request_type(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return PKGMGR_REQ_INVALID;
-  return cls->GetRequest()->GetRequestType();
-}
-
-API uid_t pkgmgr_installer_get_uid(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return PKGMGR_REQ_INVALID;
-  return cls->GetRequest()->GetUid();
-}
-
-API const char* pkgmgr_installer_get_request_info(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return nullptr;
-  return cls->GetRequest()->GetRequestInfo().c_str();
-}
-
-API const char* pkgmgr_installer_get_request_info_at(pkgmgr_installer *pi,
-    int at) {
-  CHK_PI_RET(nullptr);
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  auto& rq = cls->GetRequest();
-  if (!rq)
-    return nullptr;
-
-  const auto& requests = rq->GetRequests();
-  if (requests.size() <= at)
-    return nullptr;
-
-  return requests[at].c_str();
-}
-
-API int pkgmgr_installer_get_request_info_count(pkgmgr_installer *pi) {
-  CHK_PI_RET(PKGMGR_REQ_INVALID);
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  auto& rq = cls->GetRequest();
-  if (!rq)
-    return PKGMGR_REQ_INVALID;
-
-  return rq->GetRequests().size();
-}
-
-API const char *pkgmgr_installer_get_tep_path(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return nullptr;
-  return cls->GetRequest()->GetTepPath().c_str();
-}
-
-API int pkgmgr_installer_get_tep_move_type(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return PKGMGR_REQ_INVALID;
-  return cls->GetRequest()->IsTepMove() ? 1 : 0;
-}
-
-API const char* pkgmgr_installer_get_session_id(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return nullptr;
-  return cls->GetRequest()->GetSessionId().c_str();
-}
-
-API const char* pkgmgr_installer_get_license_path(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return nullptr;
-  return cls->GetRequest()->GetLicensePath().c_str();
-}
-
-API const char* pkgmgr_installer_get_optional_data(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return nullptr;
-  return cls->GetRequest()->GetOptionalData().c_str();
-}
-
-API int pkgmgr_installer_is_quiet(pkgmgr_installer *pi) {
-  return 1;
-}
-
-API int pkgmgr_installer_get_move_type(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return PKGMGR_REQ_INVALID;
-  return cls->GetRequest()->GetMoveType();
-}
-
-API const char *pkgmgr_installer_get_caller_pkgid(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return nullptr;
-  return cls->GetRequest()->GetCallerPkgid().c_str();
-}
-
-API int pkgmgr_installer_get_is_preload(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return PKGMGR_REQ_INVALID;
-  return cls->GetRequest()->IsPreload() ? 1 : 0;
-}
-
-API int pkgmgr_installer_get_force_removal(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return PKGMGR_REQ_INVALID;
-  return cls->GetRequest()->IsForceRemoval() ? 1 : 0;
-}
-
-API int pkgmgr_installer_get_is_preload_rw(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return PKGMGR_REQ_INVALID;
-  return cls->GetRequest()->IsPreloadRw() ? 1 : 0;
-}
-
-API int pkgmgr_installer_get_no_removal(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return PKGMGR_REQ_INVALID;
-  return cls->GetRequest()->IsNoRemoval() ? 1 : 0;
-}
-
-API int pkgmgr_installer_get_keep_rwdata(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return PKGMGR_REQ_INVALID;
-  return cls->GetRequest()->IsKeepRwData() ? 1 : 0;
-}
-
-API int pkgmgr_installer_get_partial_rw(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return PKGMGR_REQ_INVALID;
-  return cls->GetRequest()->IsPartialRw() ? 1 : 0;
-}
-
-API int pkgmgr_installer_get_debug_mode(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return PKGMGR_REQ_INVALID;
-  return cls->GetRequest()->IsDebugMode() ? 1 : 0;
-}
-
-API int pkgmgr_installer_get_skip_check_reference(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return PKGMGR_REQ_INVALID;
-  return cls->GetRequest()->IsSkipCheckReference() ? 1 : 0;
-}
-
-API int pkgmgr_installer_get_skip_optimization(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return PKGMGR_REQ_INVALID;
-  return cls->GetRequest()->IsSkipOptimization() ? 1 : 0;
-}
-
-API int pkgmgr_installer_get_recovery_cleanup(pkgmgr_installer *pi) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return PKGMGR_REQ_INVALID;
-  return cls->GetRequest()->IsRecoveryCleanup() ? 1 : 0;
-}
-
-API int pkgmgr_installer_send_app_uninstall_signal(pkgmgr_installer *pi,
-    const char *pkg_type, const char *pkgid, const char *val) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return -1;
-  return cls->SendSignal(pkg_type, pkgid, "", PKGMGR_INSTALLER_APPID_KEY_STR, val);
-}
-
-API int pkgmgr_installer_send_app_uninstall_signal_for_uid(
-    pkgmgr_installer *pi, uid_t uid, const char *pkg_type,
-    const char *pkgid, const char *val) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return -1;
-  return cls->SendSignalForUid(uid, pkg_type, pkgid, "", PKGMGR_INSTALLER_APPID_KEY_STR, val);
-}
-
-API int pkgmgr_installer_set_uid(pkgmgr_installer *pi, uid_t uid) {
-  if (pi == NULL)
-    return -1;
-
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return -1;
-
-  cls->GetRequest()->SetUid(uid);
-
-  g_target_uid = uid;
-
-  return 0;
-}
-
-API int pkgmgr_installer_send_app_signal(pkgmgr_installer *pi,
-    const char *pkg_type, const char *pkgid, const char *appid,
-    const char *key, const char *val) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return -1;
-  return cls->SendSignal(pkg_type, pkgid, appid, key, val);
-}
-
-API int pkgmgr_installer_send_signal(pkgmgr_installer *pi,
-    const char *pkg_type, const char *pkgid, const char *key,
-    const char *val) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return -1;
-  return cls->SendSignal(pkg_type, pkgid, "", key, val);
-}
-
-API int pkgmgr_installer_send_app_signal_for_uid(pkgmgr_installer *pi,
-    uid_t uid, const char *pkg_type, const char *pkgid,
-    const char *appid, const char *key, const char *val) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return -1;
-  return cls->SendSignalForUid(uid, pkg_type, pkgid, appid, key, val);
-}
-
-API int pkgmgr_installer_send_signal_for_uid(pkgmgr_installer *pi,
-    uid_t uid, const char *pkg_type, const char *pkgid,
-    const char *key, const char *val) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return -1;
-  return cls->SendSignalForUid(uid, pkg_type, pkgid, "", key, val);
-}
-
-API int pkgmgr_installer_set_request_type(pkgmgr_installer *pi,
-    int request_type) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return -1;
-  cls->GetRequest()->SetRequestType(request_type);
-  return 0;
-}
-
-API int pkgmgr_installer_set_session_id(pkgmgr_installer *pi,
-    const char *session_id) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return -1;
-  cls->GetRequest()->SetSessionId(std::string(session_id));
-  return 0;
-}
-
-API int pkgmgr_installer_create_certinfo_set_handle(
-    pkgmgr_instcertinfo_h *handle) {
-  return pkgmgrinfo_create_certinfo_set_handle(handle);
-}
-
-API int pkgmgr_installer_set_cert_value(pkgmgr_instcertinfo_h handle,
-    pkgmgr_instcert_type cert_type, char *cert_value) {
-  return pkgmgrinfo_set_cert_value(handle, static_cast<pkgmgrinfo_instcert_type>(cert_type), cert_value);
-}
-
-API int pkgmgr_installer_save_certinfo(const char *pkgid,
-    pkgmgr_instcertinfo_h handle, uid_t uid) {
-  return pkgmgrinfo_save_certinfo(pkgid, handle, uid);
-}
-
-API int pkgmgr_installer_destroy_certinfo_set_handle(
-    pkgmgr_instcertinfo_h handle) {
-  return pkgmgrinfo_destroy_certinfo_set_handle(handle);
-}
-
-API int pkgmgr_installer_delete_certinfo(const char *pkgid) {
-  return pkgmgrinfo_delete_certinfo(pkgid);
-}
-
-API int pkgmgr_installer_set_privilege_level(pkgmgr_privilege_level level) {
-  //TODO
-  return 0;
-}
-
-API int pkgmgr_installer_info_get_target_uid(uid_t *uid) {
-  *uid = g_target_uid;
-
-  return 0;
-}
-
-API int pkgmgr_installer_info_get_privilege_level(
-    pkgmgr_privilege_level *level) {
-  //TODO
-  return 0;
-}
-
-API int pkgmgr_installer_info_get_debug_mode(int *debug_mode) {
-  //TODO
-  return 0;
-}
-
-API int pkgmgr_installer_info_get_skip_optimization(int *skip_optimization) {
-  //TODO
-  return 0;
-}
-
-API const char* pkgmgr_installer_error_to_string(int error_code) {
-  //TODO
-  return nullptr;
-}
-
-API int pkgmgr_installer_add_pkg(pkgmgr_installer *pi,
-    const char *pkgid, const char *pkg_type) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  cls->AddPkg(pkgid, pkg_type);
-
-  return 0;
-}
-
-API int pkgmgr_installer_send_signals(pkgmgr_installer *pi,
-    const char *key, const char *val) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return -1;
-  return cls->SendSignals(key, val);
-}
-
-API int pkgmgr_installer_send_signals_for_uid(pkgmgr_installer *pi, uid_t uid,
-    const char *key, const char *val) {
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return -1;
-  return cls->SendSignalsForUid(uid, key, val);
-}
-
-API int pkgmgr_installer_set_is_upgrade(pkgmgr_installer *pi, int is_upgrade) {
-  //TODO
-  return 0;
-}
-
-API int pkgmgr_installer_send_res_signal(pkgmgr_installer *pi,
-    const char *pkgid, const char *status,
-    pkgmgr_res_event_info *event_info) {
-  if (!pi || !pkgid || !status || !event_info) {
-    _E("invalid argument");
-    return -1;
-  }
-
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return -1;
-
-  return cls->SendSignalForResource(pkgid, status,
-      reinterpret_cast<rpc_port::PkgSignal::ExtraData*>(event_info));
-}
-
-API int pkgmgr_installer_send_res_signal_for_uid(pkgmgr_installer *pi,
-    uid_t uid, const char *pkgid, const char *status,
-    pkgmgr_res_event_info *event_info) {
-  if (!pi || !pkgid || !status || !event_info) {
-    _E("invalid argument");
-    return -1;
-  }
-
-  auto* cls = static_cast<pkgmgr::installer::Control*>(pi);
-  if (!cls->GetRequest())
-    return -1;
-
-  return cls->SendSignalForResourceForUid(uid, pkgid, status,
-      reinterpret_cast<rpc_port::PkgSignal::ExtraData*>(event_info));
-}
-
-API int pkgmgr_installer_send_pkg_upgrade_signal(pkgmgr_installer *pi,
-    unsigned int progress) {
-  //TODO
-  return 0;
-}
diff --git a/installer/src/control.cc b/installer/src/control.cc
deleted file mode 100644 (file)
index 8c0e8f0..0000000
+++ /dev/null
@@ -1,741 +0,0 @@
-/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include "control.hh"
-
-#include <getopt.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <glib.h>
-
-#include "pkgmgr_installer.h"
-#include "pkgmgr_installer_debug.h"
-#include "pkgmgr_installer_type.h"
-
-namespace {
-
-constexpr int OPTVAL_PRELOAD = 1000;
-constexpr int OPTVAL_FORCE_REMOVAL = 1001;
-constexpr int OPTVAL_PRELOAD_RW = 1002;
-constexpr int OPTVAL_NO_REMOVAL = 1003;
-constexpr int OPTVAL_KEEP_RWDATA = 1004;
-constexpr int OPTVAL_PARTIAL_RW = 1005;
-constexpr int OPTVAL_MIGRATE_EXTIMG = 1006;
-constexpr int OPTVAL_SKIP_CHECK_REFERENCE = 1007;
-constexpr int OPTVAL_RECOVER_DB = 1008;
-constexpr int OPTVAL_RECOVERY_CLEANUP = 1009;
-
-constexpr const char short_opts[] = "k:l:i:d:c:m:t:o:r:p:s:b:e:M:y:u:w:D:A:qGS";
-constexpr const struct option long_opts[] = {
-  { "session-id", 1, nullptr, 'k' },
-  { "license-path", 1, nullptr, 'l' },
-  { "install", 1, nullptr, 'i' },
-  { "uninstall", 1, nullptr, 'd' },
-  { "clear", 1, nullptr, 'c' },
-  { "move", 1, nullptr, 'm' },
-  { "move-type", 1, nullptr, 't' },
-  { "optional-data", 0, nullptr, 'o' },
-  { "reinstall", 0, nullptr, 'r' },
-  { "caller-pkgid", 1, nullptr, 'p' },
-  { "tep-path", 1, nullptr, 'e' },
-  { "tep-move", 1, nullptr, 'M' },
-  { "smack", 1, nullptr, 's' },
-  { "manifest-direct-install", 1, nullptr, 'y' },
-  { "mount-install", 1, nullptr, 'w' },
-  { "recovery", 1, nullptr, 'b' },
-  { "debug-mode", 0, nullptr, 'G' },
-  { "skip-optimization", 0, nullptr, 'S' },
-  { "preload", 0, nullptr, OPTVAL_PRELOAD },
-  { "force-remove", 0, nullptr, OPTVAL_FORCE_REMOVAL },
-  { "preload-rw", 0, nullptr, OPTVAL_PRELOAD_RW },
-  { "no-remove", 0, nullptr, OPTVAL_NO_REMOVAL },
-  { "keep-rwdata", 0, nullptr, OPTVAL_KEEP_RWDATA },
-  { "partial-rw", 0, nullptr, OPTVAL_PARTIAL_RW },
-  { "migrate-extimg", 1, nullptr, OPTVAL_MIGRATE_EXTIMG },
-  { "skip-check-reference", 0, nullptr, OPTVAL_SKIP_CHECK_REFERENCE },
-  { "recover-db", 1, nullptr, OPTVAL_RECOVER_DB },
-  { "recovery-cleanup", 0, nullptr, OPTVAL_RECOVERY_CLEANUP },
-  { 0, 0, 0, 0 }
-};
-
-static const char* __get_signal_name(
-    const std::unique_ptr<pkgmgr::installer::Request>& req,
-    const char* key, const char* pkg_type) {
-  if (strcmp(key, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0)
-    return key;
-  else if (strcmp(key, PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0)
-    return key;
-  else if (strcmp(key, PKGMGR_INSTALLER_APPID_KEY_STR) == 0)
-    return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
-  else if (strcmp(pkg_type, PKGMGR_INSTALLER_CLEAR_CACHE_KEY_STR) == 0)
-    return pkg_type;
-  else if (req->IsUpgrade())
-    return PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
-
-
-  switch (req->GetRequestType()) {
-  case PKGMGR_REQ_INSTALL:
-  case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL:
-  case PKGMGR_REQ_MOUNT_INSTALL:
-  case PKGMGR_REQ_REINSTALL:
-  case PKGMGR_REQ_ENABLE_PKG:
-  case PKGMGR_REQ_RECOVER:
-    return PKGMGR_INSTALLER_INSTALL_EVENT_STR;
-  case PKGMGR_REQ_UNINSTALL:
-  case PKGMGR_REQ_DISABLE_PKG:
-    return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
-  case PKGMGR_REQ_UPGRADE:
-    return PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
-  case PKGMGR_REQ_MOVE:
-    return PKGMGR_INSTALLER_MOVE_EVENT_STR;
-  case PKGMGR_REQ_ENABLE_APP:
-    return PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR;
-  case PKGMGR_REQ_DISABLE_APP:
-    return PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR;
-  case PKGMGR_REQ_ENABLE_APP_SPLASH_SCREEN:
-    return PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR;
-  case PKGMGR_REQ_DISABLE_APP_SPLASH_SCREEN:
-    return PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
-  case PKGMGR_REQ_CLEAR:
-    return PKGMGR_INSTALLER_CLEAR_EVENT_STR;
-  case PKGMGR_REQ_GETSIZE:
-    return PKGMGR_INSTALLER_GET_SIZE_KEY_STR;
-  case PKGMGR_REQ_RES_COPY:
-    return PKGMGR_INSTALLER_RES_COPY_EVENT_STR;
-  case PKGMGR_REQ_RES_CREATE_DIR:
-    return PKGMGR_INSTALLER_RES_CREATE_DIR_EVENT_STR;
-  case PKGMGR_REQ_RES_REMOVE:
-    return PKGMGR_INSTALLER_RES_REMOVE_EVENT_STR;
-  case PKGMGR_REQ_RES_UNINSTALL:
-    return PKGMGR_INSTALLER_RES_UNINSTALL_EVENT_STR;
-  }
-
-  _E("cannot find type");
-
-  return NULL;
-}
-
-}
-
-namespace pkgmgr {
-namespace installer {
-
-Control::Control(bool offline) {
-  if (!offline) {
-    signal_.reset(new pkg_group::PkgSignal("", true));
-  }
-
-  request_ = std::make_unique<Request>();
-
-  option_map_[OPTVAL_PRELOAD] = [](const std::unique_ptr<Request>& req) {
-    req->is_preload_ = true;
-    _D("preload request [%d]", req->is_preload_);
-    return 0;
-  };
-
-  option_map_[OPTVAL_FORCE_REMOVAL] = [](const std::unique_ptr<Request>& req) {
-    req->force_removal_ = true;
-    _D("force-remove request [%d]", req->force_removal_);
-    return 0;
-  };
-
-  option_map_[OPTVAL_PRELOAD_RW] = [](const std::unique_ptr<Request>& req) {
-    req->is_preload_rw_ = true;
-    _D("preload-rw request [%d]", req->is_preload_rw_);
-    return 0;
-  };
-
-  option_map_[OPTVAL_NO_REMOVAL] = [](const std::unique_ptr<Request>& req) {
-    req->no_removal_ = true;
-    _D("no-remove request [%d]", req->no_removal_);
-    return 0;
-  };
-
-  option_map_[OPTVAL_KEEP_RWDATA] = [](const std::unique_ptr<Request>& req) {
-    req->keep_rwdata_ = true;
-    _D("keep-rwdata request [%d]", req->keep_rwdata_);
-    return 0;
-  };
-
-  option_map_[OPTVAL_PARTIAL_RW] = [](const std::unique_ptr<Request>& req) {
-    req->partial_rw_ = true;
-    _D("partial-rw request [%d]", req->partial_rw_);
-    return 0;
-  };
-
-  option_map_[OPTVAL_MIGRATE_EXTIMG] = [this](const std::unique_ptr<Request>& req) {
-    if (mode_)
-      return -EINVAL;
-    mode_ = OPTVAL_MIGRATE_EXTIMG;
-    req->request_type_ = PKGMGR_REQ_MIGRATE_EXTIMG;
-    req->pkgmgr_info_ = optarg;
-    ParseMultiplePkgs(req);
-    _D("legacy extimg migration requested");
-    return 0;
-  };
-
-  option_map_[OPTVAL_SKIP_CHECK_REFERENCE] = [](const std::unique_ptr<Request>& req) {
-    req->skip_check_reference_ = true;
-    return 0;
-  };
-
-  option_map_[OPTVAL_RECOVER_DB] = [this](const std::unique_ptr<Request>& req) {
-    req->request_type_ = PKGMGR_REQ_RECOVER_DB;
-    req->pkgmgr_info_ = optarg;
-    ParseMultiplePkgs(req);
-    return 0;
-  };
-
-  option_map_[OPTVAL_RECOVERY_CLEANUP] = [](const std::unique_ptr<Request>& req) {
-    req->recovery_cleanup_ = true;
-    return 0;
-  };
-
-  option_map_['k'] = [](const std::unique_ptr<Request>& req) {
-    req->session_id_ = optarg;
-    return 0;
-  };
-
-  option_map_['l'] = [](const std::unique_ptr<Request>& req) {
-    req->license_path_ = optarg;
-    return 0;
-  };
-
-  option_map_['i'] = [this](const std::unique_ptr<Request>& req) {
-    if (mode_)
-      return -EINVAL;
-    mode_ = 'i';
-    req->request_type_ = PKGMGR_REQ_INSTALL;
-    req->pkgmgr_info_ = optarg;
-    ParseMultiplePkgs(req);
-    _D("option is [i] pkgid[%s]", req->pkgmgr_info_.c_str());
-    return 0;
-  };
-
-  option_map_['e'] = [](const std::unique_ptr<Request>& req) {
-    req->tep_path_ = optarg;
-    _D("option is [e] tep_path[%s]", req->tep_path_.c_str());
-    return 0;
-  };
-
-  option_map_['M'] = [](const std::unique_ptr<Request>& req) {
-    if (strcmp(optarg, "tep_move") == 0)
-      req->tep_move_ = true;
-    else
-      req->tep_move_ = false;
-    _D("option is [M] tep_move[%d]", req->tep_move_);
-    return 0;
-  };
-
-  option_map_['d'] = [this](const std::unique_ptr<Request>& req) {
-    if (mode_)
-      return -EINVAL;
-    mode_ = 'd';
-    req->request_type_ = PKGMGR_REQ_UNINSTALL;
-    req->pkgmgr_info_ = optarg;
-    ParseMultiplePkgs(req);
-    return 0;
-  };
-
-  option_map_['c'] = [this](const std::unique_ptr<Request>& req) {
-    if (mode_)
-      return -EINVAL;
-    mode_ = 'c';
-    req->request_type_ = PKGMGR_REQ_CLEAR;
-    req->pkgmgr_info_ = optarg;
-    ParseMultiplePkgs(req);
-    return 0;
-  };
-
-  option_map_['m'] = [this](const std::unique_ptr<Request>& req) {
-    if (mode_)
-      return -EINVAL;
-    mode_ = 'm';
-    req->request_type_ = PKGMGR_REQ_MOVE;
-    req->pkgmgr_info_ = optarg;
-    ParseMultiplePkgs(req);
-    return 0;
-  };
-
-  option_map_['r'] = [this](const std::unique_ptr<Request>& req) {
-    if (mode_)
-      return -EINVAL;
-    mode_ = 'r';
-    req->request_type_ = PKGMGR_REQ_REINSTALL;
-    req->pkgmgr_info_ = optarg;
-    ParseMultiplePkgs(req);
-    return 0;
-  };
-
-  option_map_['t'] = [](const std::unique_ptr<Request>& req) {
-    req->move_type_ = atoi(optarg);
-    return 0;
-  };
-
-  option_map_['p'] = [](const std::unique_ptr<Request>& req) {
-    req->caller_pkgid_ = optarg;
-    return 0;
-  };
-
-  option_map_['s'] = [this](const std::unique_ptr<Request>& req) {
-    if (mode_)
-      return -EINVAL;
-    mode_ = 's';
-    req->request_type_ = PKGMGR_REQ_SMACK;
-    req->pkgmgr_info_ = optarg;
-    ParseMultiplePkgs(req);
-    return 0;
-  };
-
-  option_map_['o'] = [](const std::unique_ptr<Request>& req) {
-    req->optional_data_ = optarg;
-    return 0;
-  };
-
-  option_map_['y'] = [this](const std::unique_ptr<Request>& req) {
-    req->request_type_ = PKGMGR_REQ_MANIFEST_DIRECT_INSTALL;
-    req->pkgmgr_info_ = optarg;
-    ParseMultiplePkgs(req);
-    return 0;
-  };
-
-  option_map_['w'] = [this](const std::unique_ptr<Request>& req) {
-    req->request_type_ = PKGMGR_REQ_MOUNT_INSTALL;
-    req->pkgmgr_info_ = optarg;
-    ParseMultiplePkgs(req);
-    return 0;
-  };
-
-  option_map_['b'] = [this](const std::unique_ptr<Request>& req) {
-    if (mode_)
-      return -EINVAL;
-    mode_ = 'b';
-    req->request_type_ = PKGMGR_REQ_RECOVER;
-    req->pkgmgr_info_ = optarg;
-    ParseMultiplePkgs(req);
-    return 0;
-  };
-
-  option_map_['D'] = [this](const std::unique_ptr<Request>& req) {
-    req->request_type_ = PKGMGR_REQ_DISABLE_PKG;
-    req->pkgmgr_info_ = optarg;
-    ParseMultiplePkgs(req);
-    return 0;
-  };
-
-  option_map_['A'] = [this](const std::unique_ptr<Request>& req) {
-    req->request_type_ = PKGMGR_REQ_ENABLE_PKG;
-    req->pkgmgr_info_ = optarg;
-    ParseMultiplePkgs(req);
-    return 0;
-  };
-
-  option_map_['u'] = [](const std::unique_ptr<Request>& req) {
-    req->target_uid_ = (uid_t)atoi(optarg);
-    return 0;
-  };
-
-  option_map_['G'] = [](const std::unique_ptr<Request>& req) {
-    req->debug_mode_ = true;
-    return 0;
-  };
-
-  option_map_['S'] = [](const std::unique_ptr<Request>& req) {
-    req->skip_optimization_ = true;
-    return 0;
-  };
-}
-
-Control::~Control() = default;
-
-void Control::ParseMultiplePkgs(const std::unique_ptr<Request>& req) {
-  while ((optind <= argc_) && (*argv_[optind - 1] != '-')) {
-    req->pkgs_.push_back(argv_[optind - 1]);
-    optind++;
-  }
-  optind--;
-}
-
-const std::unique_ptr<Request>& Control::GetRequest() const {
-  return request_;
-}
-
-int Control::SendSignal(std::string pkg_type, std::string pkgid,
-    std::string appid, std::string key, std::string val) {
-  if (!signal_) {
-    _E("offline mode");
-    return -1;
-  }
-  auto& req = GetRequest();
-  std::vector<rpc_port::PkgSignal::PkgInfo> pkgs;
-  pkgs.emplace_back(std::move(pkgid), std::move(appid), std::move(pkg_type));
-  signal_->AsyncResult("", req->GetUid(), req->GetSessionId(), std::move(pkgs),
-      key, val);
-  return 0;
-}
-
-int Control::SendSignals(std::string key, std::string val) {
-  if (!signal_) {
-    _E("offline mode");
-    return -1;
-  }
-  auto& req = GetRequest();
-  signal_->AsyncResult("", req->GetUid(), req->GetSessionId(), pkgs_, key, val);
-  return 0;
-}
-
-int Control::SendSignalForResource(std::string pkgid, std::string status,
-    rpc_port::PkgSignal::ExtraData* event_info) {
-  if (!signal_) {
-    _E("offline mode");
-    return -1;
-  }
-
-  auto& req = GetRequest();
-  const char* signal_name = __get_signal_name(req, "", "");
-  if (!signal_name) {
-    _E("unknown signal type");
-    return -1;
-  }
-
-  signal_->AsyncResultForResource(signal_name, req->GetUid(),
-      req->GetSessionId(), std::move(pkgid), std::move(status), *event_info);
-  return 0;
-}
-
-static int __send_signal_to_agent(uid_t uid, void* data, size_t len) {
-  int fd;
-  struct sockaddr_un sa;
-  int r;
-
-  fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
-  if (fd == -1) {
-    _E("failed to create socket: %d", errno);
-    return -1;
-  }
-
-  sa.sun_family = AF_UNIX;
-  snprintf(sa.sun_path, sizeof(sa.sun_path), "/run/pkgmgr/agent/%d", uid);
-
-  r = connect(fd, (struct sockaddr*)&sa, sizeof(sa));
-  if (r == -1) {
-    _E("failed to connect socket(%s): %d", sa.sun_path, errno);
-    close(fd);
-    return -1;
-  }
-
-  r = send(fd, data, len, MSG_NOSIGNAL);
-  if (r < 0) {
-    _E("failed to send data: %d", errno);
-    close(fd);
-    return -1;
-  }
-
-  close(fd);
-
-  return 0;
-}
-
-int Control::SendSignalForUid(uid_t uid, std::string pkg_type,
-    std::string pkgid, std::string appid, std::string key, std::string val) {
-  if (!signal_) {
-    _E("offline mode");
-    return -1;
-  }
-
-  const auto& req = GetRequest();
-  const char* sid = req->GetSessionId().c_str();
-
-  const char* signal_name;
-  size_t name_size;
-  GVariantBuilder* builder;
-  GVariant* gv;
-  gsize gv_len;
-  gpointer gv_data;
-  void* data;
-  void* ptr;
-  size_t data_len;
-
-  data_len = sizeof(size_t) + sizeof(gsize);
-
-  signal_name = __get_signal_name(req, key.c_str(), pkg_type.c_str());
-  if (!signal_name) {
-    _E("unknown signal name");
-    return -1;
-  }
-
-  /* including null byte */
-  name_size = strlen(signal_name) + 1;
-  data_len += name_size;
-
-  builder = g_variant_builder_new(G_VARIANT_TYPE("a(sss)"));
-  g_variant_builder_add(builder, "(sss)", pkgid.c_str(),
-      appid.c_str(), pkg_type.c_str());
-  gv = g_variant_new("(usa(sss)ss)", req->GetUid(), sid,
-      builder, key.c_str(), val.c_str());
-  g_variant_builder_unref(builder);
-  if (gv == NULL) {
-    _E("failed to create GVariant instance");
-    return -1;
-  }
-  gv_len = g_variant_get_size(gv);
-  gv_data = g_malloc(gv_len);
-  g_variant_store(gv, gv_data);
-  g_variant_unref(gv);
-  data_len += gv_len;
-
-  data = malloc(data_len);
-  if (data == NULL) {
-    _E("out of memory");
-    g_free(gv_data);
-    return -1;
-  }
-  ptr = data;
-  memcpy(ptr, &name_size, sizeof(size_t));
-  ptr += sizeof(size_t);
-  memcpy(ptr, &gv_len, sizeof(gsize));
-  ptr += sizeof(gsize);
-  memcpy(ptr, signal_name, name_size);
-  ptr += name_size;
-  memcpy(ptr, gv_data, gv_len);
-  g_free(gv_data);
-
-  if (__send_signal_to_agent(uid, data, data_len)) {
-    _E("failed to send signal to agent");
-    free(data);
-    return -1;
-  }
-
-  free(data);
-
-  return 0;
-}
-
-int Control::SendSignalsForUid(uid_t uid, std::string key, std::string val) {
-  if (!signal_) {
-    _E("offline mode");
-    return -1;
-  }
-
-  const auto& req = GetRequest();
-  const char* sid = req->GetSessionId().c_str();
-
-  const char* signal_name;
-  size_t name_size;
-  GVariantBuilder* builder;
-  GVariant* gv;
-  gsize gv_len;
-  gpointer gv_data;
-  void* data;
-  void* ptr;
-  size_t data_len;
-
-  data_len = sizeof(size_t) + sizeof(gsize);
-
-  signal_name = __get_signal_name(req, key.c_str(), "");
-  if (!signal_name) {
-    _E("unknown signal name");
-    return -1;
-  }
-
-  /* including null byte */
-  name_size = strlen(signal_name) + 1;
-  data_len += name_size;
-
-  builder = g_variant_builder_new(G_VARIANT_TYPE("a(sss)"));
-  for (const auto& pkg : pkgs_)
-    g_variant_builder_add(builder, "(sss)", pkg.GetPkgid().c_str(),
-        pkg.GetAppid().c_str(), pkg.GetPkgType().c_str());
-  gv = g_variant_new("(usa(sss)ss)", req->GetUid(), sid,
-      builder, key.c_str(), val.c_str());
-  g_variant_builder_unref(builder);
-  if (gv == NULL) {
-    _E("failed to create GVariant instance");
-    return -1;
-  }
-  gv_len = g_variant_get_size(gv);
-  gv_data = g_malloc(gv_len);
-  g_variant_store(gv, gv_data);
-  g_variant_unref(gv);
-  data_len += gv_len;
-
-  data = malloc(data_len);
-  if (data == NULL) {
-    _E("out of memory");
-    g_free(gv_data);
-    return -1;
-  }
-  ptr = data;
-  memcpy(ptr, &name_size, sizeof(size_t));
-  ptr += sizeof(size_t);
-  memcpy(ptr, &gv_len, sizeof(gsize));
-  ptr += sizeof(gsize);
-  memcpy(ptr, signal_name, name_size);
-  ptr += name_size;
-  memcpy(ptr, gv_data, gv_len);
-  g_free(gv_data);
-
-  if (__send_signal_to_agent(uid, data, data_len)) {
-    _E("failed to send signal to agent");
-    free(data);
-    return -1;
-  }
-
-  free(data);
-
-  return 0;
-}
-
-static GVariant* __get_gvariant_from_event_info(
-    pkgmgr_res_event_info* event_info) {
-  rpc_port::PkgSignal::ExtraData* info =
-      reinterpret_cast<rpc_port::PkgSignal::ExtraData*>(event_info);
-  GVariantBuilder* builder;
-  GVariant* result;
-  GList* path_states;
-  res_event_path_state_t* path_state;
-
-  builder = g_variant_builder_new(G_VARIANT_TYPE("a(si)"));
-  if (builder == NULL) {
-    _E("out of memory");
-    return NULL;
-  }
-
-  for (const auto& p : info->GetPaths())
-    g_variant_builder_add(builder, "(si)", p.GetPath(), p.GetState());
-
-  result = g_variant_new("(ia(si))", info->GetErrCode(), builder);
-  g_variant_builder_unref(builder);
-
-  if (result == NULL) {
-    _E("Fail to create extra data");
-    return NULL;
-  }
-
-  return result;
-}
-
-int Control::SendSignalForResourceForUid(uid_t uid, std::string pkgid,
-    std::string status, rpc_port::PkgSignal::ExtraData* event_info) {
-  if (!signal_) {
-    _E("offline mode");
-    return -1;
-  }
-
-  const auto& req = GetRequest();
-  const char* sid = req->GetSessionId().c_str();
-
-  const char* signal_name;
-  size_t name_size;
-  GVariant* gv;
-  gsize gv_len;
-  gpointer gv_data;
-  void* data;
-  void* ptr;
-  size_t data_len;
-  GVariant* extra_param;
-
-  data_len = sizeof(size_t) + sizeof(gsize);
-
-  signal_name = __get_signal_name(req, "", "");
-  if (!signal_name) {
-    _E("unknown signal name");
-    return -1;
-  }
-
-  /* including null byte */
-  name_size = strlen(signal_name) + 1;
-  data_len += name_size;
-
-  extra_param = __get_gvariant_from_event_info(event_info);
-  if (extra_param == NULL) {
-    _E("Fail to get extra parameter");
-    return -1;
-  }
-
-  gv = g_variant_new("(usssv)", req->GetUid(), sid,
-      pkgid.c_str(), status.c_str(), extra_param);
-  if (gv == NULL) {
-    _E("failed to create GVariant instance");
-    return -1;
-  }
-
-  gv_len = g_variant_get_size(gv);
-  gv_data = g_malloc(gv_len);
-  g_variant_store(gv, gv_data);
-  g_variant_unref(gv);
-  data_len += gv_len;
-
-  data = malloc(data_len);
-  if (data == NULL) {
-    _E("out of memory");
-    g_free(gv_data);
-    return -1;
-  }
-  ptr = data;
-  memcpy(ptr, &name_size, sizeof(size_t));
-  ptr += sizeof(size_t);
-  memcpy(ptr, &gv_len, sizeof(gsize));
-  ptr += sizeof(gsize);
-  memcpy(ptr, signal_name, name_size);
-  ptr += name_size;
-  memcpy(ptr, gv_data, gv_len);
-  g_free(gv_data);
-
-  if (__send_signal_to_agent(uid, data, data_len)) {
-    _E("failed to send signal to agent");
-    free(data);
-    return -1;
-  }
-
-  free(data);
-
-  return 0;
-}
-
-void Control::AddPkg(std::string pkgid, std::string pkg_type) {
-  pkgs_.emplace_back(rpc_port::PkgSignal::PkgInfo(std::move(pkgid),
-      "", std::move(pkg_type)));
-}
-
-int Control::SetRequestFromArgv(const int argc, char** argv) {
-  int opt_idx = 0;
-  optind = 1;
-  argc_ = argc;
-  argv_ = argv;
-  mode_ = 0;
-
-  while (true) {
-    int c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx);
-    if (c == -1)
-      break;
-
-    if (option_map_.find(c) != option_map_.end()) {
-      int ret = option_map_[c](request_);
-      if (ret < 0)
-        return ret;
-    }
-  }
-
-  return 0;
-}
-
-}  // namespace installer
-}  // namespace pkgmgr
diff --git a/installer/src/control.hh b/installer/src/control.hh
deleted file mode 100644 (file)
index 6258a4f..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef INSTALLER_SRC_CONTROL_H_
-#define INSTALLER_SRC_CONTROL_H_
-
-#include <map>
-#include <memory>
-#include <string>
-#include <list>
-#include <functional>
-
-#include "PkgSignal.h"
-#include "request.hh"
-
-namespace pkgmgr {
-namespace installer {
-
-namespace pkg_group = rpc_port::PkgSignal::group;
-
-class Control {
- public:
-  Control(bool offline = false);
-  virtual ~Control();
-  int SetRequestFromArgv(const int argc, char** argv);
-  const std::unique_ptr<Request>& GetRequest() const;
-  int SendSignal(std::string pkg_type, std::string pkgid,
-      std::string appid, std::string key, std::string val);
-  int SendSignals(std::string key, std::string val);
-  int SendSignalForResource(std::string pkgid, std::string status,
-    rpc_port::PkgSignal::ExtraData* event_info);
-  int SendSignalForUid(uid_t uid, std::string pkg_type, std::string pkgid,
-      std::string appid, std::string key, std::string val);
-  int SendSignalsForUid(uid_t uid, std::string key, std::string val);
-  int SendSignalForResourceForUid(uid_t uid, std::string pkgid,
-    std::string status, rpc_port::PkgSignal::ExtraData* event_info);
-  void AddPkg(std::string pkgid, std::string pkg_type);
-
- private:
-  void ParseMultiplePkgs(const std::unique_ptr<Request>& req);
-
- private:
-  std::unique_ptr<Request> request_;
-  std::unique_ptr<pkg_group::PkgSignal> signal_;
-  std::map<int, std::function<int(const std::unique_ptr<Request>&)>>
-      option_map_;
-  std::vector<rpc_port::PkgSignal::PkgInfo> pkgs_;
-  int argc_ = 0;
-  char** argv_ = nullptr;
-  int mode_ = 0;
-};
-
-}  // namespace installer
-}  // namespace pkgmgr
-
-#endif  // INSTALLER_SRC_CONTROL_H_
\ No newline at end of file
diff --git a/installer/src/pkgmgr_installer.c b/installer/src/pkgmgr_installer.c
new file mode 100644 (file)
index 0000000..fd8a09f
--- /dev/null
@@ -0,0 +1,1446 @@
+/*
+ * slp-pkgmgr
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
+ * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+#include <tzplatform_config.h>
+
+#include "package-manager.h"
+#include "pkgmgr_installer.h"
+#include "pkgmgr_installer_config.h"
+#include "pkgmgr_installer_debug.h"
+#include "pkgmgr_installer_info.h"
+#include "pkgmgr_installer_error.h"
+#include "package-manager-types.h"
+
+#include <pkgmgr-info.h>
+
+/* API export macro */
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#define MAX_STRLEN 1024
+#define MAX_QUERY_LEN  4096
+
+#define CHK_PI_RET(r) \
+       do { if (NULL == pi) return (r); } while (0)
+
+#define OPTVAL_PRELOAD 1000
+#define OPTVAL_FORCE_REMOVAL 1001
+#define OPTVAL_PRELOAD_RW 1002
+#define OPTVAL_NO_REMOVAL 1003
+#define OPTVAL_KEEP_RWDATA 1004
+#define OPTVAL_PARTIAL_RW 1005
+#define OPTVAL_MIGRATE_EXTIMG 1006
+#define OPTVAL_SKIP_CHECK_REFERENCE 1007
+#define OPTVAL_RECOVER_DB 1008
+#define OPTVAL_RECOVERY_CLEANUP 1009
+
+/* Supported options */
+const char *short_opts = "k:l:i:d:c:m:t:o:r:p:s:b:e:M:y:u:w:D:A:qGS";
+const struct option long_opts[] = {
+       { "session-id", 1, NULL, 'k' },
+       { "license-path", 1, NULL, 'l' },
+       { "install", 1, NULL, 'i' },
+       { "uninstall", 1, NULL, 'd' },
+       { "clear", 1, NULL, 'c' },
+       { "move", 1, NULL, 'm' },
+       { "move-type", 1, NULL, 't' },
+       { "optional-data", 0, NULL, 'o' },
+       { "reinstall", 0, NULL, 'r' },
+       { "caller-pkgid", 1, NULL, 'p' },
+       { "tep-path", 1, NULL, 'e' },
+       { "tep-move", 1, NULL, 'M' },
+       { "smack", 1, NULL, 's' },
+       { "manifest-direct-install", 1, NULL, 'y' },
+       { "mount-install", 1, NULL, 'w' },
+       { "recovery", 1, NULL, 'b' },
+       { "debug-mode", 0, NULL, 'G' },
+       { "skip-optimization", 0, NULL, 'S' },
+       { "preload", 0, NULL, OPTVAL_PRELOAD }, /* for preload RO */
+       { "force-remove", 0, NULL, OPTVAL_FORCE_REMOVAL }, /* for preload RO/RW */
+       { "preload-rw", 0, NULL, OPTVAL_PRELOAD_RW }, /* for preload RW */
+       { "no-remove", 0, NULL, OPTVAL_NO_REMOVAL }, /* for preload RW */
+       { "keep-rwdata", 0, NULL, OPTVAL_KEEP_RWDATA }, /* for preload RW */
+       { "partial-rw", 0, NULL, OPTVAL_PARTIAL_RW }, /* for preload RO */
+       { "migrate-extimg", 1, NULL, OPTVAL_MIGRATE_EXTIMG },
+       { "skip-check-reference", 0, NULL, OPTVAL_SKIP_CHECK_REFERENCE },
+       { "recover-db", 1, NULL, OPTVAL_RECOVER_DB },
+       { "recovery-cleanup", 0, NULL, OPTVAL_RECOVERY_CLEANUP },
+       { 0, 0, 0, 0 }  /* sentinel */
+};
+
+struct pkgmgr_installer {
+       int request_type;
+       int move_type;
+       int is_upgrade;
+       char *pkgmgr_info;
+       char *session_id;
+       char *license_path;
+       char *optional_data;
+       char *caller_pkgid;
+       uid_t target_uid;
+       char *tep_path;
+       int tep_move;
+       int is_tep_included;
+       int is_preload;
+       int force_removal;
+       int is_preload_rw;
+       int no_removal;
+       int keep_rwdata;
+       int partial_rw;
+       int debug_mode;
+       int skip_check_reference;
+       int skip_optimization;
+       int recovery_cleanup;
+       GDBusConnection *conn;
+       GHashTable *pkg_list;
+       GList *pkgs;
+};
+
+typedef struct pkg_signal_info {
+       char *pkgid;
+       char *pkg_type;
+} pkg_signal_info;
+
+static uid_t g_target_uid;
+static int g_debug_mode;
+static int g_skip_optimization;
+static pkgmgr_privilege_level g_privilege_level = PM_PRIVILEGE_UNKNOWN;
+
+static const char *__get_signal_name(pkgmgr_installer *pi, const char *key,
+               const char *pkg_type)
+{
+       if (strcmp(key, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0)
+               return key;
+       else if (strcmp(key, PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0)
+               return key;
+       else if (strcmp(key, PKGMGR_INSTALLER_APPID_KEY_STR) == 0)
+               return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
+       else if (strcmp(pkg_type, PKGMGR_INSTALLER_CLEAR_CACHE_KEY_STR) == 0)
+               return pkg_type;
+       else if (pi->is_upgrade)
+               return PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
+
+
+       switch (pi->request_type) {
+       case PKGMGR_REQ_INSTALL:
+       case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL:
+       case PKGMGR_REQ_MOUNT_INSTALL:
+       case PKGMGR_REQ_REINSTALL:
+       case PKGMGR_REQ_ENABLE_PKG:
+       case PKGMGR_REQ_RECOVER:
+               return PKGMGR_INSTALLER_INSTALL_EVENT_STR;
+       case PKGMGR_REQ_UNINSTALL:
+       case PKGMGR_REQ_DISABLE_PKG:
+               return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
+       case PKGMGR_REQ_UPGRADE:
+               return PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
+       case PKGMGR_REQ_MOVE:
+               return PKGMGR_INSTALLER_MOVE_EVENT_STR;
+       case PKGMGR_REQ_ENABLE_APP:
+               return PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR;
+       case PKGMGR_REQ_DISABLE_APP:
+               return PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR;
+       case PKGMGR_REQ_ENABLE_APP_SPLASH_SCREEN:
+               return PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR;
+       case PKGMGR_REQ_DISABLE_APP_SPLASH_SCREEN:
+               return PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
+       case PKGMGR_REQ_CLEAR:
+               return PKGMGR_INSTALLER_CLEAR_EVENT_STR;
+       case PKGMGR_REQ_GETSIZE:
+               return PKGMGR_INSTALLER_GET_SIZE_KEY_STR;
+       case PKGMGR_REQ_RES_COPY:
+               return PKGMGR_INSTALLER_RES_COPY_EVENT_STR;
+       case PKGMGR_REQ_RES_CREATE_DIR:
+               return PKGMGR_INSTALLER_RES_CREATE_DIR_EVENT_STR;
+       case PKGMGR_REQ_RES_REMOVE:
+               return PKGMGR_INSTALLER_RES_REMOVE_EVENT_STR;
+       case PKGMGR_REQ_RES_UNINSTALL:
+               return PKGMGR_INSTALLER_RES_UNINSTALL_EVENT_STR;
+       }
+
+       ERR("cannot find type");
+
+       return NULL;
+}
+
+static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type,
+               const char *pkgid, const char *appid, const char *key,
+               const char *val)
+{
+       char *sid;
+       const char *tmp_appid = appid;
+       const char *signal_name;
+       GVariant *v;
+       GVariantBuilder *builder;
+       GError *err = NULL;
+
+       if (!pi || pi->conn == NULL)
+               return -1;
+
+       sid = pi->session_id;
+       if (!sid)
+               sid = "";
+
+       signal_name = __get_signal_name(pi, key, pkg_type);
+       if (!signal_name) {
+               ERR("unknown signal type");
+               return -1;
+       }
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a(sss)"));
+       g_variant_builder_add(builder, "(sss)", pkgid,
+                       (tmp_appid ? tmp_appid : ""), pkg_type);
+       v = g_variant_new("(usa(sss)ss)",
+                       pi->target_uid, sid, builder, key, val);
+       g_variant_builder_unref(builder);
+       if (g_dbus_connection_emit_signal(pi->conn, NULL,
+                               PKGMGR_INSTALLER_DBUS_OBJECT_PATH,
+                               PKGMGR_INSTALLER_DBUS_INTERFACE, signal_name,
+                               v, &err) != TRUE) {
+               ERR("failed to send dbus signal");
+               if (err) {
+                       ERR("err: %s", err->message);
+                       g_error_free(err);
+               }
+               return -1;
+       }
+
+       return 0;
+}
+
+static int __send_signal_to_agent(uid_t uid, void *data, size_t len)
+{
+       int fd;
+       struct sockaddr_un sa;
+       int r;
+
+       fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
+       if (fd == -1) {
+               ERR("failed to create socket: %d", errno);
+               return -1;
+       }
+
+       sa.sun_family = AF_UNIX;
+       snprintf(sa.sun_path, sizeof(sa.sun_path), "/run/pkgmgr/agent/%d", uid);
+
+       r = connect(fd, (struct sockaddr *)&sa, sizeof(sa));
+       if (r == -1) {
+               ERR("failed to connect socket(%s): %d", sa.sun_path, errno);
+               close(fd);
+               return -1;
+       }
+
+       r = send(fd, data, len, MSG_NOSIGNAL);
+       if (r < 0) {
+               ERR("failed to send data: %d", errno);
+               close(fd);
+               return -1;
+       }
+
+       close(fd);
+
+       return 0;
+}
+
+static int __send_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
+               const char *pkg_type, const char *pkgid, const char *appid,
+               const char *key, const char *val)
+{
+       char *sid;
+       const char *signal_name;
+       const char *tmp_appid = appid;
+       size_t name_size;
+       GVariantBuilder *builder;
+       GVariant *gv;
+       gsize gv_len;
+       gpointer gv_data;
+       void *data;
+       void *ptr;
+       size_t data_len;
+
+       if (!pi || pi->conn == NULL)
+               return -1;
+
+       sid = pi->session_id;
+       if (!sid)
+               sid = "";
+
+       data_len = sizeof(size_t) + sizeof(gsize);
+
+       signal_name = __get_signal_name(pi, key, pkg_type);
+       if (!signal_name) {
+               ERR("unknown signal name");
+               return -1;
+       }
+
+       /* including null byte */
+       name_size = strlen(signal_name) + 1;
+       data_len += name_size;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a(sss)"));
+       g_variant_builder_add(builder, "(sss)", pkgid,
+                       (tmp_appid ? tmp_appid : ""), pkg_type);
+       gv = g_variant_new("(usa(sss)ss)", pi->target_uid, sid,
+                       builder, key, val);
+       g_variant_builder_unref(builder);
+       if (gv == NULL) {
+               ERR("failed to create GVariant instance");
+               return -1;
+       }
+       gv_len = g_variant_get_size(gv);
+       gv_data = g_malloc(gv_len);
+       g_variant_store(gv, gv_data);
+       g_variant_unref(gv);
+       data_len += gv_len;
+
+       data = malloc(data_len);
+       if (data == NULL) {
+               ERR("out of memory");
+               g_free(gv_data);
+               return -1;
+       }
+       ptr = data;
+       memcpy(ptr, &name_size, sizeof(size_t));
+       ptr += sizeof(size_t);
+       memcpy(ptr, &gv_len, sizeof(gsize));
+       ptr += sizeof(gsize);
+       memcpy(ptr, signal_name, name_size);
+       ptr += name_size;
+       memcpy(ptr, gv_data, gv_len);
+       g_free(gv_data);
+
+       if (__send_signal_to_agent(uid, data, data_len)) {
+               ERR("failed to send signal to agent");
+               free(data);
+               return -1;
+       }
+
+       free(data);
+
+       return 0;
+}
+
+static void __free_pkg_list(gpointer data)
+{
+       pkg_signal_info *info = (pkg_signal_info *)data;
+       free(info->pkgid);
+       free(info->pkg_type);
+       free(info);
+}
+
+API pkgmgr_installer *pkgmgr_installer_new(void)
+{
+       pkgmgr_installer *pi;
+       GError *err = NULL;
+
+       pi = calloc(1, sizeof(struct pkgmgr_installer));
+       if (pi == NULL)
+               return NULL;
+
+       pi->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+       if (pi->conn == NULL) {
+               ERR("failed to get bus: %s", err->message);
+               g_error_free(err);
+               free(pi);
+               return NULL;
+       }
+
+       pi->tep_path = NULL;
+       pi->tep_move = 0;
+       pi->request_type = PKGMGR_REQ_INVALID;
+       pi->pkg_list = g_hash_table_new_full(
+                       g_str_hash, g_str_equal, NULL, __free_pkg_list);
+       return pi;
+}
+
+API pkgmgr_installer *pkgmgr_installer_offline_new(void)
+{
+       pkgmgr_installer *pi;
+
+       pi = calloc(1, sizeof(struct pkgmgr_installer));
+       if (pi == NULL)
+               return NULL;
+
+       pi->tep_path = NULL;
+       pi->tep_move = 0;
+       pi->request_type = PKGMGR_REQ_INVALID;
+
+       return pi;
+}
+
+API int pkgmgr_installer_free(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(-EINVAL);
+
+       /* free members */
+       if (pi->pkgmgr_info)
+               free(pi->pkgmgr_info);
+       if (pi->session_id)
+               free(pi->session_id);
+       if (pi->optional_data)
+               free(pi->optional_data);
+       if (pi->caller_pkgid)
+               free(pi->caller_pkgid);
+       if (pi->tep_path)
+               free(pi->tep_path);
+
+       if (pi->conn) {
+               g_dbus_connection_flush_sync(pi->conn, NULL, NULL);
+               g_object_unref(pi->conn);
+       }
+
+       if (pi->pkgs)
+               g_list_free_full(pi->pkgs, free);
+
+       if (pi->pkg_list)
+               g_hash_table_destroy(pi->pkg_list);
+
+       free(pi);
+
+       return 0;
+}
+
+static void __parse_multiple_pkgs(pkgmgr_installer *pi, int argc, char **argv)
+{
+       while ((optind <= argc) && (*argv[optind - 1] != '-')) {
+               pi->pkgs = g_list_append(pi->pkgs, strdup(argv[optind - 1]));
+               optind++;
+       }
+       optind--;
+}
+
+API int
+pkgmgr_installer_receive_request(pkgmgr_installer *pi,
+                                const int argc, char **argv)
+{
+       CHK_PI_RET(-EINVAL);
+
+       int r = 0;
+
+       /* Parse argv */
+       optind = 1;             /* Initialize optind to clear prev. index */
+       int opt_idx = 0;
+       int c;
+       int mode = 0;
+
+       pi->target_uid = getuid();
+       g_target_uid = pi->target_uid;
+       g_debug_mode = 0;
+       g_skip_optimization = 0;
+
+       if (pi->pkgs) {
+               g_list_free_full(pi->pkgs, free);
+               pi->pkgs = NULL;
+       }
+
+       while (1) {
+               c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx);
+               /* printf("c=%d %c\n", c, c); //debug */
+               if (-1 == c)
+                       break;  /* Parse is end */
+               switch (c) {
+               case OPTVAL_PRELOAD:    /* request for preload app */
+                       pi->is_preload = 1;
+                       DBG("preload request [%d]", pi->is_preload);
+                       break;
+               case OPTVAL_FORCE_REMOVAL:      /* request for force-remove */
+                       pi->force_removal = 1;
+                       DBG("force-remove request [%d]", pi->force_removal);
+                       break;
+               case OPTVAL_PRELOAD_RW: /* request for preload-rw app */
+                       pi->is_preload_rw = 1;
+                       DBG("preload-rw request [%d]", pi->is_preload_rw);
+                       break;
+               case OPTVAL_NO_REMOVAL: /* request for no-remove */
+                       pi->no_removal = 1;
+                       DBG("no-remove request [%d]", pi->no_removal);
+                       break;
+               case OPTVAL_KEEP_RWDATA:        /* request for keep-rwdata */
+                       pi->keep_rwdata = 1;
+                       DBG("keep-rwdata request [%d]", pi->keep_rwdata);
+                       break;
+               case OPTVAL_PARTIAL_RW: /* request for partial-rw */
+                       pi->partial_rw = 1;
+                       DBG("partial-rw request [%d]", pi->partial_rw);
+                       break;
+               case OPTVAL_MIGRATE_EXTIMG:
+                       /* request for legacy extimg migration */
+                       if (mode) {
+                               r = -EINVAL;
+                               goto RET;
+                       }
+                       mode = OPTVAL_MIGRATE_EXTIMG;
+                       pi->request_type = PKGMGR_REQ_MIGRATE_EXTIMG;
+                       if (pi->pkgmgr_info)
+                               free(pi->pkgmgr_info);
+                       pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+                       __parse_multiple_pkgs(pi, argc, argv);
+                       DBG("legacy extimg migration requested");
+                       break;
+               case OPTVAL_SKIP_CHECK_REFERENCE:
+                       pi->skip_check_reference = 1;
+                       break;
+               case OPTVAL_RECOVER_DB:
+                       pi->request_type = PKGMGR_REQ_RECOVER_DB;
+                       pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+                       __parse_multiple_pkgs(pi, argc, argv);
+                       break;
+               case OPTVAL_RECOVERY_CLEANUP:
+                       pi->recovery_cleanup = 1;
+                       break;
+               case 'k':       /* session id */
+                       if (pi->session_id)
+                               free(pi->session_id);
+                       pi->session_id = strndup(optarg, MAX_STRLEN);
+                       break;
+
+               case 'l':       /* license path */
+                       if (pi->license_path)
+                               free(pi->license_path);
+                       pi->license_path = strndup(optarg, MAX_STRLEN);
+                       break;
+
+               case 'i':       /* install */
+                       if (mode) {
+                               r = -EINVAL;
+                               goto RET;
+                       }
+                       mode = 'i';
+                       pi->request_type = PKGMGR_REQ_INSTALL;
+                       if (pi->pkgmgr_info)
+                               free(pi->pkgmgr_info);
+                       pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+                       __parse_multiple_pkgs(pi, argc, argv);
+                       DBG("option is [i] pkgid[%s]", pi->pkgmgr_info);
+                       if (pi->pkgmgr_info && strlen(pi->pkgmgr_info) == 0) {
+                               free(pi->pkgmgr_info);
+                               pi->pkgmgr_info = NULL;
+                       } else {
+                               mode = 'i';
+                       }
+                       break;
+
+               case 'e':       /* install */
+                       if (pi->tep_path)
+                               free(pi->tep_path);
+                       pi->tep_path = strndup(optarg, MAX_STRLEN);
+                       pi->is_tep_included = 1;
+                       DBG("option is [e] tep_path[%s]", pi->tep_path);
+                       break;
+
+               case 'M':       /* install */
+                       if (strcmp(optarg, "tep_move") == 0)
+                               pi->tep_move = 1;
+                       else
+                               pi->tep_move = 0;
+                       DBG("option is [M] tep_move[%d]", pi->tep_move);
+                       break;
+
+               case 'd':       /* uninstall */
+                       if (mode) {
+                               r = -EINVAL;
+                               goto RET;
+                       }
+                       mode = 'd';
+                       pi->request_type = PKGMGR_REQ_UNINSTALL;
+                       if (pi->pkgmgr_info)
+                               free(pi->pkgmgr_info);
+                       pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+                       __parse_multiple_pkgs(pi, argc, argv);
+                       break;
+
+
+               case 'c':       /* clear */
+                       if (mode) {
+                               r = -EINVAL;
+                               goto RET;
+                       }
+                       mode = 'c';
+                       pi->request_type = PKGMGR_REQ_CLEAR;
+                       if (pi->pkgmgr_info)
+                               free(pi->pkgmgr_info);
+                       pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+                       __parse_multiple_pkgs(pi, argc, argv);
+                       break;
+
+               case 'm':       /* move */
+                       if (mode) {
+                               r = -EINVAL;
+                               goto RET;
+                       }
+                       mode = 'm';
+                       pi->request_type = PKGMGR_REQ_MOVE;
+                       if (pi->pkgmgr_info)
+                               free(pi->pkgmgr_info);
+                       pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+                       __parse_multiple_pkgs(pi, argc, argv);
+                       break;
+
+               case 'r':       /* reinstall */
+                       if (mode) {
+                               r = -EINVAL;
+                               goto RET;
+                       }
+                       mode = 'r';
+                       pi->request_type = PKGMGR_REQ_REINSTALL;
+                       if (pi->pkgmgr_info)
+                               free(pi->pkgmgr_info);
+                       pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+                       __parse_multiple_pkgs(pi, argc, argv);
+                       break;
+
+               case 't': /* move type*/
+                       pi->move_type = atoi(optarg);
+                       break;
+
+               case 'p': /* caller pkgid*/
+                       if (pi->caller_pkgid)
+                               free(pi->caller_pkgid);
+                       pi->caller_pkgid = strndup(optarg, MAX_STRLEN);
+
+                       break;
+
+               case 's':       /* smack */
+                       if (mode) {
+                               r = -EINVAL;
+                               goto RET;
+                       }
+                       mode = 's';
+                       pi->request_type = PKGMGR_REQ_SMACK;
+                       if (pi->pkgmgr_info)
+                               free(pi->pkgmgr_info);
+                       pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+                       __parse_multiple_pkgs(pi, argc, argv);
+                       break;
+
+               case 'o': /* optional data*/
+                       pi->optional_data = strndup(optarg, MAX_STRLEN);
+                       break;
+
+               case 'y': /* pkgid for direct manifest installation */
+                       mode = 'y';
+                       pi->request_type = PKGMGR_REQ_MANIFEST_DIRECT_INSTALL;
+                       pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+                       __parse_multiple_pkgs(pi, argc, argv);
+                       break;
+
+               case 'w': /* pkgid for mount installation */
+                       mode = 'w';
+                       pi->request_type = PKGMGR_REQ_MOUNT_INSTALL;
+                       pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+                       __parse_multiple_pkgs(pi, argc, argv);
+                       break;
+
+               case 'b': /* recovery */
+                       if (mode) {
+                               r = -EINVAL;
+                               goto RET;
+                       }
+                       mode = 'b';
+                       pi->request_type = PKGMGR_REQ_RECOVER;
+                       if (pi->pkgmgr_info)
+                               free(pi->pkgmgr_info);
+                       pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+                       __parse_multiple_pkgs(pi, argc, argv);
+                       break;
+
+               case 'D': /* disable pkg */
+                       pi->request_type = PKGMGR_REQ_DISABLE_PKG;
+                       if (pi->pkgmgr_info)
+                               free(pi->pkgmgr_info);
+                       pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+                       __parse_multiple_pkgs(pi, argc, argv);
+                       break;
+
+               case 'A': /* enable pkg */
+                       pi->request_type = PKGMGR_REQ_ENABLE_PKG;
+                       if (pi->pkgmgr_info)
+                               free(pi->pkgmgr_info);
+                       pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+                       __parse_multiple_pkgs(pi, argc, argv);
+                       break;
+
+               case 'u': /* uid */
+                       g_target_uid = (uid_t)atoi(optarg);
+                       pi->target_uid = (uid_t)atoi(optarg);
+                       break;
+
+               case 'G': /* debug mode */
+                       pi->debug_mode = 1;
+                       g_debug_mode = 1;
+                       break;
+
+               case 'S': /* skip optimization */
+                       pi->skip_optimization = 1;
+                       g_skip_optimization = 1;
+                       break;
+
+                       /* Otherwise */
+               case '?':       /* Not an option */
+                       break;
+
+               case ':':       /* */
+                       break;
+
+               }
+       }
+
+       /* if target user is not set, set as tizenglobalapp user */
+       if (pi->target_uid == 0) {
+               pi->target_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
+               g_target_uid = pi->target_uid;
+       }
+ RET:
+       return r;
+}
+
+API int pkgmgr_installer_get_request_type(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->request_type;
+}
+
+API uid_t pkgmgr_installer_get_uid(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->target_uid;
+}
+
+API const char *pkgmgr_installer_get_request_info(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->pkgmgr_info;
+}
+
+API const char *pkgmgr_installer_get_request_info_at(pkgmgr_installer *pi,
+               int at)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return (const char *)g_list_nth_data(pi->pkgs, at);
+}
+
+API int pkgmgr_installer_get_request_info_count(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return g_list_length(pi->pkgs);
+}
+
+API const char *pkgmgr_installer_get_tep_path(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->tep_path;
+}
+
+API int pkgmgr_installer_get_tep_move_type(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->tep_move;
+}
+
+API const char *pkgmgr_installer_get_session_id(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->session_id;
+}
+
+API const char *pkgmgr_installer_get_license_path(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->license_path;
+}
+
+API const char *pkgmgr_installer_get_optional_data(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->optional_data;
+}
+
+API int pkgmgr_installer_is_quiet(pkgmgr_installer *pi)
+{
+       return 1;
+}
+
+API int pkgmgr_installer_get_move_type(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->move_type;
+}
+
+API const char *pkgmgr_installer_get_caller_pkgid(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->caller_pkgid;
+}
+
+API int pkgmgr_installer_get_is_preload(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->is_preload;
+}
+
+API int pkgmgr_installer_get_force_removal(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->force_removal;
+}
+
+API int pkgmgr_installer_get_is_preload_rw(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->is_preload_rw;
+}
+
+API int pkgmgr_installer_get_no_removal(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->no_removal;
+}
+
+API int pkgmgr_installer_get_keep_rwdata(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->keep_rwdata;
+}
+
+API int pkgmgr_installer_get_partial_rw(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->partial_rw;
+}
+
+API int pkgmgr_installer_get_debug_mode(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->debug_mode;
+}
+
+API int pkgmgr_installer_get_skip_check_reference(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->skip_check_reference;
+}
+
+API int pkgmgr_installer_get_skip_optimization(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->skip_optimization;
+}
+
+API int pkgmgr_installer_get_recovery_cleanup(pkgmgr_installer *pi)
+{
+       CHK_PI_RET(PKGMGR_REQ_INVALID);
+       return pi->recovery_cleanup;
+}
+
+API int pkgmgr_installer_send_app_uninstall_signal(pkgmgr_installer *pi,
+                            const char *pkg_type,
+                            const char *pkgid,
+                            const char *val)
+{
+       int ret = 0;
+       ret = __send_signal_for_event(pi, pkg_type, pkgid, NULL,
+                       PKGMGR_INSTALLER_APPID_KEY_STR, val);
+       return ret;
+}
+
+API int pkgmgr_installer_send_app_uninstall_signal_for_uid(
+               pkgmgr_installer *pi, uid_t uid, const char *pkg_type,
+               const char *pkgid, const char *val)
+{
+       int ret = 0;
+       ret = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, NULL,
+                       PKGMGR_INSTALLER_APPID_KEY_STR, val);
+       return ret;
+}
+
+API int pkgmgr_installer_set_uid(pkgmgr_installer *pi, uid_t uid)
+{
+       if (pi == NULL)
+               return -1;
+
+       pi->target_uid = uid;
+       g_target_uid = pi->target_uid;
+
+       return 0;
+}
+
+API int
+pkgmgr_installer_send_app_signal(pkgmgr_installer *pi,
+                            const char *pkg_type,
+                            const char *pkgid,
+                            const char *appid,
+                            const char *key, const char *val)
+{
+       int r = 0;
+
+       if (!pi->conn) {
+               ERR("connection is NULL");
+               return -1;
+       }
+
+       r = __send_signal_for_event(pi, pkg_type, pkgid, appid, key, val);
+
+       return r;
+}
+
+API int
+pkgmgr_installer_send_signal(pkgmgr_installer *pi,
+                            const char *pkg_type,
+                            const char *pkgid,
+                            const char *key, const char *val)
+{
+       int r = 0;
+
+       if (!pi->conn) {
+               ERR("connection is NULL");
+               return -1;
+       }
+
+       r = __send_signal_for_event(pi, pkg_type, pkgid, NULL, key, val);
+
+       return r;
+}
+
+API int pkgmgr_installer_send_app_signal_for_uid(pkgmgr_installer *pi,
+               uid_t uid, const char *pkg_type, const char *pkgid,
+               const char *appid, const char *key, const char *val)
+{
+       int r = 0;
+
+       if (!pi->conn) {
+               ERR("connection is NULL");
+               return -1;
+       }
+
+       r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, appid,
+                       key, val);
+
+       return r;
+}
+
+API int pkgmgr_installer_send_signal_for_uid(pkgmgr_installer *pi,
+               uid_t uid, const char *pkg_type, const char *pkgid,
+               const char *key, const char *val)
+{
+       int r = 0;
+
+       if (!pi->conn) {
+               ERR("connection is NULL");
+               return -1;
+       }
+
+       r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, NULL,
+                       key, val);
+
+       return r;
+}
+
+API int pkgmgr_installer_set_request_type(pkgmgr_installer *pi, int request_type)
+{
+       if (pi == NULL)
+               return -1;
+
+       pi->request_type = request_type;
+       return 0;
+}
+
+API int pkgmgr_installer_set_session_id(pkgmgr_installer *pi, const char *session_id)
+{
+       if (pi == NULL || session_id == NULL)
+               return -1;
+
+       pi->session_id = strndup(session_id, MAX_STRLEN);
+       return 0;
+}
+
+API int pkgmgr_installer_create_certinfo_set_handle(pkgmgr_instcertinfo_h *handle)
+{
+       int ret = 0;
+       ret = pkgmgrinfo_create_certinfo_set_handle(handle);
+       return ret;
+}
+
+API int pkgmgr_installer_set_cert_value(pkgmgr_instcertinfo_h handle, pkgmgr_instcert_type cert_type, char *cert_value)
+{
+       int ret = 0;
+       ret = pkgmgrinfo_set_cert_value(handle, cert_type, cert_value);
+       return ret;
+}
+
+API int pkgmgr_installer_save_certinfo(const char *pkgid, pkgmgr_instcertinfo_h handle, uid_t uid)
+{
+       int ret = 0;
+       ret = pkgmgrinfo_save_certinfo(pkgid, handle, uid);
+       return ret;
+}
+
+API int pkgmgr_installer_destroy_certinfo_set_handle(pkgmgr_instcertinfo_h handle)
+{
+       int ret = 0;
+       ret = pkgmgrinfo_destroy_certinfo_set_handle(handle);
+       return ret;
+}
+
+API int pkgmgr_installer_delete_certinfo(const char *pkgid)
+{
+       int ret = 0;
+       ret = pkgmgrinfo_delete_certinfo(pkgid);
+       return ret;
+}
+
+API int pkgmgr_installer_set_privilege_level(pkgmgr_privilege_level level)
+{
+       g_privilege_level = level;
+
+       return 0;
+}
+
+API int pkgmgr_installer_info_get_target_uid(uid_t *uid)
+{
+       *uid = g_target_uid;
+
+       return 0;
+}
+
+API int pkgmgr_installer_info_get_privilege_level(pkgmgr_privilege_level *level)
+{
+       *level = g_privilege_level;
+
+       return 0;
+}
+
+API int pkgmgr_installer_info_get_debug_mode(int *debug_mode)
+{
+       *debug_mode = g_debug_mode;
+       return 0;
+}
+
+API int pkgmgr_installer_info_get_skip_optimization(int *skip_optimization)
+{
+       *skip_optimization = g_skip_optimization;
+       return 0;
+}
+
+#define CASE_TO_STR(ERRCODE) case ERRCODE: return ERRCODE##_STR
+API const char *pkgmgr_installer_error_to_string(int error_code)
+{
+       switch (error_code) {
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_UNDEFINED_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_GLOBALSYMLINK_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_GRANT_PERMISSION_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_IMAGE_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_UNZIP_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_SECURITY_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_REGISTER_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_PRIVILEGE_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_PARSE_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_RECOVERY_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_DELTA_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_APP_DIR_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_CONFIG_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_SIGNATURE_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_SIGNATURE_INVALID);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_CERT_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_AUTHOR_CERT_NOT_MATCH);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_AUTHOR_CERT_NOT_FOUND);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_ICON_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_ICON_NOT_FOUND);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_MANIFEST_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_MANIFEST_NOT_FOUND);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_PACKAGE_NOT_FOUND);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_OPERATION_NOT_ALLOWED);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_OUT_OF_SPACE);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_INVALID_VALUE);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_ERROR);
+       CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_OK);
+       default:
+               return PKGMGR_INSTALLER_ERRCODE_UNDEFINED_ERROR_STR;
+       }
+}
+
+API int pkgmgr_installer_add_pkg(pkgmgr_installer *pi,
+               const char *pkgid, const char *pkg_type)
+{
+       pkg_signal_info *info;
+       if (!pi || !pkgid || !pkg_type) {
+               ERR("invalid argument");
+               return -1;
+       }
+
+       info = calloc(1, sizeof(pkg_signal_info));
+       if (!info) {
+               ERR("out of memory");
+               return -1;
+       }
+
+       info->pkgid = strdup(pkgid);
+       info->pkg_type = strdup(pkg_type);
+       if (!info->pkgid || !info->pkg_type) {
+               ERR("out of memory");
+               free(info->pkgid);
+               free(info->pkg_type);
+               free(info);
+               return -1;
+       }
+       g_hash_table_insert(pi->pkg_list, (gpointer)info->pkgid, (gpointer)info);
+
+       return 0;
+}
+
+static void __build_multi_signal(gpointer key, gpointer value,
+               gpointer user_data)
+{
+       GVariantBuilder *builder = (GVariantBuilder *)user_data;
+       pkg_signal_info *info = (pkg_signal_info *)value;
+
+       g_variant_builder_add(builder, "(sss)", info->pkgid, "", info->pkg_type);
+}
+
+API int pkgmgr_installer_send_signals(pkgmgr_installer *pi,
+               const char *key, const char *val)
+{
+       char *sid;
+       const char *signal_name;
+       GError *err = NULL;
+       GVariantBuilder *builder;
+
+       if (!pi || !key || !val) {
+               ERR("invalid argument");
+               return -1;
+       }
+
+       sid = pi->session_id;
+       if (!sid)
+               sid = "";
+
+       signal_name = __get_signal_name(pi, key, "");
+       if (!signal_name) {
+               ERR("unknown signal type");
+               return -1;
+       }
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a(sss)"));
+       g_hash_table_foreach(pi->pkg_list, __build_multi_signal, builder);
+       if (g_dbus_connection_emit_signal(pi->conn, NULL,
+                               PKGMGR_INSTALLER_DBUS_OBJECT_PATH,
+                               PKGMGR_INSTALLER_DBUS_INTERFACE, signal_name,
+                               g_variant_new("(usa(sss)ss)",
+                                               pi->target_uid, sid, builder, key,
+                                               val), &err) != TRUE) {
+               ERR("failed to send dbus signal");
+               if (err) {
+                       ERR("err: %s", err->message);
+                       g_error_free(err);
+               }
+               g_variant_builder_unref(builder);
+               return -1;
+       }
+       g_variant_builder_unref(builder);
+
+       return 0;
+}
+
+API int pkgmgr_installer_send_signals_for_uid(pkgmgr_installer *pi, uid_t uid,
+               const char *key, const char *val)
+{
+       char *sid;
+       size_t data_len;
+       size_t name_size;
+       GVariant *gv;
+       GVariantBuilder *builder;
+       gsize gv_len;
+       gpointer gv_data;
+       void *data;
+       void *ptr;
+       const char *signal_name;
+
+       if (!pi || !pi->conn) {
+               ERR("connection is NULL");
+               return -1;
+       }
+
+       sid = pi->session_id;
+       if (!sid)
+               sid = "";
+
+       data_len = sizeof(size_t) + sizeof(gsize);
+
+       /* including null byte */
+       signal_name = __get_signal_name(pi, key, "");
+       if (!signal_name) {
+               ERR("unknown signal type");
+               return -1;
+       }
+       name_size = strlen(signal_name) + 1;
+       data_len += name_size;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a(sss)"));
+       g_hash_table_foreach(pi->pkg_list, __build_multi_signal, builder);
+
+       gv = g_variant_new("(usa(sss)ss)", uid, sid, builder, key, val);
+       g_variant_builder_unref(builder);
+       if (gv == NULL) {
+               ERR("failed to create GVariant instance");
+               return -1;
+       }
+
+       gv_len = g_variant_get_size(gv);
+       gv_data = g_malloc(gv_len);
+       g_variant_store(gv, gv_data);
+       g_variant_unref(gv);
+       data_len += gv_len;
+
+       data = malloc(data_len);
+       if (data == NULL) {
+               ERR("out of memory");
+               g_free(gv_data);
+               return -1;
+       }
+       ptr = data;
+       memcpy(ptr, &name_size, sizeof(size_t));
+       ptr += sizeof(size_t);
+       memcpy(ptr, &gv_len, sizeof(gsize));
+       ptr += sizeof(gsize);
+       memcpy(ptr, signal_name, name_size);
+       ptr += name_size;
+       memcpy(ptr, gv_data, gv_len);
+       g_free(gv_data);
+
+       if (__send_signal_to_agent(uid, data, data_len)) {
+               ERR("failed to send signal to agent");
+               free(data);
+               return -1;
+       }
+
+       free(data);
+
+       return 0;
+}
+
+API int pkgmgr_installer_set_is_upgrade(pkgmgr_installer *pi, int is_upgrade) {
+       if (pi == NULL)
+               return -1;
+
+       pi->is_upgrade = is_upgrade;
+       return 0;
+}
+
+static GVariant *__get_gvariant_from_event_info(pkgmgr_res_event_info *event_info)
+{
+       pkgmgr_res_event_info_t *info = event_info;
+       GVariantBuilder *builder;
+       GVariant *result;
+       GList *path_states;
+       res_event_path_state_t *path_state;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a(si)"));
+       if (builder == NULL) {
+               ERR("out of memory");
+               return NULL;
+       }
+
+       for (path_states = info->path_states; path_states != NULL;
+                       path_states = path_states->next) {
+               path_state = (res_event_path_state_t *)path_states->data;
+               g_variant_builder_add(builder, "(si)",
+                               path_state->path, path_state->state);
+       }
+
+       result = g_variant_new("(ia(si))", info->error_code, builder);
+       g_variant_builder_unref(builder);
+
+       if (result == NULL) {
+               ERR("Fail to create extra data");
+               return NULL;
+       }
+
+       return result;
+}
+
+API int pkgmgr_installer_send_res_signal(pkgmgr_installer *pi,
+               const char *pkgid, const char *status,
+               pkgmgr_res_event_info *event_info)
+{
+       char *sid;
+       const char *signal_name;
+       GError *err = NULL;
+       GVariant *extra_param;
+
+       if (!pi || !pkgid || !status) {
+               ERR("invalid argument");
+               return -1;
+       }
+
+       sid = pi->session_id;
+       if (!sid)
+               sid = "";
+
+       signal_name = __get_signal_name(pi, "", "");
+       if (!signal_name) {
+               ERR("unknown signal type");
+               return -1;
+       }
+
+       extra_param = __get_gvariant_from_event_info(event_info);
+       if (extra_param == NULL) {
+               ERR("Fail to get extra parameter");
+               return -1;
+       }
+
+       if (g_dbus_connection_emit_signal(pi->conn, NULL,
+                               PKGMGR_INSTALLER_DBUS_OBJECT_PATH,
+                               PKGMGR_INSTALLER_DBUS_INTERFACE, signal_name,
+                               g_variant_new("(usssv)", pi->target_uid, sid,
+                                               pkgid, status, extra_param),
+                               &err) != TRUE) {
+               ERR("failed to send dbus signal");
+               if (err) {
+                       ERR("err: %s", err->message);
+                       g_error_free(err);
+               }
+               return -1;
+       }
+
+       return 0;
+}
+
+API int pkgmgr_installer_send_res_signal_for_uid(pkgmgr_installer *pi,
+               uid_t uid, const char *pkgid, const char *status,
+               pkgmgr_res_event_info *event_info)
+{
+       char *sid;
+       size_t data_len;
+       size_t name_size;
+       GVariant *gv;
+       gsize gv_len;
+       gpointer gv_data;
+       void *data;
+       void *ptr;
+       const char *signal_name;
+       GVariant *extra_param;
+
+       if (!pi || !pi->conn) {
+               ERR("connection is NULL");
+               return -1;
+       }
+
+       sid = pi->session_id;
+       if (!sid)
+               sid = "";
+
+       data_len = sizeof(size_t) + sizeof(gsize);
+
+       /* including null byte */
+       signal_name = __get_signal_name(pi, "", "");
+       if (!signal_name) {
+               ERR("unknown signal type");
+               return -1;
+       }
+       name_size = strlen(signal_name) + 1;
+       data_len += name_size;
+
+       extra_param = __get_gvariant_from_event_info(event_info);
+       if (extra_param == NULL) {
+               ERR("Fail to get extra parameter");
+               return -1;
+       }
+
+       gv = g_variant_new("(usssv)", pi->target_uid, sid,
+                       pkgid, status, extra_param);
+       if (gv == NULL) {
+               ERR("failed to create GVariant instance");
+               return -1;
+       }
+
+       gv_len = g_variant_get_size(gv);
+       gv_data = g_malloc(gv_len);
+       g_variant_store(gv, gv_data);
+       g_variant_unref(gv);
+       data_len += gv_len;
+
+       data = malloc(data_len);
+       if (data == NULL) {
+               ERR("out of memory");
+               g_free(gv_data);
+               return -1;
+       }
+       ptr = data;
+       memcpy(ptr, &name_size, sizeof(size_t));
+       ptr += sizeof(size_t);
+       memcpy(ptr, &gv_len, sizeof(gsize));
+       ptr += sizeof(gsize);
+       memcpy(ptr, signal_name, name_size);
+       ptr += name_size;
+       memcpy(ptr, gv_data, gv_len);
+       g_free(gv_data);
+
+       if (__send_signal_to_agent(uid, data, data_len)) {
+               ERR("failed to send signal to agent");
+               free(data);
+               return -1;
+       }
+
+       free(data);
+
+       return 0;
+}
+
+API int pkgmgr_installer_send_pkg_upgrade_signal(pkgmgr_installer *pi,
+               unsigned int progress)
+{
+       const char *signal_name;
+       GError *err = NULL;
+
+       if (!pi) {
+               ERR("invalid argument");
+               return -1;
+       }
+
+       signal_name = PKGMGR_INSTALLER_PKG_UPGRADE_EVENT_STR;
+       if (g_dbus_connection_emit_signal(pi->conn, NULL,
+                               PKGMGR_INSTALLER_DBUS_OBJECT_PATH,
+                               PKGMGR_INSTALLER_DBUS_INTERFACE, signal_name,
+                               g_variant_new("(u)", progress),
+                               &err) != TRUE) {
+               ERR("failed to send dbus signal");
+               if (err) {
+                       ERR("err: %s", err->message);
+                       g_error_free(err);
+               }
+               return -1;
+       }
+
+       return 0;
+}
index af71836..07b2e5e 100644 (file)
@@ -43,7 +43,7 @@ extern "C" {
 /**
  * pkgmgr_installer is an opaque type for an object
  */
-typedef void pkgmgr_installer;
+typedef struct pkgmgr_installer pkgmgr_installer;
 typedef void *pkgmgr_instcertinfo_h;
 
 /**
index a92a883..26df677 100644 (file)
 #endif /* LOG_TAG */
 #define LOG_TAG "PKGMGR_INSTALLER"
 
-#ifndef _E
-#define _E LOGE
+#ifndef ERR
+#define ERR(fmt, args...) LOGE("[%s:%d] "fmt"\n", __func__, __LINE__, ##args)
 #endif
 
-#ifndef _D
-#define _D LOGD
+#ifndef DBG
+#define DBG(fmt, args...) LOGD("[%s:%d] "fmt"\n", __func__, __LINE__, ##args)
 #endif
 
-#ifndef _I
-#define _I LOGI
+#ifndef INFO
+#define INFO(fmt, args...) LOGI("[%s:%d] "fmt"\n", __func__, __LINE__, ##args)
 #endif
 
 #endif  /* __PKGMGR_INSTALLER_DEBUG_H__ */
index d8e49ad..d9c48d0 100644 (file)
@@ -24,8 +24,6 @@
 #include <list>
 #include <vector>
 
-#include "PkgSignal.h"
-
 namespace pkgmgr {
 namespace installer {