X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fjobs%2Fwidget_install%2Fjob_widget_install.cpp;h=e746f0161e91cf09046ac526275ca008e1e4be2a;hb=253c98d93cddcecefe06429babf6ee11d323f970;hp=2607ab691ac40c903d299829b3cdbc3cc907e516;hpb=30f09f632ad20e9b29fec8e484cb861fdc93cfd3;p=framework%2Fweb%2Fwrt-installer.git diff --git a/src/jobs/widget_install/job_widget_install.cpp b/src/jobs/widget_install/job_widget_install.cpp index 2607ab6..e746f01 100644 --- a/src/jobs/widget_install/job_widget_install.cpp +++ b/src/jobs/widget_install/job_widget_install.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -48,14 +49,13 @@ #include #include #include -//#include -#include //temporary code #include "root_parser.h" #include "widget_parser.h" #include "parser_runner.h" #include #include +#include #include #include #include @@ -68,22 +68,23 @@ #include #include #include -#include -#include +#include #include - -#include +#include #include #include #include +#include using namespace WrtDB; +using namespace Jobs::Exceptions; namespace // anonymous { const char * const CONFIG_XML = "config.xml"; const char * const WITH_OSP_XML = "res/wgt/config.xml"; +const char * const OSP_MANIFEST_XML = "info/manifest.xml"; //allowed: a-z, A-Z, 0-9 const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}.{1,}$"; @@ -92,37 +93,12 @@ const size_t PACKAGE_ID_LENGTH = 10; static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption"; static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable"; +static const DPL::String SETTING_VALUE_ENCRYPTION_DISABLE = L"disable"; const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME = - L"install-location-type"; + L"install-location"; const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT = L"prefer-external"; -class InstallerTaskFail : - public DPL::TaskDecl -{ - private: - bool m_deferred; - - void StepFail() - { - if (m_deferred) { - ThrowMsg(Jobs::WidgetInstall::Exceptions::Deferred, - "Widget installation or update deferred!"); - } else { - ThrowMsg(Jobs::WidgetInstall::Exceptions::NotAllowed, - "Widget installation or update not allowed!"); - } - } - - public: - InstallerTaskFail(bool deferred) : - DPL::TaskDecl(this), - m_deferred(deferred) - { - AddStep(&InstallerTaskFail::StepFail); - } -}; - const std::string XML_EXTENSION = ".xml"; bool hasExtension(const std::string& filename, const std::string& extension) @@ -133,60 +109,84 @@ bool hasExtension(const std::string& filename, const std::string& extension) if (fileLen < extLen) { LogError("Filename " << filename << " is shorter than extension " << extension); - return false; + false; } return (0 == filename.compare(fileLen - extLen, extLen, extension)); } +} // namespace anonymous -bool checkTizenPkgIdExist(const std::string& tizenPkgId) +namespace Jobs { +namespace WidgetInstall { +class InstallerTaskFail : + public DPL::TaskDecl { - std::string installPath = - std::string(GlobalConfig::GetUserInstalledWidgetPath()) + - "/" + tizenPkgId; - std::string preinstallPath = - std::string(GlobalConfig::GetUserPreloadedWidgetPath()) + - "/" + tizenPkgId; + private: + ConfigureResult m_result; - struct stat dirStat; - if ((stat(installPath.c_str(), &dirStat) == 0) || - (stat(preinstallPath.c_str(), &dirStat) == 0)) + void StepFail() { - return true; + if (m_result == ConfigureResult::Failed_InvalidConfig) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid, + "invalid config"); + } else if (m_result == ConfigureResult::Failed_OpenZipError) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::OpenZipFailed, + "can't open wgt file"); + } else if (m_result == ConfigureResult::Failed_UnzipError) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::ExtractFileFailed, + "can't extract wgt file"); + } else if (m_result == ConfigureResult::Failed_LowerVersion) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageLowerVersion, + "package version is lower than installed version"); + } else if (m_result == ConfigureResult::Failed_AlreadyInstalled) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::PackageAlreadyInstalled, + "package is already installed"); + } else if (m_result == ConfigureResult::Failed_WidgetRunning) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetRunningError, + "widget is running"); + } else if (m_result == ConfigureResult::Failed_DrmError) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::DrmDecryptFailed, + "drm failed"); + } else if (m_result == ConfigureResult::Failed_NotSupportRDSUpdate) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::NotSupportRDSUpdate, + "RDS update failed"); + } else { + ThrowMsg(Jobs::WidgetInstall::Exceptions::NotAllowed, + "widget installation or update not allowed!"); + } } - return false; -} -} // namespace anonymous -namespace Jobs { -namespace WidgetInstall { + public: + InstallerTaskFail(ConfigureResult result) : + DPL::TaskDecl(this), + m_result(result) + { + AddStep(&InstallerTaskFail::StepFail); + } +}; + JobWidgetInstall::JobWidgetInstall( std::string const &widgetPath, const WidgetInstallationStruct & installerStruct) : Job(Installation), JobContextBase(installerStruct), - m_exceptionCaught(Exceptions::Success) + m_exceptionCaught(Jobs::Exceptions::Success) { - m_installerContext.m_quiet = m_jobStruct.m_quiet; - - ConfigureResult result = PrePareInstallation(widgetPath); + m_installerContext.mode = m_jobStruct.m_installMode; + getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_START_KEY, + PKGMGR_START_INSTALL); + getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_PROGRESS_KEY, + PKGMGR_START_VALUE); + ConfigureResult result = prepareInstallation(widgetPath); if (result == ConfigureResult::Ok) { - LogInfo("Configure installation succeeded"); + LogDebug("Configure installation succeeded"); m_installerContext.job->SetProgressFlag(true); AddTask(new TaskRecovery(m_installerContext)); - // Create installation tasks - if (m_installerContext.widgetConfig.packagingType != - WrtDB::PKG_TYPE_DIRECTORY_WEB_APP && - m_installerContext.widgetConfig.packagingType != - WrtDB::PKG_TYPE_HOSTED_WEB_APP && - !m_isDRM) - { - AddTask(new TaskUnzip(m_installerContext)); - } - AddTask(new TaskWidgetConfig(m_installerContext)); if (m_installerContext.widgetConfig.packagingType == WrtDB::PKG_TYPE_HOSTED_WEB_APP) @@ -194,39 +194,30 @@ JobWidgetInstall::JobWidgetInstall( AddTask(new TaskPrepareFiles(m_installerContext)); } AddTask(new TaskCertify(m_installerContext)); + AddTask(new TaskCertifyLevel(m_installerContext)); if (m_needEncryption) { AddTask(new TaskEncryptResource(m_installerContext)); } - AddTask(new TaskFileManipulation(m_installerContext)); - // TODO: Update progress information for this task - - //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 TaskManifestFile(m_installerContext)); - AddTask(new TaskCertificates(m_installerContext)); if (m_installerContext.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) { AddTask(new TaskInstallOspsvc(m_installerContext)); } - AddTask(new TaskPluginsCopy(m_installerContext)); AddTask(new TaskDatabase(m_installerContext)); AddTask(new TaskAceCheck(m_installerContext)); + AddTask(new TaskSmack(m_installerContext)); + AddTask(new TaskPkgInfoUpdate(m_installerContext)); } else if (result == ConfigureResult::Updated) { - LogInfo("Configure installation updated"); - LogInfo("Widget Update"); + LogDebug("Configure installation updated"); + LogDebug("Widget Update"); m_installerContext.job->SetProgressFlag(true); - if (m_installerContext.widgetConfig.packagingType != - WrtDB::PKG_TYPE_HOSTED_WEB_APP && - m_installerContext.widgetConfig.packagingType != - WrtDB::PKG_TYPE_DIRECTORY_WEB_APP && - !m_isDRM) + + if (m_installerContext.mode.command == + InstallMode::Command::REINSTALL) { - AddTask(new TaskUnzip(m_installerContext)); + AddTask(new TaskPrepareReinstall(m_installerContext)); } AddTask(new TaskWidgetConfig(m_installerContext)); @@ -238,68 +229,69 @@ JobWidgetInstall::JobWidgetInstall( } AddTask(new TaskCertify(m_installerContext)); - if (m_installerContext.widgetConfig.packagingType != - WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) - { + AddTask(new TaskCertifyLevel(m_installerContext)); + if (m_needEncryption) { + AddTask(new TaskEncryptResource(m_installerContext)); + } + if (m_installerContext.mode.extension != + InstallMode::ExtensionType::DIR) { AddTask(new TaskUpdateFiles(m_installerContext)); + AddTask(new TaskFileManipulation(m_installerContext)); } - /* TODO : To backup file, save md5 values */ - AddTask(new TaskSmack(m_installerContext)); - AddTask(new TaskManifestFile(m_installerContext)); if (m_installerContext.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) { AddTask(new TaskInstallOspsvc(m_installerContext)); } - if (m_installerContext.widgetConfig.packagingType != - WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) - { - AddTask(new TaskRemoveBackupFiles(m_installerContext)); - } - AddTask(new TaskPluginsCopy(m_installerContext)); AddTask(new TaskDatabase(m_installerContext)); AddTask(new TaskAceCheck(m_installerContext)); //TODO: remove widgetHandle from this task and move before database task // by now widget handle is needed in ace check // Any error in acecheck while update will break widget - } else if (result == ConfigureResult::Deferred) { - // Installation is deferred - LogInfo("Configure installation deferred"); - - AddTask(new InstallerTaskFail(true)); - } else if (result == ConfigureResult::Failed) { + AddTask(new TaskSmack(m_installerContext)); + AddTask(new TaskRemoveBackupFiles(m_installerContext)); + AddTask(new TaskPkgInfoUpdate(m_installerContext)); + } else { // Installation is not allowed to proceed due to widget update policy LogWarning("Configure installation failed!"); - AddTask(new InstallerTaskFail(false)); - } else { - Assert(false && "Invalid configure result!"); + AddTask(new InstallerTaskFail(result)); } } -JobWidgetInstall::ConfigureResult JobWidgetInstall::PrePareInstallation( +ConfigureResult JobWidgetInstall::prepareInstallation( const std::string &widgetPath) { ConfigureResult result; m_needEncryption = false; - Try { - std::string tempDir = - Jobs::WidgetInstall::createTempPath(m_jobStruct.m_preload); - - m_isDRM = isDRMWidget(widgetPath); - if (true == m_isDRM) { - LogDebug("decrypt DRM widget"); - if (DecryptDRMWidget(widgetPath, tempDir)) { - LogDebug("Failed decrypt DRM widget"); - return ConfigureResult::Failed; + std::string tempDir; + if (m_installerContext.mode.extension == InstallMode::ExtensionType::DIR) { + if (m_installerContext.mode.command == + InstallMode::Command::REINSTALL) { + std::ostringstream tempPathBuilder; + tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath(); + tempPathBuilder << WrtDB::GlobalConfig::GetTmpDirPath(); + tempPathBuilder << "/"; + tempPathBuilder << widgetPath; + tempDir = tempPathBuilder.str();; + } else { + tempDir = widgetPath; } + } else { + tempDir = + Jobs::WidgetInstall::createTempPath( + m_installerContext.mode.rootPath == + InstallMode::RootPath::RO); + WidgetUnzip wgtUnzip; + wgtUnzip.unzipWgtFile(widgetPath, tempDir); } LogDebug("widgetPath:" << widgetPath); + LogDebug("tempPath:" << tempDir); m_installerContext.widgetConfig.packagingType = checkPackageType(widgetPath, tempDir); @@ -307,7 +299,7 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::PrePareInstallation( widgetPath, tempDir, m_installerContext.widgetConfig.packagingType, - m_isDRM); + m_installerContext.mode.command == InstallMode::Command::REINSTALL); LogDebug("widget packaging type : " << m_installerContext.widgetConfig.packagingType.pkgType); @@ -315,13 +307,41 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::PrePareInstallation( setApplicationType(configData); m_needEncryption = detectResourceEncryption(configData); setInstallLocationType(configData); + m_installerContext.callerPkgId = + DPL::FromUTF8String(getInstallerStruct().pkgmgrInterface->getCallerId()); + LogDebug("Caller Package Id : " << m_installerContext.callerPkgId); // Configure installation result = ConfigureInstallation(widgetPath, configData, tempDir); } + Catch(Exceptions::OpenZipFailed) + { + LogError("Failed to unzip for widget"); + result = ConfigureResult::Failed_OpenZipError; + } Catch(Exceptions::ExtractFileFailed) { - LogError("Failed to create temporary path for widget"); + LogError("Failed to unzip for widget"); + result = ConfigureResult::Failed_UnzipError; + } + Catch(Exceptions::DrmDecryptFailed) + { + LogError("Failed to unzip for widget"); + result = ConfigureResult::Failed_DrmError; + } + Catch(Exceptions::MissingConfig) + { + LogError("Failed to localize config.xml"); + result = ConfigureResult::Failed_InvalidConfig; + } + Catch(Exceptions::WidgetConfigFileInvalid) + { + LogError("Invalid configuration file"); + result = ConfigureResult::Failed_InvalidConfig; + } + Catch(DPL::Exception) + { + LogError("Unknown exception"); result = ConfigureResult::Failed; } @@ -362,7 +382,7 @@ void JobWidgetInstall::setTizenId( TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId(); LogDebug("Checking if pkg id is unique"); while (true) { - if (checkTizenPkgIdExist(DPL::ToUTF8String(pkgId))) { + if (!validateTizenPackageID(pkgId)) { //path exist, chose another one pkgId = WidgetDAOReadOnly::generatePkgId(); continue; @@ -370,7 +390,7 @@ void JobWidgetInstall::setTizenId( break; } m_installerContext.widgetConfig.tzPkgid = pkgId; - LogInfo("tizen_id name was generated by WRT: " << + LogDebug("tizen_id name was generated by WRT: " << m_installerContext.widgetConfig.tzPkgid); } @@ -427,9 +447,9 @@ void JobWidgetInstall::setTizenId( m_installerContext. widgetConfig. tzPkgid)); - LogInfo("Tizen App Id : " << m_installerContext.widgetConfig.tzAppid); - LogInfo("Tizen Pkg Id : " << m_installerContext.widgetConfig.tzPkgid); - LogInfo("W3C Widget GUID : " << m_installerContext.widgetConfig.guid); + LogDebug("Tizen App Id : " << m_installerContext.widgetConfig.tzAppid); + LogDebug("Tizen Pkg Id : " << m_installerContext.widgetConfig.tzPkgid); + LogDebug("W3C Widget GUID : " << m_installerContext.widgetConfig.guid); } void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath, @@ -440,181 +460,196 @@ void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath, tzPkgid), widgetPath, tempPath, m_installerContext.widgetConfig.packagingType, - m_installerContext.locationType); + m_installerContext.mode.rootPath == + InstallMode::RootPath::RO, + m_installerContext.mode.extension); m_installerContext.locations->registerAppid( DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid)); - LogInfo("widgetSource " << widgetPath); + LogDebug("widgetSource " << widgetPath); } -JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation( +ConfigureResult JobWidgetInstall::ConfigureInstallation( const std::string &widgetSource, const WrtDB::ConfigParserData &configData, const std::string &tempPath) { - WidgetUpdateInfo update = detectWidgetUpdate( - configData, - m_installerContext. - widgetConfig.webAppType, - m_installerContext. - widgetConfig.tzAppid); - ConfigureResult result = checkWidgetUpdate(update); - - // Validate tizenId - regex_t reg; - if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) { - LogDebug("Regcomp failed"); + ConfigureResult result = ConfigureResult::Failed; + WidgetUpdateInfo update; + + // checking installed web application + Try { + // checking existing application is installed + WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid); + // no excpetion means, it isn't update mode + getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_START_KEY, + PKGMGR_START_UPDATE); + + update = detectWidgetUpdate(configData, + m_installerContext.widgetConfig.tzAppid); + result = checkWidgetUpdate(update); + if (result != ConfigureResult::Updated) { + // Already installed TizenAppId. return failed + return ConfigureResult::Failed_AlreadyInstalled; + } + if (!checkSupportRDSUpdate(configData)) { + return ConfigureResult::Failed_NotSupportRDSUpdate; + } + m_installerContext.isUpdateMode = true; } + Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) { + result = ConfigureResult::Ok; + m_installerContext.isUpdateMode = false; - if ((regexec(®, - DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid). - c_str(), - static_cast(0), NULL, 0) == REG_NOMATCH) || - (checkTizenPkgIdExist(DPL::ToUTF8String(m_installerContext.widgetConfig - .tzPkgid)) && - result != ConfigureResult::Updated)) - { - //it is true when tizenId does not fit REG_TIZENID_PATTERN - LogError("tizen_id provided but not proper or pkgId directory exists"); - //TODO(t.iwanek): appId is unique, what about installation of - // abcdefghij.test1 and abcdefghij.test2? - regfree(®); - return ConfigureResult::Failed; + if (!validateTizenApplicationID( + m_installerContext.widgetConfig.tzAppid)) + { + LogError("tizen application ID is already used"); + return ConfigureResult::Failed_InvalidConfig; + } + if (!validateTizenPackageID(m_installerContext.widgetConfig.tzPkgid)) { + LogError("tizen package ID is already used"); + return ConfigureResult::Failed_AlreadyInstalled; + } } - regfree(®); configureWidgetLocation(widgetSource, tempPath); // Init installer context m_installerContext.installStep = InstallerContext::INSTALL_START; m_installerContext.job = this; - m_installerContext.existingWidgetInfo = update.existingWidgetInfo; m_installerContext.widgetConfig.shareHref = std::string(); return result; } -JobWidgetInstall::ConfigureResult JobWidgetInstall::checkWidgetUpdate( - const WidgetUpdateInfo &update) +bool JobWidgetInstall::validateTizenApplicationID( + const WrtDB::TizenAppId &tizenAppId) { - LogInfo( - "Widget install/update: incoming guid = '" << - update.incomingGUID << "'"); - LogInfo( - "Widget install/update: incoming version = '" << - update.incomingVersion << "'"); - - // Check policy - WidgetUpdateMode::Type updateTypeCheckBit; - - if (update.existingWidgetInfo.isExist == false) { - LogInfo("Widget info does not exist"); - updateTypeCheckBit = WidgetUpdateMode::NotInstalled; - - getInstallerStruct().pkgmgrInterface->sendSignal( - PKGMGR_START_KEY, - PKGMGR_START_INSTALL); - - } else { - LogInfo("Widget info exists. appid: " << - update.existingWidgetInfo.tzAppid); - - getInstallerStruct().pkgmgrInterface->sendSignal( - PKGMGR_START_KEY, - PKGMGR_START_UPDATE); + LogDebug("tizen application ID = [" << tizenAppId << "]"); - TizenAppId tzAppid = update.existingWidgetInfo.tzAppid; - - LogInfo("Widget model exists. tizen app id: " << tzAppid); - - // Check running state - bool isRunning = false; - int retval = app_manager_is_running(DPL::ToUTF8String( - tzAppid).c_str(), &isRunning); - if (APP_MANAGER_ERROR_NONE != retval) { - LogError("Fail to get running state"); - return ConfigureResult::Failed; - } + regex_t reg; + if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) { + LogDebug("Regcomp failed"); + } - if (true == isRunning) { - // Must be deferred when update in progress - if (m_jobStruct.updateMode == WidgetUpdateMode::PolicyWac) { - LogInfo( - "Widget is already running. Policy is update according to WAC"); + if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0) + == REG_NOMATCH) + { + regfree(®); + return false; + } + regfree(®); + return true; +} - return ConfigureResult::Deferred; - } else { - LogInfo( - "Widget is already running. Policy is not update according to WAC"); +bool JobWidgetInstall::validateTizenPackageID( + const WrtDB::TizenPkgId &tizenPkgId) +{ + std::string pkgId = DPL::ToUTF8String(tizenPkgId); - return ConfigureResult::Failed; - } - } + std::string installPath = + std::string(GlobalConfig::GetUserInstalledWidgetPath()) + + "/" + pkgId; - m_installerContext.widgetConfig.tzAppid = tzAppid; - OptionalWidgetVersion existingVersion; - existingVersion = update.existingWidgetInfo.existingVersion; - OptionalWidgetVersion incomingVersion = update.incomingVersion; - - updateTypeCheckBit = CalcWidgetUpdatePolicy(existingVersion, - incomingVersion); - // Calc proceed flag - if ((m_jobStruct.updateMode & updateTypeCheckBit) > 0 || - m_jobStruct.updateMode == - WidgetUpdateMode::PolicyDirectoryForceInstall) - { - LogInfo("Whether widget policy allow proceed ok"); - return ConfigureResult::Updated; - } else { - return ConfigureResult::Failed; - } + struct stat dirStat; + if ((stat(installPath.c_str(), &dirStat) == 0)) + { + return false; } - return ConfigureResult::Ok; + return true; } -WidgetUpdateMode::Type JobWidgetInstall::CalcWidgetUpdatePolicy( - const OptionalWidgetVersion &existingVersion, - const OptionalWidgetVersion &incomingVersion) const +ConfigureResult JobWidgetInstall::checkWidgetUpdate( + const WidgetUpdateInfo &update) { - // Widget is installed, check versions - if (!existingVersion && !incomingVersion) { - return WidgetUpdateMode::ExistingVersionEqual; - } else if (!existingVersion && !!incomingVersion) { - return WidgetUpdateMode::ExistingVersionNewer; - } else if (!!existingVersion && !incomingVersion) { - return WidgetUpdateMode::ExistingVersionOlder; - } else { - LogInfo("Existing widget: version = '" << *existingVersion << "'"); - - if (!existingVersion->IsWac() && !incomingVersion->IsWac()) { - return WidgetUpdateMode::BothVersionsNotStd; - } else if (!existingVersion->IsWac()) { - return WidgetUpdateMode::ExistingVersionNotStd; - } else if (!incomingVersion->IsWac()) { - return WidgetUpdateMode::IncomingVersionNotStd; + if (update.existingVersion.IsNull() || update.incomingVersion.IsNull()) { + return ConfigureResult::Failed; + } + + LogDebug("existing version = '" << update.existingVersion); + LogDebug("incoming version = '" << update.incomingVersion); + LogDebug("Tizen AppID = " << update.tzAppId); + + // Check running state + bool isRunning = false; + int ret = + app_manager_is_running(DPL::ToUTF8String(update.tzAppId).c_str(), + &isRunning); + if (APP_MANAGER_ERROR_NONE != ret) { + LogError("Fail to get running state"); + return ConfigureResult::Failed_WidgetRunning; + } + + if (true == isRunning) { + // get app_context for running application + // app_context must be released with app_context_destroy + app_context_h appCtx = NULL; + ret = + app_manager_get_app_context( + DPL::ToUTF8String(update.tzAppId).c_str(), + &appCtx); + if (APP_MANAGER_ERROR_NONE != ret) { + LogError("Fail to get app_context"); + return ConfigureResult::Failed_WidgetRunning; + } + + // terminate app_context_h + ret = app_manager_terminate_app(appCtx); + if (APP_MANAGER_ERROR_NONE != ret) { + LogError("Fail to terminate running application"); + app_context_destroy(appCtx); + return ConfigureResult::Failed_WidgetRunning; } else { - // Both versions are WAC-comparable. Do compare. - if (*incomingVersion == *existingVersion) { - return WidgetUpdateMode::ExistingVersionEqual; - } else if (*incomingVersion > *existingVersion) { - return WidgetUpdateMode::ExistingVersionOlder; - } else { - return WidgetUpdateMode::ExistingVersionNewer; + app_context_destroy(appCtx); + // app_manager_terminate_app isn't sync API + // wait until application isn't running (50ms * 100) + bool isStillRunning = true; + int checkingloop = 100; + struct timespec duration = { 0, 50 * 1000 * 1000 }; + while (--checkingloop >= 0) { + nanosleep(&duration, NULL); + int ret = + app_manager_is_running( + DPL::ToUTF8String(update.tzAppId).c_str(), + &isStillRunning); + if (APP_MANAGER_ERROR_NONE != ret) { + LogError("Fail to get running state"); + return ConfigureResult::Failed_WidgetRunning; + } + if (!isStillRunning) { + break; + } + } + if (isStillRunning) { + LogError("Fail to terminate running application"); + return ConfigureResult::Failed_WidgetRunning; } + LogDebug("terminate application"); } } + + m_installerContext.widgetConfig.tzAppid = update.tzAppId; + + if (!!update.existingVersion || + m_installerContext.mode.extension == + InstallMode::ExtensionType::DIR) { + return ConfigureResult::Updated; + } + + return ConfigureResult::Failed; } ConfigParserData JobWidgetInstall::getWidgetDataFromXML( const std::string &widgetSource, const std::string &tempPath, WrtDB::PackagingType pkgType, - bool isDRM) + bool isReinstall) { // Parse config ParserRunner parser; ConfigParserData configInfo; - Try { if (pkgType == PKG_TYPE_HOSTED_WEB_APP) { @@ -623,155 +658,81 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML( new RootParser(configInfo, DPL::FromUTF32String( L"widget")))); - } else if (pkgType == PKG_TYPE_DIRECTORY_WEB_APP) { - parser.Parse(widgetSource + '/' + WITH_OSP_XML, - ElementParserPtr( - new RootParser( - configInfo, - DPL::FromUTF32String(L"widget")))); } else { - if (!isDRM) { - std::unique_ptr zipFile( - new DPL::ZipInput(widgetSource)); - - std::unique_ptr configFile; - - // Open config.xml file - if (pkgType == PKG_TYPE_HYBRID_WEB_APP) { - configFile.reset(zipFile->OpenFile(WITH_OSP_XML)); - } else { - configFile.reset(zipFile->OpenFile(CONFIG_XML)); - } + std::string configFile; + configFile = tempPath + "/" + CONFIG_XML; + if (!WrtUtilFileExists(configFile)) { + configFile = tempPath + "/" + 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(configInfo, - DPL:: - FromUTF32String( - L"widget")))); - } else { - // DRM widget - std::string configFile; - if (pkgType == PKG_TYPE_HYBRID_WEB_APP) { - configFile = tempPath + "/" + WITH_OSP_XML; - } else { - configFile = tempPath + "/" + CONFIG_XML; + if (isReinstall) { + // checking RDS data directory + if (access(configFile.c_str(), F_OK) != 0) { + std::string tzAppId = + widgetSource.substr(widgetSource.find_last_of("/")+1); + WidgetDAOReadOnly dao(WidgetDAOReadOnly::getTzAppId(DPL::FromUTF8String(tzAppId))); + configFile = DPL::ToUTF8String(*dao.getWidgetInstalledPath()); + configFile += "/"; + configFile += WITH_OSP_XML; } + } - parser.Parse(configFile, - ElementParserPtr( - new RootParser(configInfo, - DPL:: - FromUTF32String( - L"widget")))); + if(!DPL::Utils::Path(configFile).Exists()) + { + ThrowMsg(Exceptions::MissingConfig, "Config file not exists"); } + + parser.Parse(configFile, + ElementParserPtr( + new RootParser(configInfo, + DPL:: + FromUTF32String( + L"widget")))); } } - Catch(DPL::ZipInput::Exception::OpenFailed) - { - LogError("Failed to open widget package"); - return ConfigParserData(); - } - Catch(DPL::ZipInput::Exception::OpenFileFailed) - { - LogError("Failed to open config.xml file"); - return ConfigParserData(); - } - Catch(DPL::CopyFailed) - { - LogError("Failed to extract config.xml file"); - return ConfigParserData(); - } - Catch(DPL::FileInput::Exception::OpenFailed) - { - LogError("Failed to open config.xml file"); - return ConfigParserData(); - } Catch(ElementParser::Exception::ParseError) { LogError("Failed to parse config.xml file"); return ConfigParserData(); } - Catch(DPL::ZipInput::Exception::SeekFileFailed) + Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) { - LogError("Failed to seek widget archive - corrupted package?"); + LogError("Failed to find installed widget - give proper tizenId"); + return ConfigParserData(); + } + Catch(Exceptions::WidgetConfigFileNotFound){ + LogError("Failed to find config.xml"); return ConfigParserData(); } + return configInfo; } WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate( const ConfigParserData &configInfo, - const WrtDB::WidgetType appType, const WrtDB::TizenAppId &tizenId) { - LogInfo("Checking up widget package for config.xml..."); - - DPL::OptionalString widgetGUID; - OptionalWidgetVersion widgetVersion; - - // Check widget id - widgetGUID = configInfo.widget_id; - - if (widgetGUID.IsNull()) { - LogWarning("Installed widget has no GUID"); - return WidgetUpdateInfo(); - } - - LogDebug("Installed widget GUID: " << *widgetGUID); + LogDebug("Checking up widget package for config.xml..."); + OptionalWidgetVersion incomingVersion; - // Locate widget ID with this GUID - // Incoming widget version if (!configInfo.version.IsNull()) { - widgetVersion = + incomingVersion = DPL::Optional( WidgetVersion(*configInfo.version)); } - if (appType == APP_TYPE_WAC20) { - Try - { - // Search widget handle by GUID - WidgetDAOReadOnly dao(widgetGUID); - return WidgetUpdateInfo( - widgetGUID, - widgetVersion, - WidgetUpdateInfo::ExistingWidgetInfo( - dao.getTzAppId(), dao.getVersion())); - } - Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) - { - // GUID isn't installed - return WidgetUpdateInfo( - widgetGUID, - widgetVersion, - WidgetUpdateInfo::ExistingWidgetInfo()); - } - } else { - Try - { - // Search widget handle by appId - WidgetDAOReadOnly dao(tizenId); - return WidgetUpdateInfo( - widgetGUID, - widgetVersion, - WidgetUpdateInfo::ExistingWidgetInfo( - dao.getTzAppId(), dao.getVersion())); - } - Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) - { - // GUID isn't installed - return WidgetUpdateInfo( - widgetGUID, - widgetVersion, - WidgetUpdateInfo::ExistingWidgetInfo()); - } + WidgetDAOReadOnly dao(tizenId); + + OptionalWidgetVersion optVersion; + DPL::OptionalString version = dao.getVersion(); + if (!version.IsNull()) { + optVersion = OptionalWidgetVersion(WidgetVersion(*version)); } + + return WidgetUpdateInfo( + dao.getTzAppId(), + optVersion, + incomingVersion); } void JobWidgetInstall::SendProgress() @@ -815,10 +776,10 @@ void JobWidgetInstall::SendFinishedSuccess() sync(); if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) { - if (false == m_installerContext.existingWidgetInfo.isExist) { - WidgetInstallToExtSingleton::Instance().postInstallation(true); - } else { + if (m_installerContext.isUpdateMode) { WidgetInstallToExtSingleton::Instance().postUpgrade(true); + } else { + WidgetInstallToExtSingleton::Instance().postInstallation(true); } WidgetInstallToExtSingleton::Instance().deinitialize(); } @@ -839,7 +800,7 @@ void JobWidgetInstall::SendFinishedSuccess() LogDebug("Call widget install successfinishedCallback"); getInstallerStruct().finishedCallback(getInstallerStruct().userParam, DPL::ToUTF8String( - tizenId), Exceptions::Success); + tizenId), Jobs::Exceptions::Success); } void JobWidgetInstall::SendFinishedFailure() @@ -848,14 +809,20 @@ void JobWidgetInstall::SendFinishedFailure() // remove widget install information file unlink(m_installerContext.installInfo.c_str()); - LogError("Error in installation step: " << m_exceptionCaught); + LogError("Error number: " << m_exceptionCaught); LogError("Message: " << m_exceptionMessage); TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid; LogDebug("Call widget install failure finishedCallback"); + std::stringstream errorNum; + errorNum << m_exceptionCaught; // send signal of pkgmgr getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_ERROR, + errorNum.str()); + + getInstallerStruct().pkgmgrInterface->sendSignal( PKGMGR_END_KEY, PKGMGR_END_FAILURE); @@ -866,7 +833,7 @@ void JobWidgetInstall::SendFinishedFailure() void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e) { - m_exceptionCaught = static_cast(e.getParam()); + m_exceptionCaught = static_cast(e.getParam()); m_exceptionMessage = e.GetMessage(); } @@ -897,7 +864,6 @@ void JobWidgetInstall::displayWidgetInfo() localizedInfo.description; out << std::endl << "Widget Id: " << dao.getGUID(); out << std::endl << "Widget recognized: " << dao.isRecognized(); - out << std::endl << "Widget wac signed: " << dao.isWacSigned(); out << std::endl << "Widget distributor signed: " << dao.isDistributorSigned(); out << std::endl << "Widget trusted: " << dao.isTrusted(); @@ -925,133 +891,55 @@ void JobWidgetInstall::displayWidgetInfo() FOREACH(it, list) { out << std::endl << " Name: " << it->name; - out << std::endl << " Required: " << it->required; - out << std::endl << " Params:"; } } out << std::endl; - LogInfo(out.str()); + LogDebug(out.str()); } WrtDB::PackagingType JobWidgetInstall::checkPackageType( const std::string &widgetSource, const std::string &tempPath) { - // Check installation type (direcotory/ or config.xml or widget.wgt) - if (WidgetUpdateMode::PolicyDirectoryForceInstall == - m_jobStruct.updateMode) - { - LogDebug("Install directly from directory"); - return PKG_TYPE_DIRECTORY_WEB_APP; - } if (hasExtension(widgetSource, XML_EXTENSION)) { - LogInfo("Hosted app installation"); + LogDebug("Hosted app installation"); return PKG_TYPE_HOSTED_WEB_APP; } - if (m_isDRM) { - std::string configFile = tempPath + "/" + CONFIG_XML; - if (WrtUtilFileExists(configFile)) { - return PKG_TYPE_NOMAL_WEB_APP; - } - - configFile = tempPath + "/" + WITH_OSP_XML; - if (WrtUtilFileExists(configFile)) { - return PKG_TYPE_HYBRID_WEB_APP; - } - } else { - std::unique_ptr 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; - } - Catch(DPL::ZipInput::Exception::SeekFileFailed) - { - LogError("Failed to seek widget package file"); - return PKG_TYPE_UNKNOWN; - } - - Try - { - // Open config.xml file in package root - std::unique_ptr configFile( - zipFile->OpenFile(CONFIG_XML)); - return PKG_TYPE_NOMAL_WEB_APP; - } - Catch(DPL::ZipInput::Exception::OpenFileFailed) - { - LogDebug("Could not find config.xml"); - } - - Try - { - // Open config.xml file in package root - std::unique_ptr configFile( - zipFile->OpenFile(WITH_OSP_XML)); - - return PKG_TYPE_HYBRID_WEB_APP; - } - Catch(DPL::ZipInput::Exception::OpenFileFailed) - { - LogDebug("Could not find wgt/config.xml"); - return PKG_TYPE_UNKNOWN; - } + std::string configFile = tempPath + "/" + OSP_MANIFEST_XML; + if (WrtUtilFileExists(configFile)) { + return PKG_TYPE_HYBRID_WEB_APP; } - return PKG_TYPE_UNKNOWN; + return PKG_TYPE_NOMAL_WEB_APP; } void JobWidgetInstall::setApplicationType( const WrtDB::ConfigParserData &configInfo) { + AppType widgetAppType = APP_TYPE_UNKNOWN; FOREACH(iterator, configInfo.nameSpaces) { - LogInfo("namespace = [" << *iterator << "]"); - AppType currentAppType = APP_TYPE_UNKNOWN; - - if (*iterator == ConfigurationNamespace::W3CWidgetNamespaceName) { - continue; - } else if ( - *iterator == - ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement || - *iterator == - ConfigurationNamespace::WacWidgetNamespaceName) - { - currentAppType = APP_TYPE_WAC20; - } else if (*iterator == - ConfigurationNamespace::TizenWebAppNamespaceName) - { - currentAppType = APP_TYPE_TIZENWEBAPP; - } + LogDebug("namespace = [" << *iterator << "]"); - if (m_installerContext.widgetConfig.webAppType == - APP_TYPE_UNKNOWN) - { - m_installerContext.widgetConfig.webAppType = currentAppType; - } else if (m_installerContext.widgetConfig.webAppType == - currentAppType) - { - continue; + if (*iterator == ConfigurationNamespace::TizenWebAppNamespaceName) { + if (widgetAppType != APP_TYPE_UNKNOWN && + widgetAppType != APP_TYPE_TIZENWEBAPP) + { + LogError("To many namespaces declared in configuration fileA."); + ThrowMsg(Exceptions::WidgetConfigFileInvalid, + "Config.xml has more than one valid namespace"); + } + widgetAppType = APP_TYPE_TIZENWEBAPP; } else { - ThrowMsg(Exceptions::WidgetConfigFileInvalid, - "Config.xml has more than one namespace"); + LogDebug("Namespace ignored."); } } - // If there is no define, type set to WAC 2.0 - if (m_installerContext.widgetConfig.webAppType == APP_TYPE_UNKNOWN) { - m_installerContext.widgetConfig.webAppType = APP_TYPE_WAC20; - } + m_installerContext.widgetConfig.webAppType = widgetAppType; - LogInfo("type = [" << + LogDebug("type = [" << m_installerContext.widgetConfig.webAppType.getApptypeToString() << "]"); } @@ -1072,18 +960,11 @@ bool JobWidgetInstall::detectResourceEncryption( } void JobWidgetInstall::setInstallLocationType( - const - WrtDB::ConfigParserData & - configData) + const WrtDB::ConfigParserData & configData) { m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL; - - if (true == m_jobStruct.m_preload) { - m_installerContext.locationType = - INSTALL_LOCATION_TYPE_PRELOAD; - } else { - FOREACH(it, configData.settingsList) - { + if (m_installerContext.mode.installTime != InstallMode::InstallTime::PRELOAD) { + FOREACH(it, configData.settingsList) { if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME && it->m_value == SETTING_VALUE_INSTALLTOEXT_PREPER_EXT) @@ -1096,54 +977,39 @@ void JobWidgetInstall::setInstallLocationType( } } -bool JobWidgetInstall::isDRMWidget(std::string widgetPath) +bool JobWidgetInstall::checkSupportRDSUpdate(const WrtDB::ConfigParserData + &configInfo) { - /* TODO : - * drm_bool_type_e is_drm_file = DRM_UNKNOWN; - * int ret = -1; - * - * ret = drm_is_drm_file(widgetPath.c_str(), &is_drm_file); - * if(DRM_RETURN_SUCCESS == ret && DRM_TRUE == is_drm_file) { - */ - - /* blow code temporary code for drm. */ - int ret = drm_oem_intel_isDrmFile(const_cast(widgetPath.c_str())); - if (1 == ret) { - return true; - } else { - return false; - } -} - -bool JobWidgetInstall::DecryptDRMWidget(std::string widgetPath, - std::string destPath) -{ - /* TODO : - * drm_trusted_sapps_decrypt_package_info_s package_info; - * - * strncpy(package_info.sadcf_filepath, widgetPath.c_str(), - * sizeof(package_info.sadcf_filepath)); - * strncpy(package_info.decrypt_filepath, destPath.c_str(), - * sizeof(package_info.decrypt_filepath)); - * - * drm_trusted_request_type_e requestType = - * DRM_TRUSTED_REQ_TYPE_SAPPS_DECRYPT_PACKAGE; - * - * int ret = drm_trusted_handle_request(requestType, - * (void *)&package_info, NULL); - * if (DRM_TRUSTED_RETURN_SUCCESS == ret) { - * return true; - * } else { - * return false; - * } - */ - if (drm_oem_intel_decrypt_package(const_cast(widgetPath.c_str()), - const_cast(destPath.c_str())) != 0) + if (m_installerContext.mode.command == + InstallMode::Command::REINSTALL) { - return true; - } else { - return false; + DPL::String configValue = SETTING_VALUE_ENCRYPTION_DISABLE; + DPL::String dbValue = SETTING_VALUE_ENCRYPTION_DISABLE; + + WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid); + WrtDB::WidgetSettings widgetSettings; + dao.getWidgetSettings(widgetSettings); + + FOREACH(it, widgetSettings) { + if (it->settingName == SETTING_VALUE_ENCRYPTION) { + dbValue = it->settingValue; + } + } + + FOREACH(data, configInfo.settingsList) + { + if (data->m_name == SETTING_VALUE_ENCRYPTION) + { + configValue = data->m_value; + } + } + if (configValue != dbValue) { + LogError("Not Support RDS mode because of encryption setting"); + return false; + } } + + return true; } } //namespace WidgetInstall } //namespace Jobs