[Release] wrt-installer_0.1.37
[framework/web/wrt-installer.git] / src / pkg-manager / backendlib.cpp
index f2ebcf5..497bf3f 100644 (file)
@@ -23,6 +23,8 @@
  *             to package manager
  */
 #include "package-manager-plugin.h"
+#include <package-manager.h>
+#include <regex.h>
 #include <dlog.h>
 #include <dpl/wrt-dao-ro/global_config.h>
 #include <vcore/VCore.h>
 #include <dpl/foreach.h>
 #include <dpl/utils/folder_size.h>
 #include <dpl/wrt-dao-ro/wrt_db_types.h>
+#include <dpl/copy.h>
+#include <dpl/abstract_waitable_input_adapter.h>
+#include <dpl/abstract_waitable_output_adapter.h>
+#include <dpl/zip_input.h>
+#include <dpl/binary_queue.h>
+#include <dpl/file_input.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include "root_parser.h"
+#include "widget_parser.h"
+#include "parser_runner.h"
 
 using namespace WrtDB;
 
@@ -43,7 +55,7 @@ using namespace WrtDB;
 #undef FALSE
 #define TRUE 0
 #define FALSE -1
-#define GET_DIRECTORY_SIZE_KB(x)    (x)/1024
+#define GET_DIRECTORY_SIZE_KB(x)    (x) / 1024
 
 #ifdef __cplusplus
 extern "C"
@@ -53,11 +65,19 @@ extern "C"
 static void pkg_native_plugin_on_unload();
 static int pkg_plugin_app_is_installed(const char *pkg_name);
 static int pkg_plugin_get_installed_apps_list(const char *category,
-        const char *option, package_manager_pkg_info_t **list, int *count);
-static int pkg_plugin_get_app_detail_info(const char *pkg_name,
-        package_manager_pkg_detail_info_t *pkg_detail_info);
-static int pkg_plugin_get_app_detail_info_from_package(const char *pkg_path,
-        package_manager_pkg_detail_info_t *pkg_detail_info);
+                                              const char *option,
+                                              package_manager_pkg_info_t **list,
+                                              int *count);
+static int pkg_plugin_get_app_detail_info(
+    const char *pkg_name,
+    package_manager_pkg_detail_info_t *
+    pkg_detail_info);
+static int pkg_plugin_get_app_detail_info_from_package(
+    const char *pkg_path,
+    package_manager_pkg_detail_info_t
+    *pkg_detail_info);
+
+pkgmgr_info *pkgmgr_client_check_pkginfo_from_file(const char *pkg_path);
 
 static void pkg_native_plugin_on_unload()
 {
@@ -66,35 +86,52 @@ static void pkg_native_plugin_on_unload()
 
 static int pkg_plugin_app_is_installed(const char *pkg_name)
 {
+    const char* REG_PKGID_PATTERN = "^[a-zA-Z0-9]{10}$";
     LogDebug("pkg_plugin_app_is_installed() is called");
 
     WrtDB::WrtDatabase::attachToThreadRO();
 
-    bool result = WidgetDAOReadOnly::isWidgetInstalled(
-                    DPL::FromUTF8String(pkg_name));
-    WrtDB::WrtDatabase::detachFromThread();
+    regex_t reg;
+    if (regcomp(&reg, REG_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+        LogDebug("Regcomp failed");
+    }
 
-    if (result) {
-        return TRUE;
-    } else {
+    WrtDB::TizenAppId appid;
+
+    if (!(regexec(&reg, pkg_name,
+                    static_cast<size_t>(0), NULL, 0) == 0))
+    {
+        LogError("Invalid argument : " << pkg_name);
         return FALSE;
     }
+
+    Try {
+        WrtDB::TizenPkgId pkgid(DPL::FromUTF8String(pkg_name));
+        appid = WidgetDAOReadOnly::getTzAppId(pkgid);
+        LogDebug("appid : " << appid);
+    } Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
+        WrtDB::WrtDatabase::detachFromThread();
+        return FALSE;
+    }
+    WrtDB::WrtDatabase::detachFromThread();
+    return TRUE;
 }
 
 static int pkg_plugin_get_installed_apps_list(const char * /*category*/,
-        const char * /*option*/, package_manager_pkg_info_t **list, int *count)
+                                              const char * /*option*/,
+                                              package_manager_pkg_info_t **list,
+                                              int *count)
 {
     LogDebug("pkg_plugin_get_installed_apps_list() is called");
 
     package_manager_pkg_info_t *pkg_list = NULL;
     package_manager_pkg_info_t *pkg_last = NULL;
 
-
     WrtDB::WrtDatabase::attachToThreadRO();
-    WidgetPkgNameList pkgnameslList = WidgetDAOReadOnly::getPkgnameList();
+    TizenAppIdList tizenAppidList = WidgetDAOReadOnly::getTizenAppidList();
     *count = 0;
 
-    FOREACH(iterator, pkgnameslList) {
+    FOREACH(iterator, tizenAppidList) {
         package_manager_pkg_info_t *pkg_info =
             static_cast<package_manager_pkg_info_t*>
             (malloc(sizeof(package_manager_pkg_info_t)));
@@ -106,11 +143,11 @@ static int pkg_plugin_get_installed_apps_list(const char * /*category*/,
             pkg_last->next = pkg_info;
         }
 
-        WidgetPkgName pkgname = *iterator;
-        WidgetDAOReadOnly widget(pkgname);
+        TizenAppId tzAppid = *iterator;
+        WidgetDAOReadOnly widget(tzAppid);
         strncpy(pkg_info->pkg_type, "wgt", PKG_TYPE_STRING_LEN_MAX);
         snprintf(pkg_info->pkg_name, PKG_NAME_STRING_LEN_MAX, "%s",
-                DPL::ToUTF8String(pkgname).c_str());
+                 DPL::ToUTF8String(tzAppid).c_str());
 
         DPL::Optional<DPL::String> version = widget.getVersion();
         if (!version.IsNull()) {
@@ -128,16 +165,26 @@ static int pkg_plugin_get_installed_apps_list(const char * /*category*/,
     return TRUE;
 }
 
-static int pkg_plugin_get_app_detail_info(const char *pkg_name,
-        package_manager_pkg_detail_info_t *pkg_detail_info)
+static int pkg_plugin_get_app_detail_info(
+    const char *pkg_name,
+    package_manager_pkg_detail_info_t *
+    pkg_detail_info)
 {
     LogDebug("pkg_plugin_get_app_detail_info() is called");
 
-
     WrtDB::WrtDatabase::attachToThreadRO();
-    int handle = WidgetDAOReadOnly::getHandle(
-                    DPL::FromUTF8String(pkg_name));
-    WidgetDAOReadOnly widget(handle);
+
+    WrtDB::TizenAppId appid;
+    Try {
+        WrtDB::TizenPkgId pkgid(DPL::FromUTF8String(pkg_name));
+        appid = WidgetDAOReadOnly::getTzAppId(pkgid);
+        LogDebug("appid : " << appid);
+    } Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
+        WrtDB::WrtDatabase::detachFromThread();
+        return FALSE;
+    }
+
+    WidgetDAOReadOnly widget(appid);
 
     DPL::Optional<DPL::String> version = widget.getVersion();
     DPL::Optional<DPL::String> id = widget.getGUID();
@@ -148,12 +195,14 @@ static int pkg_plugin_get_app_detail_info(const char *pkg_name,
                 DPL::ToUTF8String(*version).c_str(),
                 PKG_VERSION_STRING_LEN_MAX - 1);
     }
-    snprintf(pkg_detail_info->optional_id, PKG_NAME_STRING_LEN_MAX, "%d",
-           handle);
+    snprintf(pkg_detail_info->pkgid, PKG_NAME_STRING_LEN_MAX, "%s",
+             pkg_name);
+    snprintf(pkg_detail_info->optional_id, PKG_NAME_STRING_LEN_MAX, "%s",
+             DPL::ToUTF8String(appid).c_str());
     WidgetLocalizedInfo localizedInfo;
 
     if (locale.IsNull()) {
-        LogError("is NULL");
+        LogDebug("locale is NULL");
         DPL::String languageTag(L"");
         localizedInfo = widget.getLocalizedInfo(languageTag);
     } else {
@@ -169,6 +218,11 @@ static int pkg_plugin_get_app_detail_info(const char *pkg_name,
     strncpy(pkg_detail_info->pkg_type, "wgt", PKG_TYPE_STRING_LEN_MAX);
     strncpy(pkg_detail_info->pkg_name, pkg_name, PKG_NAME_STRING_LEN_MAX - 1);
 
+    std::string min_version = DPL::ToUTF8String((*widget.getMinimumWacVersion()));
+
+    strncpy(pkg_detail_info->min_platform_version, min_version.c_str(),
+            PKG_VERSION_STRING_LEN_MAX - 1);
+
     /* set installed time */
     pkg_detail_info->installed_time = widget.getInstallTime();
 
@@ -196,13 +250,220 @@ static int pkg_plugin_get_app_detail_info(const char *pkg_name,
     return TRUE;
 }
 
+int getConfigParserData(const std::string &widgetPath, ConfigParserData& configInfo)
+{
+    const char* CONFIG_XML = "config.xml";
+    const char* WITH_OSP_XML = "res/wgt/config.xml";
+
+    Try {
+        ParserRunner parser;
+
+        std::unique_ptr<DPL::ZipInput> zipFile(
+                new DPL::ZipInput(widgetPath));
+
+        std::unique_ptr<DPL::ZipInput::File> configFile;
+
+        // Open config.xml file
+        Try {
+            configFile.reset(zipFile->OpenFile(CONFIG_XML));
+        }
+        Catch(DPL::ZipInput::Exception::OpenFileFailed)
+        {
+            configFile.reset(zipFile->OpenFile(WITH_OSP_XML));
+        }
+
+        // Extract config
+        DPL::BinaryQueue buffer;
+        DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
+        DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
+        DPL::Copy(&inputAdapter, &outputAdapter);
+        parser.Parse(&buffer,
+                ElementParserPtr(
+                    new RootParser<WidgetParser>(configInfo,
+                        DPL::
+                        FromUTF32String(
+                            L"widget"))));
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        LogError("Failed to open widget package");
+        return FALSE;
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        LogError("Failed to open config.xml file");
+        return FALSE;
+    }
+    Catch(DPL::CopyFailed)
+    {
+        LogError("Failed to extract config.xml file");
+        return FALSE;
+    }
+    Catch(DPL::FileInput::Exception::OpenFailed)
+    {
+        LogError("Failed to open config.xml file");
+        return FALSE;
+    }
+    Catch(ElementParser::Exception::ParseError)
+    {
+        LogError("Failed to parse config.xml file");
+        return FALSE;
+    }
+    Catch(DPL::ZipInput::Exception::SeekFileFailed)
+    {
+        LogError("Failed to seek widget archive - corrupted package?");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+char* getIconInfo(const std::string widgetPath,
+        const std::string icon_name, int &icon_size)
+{
+    Try {
+        std::unique_ptr<DPL::ZipInput> zipFile(
+                new DPL::ZipInput(widgetPath));
+
+        std::unique_ptr<DPL::ZipInput::File> iconFile;
+
+        iconFile.reset(zipFile->OpenFile(icon_name));
+
+        DPL::BinaryQueue buffer;
+        DPL::AbstractWaitableInputAdapter inputAdapter(iconFile.get());
+        DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
+        DPL::Copy(&inputAdapter, &outputAdapter);
+        icon_size = buffer.Size();
+        char *getBuffer = (char*) calloc(1, (sizeof(char) * icon_size) + 1);
+        buffer.Flatten(getBuffer, buffer.Size());
+        return getBuffer;
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        LogError("Failed to open widget package");
+        return NULL;
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        LogError("Failed to open icon file");
+        return NULL;
+    }
+}
+
+int getWidgetDetailInfoFromPackage(const char* pkgPath,
+        package_manager_pkg_detail_info_t* pkg_detail_info)
+{
+    const std::string widget_path(pkgPath);
+    ConfigParserData configInfo;
+
+    if (FALSE == getConfigParserData(widget_path, configInfo)) {
+        return FALSE;
+    }
+
+    strncpy(pkg_detail_info->pkg_type, "wgt", PKG_TYPE_STRING_LEN_MAX);
+    if (!configInfo.tizenPkgId.IsNull()) {
+        strncpy(pkg_detail_info->pkgid,
+                DPL::ToUTF8String(*configInfo.tizenPkgId).c_str(), PKG_TYPE_STRING_LEN_MAX - 1);
+    }
+    if (!configInfo.tizenAppId.IsNull()) {
+        strncpy(pkg_detail_info->pkg_name,
+                DPL::ToUTF8String(*configInfo.tizenAppId).c_str(),
+                PKG_NAME_STRING_LEN_MAX - 1);
+    }
+    if (!configInfo.version.IsNull()) {
+        strncpy(pkg_detail_info->version,
+                DPL::ToUTF8String(*configInfo.version).c_str(),
+                PKG_VERSION_STRING_LEN_MAX - 1);
+    }
+
+    DPL::Optional<DPL::String> name;
+    DPL::Optional<DPL::String> desc;
+    DPL::OptionalString defaultLocale = configInfo.defaultlocale;
+
+    FOREACH(localizedData, configInfo.localizedDataSet)
+    {
+        Locale i = localizedData->first;
+        if (!!defaultLocale) {
+            if (defaultLocale == i) {
+                name = localizedData->second.name;
+                desc = localizedData->second.description;
+                break;
+            }
+        } else {
+            name = localizedData->second.name;
+            desc = localizedData->second.description;
+            break;
+        }
+    }
+
+    if( !name.IsNull()) {
+        strncpy(pkg_detail_info->label, DPL::ToUTF8String(*name).c_str(),
+                PKG_LABEL_STRING_LEN_MAX - 1);
+    }
+
+    if (!desc.IsNull()) {
+        strncpy(pkg_detail_info->pkg_description,
+                DPL::ToUTF8String(*desc).c_str(),
+                PKG_VALUE_STRING_LEN_MAX - 1);
+    }
+
+    if (!configInfo.tizenMinVersionRequired.IsNull()) {
+        strncpy(pkg_detail_info->min_platform_version,
+                DPL::ToUTF8String(*configInfo.tizenMinVersionRequired).c_str(),
+                PKG_VERSION_STRING_LEN_MAX - 1);
+    }
+
+    if (!configInfo.authorName.IsNull()) {
+        strncpy(pkg_detail_info->author,
+                DPL::ToUTF8String(*configInfo.authorName).c_str(),
+                PKG_VALUE_STRING_LEN_MAX - 1);
+    }
+
+    GList *privilege_list = pkg_detail_info->privilege_list;
+
+    FOREACH(it, configInfo.featuresList) {
+        std::string featureInfo =  DPL::ToUTF8String(it->name);
+        LogDebug("privilege : " << featureInfo);
+        int length = featureInfo.size();
+        char *privilege = (char*) calloc(1, (sizeof(char) * (length + 1)));
+        snprintf(privilege, length + 1, "%s", featureInfo.c_str());
+        privilege_list = g_list_append(privilege_list, &privilege);
+    }
+
+    std::string icon_name;
+    FOREACH(i, configInfo.iconsList) {
+        LogDebug("icon name: " << i->src);
+        icon_name = DPL::ToUTF8String(i->src);
+        break;
+    }
+
+    pkg_detail_info->icon_buf = getIconInfo(widget_path, icon_name,
+            pkg_detail_info->icon_size);
+    LogDebug("icon size : " << pkg_detail_info->icon_size);
+
+    return TRUE;
+}
+
 static int pkg_plugin_get_app_detail_info_from_package(
-        const char * /*pkg_path*/,
-        package_manager_pkg_detail_info_t * /*pkg_detail_info*/)
+    const char * pkg_path,
+    package_manager_pkg_detail_info_t * pkg_detail_info)
 {
     LogDebug("pkg_plugin_get_app_detail_info_from_package() is called");
+    return getWidgetDetailInfoFromPackage(pkg_path, pkg_detail_info);
+}
 
-    return TRUE;
+pkgmgr_info *pkgmgr_client_check_pkginfo_from_file(const char *pkg_path)
+{
+    LogDebug("pkgmgr_client_check_pkginfo_from_file() is called");
+    package_manager_pkg_detail_info_t *pkg_detail_info;
+    pkg_detail_info = (package_manager_pkg_detail_info_t*)malloc(
+            sizeof(package_manager_pkg_detail_info_t));
+    int ret = getWidgetDetailInfoFromPackage(pkg_path, pkg_detail_info);
+    if (FALSE == ret) {
+        LogError("Failed to get package detail info ");
+        return NULL;
+    }
+    return &pkg_detail_info;
 }
 
 __attribute__ ((visibility("default")))