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>
13 #include "base/files/file_path.h"
14 #include "base/file_util.h"
18 typedef int (*PkgParser)(const char*, char* const*);
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.");
25 // Package type sent in every signal.
26 const char PKGMGR_PKG_TYPE[] = "rpm";
28 // Notification about operation start.
29 const char PKGMGR_START_KEY[] = "start";
31 // Value for new installation.
32 const char PKGMGR_START_INSTALL[] = "install";
34 // Value for uninstallation.
35 const char PKGMGR_START_UNINSTALL[] = "uninstall";
38 const char PKGMGR_START_UPDATE[] = "update";
40 // Notification about end of installation with status.
41 const char PKGMGR_END_KEY[] = "end";
43 // Success value of end of installation.
44 const char PKGMGR_END_SUCCESS[] = "ok";
46 // Failure value of end of installation.
47 const char PKGMGR_END_FAILURE[] = "fail";
49 const std::string kAppIdPrefix("xwalk.");
53 FileDeleter(const base::FilePath& path, bool recursive)
55 recursive_(recursive) {}
61 base::DeleteFile(path_, recursive_);
73 const char* ToEndStatus(bool result) {
74 return result ? PKGMGR_END_SUCCESS : PKGMGR_END_FAILURE;
79 PackageInstallerHelper::PackageInstallerHelper(const std::string& appid)
82 fprintf(stdout, "Invalid app id is provided for pkg installer.\n");
84 handle_ = pkgmgr_installer_new();
86 fprintf(stdout, "Fail to get package manager installer handle.\n");
89 PackageInstallerHelper::~PackageInstallerHelper() {
91 pkgmgr_installer_free(handle_);
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));
103 bool PackageInstallerHelper::UninstallApplication() {
104 SendSignal(PKGMGR_START_KEY, PKGMGR_START_UNINSTALL);
105 bool ret = UninstallApplicationInternal();
106 SendSignal(PKGMGR_END_KEY, ToEndStatus(ret));
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();
116 ret = InstallApplicationInternal(xmlpath, iconpath);
117 SendSignal(PKGMGR_END_KEY, ToEndStatus(ret));
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");
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());
139 FileDeleter icon_cleaner(icon_dst, false);
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());
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());
155 FileDeleter xml_cleaner(xml_dst, false);
156 icon_cleaner.Dismiss();
157 xml_cleaner.Dismiss();
162 bool PackageInstallerHelper::UninstallApplicationInternal() {
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());
173 base::FilePath xmlpath(kXmlDir);
174 xmlpath = xmlpath.Append(kServicePrefix + std::string(appid_) + ".xml");
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());
184 if (!base::DeleteFile(xmlpath, false)) {
185 fprintf(stdout, "Couldn't delete '%s'\n", xmlpath_str.c_str());
192 bool PackageInstallerHelper::SendSignal(
193 const std::string& key,
194 const std::string& value) {
196 fprintf(stdout, "The package install manager is not initialized.\n");
200 if (key.empty() || value.empty()) {
201 fprintf(stdout, " Fail to send signal, key/value is empty.\n");
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");