2 * Copyright (c) 2010 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @file task_db_update.cpp
18 * @author Lukasz Wrzosek(l.wrzosek@samsung.com)
20 * @brief Implementation file for installer task database updating
29 #include <widget_install/task_file_manipulation.h>
30 #include <widget_install/job_widget_install.h>
31 #include <widget_install/widget_install_errors.h>
32 #include <widget_install/widget_install_context.h>
33 #include <widget_install/directory_api.h>
34 #include <dpl/utils/wrt_utility.h>
35 #include <dpl/utils/path.h>
36 #include <dpl/foreach.h>
37 #include <dpl/assert.h>
38 #include <dpl/errno_string.h>
39 #include <dpl/utils/folder_size.h>
40 #include <dpl/wrt-dao-ro/global_config.h>
42 #include <widget_install_to_external.h>
43 #include <installer_log.h>
44 #include <widget_unzip.h>
46 #define WEBAPP_DEFAULT_UID 5000
47 #define WEBAPP_DEFAULT_GID 5000
50 const mode_t PRIVATE_STORAGE_MODE = 0700;
51 const mode_t SHARED_STORAGE_MODE = 0755;
54 using namespace WrtDB;
57 const char* GLIST_RES_DIR = "res";
59 bool _FolderCopy(std::string source, std::string dest)
61 DIR* dir = opendir(source.c_str());
67 struct dirent *dEntryResult;
72 return_code = readdir_r(dir, &dEntry, &dEntryResult);
73 if (dEntryResult != NULL && return_code == 0) {
74 std::string fileName = dEntry.d_name;
75 std::string fullName = source + "/" + fileName;
77 if (stat(fullName.c_str(), &statInfo) != 0) {
82 if (S_ISDIR(statInfo.st_mode)) {
83 if (("." == fileName) || (".." == fileName)) {
86 std::string destFolder = dest + "/" + fileName;
87 WrtUtilMakeDir(destFolder);
89 if (!_FolderCopy(fullName, destFolder)) {
95 std::string destFile = dest + "/" + fileName;
96 std::ifstream infile(fullName);
97 std::ofstream outfile(destFile);
98 outfile << infile.rdbuf();
102 } while (dEntryResult != NULL && return_code == 0);
109 namespace WidgetInstall {
110 TaskFileManipulation::TaskFileManipulation(InstallerContext& context) :
111 DPL::TaskDecl<TaskFileManipulation>(this),
115 AddStep(&TaskFileManipulation::StartStep);
116 AddStep(&TaskFileManipulation::StepCheckInstallLocation);
117 AddStep(&TaskFileManipulation::StepPrepareRootDirectory);
118 if (m_context.mode.extension != InstallMode::ExtensionType::DIR)
120 AddStep(&TaskFileManipulation::StepUnzipWgtFile);
122 AddStep(&TaskFileManipulation::EndStep);
124 AddAbortStep(&TaskFileManipulation::StepAbortPrepareRootDirectory);
127 void TaskFileManipulation::StepCheckInstallLocation()
129 _D("StepCheckInstallLocation");
130 if (m_context.mode.rootPath == InstallMode::RootPath::RO) {
131 m_context.locationType = INSTALL_LOCATION_TYPE_INTERNAL_ONLY;
135 // If webapp is hybrid app, it should be installed to internal storage.
136 // Because Service app should be installed to internal.
137 if (m_context.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) {
138 m_context.locationType = INSTALL_LOCATION_TYPE_INTERNAL_ONLY;
142 std::string installedPath = WrtDB::GlobalConfig::GetUserInstalledWidgetPath();
143 WidgetUnzip wgtUnzip(m_context.requestedPath);
145 if (m_context.locationType == INSTALL_LOCATION_TYPE_AUTO) {
147 // vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT)
148 // 0 : phone internal memory
150 if (vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT,
152 _E("vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT) \
155 _D("default setting : storage [%d]", storage);
157 m_context.locationType = INSTALL_LOCATION_TYPE_PREFER_EXTERNAL;
159 m_context.locationType = INSTALL_LOCATION_TYPE_INTERNAL_ONLY;
160 if(!wgtUnzip.checkAvailableSpace(installedPath)) {
161 m_context.locationType = INSTALL_LOCATION_TYPE_PREFER_EXTERNAL;
166 if (m_context.locationType == INSTALL_LOCATION_TYPE_PREFER_EXTERNAL) {
168 if (vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &mmcStatus)) {
169 _E("vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS) failed.");
170 mmcStatus = VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED;
173 if (VCONFKEY_SYSMAN_MMC_MOUNTED != mmcStatus) {
174 _D("mmcStatus is MMC_REMOVED or NOT_MOUNTED.");
175 m_context.locationType = INSTALL_LOCATION_TYPE_INTERNAL_ONLY;
179 if (m_context.locationType == INSTALL_LOCATION_TYPE_INTERNAL_ONLY) {
180 if(!wgtUnzip.checkAvailableSpace(installedPath)) {
181 ThrowMsg(Exceptions::OutOfStorageFailed, "There is no space for installation");
186 void TaskFileManipulation::StepPrepareRootDirectory()
188 if (m_context.locationType == INSTALL_LOCATION_TYPE_PREFER_EXTERNAL) {
189 prepareExternalDir();
191 std::string widgetPath = m_context.locations->getPackageInstallationDir();
192 std::string widgetBinPath = m_context.locations->getBinaryDir();
193 std::string widgetSrcPath = m_context.locations->getSourceDir();
195 if (!m_context.isUpdateMode) {
196 _D("Remove existing directory : %s", widgetPath.c_str());
197 DPL::Utils::TryRemove(DPL::Utils::Path(widgetPath));
199 WrtUtilMakeDir(widgetPath);
201 _D("Create resource directory");
202 WrtUtilMakeDir(widgetBinPath);
203 WrtUtilMakeDir(widgetSrcPath);
206 m_context.job->UpdateProgress(
207 InstallerContext::INSTALL_DIR_CREATE,
208 "Widget Directory Created");
211 void TaskFileManipulation::StepUnzipWgtFile()
213 if (m_context.widgetConfig.packagingType != PKG_TYPE_HOSTED_WEB_APP) {
215 if (m_context.widgetConfig.packagingType == PKG_TYPE_HYBRID_WEB_APP) {
216 instDir = m_context.locations->getPackageInstallationDir();
218 instDir = m_context.locations->getSourceDir();
221 _D("unzip file to %s", instDir.c_str());
223 WidgetUnzip wgtUnzip(m_context.requestedPath);
224 wgtUnzip.unzipWgtFile(instDir);
226 _D("From browser installation - unzip is not done");
229 m_context.job->UpdateProgress(
230 InstallerContext::INSTALL_UNZIP_WGT,
234 void TaskFileManipulation::StepAbortPrepareRootDirectory()
236 _D("[Create Root Directory] Aborting.... (Rename path)");
237 if (m_context.locationType == INSTALL_LOCATION_TYPE_PREFER_EXTERNAL) {
238 if (m_context.isUpdateMode) {
239 WidgetInstallToExtSingleton::Instance().postUpgrade(false);
241 WidgetInstallToExtSingleton::Instance().postInstallation(false);
243 WidgetInstallToExtSingleton::Instance().deinitialize();
245 std::string widgetPath;
246 widgetPath = m_context.locations->getPackageInstallationDir();
247 if (!WrtUtilRemove(widgetPath)) {
248 _E("Error occurs during removing existing folder");
250 // Remove user data directory if preload web app.
251 std::string userData = m_context.locations->getUserDataRootDir();
252 if (0 == access(userData.c_str(), F_OK)) {
253 if (!WrtUtilRemove(userData)) {
254 _E("Error occurs during removing user data directory");
260 void TaskFileManipulation::prepareExternalDir()
262 _D("Step prepare to install in exernal directory");
265 DPL::ToUTF8String(m_context.widgetConfig.tzPkgid);
267 WidgetInstallToExtSingleton::Instance().initialize(pkgid);
269 std::unique_ptr<DPL::ZipInput> zipFile(new
270 DPL::ZipInput(m_context.requestedPath));
271 double unzipSize = zipFile->GetTotalUncompressedSize();
272 int folderSize = (int)(unzipSize / (1024 * 1024)) + 1;
275 app2ext_dir_details* dirDetail = NULL;
277 dirDetail = (app2ext_dir_details*) calloc(1,
279 app2ext_dir_details));
280 if (NULL == dirDetail) {
281 ThrowMsg(Exceptions::ErrorExternalInstallingFailure,
284 dirDetail->name = strdup(GLIST_RES_DIR);
285 dirDetail->type = APP2EXT_DIR_RO;
286 list = g_list_append(list, dirDetail);
288 if (m_context.isUpdateMode) {
289 WidgetInstallToExtSingleton::Instance().preUpgrade(list,
292 WidgetInstallToExtSingleton::Instance().preInstallation(list,
298 /* make bin directory */
299 std::string widgetBinPath = m_context.locations->getBinaryDir();
300 WrtUtilMakeDir(widgetBinPath);
301 std::string sourceDir = m_context.locations->getSourceDir();
302 WrtUtilMakeDir(sourceDir);
304 Catch(DPL::ZipInput::Exception::OpenFailed) {
305 ReThrowMsg(Exceptions::ErrorExternalInstallingFailure,
307 create external folder ");
309 Catch(WidgetInstallToExt::Exception::ErrorInstallToExt)
311 ReThrowMsg(Exceptions::ErrorExternalInstallingFailure,
312 "Error during create external folder ");
316 void TaskFileManipulation::StartStep()
318 LOGD("--------- <TaskFileManipulation> : START ----------");
321 void TaskFileManipulation::EndStep()
323 LOGD("--------- <TaskFileManipulation> : END ----------");
325 } //namespace WidgetInstall