${INSTALLER_JOBS}/widget_install/task_commons.cpp
${INSTALLER_JOBS}/widget_install/task_widget_config.cpp
${INSTALLER_JOBS}/widget_install/task_database.cpp
+ ${INSTALLER_JOBS}/widget_install/task_installer_fail.cpp
+ ${INSTALLER_JOBS}/widget_install/task_configuration.cpp
${INSTALLER_JOBS}/widget_install/ace_registration.cpp
${INSTALLER_JOBS}/widget_install/task_file_manipulation.cpp
${INSTALLER_JOBS}/widget_install/task_smack.cpp
#ifndef INSTALLER_MODEL_H
#define INSTALLER_MODEL_H
-#include <dpl/task_list.h>
+#include <dpl/mutable_task_list.h>
namespace Jobs {
class JobExceptionBase;
typedef int JobHandle;
class Job :
- public DPL::TaskList
+ public DPL::MutableTaskList
{
public:
Job(InstallationType installType);
* @version 1.0
* @brief Implementation file for main installer task
*/
-#include <memory>
#include <string>
#include <sys/time.h>
#include <ctime>
#include <limits.h>
#include <regex.h>
-#include <dpl/noncopyable.h>
#include <dpl/abstract_waitable_input_adapter.h>
#include <dpl/abstract_waitable_output_adapter.h>
#include <dpl/zip_input.h>
#include <widget_install/task_pkg_info_update.h>
#include <widget_install/task_commons.h>
#include <widget_install/task_prepare_reinstall.h>
+#include <widget_install/task_configuration.h>
+#include <widget_install/task_installer_fail.h>
#include <widget_install/widget_install_errors.h>
#include <widget_install/widget_install_context.h>
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,}$";
-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";
-static const DPL::String SETTING_VALUE_ENCRYPTION_DISABLE = L"disable";
-const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME =
- L"install-location";
-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);
- false;
- }
- return (0 == filename.compare(fileLen - extLen, extLen, extension));
-}
-} // namespace anonymous
-
namespace Jobs {
namespace WidgetInstall {
-class InstallerTaskFail :
- public DPL::TaskDecl<InstallerTaskFail>
-{
- private:
- ConfigureResult m_result;
-
- void StepFail()
- {
- 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!");
- }
- }
-
- public:
- InstallerTaskFail(ConfigureResult result) :
- DPL::TaskDecl<InstallerTaskFail>(this),
- m_result(result)
- {
- AddStep(&InstallerTaskFail::StepFail);
- }
-};
JobWidgetInstall::JobWidgetInstall(
std::string const &widgetPath,
m_exceptionCaught(Jobs::Exceptions::Success)
{
m_installerContext.mode = m_jobStruct.m_installMode;
- ConfigureResult result = prepareInstallation(widgetPath);
-
- if (result == ConfigureResult::Ok) {
- LogDebug("Configure installation succeeded");
- m_installerContext.job->SetProgressFlag(true);
-
- AddTask(new TaskRecovery(m_installerContext));
-
- AddTask(new TaskWidgetConfig(m_installerContext));
- if (m_installerContext.widgetConfig.packagingType ==
- WrtDB::PKG_TYPE_HOSTED_WEB_APP)
- {
- 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));
- AddTask(new TaskManifestFile(m_installerContext));
- if (m_installerContext.widgetConfig.packagingType ==
- PKG_TYPE_HYBRID_WEB_APP)
- {
- AddTask(new TaskInstallOspsvc(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) {
- LogDebug("Configure installation updated");
- LogDebug("Widget Update");
- m_installerContext.job->SetProgressFlag(true);
-
- if (m_installerContext.mode.command ==
- InstallMode::Command::REINSTALL)
- {
- AddTask(new TaskPrepareReinstall(m_installerContext));
- }
-
- AddTask(new TaskWidgetConfig(m_installerContext));
-
- if (m_installerContext.widgetConfig.packagingType ==
- WrtDB::PKG_TYPE_HOSTED_WEB_APP)
- {
- AddTask(new TaskPrepareFiles(m_installerContext));
- }
-
- AddTask(new TaskCertify(m_installerContext));
- 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));
- }
-
- AddTask(new TaskManifestFile(m_installerContext));
- if (m_installerContext.widgetConfig.packagingType ==
- PKG_TYPE_HYBRID_WEB_APP)
- {
- AddTask(new TaskInstallOspsvc(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
- 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!");
- getInstallerStruct().pkgmgrInterface->sendSignal(
- PKGMGR_START_KEY,
- PKGMGR_START_INSTALL);
- getInstallerStruct().pkgmgrInterface->sendSignal(
- PKGMGR_PROGRESS_KEY,
- PKGMGR_START_VALUE);
-
- AddTask(new InstallerTaskFail(result));
- }
-}
-
-ConfigureResult JobWidgetInstall::prepareInstallation(
- const std::string &widgetPath)
-{
- ConfigureResult result;
- m_needEncryption = false;
- Try
- {
- 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);
- ConfigParserData configData = getWidgetDataFromXML(
- widgetPath,
- tempDir,
- m_installerContext.widgetConfig.packagingType,
- m_installerContext.mode.command == InstallMode::Command::REINSTALL);
- LogDebug("widget packaging type : " <<
- m_installerContext.widgetConfig.packagingType.pkgType);
-
- setTizenId(configData);
- 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);
- getInstallerStruct().pkgmgrInterface->sendSignal(
- PKGMGR_PROGRESS_KEY,
- PKGMGR_START_VALUE);
- }
- Catch(Exceptions::OpenZipFailed)
- {
- LogError("Failed to unzip for widget");
- result = ConfigureResult::Failed_OpenZipError;
- }
- Catch(Exceptions::ExtractFileFailed)
- {
- 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;
- }
-
- return result;
-}
-
-void JobWidgetInstall::setTizenId(
- const WrtDB::ConfigParserData &configInfo)
-{
- bool shouldMakeAppid = false;
- using namespace PackageManager;
- if (!!configInfo.tizenAppId) {
- LogDebug("Setting tizenAppId provided in config.xml: " <<
- configInfo.tizenAppId);
-
- 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 {
- 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;
- LogDebug("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");
- }
-
- LogDebug("Name : " << name);
- if (!name || (regexec(®x, DPL::ToUTF8String(*name).c_str(),
- static_cast<size_t>(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");
- }
- 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;
- }
-
- // send start signal of pkgmgr
- getInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String(
- m_installerContext.
- widgetConfig.
- tzPkgid));
- 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,
- const std::string& tempPath)
-{
- m_installerContext.locations =
- WidgetLocation(DPL::ToUTF8String(m_installerContext.widgetConfig.
- tzPkgid),
- widgetPath, tempPath,
- m_installerContext.widgetConfig.packagingType,
- m_installerContext.mode.rootPath ==
- InstallMode::RootPath::RO,
- m_installerContext.mode.extension);
- m_installerContext.locations->registerAppid(
- DPL::ToUTF8String(m_installerContext.widgetConfig.tzAppid));
-
- LogDebug("widgetSource " << widgetPath);
-}
+ m_installerContext.requestedPath = widgetPath;
-ConfigureResult JobWidgetInstall::ConfigureInstallation(
- const std::string &widgetSource,
- const WrtDB::ConfigParserData &configData,
- const std::string &tempPath)
-{
- 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) {
- getInstallerStruct().pkgmgrInterface->sendSignal(
- PKGMGR_START_KEY,
- PKGMGR_START_INSTALL);
- result = ConfigureResult::Ok;
- 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;
- }
- }
-
- configureWidgetLocation(widgetSource, tempPath);
+ //start configuration of installation
+ AddTask(new TaskConfiguration(m_installerContext));
// Init installer context
m_installerContext.installStep = InstallerContext::INSTALL_START;
m_installerContext.job = this;
m_installerContext.widgetConfig.shareHref = std::string();
-
- return result;
}
-bool JobWidgetInstall::validateTizenApplicationID(
- const WrtDB::TizenAppId &tizenAppId)
+void JobWidgetInstall::appendNewInstallationTaskList()
{
- LogDebug("tizen application ID = [" << tizenAppId << "]");
+ LogDebug("Configure installation succeeded");
+ m_installerContext.job->SetProgressFlag(true);
- regex_t reg;
- if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
- LogDebug("Regcomp failed");
- }
+ AddTask(new TaskRecovery(m_installerContext));
- if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
- == REG_NOMATCH)
+ AddTask(new TaskWidgetConfig(m_installerContext));
+ if (m_installerContext.widgetConfig.packagingType ==
+ WrtDB::PKG_TYPE_HOSTED_WEB_APP)
{
- regfree(®);
- return false;
+ AddTask(new TaskPrepareFiles(m_installerContext));
}
- regfree(®);
- return true;
-}
-
-bool JobWidgetInstall::validateTizenPackageID(
- const WrtDB::TizenPkgId &tizenPkgId)
-{
- std::string pkgId = DPL::ToUTF8String(tizenPkgId);
-
- std::string installPath =
- std::string(GlobalConfig::GetUserInstalledWidgetPath()) +
- "/" + pkgId;
-
- struct stat dirStat;
- if ((stat(installPath.c_str(), &dirStat) == 0))
+ AddTask(new TaskCertify(m_installerContext));
+ AddTask(new TaskCertifyLevel(m_installerContext));
+ if (m_installerContext.needEncryption) {
+ AddTask(new TaskEncryptResource(m_installerContext));
+ }
+ AddTask(new TaskFileManipulation(m_installerContext));
+ AddTask(new TaskManifestFile(m_installerContext));
+ if (m_installerContext.widgetConfig.packagingType ==
+ PKG_TYPE_HYBRID_WEB_APP)
{
- return false;
+ AddTask(new TaskInstallOspsvc(m_installerContext));
}
- return true;
+ AddTask(new TaskDatabase(m_installerContext));
+ AddTask(new TaskAceCheck(m_installerContext));
+ AddTask(new TaskSmack(m_installerContext));
+ AddTask(new TaskPkgInfoUpdate(m_installerContext));
}
-ConfigureResult JobWidgetInstall::checkWidgetUpdate(
- const WidgetUpdateInfo &update)
+void JobWidgetInstall::appendUpdateInstallationTaskList()
{
- if (update.existingVersion.IsNull() || update.incomingVersion.IsNull()) {
- return ConfigureResult::Failed;
- }
+ LogDebug("Configure installation updated");
+ LogDebug("Widget Update");
+ m_installerContext.job->SetProgressFlag(true);
- 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 (m_installerContext.mode.command ==
+ InstallMode::Command::REINSTALL)
+ {
+ AddTask(new TaskPrepareReinstall(m_installerContext));
}
- 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;
- }
+ AddTask(new TaskWidgetConfig(m_installerContext));
- // 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 {
- 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");
- }
+ if (m_installerContext.widgetConfig.packagingType ==
+ WrtDB::PKG_TYPE_HOSTED_WEB_APP)
+ {
+ AddTask(new TaskPrepareFiles(m_installerContext));
}
- m_installerContext.widgetConfig.tzAppid = update.tzAppId;
+ AddTask(new TaskCertify(m_installerContext));
+ AddTask(new TaskCertifyLevel(m_installerContext));
+ if (m_installerContext.needEncryption) {
+ AddTask(new TaskEncryptResource(m_installerContext));
+ }
- if (!!update.existingVersion ||
- m_installerContext.mode.extension ==
+ if (m_installerContext.mode.extension !=
InstallMode::ExtensionType::DIR) {
- return ConfigureResult::Updated;
+ AddTask(new TaskUpdateFiles(m_installerContext));
+ AddTask(new TaskFileManipulation(m_installerContext));
}
- return ConfigureResult::Failed;
-}
-
-ConfigParserData JobWidgetInstall::getWidgetDataFromXML(
- const std::string &widgetSource,
- const std::string &tempPath,
- WrtDB::PackagingType pkgType,
- bool isReinstall)
-{
- // Parse config
- ParserRunner parser;
- ConfigParserData configInfo;
- Try
+ AddTask(new TaskManifestFile(m_installerContext));
+ if (m_installerContext.widgetConfig.packagingType ==
+ PKG_TYPE_HYBRID_WEB_APP)
{
- if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
- parser.Parse(widgetSource,
- ElementParserPtr(
- new RootParser<WidgetParser>(configInfo,
- DPL::FromUTF32String(
- L"widget"))));
- } else {
- std::string configFile;
- configFile = tempPath + "/" + CONFIG_XML;
- if (!WrtUtilFileExists(configFile)) {
- configFile = tempPath + "/" + WITH_OSP_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;
- }
- }
-
- if(!DPL::Utils::Path(configFile).Exists())
- {
- ThrowMsg(Exceptions::MissingConfig, "Config file not exists");
- }
-
- parser.Parse(configFile,
- ElementParserPtr(
- new RootParser<WidgetParser>(configInfo,
- DPL::
- FromUTF32String(
- L"widget"))));
- }
- }
- Catch(ElementParser::Exception::ParseError)
- {
- LogError("Failed to parse config.xml file");
- return ConfigParserData();
- }
- Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
- {
- LogError("Failed to find installed widget - give proper tizenId");
- return ConfigParserData();
- }
- Catch(Exceptions::WidgetConfigFileNotFound){
- LogError("Failed to find config.xml");
- return ConfigParserData();
+ AddTask(new TaskInstallOspsvc(m_installerContext));
}
- return configInfo;
+ 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
+ AddTask(new TaskSmack(m_installerContext));
+ AddTask(new TaskRemoveBackupFiles(m_installerContext));
+ AddTask(new TaskPkgInfoUpdate(m_installerContext));
}
-WidgetUpdateInfo JobWidgetInstall::detectWidgetUpdate(
- const ConfigParserData &configInfo,
- const WrtDB::TizenAppId &tizenId)
+void JobWidgetInstall::appendFailureTaskList()
{
- LogDebug("Checking up widget package for config.xml...");
- OptionalWidgetVersion incomingVersion;
-
- if (!configInfo.version.IsNull()) {
- incomingVersion =
- DPL::Optional<WidgetVersion>(
- WidgetVersion(*configInfo.version));
- }
-
- WidgetDAOReadOnly dao(tizenId);
-
- OptionalWidgetVersion optVersion;
- DPL::OptionalString version = dao.getVersion();
- if (!version.IsNull()) {
- optVersion = OptionalWidgetVersion(WidgetVersion(*version));
- }
+ // Installation is not allowed to proceed due to widget update policy
+ LogWarning("Configure installation failed!");
+ getInstallerStruct().pkgmgrInterface->sendSignal(
+ PKGMGR_START_KEY,
+ PKGMGR_START_INSTALL);
+ getInstallerStruct().pkgmgrInterface->sendSignal(
+ PKGMGR_PROGRESS_KEY,
+ PKGMGR_START_VALUE);
- return WidgetUpdateInfo(
- dao.getTzAppId(),
- optVersion,
- incomingVersion);
+ AddTask(new InstallerTaskFail(m_installerContext.confResult));
}
void JobWidgetInstall::SendProgress()
LogDebug(out.str());
}
-
-WrtDB::PackagingType JobWidgetInstall::checkPackageType(
- const std::string &widgetSource,
- const std::string &tempPath)
-{
- if (hasExtension(widgetSource, XML_EXTENSION)) {
- LogDebug("Hosted app installation");
- return PKG_TYPE_HOSTED_WEB_APP;
- }
-
- std::string configFile = tempPath + "/" + OSP_MANIFEST_XML;
- if (WrtUtilFileExists(configFile)) {
- return PKG_TYPE_HYBRID_WEB_APP;
- }
-
- return PKG_TYPE_NOMAL_WEB_APP;
-}
-
-void JobWidgetInstall::setApplicationType(
- const WrtDB::ConfigParserData &configInfo)
-{
- AppType widgetAppType = APP_TYPE_UNKNOWN;
- FOREACH(iterator, configInfo.nameSpaces) {
- LogDebug("namespace = [" << *iterator << "]");
-
- 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 {
- LogDebug("Namespace ignored.");
- }
- }
-
- m_installerContext.widgetConfig.webAppType = widgetAppType;
-
- LogDebug("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)
- {
- LogDebug("resource need encryption");
- return true;
- }
- }
- return false;
-}
-
-void JobWidgetInstall::setInstallLocationType(
- const WrtDB::ConfigParserData & configData)
-{
- m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL;
- 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)
- {
- LogDebug("This widget will be installed to sd card");
- m_installerContext.locationType =
- INSTALL_LOCATION_TYPE_EXTERNAL;
- }
- }
- }
-}
-
-bool JobWidgetInstall::checkSupportRDSUpdate(const WrtDB::ConfigParserData
- &configInfo)
-{
- if (m_installerContext.mode.command ==
- InstallMode::Command::REINSTALL)
- {
- 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
#ifndef WRT_SRC_INSTALLER_CORE_JOB_JOB_WIDGET_INSTALL_H_
#define WRT_SRC_INSTALLER_CORE_JOB_JOB_WIDGET_INSTALL_H_
-#include <dpl/optional.h>
-#include <dpl/string.h>
#include <job.h>
#include <job_base.h>
#include <dpl/utils/widget_version.h>
-#include <widget_install/widget_install_context.h>
-#include <widget_install/widget_update_info.h>
-#include <dpl/wrt-dao-ro/config_parser_data.h>
#include "widget_installer_struct.h"
+#include <widget_install/widget_install_context.h>
using namespace Jobs::Exceptions;
namespace Jobs {
namespace WidgetInstall {
-enum class ConfigureResult
-{
- Ok,
- Updated,
- Failed,
- Failed_InvalidConfig,
- Failed_LowerVersion,
- Failed_AlreadyInstalled,
- Failed_WidgetRunning,
- Failed_DrmError,
- Failed_NotSupportRDSUpdate,
- Failed_OpenZipError,
- Failed_UnzipError,
-};
class JobWidgetInstall :
public Job,
private:
InstallerContext m_installerContext;
- //TODO move it to base class of all jobs -> make it base template class??
Jobs::Exceptions::Type m_exceptionCaught;
std::string m_exceptionMessage;
- WidgetUpdateInfo m_widgetUpdateInfo;
- bool m_needEncryption;
-
- ConfigureResult ConfigureInstallation(const std::string &widgetSource,
- const WrtDB::ConfigParserData
- &configData,
- const std::string &tempPath);
- static WrtDB::ConfigParserData getWidgetDataFromXML(
- const std::string &widgetSource,
- const std::string &tempPath,
- WrtDB::PackagingType pkgType,
- bool isReinstall);
- static WidgetUpdateInfo detectWidgetUpdate(
- const WrtDB::ConfigParserData &configInfo,
- const WrtDB::TizenAppId &tizenId);
- void setTizenId(const WrtDB::ConfigParserData &configInfo);
- void displayWidgetInfo();
- void configureWidgetLocation(const std::string & widgetPath,
- const std::string &tempPath);
-
- WrtDB::PackagingType checkPackageType(
- const std::string &widgetSource,
- const std::string &tempPath);
- bool detectResourceEncryption(const WrtDB::ConfigParserData &configData);
- void setInstallLocationType(const WrtDB::ConfigParserData
- &configData);
- ConfigureResult prepareInstallation(const std::string &widgetPath);
- bool validateTizenApplicationID(const WrtDB::TizenAppId &tizenAppId);
- bool validateTizenPackageID(const WrtDB::TizenPkgId &tizenPkgId);
- ConfigureResult checkWidgetUpdate(const WidgetUpdateInfo &update);
- void setApplicationType(const WrtDB::ConfigParserData &configInfo);
- bool checkSupportRDSUpdate(const WrtDB::ConfigParserData &configInfo);
public:
/**
void SendFinishedSuccess();
void SendFinishedFailure();
void SendProgressIconPath(const std::string &path);
+
void SaveExceptionData(const Jobs::JobExceptionBase&);
+ void displayWidgetInfo();
+
+ //execution paths
+ void appendNewInstallationTaskList();
+ void appendUpdateInstallationTaskList();
+ void appendFailureTaskList();
};
} //namespace WidgetInstall
} //namespace Jobs
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file task_configuration.cpp
+ * @version 1.0
+ * @author Tomasz Iwanek
+ * @brief implementation file for configuration task
+ */
+#include "task_configuration.h"
+
+#include <string>
+#include <sstream>
+#include <memory>
+#include <sys/time.h>
+#include <ctime>
+#include <cstdlib>
+#include <limits.h>
+#include <regex.h>
+
+#include <dpl/utils/wrt_utility.h>
+#include <dpl/utils/path.h>
+#include <dpl/wrt-dao-ro/common_dao_types.h>
+#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <dpl/wrt-dao-ro/global_config.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include <dpl/localization/w3c_file_localization.h>
+
+#include <libiriwrapper.h>
+#include <pkg-manager/pkgmgr_signal.h>
+#include <app_manager.h>
+
+#include "root_parser.h"
+#include "widget_parser.h"
+#include "parser_runner.h"
+
+#include <widget_install/widget_install_errors.h>
+#include <widget_install/widget_install_context.h>
+#include <widget_install_to_external.h>
+#include <widget_install/widget_unzip.h>
+#include <widget_install/job_widget_install.h>
+#include <widget_install/task_commons.h>
+
+using namespace WrtDB;
+
+namespace {
+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,}$";
+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";
+static const DPL::String SETTING_VALUE_ENCRYPTION_DISABLE = L"disable";
+const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME =
+ L"install-location";
+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 {
+
+TaskConfiguration::TaskConfiguration(InstallerContext& context) :
+ DPL::TaskDecl<TaskConfiguration>(this),
+ m_context(context),
+ m_result(ConfigureResult::Unknown)
+{
+ AddStep(&TaskConfiguration::StartStep);
+ AddStep(&TaskConfiguration::PrepareInstallationStep);
+ AddStep(&TaskConfiguration::AppendTasklistStep);
+ AddStep(&TaskConfiguration::EndStep);
+}
+
+void TaskConfiguration::StartStep()
+{
+ LogDebug("--------- <TaskConfiguration> : START ----------");
+}
+
+void TaskConfiguration::EndStep()
+{
+ LogDebug("--------- <TaskConfiguration> : END ----------");
+}
+
+void TaskConfiguration::AppendTasklistStep()
+{
+ // TODO: (job_install_refactoring) do not store config result anywhere
+ m_context.confResult = m_result;
+
+ if (m_result == ConfigureResult::Ok) {
+ LogInfo("TaskConfiguration -> new installation task list");
+ m_context.job->appendNewInstallationTaskList();
+ } else if (m_result == ConfigureResult::Updated) {
+ LogInfo("TaskConfiguration -> update installation task list");
+ m_context.job->appendUpdateInstallationTaskList();
+ } else {
+ LogInfo("TaskConfiguration -> failure task list");
+ m_context.job->appendFailureTaskList();
+ }
+}
+
+void TaskConfiguration::PrepareInstallationStep()
+{
+ // TODO: (job_install_refactoring) clean up this task
+ std::string widgetPath = m_context.requestedPath;
+ ConfigureResult result;
+ m_context.needEncryption = false;
+ Try
+ {
+ std::string tempDir;
+ if (m_context.mode.extension == InstallMode::ExtensionType::DIR) {
+ if (m_context.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_context.mode.rootPath ==
+ InstallMode::RootPath::RO);
+ WidgetUnzip wgtUnzip;
+ wgtUnzip.unzipWgtFile(widgetPath, tempDir);
+ }
+
+ LogDebug("widgetPath:" << widgetPath);
+ LogDebug("tempPath:" << tempDir);
+
+ m_context.widgetConfig.packagingType =
+ checkPackageType(widgetPath, tempDir);
+ ConfigParserData configData = getWidgetDataFromXML(
+ widgetPath,
+ tempDir,
+ m_context.widgetConfig.packagingType,
+ m_context.mode.command == InstallMode::Command::REINSTALL);
+ LogDebug("widget packaging type : " <<
+ m_context.widgetConfig.packagingType.pkgType);
+
+ setTizenId(configData);
+ setApplicationType(configData);
+ m_context.needEncryption = detectResourceEncryption(configData);
+ setInstallLocationType(configData);
+ // TODO: (job_install_refactoring) hide this call
+ m_context.callerPkgId =
+ DPL::FromUTF8String(m_context.job->getInstallerStruct().pkgmgrInterface->getCallerId());
+ LogDebug("Caller Package Id : " << m_context.callerPkgId);
+
+ // Configure installation
+ result = ConfigureInstallation(widgetPath, configData, tempDir);
+ // TODO: (job_install_refactoring) hide this call
+ m_context.job->getInstallerStruct().pkgmgrInterface->sendSignal(
+ PKGMGR_PROGRESS_KEY,
+ PKGMGR_START_VALUE);
+ }
+ Catch(Exceptions::OpenZipFailed)
+ {
+ LogError("Failed to unzip for widget");
+ result = ConfigureResult::Failed_OpenZipError;
+ }
+ Catch(Exceptions::ExtractFileFailed)
+ {
+ 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;
+ }
+
+ m_result = result;
+}
+
+void TaskConfiguration::setTizenId(
+ const WrtDB::ConfigParserData &configInfo)
+{
+ bool shouldMakeAppid = false;
+ using namespace PackageManager;
+ if (!!configInfo.tizenAppId) {
+ LogDebug("Setting tizenAppId provided in config.xml: " <<
+ configInfo.tizenAppId);
+
+ m_context.widgetConfig.tzAppid = *configInfo.tizenAppId;
+ //check package id.
+ if (!!configInfo.tizenPkgId) {
+ LogDebug("Setting tizenPkgId provided in config.xml: " <<
+ configInfo.tizenPkgId);
+
+ m_context.widgetConfig.tzPkgid = *configInfo.tizenPkgId;
+ } else {
+ DPL::String appid = *configInfo.tizenAppId;
+ if (appid.length() > PACKAGE_ID_LENGTH) {
+ m_context.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_context.widgetConfig.tzPkgid =
+ *configInfo.tizenAppId;
+ shouldMakeAppid = true;
+ }
+ }
+ } else {
+ 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_context.widgetConfig.tzPkgid = pkgId;
+ LogDebug("tizen_id name was generated by WRT: " <<
+ m_context.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");
+ }
+
+ LogDebug("Name : " << name);
+ if (!name || (regexec(®x, DPL::ToUTF8String(*name).c_str(),
+ static_cast<size_t>(0), NULL, 0) != REG_NOERROR))
+ {
+ // TODO : (job_install_refactoring) 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");
+ }
+ regfree(®x);
+ LogDebug("Name : " << name);
+ std::ostringstream genid;
+ genid << m_context.widgetConfig.tzPkgid << "." << name;
+ LogDebug("tizen appid was generated by WRT : " << genid.str());
+
+ DPL::OptionalString appid = DPL::FromUTF8String(genid.str());
+ NormalizeAndTrimSpaceString(appid);
+ m_context.widgetConfig.tzAppid = *appid;
+ }
+
+ // send start signal of pkgmgr
+ // TODO: (job_install_refactoring) hide this call
+ m_context.job->getInstallerStruct().pkgmgrInterface->setPkgname(DPL::ToUTF8String(
+ m_context.
+ widgetConfig.
+ tzPkgid));
+ LogDebug("Tizen App Id : " << m_context.widgetConfig.tzAppid);
+ LogDebug("Tizen Pkg Id : " << m_context.widgetConfig.tzPkgid);
+ LogDebug("W3C Widget GUID : " << m_context.widgetConfig.guid);
+}
+
+void TaskConfiguration::configureWidgetLocation(const std::string & widgetPath,
+ const std::string& tempPath)
+{
+ m_context.locations =
+ WidgetLocation(DPL::ToUTF8String(m_context.widgetConfig.
+ tzPkgid),
+ widgetPath, tempPath,
+ m_context.widgetConfig.packagingType,
+ m_context.mode.rootPath ==
+ InstallMode::RootPath::RO,
+ m_context.mode.extension);
+ m_context.locations->registerAppid(
+ DPL::ToUTF8String(m_context.widgetConfig.tzAppid));
+
+ LogDebug("widgetSource " << widgetPath);
+}
+
+ConfigureResult TaskConfiguration::ConfigureInstallation(
+ const std::string &widgetSource,
+ const WrtDB::ConfigParserData &configData,
+ const std::string &tempPath)
+{
+ ConfigureResult result = ConfigureResult::Failed;
+ WidgetUpdateInfo update;
+
+ // checking installed web application
+ Try {
+ // checking existing application is installed
+ WidgetDAOReadOnly dao(m_context.widgetConfig.tzAppid);
+ // no excpetion means, it isn't update mode
+ // TODO: (job_install_refactoring) hide this call/
+ m_context.job->getInstallerStruct().pkgmgrInterface->sendSignal(
+ PKGMGR_START_KEY,
+ PKGMGR_START_UPDATE);
+
+ update = detectWidgetUpdate(configData,
+ m_context.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_context.isUpdateMode = true;
+ }
+ Catch(WidgetDAOReadOnly::Exception::WidgetNotExist) {
+ // TODO: (job_install_refactoring) hide this call
+ m_context.job->getInstallerStruct().pkgmgrInterface->sendSignal(
+ PKGMGR_START_KEY,
+ PKGMGR_START_INSTALL);
+ result = ConfigureResult::Ok;
+ m_context.isUpdateMode = false;
+
+ if (!validateTizenApplicationID(
+ m_context.widgetConfig.tzAppid))
+ {
+ LogError("tizen application ID is already used");
+ return ConfigureResult::Failed_InvalidConfig;
+ }
+ if (!validateTizenPackageID(m_context.widgetConfig.tzPkgid)) {
+ LogError("tizen package ID is already used");
+ return ConfigureResult::Failed_AlreadyInstalled;
+ }
+ }
+
+ configureWidgetLocation(widgetSource, tempPath);
+
+ return result;
+}
+
+bool TaskConfiguration::validateTizenApplicationID(
+ const WrtDB::TizenAppId &tizenAppId)
+{
+ LogDebug("tizen application ID = [" << tizenAppId << "]");
+
+ regex_t reg;
+ if (regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+ LogDebug("Regcomp failed");
+ }
+
+ if (regexec(®, DPL::ToUTF8String(tizenAppId).c_str(), 0, NULL, 0)
+ == REG_NOMATCH)
+ {
+ regfree(®);
+ return false;
+ }
+ regfree(®);
+ return true;
+}
+
+bool TaskConfiguration::validateTizenPackageID(
+ const WrtDB::TizenPkgId &tizenPkgId)
+{
+ std::string pkgId = DPL::ToUTF8String(tizenPkgId);
+
+ std::string installPath =
+ std::string(GlobalConfig::GetUserInstalledWidgetPath()) +
+ "/" + pkgId;
+
+ struct stat dirStat;
+ if ((stat(installPath.c_str(), &dirStat) == 0))
+ {
+ return false;
+ }
+ return true;
+}
+
+ConfigureResult TaskConfiguration::checkWidgetUpdate(
+ const WidgetUpdateInfo &update)
+{
+ 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 {
+ 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_context.widgetConfig.tzAppid = update.tzAppId;
+
+ if (!!update.existingVersion ||
+ m_context.mode.extension ==
+ InstallMode::ExtensionType::DIR) {
+ return ConfigureResult::Updated;
+ }
+
+ return ConfigureResult::Failed;
+}
+
+ConfigParserData TaskConfiguration::getWidgetDataFromXML(
+ const std::string &widgetSource,
+ const std::string &tempPath,
+ WrtDB::PackagingType pkgType,
+ bool isReinstall)
+{
+ // Parse config
+ ParserRunner parser;
+ ConfigParserData configInfo;
+ Try
+ {
+ if (pkgType == PKG_TYPE_HOSTED_WEB_APP) {
+ parser.Parse(widgetSource,
+ ElementParserPtr(
+ new RootParser<WidgetParser>(configInfo,
+ DPL::FromUTF32String(
+ L"widget"))));
+ } else {
+ std::string configFile;
+ configFile = tempPath + "/" + CONFIG_XML;
+ if (!WrtUtilFileExists(configFile)) {
+ configFile = tempPath + "/" + WITH_OSP_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;
+ }
+ }
+
+ if(!DPL::Utils::Path(configFile).Exists())
+ {
+ ThrowMsg(Exceptions::MissingConfig, "Config file not exists");
+ }
+
+ parser.Parse(configFile,
+ ElementParserPtr(
+ new RootParser<WidgetParser>(configInfo,
+ DPL::
+ FromUTF32String(
+ L"widget"))));
+ }
+ }
+ Catch(ElementParser::Exception::ParseError)
+ {
+ LogError("Failed to parse config.xml file");
+ return ConfigParserData();
+ }
+ Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
+ {
+ 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 TaskConfiguration::detectWidgetUpdate(
+ const ConfigParserData &configInfo,
+ const WrtDB::TizenAppId &tizenId)
+{
+ LogDebug("Checking up widget package for config.xml...");
+ OptionalWidgetVersion incomingVersion;
+
+ if (!configInfo.version.IsNull()) {
+ incomingVersion =
+ DPL::Optional<WidgetVersion>(
+ WidgetVersion(*configInfo.version));
+ }
+
+ WidgetDAOReadOnly dao(tizenId);
+
+ OptionalWidgetVersion optVersion;
+ DPL::OptionalString version = dao.getVersion();
+ if (!version.IsNull()) {
+ optVersion = OptionalWidgetVersion(WidgetVersion(*version));
+ }
+
+ return WidgetUpdateInfo(
+ dao.getTzAppId(),
+ optVersion,
+ incomingVersion);
+}
+
+
+WrtDB::PackagingType TaskConfiguration::checkPackageType(
+ const std::string &widgetSource,
+ const std::string &tempPath)
+{
+ if (hasExtension(widgetSource, XML_EXTENSION)) {
+ LogDebug("Hosted app installation");
+ return PKG_TYPE_HOSTED_WEB_APP;
+ }
+
+ std::string configFile = tempPath + "/" + OSP_MANIFEST_XML;
+ if (WrtUtilFileExists(configFile)) {
+ return PKG_TYPE_HYBRID_WEB_APP;
+ }
+
+ return PKG_TYPE_NOMAL_WEB_APP;
+}
+
+void TaskConfiguration::setApplicationType(
+ const WrtDB::ConfigParserData &configInfo)
+{
+ AppType widgetAppType = APP_TYPE_UNKNOWN;
+ FOREACH(iterator, configInfo.nameSpaces) {
+ LogDebug("namespace = [" << *iterator << "]");
+
+ 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 {
+ LogDebug("Namespace ignored.");
+ }
+ }
+
+ m_context.widgetConfig.webAppType = widgetAppType;
+
+ LogDebug("type = [" <<
+ m_context.widgetConfig.webAppType.getApptypeToString() <<
+ "]");
+}
+
+bool TaskConfiguration::detectResourceEncryption(
+ const WrtDB::ConfigParserData &configData)
+{
+ FOREACH(it, configData.settingsList)
+ {
+ if (it->m_name == SETTING_VALUE_ENCRYPTION &&
+ it->m_value == SETTING_VALUE_ENCRYPTION_ENABLE)
+ {
+ LogDebug("resource need encryption");
+ return true;
+ }
+ }
+ return false;
+}
+
+void TaskConfiguration::setInstallLocationType(
+ const WrtDB::ConfigParserData & configData)
+{
+ m_context.locationType = INSTALL_LOCATION_TYPE_NOMAL;
+ if (m_context.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)
+ {
+ LogDebug("This widget will be installed to sd card");
+ m_context.locationType =
+ INSTALL_LOCATION_TYPE_EXTERNAL;
+ }
+ }
+ }
+}
+
+bool TaskConfiguration::checkSupportRDSUpdate(const WrtDB::ConfigParserData
+ &configInfo)
+{
+ if (m_context.mode.command ==
+ InstallMode::Command::REINSTALL)
+ {
+ DPL::String configValue = SETTING_VALUE_ENCRYPTION_DISABLE;
+ DPL::String dbValue = SETTING_VALUE_ENCRYPTION_DISABLE;
+
+ WidgetDAOReadOnly dao(m_context.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;
+}
+
+}
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file task_configuration.h
+ * @version 1.0
+ * @author Tomasz Iwanek
+ * @brief header file for configuration task
+ */
+#ifndef TASK_CONFIGURATION_H
+#define TASK_CONFIGURATION_H
+
+#include <dpl/task_list.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+
+#include <widget_install/widget_update_info.h>
+#include <widget_install/widget_install_context.h>
+
+class InstallerContext;
+
+namespace Jobs {
+namespace WidgetInstall {
+
+class TaskConfiguration : public DPL::TaskDecl<TaskConfiguration>
+{
+ InstallerContext& m_context;
+ ConfigureResult m_result;
+ WidgetUpdateInfo m_widgetUpdateInfo;
+
+ ConfigureResult ConfigureInstallation(const std::string &widgetSource,
+ const WrtDB::ConfigParserData
+ &configData,
+ const std::string &tempPath);
+ static WrtDB::ConfigParserData getWidgetDataFromXML(
+ const std::string &widgetSource,
+ const std::string &tempPath,
+ WrtDB::PackagingType pkgType,
+ bool isReinstall);
+ static WidgetUpdateInfo detectWidgetUpdate(
+ const WrtDB::ConfigParserData &configInfo,
+ const WrtDB::TizenAppId &tizenId);
+ void setTizenId(const WrtDB::ConfigParserData &configInfo);
+ void configureWidgetLocation(const std::string & widgetPath,
+ const std::string &tempPath);
+
+ WrtDB::PackagingType checkPackageType(
+ const std::string &widgetSource,
+ const std::string &tempPath);
+ bool detectResourceEncryption(const WrtDB::ConfigParserData &configData);
+ void setInstallLocationType(const WrtDB::ConfigParserData
+ &configData);
+
+ bool validateTizenApplicationID(const WrtDB::TizenAppId &tizenAppId);
+ bool validateTizenPackageID(const WrtDB::TizenPkgId &tizenPkgId);
+ ConfigureResult checkWidgetUpdate(const WidgetUpdateInfo &update);
+ void setApplicationType(const WrtDB::ConfigParserData &configInfo);
+ bool checkSupportRDSUpdate(const WrtDB::ConfigParserData &configInfo);
+
+ void PrepareInstallationStep();
+ void AppendTasklistStep();
+
+ void StartStep();
+ void EndStep();
+
+public:
+ TaskConfiguration(InstallerContext& context);
+};
+
+}
+}
+
+#endif // TASK_CONFIGURATION_H
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file task_installer_fail.cpp
+ * @version 1.0
+ * @brief implementation file for failure task
+ */
+#include "task_installer_fail.h"
+
+#include <widget_install/widget_install_errors.h>
+
+using namespace WrtDB;
+using namespace Jobs::Exceptions;
+
+namespace Jobs {
+namespace WidgetInstall {
+
+void InstallerTaskFail::StepFail()
+{
+ 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!");
+ }
+}
+
+InstallerTaskFail::InstallerTaskFail(ConfigureResult result) :
+ DPL::TaskDecl<InstallerTaskFail>(this),
+ m_result(result)
+{
+ AddStep(&InstallerTaskFail::StepFail);
+}
+
+}
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file task_installer_fail.h
+ * @version 1.0
+ * @brief header file for failure task
+ */
+#ifndef TASK_INSTALLER_FAIL_H
+#define TASK_INSTALLER_FAIL_H
+
+#include <dpl/task_list.h>
+#include <widget_install/widget_install_context.h>
+
+namespace Jobs {
+namespace WidgetInstall {
+class InstallerTaskFail :
+ public DPL::TaskDecl<InstallerTaskFail>
+{
+ private:
+ ConfigureResult m_result;
+
+ void StepFail();
+
+ public:
+ InstallerTaskFail(ConfigureResult result);
+};
+
+}
+}
+
+#endif // TASK_INSTALLER_FAIL_H
typedef std::map<DPL::String, bool> RequestedDevCapsMap;
+//TODO: move it elsewhere
+enum class ConfigureResult
+{
+ Ok,
+ Updated,
+ Failed,
+ Failed_InvalidConfig,
+ Failed_LowerVersion,
+ Failed_AlreadyInstalled,
+ Failed_WidgetRunning,
+ Failed_DrmError,
+ Failed_NotSupportRDSUpdate,
+ Failed_OpenZipError,
+ Failed_UnzipError,
+ Unknown
+};
+
struct InstallerContext
{
typedef enum InstallStepEnum
bool isUpdateMode;
InstallMode mode;
DPL::String callerPkgId;
+
+ std::string requestedPath;
+ bool needEncryption; // TODO: (job_install_refactoring) place into wisily not here
+ ConfigureResult confResult; //configuration result - TODO: (job_install_refactoring) get rid of this
};
#endif // INSTALLER_CONTEXT_H