* @version 1.0
* @brief Implementation file for main installer task
*/
+#include <memory>
+
#include <dpl/noncopyable.h>
#include <dpl/abstract_waitable_input_adapter.h>
#include <dpl/abstract_waitable_output_adapter.h>
#include <dpl/zip_input.h>
-#include <dpl/scoped_ptr.h>
#include <dpl/binary_queue.h>
#include <dpl/copy.h>
#include <dpl/assert.h>
#include <dpl/sstream.h>
#include <dpl/wrt-dao-ro/common_dao_types.h>
-#include <dpl/utils/file_utils.h>
#include "root_parser.h"
#include "widget_parser.h"
#include "parser_runner.h"
#include <widget_install/task_unzip.h>
#include <widget_install/task_certify.h>
#include <widget_install/task_widget_config.h>
-#include <widget_install/task_db_update.h>
#include <widget_install/task_file_manipulation.h>
#include <widget_install/task_ace_check.h>
#include <widget_install/task_smack.h>
#include <widget_install/task_recovery.h>
#include <widget_install/task_install_ospsvc.h>
#include <widget_install/task_update_files.h>
-#include <widget_install/task_new_db_insert.h>
+#include <widget_install/task_database.h>
#include <widget_install/task_remove_backup.h>
#include <widget_install/task_encrypt_resource.h>
+#include <widget_install/task_certificates.h>
+
+#ifdef LB_SUPPORT
+#include <widget_install/task_livebox_conf.h>
+#endif
+#include <widget_install/task_plugins_copy.h>
+
#include <widget_install/widget_install_errors.h>
#include <widget_install/widget_install_context.h>
#include <string>
#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
#include <dpl/wrt-dao-ro/global_config.h>
#include <dpl/wrt-dao-rw/global_dao.h> // TODO remove
-#include <aul.h>
#include <dpl/localization/w3c_file_localization.h>
#include <libiriwrapper.h>
#include <pkg-manager/pkgmgr_signal.h>
+#include <app_manager.h>
using namespace WrtDB;
const char * const CONFIG_XML = "config.xml";
const char * const WITH_OSP_XML = "res/wgt/config.xml";
-//allowed: a-z, A-Z, 0-9, '.', '-', '_', ' '
-const char* REG_TIZENID_PATTERN = "^[-. a-zA-Z0-9_@+=]*$";
-const int RESERVED_COUNT = 20; //number of chars reserved in name (e.g. for '.desktop')
-const int MAX_TIZENID_LENTH = 255 - RESERVED_COUNT;
+//allowed: a-z, A-Z, 0-9
+const char* REG_TIZENID_PATTERN = "^[a-zA-Z0-9]{10}$";
+const int MAX_TIZENID_LENGTH = 10;
static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption";
static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable";
struct timeval tv;
gettimeofday(&tv, NULL);
srand(time(NULL) + tv.tv_usec);
- WrtDB::DbWidgetHandle handle;
- do {
- handle = rand() % INT_MAX + 1;
- LogInfo("Random widget handle: " << handle);
- } while (WidgetDAOReadOnly::isWidgetInstalled(handle));
- m_installerContext.widgetHandle = handle;
m_installerContext.m_quiet = m_jobStruct.m_quiet;
if(!browserRequest)
ConfigParserData configData = getWidgetDataFromXML(widgetPath, browserRequest,
m_installerContext.widgetConfig.pType);
WidgetUpdateInfo update = detectWidgetUpdate(configData);
-
bool needEncryption = detectResourceEncryption(configData);
-
// Configure installation
- ConfigureResult result = ConfigureInstallation(widgetPath, update);
- if (!setTizenId(configData)) {
- result = ConfigureResult::Failed;
- } else {
- using namespace PackageManager;
- LogInfo("WidgetHandle: " << m_installerContext.widgetHandle);
- LogInfo("Tizen Id: " << m_installerContext.widgetConfig.pkgname);
-
- configureWidgetLocation(widgetPath, browserRequest);
+ ConfigureResult result = ConfigureInstallation(widgetPath, configData,
+ update, browserRequest);
- // send start signal of pkgmgr
- PkgmgrSignalSingleton::Instance().setPkgname(
- DPL::ToUTF8String(
- *m_installerContext.widgetConfig.pkgname));
- PkgmgrSignalSingleton::Instance().sendSignal(
- PKGMGR_START_KEY,
- PKGMGR_START_INSTALL);
- }
if (result == ConfigureResult::Ok) {
LogInfo("Configure installation succeeded");
if (needEncryption) {
AddTask(new TaskEncryptResource(m_installerContext));
}
- AddTask(new TaskDbUpdate(m_installerContext));
AddTask(new TaskFileManipulation(m_installerContext));
// TODO: Update progress information for this task
AddTask(new TaskPrivateStorage(m_installerContext));
- AddTask(new TaskAceCheck(m_installerContext));
+
//This is sort of quick solution, because ACE verdicts are based upon
//data from DAO (DB). So AceCheck for now has to be AFTER DbUpdate
//task.
AddTask(new TaskSmack(m_installerContext));
AddTask(new TaskManifestFile(m_installerContext));
+ AddTask(new TaskCertificates(m_installerContext));
if (m_installerContext.widgetConfig.pType ==
PKG_TYPE_TIZEN_WITHSVCAPP) {
AddTask(new TaskInstallOspsvc(m_installerContext));
}
+#ifdef LB_SUPPORT
+ AddTask(new TaskLiveboxConf(m_installerContext));
+#endif
+ AddTask(new TaskPluginsCopy(m_installerContext));
+
+ AddTask(new TaskDatabase(m_installerContext));
+ AddTask(new TaskAceCheck(m_installerContext));
} else if (result == ConfigureResult::Updated) {
LogInfo("Configure installation updated");
LogInfo("Widget Update");
AddTask(new TaskCertify(m_installerContext));
AddTask(new TaskUpdateFiles(m_installerContext));
- AddTask(new TaskNewDbInsert(m_installerContext));
/* TODO : To backup file, save md5 values */
- AddTask(new TaskAceCheck(m_installerContext));
AddTask(new TaskSmack(m_installerContext));
AddTask(new TaskManifestFile(m_installerContext));
- AddTask(new TaskRemoveBackupFiles(m_installerContext));
if (m_installerContext.widgetConfig.pType ==
PKG_TYPE_TIZEN_WITHSVCAPP) {
AddTask(new TaskInstallOspsvc(m_installerContext));
}
+ AddTask(new TaskRemoveBackupFiles(m_installerContext));
+#ifdef LB_SUPPORT
+ AddTask(new TaskLiveboxConf(m_installerContext));
+#endif
+ AddTask(new TaskPluginsCopy(m_installerContext));
+
+ AddTask(new TaskDatabase(m_installerContext));
+
+ AddTask(new TaskAceCheck(m_installerContext));
+ //TODO: remove widgetHandle from this task and move before database task
+ // by now widget handle is needed in ace check
+ // Any error in acecheck while update will break widget
+
} else if (result == ConfigureResult::Deferred) {
// Installation is deferred
LogInfo("Configure installation deferred");
}
}
+std::string JobWidgetInstall::generateTizenId() {
+ std::string allowed("0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz");
+ std::string tizenId;
+ tizenId.resize(MAX_TIZENID_LENGTH);
+ for (int i = 0; i < MAX_TIZENID_LENGTH; ++i) {
+ tizenId[i] = allowed[rand() % allowed.length()];
+ }
+ return tizenId;
+}
+
bool JobWidgetInstall::setTizenId(
- const WrtDB::ConfigParserData &configInfo)
+ const WrtDB::ConfigParserData &configInfo, ConfigureResult result)
{
- Assert(!!m_installerContext.widgetHandle
- && "Widget Handle should be initialized");
-
regex_t reg;
- regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB);
+ regcomp(®, REG_TIZENID_PATTERN, REG_NOSUB | REG_EXTENDED);
struct stat dirStat;
if(!!configInfo.tizenId) {
- LogDebug("Setting tizenId provided in config.xml");
+ LogDebug("Setting tizenId provided in config.xml: " << configInfo.tizenId);
if ((regexec(®, DPL::ToUTF8String(*(configInfo.tizenId)).c_str(),
- static_cast<size_t>(0), NULL, 0) != 0) ||
- (DPL::ToUTF8String(*(configInfo.tizenId)).size() > MAX_TIZENID_LENTH) ||
- (stat((std::string(GlobalConfig::GetUserInstalledWidgetPath()) + "/"
- + DPL::ToUTF8String(*(configInfo.tizenId))).c_str(), &dirStat) == 0))
+ static_cast<size_t>(0), NULL, 0) != REG_NOERROR) ||
+ ((stat((std::string(GlobalConfig::GetUserInstalledWidgetPath()) + "/"
+ + DPL::ToUTF8String(*(configInfo.tizenId))).c_str(), &dirStat) == 0)
+ && result != ConfigureResult::Updated))
{
//it is true when tizenId does not fit REG_TIZENID_PATTERN
- LogError("pkgName provided but not proper.");
+ LogError("tizen_id provided but not proper.");
regfree(®);
return false;
}
m_installerContext.widgetConfig.pkgname = configInfo.tizenId;
} else {
- LogInfo("package name is generated by WRT");
- // tizen id should be generated by secure random algorithm
- std::string pkgName = WrtDB::GlobalConfig::GetPkgnamePrefix();
-
- bool named = false;
- FOREACH(it, configInfo.localizedDataSet)
- {
- if (!!((it->second).name)) {
- //there is a name provided
- std::string name = DPL::ToUTF8String(*(it->second).name);
- //cut very long widget's name
- name = name.substr(0, MAX_TIZENID_LENTH - strlen(
- WrtDB::GlobalConfig::GetPkgnamePrefix()));
- //check name if all characters are supported by filesystem
- if (regexec(®, name.c_str(), static_cast<size_t>(0), NULL, 0)
- == 0)
- {
- //WidgetName is ok and can be used as package name
- //replace all spaces with '_'
- size_t pos = 0;
- while((pos = name.find(" ", pos)) != std::string::npos) {
- name.replace(pos, 1, "_");
- ++pos;
- }
- pkgName += name;
- named = true;
+ std::string tizenId = generateTizenId();
+
+ // only for installation, not for update
+ if (result == ConfigureResult::Ok) {
+ //check if there is package with same name and if generate different name
+ std::string path = GlobalConfig::GetUserInstalledWidgetPath();
+ path += "/";
+
+ std::ostringstream newPath;
+ newPath << path << tizenId;
+
+ LogDebug("Checking if tizen id is unique");
+ while (true) {
+ if (stat(newPath.str().c_str(), &dirStat) == 0) {
+ //path exist, chose another one
+ tizenId = generateTizenId();
+ newPath.str("");
+ newPath << path << tizenId;
+ continue;
}
break;
}
- }
- if (!named) // there is no widget name provided, use widgetHandle
- {
- pkgName += std::to_string(*(m_installerContext.widgetHandle));
+ m_installerContext.widgetConfig.pkgname =
+ DPL::FromUTF8String(tizenId);
}
-
- //check if there is package with same name and if generate different name
- std::string path = GlobalConfig::GetUserInstalledWidgetPath();
- path += "/";
-
- std::ostringstream newPath;
- newPath << path << pkgName;
-
- std::string suffix;
- for (int i = 0;; ++i) {
- if (stat(newPath.str().c_str(), &dirStat) == 0) {
- //path exist, chose another one, eg. widgetName1
- suffix = std::to_string(i + 1);
- pkgName = pkgName.substr(
- 0, MAX_TIZENID_LENTH - suffix.size());
- newPath.str("");
- newPath << path << pkgName << suffix;
- continue;
- }
- pkgName += suffix;
- break;
- }
-
- m_installerContext.widgetConfig.pkgname =
- DPL::FromUTF8String(pkgName);
-
+ LogInfo("tizen_id name was generated by WRT: " << tizenId);
}
regfree(®);
return true;
}
-DPL::Optional<WidgetHandle> JobWidgetInstall::getNewWidgetHandle() const
+DPL::OptionalString JobWidgetInstall::getNewTizenId() const
{
- return m_installerContext.widgetHandle;
+ return m_installerContext.widgetConfig.pkgname;
}
void JobWidgetInstall::configureWidgetLocation(const std::string & widgetPath, bool browserRequest)
{
- Try
- {
- m_installerContext.locations = WidgetLocation(DPL::ToUTF8String(*m_installerContext.widgetConfig.pkgname),
- widgetPath, browserRequest, m_installerContext.widgetConfig.pType);
- }
- Catch(FileUtils::CreateDirectoryException)
- {
- LogError("Failed to create temporary path for widget");
- ReThrowMsg(FileUtils::CreateDirectoryException, "Failed to create temporary path for widget");
- }
+ m_installerContext.locations = WidgetLocation(DPL::ToUTF8String(*m_installerContext.widgetConfig.pkgname),
+ widgetPath, browserRequest, m_installerContext.widgetConfig.pType);
LogInfo("widgetSource " << widgetPath);
}
JobWidgetInstall::ConfigureResult JobWidgetInstall::ConfigureInstallation(
const std::string &widgetSource,
- const WidgetUpdateInfo &update)
+ const WrtDB::ConfigParserData &configData,
+ const WidgetUpdateInfo &update,
+ bool browserRequest)
{
LogInfo(
"Widget install/update: incoming guid = '" <<
// Check policy
WidgetUpdateMode::Type updateTypeCheckBit;
+ JobWidgetInstall::ConfigureResult ret = ConfigureResult::Ok;
if (update.existingWidgetInfo.isExist == false) {
LogInfo("Widget info does not exist");
updateTypeCheckBit = WidgetUpdateMode::NotInstalled;
} else {
- LogInfo("Widget info exists. Handle: " <<
- update.existingWidgetInfo.existingHandle);
+ LogInfo("Widget info exists. PkgName: " <<
+ update.existingWidgetInfo.pkgname);
- DPL::OptionalString pkgname =
- WidgetDAOReadOnly(update.existingWidgetInfo.existingHandle).getPkgname();
+ DPL::OptionalString pkgname = update.existingWidgetInfo.pkgname;
if(pkgname.IsNull()) {
LogInfo("But package name doesn't exist");
}
LogInfo("Widget model exists. package name: " << pkgname);
- if (aul_app_is_running(DPL::ToUTF8String(*pkgname).c_str())) {
+
+ // Check running state
+ int retval = APP_MANAGER_ERROR_NONE;
+ bool isRunning = false;
+ retval = app_manager_is_running(DPL::ToUTF8String(*pkgname).c_str(), &isRunning);
+ if (APP_MANAGER_ERROR_NONE != retval) {
+ LogError("Fail to get running state");
+ return ConfigureResult::Failed;
+ }
+
+ if (true == isRunning) {
// Must be deferred when update in progress
if (m_jobStruct.updateMode == WidgetUpdateMode::PolicyWac) {
LogInfo(
updateTypeCheckBit = CalcWidgetUpdatePolicy(existingVersion,
incomingVersion);
+ // Calc proceed flag
+ if ((m_jobStruct.updateMode & updateTypeCheckBit) > 0) {
+ LogInfo("Whether widget policy allow proceed ok");
+ ret = ConfigureResult::Updated;
+ }
+ else
+ return ConfigureResult::Failed;
}
- // Calc proceed flag
- bool canProceed = (m_jobStruct.updateMode & updateTypeCheckBit) > 0;
+ if (!setTizenId(configData, ret)) {
+ return ConfigureResult::Failed;
+ } else {
+ using namespace PackageManager;
+ LogInfo("Tizen Id: " << m_installerContext.widgetConfig.pkgname);
- LogInfo("Whether widget policy allow proceed: " << canProceed);
+ configureWidgetLocation(widgetSource, browserRequest);
+
+ // send start signal of pkgmgr
+ PkgmgrSignalSingleton::Instance().setPkgname(
+ DPL::ToUTF8String(
+ *m_installerContext.widgetConfig.pkgname));
+ PkgmgrSignalSingleton::Instance().sendSignal(
+ PKGMGR_START_KEY,
+ PKGMGR_START_INSTALL);
+ }
// Init installer context
m_installerContext.installStep = InstallerContext::INSTALL_START;
m_installerContext.existingWidgetInfo = update.existingWidgetInfo;
m_installerContext.widgetConfig.shareHref = std::string();
- if (m_installerContext.existingWidgetInfo.isExist) {
- return canProceed ? ConfigureResult::Updated : ConfigureResult::Failed;
- }
-
// Return result
- return canProceed ? ConfigureResult::Ok : ConfigureResult::Failed;
+ return ret;
}
WidgetUpdateMode::Type JobWidgetInstall::CalcWidgetUpdatePolicy(
}
else {
// Open zip file
- DPL::ScopedPtr<DPL::ZipInput> zipFile(
+ std::unique_ptr<DPL::ZipInput> zipFile(
new DPL::ZipInput(widgetSource));
- DPL::ScopedPtr<DPL::ZipInput::File> configFile;
+ std::unique_ptr<DPL::ZipInput::File> configFile;
// Open config.xml file
if (isOspsvc == PKG_TYPE_TIZEN_WITHSVCAPP) {
- configFile.Reset(zipFile->OpenFile(WITH_OSP_XML));
+ configFile.reset(zipFile->OpenFile(WITH_OSP_XML));
} else {
- configFile.Reset(zipFile->OpenFile(CONFIG_XML));
+ configFile.reset(zipFile->OpenFile(CONFIG_XML));
}
// Extract config
DPL::BinaryQueue buffer;
- DPL::AbstractWaitableInputAdapter inputAdapter(configFile.Get());
+ DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
DPL::Copy(&inputAdapter, &outputAdapter);
parser.Parse(&buffer,
}
Catch(DPL::ZipInput::Exception::OpenFailed)
{
- LogDebug("Failed to open widget package");
+ LogError("Failed to open widget package");
return ConfigParserData();
}
Catch(DPL::ZipInput::Exception::OpenFileFailed)
{
- LogDebug("Failed to open config.xml file");
+ LogError("Failed to open config.xml file");
return ConfigParserData();
}
Catch(DPL::CopyFailed)
{
- LogDebug("Failed to extract config.xml file");
+ LogError("Failed to extract config.xml file");
return ConfigParserData();
}
Catch(ElementParser::Exception::ParseError)
{
- LogDebug("Failed to parse config.xml file");
+ LogError("Failed to parse config.xml file");
return ConfigParserData();
}
}
widgetGUID = configInfo.widget_id;
if (widgetGUID.IsNull()) {
- LogDebug("Installed widget has no GUID");
+ LogWarning("Installed widget has no GUID");
return WidgetUpdateInfo();
}
widgetGUID,
widgetVersion,
WidgetUpdateInfo::ExistingWidgetInfo(
- dao.getHandle(), dao.getVersion()));
+ *dao.getPkgname(), dao.getVersion()));
}
Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
{
//inform widget info
JobWidgetInstall::displayWidgetInfo();
- DPL::Optional<WidgetHandle> handle = getNewWidgetHandle();
+ DPL::OptionalString tizenId = getNewTizenId();
// send signal of pkgmgr
PkgmgrSignalSingleton::Instance().sendSignal(
LogDebug("Call widget install successfinishedCallback");
getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
- !!handle ? *handle : WrtDB::INVALID_WIDGET_HANDLE, Exceptions::Success);
+ tizenId.IsNull() ? "" : DPL::ToUTF8String(*tizenId), Exceptions::Success);
}
void JobWidgetInstall::SendFinishedFailure()
LogError("Error in installation step: " << m_exceptionCaught);
LogError("Message: " << m_exceptionMessage);
- DPL::Optional<WidgetHandle> handle = getNewWidgetHandle();
+ DPL::OptionalString tizenId = getNewTizenId();
LogDebug("Call widget install failure finishedCallback");
PKGMGR_END_FAILURE);
getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
- !!handle ? *handle : WrtDB::INVALID_WIDGET_HANDLE, m_exceptionCaught);
+ tizenId.IsNull() ? "" : DPL::ToUTF8String(*tizenId), m_exceptionCaught);
}
void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
void JobWidgetInstall::displayWidgetInfo()
{
- DPL::Optional<WidgetHandle> handle = getNewWidgetHandle();
- Assert(!!handle);
-
- WidgetDAOReadOnly dao(*handle);
+ WidgetDAOReadOnly dao(m_installerContext.locations->getPkgname());
std::ostringstream out;
WidgetLocalizedInfo localizedInfo =
- W3CFileLocalization::getLocalizedInfo(*handle);
+ W3CFileLocalization::getLocalizedInfo(dao.getHandle()); //TODO: pkgname arg
out << std::endl <<
"===================================== INSTALLED WIDGET INFO ========="\
out << std::endl << "Width: " << size.width;
out << std::endl << "Height: " << size.height;
out << std::endl << "Start File: " <<
- W3CFileLocalization::getStartFile(*handle);
+ W3CFileLocalization::getStartFile(dao.getHandle()); //TODO: pkgname arg
out << std::endl << "Version: " << dao.getVersion();
out << std::endl << "Licence: " <<
localizedInfo.license;
dao.isDistributorSigned();
out << std::endl << "Widget trusted: " << dao.isTrusted();
- OptionalWidgetIcon icon = W3CFileLocalization::getIcon(*handle);
+ OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getHandle()); //TODO: pkgname arg
DPL::OptionalString iconSrc =
!!icon ? icon->src : DPL::OptionalString::Null;
out << std::endl << "Icon: " << iconSrc;
using namespace WrtDB;
PackagingType pType = PKG_TYPE_UNKNOWN;
- DPL::ScopedPtr<DPL::ZipInput> zipFile;
+ std::unique_ptr<DPL::ZipInput> zipFile;
Try
{
// Open zip file
- zipFile.Reset(new DPL::ZipInput(widgetSource));
+ zipFile.reset(new DPL::ZipInput(widgetSource));
}
Catch(DPL::ZipInput::Exception::OpenFailed)
{
- LogDebug("Failed to open widget package");
+ LogError("Failed to open widget package");
return PKG_TYPE_UNKNOWN;
}
Try
{
// Open config.xml file in package root
- DPL::ScopedPtr<DPL::ZipInput::File> configFile(
+ std::unique_ptr<DPL::ZipInput::File> configFile(
zipFile->OpenFile(CONFIG_XML));
pType = PKG_TYPE_TIZEN_WEBAPP;
}
Catch(DPL::ZipInput::Exception::OpenFileFailed)
{
- LogDebug("Could not find config.xml");
+ LogWarning("Could not find ./config.xml");
}
Try
{
// Open config.xml file in package root
- DPL::ScopedPtr<DPL::ZipInput::File> configFile(
+ std::unique_ptr<DPL::ZipInput::File> configFile(
zipFile->OpenFile(WITH_OSP_XML));
if (pType == PKG_TYPE_TIZEN_WEBAPP) {
+ LogWarning("Two config.xml's found. Application type is unknown.");
return PKG_TYPE_UNKNOWN;
}
}
Catch(DPL::ZipInput::Exception::OpenFileFailed)
{
- LogDebug("Could not find wgt/config.xml");
- return PKG_TYPE_UNKNOWN;
+ LogWarning("Could not find ./res/wgt/config.xml");
}
+ if (pType == PKG_TYPE_UNKNOWN) {
+ LogWarning("config.xml not found. Application type is unknown.");
+ }
return pType;
}