14e01c5e28939738003b65e6d24f79256c313b16
[framework/web/wrt-installer.git] / src_wearable / jobs / widget_install / job_widget_install.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 /*
17  * @file    job_widget_install.cpp
18  * @author  Radoslaw Wicik r.wicik@samsung.com
19  * @author  Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
20  * @version 1.0
21  * @brief   Implementation file for main installer task
22  */
23 #include <string>
24 #include <sys/time.h>
25 #include <ctime>
26 #include <cstdlib>
27 #include <limits.h>
28 #include <regex.h>
29
30 #include <dpl/utils/wrt_utility.h>
31 #include <dpl/utils/path.h>
32 #include <dpl/localization/w3c_file_localization.h>
33
34 #include <pkg-manager/pkgmgr_signal.h>
35 #include <app_manager.h>
36
37 #include "root_parser.h"
38 #include "widget_parser.h"
39 #include "parser_runner.h"
40 #include <widget_install/job_widget_install.h>
41 #include <widget_install/task_certify.h>
42 #include <widget_install/task_certify_level.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
62 #include <widget_install_to_external.h>
63 #include <widget_install/widget_unzip.h>
64
65 #include <installer_log.h>
66
67 using namespace WrtDB;
68 using namespace Jobs::Exceptions;
69
70 namespace Jobs {
71 namespace WidgetInstall {
72
73 JobWidgetInstall::JobWidgetInstall(
74     std::string const &widgetPath,
75     std::string const &tzPkgId,
76     const Jobs::WidgetInstall::WidgetInstallationStruct &
77     installerStruct) :
78     Job(UnknownInstallation),
79     JobContextBase<Jobs::WidgetInstall::WidgetInstallationStruct>(installerStruct),
80     m_exceptionCaught(Jobs::Exceptions::Success)
81 {
82     m_installerContext.mode = m_jobStruct.m_installMode;
83     m_installerContext.requestedPath = widgetPath;
84     m_jobStruct.pkgmgrInterface->setPkgname(tzPkgId);
85
86     if (InstallMode::Command::RECOVERY == m_installerContext.mode.command) {
87         m_installerContext.widgetConfig.tzPkgid = DPL::FromUTF8String(tzPkgId);
88         AddTask(new TaskRecovery(m_installerContext));
89     }
90
91     //start configuration of installation
92     AddTask(new TaskConfiguration(m_installerContext));
93
94     // Init installer context
95     m_installerContext.installStep = InstallerContext::INSTALL_START;
96     m_installerContext.job = this;
97
98     m_installerContext.callerPkgId
99             = DPL::FromUTF8String(m_jobStruct.pkgmgrInterface->getCallerId());
100     _D("Caller Package Id : %s", DPL::ToUTF8String(m_installerContext.callerPkgId).c_str());
101 }
102
103 void JobWidgetInstall::appendNewInstallationTaskList()
104 {
105     _D("Configure installation succeeded");
106     m_installerContext.job->SetProgressFlag(true);
107
108     AddTask(new TaskFileManipulation(m_installerContext));
109     AddTask(new TaskProcessConfig(m_installerContext));
110     if (m_installerContext.widgetConfig.packagingType ==
111         WrtDB::PKG_TYPE_HOSTED_WEB_APP)
112     {
113         AddTask(new TaskPrepareFiles(m_installerContext));
114     }
115     AddTask(new TaskCertify(m_installerContext));
116     AddTask(new TaskCertifyLevel(m_installerContext));
117     AddTask(new TaskUserDataManipulation(m_installerContext));
118     if (m_installerContext.needEncryption) {
119         AddTask(new TaskEncryptResource(m_installerContext));
120     }
121     AddTask(new TaskManifestFile(m_installerContext));
122     if (m_installerContext.widgetConfig.packagingType ==
123         PKG_TYPE_HYBRID_WEB_APP) {
124         AddTask(new TaskInstallOspsvc(m_installerContext));
125     }
126     AddTask(new TaskDatabase(m_installerContext));
127     AddTask(new TaskAceCheck(m_installerContext));
128     AddTask(new TaskSmack(m_installerContext));
129     AddTask(new TaskPkgInfoUpdate(m_installerContext));
130 }
131
132 void JobWidgetInstall::appendUpdateInstallationTaskList()
133 {
134     _D("Configure installation updated");
135     _D("Widget Update");
136     m_installerContext.job->SetProgressFlag(true);
137     AddTask(new TaskStatusCheck(m_installerContext));
138
139     if (m_installerContext.mode.command ==
140         InstallMode::Command::REINSTALL) {
141         AddTask(new TaskPrepareReinstall(m_installerContext));
142     }
143
144     if (m_installerContext.mode.extension !=
145             InstallMode::ExtensionType::DIR) {
146         AddTask(new TaskUpdateFiles(m_installerContext));
147         AddTask(new TaskFileManipulation(m_installerContext));
148     }
149
150     AddTask(new TaskProcessConfig(m_installerContext));
151
152     if (m_installerContext.widgetConfig.packagingType ==
153         WrtDB::PKG_TYPE_HOSTED_WEB_APP) {
154         AddTask(new TaskPrepareFiles(m_installerContext));
155     }
156
157     AddTask(new TaskCertify(m_installerContext));
158     AddTask(new TaskCertifyLevel(m_installerContext));
159     AddTask(new TaskUserDataManipulation(m_installerContext));
160     if (m_installerContext.needEncryption) {
161         AddTask(new TaskEncryptResource(m_installerContext));
162     }
163     AddTask(new TaskManifestFile(m_installerContext));
164     if (m_installerContext.widgetConfig.packagingType ==
165         PKG_TYPE_HYBRID_WEB_APP) {
166         AddTask(new TaskInstallOspsvc(m_installerContext));
167     }
168
169     AddTask(new TaskDatabase(m_installerContext));
170     AddTask(new TaskAceCheck(m_installerContext));
171     //TODO: remove widgetHandle from this task and move before database task
172     // by now widget handle is needed in ace check
173     // Any error in acecheck while update will break widget
174     AddTask(new TaskSmack(m_installerContext));
175     AddTask(new TaskRemoveBackupFiles(m_installerContext));
176     AddTask(new TaskPkgInfoUpdate(m_installerContext));
177 }
178
179 void JobWidgetInstall::appendRDSUpdateTaskList()
180 {
181     _D("Configure installation RDS updated");
182     m_installerContext.job->SetProgressFlag(true);
183     AddTask(new TaskStatusCheck(m_installerContext));
184     AddTask(new TaskPrepareReinstall(m_installerContext));
185     AddTask(new TaskCertify(m_installerContext));
186 }
187
188 void JobWidgetInstall::appendRecoveryTaskList()
189 {
190     _D("Recovery Task");
191     m_installerContext.job->SetProgressFlag(true);
192
193     AddTask(new TaskProcessConfig(m_installerContext));
194
195     AddTask(new TaskCertify(m_installerContext));
196     AddTask(new TaskCertifyLevel(m_installerContext));
197     AddTask(new TaskManifestFile(m_installerContext));
198     if (m_installerContext.widgetConfig.packagingType ==
199         PKG_TYPE_HYBRID_WEB_APP) {
200         AddTask(new TaskInstallOspsvc(m_installerContext));
201     }
202     AddTask(new TaskSmack(m_installerContext));
203 }
204
205 void JobWidgetInstall::appendFotaInstallationTaskList()
206 {
207     /* TODO */
208     _D("Configure installation succeeded");
209     m_installerContext.job->SetProgressFlag(true);
210
211     AddTask(new TaskProcessConfig(m_installerContext));
212     AddTask(new TaskCertify(m_installerContext));
213     AddTask(new TaskCertifyLevel(m_installerContext));
214     AddTask(new TaskUserDataManipulation(m_installerContext));
215     if (m_installerContext.needEncryption) {
216         AddTask(new TaskEncryptResource(m_installerContext));
217     }
218     AddTask(new TaskManifestFile(m_installerContext));
219     if (m_installerContext.widgetConfig.packagingType ==
220         PKG_TYPE_HYBRID_WEB_APP)
221     {
222         AddTask(new TaskInstallOspsvc(m_installerContext));
223     }
224     AddTask(new TaskDatabase(m_installerContext));
225     AddTask(new TaskAceCheck(m_installerContext));
226     AddTask(new TaskSmack(m_installerContext));
227     AddTask(new TaskRemoveBackupFiles(m_installerContext));
228     AddTask(new TaskPkgInfoUpdate(m_installerContext));
229 }
230
231 void JobWidgetInstall::appendFotaUpdateTaskList()
232 {
233     _D("Configure installation updated");
234     _D("Widget Update");
235     m_installerContext.job->SetProgressFlag(true);
236
237     AddTask(new TaskProcessConfig(m_installerContext));
238     AddTask(new TaskCertify(m_installerContext));
239     AddTask(new TaskCertifyLevel(m_installerContext));
240     AddTask(new TaskUserDataManipulation(m_installerContext));
241     if (m_installerContext.needEncryption) {
242         AddTask(new TaskEncryptResource(m_installerContext));
243     }
244
245     AddTask(new TaskManifestFile(m_installerContext));
246     if (m_installerContext.widgetConfig.packagingType ==
247         PKG_TYPE_HYBRID_WEB_APP)
248     {
249         AddTask(new TaskInstallOspsvc(m_installerContext));
250     }
251
252     AddTask(new TaskDatabase(m_installerContext));
253     AddTask(new TaskAceCheck(m_installerContext));
254     //TODO: remove widgetHandle from this task and move before database task
255     // by now widget handle is needed in ace check
256     // Any error in acecheck while update will break widget
257     AddTask(new TaskSmack(m_installerContext));
258     AddTask(new TaskRemoveBackupFiles(m_installerContext));
259     AddTask(new TaskPkgInfoUpdate(m_installerContext));
260 }
261
262 void JobWidgetInstall::SendProgress()
263 {
264     using namespace PackageManager;
265     if (GetProgressFlag() != false) {
266         if (GetInstallerStruct().progressCallback != NULL) {
267             // send progress signal of pkgmgr
268             GetInstallerStruct().pkgmgrInterface->sendProgress(GetProgressPercent());
269
270             _D("Call widget install progressCallback");
271             GetInstallerStruct().progressCallback(
272                 GetInstallerStruct().userParam,
273                 GetProgressPercent(),
274                 GetProgressDescription());
275         }
276     }
277 }
278
279 void JobWidgetInstall::SendProgressIconPath(const std::string &path)
280 {
281     using namespace PackageManager;
282     if (GetProgressFlag() != false) {
283         if (GetInstallerStruct().progressCallback != NULL) {
284             // send progress signal of pkgmgr
285             GetInstallerStruct().pkgmgrInterface->sendIconPath(path);
286         }
287     }
288 }
289
290 void JobWidgetInstall::SendFinishedSuccess()
291 {
292     using namespace PackageManager;
293     // TODO : sync should move to separate task.
294     sync();
295
296     if (INSTALL_LOCATION_TYPE_PREFER_EXTERNAL == m_installerContext.locationType) {
297         if (m_installerContext.isUpdateMode) {
298             WidgetInstallToExtSingleton::Instance().postUpgrade(true);
299         } else {
300             WidgetInstallToExtSingleton::Instance().postInstallation(true);
301         }
302         WidgetInstallToExtSingleton::Instance().deinitialize();
303     }
304
305     // remove widget install information file
306     unlink(m_installerContext.installInfo.c_str());
307
308     //inform widget info
309     JobWidgetInstall::displayWidgetInfo();
310
311     TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
312
313     // send signal of pkgmgr
314     GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught);
315
316     _D("Call widget install successfinishedCallback");
317     GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
318                                           DPL::ToUTF8String(
319                                               tizenId), Jobs::Exceptions::Success);
320 }
321
322 void JobWidgetInstall::SendFinishedFailure()
323 {
324     using namespace PackageManager;
325     // remove widget install information file
326     unlink(m_installerContext.installInfo.c_str());
327
328     // print error message
329     LOGE(COLOR_ERROR "Error number: %d" COLOR_END, m_exceptionCaught);
330     LOGE(COLOR_ERROR "Message: %s" COLOR_END, m_exceptionMessage.c_str());
331     fprintf(stderr, "[Err:%d] %s", m_exceptionCaught, m_exceptionMessage.c_str());
332
333     TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
334
335     _D("Call widget install failure finishedCallback");
336
337     // send signal of pkgmgr
338     GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught);
339
340     GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
341                                           DPL::ToUTF8String(
342                                               tizenId), m_exceptionCaught);
343 }
344
345 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
346 {
347     m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
348     m_exceptionMessage = e.GetMessage();
349 }
350 void JobWidgetInstall::displayWidgetInfo()
351 {
352     if (m_installerContext.widgetConfig.webAppType.appType == WrtDB::APP_TYPE_TIZENWEBAPP)
353     {
354         WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
355
356         std::ostringstream out;
357         WidgetLocalizedInfo localizedInfo =
358             W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
359
360         out << std::endl <<
361         "===================================== INSTALLED WIDGET INFO =========" \
362         "============================";
363         out << std::endl << "Name:                        " << localizedInfo.name;
364         out << std::endl << "AppId:                     " << dao.getTzAppId();
365         WidgetSize size = dao.getPreferredSize();
366         out << std::endl << "Width:                       " << size.width;
367         out << std::endl << "Height:                      " << size.height;
368         out << std::endl << "Start File:                  " <<
369         W3CFileLocalization::getStartFile(dao.getTzAppId());
370         out << std::endl << "Version:                     " << dao.getVersion();
371         out << std::endl << "Licence:                     " <<
372         localizedInfo.license;
373         out << std::endl << "Licence Href:                " <<
374         localizedInfo.licenseHref;
375         out << std::endl << "Description:                 " <<
376         localizedInfo.description;
377         out << std::endl << "Widget Id:                   " << dao.getGUID();
378
379         OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
380         DPL::OptionalString iconSrc =
381             !!icon ? icon->src : DPL::OptionalString::Null;
382         out << std::endl << "Icon:                        " << iconSrc;
383
384         out << std::endl << "Preferences:";
385         {
386             PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
387             FOREACH(it, list)
388             {
389                 out << std::endl << "  Key:                       " <<
390                 it->key_name;
391                 out << std::endl << "      Readonly:              " <<
392                 it->readonly;
393             }
394         }
395
396         out << std::endl;
397
398         _D("%s", out.str().c_str());
399     }
400 }
401 } //namespace WidgetInstall
402 } //namespace Jobs