Tizen 2.4.0 rev3 SDK Public Release
[framework/web/wearable/wrt-installer.git] / src / 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_process_config.h>
43 #include <widget_install/task_file_manipulation.h>
44 #include <widget_install/task_ace_check.h>
45 #include <widget_install/task_smack.h>
46 #include <widget_install/task_manifest_file.h>
47 #include <widget_install/task_prepare_files.h>
48 #include <widget_install/task_recovery.h>
49 #include <widget_install/task_install_ospsvc.h>
50 #include <widget_install/task_update_files.h>
51 #include <widget_install/task_database.h>
52 #include <widget_install/task_remove_backup.h>
53 #include <widget_install/task_encrypt_resource.h>
54 #include <widget_install/task_pkg_info_update.h>
55 #include <widget_install/task_commons.h>
56 #include <widget_install/task_prepare_reinstall.h>
57 #include <widget_install/task_configuration.h>
58 #include <widget_install/task_user_data_manipulation.h>
59 #include <widget_install/task_status_check.h>
60 #include <widget_install_to_external.h>
61 #include <widget_install/widget_unzip.h>
62
63 #include <installer_log.h>
64
65 using namespace WrtDB;
66 using namespace Jobs::Exceptions;
67
68 namespace Jobs {
69 namespace WidgetInstall {
70
71 JobWidgetInstall::JobWidgetInstall(
72     std::string const &widgetPath,
73     std::string const &tzPkgId,
74     const Jobs::WidgetInstall::WidgetInstallationStruct &
75     installerStruct) :
76     Job(UnknownInstallation),
77     JobContextBase<Jobs::WidgetInstall::WidgetInstallationStruct>(installerStruct),
78     m_exceptionCaught(Jobs::Exceptions::Success)
79 {
80     m_installerContext.mode = m_jobStruct.m_installMode;
81     m_installerContext.requestedPath = widgetPath;
82     m_jobStruct.pkgmgrInterface->setPkgname(tzPkgId);
83
84     if (InstallMode::Command::RECOVERY == m_installerContext.mode.command) {
85         m_installerContext.widgetConfig.tzPkgid = DPL::FromUTF8String(tzPkgId);
86         AddTask(new TaskRecovery(m_installerContext));
87     }
88
89     //start configuration of installation
90     AddTask(new TaskConfiguration(m_installerContext));
91
92     // Init installer context
93     m_installerContext.installStep = InstallerContext::INSTALL_START;
94     m_installerContext.job = this;
95
96     m_installerContext.callerPkgId
97             = DPL::FromUTF8String(m_jobStruct.pkgmgrInterface->getCallerId());
98     _D("Caller Package Id : %s", DPL::ToUTF8String(m_installerContext.callerPkgId).c_str());
99 }
100
101 void JobWidgetInstall::appendNewInstallationTaskList()
102 {
103     _D("Configure installation succeeded");
104     m_installerContext.job->SetProgressFlag(true);
105
106     AddTask(new TaskFileManipulation(m_installerContext));
107     AddTask(new TaskProcessConfig(m_installerContext));
108     if (m_installerContext.widgetConfig.packagingType ==
109         WrtDB::PKG_TYPE_HOSTED_WEB_APP)
110     {
111         AddTask(new TaskPrepareFiles(m_installerContext));
112     }
113     AddTask(new TaskCertify(m_installerContext));
114     AddTask(new TaskUserDataManipulation(m_installerContext));
115     if (m_installerContext.needEncryption) {
116         AddTask(new TaskEncryptResource(m_installerContext));
117     }
118     AddTask(new TaskManifestFile(m_installerContext));
119     if (m_installerContext.widgetConfig.packagingType ==
120         PKG_TYPE_HYBRID_WEB_APP) {
121         AddTask(new TaskInstallOspsvc(m_installerContext));
122     }
123     AddTask(new TaskDatabase(m_installerContext));
124     AddTask(new TaskAceCheck(m_installerContext));
125     AddTask(new TaskSmack(m_installerContext));
126     AddTask(new TaskPkgInfoUpdate(m_installerContext));
127 }
128
129 void JobWidgetInstall::appendUpdateInstallationTaskList()
130 {
131     _D("Configure installation updated");
132     _D("Widget Update");
133     m_installerContext.job->SetProgressFlag(true);
134     AddTask(new TaskStatusCheck(m_installerContext));
135
136     if (m_installerContext.mode.command ==
137         InstallMode::Command::REINSTALL) {
138         AddTask(new TaskPrepareReinstall(m_installerContext));
139     }
140
141     if (m_installerContext.mode.extension !=
142             InstallMode::ExtensionType::DIR) {
143         AddTask(new TaskUpdateFiles(m_installerContext));
144         AddTask(new TaskFileManipulation(m_installerContext));
145     }
146
147     AddTask(new TaskProcessConfig(m_installerContext));
148
149     if (m_installerContext.widgetConfig.packagingType ==
150         WrtDB::PKG_TYPE_HOSTED_WEB_APP) {
151         AddTask(new TaskPrepareFiles(m_installerContext));
152     }
153
154     AddTask(new TaskCertify(m_installerContext));
155     AddTask(new TaskUserDataManipulation(m_installerContext));
156     if (m_installerContext.needEncryption) {
157         AddTask(new TaskEncryptResource(m_installerContext));
158     }
159     AddTask(new TaskManifestFile(m_installerContext));
160     if (m_installerContext.widgetConfig.packagingType ==
161         PKG_TYPE_HYBRID_WEB_APP) {
162         AddTask(new TaskInstallOspsvc(m_installerContext));
163     }
164
165     AddTask(new TaskDatabase(m_installerContext));
166     AddTask(new TaskAceCheck(m_installerContext));
167     //TODO: remove widgetHandle from this task and move before database task
168     // by now widget handle is needed in ace check
169     // Any error in acecheck while update will break widget
170     AddTask(new TaskSmack(m_installerContext));
171     AddTask(new TaskRemoveBackupFiles(m_installerContext));
172     AddTask(new TaskPkgInfoUpdate(m_installerContext));
173 }
174
175 void JobWidgetInstall::appendRDSUpdateTaskList()
176 {
177     _D("Configure installation RDS updated");
178     m_installerContext.job->SetProgressFlag(true);
179     AddTask(new TaskStatusCheck(m_installerContext));
180     AddTask(new TaskPrepareReinstall(m_installerContext));
181     AddTask(new TaskCertify(m_installerContext));
182 }
183
184 void JobWidgetInstall::appendRecoveryTaskList()
185 {
186     _D("Recovery Task");
187     m_installerContext.job->SetProgressFlag(true);
188
189     AddTask(new TaskProcessConfig(m_installerContext));
190
191     AddTask(new TaskCertify(m_installerContext));
192     AddTask(new TaskManifestFile(m_installerContext));
193     if (m_installerContext.widgetConfig.packagingType ==
194         PKG_TYPE_HYBRID_WEB_APP) {
195         AddTask(new TaskInstallOspsvc(m_installerContext));
196     }
197     AddTask(new TaskSmack(m_installerContext));
198 }
199
200 void JobWidgetInstall::appendFotaInstallationTaskList()
201 {
202     /* TODO */
203     _D("Configure installation succeeded");
204     m_installerContext.job->SetProgressFlag(true);
205
206     AddTask(new TaskProcessConfig(m_installerContext));
207     AddTask(new TaskCertify(m_installerContext));
208     AddTask(new TaskUserDataManipulation(m_installerContext));
209     if (m_installerContext.needEncryption) {
210         AddTask(new TaskEncryptResource(m_installerContext));
211     }
212     AddTask(new TaskManifestFile(m_installerContext));
213     if (m_installerContext.widgetConfig.packagingType ==
214         PKG_TYPE_HYBRID_WEB_APP)
215     {
216         AddTask(new TaskInstallOspsvc(m_installerContext));
217     }
218     AddTask(new TaskDatabase(m_installerContext));
219     AddTask(new TaskAceCheck(m_installerContext));
220     AddTask(new TaskSmack(m_installerContext));
221     AddTask(new TaskRemoveBackupFiles(m_installerContext));
222     AddTask(new TaskPkgInfoUpdate(m_installerContext));
223 }
224
225 void JobWidgetInstall::appendFotaUpdateTaskList()
226 {
227     _D("Configure installation updated");
228     _D("Widget Update");
229     m_installerContext.job->SetProgressFlag(true);
230
231     AddTask(new TaskProcessConfig(m_installerContext));
232     AddTask(new TaskCertify(m_installerContext));
233     AddTask(new TaskUserDataManipulation(m_installerContext));
234     if (m_installerContext.needEncryption) {
235         AddTask(new TaskEncryptResource(m_installerContext));
236     }
237
238     AddTask(new TaskManifestFile(m_installerContext));
239     if (m_installerContext.widgetConfig.packagingType ==
240         PKG_TYPE_HYBRID_WEB_APP)
241     {
242         AddTask(new TaskInstallOspsvc(m_installerContext));
243     }
244
245     AddTask(new TaskDatabase(m_installerContext));
246     AddTask(new TaskAceCheck(m_installerContext));
247     //TODO: remove widgetHandle from this task and move before database task
248     // by now widget handle is needed in ace check
249     // Any error in acecheck while update will break widget
250     AddTask(new TaskSmack(m_installerContext));
251     AddTask(new TaskRemoveBackupFiles(m_installerContext));
252     AddTask(new TaskPkgInfoUpdate(m_installerContext));
253 }
254
255 void JobWidgetInstall::SendProgress()
256 {
257     using namespace PackageManager;
258     if (GetProgressFlag() != false) {
259         if (GetInstallerStruct().progressCallback != NULL) {
260             // send progress signal of pkgmgr
261             GetInstallerStruct().pkgmgrInterface->sendProgress(GetProgressPercent());
262
263             _D("Call widget install progressCallback");
264             GetInstallerStruct().progressCallback(
265                 GetInstallerStruct().userParam,
266                 GetProgressPercent(),
267                 GetProgressDescription());
268         }
269     }
270 }
271
272 void JobWidgetInstall::SendProgressIconPath(const std::string &path)
273 {
274     using namespace PackageManager;
275     if (GetProgressFlag() != false) {
276         if (GetInstallerStruct().progressCallback != NULL) {
277             // send progress signal of pkgmgr
278             GetInstallerStruct().pkgmgrInterface->sendIconPath(path);
279         }
280     }
281 }
282
283 void JobWidgetInstall::SendFinishedSuccess()
284 {
285     using namespace PackageManager;
286     // TODO : sync should move to separate task.
287     sync();
288
289     if (INSTALL_LOCATION_TYPE_PREFER_EXTERNAL == m_installerContext.locationType) {
290         if (m_installerContext.isUpdateMode) {
291             WidgetInstallToExtSingleton::Instance().postUpgrade(true);
292         } else {
293             WidgetInstallToExtSingleton::Instance().postInstallation(true);
294         }
295         WidgetInstallToExtSingleton::Instance().deinitialize();
296     }
297
298     //inform widget info
299     JobWidgetInstall::displayWidgetInfo();
300
301     TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
302
303     // send signal of pkgmgr
304     GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught);
305
306     _D("Call widget install successfinishedCallback");
307     GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
308                                           DPL::ToUTF8String(
309                                               tizenId), Jobs::Exceptions::Success);
310 }
311
312 void JobWidgetInstall::SendFinishedFailure()
313 {
314     using namespace PackageManager;
315
316     // print error message
317     LOGE(COLOR_ERROR "Error number: %d" COLOR_END, m_exceptionCaught);
318     LOGE(COLOR_ERROR "Message: %s" COLOR_END, m_exceptionMessage.c_str());
319     fprintf(stderr, "[Err:%d] %s", m_exceptionCaught, m_exceptionMessage.c_str());
320
321     TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
322
323     _D("Call widget install failure finishedCallback");
324
325     // send signal of pkgmgr
326     GetInstallerStruct().pkgmgrInterface->endJob(m_exceptionCaught, m_exceptionMessage.c_str());
327
328     GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
329                                           DPL::ToUTF8String(
330                                               tizenId), m_exceptionCaught);
331 }
332
333 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
334 {
335     m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
336     m_exceptionMessage = e.GetMessage();
337 }
338
339 void JobWidgetInstall::displayWidgetInfo()
340 {
341     if (m_installerContext.widgetConfig.webAppType.appType == WrtDB::APP_TYPE_TIZENWEBAPP)
342     {
343         WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
344
345         std::ostringstream out;
346         WidgetLocalizedInfo localizedInfo =
347         W3CFileLocalization::getLocalizedInfo(dao.getTizenAppId());
348
349         out << std::endl <<
350         "===================================== INSTALLED WIDGET INFO =========" \
351         "============================";
352         out << std::endl << "Name:                        " << localizedInfo.name;
353     out << std::endl << "AppId:                     " << dao.getTizenAppId();
354         WidgetSize size = dao.getPreferredSize();
355         out << std::endl << "Width:                       " << size.width;
356         out << std::endl << "Height:                      " << size.height;
357         out << std::endl << "Start File:                  " <<
358     W3CFileLocalization::getStartFile(dao.getTizenAppId());
359         out << std::endl << "Version:                     " << dao.getVersion();
360         out << std::endl << "Licence:                     " <<
361         localizedInfo.license;
362         out << std::endl << "Licence Href:                " <<
363         localizedInfo.licenseHref;
364         out << std::endl << "Description:                 " <<
365         localizedInfo.description;
366         out << std::endl << "Widget Id:                   " << dao.getGUID();
367
368     OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTizenAppId());
369         DPL::OptionalString iconSrc =
370             !!icon ? icon->src : DPL::OptionalString::Null;
371         out << std::endl << "Icon:                        " << iconSrc;
372
373         out << std::endl << "Preferences:";
374         {
375             PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
376             FOREACH(it, list)
377             {
378                 out << std::endl << "  Key:                       " <<
379                 it->key_name;
380                 out << std::endl << "      Readonly:              " <<
381                 it->readonly;
382             }
383         }
384
385         out << std::endl;
386
387         _D("%s", out.str().c_str());
388     }
389 }
390 } //namespace WidgetInstall
391 } //namespace Jobs