Fix wgt lib to extract manifest and icon only
[platform/core/appfw/wgt-backend.git] / src / lib / wgt_archive_info.cc
1 // Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "lib/wgt_archive_info.h"
6
7 #include <package-manager-plugin.h>
8 #include <pkgmgr-info.h>
9 #include <vconf.h>
10
11 #include <wgt_manifest_handlers/widget_config_parser.h>
12 #include <wgt_manifest_handlers/application_icons_handler.h>
13 #include <wgt_manifest_handlers/application_manifest_constants.h>
14 #include <wgt_manifest_handlers/permissions_handler.h>
15 #include <wgt_manifest_handlers/tizen_application_handler.h>
16 #include <wgt_manifest_handlers/widget_handler.h>
17
18 #include <common/utils/file_util.h>
19
20 #include <cstdio>
21 #include <cstdlib>
22 #include <fstream>
23 #include <string>
24 #include <vector>
25
26 namespace bf = boost::filesystem;
27 namespace ci = common_installer;
28
29 namespace {
30
31 const char kVconfLanguageKey[] = "db/menu_widget/language";
32 const char kConfigFileName[] = "config.xml";
33
34 bool ExtractPackageArchive(const char* file_path, const char* file,
35     const bf::path& tmp_dir) {
36   if (!ci::ExtractToTmpDir(file_path, tmp_dir, file)) {
37     LOG(ERROR) << "Failed to extract";
38     return false;
39   }
40   return true;
41 }
42
43 bool GetPackageInfo(const wgt::parse::WidgetConfigParser& parser,
44     package_manager_pkg_detail_info_t* info) {
45   auto widget_info =
46       std::static_pointer_cast<const wgt::parse::WidgetInfo>(
47           parser.GetManifestData(wgt::parse::WidgetInfo::Key()));
48   auto app_info =
49       std::static_pointer_cast<const wgt::parse::TizenApplicationInfo>(
50           parser.GetManifestData(wgt::parse::TizenApplicationInfo::Key()));
51   if (!widget_info || !app_info) {
52     LOG(ERROR) << "WidgetInfo / TizenApplicationInfo not found";
53     return false;
54   }
55
56   snprintf(info->pkg_type, sizeof(info->pkg_type), "wgt");
57   snprintf(info->version, sizeof(info->version), "%s",
58       widget_info->version().c_str());
59   snprintf(info->author, sizeof(info->version), "%s",
60       widget_info->author().c_str());
61
62   snprintf(info->pkg_name, sizeof(info->pkg_name), "%s",
63       app_info->package().c_str());
64   snprintf(info->pkgid, sizeof(info->pkgid), "%s", app_info->package().c_str());
65   snprintf(info->api_version, sizeof(info->api_version), "%s",
66       app_info->required_version().c_str());
67
68   return true;
69 }
70
71 bool GetPrivilegesInfo(const wgt::parse::WidgetConfigParser& parser,
72     package_manager_pkg_detail_info_t* info) {
73   auto privileges_info =
74       std::static_pointer_cast<const wgt::parse::PermissionsInfo>(
75           parser.GetManifestData(wgt::parse::PermissionsInfo::Key()));
76   if (!privileges_info)
77     return false;
78
79   const auto& privileges = privileges_info->GetAPIPermissions();
80   for (auto& priv : privileges) {
81     info->privilege_list = g_list_append(info->privilege_list,
82         strdup(priv.c_str()));
83   }
84
85   return true;
86 }
87
88 bool GetLabelInfo(const wgt::parse::WidgetConfigParser& parser,
89     const char* locale, package_manager_pkg_detail_info_t* info) {
90   auto widget_info =
91       std::static_pointer_cast<const wgt::parse::WidgetInfo>(
92           parser.GetManifestData(wgt::parse::WidgetInfo::Key()));
93   if (!widget_info)
94     return false;
95
96   std::string name;
97   const auto& labels = widget_info->name_set();
98   if (labels.find(locale) != labels.end()) {
99     name = labels.find(locale)->second;
100     snprintf(info->label, sizeof(info->label), "%s", name.c_str());
101     return true;
102   } else if (labels.find("") != labels.end()) {
103     name = labels.find("")->second;
104     snprintf(info->label, sizeof(info->label), "%s", name.c_str());
105     return true;
106   }
107
108   return false;
109 }
110
111 bool GetDescriptionInfo(const wgt::parse::WidgetConfigParser& parser,
112     const char* locale, package_manager_pkg_detail_info_t* info) {
113   auto widget_info =
114       std::static_pointer_cast<const wgt::parse::WidgetInfo>(
115           parser.GetManifestData(wgt::parse::WidgetInfo::Key()));
116   if (!widget_info)
117     return false;
118
119   std::string desc;
120   const auto& descriptions = widget_info->description_set();
121   if (descriptions.find(locale) != descriptions.end()) {
122     desc = descriptions.find(locale)->second;
123     snprintf(info->pkg_description, sizeof(info->pkg_description), "%s",
124         desc.c_str());
125     return true;
126   } else if (descriptions.find("") != descriptions.end()) {
127     desc = descriptions.find("")->second;
128     snprintf(info->pkg_description, sizeof(info->pkg_description), "%s",
129         desc.c_str());
130     return true;
131   }
132
133   return false;
134 }
135
136 bool ReadIcon(const bf::path& icon, const bf::path& tmp_dir,
137     package_manager_pkg_detail_info_t* info) {
138   bf::path icon_path = tmp_dir / icon;
139
140   LOG(INFO) << "Icon file path: " << icon_path;
141
142   std::ifstream ifs(icon_path.c_str(),
143       std::ifstream::in | std::ifstream::binary);
144   ifs.seekg(0, ifs.end);
145   int len = ifs.tellg();
146   ifs.seekg(0, ifs.beg);
147
148   if (len <= 0)
149     return false;
150
151   char* buf = static_cast<char*>(malloc(sizeof(char) * len));
152
153   LOG(INFO) << "Reading icon file, " << len << " bytes";
154   ifs.read(buf, len);
155
156   info->icon_buf = buf;
157   info->icon_size = len;
158
159   return true;
160 }
161
162 std::string GetIconInfo(const wgt::parse::WidgetConfigParser& parser) {
163   auto icons_info =
164       std::static_pointer_cast<const wgt::parse::ApplicationIconsInfo>(
165           parser.GetManifestData(wgt::parse::ApplicationIconsInfo::Key()));
166   if (!icons_info)
167     return {};
168
169   return std::string(icons_info->icons().front().path());
170 }
171
172 }  // namespace
173
174 bool WgtArchiveInfo::GetArchiveInfo(const char* file_path,
175     package_manager_pkg_detail_info_t* info) {
176   bf::path tmp_dir = ci::GenerateTmpDir("/tmp");
177   if (!ci::CreateDir(tmp_dir))
178     return false;
179   LOG(DEBUG) << "Unpack at temporary dir: " << tmp_dir;
180   if (!ExtractPackageArchive(file_path, kConfigFileName, tmp_dir))
181     return false;
182
183   wgt::parse::WidgetConfigParser parser;
184   bf::path manifest_path = tmp_dir / kConfigFileName;
185   if (!parser.ParseManifest(manifest_path)) {
186     LOG(ERROR) << "Failed to parse";
187     bf::remove_all(tmp_dir);
188     return false;
189   }
190
191   if (!GetPackageInfo(parser, info)) {
192     LOG(ERROR) << "Failed to get package info";
193     bf::remove_all(tmp_dir);
194     return false;
195   }
196   if (!GetPrivilegesInfo(parser, info))
197     LOG(WARNING) << "Failed to get privileges info";
198   std::string icon = GetIconInfo(parser);
199   if (!icon.empty()) {
200     if (!ExtractPackageArchive(file_path, icon.c_str(), tmp_dir))
201       return false;
202     if (!ReadIcon(icon, tmp_dir, info)) {
203       LOG(WARNING) << "Failed to get icon info";
204       return false;
205     }
206   }
207
208   char* locale = vconf_get_str(kVconfLanguageKey);
209   if (!GetLabelInfo(parser, locale, info))
210     LOG(WARNING) << "Failed to get label info";
211   if (!GetDescriptionInfo(parser, locale, info))
212     LOG(WARNING) << "Failed to get description info";
213
214   free(locale);
215   bf::remove_all(tmp_dir);
216
217   return true;
218 }