2 * Copyright (c) 2011 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 job_widget_install.cpp
18 * @author Radoslaw Wicik r.wicik@samsung.com
19 * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
21 * @brief Implementation file for main installer task
30 #include <dpl/platform.h>
31 #include <dpl/utils/wrt_utility.h>
32 #include <dpl/utils/path.h>
33 #include <dpl/localization/w3c_file_localization.h>
35 #include <pkg-manager/pkgmgr_signal.h>
36 #include <app_manager.h>
37 #include <privilege-control.h>
38 #include "root_parser.h"
39 #include "widget_parser.h"
40 #include "parser_runner.h"
41 #include <widget_install/job_widget_install.h>
42 #include <widget_install/task_certify.h>
43 #include <widget_install/task_process_config.h>
44 #include <widget_install/task_file_manipulation.h>
45 #include <widget_install/task_ace_check.h>
46 #include <widget_install/task_smack.h>
47 #include <widget_install/task_manifest_file.h>
48 #include <widget_install/task_prepare_files.h>
49 #include <widget_install/task_recovery.h>
50 #include <widget_install/task_install_ospsvc.h>
51 #include <widget_install/task_update_files.h>
52 #include <widget_install/task_database.h>
53 #include <widget_install/task_remove_backup.h>
54 #include <widget_install/task_encrypt_resource.h>
55 #include <widget_install/task_pkg_info_update.h>
56 #include <widget_install/task_commons.h>
57 #include <widget_install/task_prepare_reinstall.h>
58 #include <widget_install/task_configuration.h>
59 #include <widget_install/task_user_data_manipulation.h>
60 #include <widget_install/task_status_check.h>
61 #if ENABLE(PRE_LAUNCH)
62 #include <widget_install/task_prelaunching_registration.h>
64 #include <widget_install_to_external.h>
65 #include <boost/optional/optional_io.hpp>
66 #include <boost/filesystem.hpp>
67 #include <dpl/log/secure_log.h>
69 namespace bf = boost::filesystem;
71 using namespace WrtDB;
72 using namespace Jobs::Exceptions;
75 namespace WidgetInstall {
77 JobWidgetInstall::JobWidgetInstall(
78 std::string const &widgetPath,
79 std::string const &tzPkgId,
80 const Jobs::WidgetInstall::WidgetInstallationStruct &
82 Job(UnknownInstallation),
83 JobContextBase<Jobs::WidgetInstall::WidgetInstallationStruct>(installerStruct),
84 m_exceptionCaught(Jobs::Exceptions::Success)
86 m_installerContext.mode = m_jobStruct.m_installMode;
87 m_installerContext.requestedPath = widgetPath;
88 m_jobStruct.pkgmgrInterface->setPkgname(tzPkgId);
90 if (InstallMode::Command::RECOVERY == m_installerContext.mode.command) {
91 m_installerContext.widgetConfig.tzPkgid = DPL::FromUTF8String(tzPkgId);
92 AddTask(new TaskRecovery(this));
95 //start configuration of installation
96 AddTask(new TaskConfiguration(this));
98 m_installerContext.callerPkgId
99 = DPL::FromUTF8String(m_jobStruct.pkgmgrInterface->getCallerId());
100 _D("Caller Package Id : %s", DPL::ToUTF8String(m_installerContext.callerPkgId).c_str());
103 void JobWidgetInstall::appendNewInstallationTaskList()
105 _D("Configure installation succeeded");
106 SetProgressFlag(true);
108 AddTask(new TaskFileManipulation(this));
109 AddTask(new TaskProcessConfig(this));
110 if (m_installerContext.widgetConfig.packagingType ==
111 WrtDB::PKG_TYPE_HOSTED_WEB_APP)
113 AddTask(new TaskPrepareFiles(this));
115 AddTask(new TaskCertify(this));
116 AddTask(new TaskUserDataManipulation(this));
117 if (m_installerContext.needEncryption) {
118 AddTask(new TaskEncryptResource(this));
120 AddTask(new TaskManifestFile(this));
121 if (m_installerContext.widgetConfig.packagingType ==
122 PKG_TYPE_HYBRID_WEB_APP) {
123 AddTask(new TaskInstallOspsvc(this));
125 AddTask(new TaskDatabase(this));
126 AddTask(new TaskAceCheck(this));
127 AddTask(new TaskSmack(this));
128 AddTask(new TaskPkgInfoUpdate(this));
129 #if ENABLE(PRE_LAUNCH)
130 if (m_installerContext.isNeedPreLaunching) {
131 AddTask(new TaskPreLaunchingRegistration(this));
136 void JobWidgetInstall::appendUpdateInstallationTaskList()
138 _D("Configure installation updated");
140 SetProgressFlag(true);
141 AddTask(new TaskStatusCheck(this));
143 if (m_installerContext.mode.command ==
144 InstallMode::Command::REINSTALL) {
145 AddTask(new TaskPrepareReinstall(this));
148 if (m_installerContext.mode.extension !=
149 InstallMode::ExtensionType::DIRECTORY) {
150 AddTask(new TaskUpdateFiles(this));
151 AddTask(new TaskFileManipulation(this));
154 AddTask(new TaskProcessConfig(this));
156 if (m_installerContext.widgetConfig.packagingType ==
157 WrtDB::PKG_TYPE_HOSTED_WEB_APP) {
158 AddTask(new TaskPrepareFiles(this));
161 AddTask(new TaskCertify(this));
162 AddTask(new TaskUserDataManipulation(this));
163 if (m_installerContext.needEncryption) {
164 AddTask(new TaskEncryptResource(this));
166 AddTask(new TaskManifestFile(this));
167 if (m_installerContext.widgetConfig.packagingType ==
168 PKG_TYPE_HYBRID_WEB_APP) {
169 AddTask(new TaskInstallOspsvc(this));
172 AddTask(new TaskDatabase(this));
173 AddTask(new TaskAceCheck(this));
174 //TODO: remove widgetHandle from this task and move before database task
175 // by now widget handle is needed in ace check
176 // Any error in acecheck while update will break widget
177 AddTask(new TaskSmack(this));
178 AddTask(new TaskRemoveBackupFiles(this));
179 AddTask(new TaskPkgInfoUpdate(this));
182 void JobWidgetInstall::appendRDSUpdateTaskList()
184 _D("Configure installation RDS updated");
185 SetProgressFlag(true);
186 AddTask(new TaskStatusCheck(this));
187 AddTask(new TaskPrepareReinstall(this));
188 AddTask(new TaskCertify(this));
191 void JobWidgetInstall::appendRecoveryTaskList()
194 SetProgressFlag(true);
196 AddTask(new TaskProcessConfig(this));
198 AddTask(new TaskCertify(this));
199 AddTask(new TaskManifestFile(this));
200 if (m_installerContext.widgetConfig.packagingType ==
201 PKG_TYPE_HYBRID_WEB_APP) {
202 AddTask(new TaskInstallOspsvc(this));
204 AddTask(new TaskSmack(this));
207 void JobWidgetInstall::appendFotaInstallationTaskList()
210 _D("Configure installation succeeded");
211 SetProgressFlag(true);
213 AddTask(new TaskProcessConfig(this));
214 AddTask(new TaskCertify(this));
215 AddTask(new TaskUserDataManipulation(this));
216 if (m_installerContext.needEncryption) {
217 AddTask(new TaskEncryptResource(this));
219 AddTask(new TaskManifestFile(this));
220 if (m_installerContext.widgetConfig.packagingType ==
221 PKG_TYPE_HYBRID_WEB_APP)
223 AddTask(new TaskInstallOspsvc(this));
225 AddTask(new TaskDatabase(this));
226 AddTask(new TaskAceCheck(this));
227 AddTask(new TaskSmack(this));
228 AddTask(new TaskPkgInfoUpdate(this));
231 void JobWidgetInstall::appendFotaUpdateTaskList()
233 _D("Configure installation updated");
235 SetProgressFlag(true);
237 AddTask(new TaskProcessConfig(this));
238 AddTask(new TaskCertify(this));
239 AddTask(new TaskUserDataManipulation(this));
240 if (m_installerContext.needEncryption) {
241 AddTask(new TaskEncryptResource(this));
244 AddTask(new TaskManifestFile(this));
245 if (m_installerContext.widgetConfig.packagingType ==
246 PKG_TYPE_HYBRID_WEB_APP)
248 AddTask(new TaskInstallOspsvc(this));
251 AddTask(new TaskDatabase(this));
252 AddTask(new TaskAceCheck(this));
253 //TODO: remove widgetHandle from this task and move before database task
254 // by now widget handle is needed in ace check
255 // Any error in acecheck while update will break widget
256 AddTask(new TaskSmack(this));
257 AddTask(new TaskPkgInfoUpdate(this));
258 #if ENABLE(PRE_LAUNCH)
259 if (m_installerContext.isNeedPreLaunching) {
260 AddTask(new TaskPreLaunchingRegistration(this));
265 void JobWidgetInstall::SendProgress()
267 using namespace PackageManager;
268 if (GetProgressFlag() != false) {
269 if (GetInstallerStruct().progressCallback != NULL) {
270 // send progress signal of pkgmgr
271 GetInstallerStruct().pkgmgrInterface->sendProgressInstall(GetProgressPercent());
273 _D("Call widget install progressCallback");
274 GetInstallerStruct().progressCallback(
275 GetInstallerStruct().userParam,
276 GetProgressPercent(),
277 GetProgressDescription());
282 void JobWidgetInstall::SendProgressIconPath(const std::string &path)
284 using namespace PackageManager;
285 if (GetProgressFlag() != false) {
286 if (GetInstallerStruct().progressCallback != NULL) {
287 // send progress signal of pkgmgr
288 GetInstallerStruct().pkgmgrInterface->sendIconPath(path);
293 void JobWidgetInstall::SendFinishedSuccess()
295 using namespace PackageManager;
296 // TODO : sync should move to separate task.
299 if (INSTALL_LOCATION_TYPE_PREFER_EXTERNAL == m_installerContext.locationType) {
300 if (m_installerContext.isUpdateMode) {
301 WidgetInstallToExtSingleton::Instance().postUpgrade(true);
303 WidgetInstallToExtSingleton::Instance().postInstallation(true);
305 WidgetInstallToExtSingleton::Instance().deinitialize();
308 /* smack label of ".mmc" is changed to "wrt-installer" after calling above function.
309 smack label of ".mmc" must be set to [pkgid] to success uninstallation by app2ext. */
310 std::string mmcDir = m_installerContext.locations->getPackageInstallationDir() + "/.mmc";
311 std::string pkgid = DPL::ToUTF8String(m_installerContext.widgetConfig.tzPkgid);
312 if (PC_OPERATION_SUCCESS != perm_app_setup_path(pkgid.c_str(), mmcDir.c_str(), APP_PATH_PRIVATE)) {
313 _W("change to wrt-installer label to %s", mmcDir.c_str());
317 JobWidgetInstall::displayWidgetInfo();
319 TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
321 // send signal of pkgmgr
322 GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught);
324 _D("Call widget install successfinishedCallback");
325 GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
327 tizenId), Jobs::Exceptions::Success);
330 void JobWidgetInstall::SendFinishedFailure()
332 using namespace PackageManager;
334 // print error message
335 LOGE("Error number: %d", m_exceptionCaught);
336 LOGE("Error message: %s", m_exceptionMessage.c_str());
337 fprintf(stderr, "[Err:%d] %s", m_exceptionCaught, m_exceptionMessage.c_str());
339 TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
341 _D("Call widget install failure finishedCallback");
343 // send signal of pkgmgr
344 GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught, m_exceptionMessage.c_str());
346 GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
348 tizenId), m_exceptionCaught);
351 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
353 m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
354 m_exceptionMessage = e.GetMessage();
357 void JobWidgetInstall::displayWidgetInfo()
359 if (m_installerContext.widgetConfig.webAppType.appType == WrtDB::APP_TYPE_TIZENWEBAPP)
361 WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
363 std::ostringstream out;
364 WidgetLocalizedInfo localizedInfo =
365 W3CFileLocalization::getLocalizedInfo(dao.getTizenAppId());
366 WidgetSize size = dao.getPreferredSize();
367 DPL::OptionalString startFile =
368 W3CFileLocalization::getStartFile(dao.getTizenAppId());
371 "===================================== INSTALLED WIDGET INFO =========" \
372 "============================";
373 if (!!(localizedInfo.name))
374 out << std::endl << "Name: " << *(localizedInfo.name);
376 out << std::endl << "Name: " << "--";
377 out << std::endl << "AppId: " << dao.getTizenAppId();
378 out << std::endl << "Width: " << size.width;
379 out << std::endl << "Height: " << size.height;
381 out << std::endl << "Start File: " << *(startFile);
383 out << std::endl << "Start File: " << "--";
384 if (!!(dao.getVersion()))
385 out << std::endl << "Version: " << *(dao.getVersion());
387 out << std::endl << "Version: " << "--";
388 if (!!(localizedInfo.license))
389 out << std::endl << "Licence: " << *(localizedInfo.license);
391 out << std::endl << "Licence: " << "--";
392 if (!!(localizedInfo.licenseHref))
393 out << std::endl << "Licence Href: " << *(localizedInfo.licenseHref);
395 out << std::endl << "Licence Href: " << "--";
396 if (!!(localizedInfo.description))
397 out << std::endl << "Description: " << *(localizedInfo.description);
399 out << std::endl << "Description: " << "--";
400 if (!!(dao.getGUID()))
401 out << std::endl << "Widget Id: " << *(dao.getGUID());
403 out << std::endl << "Widget Id: " << "--";
405 OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTizenAppId());
406 DPL::OptionalString iconSrc =
407 !!icon ? icon->src : DPL::OptionalString();
409 out << std::endl << "Icon: " << *(iconSrc);
411 out << std::endl << "Icon: " << "--";
413 out << std::endl << "Preferences:";
415 PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
418 out << std::endl << " Key: " <<
420 out << std::endl << " Readonly: " <<
427 _D("%s", out.str().c_str());
431 void JobWidgetInstall::SecureRemove(const bf::path& path)
434 _E("error for get path");
435 ThrowMsg(Jobs::WidgetInstall::Exceptions::RemovingFileFailure, "Try to remove insecure location");
439 const char* blacklist[] = {
446 "/opt/share/widget/",
447 "/opt/share/widget/temp_info",
448 "/opt/share/widget/temp_info/",
449 "/opt/share/packages",
450 "/opt/share/packages/",
451 "/opt/share/applications",
452 "/opt/share/applications/",
460 char* canonicalizeFilePath = canonicalize_file_name(path.c_str());
461 if (!canonicalizeFilePath) {
462 _E("error : a pathname[%s] component is unreadable or does not exist", path.c_str());
463 //ThrowMsg(Jobs::WidgetInstall::Exceptions::RemovingFileFailure, "Try to remove insecure location");
468 while(blacklist[idx]){
469 char* cmpFilePath = canonicalize_file_name(blacklist[idx]);
471 if(!strcmp(canonicalizeFilePath, cmpFilePath)) {
472 _E("illegal access : %s", path.c_str());
474 free(canonicalizeFilePath);
475 ThrowMsg(Jobs::WidgetInstall::Exceptions::RemovingFileFailure, "Try to remove insecure location");
482 free(canonicalizeFilePath);
483 bf::remove_all(path);
485 } //namespace WidgetInstall