[Release] wrt-installer_0.1.121
[platform/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/abstract_waitable_input_adapter.h>
31 #include <dpl/abstract_waitable_output_adapter.h>
32 #include <dpl/zip_input.h>
33 #include <dpl/binary_queue.h>
34 #include <dpl/copy.h>
35 #include <dpl/assert.h>
36 #include <dpl/sstream.h>
37 #include <dpl/file_input.h>
38 #include <dpl/utils/wrt_utility.h>
39 #include <dpl/utils/path.h>
40 #include <dpl/wrt-dao-ro/common_dao_types.h>
41 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
42 #include <dpl/wrt-dao-ro/global_config.h>
43 #include <dpl/wrt-dao-ro/config_parser_data.h>
44 #include <dpl/wrt-dao-rw/global_dao.h> // TODO remove
45 #include <dpl/localization/w3c_file_localization.h>
46
47 #include <libiriwrapper.h>
48 #include <pkg-manager/pkgmgr_signal.h>
49 #include <app_manager.h>
50
51 #include "root_parser.h"
52 #include "widget_parser.h"
53 #include "parser_runner.h"
54 #include <widget_install/job_widget_install.h>
55 #include <widget_install/task_certify.h>
56 #include <widget_install/task_certify_level.h>
57 #include <widget_install/task_widget_config.h>
58 #include <widget_install/task_file_manipulation.h>
59 #include <widget_install/task_ace_check.h>
60 #include <widget_install/task_smack.h>
61 #include <widget_install/task_manifest_file.h>
62 #include <widget_install/task_prepare_files.h>
63 #include <widget_install/task_recovery.h>
64 #include <widget_install/task_install_ospsvc.h>
65 #include <widget_install/task_update_files.h>
66 #include <widget_install/task_database.h>
67 #include <widget_install/task_remove_backup.h>
68 #include <widget_install/task_encrypt_resource.h>
69 #include <widget_install/task_pkg_info_update.h>
70 #include <widget_install/task_commons.h>
71 #include <widget_install/task_prepare_reinstall.h>
72 #include <widget_install/task_configuration.h>
73 #include <widget_install/task_installer_fail.h>
74
75 #include <widget_install/widget_install_errors.h>
76 #include <widget_install/widget_install_context.h>
77 #include <widget_install_to_external.h>
78 #include <widget_install/widget_unzip.h>
79
80 using namespace WrtDB;
81 using namespace Jobs::Exceptions;
82
83 namespace Jobs {
84 namespace WidgetInstall {
85
86 JobWidgetInstall::JobWidgetInstall(
87     std::string const &widgetPath,
88     const WidgetInstallationStruct &
89     installerStruct) :
90     Job(Installation),
91     JobContextBase<WidgetInstallationStruct>(installerStruct),
92     m_exceptionCaught(Jobs::Exceptions::Success)
93 {
94     m_installerContext.mode = m_jobStruct.m_installMode;
95     m_installerContext.requestedPath = widgetPath;
96
97     //start configuration of installation
98     AddTask(new TaskConfiguration(m_installerContext));
99
100     // Init installer context
101     m_installerContext.installStep = InstallerContext::INSTALL_START;
102     m_installerContext.job = this;
103     m_installerContext.widgetConfig.shareHref = std::string();
104 }
105
106 void JobWidgetInstall::appendNewInstallationTaskList()
107 {
108     LogDebug("Configure installation succeeded");
109     m_installerContext.job->SetProgressFlag(true);
110
111     AddTask(new TaskRecovery(m_installerContext));
112
113     AddTask(new TaskWidgetConfig(m_installerContext));
114     if (m_installerContext.widgetConfig.packagingType ==
115         WrtDB::PKG_TYPE_HOSTED_WEB_APP)
116     {
117         AddTask(new TaskPrepareFiles(m_installerContext));
118     }
119     AddTask(new TaskCertify(m_installerContext));
120     AddTask(new TaskCertifyLevel(m_installerContext));
121     if (m_installerContext.needEncryption) {
122         AddTask(new TaskEncryptResource(m_installerContext));
123     }
124     AddTask(new TaskFileManipulation(m_installerContext));
125     AddTask(new TaskManifestFile(m_installerContext));
126     if (m_installerContext.widgetConfig.packagingType ==
127         PKG_TYPE_HYBRID_WEB_APP)
128     {
129         AddTask(new TaskInstallOspsvc(m_installerContext));
130     }
131     AddTask(new TaskDatabase(m_installerContext));
132     AddTask(new TaskAceCheck(m_installerContext));
133     AddTask(new TaskSmack(m_installerContext));
134     AddTask(new TaskPkgInfoUpdate(m_installerContext));
135 }
136
137 void JobWidgetInstall::appendUpdateInstallationTaskList()
138 {
139     LogDebug("Configure installation updated");
140     LogDebug("Widget Update");
141     m_installerContext.job->SetProgressFlag(true);
142
143     if (m_installerContext.mode.command ==
144         InstallMode::Command::REINSTALL)
145     {
146         AddTask(new TaskPrepareReinstall(m_installerContext));
147     }
148
149     AddTask(new TaskWidgetConfig(m_installerContext));
150
151     if (m_installerContext.widgetConfig.packagingType ==
152         WrtDB::PKG_TYPE_HOSTED_WEB_APP)
153     {
154         AddTask(new TaskPrepareFiles(m_installerContext));
155     }
156
157     AddTask(new TaskCertify(m_installerContext));
158     AddTask(new TaskCertifyLevel(m_installerContext));
159     if (m_installerContext.needEncryption) {
160         AddTask(new TaskEncryptResource(m_installerContext));
161     }
162
163     if (m_installerContext.mode.extension !=
164             InstallMode::ExtensionType::DIR) {
165         AddTask(new TaskUpdateFiles(m_installerContext));
166         AddTask(new TaskFileManipulation(m_installerContext));
167     }
168
169     AddTask(new TaskManifestFile(m_installerContext));
170     if (m_installerContext.widgetConfig.packagingType ==
171         PKG_TYPE_HYBRID_WEB_APP)
172     {
173         AddTask(new TaskInstallOspsvc(m_installerContext));
174     }
175
176     AddTask(new TaskDatabase(m_installerContext));
177     AddTask(new TaskAceCheck(m_installerContext));
178     //TODO: remove widgetHandle from this task and move before database task
179     // by now widget handle is needed in ace check
180     // Any error in acecheck while update will break widget
181     AddTask(new TaskSmack(m_installerContext));
182     AddTask(new TaskRemoveBackupFiles(m_installerContext));
183     AddTask(new TaskPkgInfoUpdate(m_installerContext));
184 }
185
186 void JobWidgetInstall::appendFailureTaskList()
187 {
188     // Installation is not allowed to proceed due to widget update policy
189     LogWarning("Configure installation failed!");
190     getInstallerStruct().pkgmgrInterface->sendSignal(
191             PKGMGR_START_KEY,
192             PKGMGR_START_INSTALL);
193     getInstallerStruct().pkgmgrInterface->sendSignal(
194             PKGMGR_PROGRESS_KEY,
195             PKGMGR_START_VALUE);
196
197     AddTask(new InstallerTaskFail(m_installerContext.confResult));
198 }
199
200 void JobWidgetInstall::SendProgress()
201 {
202     using namespace PackageManager;
203     if (GetProgressFlag() != false) {
204         if (getInstallerStruct().progressCallback != NULL) {
205             // send progress signal of pkgmgr
206             std::ostringstream percent;
207             percent << static_cast<int>(GetProgressPercent());
208             getInstallerStruct().pkgmgrInterface->sendSignal(
209                 PKGMGR_PROGRESS_KEY,
210                 percent.str());
211
212             LogPedantic("Call widget install progressCallback");
213             getInstallerStruct().progressCallback(
214                 getInstallerStruct().userParam,
215                 GetProgressPercent(),
216                 GetProgressDescription());
217         }
218     }
219 }
220
221 void JobWidgetInstall::SendProgressIconPath(const std::string &path)
222 {
223     using namespace PackageManager;
224     if (GetProgressFlag() != false) {
225         if (getInstallerStruct().progressCallback != NULL) {
226             // send progress signal of pkgmgr
227             getInstallerStruct().pkgmgrInterface->sendSignal(
228                 PKGMGR_ICON_PATH,
229                 path);
230         }
231     }
232 }
233
234 void JobWidgetInstall::SendFinishedSuccess()
235 {
236     using namespace PackageManager;
237     // TODO : sync should move to separate task.
238     sync();
239
240     if (INSTALL_LOCATION_TYPE_EXTERNAL == m_installerContext.locationType) {
241         if (m_installerContext.isUpdateMode) {
242             WidgetInstallToExtSingleton::Instance().postUpgrade(true);
243         } else {
244             WidgetInstallToExtSingleton::Instance().postInstallation(true);
245         }
246         WidgetInstallToExtSingleton::Instance().deinitialize();
247     }
248
249     // remove widget install information file
250     unlink(m_installerContext.installInfo.c_str());
251
252     //inform widget info
253     JobWidgetInstall::displayWidgetInfo();
254
255     TizenAppId& tizenId = m_installerContext.widgetConfig.tzAppid;
256
257     // send signal of pkgmgr
258     getInstallerStruct().pkgmgrInterface->sendSignal(
259         PKGMGR_END_KEY,
260         PKGMGR_END_SUCCESS);
261
262     LogDebug("Call widget install successfinishedCallback");
263     getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
264                                           DPL::ToUTF8String(
265                                               tizenId), Jobs::Exceptions::Success);
266 }
267
268 void JobWidgetInstall::SendFinishedFailure()
269 {
270     using namespace PackageManager;
271     // remove widget install information file
272     unlink(m_installerContext.installInfo.c_str());
273
274     LogError("Error number: " << m_exceptionCaught);
275     LogError("Message: " << m_exceptionMessage);
276     TizenAppId & tizenId = m_installerContext.widgetConfig.tzAppid;
277
278     LogDebug("Call widget install failure finishedCallback");
279     std::stringstream errorNum;
280     errorNum << m_exceptionCaught;
281
282     // send signal of pkgmgr
283     getInstallerStruct().pkgmgrInterface->sendSignal(
284         PKGMGR_ERROR,
285         errorNum.str());
286
287     getInstallerStruct().pkgmgrInterface->sendSignal(
288         PKGMGR_END_KEY,
289         PKGMGR_END_FAILURE);
290
291     getInstallerStruct().finishedCallback(getInstallerStruct().userParam,
292                                           DPL::ToUTF8String(
293                                               tizenId), m_exceptionCaught);
294 }
295
296 void JobWidgetInstall::SaveExceptionData(const Jobs::JobExceptionBase &e)
297 {
298     m_exceptionCaught = static_cast<Jobs::Exceptions::Type>(e.getParam());
299     m_exceptionMessage = e.GetMessage();
300 }
301
302 void JobWidgetInstall::displayWidgetInfo()
303 {
304     WidgetDAOReadOnly dao(m_installerContext.widgetConfig.tzAppid);
305
306     std::ostringstream out;
307     WidgetLocalizedInfo localizedInfo =
308         W3CFileLocalization::getLocalizedInfo(dao.getTzAppId());
309
310     out << std::endl <<
311     "===================================== INSTALLED WIDGET INFO =========" \
312     "============================";
313     out << std::endl << "Name:                        " << localizedInfo.name;
314     out << std::endl << "AppId:                     " << dao.getTzAppId();
315     WidgetSize size = dao.getPreferredSize();
316     out << std::endl << "Width:                       " << size.width;
317     out << std::endl << "Height:                      " << size.height;
318     out << std::endl << "Start File:                  " <<
319     W3CFileLocalization::getStartFile(dao.getTzAppId());
320     out << std::endl << "Version:                     " << dao.getVersion();
321     out << std::endl << "Licence:                     " <<
322     localizedInfo.license;
323     out << std::endl << "Licence Href:                " <<
324     localizedInfo.licenseHref;
325     out << std::endl << "Description:                 " <<
326     localizedInfo.description;
327     out << std::endl << "Widget Id:                   " << dao.getGUID();
328     out << std::endl << "Widget recognized:           " << dao.isRecognized();
329     out << std::endl << "Widget distributor signed:   " <<
330     dao.isDistributorSigned();
331     out << std::endl << "Widget trusted:              " << dao.isTrusted();
332
333     OptionalWidgetIcon icon = W3CFileLocalization::getIcon(dao.getTzAppId());
334     DPL::OptionalString iconSrc =
335         !!icon ? icon->src : DPL::OptionalString::Null;
336     out << std::endl << "Icon:                        " << iconSrc;
337
338     out << std::endl << "Preferences:";
339     {
340         PropertyDAOReadOnly::WidgetPreferenceList list = dao.getPropertyList();
341         FOREACH(it, list)
342         {
343             out << std::endl << "  Key:                       " <<
344             it->key_name;
345             out << std::endl << "      Readonly:              " <<
346             it->readonly;
347         }
348     }
349
350     out << std::endl << "Features:";
351     {
352         WidgetFeatureSet list = dao.getFeaturesList();
353         FOREACH(it, list)
354         {
355             out << std::endl << "  Name:                      " << it->name;
356         }
357     }
358
359     out << std::endl;
360
361     LogDebug(out.str());
362 }
363 } //namespace WidgetInstall
364 } //namespace Jobs