X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fjobs%2Fwidget_install%2Fjob_widget_install.cpp;h=d31aa5a71dc353e1907e7ef32a955317e7625cda;hb=6c643b796dc60f4f3e2870146ddb222246bba734;hp=c311d8ca0b6616dc093cf6c1984172324fa1fd5f;hpb=42655b8f6796ff8d3354042ec7bfe6e26808418f;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 c311d8c..d31aa5a 100644 --- a/src/jobs/widget_install/job_widget_install.cpp +++ b/src/jobs/widget_install/job_widget_install.cpp @@ -79,6 +79,7 @@ #include using namespace WrtDB; +using namespace Jobs::Exceptions; namespace // anonymous { @@ -97,32 +98,6 @@ const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME = 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) @@ -137,35 +112,58 @@ bool hasExtension(const std::string& filename, const std::string& extension) } 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::Deferred) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::Deferred, + "widget installation or update deferred!"); + } else if (m_result == ConfigureResult::Failed_InvalidConfig) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::WidgetConfigFileInvalid, + "invalid config"); + } 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::DRMFailed, + "drm 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; @@ -238,6 +236,10 @@ JobWidgetInstall::JobWidgetInstall( } AddTask(new TaskCertify(m_installerContext)); + if (m_needEncryption) { + AddTask(new TaskEncryptResource(m_installerContext)); + } + if (m_installerContext.widgetConfig.packagingType != WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) { @@ -268,18 +270,19 @@ JobWidgetInstall::JobWidgetInstall( // Installation is deferred LogInfo("Configure installation deferred"); - AddTask(new InstallerTaskFail(true)); - } else if (result == ConfigureResult::Failed) { + AddTask(new InstallerTaskFail(result)); + } else if (result >= ConfigureResult::Failed && + result <= ConfigureResult::Failed_DrmError) { // Installation is not allowed to proceed due to widget update policy LogWarning("Configure installation failed!"); - AddTask(new InstallerTaskFail(false)); + AddTask(new InstallerTaskFail(result)); } else { Assert(false && "Invalid configure result!"); } } -JobWidgetInstall::ConfigureResult JobWidgetInstall::PrePareInstallation( +ConfigureResult JobWidgetInstall::PrePareInstallation( const std::string &widgetPath) { ConfigureResult result; @@ -288,14 +291,14 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::PrePareInstallation( Try { std::string tempDir = - Jobs::WidgetInstall::createTempPath(m_jobStruct.m_preload); + Jobs::WidgetInstall::createTempPath(m_jobStruct.m_installMode == InstallMode::INSTALL_MODE_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; + return ConfigureResult::Failed_DrmError; } } @@ -322,7 +325,7 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::PrePareInstallation( Catch(Exceptions::ExtractFileFailed) { LogError("Failed to create temporary path for widget"); - result = ConfigureResult::Failed; + result = ConfigureResult::Failed_InvalidConfig; } return result; @@ -362,7 +365,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; @@ -447,159 +450,155 @@ void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath, LogInfo("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; + } + m_installerContext.isUpdateMode = true; } + Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) { + result = ConfigureResult::Ok; + getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_START_KEY, + PKGMGR_START_INSTALL); + 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 << "'"); + LogInfo("tizen application ID = [" << tizenAppId << "]"); - // 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); + regex_t reg; + if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) { + LogDebug("Regcomp failed"); + } - TizenAppId tzAppid = update.existingWidgetInfo.tzAppid; + if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0) + == REG_NOMATCH) + { + regfree(®); + return false; + } + regfree(®); + return true; +} - LogInfo("Widget model exists. tizen app id: " << tzAppid); +bool JobWidgetInstall::validateTizenPackageID( + const WrtDB::TizenPkgId &tizenPkgId) +{ + std::string pkgId = DPL::ToUTF8String(tizenPkgId); - // 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; - } + std::string installPath = + std::string(GlobalConfig::GetUserInstalledWidgetPath()) + + "/" + pkgId; + std::string preinstallPath = + std::string(GlobalConfig::GetUserPreloadedWidgetPath()) + + "/" + pkgId; - 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"); + struct stat dirStat; + if ((stat(installPath.c_str(), &dirStat) == 0) || + (stat(preinstallPath.c_str(), &dirStat) == 0)) + { + return false; + } + return true; +} - return ConfigureResult::Deferred; - } else { - LogInfo( - "Widget is already running. Policy is not update according to WAC"); +ConfigureResult JobWidgetInstall::checkWidgetUpdate( + const WidgetUpdateInfo &update) +{ + LogInfo("incoming version = '" << update.incomingVersion); + LogInfo("Tizen AppID = " << update.tzAppId); + + // Check running state + bool isRunning = false; + int retval = + app_manager_is_running(DPL::ToUTF8String(update.tzAppId).c_str(), + &isRunning); + if (APP_MANAGER_ERROR_NONE != retval || isRunning) { + LogError("Fail to get running state"); + return ConfigureResult::Failed_WidgetRunning; + } - return ConfigureResult::Failed; - } - } + m_installerContext.widgetConfig.tzAppid = update.tzAppId; - 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; - } + if (isUpperVersion(update.existingVersion, update.incomingVersion) || + m_jobStruct.m_installMode == InstallMode::INSTALL_MODE_DIRECTORY) + { + LogInfo("Whether widget policy allow proceed ok"); + return ConfigureResult::Updated; + } else { + return ConfigureResult::Failed_LowerVersion; } - return ConfigureResult::Ok; + + return ConfigureResult::Failed; } -WidgetUpdateMode::Type JobWidgetInstall::CalcWidgetUpdatePolicy( +bool JobWidgetInstall::isUpperVersion( const OptionalWidgetVersion &existingVersion, - const OptionalWidgetVersion &incomingVersion) const + const OptionalWidgetVersion &incomingVersion) { - // Widget is installed, check versions + LogInfo("Existing version = '" << *existingVersion); + LogInfo("Incoming version = '" << *incomingVersion); + if (!existingVersion && !incomingVersion) { - return WidgetUpdateMode::ExistingVersionEqual; + return false; } else if (!existingVersion && !!incomingVersion) { - return WidgetUpdateMode::ExistingVersionNewer; + return false; } else if (!!existingVersion && !incomingVersion) { - return WidgetUpdateMode::ExistingVersionOlder; + return true; } 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 (!existingVersion->IsWac() || !incomingVersion->IsWac()) { + return false; } else { - // Both versions are WAC-comparable. Do compare. if (*incomingVersion == *existingVersion) { - return WidgetUpdateMode::ExistingVersionEqual; + return false; } else if (*incomingVersion > *existingVersion) { - return WidgetUpdateMode::ExistingVersionOlder; + return true; } else { - return WidgetUpdateMode::ExistingVersionNewer; + return false; } } } @@ -707,71 +706,22 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML( WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate( const ConfigParserData &configInfo, - const WrtDB::WidgetType appType, const WrtDB::TizenAppId &tizenId) { LogInfo("Checking up widget package for config.xml..."); + OptionalWidgetVersion incomingVersion; - 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); - - // 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); + return WidgetUpdateInfo( + dao.getTzAppId(), + WidgetVersion(*dao.getVersion()), + incomingVersion); } void JobWidgetInstall::SendProgress() @@ -815,10 +765,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 +789,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 +798,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 +822,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 +853,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(); @@ -938,8 +893,7 @@ WrtDB::PackagingType JobWidgetInstall::checkPackageType( const std::string &tempPath) { // Check installation type (direcotory/ or config.xml or widget.wgt) - if (WidgetUpdateMode::PolicyDirectoryForceInstall == - m_jobStruct.updateMode) + if (m_jobStruct.m_installMode == InstallMode::INSTALL_MODE_DIRECTORY) { LogDebug("Install directly from directory"); return PKG_TYPE_DIRECTORY_WEB_APP; @@ -1076,7 +1030,7 @@ void JobWidgetInstall::setInstallLocationType( { m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL; - if (true == m_jobStruct.m_preload) { + if (m_jobStruct.m_installMode == InstallMode::INSTALL_MODE_PRELOAD) { m_installerContext.locationType = INSTALL_LOCATION_TYPE_PRELOAD; } else {