From c952c0d74a1da5d7760ba7f2136ce4abca678220 Mon Sep 17 00:00:00 2001 From: Soyoung Kim Date: Fri, 18 Oct 2013 18:19:55 +0900 Subject: [PATCH] [Install Location: Part 2] WGT file unzip to package directory (/opt/usr/apps/[pkgid]) instead of temporary directory [Issue#] P130919-00555 [Problem] web app install to internal storage even if install location is set "SD card" from setting menu. [Cause] There is an issue to process getting install location. (Before parsing config.xml, installer cannot get install location info.) [Solution] - Parsing config.xml should be done before unzip wgt. - So parsing config.xml is separated before unzip. [Remarks] Installer, therefore, should implement below install location spec. * Auto: Get setting value about default storage at setting menu. - If user set "Device memory" try internal storage. If fails, try external storage. - If user set "SD card" try SD card. If fails, try internal storage. * Internal-only: Try internal storage. - If there is no space in internal memory, installation is failed. * Prefer-external: Try external storage. - If SD card is not available, try internal storage. There are three parts for implementation. * Part 1: This patch is for separating parse config.xml before unzipping wgt file. * Part 2: WGT file unzip to directory package directory (/opt/usr/apps/[pkgid]) instead of temporary directory. * Part 3: Implement about install location (auto, internal only prefer-external) [Verification] SD card should be attached in the device for this feature. - First> Normal and Hybrid web app can be installed without error. - Second> WebApp should be installed into device memory or SD card depending on install-location 1. Install-location: internal-only => should be installed into device memory 2. Install-location: prefer-external 1) SD card is enabled => into SD card. 2) SD card is disabled => into device memory. 3. Install-location: * Auto and default storage is "Device Memory" 1) into device memory. 2) If device Memory is full = > into SD card. * Auto and default storage is "SD card" 1) into SD card 2) If SD card isn't available => into device memory. [SCMRequest] N/A Change-Id: Iffbd7f35e3c9e9d03feeb987d4d7762f61c6c15d --- src/CMakeLists.txt | 1 + src/jobs/widget_install/job_widget_install.cpp | 17 +- src/jobs/widget_install/task_certify.cpp | 8 +- src/jobs/widget_install/task_certify_level.cpp | 9 +- src/jobs/widget_install/task_configuration.cpp | 42 +--- src/jobs/widget_install/task_configuration.h | 2 - src/jobs/widget_install/task_encrypt_resource.cpp | 9 +- src/jobs/widget_install/task_file_manipulation.cpp | 203 ++---------------- src/jobs/widget_install/task_file_manipulation.h | 5 +- src/jobs/widget_install/task_prepare_files.cpp | 2 +- src/jobs/widget_install/task_process_config.cpp | 10 +- .../widget_install/task_user_data_manipulation.cpp | 233 +++++++++++++++++++++ .../widget_install/task_user_data_manipulation.h | 48 +++++ src/jobs/widget_install/widget_install_context.h | 6 +- src/jobs/widget_install/widget_unzip.cpp | 5 +- src/jobs/widget_install/widget_unzip.h | 4 +- src/misc/widget_location.cpp | 20 +- src/misc/widget_location.h | 11 - 18 files changed, 338 insertions(+), 297 deletions(-) create mode 100644 src/jobs/widget_install/task_user_data_manipulation.cpp create mode 100644 src/jobs/widget_install/task_user_data_manipulation.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8009d61..5d81831 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,6 +67,7 @@ SET(INSTALLER_SOURCES ${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_user_data_manipulation.cpp ${INSTALLER_JOBS}/widget_install/task_smack.cpp ${INSTALLER_JOBS}/widget_install/task_ace_check.cpp ${INSTALLER_JOBS}/widget_install/task_manifest_file.cpp diff --git a/src/jobs/widget_install/job_widget_install.cpp b/src/jobs/widget_install/job_widget_install.cpp index f7ca2e4..27d47c6 100644 --- a/src/jobs/widget_install/job_widget_install.cpp +++ b/src/jobs/widget_install/job_widget_install.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -100,6 +101,7 @@ void JobWidgetInstall::appendNewInstallationTaskList() AddTask(new TaskRecovery(m_installerContext)); + AddTask(new TaskFileManipulation(m_installerContext)); AddTask(new TaskProcessConfig(m_installerContext)); if (m_installerContext.widgetConfig.packagingType == WrtDB::PKG_TYPE_HOSTED_WEB_APP) @@ -108,10 +110,10 @@ void JobWidgetInstall::appendNewInstallationTaskList() } AddTask(new TaskCertify(m_installerContext)); AddTask(new TaskCertifyLevel(m_installerContext)); + AddTask(new TaskUserDataManipulation(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) @@ -136,6 +138,12 @@ void JobWidgetInstall::appendUpdateInstallationTaskList() AddTask(new TaskPrepareReinstall(m_installerContext)); } + if (m_installerContext.mode.extension != + InstallMode::ExtensionType::DIR) { + AddTask(new TaskUpdateFiles(m_installerContext)); + AddTask(new TaskFileManipulation(m_installerContext)); + } + AddTask(new TaskProcessConfig(m_installerContext)); if (m_installerContext.widgetConfig.packagingType == @@ -146,16 +154,11 @@ void JobWidgetInstall::appendUpdateInstallationTaskList() AddTask(new TaskCertify(m_installerContext)); AddTask(new TaskCertifyLevel(m_installerContext)); + AddTask(new TaskUserDataManipulation(m_installerContext)); if (m_installerContext.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) diff --git a/src/jobs/widget_install/task_certify.cpp b/src/jobs/widget_install/task_certify.cpp index 9026967..81f21b0 100644 --- a/src/jobs/widget_install/task_certify.cpp +++ b/src/jobs/widget_install/task_certify.cpp @@ -215,13 +215,7 @@ void TaskCertify::stepSignature() _D("================ Step: <> ENTER ==============="); std::string widgetPath; - widgetPath = m_contextData.locations->getTemporaryPackageDir() + "/"; - - if (m_contextData.mode.command == - InstallMode::Command::REINSTALL) - { - widgetPath = m_contextData.locations->getPackageInstallationDir() + "/"; - } + widgetPath = m_contextData.locations->getPackageInstallationDir() + "/"; SignatureFileInfoSet signatureFiles; diff --git a/src/jobs/widget_install/task_certify_level.cpp b/src/jobs/widget_install/task_certify_level.cpp index c8a8f38..9d1bc50 100644 --- a/src/jobs/widget_install/task_certify_level.cpp +++ b/src/jobs/widget_install/task_certify_level.cpp @@ -80,14 +80,7 @@ void TaskCertifyLevel::getSignatureFiles(const std::string& path, TaskCertifyLevel::Level TaskCertifyLevel::getCertifyLevel() { - std::string widgetPath; - widgetPath = m_contextData.locations->getTemporaryPackageDir() + "/"; - - if (m_contextData.mode.command == InstallMode::Command::REINSTALL) { - widgetPath = - m_contextData.locations->getPackageInstallationDir() + "/"; - } - + std::string widgetPath = m_contextData.locations->getPackageInstallationDir() + "/"; SignatureFileInfoSet signatureFiles; Try { diff --git a/src/jobs/widget_install/task_configuration.cpp b/src/jobs/widget_install/task_configuration.cpp index 2835558..415898f 100644 --- a/src/jobs/widget_install/task_configuration.cpp +++ b/src/jobs/widget_install/task_configuration.cpp @@ -102,8 +102,6 @@ TaskConfiguration::TaskConfiguration(InstallerContext& context) : AddStep(&TaskConfiguration::SetupTempDirStep); AddStep(&TaskConfiguration::UnzipConfigurationStep); AddStep(&TaskConfiguration::ParseXMLConfigStep); - AddStep(&TaskConfiguration::UnzipWidgetFileStep); - AddStep(&TaskConfiguration::CheckPackageTypeStep); AddStep(&TaskConfiguration::TizenIdStep); AddStep(&TaskConfiguration::CheckAppRunningStateStep); @@ -183,9 +181,11 @@ void TaskConfiguration::UnzipConfigurationStep() if(!hasExtension(m_context.requestedPath, XML_EXTENSION)) //unzip everything except xml files { WidgetUnzip wgtUnzip; - wgtUnzip.unzipConfiguration(m_context.requestedPath, m_tempDir); + wgtUnzip.unzipConfiguration(m_context.requestedPath, m_tempDir, + &m_context.widgetConfig.packagingType); m_configuration += m_tempDir + "/" + CONFIG_XML; } else{ + m_context.widgetConfig.packagingType = PKG_TYPE_HOSTED_WEB_APP; m_configuration += m_context.requestedPath; } } else { @@ -202,6 +202,8 @@ void TaskConfiguration::UnzipConfigurationStep() configFile += "/"; configFile += WITH_OSP_XML; } + } else { + m_context.widgetConfig.packagingType = PKG_TYPE_NOMAL_WEB_APP; } m_configuration = configFile; } else { @@ -209,22 +211,7 @@ void TaskConfiguration::UnzipConfigurationStep() } } _D("m_configuration : %s", m_configuration.c_str()); -} - -void TaskConfiguration::UnzipWidgetFileStep() -{ - _D("UnzipWidgetFileStep"); - if (m_context.mode.extension != InstallMode::ExtensionType::DIR) { - if(!hasExtension(m_context.requestedPath, XML_EXTENSION)) //unzip everything except xml files - { - WidgetUnzip wgtUnzip; - wgtUnzip.unzipWgtFile(m_context.requestedPath, m_tempDir); - } - else - { - _D("From browser installation - unzip is not done"); - } - } + _D("Package Type : %s", m_context.widgetConfig.packagingType.getPkgtypeToString().c_str()); } void TaskConfiguration::ParseXMLConfigStep() @@ -587,23 +574,6 @@ WidgetUpdateInfo TaskConfiguration::detectWidgetUpdate( incomingVersion); } -void TaskConfiguration::CheckPackageTypeStep() -{ - if (hasExtension(m_context.requestedPath, XML_EXTENSION)) { - _D("Hosted app installation"); - m_context.widgetConfig.packagingType = PKG_TYPE_HOSTED_WEB_APP; - return; - } - - std::string configFile = m_tempDir + "/" + OSP_MANIFEST_XML; - if (WrtUtilFileExists(configFile)) { - m_context.widgetConfig.packagingType = PKG_TYPE_HYBRID_WEB_APP; - return; - } - - m_context.widgetConfig.packagingType = PKG_TYPE_NOMAL_WEB_APP; -} - void TaskConfiguration::ApplicationTypeStep() //TODO: is this really needed as WAC is not supported? { AppType widgetAppType = APP_TYPE_UNKNOWN; diff --git a/src/jobs/widget_install/task_configuration.h b/src/jobs/widget_install/task_configuration.h index d239b54..39e4701 100644 --- a/src/jobs/widget_install/task_configuration.h +++ b/src/jobs/widget_install/task_configuration.h @@ -72,8 +72,6 @@ class TaskConfiguration : public DPL::TaskDecl void SetupTempDirStep(); void UnzipConfigurationStep(); void ParseXMLConfigStep(); - void UnzipWidgetFileStep(); - void CheckPackageTypeStep(); void TizenIdStep(); void CheckAppRunningStateStep(); diff --git a/src/jobs/widget_install/task_encrypt_resource.cpp b/src/jobs/widget_install/task_encrypt_resource.cpp index d3255fb..3966ca8 100644 --- a/src/jobs/widget_install/task_encrypt_resource.cpp +++ b/src/jobs/widget_install/task_encrypt_resource.cpp @@ -196,7 +196,7 @@ void TaskEncryptResource::StepEncryptResource() { _D("Step Encrypt resource"); - EncryptDirectory(m_context.locations->getTemporaryRootDir()); + EncryptDirectory(m_context.locations->getSourceDir()); } void TaskEncryptResource::EncryptDirectory(std::string path) @@ -325,13 +325,8 @@ void TaskEncryptResource::EncryptFile(const std::string &fileName) } } - std::string realPath = fileName; - realPath.replace(0, - m_context.locations->getTemporaryRootDir().length(), - m_context.locations->getSourceDir()); - WrtDB::EncryptedFileInfo fileInfo; - fileInfo.fileName = DPL::FromUTF8String(realPath); + fileInfo.fileName = DPL::FromUTF8String(fileName); fileInfo.fileSize = fileSize; m_context.widgetConfig.encryptedFiles.insert(fileInfo); diff --git a/src/jobs/widget_install/task_file_manipulation.cpp b/src/jobs/widget_install/task_file_manipulation.cpp index a9dff14..0ab5ee3 100644 --- a/src/jobs/widget_install/task_file_manipulation.cpp +++ b/src/jobs/widget_install/task_file_manipulation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2010 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. @@ -37,6 +37,7 @@ #include #include #include +#include #define WEBAPP_DEFAULT_UID 5000 #define WEBAPP_DEFAULT_GID 5000 @@ -98,45 +99,6 @@ bool _FolderCopy(std::string source, std::string dest) closedir(dir); return true; } - -void changeOwnerForDirectory(std::string storagePath, mode_t mode) { - if (euidaccess(storagePath.c_str(), F_OK) != 0) { - if (!WrtUtilMakeDir(storagePath, mode)) { - _E("Failed to create directory : %s", storagePath.c_str()); - ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, - "Failed to create directory : " << storagePath); - } - // '5000' is default uid, gid for applications. - // So installed applications should be launched as process of uid - // '5000'. - // the process can access private directory 'data' of itself. - if (chown(storagePath.c_str(), - WEBAPP_DEFAULT_UID, - WEBAPP_DEFAULT_GID) != 0) - { - ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, - "Chown to invaild user"); - } - } else if (euidaccess(storagePath.c_str(), W_OK | R_OK | X_OK) == 0) { - _D("%s already exists.", storagePath.c_str()); - // Even if private directory already is created, private dircetory - // should change owner. - if (chown(storagePath.c_str(), - WEBAPP_DEFAULT_UID, - WEBAPP_DEFAULT_GID) != 0) - { - ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, - "Chown to invaild user"); - } - if (chmod(storagePath.c_str(), mode) != 0) { - ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, - "chmod to 0700"); - } - } else { - ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, - "No access to private storage."); - } -} } namespace Jobs { @@ -153,18 +115,12 @@ TaskFileManipulation::TaskFileManipulation(InstallerContext& context) : AddStep(&TaskFileManipulation::StepCreateDirs); if (m_context.mode.extension != InstallMode::ExtensionType::DIR) { - AddStep(&TaskFileManipulation::StepRenamePath); + AddStep(&TaskFileManipulation::StepUnzipWgtFile); AddAbortStep(&TaskFileManipulation::StepAbortRenamePath); } - AddStep(&TaskFileManipulation::StepCreatePrivateStorageDir); - AddStep(&TaskFileManipulation::StepCreateSharedFolder); - AddStep(&TaskFileManipulation::StepLinkForPreload); - } else { AddStep(&TaskFileManipulation::StepPrepareExternalDir); AddStep(&TaskFileManipulation::StepInstallToExternal); - AddStep(&TaskFileManipulation::StepCreatePrivateStorageDir); - AddStep(&TaskFileManipulation::StepCreateSharedFolder); AddAbortStep(&TaskFileManipulation::StepAbortCreateExternalDir); } @@ -201,111 +157,30 @@ void TaskFileManipulation::StepCreateDirs() "Widget Directory Created"); } -void TaskFileManipulation::StepCreatePrivateStorageDir() +void TaskFileManipulation::StepUnzipWgtFile() { - std::string storagePath = m_context.locations->getPrivateStorageDir(); - _D("Create private storage directory : %s", m_context.locations->getPrivateStorageDir().c_str()); - - changeOwnerForDirectory(storagePath, PRIVATE_STORAGE_MODE); - - if (m_context.isUpdateMode) { //update - std::string backData = m_context.locations->getBackupPrivateDir(); - _D("copy private storage %s to %s", backData.c_str(), storagePath.c_str()); - if (!DirectoryApi::DirectoryCopy(backData, storagePath)) { - _E("Failed to rename %s to %s", backData.c_str(), storagePath.c_str()); - ThrowMsg(Exceptions::BackupFailed, - "Error occurs copy private strage files"); + if (m_context.widgetConfig.packagingType != PKG_TYPE_HOSTED_WEB_APP) { + std::string instDir; + if (m_context.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) { + instDir = m_context.locations->getPackageInstallationDir(); + } else { + instDir = m_context.locations->getSourceDir(); } - } - std::string tempStoragePath = m_context.locations->getPrivateTempStorageDir(); - _D("Create temp private storage directory : %s", tempStoragePath.c_str()); - changeOwnerForDirectory(tempStoragePath, PRIVATE_STORAGE_MODE); -} - -void TaskFileManipulation::StepRenamePath() -{ - std::string instDir; + _D("unzip file to %s", instDir.c_str()); - if (m_context.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) { - instDir = m_context.locations->getPackageInstallationDir(); + WidgetUnzip wgtUnzip; + wgtUnzip.unzipWgtFile(m_context.requestedPath, instDir); } else { - instDir = m_context.locations->getSourceDir(); - } - - _D("Copy file from temp directory to %s", instDir.c_str()); - if (!WrtUtilRemove(instDir)) { - ThrowMsg(Exceptions::RemovingFolderFailure, - "Error occurs during removing existing folder"); + _D("From browser installation - unzip is not done"); } - if (!(rename(m_context.locations->getTemporaryPackageDir().c_str(), - instDir.c_str()) == 0)) - { - ThrowMsg(Exceptions::FileOperationFailed, - "Error occurs during renaming widget folder"); - } m_context.job->UpdateProgress( - InstallerContext::INSTALL_RENAME_PATH, - "Widget Rename path Finished"); -} - -void TaskFileManipulation::StepLinkForPreload() -{ - if (m_context.mode.rootPath == InstallMode::RootPath::RO) { - std::string optRes = m_context.locations->getUserDataRootDir() + - WrtDB::GlobalConfig::GetWidgetResPath(); - std::string usrRes = m_context.locations->getPackageInstallationDir() + - WrtDB::GlobalConfig::GetWidgetResPath(); - - if (0 != access(optRes.c_str(), F_OK)) { - _D("Make symbolic name for preload app %s to %s", usrRes.c_str(), optRes.c_str()); - - if (symlink(usrRes.c_str(), optRes.c_str()) != 0) - { - int error = errno; - if (error) - _E("Failed to make a symbolic name for a file [%s]", (DPL::GetErrnoString(error)).c_str()); - ThrowMsg(Exceptions::FileOperationFailed, - "Symbolic link creating is not done."); - } - } - - /* link for data directory */ - std::string storagePath = m_context.locations->getPrivateStorageDir(); - std::string dataDir = m_context.locations->getPackageInstallationDir() + - "/" + WrtDB::GlobalConfig::GetWidgetPrivateStoragePath(); - if (0 != access(dataDir.c_str(), F_OK)) { - _D("Make symbolic name for preload app %s to %s", storagePath.c_str(), dataDir.c_str()); - - if (symlink(storagePath.c_str(), dataDir.c_str()) != 0) - { - int error = errno; - if (error) - _E("Failed to make a symbolic name for a file [%s]", (DPL::GetErrnoString(error)).c_str()); - ThrowMsg(Exceptions::FileOperationFailed, - "Symbolic link creating is not done."); - } - changeOwnerForDirectory(dataDir, PRIVATE_STORAGE_MODE); - } - - if (m_context.widgetConfig.packagingType != PKG_TYPE_HYBRID_WEB_APP) { - std::string widgetBinPath = m_context.locations->getBinaryDir(); - std::string userBinPath = m_context.locations->getUserBinaryDir(); - _D("Make symbolic link for preload app %s to %s", widgetBinPath.c_str(), userBinPath.c_str()); - if (symlink(widgetBinPath.c_str(), userBinPath.c_str()) != 0) - { - int error = errno; - if (error) - _E("Failed to make a symbolic name for a file [%s]", (DPL::GetErrnoString(error)).c_str()); - ThrowMsg(Exceptions::FileOperationFailed, - "Symbolic link creating is not done."); - } - - } - } + InstallerContext::INSTALL_UNZIP_WGT, + "Unzip WGT File"); } +/* TODO : modify name */ void TaskFileManipulation::StepAbortRenamePath() { _D("[Rename Widget Path] Aborting.... (Rename path)"); @@ -404,50 +279,6 @@ void TaskFileManipulation::StepAbortCreateExternalDir() WidgetInstallToExtSingleton::Instance().deinitialize(); } -void TaskFileManipulation::StepCreateSharedFolder() -{ - _D("StepCreateSharedFolder"); - std::string sharedPath = m_context.locations->getSharedRootDir(); - _D("Create shared directory : %s", m_context.locations->getSharedRootDir().c_str()); - - WrtUtilMakeDir(sharedPath); - WrtUtilMakeDir(m_context.locations->getSharedResourceDir()); - - changeOwnerForDirectory(m_context.locations->getSharedDataDir(), - SHARED_STORAGE_MODE); - changeOwnerForDirectory(m_context.locations->getSharedTrustedDir(), - SHARED_STORAGE_MODE); - - - // additional check for rootPath installation - // If this app is preloaded, "shared" diretory is already on place and do not needs to be moved - // TODO: why "shared" is on RW partion always but "data" and "tmp" are linked - if (m_context.isUpdateMode - && !(m_context.mode.rootPath == InstallMode::RootPath::RO - && m_context.mode.installTime == InstallMode::InstallTime::PRELOAD)) { - - /* Restore /shared/data */ - _D("copy %s to %s", m_context.locations->getBackupSharedDataDir().c_str(), m_context.locations->getSharedDataDir().c_str()); - if (!DirectoryApi::DirectoryCopy( - m_context.locations->getBackupSharedDataDir(), - m_context.locations->getSharedDataDir())) { - _E("Failed to rename %s to %s", m_context.locations->getBackupSharedDataDir().c_str(), m_context.locations->getSharedDataDir().c_str()); - ThrowMsg(Exceptions::BackupFailed, - "Error occurs copy shared strage files"); - } - - /* Restore /shared/trusted */ - _D("copy %s to %s", m_context.locations->getBackupSharedTrustedDir().c_str(), m_context.locations->getSharedTrustedDir().c_str()); - if (!DirectoryApi::DirectoryCopy( - m_context.locations->getBackupSharedTrustedDir(), - m_context.locations->getSharedTrustedDir())) { - _E("Failed to rename %s to %s", m_context.locations->getBackupSharedTrustedDir().c_str(), m_context.locations->getSharedTrustedDir().c_str()); - ThrowMsg(Exceptions::BackupFailed, - "Error occurs copy shared strage files"); - } - } -} - void TaskFileManipulation::StartStep() { _D("--------- : START ----------"); diff --git a/src/jobs/widget_install/task_file_manipulation.h b/src/jobs/widget_install/task_file_manipulation.h index 24f5cf3..80d3218 100644 --- a/src/jobs/widget_install/task_file_manipulation.h +++ b/src/jobs/widget_install/task_file_manipulation.h @@ -37,12 +37,9 @@ class TaskFileManipulation : // install internal location void StepCreateDirs(); - void StepRenamePath(); - void StepCreatePrivateStorageDir(); - void StepCreateSharedFolder(); + void StepUnzipWgtFile(); void StepAbortRenamePath(); - void StepLinkForPreload(); // install external location void StepPrepareExternalDir(); diff --git a/src/jobs/widget_install/task_prepare_files.cpp b/src/jobs/widget_install/task_prepare_files.cpp index ccd8ebf..55791f4 100644 --- a/src/jobs/widget_install/task_prepare_files.cpp +++ b/src/jobs/widget_install/task_prepare_files.cpp @@ -57,7 +57,7 @@ void TaskPrepareFiles::CopyFile(const std::string& source) filename = source.substr(last + 1); } std::string target = - m_installerContext.locations->getTemporaryPackageDir() + '/' + + m_installerContext.locations->getSourceDir() + '/' + filename; _D("source %s", source.c_str()); _D("target %s", target.c_str()); diff --git a/src/jobs/widget_install/task_process_config.cpp b/src/jobs/widget_install/task_process_config.cpp index 57958eb..2c92f2c 100755 --- a/src/jobs/widget_install/task_process_config.cpp +++ b/src/jobs/widget_install/task_process_config.cpp @@ -90,7 +90,8 @@ void TaskProcessConfig::ReadLocaleFolders() m_localeFolders.insert(L""); std::string localePath = - m_installContext.locations->getConfigurationDir() + "/locales"; + m_installContext.locations->getSourceDir() + "/locales"; + DIR* localeDir = opendir(localePath.c_str()); if (!localeDir) { _D("No /locales directory in the widget package."); @@ -178,8 +179,9 @@ void TaskProcessConfig::ProcessStartFile(const DPL::OptionalString& path, DPL::String relativePath = pathPrefix + *path; DPL::String absolutePath = DPL::FromUTF8String( - m_installContext.locations->getConfigurationDir()) + L"/" + + m_installContext.locations->getSourceDir()) + L"/" + relativePath; + _D("absolutePath : %ls", absolutePath.c_str()); // get property data from packaged app if (WrtUtilFileExists(DPL::ToUTF8String(absolutePath))) { @@ -258,7 +260,7 @@ void TaskProcessConfig::ProcessBackgroundPageFile() if (!!m_installContext.widgetConfig.configInfo.backgroundPage) { // check whether file exists DPL::String backgroundPagePath = DPL::FromUTF8String( - m_installContext.locations->getConfigurationDir()) + L"/" + + m_installContext.locations->getSourceDir()) + L"/" + *m_installContext.widgetConfig.configInfo.backgroundPage; //if no then cancel installation if (!WrtUtilFileExists(DPL::ToUTF8String(backgroundPagePath))) { @@ -309,7 +311,7 @@ void TaskProcessConfig::ProcessIcon(const WrtDB::ConfigParserData::Icon& icon) DPL::String relativePath = pathPrefix + icon.src; DPL::String absolutePath = DPL::FromUTF8String( - m_installContext.locations->getConfigurationDir()) + L"/" + + m_installContext.locations->getSourceDir()) + L"/" + relativePath; if (WrtUtilFileExists(DPL::ToUTF8String(absolutePath))) { diff --git a/src/jobs/widget_install/task_user_data_manipulation.cpp b/src/jobs/widget_install/task_user_data_manipulation.cpp new file mode 100644 index 0000000..808529e --- /dev/null +++ b/src/jobs/widget_install/task_user_data_manipulation.cpp @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2011 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_user_data_manipulation.cpp + * @author Soyoung Kim (sy037.kim@samsung.com) + * @version 1.0 + * @brief Implementation file for installer task user data folder + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WEBAPP_DEFAULT_UID 5000 +#define WEBAPP_DEFAULT_GID 5000 + +namespace { +const mode_t PRIVATE_STORAGE_MODE = 0700; +const mode_t SHARED_STORAGE_MODE = 0755; +} + +using namespace WrtDB; + +namespace { +void changeOwnerForDirectory(std::string storagePath, mode_t mode) { + if (euidaccess(storagePath.c_str(), F_OK) != 0) { + if (!WrtUtilMakeDir(storagePath, mode)) { + _E("Failed to create directory : %s", storagePath.c_str()); + ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, + "Failed to create directory : " << storagePath); + } + // '5000' is default uid, gid for applications. + // So installed applications should be launched as process of uid + // '5000'. + // the process can access private directory 'data' of itself. + if (chown(storagePath.c_str(), + WEBAPP_DEFAULT_UID, + WEBAPP_DEFAULT_GID) != 0) + { + ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, + "Chown to invaild user"); + } + } else if (euidaccess(storagePath.c_str(), W_OK | R_OK | X_OK) == 0) { + _D("%s already exists.", storagePath.c_str()); + // Even if private directory already is created, private dircetory + // should change owner (recursively). + if (chown(storagePath.c_str(), + WEBAPP_DEFAULT_UID, + WEBAPP_DEFAULT_GID) != 0) + { + ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, + "Chown to invaild user"); + } + if (chmod(storagePath.c_str(), mode) != 0) { + ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, + "chmod to 0700"); + } + } else { + ThrowMsg(Jobs::WidgetInstall::Exceptions::FileOperationFailed, + "No access to private storage."); + } +} +} + +namespace Jobs { +namespace WidgetInstall { +TaskUserDataManipulation::TaskUserDataManipulation(InstallerContext& context) : + DPL::TaskDecl(this), + m_context(context) +{ + AddStep(&TaskUserDataManipulation::StartStep); + AddStep(&TaskUserDataManipulation::StepCreatePrivateStorageDir); + AddStep(&TaskUserDataManipulation::StepCreateSharedFolder); + AddStep(&TaskUserDataManipulation::StepLinkForPreload); + AddStep(&TaskUserDataManipulation::EndStep); +} + +void TaskUserDataManipulation::StepCreatePrivateStorageDir() +{ + std::string storagePath = m_context.locations->getPrivateStorageDir(); + _D("Create private storage directory : %s", m_context.locations->getPrivateStorageDir().c_str()); + + changeOwnerForDirectory(storagePath, PRIVATE_STORAGE_MODE); + + if (m_context.isUpdateMode) { //update + std::string backData = m_context.locations->getBackupPrivateDir(); + _D("copy private storage %s to %s", backData.c_str(), storagePath.c_str()); + if (!DirectoryApi::DirectoryCopy(backData, storagePath)) { + _E("Failed to rename %s to %s", backData.c_str(), storagePath.c_str()); + ThrowMsg(Exceptions::BackupFailed, + "Error occurs copy private strage files"); + } + } + + std::string tempStoragePath = m_context.locations->getPrivateTempStorageDir(); + _D("Create temp private storage directory : %s", tempStoragePath.c_str()); + changeOwnerForDirectory(tempStoragePath, PRIVATE_STORAGE_MODE); +} + +void TaskUserDataManipulation::StepLinkForPreload() +{ + if (m_context.mode.rootPath == InstallMode::RootPath::RO) { + std::string optRes = m_context.locations->getUserDataRootDir() + + WrtDB::GlobalConfig::GetWidgetResPath(); + std::string usrRes = m_context.locations->getPackageInstallationDir() + + WrtDB::GlobalConfig::GetWidgetResPath(); + + if (0 != access(optRes.c_str(), F_OK)) { + _D("Make symbolic name for preload app %s to %s", usrRes.c_str(), optRes.c_str()); + + if (symlink(usrRes.c_str(), optRes.c_str()) != 0) + { + int error = errno; + if (error) + _E("Failed to make a symbolic name for a file [%s]", (DPL::GetErrnoString(error)).c_str()); + ThrowMsg(Exceptions::FileOperationFailed, + "Symbolic link creating is not done."); + } + } + + /* link for data directory */ + std::string storagePath = m_context.locations->getPrivateStorageDir(); + std::string dataDir = m_context.locations->getPackageInstallationDir() + + "/" + WrtDB::GlobalConfig::GetWidgetPrivateStoragePath(); + if (0 != access(dataDir.c_str(), F_OK)) { + _D("Make symbolic name for preload app %s to %s", storagePath.c_str(), dataDir.c_str()); + + if (symlink(storagePath.c_str(), dataDir.c_str()) != 0) + { + int error = errno; + if (error) + _E("Failed to make a symbolic name for a file [%s]", (DPL::GetErrnoString(error)).c_str()); + ThrowMsg(Exceptions::FileOperationFailed, + "Symbolic link creating is not done."); + } + changeOwnerForDirectory(dataDir, PRIVATE_STORAGE_MODE); + } + + if (m_context.widgetConfig.packagingType != PKG_TYPE_HYBRID_WEB_APP) { + std::string widgetBinPath = m_context.locations->getBinaryDir(); + std::string userBinPath = m_context.locations->getUserBinaryDir(); + _D("Make symbolic link for preload app %s to %s", widgetBinPath.c_str(), userBinPath.c_str()); + if (symlink(widgetBinPath.c_str(), userBinPath.c_str()) != 0) + { + int error = errno; + if (error) + _E("Failed to make a symbolic name for a file [%s]", (DPL::GetErrnoString(error)).c_str()); + ThrowMsg(Exceptions::FileOperationFailed, + "Symbolic link creating is not done."); + } + + } + } +} + +void TaskUserDataManipulation::StepCreateSharedFolder() +{ + _D("StepCreateSharedFolder"); + std::string sharedPath = m_context.locations->getSharedRootDir(); + _D("Create shared directory : %s", m_context.locations->getSharedRootDir().c_str()); + + WrtUtilMakeDir(sharedPath); + WrtUtilMakeDir(m_context.locations->getSharedResourceDir()); + + changeOwnerForDirectory(m_context.locations->getSharedDataDir(), + SHARED_STORAGE_MODE); + changeOwnerForDirectory(m_context.locations->getSharedTrustedDir(), + SHARED_STORAGE_MODE); + + + // additional check for rootPath installation + // If this app is preloaded, "shared" diretory is already on place and do not needs to be moved + // TODO: why "shared" is on RW partion always but "data" and "tmp" are linked + if (m_context.isUpdateMode + && !(m_context.mode.rootPath == InstallMode::RootPath::RO + && m_context.mode.installTime == InstallMode::InstallTime::PRELOAD)) { + + /* Restore /shared/data */ + _D("copy %s to %s", m_context.locations->getBackupSharedDataDir().c_str(), m_context.locations->getSharedDataDir().c_str()); + if (!DirectoryApi::DirectoryCopy( + m_context.locations->getBackupSharedDataDir(), + m_context.locations->getSharedDataDir())) { + _E("Failed to rename %s to %s", m_context.locations->getBackupSharedDataDir().c_str(), m_context.locations->getSharedDataDir().c_str()); + ThrowMsg(Exceptions::BackupFailed, + "Error occurs copy shared strage files"); + } + + /* Restore /shared/trusted */ + _D("copy %s to %s", m_context.locations->getBackupSharedTrustedDir().c_str(), m_context.locations->getSharedTrustedDir().c_str()); + if (!DirectoryApi::DirectoryCopy( + m_context.locations->getBackupSharedTrustedDir(), + m_context.locations->getSharedTrustedDir())) { + _E("Failed to rename %s to %s", m_context.locations->getBackupSharedTrustedDir().c_str(), m_context.locations->getSharedTrustedDir().c_str()); + ThrowMsg(Exceptions::BackupFailed, + "Error occurs copy shared strage files"); + } + } +} + +void TaskUserDataManipulation::StartStep() +{ + _D("--------- : START ----------"); +} + +void TaskUserDataManipulation::EndStep() +{ + _D("--------- : END ----------"); +} +} //namespace WidgetInstall +} //namespace Jobs diff --git a/src/jobs/widget_install/task_user_data_manipulation.h b/src/jobs/widget_install/task_user_data_manipulation.h new file mode 100644 index 0000000..fbfabcc --- /dev/null +++ b/src/jobs/widget_install/task_user_data_manipulation.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 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_user_data_manipulation.cpp + * @author Soyoung Kim (sy037.kim@samsung.com) + * @version 1.0 + * @brief Implementation file for installer task user data folder + */ +#ifndef JOS_WIDGET_INSTALL_TASK_USER_DATA_MANIPULATION_H +#define JOS_WIDGET_INSTALL_TASK_USER_DATA_MANIPULATION_H + +#include + +class InstallerContext; + +namespace Jobs { +namespace WidgetInstall { +class TaskUserDataManipulation : + public DPL::TaskDecl +{ + InstallerContext& m_context; + + void StartStep(); + void EndStep(); + void StepCreatePrivateStorageDir(); + void StepCreateSharedFolder(); + void StepLinkForPreload(); + + public: + TaskUserDataManipulation(InstallerContext& context); +}; +} //namespace WidgetInstall +} //namespace Jobs + +#endif //JOS_WIDGET_INSTALL_TASK_USER_DATA_MANIPULATION_H diff --git a/src/jobs/widget_install/widget_install_context.h b/src/jobs/widget_install/widget_install_context.h index 5750cbd..e591bf3 100644 --- a/src/jobs/widget_install/widget_install_context.h +++ b/src/jobs/widget_install/widget_install_context.h @@ -52,15 +52,15 @@ struct InstallerContext INSTALL_RDS_DELTA_CHECK, INSTALL_RDS_PREPARE, + INSTALL_CREATE_BACKUP_DIR, /* For Update */ + INSTALL_DIR_CREATE, + INSTALL_UNZIP_WGT, INSTALL_WIDGET_CONFIG1, INSTALL_WIDGET_CONFIG2, INSTALL_DIGSIG_CHECK, INSTALL_CERT_CHECK, INSTALL_CERTIFY_LEVEL_CHECK, INSTALL_ECRYPTION_FILES, - INSTALL_CREATE_BACKUP_DIR, /* For Update */ - INSTALL_DIR_CREATE, - INSTALL_RENAME_PATH, INSTALL_BACKUP_ICONFILE, /* For Update */ INSTALL_COPY_ICONFILE, INSTALL_COPY_LIVEBOX_FILES, diff --git a/src/jobs/widget_install/widget_unzip.cpp b/src/jobs/widget_install/widget_unzip.cpp index 7c9e5c6..0bdaedc 100644 --- a/src/jobs/widget_install/widget_unzip.cpp +++ b/src/jobs/widget_install/widget_unzip.cpp @@ -324,9 +324,10 @@ void WidgetUnzip::checkAvailableSpace(const std::string &destination) } void WidgetUnzip::unzipConfiguration(const std::string &source, - const std::string &destination) + const std::string &destination, WrtDB::PackagingType* type) { _D("unzipConfiguration"); + Try { std::string wgtFile = getDecryptedPackage(source); _D("wgtFile : %s", wgtFile.c_str()); @@ -337,8 +338,10 @@ void WidgetUnzip::unzipConfiguration(const std::string &source, Try { configFile.reset(zipFile->OpenFile(HYBRID_CONFIG_XML)); + *type = PKG_TYPE_HYBRID_WEB_APP; } Catch(DPL::ZipInput::Exception::OpenFileFailed) { configFile.reset(zipFile->OpenFile(WEB_APP_CONFIG_XML)); + *type = PKG_TYPE_NOMAL_WEB_APP; } std::string extractPath = destination + "/" + WEB_APP_CONFIG_XML; diff --git a/src/jobs/widget_install/widget_unzip.h b/src/jobs/widget_install/widget_unzip.h index 2de8f99..df37f00 100644 --- a/src/jobs/widget_install/widget_unzip.h +++ b/src/jobs/widget_install/widget_unzip.h @@ -25,6 +25,7 @@ #include #include +#include namespace Jobs { namespace WidgetInstall { @@ -32,7 +33,8 @@ class WidgetUnzip { public: void unzipWgtFile(const std::string &source, const std::string &destination); - void unzipConfiguration(const std::string &source, const std::string &destination); + void unzipConfiguration(const std::string &source, const std::string + &destination, WrtDB::PackagingType *type); private: // Unzip state diff --git a/src/misc/widget_location.cpp b/src/misc/widget_location.cpp index 7efb4c4..182df80 100644 --- a/src/misc/widget_location.cpp +++ b/src/misc/widget_location.cpp @@ -192,25 +192,7 @@ std::string WidgetLocation::getTemporaryRootDir() const if (m_extensionType == InstallMode::ExtensionType::DIR) { return getWidgetSource() + WrtDB::GlobalConfig::GetWidgetSrcPath(); } - if (m_type == WrtDB::PKG_TYPE_HYBRID_WEB_APP) { - return getTemporaryPackageDir() + WrtDB::GlobalConfig::GetWidgetSrcPath(); - } else { - return getTemporaryPackageDir(); - } -} - -std::string WidgetLocation::getConfigurationDir() const -{ - if (m_type == WrtDB::PKG_TYPE_HOSTED_WEB_APP) { - std::string path = "."; - std::size_t index = m_widgetSource.find_last_of("\\/"); - if (index != std::string::npos) { - path = m_widgetSource.substr(0, index); - } - return path; - } else { - return getTemporaryRootDir(); - } + return getSourceDir(); } DPL::String WidgetLocation::getPkgId() const diff --git a/src/misc/widget_location.h b/src/misc/widget_location.h index 92abbbc..7208170 100644 --- a/src/misc/widget_location.h +++ b/src/misc/widget_location.h @@ -156,17 +156,6 @@ class WidgetLocation * into 'res/wgt' */ std::string getTemporaryRootDir() const; - /** - * @brief getConfigurationDir Returns rott directory for configuration - * requirements - * - * 1) For packed widgets it is just root of unpacked sources - * 2) For browser installation it is directory name of widget passed to - * installer - * - * @return configuration directory - */ - std::string getConfigurationDir() const; //icons /** -- 2.7.4