Upstream version 7.35.138.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
11 #undef LOG
12 #include <string>
13 #include "base/files/file_path.h"
14 #include "base/file_util.h"
15
16 namespace {
17
18 typedef int (*PkgParser)(const char*, char* const*);
19
20 const base::FilePath kIconDir("/opt/share/icons/default/small/");
21 const base::FilePath kXmlDir("/opt/share/packages/");
22 const base::FilePath kXWalkLauncherBinary("/usr/bin/xwalk-launcher");
23 const std::string kServicePrefix("xwalk-service.");
24
25 // Package type sent in every signal.
26 const char PKGMGR_PKG_TYPE[] = "rpm";
27
28 // Notification about operation start.
29 const char PKGMGR_START_KEY[] = "start";
30
31 // Value for new installation.
32 const char PKGMGR_START_INSTALL[] = "install";
33
34 // Value for uninstallation.
35 const char PKGMGR_START_UNINSTALL[] = "uninstall";
36
37 // Value for update.
38 const char PKGMGR_START_UPDATE[] = "update";
39
40 // Notification about end of installation with status.
41 const char PKGMGR_END_KEY[] = "end";
42
43 // Success value of end of installation.
44 const char PKGMGR_END_SUCCESS[] = "ok";
45
46 // Failure value of end of installation.
47 const char PKGMGR_END_FAILURE[] = "fail";
48
49 const std::string kAppIdPrefix("xwalk.");
50
51 class FileDeleter {
52  public:
53   FileDeleter(const base::FilePath& path, bool recursive)
54       : path_(path),
55         recursive_(recursive) {}
56
57   ~FileDeleter() {
58     if (path_.empty())
59       return;
60
61     base::DeleteFile(path_, recursive_);
62   }
63
64   void Dismiss() {
65     path_.clear();
66   }
67
68  private:
69   base::FilePath path_;
70   bool recursive_;
71 };
72
73 const char* ToEndStatus(bool result) {
74   return result ? PKGMGR_END_SUCCESS : PKGMGR_END_FAILURE;
75 }
76
77 }  // namespace
78
79 PackageInstallerHelper::PackageInstallerHelper(const std::string& appid)
80     : appid_(appid) {
81   if (appid_.empty())
82     fprintf(stdout, "Invalid app id is provided for pkg installer.\n");
83
84   handle_ = pkgmgr_installer_new();
85   if (!handle_)
86     fprintf(stdout, "Fail to get package manager installer handle.\n");
87 }
88
89 PackageInstallerHelper::~PackageInstallerHelper() {
90   if (handle_)
91     pkgmgr_installer_free(handle_);
92 }
93
94 bool PackageInstallerHelper::InstallApplication(
95     const std::string& xmlpath,
96     const std::string& iconpath) {
97   SendSignal(PKGMGR_START_KEY, PKGMGR_START_INSTALL);
98   bool ret = InstallApplicationInternal(xmlpath, iconpath);
99   SendSignal(PKGMGR_END_KEY, ToEndStatus(ret));
100   return ret;
101 }
102
103 bool PackageInstallerHelper::UninstallApplication() {
104   SendSignal(PKGMGR_START_KEY, PKGMGR_START_UNINSTALL);
105   bool ret = UninstallApplicationInternal();
106   SendSignal(PKGMGR_END_KEY, ToEndStatus(ret));
107   return ret;
108 }
109
110 bool PackageInstallerHelper::UpdateApplication(
111     const std::string& xmlpath,
112     const std::string& iconpath) {
113   SendSignal(PKGMGR_START_KEY, PKGMGR_START_UPDATE);
114   bool ret = UninstallApplicationInternal();
115   if (ret)
116     ret = InstallApplicationInternal(xmlpath, iconpath);
117   SendSignal(PKGMGR_END_KEY, ToEndStatus(ret));
118   return ret;
119 }
120
121 bool PackageInstallerHelper::InstallApplicationInternal(
122     const std::string& xmlpath,
123     const std::string& iconpath) {
124   if (xmlpath.empty() || iconpath.empty()) {
125     fprintf(stdout, "Invalid xml path or icon path for installation\n");
126   }
127
128   base::FilePath icon_src(iconpath);
129   // icon_dst == /opt/share/icons/default/small/xwalk-service.<appid>.png
130   // FIXME(vcgomes): Add support for more icon types
131   base::FilePath icon_dst = kIconDir.Append(
132       kServicePrefix + std::string(appid_) + ".png");
133   if (!base::CopyFile(icon_src, icon_dst)) {
134     fprintf(stdout, "Couldn't copy application icon to '%s'\n",
135             icon_dst.value().c_str());
136     return false;
137   }
138
139   FileDeleter icon_cleaner(icon_dst, false);
140
141   base::FilePath xml_src(xmlpath);
142   base::FilePath xml_dst = kXmlDir.Append(
143       kServicePrefix + std::string(appid_) + ".xml");
144   if (!base::CopyFile(xml_src, xml_dst)) {
145     fprintf(stdout, "Couldn't copy application XML metadata to '%s'\n",
146             xml_dst.value().c_str());
147     return false;
148   }
149
150   if (pkgmgr_parser_parse_manifest_for_installation(xmlpath.c_str(), NULL)) {
151     fprintf(stdout, "Couldn't parse manifest XML '%s'\n", xmlpath.c_str());
152     return false;
153   }
154
155   FileDeleter xml_cleaner(xml_dst, false);
156   icon_cleaner.Dismiss();
157   xml_cleaner.Dismiss();
158
159   return true;
160 }
161
162 bool PackageInstallerHelper::UninstallApplicationInternal() {
163   bool result = true;
164
165   // FIXME(vcgomes): Add support for more icon types
166   base::FilePath icon_dst = kIconDir.Append(
167       kServicePrefix + appid_ + ".png");
168   if (!base::DeleteFile(icon_dst, false)) {
169     fprintf(stdout, "Couldn't delete '%s'\n", icon_dst.value().c_str());
170     result = false;
171   }
172
173   base::FilePath xmlpath(kXmlDir);
174   xmlpath = xmlpath.Append(kServicePrefix + std::string(appid_) + ".xml");
175
176   std::string xmlpath_str = xmlpath.MaybeAsASCII();
177   assert(!xmlpath_str.empty());
178   if (pkgmgr_parser_parse_manifest_for_uninstallation(
179         xmlpath_str.c_str(), NULL)) {
180     fprintf(stdout, "Couldn't parse manifest XML '%s'\n", xmlpath_str.c_str());
181     result = false;
182   }
183
184   if (!base::DeleteFile(xmlpath, false)) {
185     fprintf(stdout, "Couldn't delete '%s'\n", xmlpath_str.c_str());
186     result = false;
187   }
188
189   return result;
190 }
191
192 bool PackageInstallerHelper::SendSignal(
193     const std::string& key,
194     const std::string& value) {
195   if (!handle_) {
196     fprintf(stdout, "The package install manager is not initialized.\n");
197     return false;
198   }
199
200   if (key.empty() || value.empty()) {
201     fprintf(stdout, " Fail to send signal, key/value is empty.\n");
202     return false;
203   }
204
205   if (pkgmgr_installer_send_signal(
206           handle_, PKGMGR_PKG_TYPE, appid_.c_str(),
207           key.c_str(), value.c_str())) {
208     fprintf(stdout, "Fail to send package manager signal.\n");
209   }
210
211   return true;
212 }