Upstream version 8.36.161.0
[platform/framework/web/crosswalk.git] / src / xwalk / application / tools / tizen / xwalk_package_installer_helper.cc
1 // Copyright (c) 2014 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "xwalk/application/tools/tizen/xwalk_package_installer_helper.h"
6
7 #include <assert.h>
8 #include <stdio.h>
9 #include <pkgmgr/pkgmgr_parser.h>
10 #include <tzplatform_config.h>
11
12 #undef LOG
13 #include <string>
14 #include "base/files/file_path.h"
15 #include "base/file_util.h"
16
17 namespace {
18
19 typedef int (*PkgParser)(const char*, char* const*);
20
21 const base::FilePath kXWalkLauncherBinary("/usr/bin/xwalk-launcher");
22 const char kIconDir[] = "icons/default/small/";
23 const char kXmlDir[] = "packages/";
24 const std::string kServicePrefix("xwalk-service.");
25 const std::string kXmlFileExt(".xml");
26 const std::string kPngFileExt(".png");
27
28 // Package type sent in every signal.
29 const char PKGMGR_PKG_TYPE[] = "rpm";
30
31 // Notification about operation start.
32 const char PKGMGR_START_KEY[] = "start";
33
34 // Value for new installation.
35 const char PKGMGR_START_INSTALL[] = "install";
36
37 // Value for uninstallation.
38 const char PKGMGR_START_UNINSTALL[] = "uninstall";
39
40 // Value for update.
41 const char PKGMGR_START_UPDATE[] = "update";
42
43 // Notification about end of installation with status.
44 const char PKGMGR_END_KEY[] = "end";
45
46 // Success value of end of installation.
47 const char PKGMGR_END_SUCCESS[] = "ok";
48
49 // Failure value of end of installation.
50 const char PKGMGR_END_FAILURE[] = "fail";
51
52 const std::string kAppIdPrefix("xwalk.");
53
54 class FileDeleter {
55  public:
56   FileDeleter(const base::FilePath& path, bool recursive)
57       : path_(path),
58         recursive_(recursive) {}
59
60   ~FileDeleter() {
61     if (path_.empty())
62       return;
63
64     base::DeleteFile(path_, recursive_);
65   }
66
67   void Dismiss() {
68     path_.clear();
69   }
70
71  private:
72   base::FilePath path_;
73   bool recursive_;
74 };
75
76 const char* ToEndStatus(bool result) {
77   return result ? PKGMGR_END_SUCCESS : PKGMGR_END_FAILURE;
78 }
79
80 inline base::FilePath GetDestFilePath(const base::FilePath& DirPath,
81                                       const std::string& appid,
82                                       const std::string& file_ext) {
83   return DirPath.Append(kServicePrefix + std::string(appid) + file_ext);
84 }
85
86 bool CopyFileToDst(const base::FilePath& file_src,
87                    const base::FilePath& file_dst) {
88   if (!base::CopyFile(file_src, file_dst)) {
89     fprintf(stdout, "Couldn't copy application file to '%s'\n",
90             file_dst.value().c_str());
91     return false;
92   }
93   return true;
94 }
95
96 }  // namespace
97
98 PackageInstallerHelper::PackageInstallerHelper(const std::string& appid)
99     : appid_(appid) {
100   if (appid_.empty())
101     fprintf(stdout, "Invalid app id is provided for pkg installer.\n");
102
103   handle_ = pkgmgr_installer_new();
104   if (!handle_)
105     fprintf(stdout, "Fail to get package manager installer handle.\n");
106 }
107
108 PackageInstallerHelper::~PackageInstallerHelper() {
109   if (handle_)
110     pkgmgr_installer_free(handle_);
111 }
112
113 bool PackageInstallerHelper::InstallApplication(
114     const std::string& xmlpath,
115     const std::string& iconpath) {
116   SendSignal(PKGMGR_START_KEY, PKGMGR_START_INSTALL);
117   bool ret = InstallApplicationInternal(xmlpath, iconpath);
118   SendSignal(PKGMGR_END_KEY, ToEndStatus(ret));
119   return ret;
120 }
121
122 bool PackageInstallerHelper::UninstallApplication() {
123   SendSignal(PKGMGR_START_KEY, PKGMGR_START_UNINSTALL);
124   bool ret = UninstallApplicationInternal();
125   SendSignal(PKGMGR_END_KEY, ToEndStatus(ret));
126   return ret;
127 }
128
129 bool PackageInstallerHelper::UpdateApplication(
130     const std::string& xmlpath,
131     const std::string& iconpath) {
132   SendSignal(PKGMGR_START_KEY, PKGMGR_START_UPDATE);
133   bool ret = UpdateApplicationInternal(xmlpath, iconpath);
134   SendSignal(PKGMGR_END_KEY, ToEndStatus(ret));
135   return ret;
136 }
137
138 bool PackageInstallerHelper::InstallApplicationInternal(
139     const std::string& xmlpath,
140     const std::string& iconpath) {
141   if (xmlpath.empty() || iconpath.empty()) {
142     fprintf(stdout, "Invalid xml path or icon path for installation\n");
143   }
144
145   base::FilePath xml(tzplatform_mkpath(TZ_SYS_SHARE, kXmlDir));
146   base::FilePath icon(tzplatform_mkpath(TZ_SYS_SHARE, kIconDir));
147
148   // FIXME(vcgomes): Add support for more icon types
149   base::FilePath xml_dst = GetDestFilePath(xml, appid_, kXmlFileExt);
150   base::FilePath icon_dst = GetDestFilePath(icon, appid_, kPngFileExt);
151   FileDeleter xml_cleaner(xml_dst, false);
152   FileDeleter icon_cleaner(icon_dst, false);
153
154
155   if (!CopyFileToDst(base::FilePath(xmlpath), xml_dst)
156      || !CopyFileToDst(base::FilePath(iconpath), icon_dst))
157     return false;
158
159   if (pkgmgr_parser_parse_manifest_for_installation(xmlpath.c_str(), NULL)) {
160     fprintf(stdout, "Couldn't parse manifest XML '%s'\n", xmlpath.c_str());
161     return false;
162   }
163
164   xml_cleaner.Dismiss();
165   icon_cleaner.Dismiss();
166
167   return true;
168 }
169
170 bool PackageInstallerHelper::UninstallApplicationInternal() {
171   bool result = true;
172
173   base::FilePath xml(tzplatform_mkpath(TZ_SYS_SHARE, kXmlDir));
174   base::FilePath icon(tzplatform_mkpath(TZ_SYS_SHARE, kIconDir));
175
176   // FIXME(vcgomes): Add support for more icon types
177   base::FilePath iconpath = GetDestFilePath(icon, appid_, kPngFileExt);
178   base::FilePath xmlpath = GetDestFilePath(xml, appid_, kXmlFileExt);
179   FileDeleter icon_cleaner(iconpath, false);
180   FileDeleter xml_cleaner(xmlpath, false);
181
182   std::string xmlpath_str = xmlpath.MaybeAsASCII();
183   assert(!xmlpath_str.empty());
184   if (pkgmgr_parser_parse_manifest_for_uninstallation(
185         xmlpath_str.c_str(), NULL)) {
186     fprintf(stdout, "Couldn't parse manifest XML '%s'\n", xmlpath_str.c_str());
187     icon_cleaner.Dismiss();
188     xml_cleaner.Dismiss();
189     return false;
190   }
191   return true;
192 }
193
194 bool PackageInstallerHelper::UpdateApplicationInternal(
195     const std::string& xmlpath,
196     const std::string& iconpath) {
197   if (xmlpath.empty() || iconpath.empty()) {
198     fprintf(stdout, "Invalid xml path or icon path for update\n");
199   }
200
201   base::FilePath xml(tzplatform_mkpath(TZ_SYS_SHARE, kXmlDir));
202   base::FilePath icon(tzplatform_mkpath(TZ_SYS_SHARE, kIconDir));
203
204   // FIXME(vcgomes): Add support for more icon types
205   base::FilePath xml_dst = GetDestFilePath(xml, appid_, kXmlFileExt);
206   base::FilePath icon_dst = GetDestFilePath(icon, appid_, kPngFileExt);
207   FileDeleter xml_cleaner(xml_dst, false);
208   FileDeleter icon_cleaner(icon_dst, false);
209
210
211   if (!CopyFileToDst(base::FilePath(xmlpath), xml_dst)
212      || !CopyFileToDst(base::FilePath(iconpath), icon_dst))
213     return false;
214
215   if (pkgmgr_parser_parse_manifest_for_upgrade(xmlpath.c_str(), NULL)) {
216     fprintf(stdout, "Couldn't parse manifest XML '%s'\n", xmlpath.c_str());
217     return false;
218   }
219
220   xml_cleaner.Dismiss();
221   icon_cleaner.Dismiss();
222
223   return true;
224 }
225
226 bool PackageInstallerHelper::SendSignal(
227     const std::string& key,
228     const std::string& value) {
229   if (!handle_) {
230     fprintf(stdout, "The package install manager is not initialized.\n");
231     return false;
232   }
233
234   if (key.empty() || value.empty()) {
235     fprintf(stdout, " Fail to send signal, key/value is empty.\n");
236     return false;
237   }
238
239   if (pkgmgr_installer_send_signal(
240           handle_, PKGMGR_PKG_TYPE, appid_.c_str(),
241           key.c_str(), value.c_str())) {
242     fprintf(stdout, "Fail to send package manager signal.\n");
243   }
244
245   return true;
246 }