X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fjobs%2Fwidget_install%2Fjob_widget_install.cpp;h=9bfad482f27e99f629e2db1cfa3159899f4ffd8a;hb=c21ace8409c3059da57bf0de1bdb8530044cb2a8;hp=96aa5bbae759f62d004728ce9953f16deed8ec1b;hpb=a118ccce57824bb8f7565026318a21c574a79137;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 96aa5bb..9bfad48 100644 --- a/src/jobs/widget_install/job_widget_install.cpp +++ b/src/jobs/widget_install/job_widget_install.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include // TODO remove #include @@ -60,7 +61,6 @@ #include #include #include -#include #include #include #include @@ -71,12 +71,15 @@ #include #include #include + #include #include #include +#include using namespace WrtDB; +using namespace Jobs::Exceptions; namespace // anonymous { @@ -84,88 +87,107 @@ 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]{10}$"; +const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}.{1,}$"; +const char* REG_NAME_PATTERN = "^[a-zA-Z0-9._-]{1,}$"; +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"; +const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME = + L"install-location-type"; +const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT = + L"prefer-external"; + +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 { +namespace WidgetInstall { class InstallerTaskFail : public DPL::TaskDecl { private: - bool m_deferred; + ConfigureResult m_result; void StepFail() { - if (m_deferred) { + if (m_result == ConfigureResult::Deferred) { ThrowMsg(Jobs::WidgetInstall::Exceptions::Deferred, - "Widget installation or update 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!"); + "widget installation or update not allowed!"); } } public: - InstallerTaskFail(bool deferred) : + InstallerTaskFail(ConfigureResult result) : DPL::TaskDecl(this), - m_deferred(deferred) + m_result(result) { 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 { -namespace WidgetInstall { -JobWidgetInstall::JobWidgetInstall(std::string const &widgetPath, - const WidgetInstallationStruct &installerStruct) : +JobWidgetInstall::JobWidgetInstall( + std::string const &widgetPath, + const WidgetInstallationStruct & + installerStruct) : Job(Installation), JobContextBase(installerStruct), - m_exceptionCaught(Exceptions::Success) + m_exceptionCaught(Jobs::Exceptions::Success) { - struct timeval tv; - gettimeofday(&tv, NULL); - srand(time(NULL) + tv.tv_usec); - m_installerContext.m_quiet = m_jobStruct.m_quiet; ConfigureResult result = PrePareInstallation(widgetPath); if (result == ConfigureResult::Ok) { LogInfo("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 && + WrtDB::PKG_TYPE_DIRECTORY_WEB_APP && m_installerContext.widgetConfig.packagingType != - WrtDB::PKG_TYPE_HOSTED_WEB_APP && + 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 || - m_installerContext.widgetConfig.packagingType == - WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) + if (m_installerContext.widgetConfig.packagingType == + WrtDB::PKG_TYPE_HOSTED_WEB_APP) { AddTask(new TaskPrepareFiles(m_installerContext)); } @@ -173,32 +195,33 @@ JobWidgetInstall::JobWidgetInstall(std::string const &widgetPath, if (m_needEncryption) { AddTask(new TaskEncryptResource(m_installerContext)); } + AddTask(new TaskFileManipulation(m_installerContext)); // TODO: Update progress information for this task - AddTask(new TaskPrivateStorage(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 TaskManifestFile(m_installerContext)); - AddTask(new TaskCertificates(m_installerContext)); if (m_installerContext.widgetConfig.packagingType == - PKG_TYPE_HYBRID_WEB_APP) { + PKG_TYPE_HYBRID_WEB_APP) + { AddTask(new TaskInstallOspsvc(m_installerContext)); } + AddTask(new TaskCertificates(m_installerContext)); AddTask(new TaskPluginsCopy(m_installerContext)); AddTask(new TaskDatabase(m_installerContext)); AddTask(new TaskAceCheck(m_installerContext)); } else if (result == ConfigureResult::Updated) { LogInfo("Configure installation updated"); LogInfo("Widget Update"); + m_installerContext.job->SetProgressFlag(true); if (m_installerContext.widgetConfig.packagingType != - WrtDB::PKG_TYPE_HOSTED_WEB_APP && + WrtDB::PKG_TYPE_HOSTED_WEB_APP && m_installerContext.widgetConfig.packagingType != - WrtDB::PKG_TYPE_DIRECTORY_WEB_APP && + WrtDB::PKG_TYPE_DIRECTORY_WEB_APP && !m_isDRM) { AddTask(new TaskUnzip(m_installerContext)); @@ -207,63 +230,75 @@ JobWidgetInstall::JobWidgetInstall(std::string const &widgetPath, AddTask(new TaskWidgetConfig(m_installerContext)); if (m_installerContext.widgetConfig.packagingType == - WrtDB::PKG_TYPE_HOSTED_WEB_APP || - m_installerContext.widgetConfig.packagingType == - WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) + WrtDB::PKG_TYPE_HOSTED_WEB_APP) { AddTask(new TaskPrepareFiles(m_installerContext)); } AddTask(new TaskCertify(m_installerContext)); - AddTask(new TaskUpdateFiles(m_installerContext)); + if (m_needEncryption) { + AddTask(new TaskEncryptResource(m_installerContext)); + } + + if (m_installerContext.widgetConfig.packagingType != + WrtDB::PKG_TYPE_DIRECTORY_WEB_APP) + { + AddTask(new TaskUpdateFiles(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) { + PKG_TYPE_HYBRID_WEB_APP) + { AddTask(new TaskInstallOspsvc(m_installerContext)); } - AddTask(new TaskRemoveBackupFiles(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 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( - const std::string &widgetPath) +ConfigureResult JobWidgetInstall::PrePareInstallation( + const std::string &widgetPath) { ConfigureResult result; m_needEncryption = false; Try { - std::string tempDir = Jobs::WidgetInstall::createTempPath(); + 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)) { + if (DecryptDRMWidget(widgetPath, tempDir)) { LogDebug("Failed decrypt DRM widget"); - return ConfigureResult::Failed; + return ConfigureResult::Failed_DrmError; } } @@ -271,202 +306,284 @@ JobWidgetInstall::ConfigureResult JobWidgetInstall::PrePareInstallation( m_installerContext.widgetConfig.packagingType = checkPackageType(widgetPath, tempDir); - ConfigParserData configData = getWidgetDataFromXML(widgetPath, tempDir, - m_installerContext.widgetConfig.packagingType, m_isDRM); + ConfigParserData configData = getWidgetDataFromXML( + widgetPath, + tempDir, + m_installerContext.widgetConfig.packagingType, + m_isDRM); LogDebug("widget packaging type : " << - m_installerContext.widgetConfig.packagingType.pkgType); - WidgetUpdateInfo update = detectWidgetUpdate(configData); + m_installerContext.widgetConfig.packagingType.pkgType); + + setTizenId(configData); + setApplicationType(configData); m_needEncryption = detectResourceEncryption(configData); + setInstallLocationType(configData); // Configure installation - result = ConfigureInstallation(widgetPath, configData, update, tempDir); + result = ConfigureInstallation(widgetPath, configData, tempDir); } Catch(Exceptions::ExtractFileFailed) { LogError("Failed to create temporary path for widget"); - result = ConfigureResult::Failed; + result = ConfigureResult::Failed_InvalidConfig; } return result; } -bool JobWidgetInstall::setTizenId( - const WrtDB::ConfigParserData &configInfo, ConfigureResult result) +void JobWidgetInstall::setTizenId( + const WrtDB::ConfigParserData &configInfo) { - regex_t reg; - if(regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED)!=0){ - LogDebug("Regcomp failed"); - } + bool shouldMakeAppid = false; + using namespace PackageManager; + if (!!configInfo.tizenAppId) { + LogDebug("Setting tizenAppId provided in config.xml: " << + configInfo.tizenAppId); - struct stat dirStat; - if(!!configInfo.tizenId) { - LogDebug("Setting tizenId provided in config.xml: " << configInfo.tizenId); - if ((regexec(®, DPL::ToUTF8String(*(configInfo.tizenId)).c_str(), - static_cast(0), NULL, 0) != REG_NOERROR) || - ((stat((std::string(GlobalConfig::GetUserInstalledWidgetPath()) + "/" - + DPL::ToUTF8String(*(configInfo.tizenId))).c_str(), &dirStat) == 0) - && result != ConfigureResult::Updated)) - { - //it is true when tizenId does not fit REG_TIZENID_PATTERN - LogError("tizen_id provided but not proper."); - regfree(®); - return false; - } - m_installerContext.widgetConfig.pkgname = configInfo.tizenId; + m_installerContext.widgetConfig.tzAppid = *configInfo.tizenAppId; + //check package id. + if (!!configInfo.tizenPkgId) { + LogDebug("Setting tizenPkgId provided in config.xml: " << + configInfo.tizenPkgId); + m_installerContext.widgetConfig.tzPkgid = *configInfo.tizenPkgId; + } else { + DPL::String appid = *configInfo.tizenAppId; + if (appid.length() > PACKAGE_ID_LENGTH) { + m_installerContext.widgetConfig.tzPkgid = + appid.substr(0, PACKAGE_ID_LENGTH); + } else { + //old version appid only has 10byte random character is able to install for a while. + //this case appid equal pkgid. + m_installerContext.widgetConfig.tzPkgid = + *configInfo.tizenAppId; + shouldMakeAppid = true; + } + } } else { - WidgetPkgName tizenId = WidgetDAOReadOnly::generateTizenId(); - - // only for installation, not for update - if (result == ConfigureResult::Ok) { - //check if there is package with same name and if generate different name - std::string path = GlobalConfig::GetUserInstalledWidgetPath(); - path += "/"; - - std::ostringstream newPath; - newPath << path << tizenId; - - LogDebug("Checking if tizen id is unique"); - while (true) { - if (stat(newPath.str().c_str(), &dirStat) == 0) { - //path exist, chose another one - tizenId = WidgetDAOReadOnly::generateTizenId(); - newPath.str(""); - newPath << path << tizenId; - continue; + shouldMakeAppid = true; + TizenPkgId pkgId = WidgetDAOReadOnly::generatePkgId(); + LogDebug("Checking if pkg id is unique"); + while (true) { + if (!validateTizenPackageID(pkgId)) { + //path exist, chose another one + pkgId = WidgetDAOReadOnly::generatePkgId(); + continue; + } + break; + } + m_installerContext.widgetConfig.tzPkgid = pkgId; + LogInfo("tizen_id name was generated by WRT: " << + m_installerContext.widgetConfig.tzPkgid); + } + + if (shouldMakeAppid == true) { + DPL::OptionalString name; + DPL::OptionalString defaultLocale = configInfo.defaultlocale; + + FOREACH(localizedData, configInfo.localizedDataSet) + { + Locale i = localizedData->first; + if (!!defaultLocale) { + if (defaultLocale == i) { + name = localizedData->second.name; + break; } + } else { + name = localizedData->second.name; break; } + } + regex_t regx; + if (regcomp(®x, REG_NAME_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) { + LogDebug("Regcomp failed"); + } - m_installerContext.widgetConfig.pkgname = tizenId; + LogDebug("Name : " << name); + if (!name || (regexec(®x, DPL::ToUTF8String(*name).c_str(), + static_cast(0), NULL, 0) != REG_NOERROR)) + { + // TODO : generate name move to wrt-commons + std::string allowedString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + std::ostringstream genName; + struct timeval tv; + gettimeofday(&tv, NULL); + unsigned int seed = time(NULL) + tv.tv_usec; + + genName << "_" << allowedString[rand_r(&seed) % allowedString.length()]; + name = DPL::FromUTF8String(genName.str()); + LogDebug("name was generated by WRT"); } - LogInfo("tizen_id name was generated by WRT: " << tizenId); + regfree(®x); + LogDebug("Name : " << name); + std::ostringstream genid; + genid << m_installerContext.widgetConfig.tzPkgid << "." << name; + LogDebug("tizen appid was generated by WRT : " << genid.str()); + + DPL::OptionalString appid = DPL::FromUTF8String(genid.str()); + NormalizeAndTrimSpaceString(appid); + m_installerContext.widgetConfig.tzAppid = *appid; } - regfree(®); - LogInfo("Tizen Id : " << m_installerContext.widgetConfig.pkgname); + // send start signal of pkgmgr + getInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String( + 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); - return true; } void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath, const std::string& tempPath) { m_installerContext.locations = - WidgetLocation(DPL::ToUTF8String(*m_installerContext.widgetConfig.pkgname), - widgetPath, tempPath, - m_installerContext.widgetConfig.packagingType); + WidgetLocation(DPL::ToUTF8String(m_installerContext.widgetConfig. + tzPkgid), + widgetPath, tempPath, + m_installerContext.widgetConfig.packagingType, + m_installerContext.locationType); + m_installerContext.locations->registerAppid( + DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid)); LogInfo("widgetSource " << widgetPath); } -JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation( - const std::string &widgetSource, - const WrtDB::ConfigParserData &configData, - const WidgetUpdateInfo &update, - const std::string &tempPath) +ConfigureResult JobWidgetInstall::ConfigureInstallation( + const std::string &widgetSource, + const WrtDB::ConfigParserData &configData, + const std::string &tempPath) { - LogInfo( - "Widget install/update: incoming guid = '" << - update.incomingGUID << "'"); - LogInfo( - "Widget install/update: incoming version = '" << - update.incomingVersion << "'"); - - // Check policy - WidgetUpdateMode::Type updateTypeCheckBit; - JobWidgetInstall::ConfigureResult ret = ConfigureResult::Ok; - - if (update.existingWidgetInfo.isExist == false) { - LogInfo("Widget info does not exist"); - updateTypeCheckBit = WidgetUpdateMode::NotInstalled; - } else { - LogInfo("Widget info exists. PkgName: " << - update.existingWidgetInfo.pkgname); + 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 (!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; + } + } - DPL::OptionalString pkgname = update.existingWidgetInfo.pkgname; + configureWidgetLocation(widgetSource, tempPath); - if(pkgname.IsNull()) { - LogInfo("But package name doesn't exist"); - return ConfigureResult::Failed; - } + // Init installer context + m_installerContext.installStep = InstallerContext::INSTALL_START; + m_installerContext.job = this; + m_installerContext.widgetConfig.shareHref = std::string(); - LogInfo("Widget model exists. package name: " << pkgname); + return result; +} - // Check running state - int retval = APP_MANAGER_ERROR_NONE; - bool isRunning = false; - retval = app_manager_is_running(DPL::ToUTF8String(*pkgname).c_str(), &isRunning); - if (APP_MANAGER_ERROR_NONE != retval) { - LogError("Fail to get running state"); - return ConfigureResult::Failed; - } +bool JobWidgetInstall::validateTizenApplicationID( + const WrtDB::TizenAppId &tizenAppId) +{ + LogInfo("tizen application ID = [" << tizenAppId << "]"); - 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"); + regex_t reg; + if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) { + LogDebug("Regcomp failed"); + } - return ConfigureResult::Deferred; - } else { - LogInfo( - "Widget is already running. Policy is not update according to WAC"); - LogInfo("Installation aborted: " << widgetSource); + if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0) + == REG_NOMATCH) + { + regfree(®); + return false; + } + regfree(®); + return true; +} - return ConfigureResult::Failed; - } - } +bool JobWidgetInstall::validateTizenPackageID( + const WrtDB::TizenPkgId &tizenPkgId) +{ + std::string pkgId = DPL::ToUTF8String(tizenPkgId); - m_installerContext.widgetConfig.pkgname = pkgname; - OptionalWidgetVersion existingVersion; - existingVersion = update.existingWidgetInfo.existingVersion; - OptionalWidgetVersion incomingVersion = update.incomingVersion; + std::string installPath = + std::string(GlobalConfig::GetUserInstalledWidgetPath()) + + "/" + pkgId; + std::string preinstallPath = + std::string(GlobalConfig::GetUserPreloadedWidgetPath()) + + "/" + pkgId; - 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"); - ret = ConfigureResult::Updated; - } - else - return ConfigureResult::Failed; + struct stat dirStat; + if ((stat(installPath.c_str(), &dirStat) == 0) || + (stat(preinstallPath.c_str(), &dirStat) == 0)) + { + return false; } + return true; +} - if (!setTizenId(configData, ret)) { - return ConfigureResult::Failed; - } else { - using namespace PackageManager; - LogInfo("Tizen Id: " << m_installerContext.widgetConfig.pkgname); +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; + } - configureWidgetLocation(widgetSource, tempPath); + m_installerContext.widgetConfig.tzAppid = update.tzAppId; - // send start signal of pkgmgr - PkgmgrSignalSingleton::Instance().setPkgname( - DPL::ToUTF8String( - *m_installerContext.widgetConfig.pkgname)); - PkgmgrSignalSingleton::Instance().sendSignal( - PKGMGR_START_KEY, - PKGMGR_START_INSTALL); + WidgetUpdateMode::Type updateTypeCheckBit; + updateTypeCheckBit = CalcWidgetUpdatePolicy(update.existingVersion, + update.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_LowerVersion; } - // 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 - return ret; + return ConfigureResult::Failed; } WidgetUpdateMode::Type JobWidgetInstall::CalcWidgetUpdatePolicy( - const OptionalWidgetVersion &existingVersion, - const OptionalWidgetVersion &incomingVersion) const + const OptionalWidgetVersion &existingVersion, + const OptionalWidgetVersion &incomingVersion) const { // Widget is installed, check versions if (!existingVersion && !incomingVersion) { @@ -498,10 +615,10 @@ WidgetUpdateMode::Type JobWidgetInstall::CalcWidgetUpdatePolicy( } ConfigParserData JobWidgetInstall::getWidgetDataFromXML( - const std::string &widgetSource, - const std::string &tempPath, - WrtDB::PackagingType pkgType, - bool isDRM) + const std::string &widgetSource, + const std::string &tempPath, + WrtDB::PackagingType pkgType, + bool isDRM) { // Parse config ParserRunner parser; @@ -511,20 +628,20 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML( { if (pkgType == PKG_TYPE_HOSTED_WEB_APP) { parser.Parse(widgetSource, - ElementParserPtr( - new RootParser(configInfo, - DPL::FromUTF32String( - L"widget")))); + ElementParserPtr( + new RootParser(configInfo, + DPL::FromUTF32String( + L"widget")))); } else if (pkgType == PKG_TYPE_DIRECTORY_WEB_APP) { - parser.Parse(widgetSource + '/' + CONFIG_XML, + parser.Parse(widgetSource + '/' + WITH_OSP_XML, ElementParserPtr( new RootParser( - configInfo, - DPL::FromUTF32String(L"widget")))); + configInfo, + DPL::FromUTF32String(L"widget")))); } else { if (!isDRM) { std::unique_ptr zipFile( - new DPL::ZipInput(widgetSource)); + new DPL::ZipInput(widgetSource)); std::unique_ptr configFile; @@ -541,10 +658,11 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML( DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer); DPL::Copy(&inputAdapter, &outputAdapter); parser.Parse(&buffer, - ElementParserPtr( - new RootParser(configInfo, - DPL::FromUTF32String( - L"widget")))); + ElementParserPtr( + new RootParser(configInfo, + DPL:: + FromUTF32String( + L"widget")))); } else { // DRM widget std::string configFile; @@ -555,10 +673,11 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML( } parser.Parse(configFile, - ElementParserPtr( - new RootParser(configInfo, - DPL::FromUTF32String( - L"widget")))); + ElementParserPtr( + new RootParser(configInfo, + DPL:: + FromUTF32String( + L"widget")))); } } } @@ -587,53 +706,32 @@ ConfigParserData JobWidgetInstall::getWidgetDataFromXML( LogError("Failed to parse config.xml file"); return ConfigParserData(); } + Catch(DPL::ZipInput::Exception::SeekFileFailed) + { + LogError("Failed to seek widget archive - corrupted package?"); + return ConfigParserData(); + } return configInfo; } WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate( - const ConfigParserData &configInfo) + const ConfigParserData &configInfo, + 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)); } - Try - { - // Search widget handle by GUID - WidgetDAOReadOnly dao(widgetGUID); - return WidgetUpdateInfo( - widgetGUID, - widgetVersion, - WidgetUpdateInfo::ExistingWidgetInfo( - *dao.getPkgname(), 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() @@ -644,13 +742,28 @@ void JobWidgetInstall::SendProgress() // send progress signal of pkgmgr std::ostringstream percent; percent << static_cast(GetProgressPercent()); - PkgmgrSignalSingleton::Instance().sendSignal( - PKGMGR_PROGRESS_KEY, - percent.str()); + getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_PROGRESS_KEY, + percent.str()); LogDebug("Call widget install progressCallbak"); - getInstallerStruct().progressCallback(getInstallerStruct().userParam, - GetProgressPercent(),GetProgressDescription()); + getInstallerStruct().progressCallback( + getInstallerStruct().userParam, + GetProgressPercent(), + GetProgressDescription()); + } + } +} + +void JobWidgetInstall::SendProgressIconPath(const std::string &path) +{ + using namespace PackageManager; + if (GetProgressFlag() != false) { + if (getInstallerStruct().progressCallback != NULL) { + // send progress signal of pkgmgr + getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_ICON_PATH, + path); } } } @@ -661,22 +774,32 @@ void JobWidgetInstall::SendFinishedSuccess() // TODO : sync should move to separate task. sync(); + if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) { + if (m_installerContext.isUpdateMode) { + WidgetInstallToExtSingleton::Instance().postUpgrade(true); + } else { + WidgetInstallToExtSingleton::Instance().postInstallation(true); + } + WidgetInstallToExtSingleton::Instance().deinitialize(); + } + // remove widget install information file unlink(m_installerContext.installInfo.c_str()); //inform widget info JobWidgetInstall::displayWidgetInfo(); - DPL::OptionalString & tizenId = m_installerContext.widgetConfig.pkgname; + TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid; // send signal of pkgmgr - PkgmgrSignalSingleton::Instance().sendSignal( - PKGMGR_END_KEY, - PKGMGR_END_SUCCESS); + getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_END_KEY, + PKGMGR_END_SUCCESS); LogDebug("Call widget install successfinishedCallback"); getInstallerStruct().finishedCallback(getInstallerStruct().userParam, - tizenId.IsNull() ? "" : DPL::ToUTF8String(*tizenId), Exceptions::Success); + DPL::ToUTF8String( + tizenId), Jobs::Exceptions::Success); } void JobWidgetInstall::SendFinishedFailure() @@ -685,60 +808,66 @@ 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); - DPL::OptionalString & tizenId = m_installerContext.widgetConfig.pkgname; + TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid; LogDebug("Call widget install failure finishedCallback"); + std::stringstream errorNum; + errorNum << m_exceptionCaught; // send signal of pkgmgr - PkgmgrSignalSingleton::Instance().sendSignal( - PKGMGR_END_KEY, - PKGMGR_END_FAILURE); + getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_ERROR, + errorNum.str()); + + getInstallerStruct().pkgmgrInterface->sendSignal( + PKGMGR_END_KEY, + PKGMGR_END_FAILURE); getInstallerStruct().finishedCallback(getInstallerStruct().userParam, - tizenId.IsNull() ? "" : DPL::ToUTF8String(*tizenId), m_exceptionCaught); + DPL::ToUTF8String( + tizenId), m_exceptionCaught); } void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e) { - m_exceptionCaught = static_cast(e.getParam()); + m_exceptionCaught = static_cast(e.getParam()); m_exceptionMessage = e.GetMessage(); } void JobWidgetInstall::displayWidgetInfo() { - WidgetDAOReadOnly dao(m_installerContext.locations->getPkgname()); + WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid); std::ostringstream out; WidgetLocalizedInfo localizedInfo = - W3CFileLocalization::getLocalizedInfo(*dao.getPkgname()); + W3CFileLocalization::getLocalizedInfo(dao.getTzAppId()); out << std::endl << - "===================================== INSTALLED WIDGET INFO ========="\ - "============================"; + "===================================== INSTALLED WIDGET INFO =========" \ + "============================"; out << std::endl << "Name: " << localizedInfo.name; - out << std::endl << "PkgName: " << dao.getPkgname(); + out << std::endl << "AppId: " << dao.getTzAppId(); WidgetSize size = dao.getPreferredSize(); out << std::endl << "Width: " << size.width; out << std::endl << "Height: " << size.height; out << std::endl << "Start File: " << - W3CFileLocalization::getStartFile(*dao.getPkgname()); + W3CFileLocalization::getStartFile(dao.getTzAppId()); out << std::endl << "Version: " << dao.getVersion(); out << std::endl << "Licence: " << - localizedInfo.license; + localizedInfo.license; out << std::endl << "Licence Href: " << - localizedInfo.licenseHref; + localizedInfo.licenseHref; out << std::endl << "Description: " << - localizedInfo.description; + 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(); + dao.isDistributorSigned(); out << std::endl << "Widget trusted: " << dao.isTrusted(); - OptionalWidgetIcon icon = W3CFileLocalization::getIcon(*dao.getPkgname()); + OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId()); DPL::OptionalString iconSrc = !!icon ? icon->src : DPL::OptionalString::Null; out << std::endl << "Icon: " << iconSrc; @@ -749,9 +878,9 @@ void JobWidgetInstall::displayWidgetInfo() FOREACH(it, list) { out << std::endl << " Key: " << - it->key_name; + it->key_name; out << std::endl << " Readonly: " << - it->readonly; + it->readonly; } } @@ -761,8 +890,6 @@ void JobWidgetInstall::displayWidgetInfo() FOREACH(it, list) { out << std::endl << " Name: " << it->name; - out << std::endl << " Required: " << it->required; - out << std::endl << " Params:"; } } @@ -772,11 +899,12 @@ void JobWidgetInstall::displayWidgetInfo() } WrtDB::PackagingType JobWidgetInstall::checkPackageType( - const std::string &widgetSource, - const std::string &tempPath) + const std::string &widgetSource, + const std::string &tempPath) { // Check installation type (direcotory/ or config.xml or widget.wgt) - if (WidgetUpdateMode::PolicyDirectoryForceInstall == m_jobStruct.updateMode) + if (WidgetUpdateMode::PolicyDirectoryForceInstall == + m_jobStruct.updateMode) { LogDebug("Install directly from directory"); return PKG_TYPE_DIRECTORY_WEB_APP; @@ -803,19 +931,23 @@ WrtDB::PackagingType JobWidgetInstall::checkPackageType( { // 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)); + zipFile->OpenFile(CONFIG_XML)); return PKG_TYPE_NOMAL_WEB_APP; } Catch(DPL::ZipInput::Exception::OpenFileFailed) @@ -827,7 +959,7 @@ WrtDB::PackagingType JobWidgetInstall::checkPackageType( { // Open config.xml file in package root std::unique_ptr configFile( - zipFile->OpenFile(WITH_OSP_XML)); + zipFile->OpenFile(WITH_OSP_XML)); return PKG_TYPE_HYBRID_WEB_APP; } @@ -841,12 +973,60 @@ WrtDB::PackagingType JobWidgetInstall::checkPackageType( return PKG_TYPE_UNKNOWN; } -bool JobWidgetInstall::detectResourceEncryption(const WrtDB::ConfigParserData &configData) +void JobWidgetInstall::setApplicationType( + const WrtDB::ConfigParserData &configInfo) +{ + 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; + } + + if (m_installerContext.widgetConfig.webAppType == + APP_TYPE_UNKNOWN) + { + m_installerContext.widgetConfig.webAppType = currentAppType; + } else if (m_installerContext.widgetConfig.webAppType == + currentAppType) + { + continue; + } else { + ThrowMsg(Exceptions::WidgetConfigFileInvalid, + "Config.xml has more than one namespace"); + } + } + + // 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; + } + + LogInfo("type = [" << + m_installerContext.widgetConfig.webAppType.getApptypeToString() << + "]"); +} + +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) { + it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE) + { LogDebug("resource need encryption"); return true; } @@ -854,19 +1034,44 @@ bool JobWidgetInstall::detectResourceEncryption(const WrtDB::ConfigParserData &c return false; } +void JobWidgetInstall::setInstallLocationType( + 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 (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME && + it->m_value == + SETTING_VALUE_INSTALLTOEXT_PREPER_EXT) + { + LogDebug("This widget will be installed to sd card"); + m_installerContext.locationType = + INSTALL_LOCATION_TYPE_EXTERNAL; + } + } + } +} + bool JobWidgetInstall::isDRMWidget(std::string widgetPath) { /* 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) { - */ + * 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) { + if (1 == ret) { return true; } else { return false; @@ -874,34 +1079,34 @@ bool JobWidgetInstall::isDRMWidget(std::string widgetPath) } bool JobWidgetInstall::DecryptDRMWidget(std::string widgetPath, - std::string destPath) + 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; - } - */ + * 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) { + const_cast(destPath.c_str())) != 0) + { return true; } else { return false; } } - } //namespace WidgetInstall } //namespace Jobs