7241597cb3fd059f8c3ccc45410e6fbc0a6210c8
[framework/web/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_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
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     const Jobs::WidgetInstall::WidgetInstallationStruct &
74     installerStruct) :
75     Job(Installation),
76     JobContextBase<Jobs::WidgetInstall::WidgetInstallationStruct>(installerStruct),
77     m_exceptionCaught(Jobs::Exceptions::Success)
78 {
79     m_installerContext.mode = m_jobStruct.m_installMode;
80     m_installerContext.requestedPath = widgetPath;
81
82     //start configuration of installation
83     AddTask(new TaskConfiguration(m_installerContext));
84
85     // Init installer context
86     m_installerContext.installStep = InstallerContext::INSTALL_START;
87     m_installerContext.job = this;
88
89     m_installerContext.callerPkgId
90             = DPL::FromUTF8String(m_jobStruct.pkgmgrInterface->getCallerId());
91     _D("Caller Package Id : %s", DPL::ToUTF8String(m_installerContext.callerPkgId).c_str());
92 }
93
94 void JobWidgetInstall::appendNewInstallationTaskList()
95 {
96     _D("Configure installation succeeded");
97     m_installerContext.job->SetProgressFlag(true);
98
99     AddTask(new TaskRecovery(m_installerContext));
100
101     AddTask(new TaskProcessConfig(m_installerContext));
102     if (m_installerContext.widgetConfig.packagingType ==
103         WrtDB::PKG_TYPE_HOSTED_WEB_APP)
104     {
105         AddTask(new TaskPrepareFiles(m_installerContext));
106     }
107     AddTask(new TaskCertify(m_installerContext));
108     AddTask(new TaskCertifyLevel(m_installerContext));
109     if (m_installerContext.needEncryption) {
110         AddTask(new TaskEncryptResource(m_installerContext));
111     }
112     AddTask(new TaskFileManipulation(m_installerContext));
113     AddTask(new TaskManifestFile(m_installerContext));
114     if (m_installerContext.widgetConfig.packagingType ==
115         PKG_TYPE_HYBRID_WEB_APP)
116     {
117         AddTask(new TaskInstallOspsvc(m_installerContext));
118     }
119     AddTask(new TaskDatabase(m_installerContext));
120     AddTask(new TaskAceCheck(m_installerContext));
121     AddTask(new TaskSmack(m_installerContext));
122     AddTask(new TaskPkgInfoUpdate(m_installerContext));
123 }
124
125 void JobWidgetInstall::appendUpdateInstallationTaskList()
126 {
127     _D("Configure installation updated");
128     _D("Widget Update");
129     m_installerContext.job->SetProgressFlag(true);
130
131     if (m_installerContext.mode.command ==
132         InstallMode::Command::REINSTALL)
133     {
134         AddTask(new TaskPrepareReinstall(m_installerContext));
135     }
136
137     AddTask(new TaskProcessConfig(m_installerContext));
138
139     if (m_installerContext.widgetConfig.packagingType ==
140         WrtDB::PKG_TYPE_HOSTED_WEB_APP)
141     {
142         AddTask(new TaskPrepareFiles(m_installerContext));
143     }
144
145     AddTask(new TaskCertify(m_installerContext));
146     AddTask(new TaskCertifyLevel(m_installerContext));
147     if (m_installerContext.needEncryption) {
148         AddTask(new TaskEncryptResource(m_installerContext));
149     }
150
151     if (m_installerContext.mode.extension !=
152             InstallMode::ExtensionType::DIR) {
153         AddTask(new TaskUpdateFiles(m_installerContext));
154         AddTask(new TaskFileManipulation(m_installerContext));
155     }
156
157     AddTask(new TaskManifestFile(m_installerContext));
158     if (m_installerContext.widgetConfig.packagingType ==
159         PKG_TYPE_HYBRID_WEB_APP)
160     {
161         AddTask(new TaskInstallOspsvc(m_installerContext));
162     }
163
164     AddTask(new TaskDatabase(m_installerContext));
165     AddTask(new TaskAceCheck(m_installerContext));
166     //TODO: remove widgetHandle from this task and move before database task
167     // by now widget handle is needed in ace check
168     // Any error in acecheck while update will break widget
169     AddTask(new TaskSmack(m_installerContext));
170     AddTask(new TaskRemoveBackupFiles(m_installerContext));
171     AddTask(new TaskPkgInfoUpdate(m_installerContext));
172 }
173
174 void JobWidgetInstall::SendProgress()
175 {
176     using namespace PackageManager;
177     if (GetProgressFlag() != false) {
178         if (GetInstallerStruct().progressCallback != NULL) {
179             // send progress signal of pkgmgr
180             std::ostringstream percent;
181             percent << static_cast<int>(GetProgressPercent());
182             GetInstallerStruct().pkgmgrInterface->sendSignal(
183                 PKGMGR_PROGRESS_KEY,
184                 percent.str());
185
186             _D("Call widget install progressCallback");
187             GetInstallerStruct().progressCallback(
188                 GetInstallerStruct().userParam,
189                 GetProgressPercent(),
190                 GetProgressDescription());
191         }
192     }
193 }
194
195 void JobWidgetInstall::SendProgressIconPath(const std::string &path)
196 {
197     using namespace PackageManager;
198     if (GetProgressFlag() != false) {
199         if (GetInstallerStruct().progressCallback != NULL) {
200             // send progress signal of pkgmgr
201             GetInstallerStruct().pkgmgrInterface->sendSignal(
202                 PKGMGR_ICON_PATH,
203                 path);
204         }
205     }
206 }
207
208 void JobWidgetInstall::SendFinishedSuccess()
209 {
210     using namespace PackageManager;
211     // TODO : sync should move to separate task.
212     sync();
213
214     if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) {
215         if (m_installerContext.isUpdateMode) {
216             WidgetInstallToExtSingleton::Instance().postUpgrade(true);
217         } else {
218             WidgetInstallToExtSingleton::Instance().postInstallation(true);
219         }
220         WidgetInstallToExtSingleton::Instance().deinitialize();
221     }
222
223     // remove widget install information file
224     unlink(m_installerContext.installInfo.c_str());
225
226     //inform widget info
227     JobWidgetInstall::displayWidgetInfo();
228
229     TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
230
231     // send signal of pkgmgr
232     GetInstallerStruct().pkgmgrInterface->sendSignal(
233         PKGMGR_END_KEY,
234         PKGMGR_END_SUCCESS);
235
236     _D("Call widget install successfinishedCallback");
237     GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
238                                           DPL::ToUTF8String(
239                                               tizenId), Jobs::Exceptions::Success);
240 }
241
242 void JobWidgetInstall::SendFinishedFailure()
243 {
244     using namespace PackageManager;
245     // remove widget install information file
246     unlink(m_installerContext.installInfo.c_str());
247
248     _E("Error number: %d", m_exceptionCaught);
249     _E("Message: %s", m_exceptionMessage.c_str());
250     TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
251
252     _D("Call widget install failure finishedCallback");
253     std::stringstream errorNum;
254     errorNum << m_exceptionCaught;
255
256     // send signal of pkgmgr
257     GetInstallerStruct().pkgmgrInterface->sendSignal(
258         PKGMGR_ERROR,
259         errorNum.str());
260
261     GetInstallerStruct().pkgmgrInterface->sendSignal(
262         PKGMGR_END_KEY,
263         PKGMGR_END_FAILURE);
264
265     GetInstallerStruct().finishedCallback(GetInstallerStruct().userParam,
266                                           DPL::ToUTF8String(
267                                               tizenId), m_exceptionCaught);
268 }
269
270 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
271 {
272     m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
273     m_exceptionMessage = e.GetMessage();
274 }
275
276 void JobWidgetInstall::displayWidgetInfo()
277 {
278     WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
279
280     std::ostringstream out;
281     WidgetLocalizedInfo localizedInfo =
282         W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
283
284     out << std::endl <<
285     "===================================== INSTALLED WIDGET INFO =========" \
286     "============================";
287     out << std::endl << "Name:                        " << localizedInfo.name;
288     out << std::endl << "AppId:                     " << dao.getTzAppId();
289     WidgetSize size = dao.getPreferredSize();
290     out << std::endl << "Width:                       " << size.width;
291     out << std::endl << "Height:                      " << size.height;
292     out << std::endl << "Start File:                  " <<
293     W3CFileLocalization::getStartFile(dao.getTzAppId());
294     out << std::endl << "Version:                     " << dao.getVersion();
295     out << std::endl << "Licence:                     " <<
296     localizedInfo.license;
297     out << std::endl << "Licence Href:                " <<
298     localizedInfo.licenseHref;
299     out << std::endl << "Description:                 " <<
300     localizedInfo.description;
301     out << std::endl << "Widget Id:                   " << dao.getGUID();
302     out << std::endl << "Widget recognized:           " << dao.isRecognized();
303     out << std::endl << "Widget distributor signed:   " <<
304     dao.isDistributorSigned();
305     out << std::endl << "Widget trusted:              " << dao.isTrusted();
306
307     OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
308     DPL::OptionalString iconSrc =
309         !!icon ? icon->src : DPL::OptionalString::Null;
310     out << std::endl << "Icon:                        " << iconSrc;
311
312     out << std::endl << "Preferences:";
313     {
314         PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
315         FOREACH(it, list)
316         {
317             out << std::endl << "  Key:                       " <<
318             it->key_name;
319             out << std::endl << "      Readonly:              " <<
320             it->readonly;
321         }
322     }
323
324     out << std::endl << "Features:";
325     {
326         WidgetFeatureSet list = dao.getFeaturesList();
327         FOREACH(it, list)
328         {
329             out << std::endl << "  Name:                      " << it->name;
330         }
331     }
332
333     out << std::endl;
334
335     _D("%s", out.str().c_str());
336 }
337 } //namespace WidgetInstall
338 } //namespace Jobs