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.
5 #include "xwalk/application/tools/tizen/xwalk_package_installer_helper.h"
9 #include <pkgmgr/pkgmgr_parser.h>
10 #include <tzplatform_config.h>
14 #include "base/files/file_path.h"
15 #include "base/file_util.h"
19 typedef int (*PkgParser)(const char*, char* const*);
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");
28 // Package type sent in every signal.
29 const char PKGMGR_PKG_TYPE[] = "rpm";
31 // Notification about operation start.
32 const char PKGMGR_START_KEY[] = "start";
34 // Value for new installation.
35 const char PKGMGR_START_INSTALL[] = "install";
37 // Value for uninstallation.
38 const char PKGMGR_START_UNINSTALL[] = "uninstall";
41 const char PKGMGR_START_UPDATE[] = "update";
43 // Notification about end of installation with status.
44 const char PKGMGR_END_KEY[] = "end";
46 // Success value of end of installation.
47 const char PKGMGR_END_SUCCESS[] = "ok";
49 // Failure value of end of installation.
50 const char PKGMGR_END_FAILURE[] = "fail";
52 const std::string kAppIdPrefix("xwalk.");
56 FileDeleter(const base::FilePath& path, bool recursive)
58 recursive_(recursive) {}
64 base::DeleteFile(path_, recursive_);
76 const char* ToEndStatus(bool result) {
77 return result ? PKGMGR_END_SUCCESS : PKGMGR_END_FAILURE;
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);
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());
98 PackageInstallerHelper::PackageInstallerHelper(const std::string& appid)
101 fprintf(stdout, "Invalid app id is provided for pkg installer.\n");
103 handle_ = pkgmgr_installer_new();
105 fprintf(stdout, "Fail to get package manager installer handle.\n");
108 PackageInstallerHelper::~PackageInstallerHelper() {
110 pkgmgr_installer_free(handle_);
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));
122 bool PackageInstallerHelper::UninstallApplication() {
123 SendSignal(PKGMGR_START_KEY, PKGMGR_START_UNINSTALL);
124 bool ret = UninstallApplicationInternal();
125 SendSignal(PKGMGR_END_KEY, ToEndStatus(ret));
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));
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");
145 base::FilePath xml(tzplatform_mkpath(TZ_SYS_SHARE, kXmlDir));
146 base::FilePath icon(tzplatform_mkpath(TZ_SYS_SHARE, kIconDir));
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);
155 if (!CopyFileToDst(base::FilePath(xmlpath), xml_dst)
156 || !CopyFileToDst(base::FilePath(iconpath), icon_dst))
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());
164 xml_cleaner.Dismiss();
165 icon_cleaner.Dismiss();
170 bool PackageInstallerHelper::UninstallApplicationInternal() {
173 base::FilePath xml(tzplatform_mkpath(TZ_SYS_SHARE, kXmlDir));
174 base::FilePath icon(tzplatform_mkpath(TZ_SYS_SHARE, kIconDir));
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);
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();
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");
201 base::FilePath xml(tzplatform_mkpath(TZ_SYS_SHARE, kXmlDir));
202 base::FilePath icon(tzplatform_mkpath(TZ_SYS_SHARE, kIconDir));
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);
211 if (!CopyFileToDst(base::FilePath(xmlpath), xml_dst)
212 || !CopyFileToDst(base::FilePath(iconpath), icon_dst))
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());
220 xml_cleaner.Dismiss();
221 icon_cleaner.Dismiss();
226 bool PackageInstallerHelper::SendSignal(
227 const std::string& key,
228 const std::string& value) {
230 fprintf(stdout, "The package install manager is not initialized.\n");
234 if (key.empty() || value.empty()) {
235 fprintf(stdout, " Fail to send signal, key/value is empty.\n");
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");