Update wrt-installer_0.0.54
[framework/web/wrt-installer.git] / src / jobs / widget_install / job_widget_install.cpp
old mode 100644 (file)
new mode 100755 (executable)
index b4214c1..059a957
@@ -29,6 +29,8 @@
 #include <dpl/copy.h>
 #include <dpl/assert.h>
 #include <dpl/sstream.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+#include <dpl/utils/file_utils.h>
 #include "root_parser.h"
 #include "widget_parser.h"
 #include "parser_runner.h"
 #include <widget_install/task_certify.h>
 #include <widget_install/task_widget_config.h>
 #include <widget_install/task_db_update.h>
+#include <widget_install/task_file_manipulation.h>
 #include <widget_install/task_ace_check.h>
 #include <widget_install/task_smack.h>
-#include <widget_install/task_desktop_file.h>
+#include <widget_install/task_manifest_file.h>
 #include <widget_install/task_private_storage.h>
 #include <widget_install/task_prepare_files.h>
+#include <widget_install/task_recovery.h>
+#include <widget_install/task_install_ospsvc.h>
+#include <widget_install/task_update_files.h>
+#include <widget_install/task_new_db_insert.h>
+#include <widget_install/task_remove_backup.h>
+#include <widget_install/task_encrypt_resource.h>
 #include <widget_install/widget_install_errors.h>
 #include <widget_install/widget_install_context.h>
 #include <string>
-#include <dpl/wrt-dao-rw/widget_dao.h> //TODO remove
+#include <sys/time.h>
+#include <ctime>
+#include <cstdlib>
+#include <limits.h>
+#include <regex.h>
 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/wrt-dao-ro/global_config.h>
 #include <dpl/wrt-dao-rw/global_dao.h> // TODO remove
 #include <aul.h>
 #include <dpl/localization/w3c_file_localization.h>
 #include <libiriwrapper.h>
+#include <pkg-manager/pkgmgr_signal.h>
 
 using namespace WrtDB;
 
 namespace // anonymous
 {
 const char * const CONFIG_XML = "config.xml";
+const char * const WITH_OSP_XML = "res/wgt/config.xml";
+
+//allowed: a-z, A-Z, 0-9, '.', '-', '_', ' '
+const char* REG_TIZENID_PATTERN = "^[-. a-zA-Z0-9_@+=]*$";
+const int RESERVED_COUNT = 20;  //number of chars reserved in name (e.g. for '.desktop')
+const int MAX_TIZENID_LENTH = 255 - RESERVED_COUNT;
+
+static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption";
+static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable";
 
 class InstallerTaskFail :
     public DPL::TaskDecl<InstallerTaskFail>
@@ -83,6 +107,20 @@ class InstallerTaskFail :
         AddStep(&InstallerTaskFail::StepFail);
     }
 };
+
+const std::string XML_EXTENSION = ".xml";
+
+bool hasExtension(const std::string& filename, const std::string& extension) {
+    LogDebug("Looking for extension " << extension << " in: "  << filename);
+    size_t fileLen = filename.length();
+    size_t extLen = extension.length();
+    if (fileLen < extLen) {
+        LogError("Filename " << filename << " is shorter than extension "
+                 << extension);
+        return false;
+    }
+    return (0 == filename.compare(fileLen-extLen, extLen, extension));
+}
 } // namespace anonymous
 
 namespace Jobs {
@@ -93,27 +131,118 @@ JobWidgetInstall::JobWidgetInstall(std::string const &widgetPath,
     JobContextBase<WidgetInstallationStruct>(installerStruct),
     m_exceptionCaught(Exceptions::Success)
 {
-    // Configure installation
-    ConfigureResult result = ConfigureInstallation(widgetPath, false);
+    // Check installation type (config.xml or widget.wgt)
+    bool browserRequest = hasExtension(widgetPath, XML_EXTENSION);
+
+    LogInfo("Hosted app installation: " << browserRequest);
+
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    srand(time(NULL) + tv.tv_usec);
+    WrtDB::DbWidgetHandle handle;
+    do {
+        handle = rand() % INT_MAX + 1;
+        LogInfo("Random widget handle: " << handle);
+    } while (WidgetDAOReadOnly::isWidgetInstalled(handle));
 
+    m_installerContext.widgetHandle = handle;
+    m_installerContext.m_quiet = m_jobStruct.m_quiet;
+
+    if(!browserRequest)
+    {
+        m_installerContext.widgetConfig.pType = checkPackageType(widgetPath);
+    }
+    else
+    {
+        m_installerContext.widgetConfig.pType = WrtDB::PKG_TYPE_TIZEN_WEBAPP;
+    }
+    LogDebug("widgetPath:" << widgetPath);
+
+    ConfigParserData configData = getWidgetDataFromXML(widgetPath, browserRequest,
+            m_installerContext.widgetConfig.pType);
+    WidgetUpdateInfo update = detectWidgetUpdate(configData);
+
+    bool needEncryption = detectResourceEncryption(configData);
+
+
+    // Configure installation
+    ConfigureResult result = ConfigureInstallation(widgetPath, update);
+    if (!setTizenId(configData)) {
+        result = ConfigureResult::Failed;
+    } else {
+        using namespace PackageManager;
+        LogInfo("WidgetHandle: " << m_installerContext.widgetHandle);
+        LogInfo("Tizen Id: " << m_installerContext.widgetConfig.pkgname);
+
+        configureWidgetLocation(widgetPath, browserRequest);
+
+        // send start signal of pkgmgr
+        PkgmgrSignalSingleton::Instance().setPkgname(
+                    DPL::ToUTF8String(
+                        *m_installerContext.widgetConfig.pkgname));
+        PkgmgrSignalSingleton::Instance().sendSignal(
+                    PKGMGR_START_KEY,
+                    PKGMGR_START_INSTALL);
+    }
     if (result == ConfigureResult::Ok) {
         LogInfo("Configure installation succeeded");
 
+        AddTask(new TaskRecovery(m_installerContext));
+
         // Create installation tasks
-        AddTask(new TaskUnzip(m_installerContext));
+        if (!m_installerContext.locations->browserRequest()) {
+            AddTask(new TaskUnzip(m_installerContext));
+        }
         AddTask(new TaskWidgetConfig(m_installerContext));
+        if (m_installerContext.locations->browserRequest()) {
+            AddTask(new TaskPrepareFiles(m_installerContext));
+        }
         AddTask(new TaskCertify(m_installerContext));
+        if (needEncryption) {
+            AddTask(new TaskEncryptResource(m_installerContext));
+        }
         AddTask(new TaskDbUpdate(m_installerContext));
+        AddTask(new TaskFileManipulation(m_installerContext));
         // TODO: Update progress information for this task
 
+        AddTask(new TaskPrivateStorage(m_installerContext));
         AddTask(new TaskAceCheck(m_installerContext));
         //This is sort of quick solution, because ACE verdicts are based upon
         //data from DAO (DB). So AceCheck for now has to be AFTER DbUpdate
         //task.
         AddTask(new TaskSmack(m_installerContext));
 
-        AddTask(new TaskDesktopFile(m_installerContext));
-        AddTask(new TaskPrivateStorage(m_installerContext));
+        AddTask(new TaskManifestFile(m_installerContext));
+        if (m_installerContext.widgetConfig.pType ==
+                PKG_TYPE_TIZEN_WITHSVCAPP) {
+            AddTask(new TaskInstallOspsvc(m_installerContext));
+        }
+    } else if (result == ConfigureResult::Updated) {
+        LogInfo("Configure installation updated");
+        LogInfo("Widget Update");
+
+        if (!m_installerContext.locations->browserRequest()) {
+            AddTask(new TaskUnzip(m_installerContext));
+        }
+        AddTask(new TaskWidgetConfig(m_installerContext));
+        if (m_installerContext.locations->browserRequest()) {
+            AddTask(new TaskPrepareFiles(m_installerContext));
+        }
+
+        AddTask(new TaskCertify(m_installerContext));
+        AddTask(new TaskUpdateFiles(m_installerContext));
+        AddTask(new TaskNewDbInsert(m_installerContext));
+
+        /* TODO : To backup file, save md5 values */
+        AddTask(new TaskAceCheck(m_installerContext));
+        AddTask(new TaskSmack(m_installerContext));
+
+        AddTask(new TaskManifestFile(m_installerContext));
+        AddTask(new TaskRemoveBackupFiles(m_installerContext));
+        if (m_installerContext.widgetConfig.pType ==
+                PKG_TYPE_TIZEN_WITHSVCAPP) {
+            AddTask(new TaskInstallOspsvc(m_installerContext));
+        }
     } else if (result == ConfigureResult::Deferred) {
         // Installation is deferred
         LogInfo("Configure installation deferred");
@@ -129,60 +258,98 @@ JobWidgetInstall::JobWidgetInstall(std::string const &widgetPath,
     }
 }
 
-JobWidgetInstall::JobWidgetInstall(
-        std::string const & widgetUrl,
-        std::string const & iconPath,
-        const WidgetInstallationStruct &installerStruct) :
-    Job(Installation),
-    JobContextBase<WidgetInstallationStruct>(installerStruct),
-    m_exceptionCaught(Exceptions::Success)
+bool JobWidgetInstall::setTizenId(
+        const WrtDB::ConfigParserData &configInfo)
 {
-    // Configure installation
-    ConfigureResult result = ConfigureInstallation(widgetUrl, true);
-
-    if (result == ConfigureResult::Ok) {
-        LogInfo("Configure installation succeeded");
-
-        // Check web app url
-        LibIri::Wrapper iri(widgetUrl.c_str());
-        if (!iri.Validate()) {
-            ThrowMsg(Exceptions::InvalidWidgetUrl,
-                     "Web app url must be a valid iri/uri/url");
+    Assert(!!m_installerContext.widgetHandle
+           && "Widget Handle should be initialized");
+
+    regex_t reg;
+    regcomp(&reg, REG_TIZENID_PATTERN, REG_NOSUB);
+    struct stat dirStat;
+    if(!!configInfo.tizenId) {
+        LogDebug("Setting tizenId provided in config.xml");
+        if ((regexec(&reg, DPL::ToUTF8String(*(configInfo.tizenId)).c_str(),
+             static_cast<size_t>(0), NULL, 0) != 0) ||
+            (DPL::ToUTF8String(*(configInfo.tizenId)).size() > MAX_TIZENID_LENTH) ||
+            (stat((std::string(GlobalConfig::GetUserInstalledWidgetPath()) + "/"
+                   + DPL::ToUTF8String(*(configInfo.tizenId))).c_str(), &dirStat) == 0))
+        {
+            //it is true when tizenId does not fit REG_TIZENID_PATTERN
+            LogError("pkgName provided but not proper.");
+            regfree(&reg);
+            return false;
         }
+        m_installerContext.widgetConfig.pkgname = configInfo.tizenId;
 
-        m_installerContext.widgetConfig.configInfo.startFile =
-                DPL::FromUTF8String(widgetUrl);
-
-        m_installerContext.iconPath = iconPath;
+    } else {
+        LogInfo("package name is generated by WRT");
+        // tizen id should be generated by secure random algorithm
+        std::string pkgName = WrtDB::GlobalConfig::GetPkgnamePrefix();
 
-        // Create installation tasks
-        AddTask(new TaskPrepareFiles(m_installerContext));
-        AddTask(new TaskWidgetConfig(m_installerContext));
-        AddTask(new TaskCertify(m_installerContext));
-        AddTask(new TaskDbUpdate(m_installerContext));
-        // TODO: Update progress information for this task
+        bool named = false;
+        FOREACH(it, configInfo.localizedDataSet)
+        {
+            if (!!((it->second).name)) {
+                //there is a name provided
+                std::string name =  DPL::ToUTF8String(*(it->second).name);
+                //cut very long widget's name
+                name = name.substr(0, MAX_TIZENID_LENTH - strlen(
+                    WrtDB::GlobalConfig::GetPkgnamePrefix()));
+                //check name if all characters are supported by filesystem
+                if (regexec(&reg, name.c_str(), static_cast<size_t>(0), NULL, 0)
+                    == 0)
+                {
+                    //WidgetName is ok and can be used as package name
+                    //replace all spaces with '_'
+                    size_t pos = 0;
+                    while((pos = name.find(" ", pos)) != std::string::npos) {
+                        name.replace(pos, 1, "_");
+                        ++pos;
+                    }
+                    pkgName += name;
+                    named = true;
+                }
+                break;
+            }
+        }
 
-        AddTask(new TaskAceCheck(m_installerContext));
-        //This is sort of quick solution, because ACE verdicts are based upon
-        //data from DAO (DB). So AceCheck for now has to be AFTER DbUpdate
-        //task.
-        AddTask(new TaskSmack(m_installerContext));
+        if (!named) // there is no widget name provided, use widgetHandle
+        {
+            pkgName += std::to_string(*(m_installerContext.widgetHandle));
+        }
 
-        AddTask(new TaskDesktopFile(m_installerContext));
-        AddTask(new TaskPrivateStorage(m_installerContext));
-    } else if (result == ConfigureResult::Deferred) {
-        // Installation is deferred
-        LogInfo("Configure installation deferred");
+        //check if there is package with same name and if generate different name
+        std::string path = GlobalConfig::GetUserInstalledWidgetPath();
+        path += "/";
+
+        std::ostringstream newPath;
+        newPath << path << pkgName;
+
+        std::string suffix;
+        for (int i = 0;; ++i) {
+            if (stat(newPath.str().c_str(), &dirStat) == 0) {
+                //path exist, chose another one, eg. widgetName1
+                suffix = std::to_string(i + 1);
+                pkgName = pkgName.substr(
+                        0, MAX_TIZENID_LENTH - suffix.size());
+                newPath.str("");
+                newPath << path << pkgName << suffix;
+                continue;
+            }
+            pkgName += suffix;
+            break;
+        }
 
-        AddTask(new InstallerTaskFail(true));
-    } else if (result == ConfigureResult::Failed) {
-        // Installation is not allowed to proceed due to widget update policy
-        LogWarning("Configure installation failed!");
+        m_installerContext.widgetConfig.pkgname =
+            DPL::FromUTF8String(pkgName);
 
-        AddTask(new InstallerTaskFail(false));
-    } else {
-        Assert(false && "Invalid configure result!");
     }
+    regfree(&reg);
+
+    LogInfo("Tizen Id : " << m_installerContext.widgetConfig.pkgname);
+    LogInfo("W3C Widget GUID : " << m_installerContext.widgetConfig.guid);
+    return true;
 }
 
 DPL::Optional<WidgetHandle> JobWidgetInstall::getNewWidgetHandle() const
@@ -190,12 +357,26 @@ DPL::Optional<WidgetHandle> JobWidgetInstall::getNewWidgetHandle() const
     return m_installerContext.widgetHandle;
 }
 
-JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation(
-        const std::string &widgetSource, bool fromBrowser)
+void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath, bool browserRequest)
 {
-    // Detect widget update
-    WidgetUpdateInfo update = detectWidgetUpdate(widgetSource, fromBrowser);
+    Try
+    {
+        m_installerContext.locations = WidgetLocation(DPL::ToUTF8String(*m_installerContext.widgetConfig.pkgname),
+                    widgetPath, browserRequest, m_installerContext.widgetConfig.pType);
+    }
+    Catch(FileUtils::CreateDirectoryException)
+    {
+        LogError("Failed to create temporary path for widget");
+        ReThrowMsg(FileUtils::CreateDirectoryException, "Failed to create temporary path for widget");
+    }
+
+    LogInfo("widgetSource " << widgetPath);
+}
 
+JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation(
+        const std::string &widgetSource,
+        const WidgetUpdateInfo &update)
+{
     LogInfo(
         "Widget install/update: incoming guid = '" <<
         update.incomingGUID << "'");
@@ -213,25 +394,20 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation(
         LogInfo("Widget info exists. Handle: " <<
                 update.existingWidgetInfo.existingHandle);
 
-        DPL::OStringStream pkgName;
         DPL::OptionalString pkgname =
             WidgetDAOReadOnly(update.existingWidgetInfo.existingHandle).getPkgname();
 
         if(pkgname.IsNull()) {
-            LogInfo("But widget package name doesn't exist");
+            LogInfo("But package name doesn't exist");
             return ConfigureResult::Failed;
         }
 
-        LogInfo("Widget model exists. Package name: " << pkgName);
+        LogInfo("Widget model exists. package name: " << pkgname);
         if (aul_app_is_running(DPL::ToUTF8String(*pkgname).c_str())) {
             // Must be deferred when update in progress
             if (m_jobStruct.updateMode == WidgetUpdateMode::PolicyWac) {
                 LogInfo(
                     "Widget is already running. Policy is update according to WAC");
-                LogInfo("Installation deferred: " << widgetSource);
-
-                GlobalDAO::AddDefferedWidgetPackageInstallation(
-                    DPL::FromUTF8String(widgetSource));
 
                 return ConfigureResult::Deferred;
             } else {
@@ -243,6 +419,7 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation(
             }
         }
 
+        m_installerContext.widgetConfig.pkgname = pkgname;
         OptionalWidgetVersion existingVersion;
         existingVersion = update.existingWidgetInfo.existingVersion;
         OptionalWidgetVersion incomingVersion = update.incomingVersion;
@@ -257,14 +434,15 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation(
     LogInfo("Whether widget policy allow proceed: " << canProceed);
 
     // Init installer context
-    m_installerContext.widgetSource = widgetSource;
-    m_installerContext.tempWidgetPath = std::string();
-    m_installerContext.widgetConfig = WidgetRegisterInfo();
     m_installerContext.installStep = InstallerContext::INSTALL_START;
     m_installerContext.job = this;
     m_installerContext.existingWidgetInfo = update.existingWidgetInfo;
     m_installerContext.widgetConfig.shareHref = std::string();
 
+    if (m_installerContext.existingWidgetInfo.isExist) {
+        return canProceed ? ConfigureResult::Updated : ConfigureResult::Failed;
+    }
+
     // Return result
     return canProceed ? ConfigureResult::Ok : ConfigureResult::Failed;
 }
@@ -302,106 +480,130 @@ WidgetUpdateMode::Type JobWidgetInstall::CalcWidgetUpdatePolicy(
     }
 }
 
-WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
-        const std::string &widgetSource, bool fromBrowser)
+ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
+        const std::string &widgetSource,
+        bool fromBrowser, WrtDB::PkgType isOspsvc)
 {
-    LogInfo("Checking up widget package for config.xml...");
-
     Try
     {
-        DPL::OptionalString widgetGUID;
-        OptionalWidgetVersion widgetVersion;
+        // Parse config
+        ParserRunner parser;
+        ConfigParserData configInfo;
+
         if (fromBrowser) {
-            widgetGUID = DPL::FromUTF8String(widgetSource);
+            parser.Parse(widgetSource,
+                         ElementParserPtr(
+                             new RootParser<WidgetParser>(configInfo,
+                                                          DPL::FromUTF32String(
+                                                              L"widget"))));
         }
         else {
             // Open zip file
             DPL::ScopedPtr<DPL::ZipInput> zipFile(
                 new DPL::ZipInput(widgetSource));
 
+            DPL::ScopedPtr<DPL::ZipInput::File> configFile;
+
             // Open config.xml file
-            DPL::ScopedPtr<DPL::ZipInput::File> configFile(
-                zipFile->OpenFile(CONFIG_XML));
+            if (isOspsvc == PKG_TYPE_TIZEN_WITHSVCAPP) {
+                configFile.Reset(zipFile->OpenFile(WITH_OSP_XML));
+            } else {
+                configFile.Reset(zipFile->OpenFile(CONFIG_XML));
+            }
 
             // Extract config
             DPL::BinaryQueue buffer;
             DPL::AbstractWaitableInputAdapter inputAdapter(configFile.Get());
             DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
             DPL::Copy(&inputAdapter, &outputAdapter);
-
-            // Parse config
-            ParserRunner parser;
-            ConfigParserData configInfo;
-
             parser.Parse(&buffer,
                          ElementParserPtr(
                              new RootParser<WidgetParser>(configInfo,
                                                           DPL::FromUTF32String(
                                                               L"widget"))));
-
-            // Check widget id
-            widgetGUID = configInfo.widget_id;
-
-            if (widgetGUID.IsNull()) {
-                LogDebug("Installed widget has no GUID");
-                return WidgetUpdateInfo();
-            }
-
-            LogDebug("Installed widget GUID: " << *widgetGUID);
-
-            // Locate widget ID with this GUID
-            // Incoming widget version
-            if (!configInfo.version.IsNull()) {
-                widgetVersion =
-                    DPL::Optional<WidgetVersion>(
-                        WidgetVersion(*configInfo.version));
-            }
         }
 
-        try
-        {
-            // Search widget handle by GUID
-            WidgetDAO dao(widgetGUID);
-            return WidgetUpdateInfo(
-                widgetGUID,
-                widgetVersion,
-                WidgetUpdateInfo::ExistingWidgetInfo(
-                    dao.getHandle(), dao.getVersion()));
-        }
-        Catch(WidgetDAOReadOnly::Exception::WidgetNotExist){
-            // GUID isn't installed
-            return WidgetUpdateInfo(
-                widgetGUID,
-                widgetVersion,
-                WidgetUpdateInfo::ExistingWidgetInfo());
-        }
+        return configInfo;
     }
     Catch(DPL::ZipInput::Exception::OpenFailed)
     {
         LogDebug("Failed to open widget package");
-        return WidgetUpdateInfo();
+        return ConfigParserData();
     }
     Catch(DPL::ZipInput::Exception::OpenFileFailed)
     {
         LogDebug("Failed to open config.xml file");
-        return WidgetUpdateInfo();
+        return ConfigParserData();
     }
     Catch(DPL::CopyFailed)
     {
         LogDebug("Failed to extract config.xml file");
-        return WidgetUpdateInfo();
+        return ConfigParserData();
     }
     Catch(ElementParser::Exception::ParseError)
     {
         LogDebug("Failed to parse config.xml file");
+        return ConfigParserData();
+    }
+}
+
+WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
+        const ConfigParserData &configInfo)
+{
+    LogInfo("Checking up widget package for config.xml...");
+
+    DPL::OptionalString widgetGUID;
+    OptionalWidgetVersion widgetVersion;
+
+    // Check widget id
+    widgetGUID = configInfo.widget_id;
+
+    if (widgetGUID.IsNull()) {
+        LogDebug("Installed widget has no GUID");
         return WidgetUpdateInfo();
     }
+
+    LogDebug("Installed widget GUID: " << *widgetGUID);
+
+    // Locate widget ID with this GUID
+    // Incoming widget version
+    if (!configInfo.version.IsNull()) {
+        widgetVersion =
+            DPL::Optional<WidgetVersion>(
+                WidgetVersion(*configInfo.version));
+    }
+
+    Try
+    {
+        // Search widget handle by GUID
+        WidgetDAOReadOnly dao(widgetGUID);
+        return WidgetUpdateInfo(
+            widgetGUID,
+            widgetVersion,
+            WidgetUpdateInfo::ExistingWidgetInfo(
+                dao.getHandle(), dao.getVersion()));
+    }
+    Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
+    {
+        // GUID isn't installed
+        return WidgetUpdateInfo(
+            widgetGUID,
+            widgetVersion,
+            WidgetUpdateInfo::ExistingWidgetInfo());
+    }
 }
 
 void JobWidgetInstall::SendProgress()
 {
+    using namespace PackageManager;
     if (GetProgressFlag() != false) {
         if (getInstallerStruct().progressCallback != NULL) {
+            // send progress signal of pkgmgr
+            std::ostringstream percent;
+            percent << static_cast<int>(GetProgressPercent());
+            PkgmgrSignalSingleton::Instance().sendSignal(
+                        PKGMGR_PROGRESS_KEY,
+                        percent.str());
 
             LogDebug("Call widget install progressCallbak");
             getInstallerStruct().progressCallback(getInstallerStruct().userParam,
@@ -412,27 +614,47 @@ void JobWidgetInstall::SendProgress()
 
 void JobWidgetInstall::SendFinishedSuccess()
 {
+    using namespace PackageManager;
+    // TODO : sync should move to separate task.
+    sync();
+
+    // remove widget install information file
+    unlink(m_installerContext.installInfo.c_str());
+
     //inform widget info
     JobWidgetInstall::displayWidgetInfo();
 
     DPL::Optional<WidgetHandle> handle = getNewWidgetHandle();
-    const WidgetHandle INVALID_WIDGET_HANDLE = 0;
+
+    // send signal of pkgmgr
+    PkgmgrSignalSingleton::Instance().sendSignal(
+                PKGMGR_END_KEY,
+                PKGMGR_END_SUCCESS);
 
     LogDebug("Call widget install successfinishedCallback");
     getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
-            !!handle ? *handle : INVALID_WIDGET_HANDLE, Exceptions::Success);
+            !!handle ? *handle : WrtDB::INVALID_WIDGET_HANDLE, Exceptions::Success);
 }
 
 void JobWidgetInstall::SendFinishedFailure()
 {
+    using namespace PackageManager;
+    // remove widget install information file
+    unlink(m_installerContext.installInfo.c_str());
+
     LogError("Error in installation step: " << m_exceptionCaught);
     LogError("Message: " << m_exceptionMessage);
     DPL::Optional<WidgetHandle> handle = getNewWidgetHandle();
-    const WidgetHandle INVALID_WIDGET_HANDLE = 0;
 
     LogDebug("Call widget install failure finishedCallback");
+
+    // send signal of pkgmgr
+    PkgmgrSignalSingleton::Instance().sendSignal(
+                PKGMGR_END_KEY,
+                PKGMGR_END_FAILURE);
+
     getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
-            !!handle ? *handle : INVALID_WIDGET_HANDLE, m_exceptionCaught);
+            !!handle ? *handle : WrtDB::INVALID_WIDGET_HANDLE, m_exceptionCaught);
 }
 
 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
@@ -456,6 +678,7 @@ void JobWidgetInstall::displayWidgetInfo()
         "===================================== INSTALLED WIDGET INFO ========="\
         "============================";
     out << std::endl << "Name:                        " << localizedInfo.name;
+    out << std::endl << "PkgName:                     " << dao.getPkgname();
     WidgetSize size = dao.getPreferredSize();
     out << std::endl << "Width:                       " << size.width;
     out << std::endl << "Height:                      " << size.height;
@@ -508,5 +731,70 @@ void JobWidgetInstall::displayWidgetInfo()
     LogInfo(out.str());
 }
 
+WrtDB::PackagingType JobWidgetInstall::checkPackageType(
+        const std::string &widgetSource)
+{
+    using namespace WrtDB;
+
+    PackagingType pType = PKG_TYPE_UNKNOWN;
+    DPL::ScopedPtr<DPL::ZipInput> zipFile;
+
+    Try
+    {
+        // Open zip file
+        zipFile.Reset(new DPL::ZipInput(widgetSource));
+
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        LogDebug("Failed to open widget package");
+        return PKG_TYPE_UNKNOWN;
+    }
+
+    Try
+    {
+        // Open config.xml file in package root
+        DPL::ScopedPtr<DPL::ZipInput::File> configFile(
+                zipFile->OpenFile(CONFIG_XML));
+        pType = PKG_TYPE_TIZEN_WEBAPP;
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        LogDebug("Could not find config.xml");
+    }
+
+    Try
+    {
+        // Open config.xml file in package root
+        DPL::ScopedPtr<DPL::ZipInput::File> configFile(
+                zipFile->OpenFile(WITH_OSP_XML));
+        if (pType == PKG_TYPE_TIZEN_WEBAPP) {
+            return PKG_TYPE_UNKNOWN;
+        }
+
+        pType = PKG_TYPE_TIZEN_WITHSVCAPP;
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        LogDebug("Could not find wgt/config.xml");
+        return PKG_TYPE_UNKNOWN;
+    }
+
+    return pType;
+}
+
+bool JobWidgetInstall::detectResourceEncryption(const WrtDB::ConfigParserData &configData)
+{
+    FOREACH(it, configData.settingsList)
+    {
+        if (it->m_name == SETTING_VALUE_ENCRYPTION &&
+                it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE) {
+            LogDebug("resource need encryption");
+            return true;
+        }
+    }
+    return false;
+}
+
 } //namespace WidgetInstall
 } //namespace Jobs