#include <cstdio>
#include <time.h>
#include <sys/stat.h>
+#include <sqlite3.h>
+#include <db-util.h>
#include <widget_install/task_database.h>
-#include <widget_install/job_widget_install.h>
#include <widget_install/widget_install_errors.h>
#include <widget_install/widget_install_context.h>
-#ifdef DBOX_ENABLED
-#include <web_provider_livebox_info.h>
+#if USE(WEB_PROVIDER)
+#include <web_provider_widget_info.h>
#endif
#include <dpl/wrt-dao-rw/widget_dao.h>
+#include <dpl/log/log.h>
#include <dpl/foreach.h>
-#include <dpl/utils/wrt_utility.h>
#include <dpl/assert.h>
+#include <dpl/platform.h>
#include <wrt-commons/security-origin-dao/security_origin_dao.h>
#include <wrt-commons/widget-interface-dao/widget_interface_dao.h>
#include <dpl/wrt-dao-ro/global_config.h>
#include <dpl/wrt-dao-ro/widget_dao_types.h>
+#include <dpl/wrt-dao-ro/WrtDatabase.h>
#include <string>
#include <sstream>
-#include <ace_api_install.h>
-#include <ace_registration.h>
#include <errno.h>
#include <string.h>
#include <map>
-#include <installer_log.h>
+#include <boost/filesystem.hpp>
+#include <dpl/log/secure_log.h>
using namespace WrtDB;
+namespace bf = boost::filesystem;
namespace Jobs {
namespace WidgetInstall {
-TaskDatabase::TaskDatabase(InstallerContext& context) :
+TaskDatabase::TaskDatabase(JobWidgetInstall * const &jobContext) :
DPL::TaskDecl<TaskDatabase>(this),
- m_context(context)
+ m_jobContext(jobContext)
{
AddStep(&TaskDatabase::StartStep);
AddStep(&TaskDatabase::StepRegisterExternalFiles);
AddStep(&TaskDatabase::StepWrtDBInsert);
- AddStep(&TaskDatabase::StepAceDBInsert);
AddStep(&TaskDatabase::StepSecurityOriginDBInsert);
AddStep(&TaskDatabase::StepWidgetInterfaceDBInsert);
AddStep(&TaskDatabase::StepRemoveExternalFiles);
-#ifdef DBOX_ENABLED
+#if USE(WEB_PROVIDER)
AddStep(&TaskDatabase::StepLiveboxDBInsert);
#endif
AddStep(&TaskDatabase::EndStep);
AddAbortStep(&TaskDatabase::StepAbortDBInsert);
- AddAbortStep(&TaskDatabase::StepAbortAceDBInsert);
AddAbortStep(&TaskDatabase::StepAbortWidgetInterfaceDBInsert);
}
+namespace {
+const char *KEY_WIDGET_ARG = "widget_arg";
+const char* const DATABASE_JOURNAL_FILENAME = "-journal";
+
+const int APP_UID = 5000;
+const int APP_GUID = 5000;
+} // anonymous namespace
+
void TaskDatabase::StepWrtDBInsert()
{
Try
{
/* Set install Time */
- time(&m_context.widgetConfig.installedTime);
+ time(&m_jobContext->m_installerContext.widgetConfig.installedTime);
- if (m_context.isUpdateMode) { //update
+ if (m_jobContext->m_installerContext.isUpdateMode) { //update
_D("Registering widget... (update)");
Try
{
- std::list<TizenAppId> idList = WidgetDAOReadOnly::getTzAppIdList(m_context.widgetConfig.tzPkgid);
- FOREACH(it , idList ){
+ std::list<TizenAppId> idList = WidgetDAOReadOnly::getTzAppIdList(m_jobContext->m_installerContext.widgetConfig.tzPkgid);
+ FOREACH(it , idList) {
//installed AppId list, It need to delete ACE Database corresponding record
m_handleToRemoveList.push_back(WidgetDAOReadOnly::getHandle(*it));
WrtDB::TizenAppId backAppId = *it + L".backup";
m_backAppIdList.push_back(backAppId);
//Change all installed tzAppid to .backup
WidgetDAO::updateTizenAppId(*it, backAppId);
- }
-
- WidgetDAO::registerWidget(m_context.widgetConfig.tzAppid,
- m_context.widgetConfig,
- m_context.widgetSecurity);
- m_handleList.push_back(WidgetDAOReadOnly::getHandle(m_context.widgetConfig.tzAppid));
+ }
- FOREACH(iterator, m_context.widgetConfig.configInfo.serviceAppInfoList) {
+ WidgetDAO::registerWidget(m_jobContext->m_installerContext.widgetConfig.tzAppid,
+ m_jobContext->m_installerContext.widgetConfig,
+ m_jobContext->m_installerContext.widgetSecurity);
+ m_handleList.push_back(WidgetDAOReadOnly::getHandle(m_jobContext->m_installerContext.widgetConfig.tzAppid));
+
+ FOREACH(iterator, m_jobContext->m_installerContext.widgetConfig.configInfo.serviceAppInfoList) {
WrtDB::TizenAppId tizenAppId = iterator->serviceId;
- WidgetDAO::registerService(*iterator, m_context.widgetConfig, m_context.widgetSecurity);
+ WidgetDAO::registerService(*iterator, m_jobContext->m_installerContext.widgetConfig, m_jobContext->m_installerContext.widgetSecurity);
m_handleList.push_back(WidgetDAOReadOnly::getHandle(tizenAppId));
}
}
Catch(WidgetDAOReadOnly::Exception::WidgetNotExist)
{
- LogError(
- "Given tizenId not found for update installation (Same GUID?)");
+ _E("Given tizenId not found for update installation (Same GUID?)");
ThrowMsg(Exceptions::DatabaseFailure,
"Given tizenId not found for update installation");
}
} else { //new installation
_D("Registering widget...");
WidgetDAO::registerWidget(
- m_context.widgetConfig.tzAppid,
- m_context.widgetConfig,
- m_context.widgetSecurity);
+ m_jobContext->m_installerContext.widgetConfig.tzAppid,
+ m_jobContext->m_installerContext.widgetConfig,
+ m_jobContext->m_installerContext.widgetSecurity);
- m_handleList.push_back(WidgetDAOReadOnly::getHandle(m_context.widgetConfig.tzAppid));
+ m_handleList.push_back(WidgetDAOReadOnly::getHandle(m_jobContext->m_installerContext.widgetConfig.tzAppid));
- FOREACH(iterator, m_context.widgetConfig.configInfo.serviceAppInfoList) {
- WidgetDAO::registerService(*iterator, m_context.widgetConfig, m_context.widgetSecurity);
+ FOREACH(iterator, m_jobContext->m_installerContext.widgetConfig.configInfo.serviceAppInfoList) {
+ WidgetDAO::registerService(*iterator, m_jobContext->m_installerContext.widgetConfig, m_jobContext->m_installerContext.widgetSecurity);
m_handleList.push_back(WidgetDAOReadOnly::getHandle(iterator->serviceId));
}
}
- FOREACH(cap, m_context.staticPermittedDevCaps) {
- _D("staticPermittedDevCaps : %ls smack status: %d", cap->first.c_str(), cap->second);
- }
-
_D("Widget registered");
}
Catch(WidgetDAO::Exception::DatabaseError)
}
}
-void TaskDatabase::StepAceDBInsert()
-{
- FOREACH(iterHandleToRemove, m_handleToRemoveList)
- {
- if (INVALID_WIDGET_HANDLE != *iterHandleToRemove) {
- _D("Removing old insallation. Handle: %d", *iterHandleToRemove);
- if (ACE_OK != ace_unregister_widget(
- static_cast<ace_widget_handle_t>(*iterHandleToRemove)))
- {
- _W("Error while removing ace entry for previous insallation");
- }
- }
- }
-
- FOREACH(iterHandle, m_handleList)
- {
- if (!AceApi::registerAceWidget(*iterHandle, m_context.widgetConfig,
- m_context.widgetSecurity.getCertificateList()))
- {
- _E("ace database insert failed");
- ThrowMsg(Exceptions::UpdateFailed,
- "Update failure. ace_register_widget failed");
- }
- _D("Ace data inserted");
- }
-}
-
void TaskDatabase::StepSecurityOriginDBInsert()
{
_D("Create Security origin database");
using namespace SecurityOriginDB;
using namespace WrtDB;
- try{
- SecurityOriginDAO dao(m_context.locations->getPkgId());
+ try {
+ SecurityOriginDAO dao(m_jobContext->m_installerContext.locations->getPkgId());
+#ifdef DEVICE_PROFILE_MOBILE
+ DPL::OptionalString minVersion = m_jobContext->m_installerContext.widgetConfig.minVersion;
+ std::string version;
+ if (!minVersion || minVersion->empty()) {
+ ThrowMsg(Exceptions::UpdateFailed, "required_version is mandatory");
+ } else {
+ version = DPL::ToUTF8String(*minVersion);
+ }
+ double requiredVersion = atof(version.c_str());
+#endif
// Checking privilege list for setting security origin exception data
- FOREACH(it, m_context.widgetConfig.configInfo.privilegeList) {
+ FOREACH(it, m_jobContext->m_installerContext.widgetConfig.configInfo.privilegeList) {
std::map<std::string, Feature>::const_iterator result =
g_W3CPrivilegeTextMap.find(DPL::ToUTF8String(it->name));
if (result != g_W3CPrivilegeTextMap.end()) {
- if (result->second == FEATURE_USER_MEDIA) {
+#ifdef DEVICE_PROFILE_MOBILE
+ if (result->second == FEATURE_USER_MEDIA && requiredVersion < 2.3) {
dao.setPrivilegeSecurityOriginData(result->second, false);
} else if (result->second == FEATURE_FULLSCREEN_MODE) {
continue;
} else {
dao.setPrivilegeSecurityOriginData(result->second);
}
+#endif
+#ifdef DEVICE_PROFILE_WEARABLE
+ if (result->second == FEATURE_FULLSCREEN_MODE) {
+ continue;
+ }
+#endif
}
}
- }catch(const SecurityOriginDAO::Exception::DatabaseError& err){
+ } catch(const SecurityOriginDAO::Exception::DatabaseError& err){
_E("error open SecurityOrigin db %s", err.GetMessage().c_str());
ThrowMsg(Exceptions::UpdateFailed, "Cannot open SecurityOrigin DB");
}
}
+static bool closeDatabase(sqlite3* dbHandle)
+{
+ if (DB_UTIL_OK != db_util_close(dbHandle)) {
+ _E("Failed to close widget interface database");
+ return false;
+ }
+ return true;
+}
+static void copyPropertiesFromWrtDatabase(DbWidgetHandle handle)
+{
+ WrtDB::WrtDatabase::attachToThreadRO();
+ WidgetInterfaceDB::WidgetInterfaceDAO dao(handle);
+ Try{
+ WrtDB::PropertyDAOReadOnly::WidgetPreferenceList existing =
+ WrtDB::PropertyDAOReadOnly::GetPropertyList(
+ WrtDB::WidgetDAOReadOnly::getTizenAppId(handle)
+ );
+
+ for (auto prop: existing) {
+ std::string key = DPL::ToUTF8String(prop.key_name);
+ if (key != KEY_WIDGET_ARG) {
+ std::string value;
+ if (!!prop.key_value) {
+ value = DPL::ToUTF8String(*(prop.key_value));
+ }
+ bool readonly = !!prop.readonly && (*prop.readonly);
+ dao.setItem(key, value, readonly, true);
+ }
+ }
+ } Catch(WrtDB::WidgetDAOReadOnly::Exception::DatabaseError) {
+ ReThrowMsg(WidgetInterfaceDB::WidgetInterfaceDAO::Exception::DatabaseError, "Cannot copy properties read from config.xml");
+ }
+ WrtDB::WrtDatabase::detachFromThread();
+}
+
void TaskDatabase::StepWidgetInterfaceDBInsert()
{
_D("Create Widget Interface database");
using namespace WrtDB;
DbWidgetHandle handle =
- WidgetDAOReadOnly::getHandle(m_context.widgetConfig.tzAppid);
+ WidgetDAOReadOnly::getHandle(m_jobContext->m_installerContext.widgetConfig.tzAppid);
+
+ std::string dbPath = WidgetInterfaceDAO::databaseFileName(handle);
// backup database
- if (m_context.isUpdateMode) {
- std::string dbPath = WidgetInterfaceDAO::databaseFileName(handle);
+ if (m_jobContext->m_installerContext.isUpdateMode) {
std::string backupDbPath = dbPath;
backupDbPath += GlobalConfig::GetBackupDatabaseSuffix();
_D("\"%s\" to \"%s\"", dbPath.c_str(), backupDbPath.c_str());
Try
{
- // automatically create widget interface database
- WidgetInterfaceDAO dao(handle);
+ // Create widget interface database
+ _D("Creating database. %s", dbPath.c_str());
+ sqlite3 *dbHandle;
+ // Open & Exec query
+ if (DB_UTIL_OK != db_util_open_with_options(dbPath.c_str(), &dbHandle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)) {
+ ThrowMsg(WidgetInterfaceDAO::Exception::DatabaseError, "widget interface database create failed");
+ }
+
+ char* error = NULL;
+ int ret = sqlite3_exec(dbHandle,
+ "create table Properties(key TEXT NOT NULL, value TEXT DEFAULT '' NOT NULL, readonly INTEGER check(readonly between 0 and 1) DEFAULT 0, configxml INTEGER check(readonly between 0 and 1) DEFAULT 0, UNIQUE (key))",
+ NULL,
+ NULL,
+ &error);
+ if (SQLITE_OK != ret) {
+ _E("Cannot exec query. %s", error);
+ closeDatabase(dbHandle);
+ ThrowMsg(WidgetInterfaceDAO::Exception::DatabaseError, "Cannot execute query");
+ }
+
+ if (!closeDatabase(dbHandle)){
+ _E("widget interface database create failed");
+ ThrowMsg(WidgetInterfaceDAO::Exception::DatabaseError, "Cannot close db");
+ }
+
+ // Copy widget interface data from .wrt.db
+ copyPropertiesFromWrtDatabase(handle);
+
+ // Change owner & permission
+ if(chown(dbPath.c_str(), APP_UID, APP_GUID) != 0) {
+ ThrowMsg(WidgetInterfaceDAO::Exception::DatabaseError, "Fail to change uid/guid");
+ }
+ std::string databaseJournal = dbPath + DATABASE_JOURNAL_FILENAME;
+ if(chown(databaseJournal.c_str(), APP_UID, APP_GUID) != 0) {
+ ThrowMsg(WidgetInterfaceDAO::Exception::DatabaseError, "Fail to change uid/guid");
+ }
}
Catch(WidgetInterfaceDAO::Exception::DatabaseError)
{
void TaskDatabase::StepRegisterExternalFiles()
{
WrtDB::ExternalLocationList externalLocationsUpdate =
- m_context.locations->listExternalLocations();
- if (m_context.isUpdateMode) { //update
+ m_jobContext->m_installerContext.locations->listExternalLocations();
+ if (m_jobContext->m_installerContext.isUpdateMode) { //update
Try
{
- WidgetDAOReadOnly dao(WidgetDAOReadOnly::getHandleByPkgId(m_context.widgetConfig.tzPkgid));
+ WidgetDAOReadOnly dao(WidgetDAOReadOnly::getHandleByPkgId(m_jobContext->m_installerContext.widgetConfig.tzPkgid));
WrtDB::ExternalLocationList externalLocationsDB =
dao.getWidgetExternalLocations();
FOREACH(file, externalLocationsDB)
}
//set external locations to be registered
- m_context.widgetConfig.externalLocations = externalLocationsUpdate;
+ m_jobContext->m_installerContext.widgetConfig.externalLocations = externalLocationsUpdate;
}
void TaskDatabase::StepRemoveExternalFiles()
FOREACH(file, m_externalLocationsToRemove)
{
- if (WrtUtilFileExists(*file)) {
- _D(" -> %s", (*file).c_str());
- if (-1 == remove(file->c_str())) {
- ThrowMsg(Exceptions::RemovingFileFailure,
- "Failed to remove external file");
- }
- } else if (WrtUtilDirExists(*file)) {
- _D(" -> %s", (*file).c_str());
- if (!WrtUtilRemove(*file)) {
- ThrowMsg(Exceptions::RemovingFolderFailure,
- "Failed to remove external directory");
+ bf::path p(*file);
+ try {
+ if (bf::is_regular_file(p)) {
+ _D(" -> %s", (*file).c_str());
+ if (-1 == TEMP_FAILURE_RETRY(remove(file->c_str()))) {
+ ThrowMsg(Exceptions::RemovingFileFailure,
+ "Failed to remove external file");
+ }
+ } else if (bf::is_directory(p)) {
+ _D(" -> %s", (*file).c_str());
+ JobWidgetInstall::SecureRemove(p);
+ } else {
+ _W(" -> %s(no such a path)", (*file).c_str());
}
- } else {
- _W(" -> %s(no such a path)", (*file).c_str());
+ } catch (const bf::filesystem_error& ex) {
+ _E("bf::filesystem::error: %s",ex.what());
}
}
}
_W("[DB Update Task] Aborting... (DB Clean)");
Try
{
- WidgetDAO::unregisterWidget(m_context.widgetConfig.tzAppid);
+ WidgetDAO::unregisterWidget(m_jobContext->m_installerContext.widgetConfig.tzAppid);
- FOREACH(iter, m_context.widgetConfig.configInfo.serviceAppInfoList) {
+ FOREACH(iter, m_jobContext->m_installerContext.widgetConfig.configInfo.serviceAppInfoList) {
WidgetDAO::unregisterWidget(iter->serviceId);
}
- if (m_context.isUpdateMode) {
+ if (m_jobContext->m_installerContext.isUpdateMode) {
FOREACH(iter, m_backAppIdList) {
unsigned pos = (*iter).find(L".backup");
- TizenAppId str = (*iter).substr(0, pos);
- WidgetDAO::updateTizenAppId(*iter, str);
+ TizenAppId str = (*iter).substr(0,pos);
+ WidgetDAO::updateTizenAppId(*iter,str);
}
}
_D("Cleaning DB successful!");
}
}
-void TaskDatabase::StepAbortAceDBInsert()
-{
- _W("[DB Update Task] ACE DB Aborting... (DB Clean)");
-
- FOREACH(iter, m_handleList) {
- ace_unregister_widget(static_cast<ace_widget_handle_t>(*iter));
- }
-
- FOREACH(iter, m_handleToRemoveList) {
- // Remove also old one. If it was already updated nothing wrong will happen,
- // but if not old widget will be removed.
- if (INVALID_WIDGET_HANDLE != *iter) {
- ace_unregister_widget(static_cast<ace_widget_handle_t>(*iter));
- }
-
- if (!AceApi::registerAceWidgetFromDB(*iter))
- {
- _E("ace database restore failed");
- }
- }
- _D("Ace data inserted");
-}
-
void TaskDatabase::StepAbortWidgetInterfaceDBInsert()
{
_D("[DB Update Task] Widget interface Aborting...");
using namespace WrtDB;
DbWidgetHandle handle =
- WidgetDAOReadOnly::getHandle(m_context.widgetConfig.tzAppid);
+ WidgetDAOReadOnly::getHandle(m_jobContext->m_installerContext.widgetConfig.tzAppid);
std::string dbPath = WidgetInterfaceDAO::databaseFileName(handle);
// remove database
}
// rollback database
- if (m_context.isUpdateMode) {
+ if (m_jobContext->m_installerContext.isUpdateMode) {
std::string backupDbPath = dbPath;
backupDbPath += GlobalConfig::GetBackupDatabaseSuffix();
_D("\"%s\" to \"%s\"", dbPath.c_str(), backupDbPath.c_str());
}
}
-#ifdef DBOX_ENABLED
+#if USE(WEB_PROVIDER)
void TaskDatabase::StepLiveboxDBInsert()
{
- if (m_context.widgetConfig.configInfo.m_livebox.size() <= 0) {
+ if (m_jobContext->m_installerContext.widgetConfig.configInfo.m_livebox.size() <= 0) {
return;
}
- std::string tizenId = DPL::ToUTF8String(m_context.widgetConfig.tzAppid);
+ std::string tizenId = DPL::ToUTF8String(m_jobContext->m_installerContext.widgetConfig.tzAppid);
// insert specific information to web livebox db
- for (auto it = m_context.widgetConfig.configInfo.m_livebox.begin();
- it != m_context.widgetConfig.configInfo.m_livebox.end(); ++it)
+ for (auto it = m_jobContext->m_installerContext.widgetConfig.configInfo.m_livebox.begin();
+ it != m_jobContext->m_installerContext.widgetConfig.configInfo.m_livebox.end(); ++it)
{
std::string boxId = DPL::ToUTF8String((**it).m_liveboxId);
std::string boxType;
if ((**it).m_type.empty()) {
- boxType = web_provider_livebox_get_default_type();
+ boxType = web_provider_widget_get_default_type();
} else {
boxType = DPL::ToUTF8String((**it).m_type);
}
int pdFastOpen = (**it).m_boxInfo.m_pdFastOpen == L"true" ? 1 : 0;
_D("livebox pd fast-open: %d", pdFastOpen);
- if (m_context.isUpdateMode) {
- web_provider_livebox_delete_by_app_id(tizenId.c_str());
+ if (m_jobContext->m_installerContext.isUpdateMode) {
+ web_provider_widget_delete_by_app_id(tizenId.c_str());
}
- web_provider_livebox_insert_box_info(
+ web_provider_widget_insert_box_info(
boxId.c_str(), tizenId.c_str(), boxType.c_str(),
autoLaunch, mouseEvent, pdFastOpen);
}
void TaskDatabase::StartStep()
{
- LOGD("--------- <TaskDatabase> : START ----------");
+ LOGI("--------- <TaskDatabase> : START ----------");
}
void TaskDatabase::EndStep()
{
- LOGD("--------- <TaskDatabase> : END ----------");
+ LOGI("--------- <TaskDatabase> : END ----------");
}
} //namespace WidgetInstall
} //namespace Jobs