BuildRequires: pkgconfig(dpl-encryption)
BuildRequires: pkgconfig(capi-appfw-app-manager)
BuildRequires: pkgconfig(drm-service-core-intel)
+BuildRequires: pkgconfig(app2sd)
Requires: xmlsec1
%description
${INSTALLER_SRC_DIR}/misc/feature_logic.cpp
${INSTALLER_SRC_DIR}/misc/libxml_utils.cpp
${INSTALLER_SRC_DIR}/misc/widget_location.cpp
+ ${INSTALLER_SRC_DIR}/misc/widget_install_to_external.cpp
${INSTALLER_SRC_DIR}/pkg-manager/pkgmgr_signal.cpp
)
shortcut
capi-appfw-app-manager
drm-service-core-intel
+ app2sd
REQUIRED
)
typedef WrtDB::DbPluginHandle PluginHandle;
+enum InstallLocationType
+{
+ INSTALL_LOCATION_TYPE_UNKNOWN = 0,
+ INSTALL_LOCATION_TYPE_NOMAL,
+ INSTALL_LOCATION_TYPE_PRELOAD,
+ INSTALL_LOCATION_TYPE_EXTERNAL
+};
+
#endif /* PLUGIN_COMMON_TYPES_H */
#include <widget_install/widget_install_errors.h>
#include <widget_install/widget_install_context.h>
+#include <widget_install_to_external.h>
using namespace WrtDB;
static const DPL::String SETTING_VALUE_ENCRYPTION = L"encryption";
static const DPL::String SETTING_VALUE_ENCRYPTION_ENABLE = L"enable";
+const DPL::String SETTING_VALUE_INSTALLTOEXT_NAME =
+ L"install-location-type";
+const DPL::String SETTING_VALUE_INSTALLTOEXT_PREPER_EXT =
+ L"prefer-external";
class InstallerTaskFail :
public DPL::TaskDecl<InstallerTaskFail>
m_installerContext.widgetConfig.packagingType.pkgType);
WidgetUpdateInfo update = detectWidgetUpdate(configData);
m_needEncryption = detectResourceEncryption(configData);
+ setInstallLocationType(configData);
// Configure installation
result = ConfigureInstallation(widgetPath, configData, update, tempDir);
WidgetLocation(DPL::ToUTF8String(*m_installerContext.widgetConfig.pkgname),
widgetPath, tempPath,
m_installerContext.widgetConfig.packagingType,
- m_jobStruct.m_preload);
+ m_installerContext.locationType);
LogInfo("widgetSource " << widgetPath);
}
// TODO : sync should move to separate task.
sync();
+ if (false == m_installerContext.existingWidgetInfo.isExist) {
+ WidgetInstallToExtSingleton::Instance().postInstallation(true);
+ } else {
+ WidgetInstallToExtSingleton::Instance().postUpgrade(true);
+ }
+ WidgetInstallToExtSingleton::Instance().deinitialize();
+
// remove widget install information file
unlink(m_installerContext.installInfo.c_str());
return false;
}
+void JobWidgetInstall::setInstallLocationType(const
+ WrtDB::ConfigParserData &configData)
+{
+ m_installerContext.locationType = INSTALL_LOCATION_TYPE_NOMAL;
+
+ if (true == m_jobStruct.m_preload) {
+ m_installerContext.locationType =
+ INSTALL_LOCATION_TYPE_PRELOAD;
+ } else {
+ FOREACH(it, configData.settingsList)
+ {
+ if (it->m_name == SETTING_VALUE_INSTALLTOEXT_NAME &&
+ it->m_value ==
+ SETTING_VALUE_INSTALLTOEXT_PREPER_EXT) {
+ LogDebug("This widget will be installed to sd card");
+ m_installerContext.locationType =
+ INSTALL_LOCATION_TYPE_EXTERNAL;
+ }
+ }
+ }
+}
+
bool JobWidgetInstall::isDRMWidget(std::string widgetPath)
{
/* TODO :
const std::string &widgetSource,
const std::string &tempPath);
bool detectResourceEncryption(const WrtDB::ConfigParserData &configData);
+ void setInstallLocationType(const WrtDB::ConfigParserData
+ &configData);
bool isDRMWidget(std::string widgetPath);
bool DecryptDRMWidget(std::string widgetPath, std::string destPath);
ConfigureResult PrePareInstallation(const std::string &widgetPath);
// Temporary path
std::ostringstream tempPathBuilder;
- //tempPathBuilder << WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
if (preload) {
tempPathBuilder << WrtDB::GlobalConfig::GetUserPreloadedWidgetPath();
} else {
* @brief Implementation file for installer task database updating
*/
#include <sys/stat.h>
+#include <dirent.h>
#include <widget_install/task_file_manipulation.h>
#include <widget_install/job_widget_install.h>
#include <widget_install/widget_install_errors.h>
#include <dpl/foreach.h>
#include <dpl/log/log.h>
#include <dpl/assert.h>
+#include <dpl/utils/folder_size.h>
#include <string>
+#include <fstream>
+#include <widget_install_to_external.h>
#define WEBAPP_DEFAULT_UID 5000
#define WEBAPP_DEFAULT_GID 5000
using namespace WrtDB;
+namespace {
+const char* GLIST_RES_DIR = "res";
+const char* GLIST_BIN_DIR = "bin";
+
+bool _FolderCopy(std::string source, std::string dest)
+{
+ DIR* dir = opendir(source.c_str());
+ if (NULL == dir) {
+ return false;
+ }
+
+ struct dirent* dEntry = NULL;
+ do {
+ struct stat statInfo;
+ if (dEntry = readdir(dir)) {
+ std::string fileName = dEntry->d_name;
+ std::string fullName = source + "/" + fileName;
+
+ if (stat(fullName.c_str(), &statInfo) != 0) {
+ return false;
+ }
+
+ if (S_ISDIR(statInfo.st_mode)) {
+ if(("." == fileName) || (".." == fileName)) {
+ continue;
+ }
+ std::string destFolder = dest + "/" + fileName;
+ WrtUtilMakeDir(destFolder);
+
+ if (!_FolderCopy(fullName, destFolder)) {
+ return false;
+ }
+ }
+
+ std::string destFile = dest + "/" + fileName;
+ std::ifstream infile(fullName);
+ std::ofstream outfile(destFile);
+ outfile << infile.rdbuf();
+ outfile.close();
+ infile.close();
+ }
+ } while(dEntry);
+ return true;
+}
+}
+
namespace Jobs {
namespace WidgetInstall {
TaskFileManipulation::TaskFileManipulation(InstallerContext& context) :
DPL::TaskDecl<TaskFileManipulation>(this),
m_context(context)
{
- AddStep(&TaskFileManipulation::StepCreateDirs);
- AddStep(&TaskFileManipulation::StepCreatePrivateStorageDir);
- AddStep(&TaskFileManipulation::StepCreateShareDir);
- if (m_context.widgetConfig.packagingType !=
- WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
- {
- AddStep(&TaskFileManipulation::StepRenamePath);
- AddAbortStep(&TaskFileManipulation::StepAbortRenamePath);
+ if (INSTALL_LOCATION_TYPE_EXTERNAL !=
+ m_context.locationType) {
+ AddStep(&TaskFileManipulation::StepCreateDirs);
+ AddStep(&TaskFileManipulation::StepCreatePrivateStorageDir);
+ AddStep(&TaskFileManipulation::StepCreateShareDir);
+ if (m_context.widgetConfig.packagingType !=
+ WrtDB::PKG_TYPE_DIRECTORY_WEB_APP)
+ {
+ AddStep(&TaskFileManipulation::StepRenamePath);
+ AddAbortStep(&TaskFileManipulation::StepAbortRenamePath);
+ }
+ } else {
+ AddStep(&TaskFileManipulation::StepPrepareExternalDir);
+ AddStep(&TaskFileManipulation::StepInstallToExternal);
+ AddStep(&TaskFileManipulation::StepCreatePrivateStorageDir);
+ AddStep(&TaskFileManipulation::StepCreateShareDir);
+
+ AddAbortStep(&TaskFileManipulation::StepAbortCreateExternalDir);
}
}
}
LogDebug("Rename widget path sucessful!");
}
+
+void TaskFileManipulation::StepPrepareExternalDir()
+{
+ LogDebug("Step prepare to install in exernal directory");
+ Try {
+ std::string pkgname =
+ DPL::ToUTF8String(*m_context.widgetConfig.pkgname);
+
+ WidgetInstallToExtSingleton::Instance().initialize(pkgname);
+
+ size_t totalSize =
+ Utils::getFolderSize(m_context.locations->getTemporaryPackageDir());
+
+ int folderSize = (int)(totalSize / (1024 * 1024)) + 1;
+
+ GList *list = NULL;
+ app2ext_dir_details* dirDetail = NULL;
+
+ std::string dirNames[2] = {GLIST_RES_DIR, GLIST_BIN_DIR};
+
+ for (int i = 0; i < 2; i++) {
+ dirDetail = (app2ext_dir_details*) calloc(1,
+ sizeof(app2ext_dir_details));
+ if (NULL == dirDetail) {
+ ThrowMsg(Exceptions::ErrorExternalInstallingFailure, "error in app2ext");
+ }
+ dirDetail->name = strdup(dirNames[i].c_str());
+ dirDetail->type = APP2EXT_DIR_RO;
+ list = g_list_append(list, dirDetail);
+ }
+
+ if (false == m_context.existingWidgetInfo.isExist) {
+ WidgetInstallToExtSingleton::Instance().preInstallation(list,
+ folderSize);
+ } else {
+ WidgetInstallToExtSingleton::Instance().preUpgrade(list,
+ folderSize);
+ }
+ free(dirDetail);
+ g_list_free(list);
+ }
+ Catch (WidgetInstallToExt::Exception::ErrorInstallToExt)
+ {
+ ReThrowMsg(Exceptions::ErrorExternalInstallingFailure, "Error during \
+ create external folder ");
+ }
+}
+
+void TaskFileManipulation::StepInstallToExternal()
+{
+ LogDebug("StepInstallExternal");
+ if (!WrtUtilMakeDir(m_context.locations->getSourceDir())) {
+ ThrowMsg(Exceptions::ErrorExternalInstallingFailure, "To make src \
+ directory failed");
+ }
+
+ LogDebug("Resource move to external storage " <<
+ m_context.locations->getSourceDir());
+ if (!_FolderCopy(m_context.locations->getTemporaryPackageDir(),
+ m_context.locations->getSourceDir()))
+ {
+ ThrowMsg(Exceptions::UnknownError,
+ "Error occurs during renaming widget folder");
+ }
+}
+
+void TaskFileManipulation::StepAbortCreateExternalDir()
+{
+ LogError("Abort StepAbortCreateExternalDir");
+ if (false == m_context.existingWidgetInfo.isExist) {
+ WidgetInstallToExtSingleton::Instance().postInstallation(false);
+ } else {
+ WidgetInstallToExtSingleton::Instance().postUpgrade(false);
+ }
+ WidgetInstallToExtSingleton::Instance().deinitialize();
+}
} //namespace WidgetInstall
} //namespace Jobs
#define INSTALLER_CORE_JOS_WIDGET_INSTALL_TASK_FILE_MANIPULATION_UPDATE_H
#include <dpl/task.h>
+#include <app2ext_interface.h>
class InstallerContext;
class TaskFileManipulation :
public DPL::TaskDecl<TaskFileManipulation>
{
- private:
InstallerContext& m_context;
+ app2ext_handle *m_extHandle;
+ // install internal location
void StepCreateDirs();
void StepRenamePath();
void StepCreatePrivateStorageDir();
void StepAbortRenamePath();
+ // install external location
+ void StepPrepareExternalDir();
+ void StepInstallToExternal();
+ void StepFinishExternalInstallation();
+ void StepAbortCreateExternalDir();
+
public:
TaskFileManipulation(InstallerContext& context);
};
RequestedDevCapsMap staticPermittedDevCaps;
std::string installInfo; ///<For recovery>
bool m_quiet;
+ InstallLocationType locationType;
};
#endif // INSTALLER_CONTEXT_H
ErrorRemovingFolderFailure, ///< Failure in removing existing widget folder
ErrorInstallOspServcie, ///< Failure in installing osp service
ErrorUpdateWidget, ///< Failure in widget update.
+ ErrorInstallToExt, ///< Failure in install to sdcard
ErrorUnknown ///< Temporary error. Try to not use this.
};
DECLARE_JOB_EXCEPTION(Base, CopyIconFailed, ErrorUnknown)
+DECLARE_JOB_EXCEPTION(Base, ErrorExternalInstallingFailure, ErrorInstallToExt)
+
// Installation osp service
DECLARE_JOB_EXCEPTION(Base, RequestInstallOspsvc, ErrorInstallOspServcie)
DECLARE_JOB_EXCEPTION(Base, InstallOspsvcFailed, ErrorInstallOspServcie)
#include <widget_uninstall/task_uninstall_ospsvc.h>
#include <widget_uninstall/task_delete_certificates.h>
#include <pkg-manager/pkgmgr_signal.h>
+#include <app2ext_interface.h>
using namespace WrtDB;
m_context.uninstallStep = UninstallerContext::UNINSTALL_START;
m_context.job = this;
m_context.pkgname = widgetPkgName;
+ m_context.isExternalWidget = getExternalWidgetFlag();
Try
{
m_exceptionCaught = static_cast<Exceptions::Type>(e.getParam());
m_exceptionMessage = e.GetMessage();
}
+
+bool JobWidgetUninstall::getExternalWidgetFlag() const
+{
+
+ LogDebug("Get external widget");
+ if (APP2EXT_SD_CARD == app2ext_get_app_location(m_context.pkgname.c_str())) {
+ LogDebug("This widget is in external stroage");
+ return true;
+ }
+ return false;
+}
+
} //namespace WidgetUninstall
} //namespace Jobs
std::string getRemovedTizenId() const;
bool getRemoveStartedFlag() const;
bool getRemoveFinishedFlag() const;
+ bool getExternalWidgetFlag() const;
void SendProgress();
void SendFinishedSuccess();
#include <pkgmgr/pkgmgr_parser.h>
#include <errno.h>
#include <string.h>
+#include <widget_install_to_external.h>
namespace Jobs {
namespace WidgetUninstall {
DPL::TaskDecl<TaskRemoveFiles>(this),
m_context(context)
{
- AddStep(&TaskRemoveFiles::StepRemoveInstallationDirectory);
+ if (!m_context.isExternalWidget) {
+ AddStep(&TaskRemoveFiles::StepRemoveInstallationDirectory);
+ } else {
+ AddStep(&TaskRemoveFiles::StepRemoveExternalWidget);
+ }
//AddStep(&TaskRemoveFiles::StepRemoveDesktop);
AddStep(&TaskRemoveFiles::StepRemoveManifest);
AddStep(&TaskRemoveFiles::StepRemoveExternalLocations);
dao.unregisterAllExternalLocations();
}
+void TaskRemoveFiles::StepRemoveExternalWidget()
+{
+ Try {
+ WidgetInstallToExtSingleton::Instance().initialize(m_context.pkgname);
+ WidgetInstallToExtSingleton::Instance().uninstallation();
+ WidgetInstallToExtSingleton::Instance().deinitialize();
+ }
+ Catch (WidgetInstallToExt::Exception::ErrorInstallToExt)
+ {
+ Throw(Jobs::WidgetUninstall::TaskRemoveFiles::Exception::RemoveFilesFailed);
+ }
+}
+
} //namespace WidgetUninstall
} //namespace Jobs
void StepRemoveManifest();
void StepRemoveExternalLocations();
+ void StepRemoveExternalWidget();
+
public:
explicit TaskRemoveFiles(UninstallerContext& context);
virtual ~TaskRemoveFiles();
UninstallStep uninstallStep; ///< current step of installation
Jobs::WidgetUninstall::JobWidgetUninstall *job;
std::string pkgname;
+ bool isExternalWidget;
};
#endif // WRT_SRC_INSTALLER_CORE_UNINSTALLER_TASKS_UNINSTALLER_CONTEXT_H_
--- /dev/null
+/*
+ * 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 widget_install_to_external.cpp
+ * @author Soyoung Kim (sy037.kim@smasung.com)
+ */
+#include "widget_install_to_external.h"
+
+#include <dpl/singleton_safe_impl.h>
+#include <dpl/assert.h>
+#include <dpl/log/log.h>
+
+IMPLEMENT_SAFE_SINGLETON(WidgetInstallToExt)
+
+WidgetInstallToExt::WidgetInstallToExt() :
+ m_handle(NULL),
+ m_appId("")
+{
+}
+
+WidgetInstallToExt::~WidgetInstallToExt()
+{
+}
+
+void WidgetInstallToExt::initialize(std::string appId)
+{
+ LogDebug("WidgetInstallToExt::initialize()");
+ m_appId = appId;
+
+ m_handle = app2ext_init(APP2EXT_SD_CARD);
+ if (NULL == m_handle) {
+ ThrowMsg(Exception::ErrorInstallToExt, "initialize failed");
+ }
+}
+
+void WidgetInstallToExt::deinitialize()
+{
+ LogDebug("WidgetInstallToExt::deinitialize()");
+ if (NULL != m_handle) {
+ if ( 0 < app2ext_deinit(m_handle)) {
+ ThrowMsg(Exception::ErrorInstallToExt, "app2ext deinitialize \
+ failed");
+ }
+ }
+}
+
+void WidgetInstallToExt::preInstallation(GList *dirList, int dSize)
+{
+ LogDebug("WidgetInstallToExt::preInstallation()");
+ Assert(m_handle);
+
+ int ret = m_handle->interface.pre_install(m_appId.c_str(), dirList, dSize);
+
+ if (APP2EXT_SUCCESS == ret ) {
+ LogDebug("App2Ext pre install success");
+ } else {
+ postInstallation(false);
+ ThrowMsg(Exception::ErrorInstallToExt, "pre-install failed");
+ }
+}
+
+void WidgetInstallToExt::postInstallation(bool status)
+{
+ LogDebug("WidgetInstallToExt::postInstallation()");
+ Assert(m_handle);
+
+ if (status) {
+ m_handle->interface.post_install(m_appId.c_str(),
+ APP2EXT_STATUS_SUCCESS);
+ } else {
+ m_handle->interface.post_install(m_appId.c_str(),
+ APP2EXT_STATUS_FAILED);
+ }
+}
+
+void WidgetInstallToExt::preUpgrade(GList *dirList, int dSize)
+{
+ LogDebug("WidgetInstallToExt::preUpgrade()");
+ Assert(m_handle);
+
+ int ret = m_handle->interface.pre_upgrade(m_appId.c_str(), dirList, dSize);
+ if (APP2EXT_SUCCESS == ret ) {
+ LogDebug("App2Ext pre-upgrade success");
+ } else {
+ postUpgrade(false);
+ ThrowMsg(Exception::ErrorInstallToExt, "pre-upgrade failed");
+ }
+}
+
+void WidgetInstallToExt::postUpgrade(bool status)
+{
+ LogDebug("WidgetInstallToExt::postUpgrade()");
+ Assert(m_handle);
+
+ if (status) {
+ m_handle->interface.post_upgrade(m_appId.c_str(),
+ APP2EXT_STATUS_SUCCESS);
+ } else {
+ m_handle->interface.post_upgrade(m_appId.c_str(),
+ APP2EXT_STATUS_FAILED);
+ }
+}
+
+void WidgetInstallToExt::uninstallation()
+{
+ LogDebug("WidgetInstallToExt::uninstallation()");
+
+ Assert(m_handle);
+
+ int ret = m_handle->interface.pre_uninstall(m_appId.c_str());
+ if (APP2EXT_SUCCESS == ret ) {
+ if (APP2EXT_SUCCESS ==
+ m_handle->interface.post_uninstall(m_appId.c_str())) {
+ LogDebug("App2Ext pre-uninstall success");
+ } else {
+ ThrowMsg(Exception::ErrorInstallToExt, "post-uninstall failed");
+ }
+ } else {
+ ThrowMsg(Exception::ErrorInstallToExt, "pre-uninstall failed");
+ }
+}
--- /dev/null
+/*
+ * 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 widget_install_to_external.h
+ * @author Soyoung Kim (sy037.kim@smasung.com)
+ */
+#ifndef WRT_INSTALLER_SRC_MISC_WIDGET_INSTALL_TO_EXTERNAL_H
+#define WRT_INSTALLER_SRC_MISC_WIDGET_INSTALL_TO_EXTERNAL_H
+
+#include <string>
+#include <dpl/singleton.h>
+#include <dpl/string.h>
+#include <app2ext_interface.h>
+
+
+class WidgetInstallToExt
+{
+public:
+ class Exception
+ {
+ public:
+ DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, ErrorInstallToExt)
+ };
+
+ void initialize(std::string appId);
+ void deinitialize();
+ void preInstallation(GList* dirList, int dSize);
+ void postInstallation(bool status);
+ void preUpgrade(GList* dirList, int dSize);
+ void postUpgrade(bool status);
+ void uninstallation();
+
+private:
+ app2ext_handle *m_handle;
+ std::string m_appId;
+
+ WidgetInstallToExt();
+ ~WidgetInstallToExt();
+
+ friend class DPL::Singleton<WidgetInstallToExt>;
+};
+
+typedef DPL::Singleton<WidgetInstallToExt> WidgetInstallToExtSingleton;
+
+#endif // WRT_INSTALLER_SRC_MISC_WIDGET_INSTALL_TO_EXTERNAL_H
WidgetLocation::WidgetLocation(const std::string & widgetname,
std::string sourcePath,
WrtDB::PackagingType t,
- bool preload):
+ InstallLocationType locationType):
m_pkgname(widgetname),
m_widgetSource(sourcePath),
m_type(t),
m_temp(new WidgetLocation::DirectoryDeletor())
{
- if (preload) {
- m_installedPath += WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
- } else {
+ if (INSTALL_LOCATION_TYPE_PRELOAD == locationType) {
m_installedPath += WrtDB::GlobalConfig::GetUserPreloadedWidgetPath();
+ } else {
+ m_installedPath += WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
}
}
std::string sourcePath,
std::string dirPath,
WrtDB::PackagingType t,
- bool preload):
+ InstallLocationType locationType):
m_pkgname(widgetname),
m_widgetSource(sourcePath),
m_type(t),
m_temp(new
WidgetLocation::DirectoryDeletor(dirPath))
{
- if (preload) {
+ if (INSTALL_LOCATION_TYPE_PRELOAD == locationType) {
m_installedPath += WrtDB::GlobalConfig::GetUserPreloadedWidgetPath();
} else {
m_installedPath += WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
#include <dpl/wrt-dao-ro/common_dao_types.h>
#include <dpl/wrt-dao-ro/widget_dao_read_only.h>
+#include <wrt_common_types.h>
/**
* @brief The WidgetLocation class
*/
WidgetLocation(const std::string & widgetname, std::string sourcePath,
WrtDB::PackagingType t = WrtDB::PKG_TYPE_NOMAL_WEB_APP,
- bool preload = false);
+ InstallLocationType ltype =
+ INSTALL_LOCATION_TYPE_NOMAL);
WidgetLocation(const std::string & widgetname, std::string sourcePath,
std::string dirPath,
WrtDB::PackagingType t = WrtDB::PKG_TYPE_NOMAL_WEB_APP,
- bool preload = false);
+ InstallLocationType ltype =
+ INSTALL_LOCATION_TYPE_NOMAL);
~WidgetLocation();