Fixed get detail information about widget from backend.
[framework/web/wrt-installer.git] / src / pkg-manager / backendlib.cpp
index 37952c1..e569561 100644 (file)
@@ -23,6 +23,7 @@
  *             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 <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;
 
@@ -66,6 +77,8 @@ static int pkg_plugin_get_app_detail_info_from_package(
     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()
 {
     LogDebug("pkg_native_plugin_unload() is called");
@@ -85,23 +98,23 @@ static int pkg_plugin_app_is_installed(const char *pkg_name)
 
     WrtDB::TizenAppId appid;
 
-    if ((regexec(&reg, pkg_name,
+    if (!(regexec(&reg, pkg_name,
                     static_cast<size_t>(0), NULL, 0) == 0))
     {
-        WrtDB::TizenPkgId pkgid(DPL::FromUTF8String(pkg_name));
-        appid = WidgetDAOReadOnly::getTzAppId(pkgid);
-    } else {
-        appid = DPL::FromUTF8String(pkg_name);
+        LogError("Invalid argument : " << pkg_name);
+        return FALSE;
     }
 
-    bool result = WidgetDAOReadOnly::isWidgetInstalled(appid);
-    WrtDB::WrtDatabase::detachFromThread();
-
-    if (result) {
-        return TRUE;
-    } else {
+    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*/,
@@ -160,9 +173,18 @@ static int pkg_plugin_get_app_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();
@@ -173,12 +195,14 @@ static int pkg_plugin_get_app_detail_info(
                 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 {
@@ -194,6 +218,11 @@ static int pkg_plugin_get_app_detail_info(
     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();
 
@@ -221,13 +250,218 @@ static int pkg_plugin_get_app_detail_info(
     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);
+    }
+    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);
+    }
+
+    if (!configInfo.authorName.IsNull()) {
+        strncpy(pkg_detail_info->author,
+                DPL::ToUTF8String(*configInfo.authorName).c_str(),
+                PKG_VALUE_STRING_LEN_MAX - 1);
+    }
+
+    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);
+
+    GList *privilege_list = NULL;
+    FOREACH(it, configInfo.featuresList) {
+        LogDebug("privilege : " << it->name);
+        int length = DPL::ToUTF8String(it->name).length();
+        char *privilege = (char*) calloc(1, (sizeof(char) * length) + 1);
+        snprintf(privilege, length + 1, "%s",
+                DPL::ToUTF8String(it->name).c_str());
+        privilege_list = g_list_append(privilege_list, privilege);
+    }
+    pkg_detail_info->privilege_list = privilege_list;
+
+    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;
+    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")))