0fd53071ceae87349268dd9430986f006c3a1c6a
[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 <vconf.h>
8
9 #include <boost/filesystem/path.hpp>
10
11 #include <wgt_manifest_handlers/widget_config_parser.h>
12 #include <wgt_manifest_handlers/addon_handler.h>
13 #include <wgt_manifest_handlers/application_icons_handler.h>
14 #include <wgt_manifest_handlers/application_manifest_constants.h>
15 #include <wgt_manifest_handlers/permissions_handler.h>
16 #include <wgt_manifest_handlers/tizen_application_handler.h>
17 #include <wgt_manifest_handlers/widget_handler.h>
18
19 #include <common/utils/file_util.h>
20
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[] = VCONFKEY_LANGSET;
32 const char kConfigFileName[] = "config.xml";
33 const char kHybridConfigFileName[] = "res/wgt/config.xml";
34
35 }  // namespace
36
37 bool WgtArchiveInfo::ExtractPackageArchive(const std::string& file_path,
38     const std::string& file, const std::string& tmp_dir) {
39   if (!ci::ExtractToTmpDir(file_path.c_str(),
40           bf::path(tmp_dir), file.c_str())) {
41     LOG(ERROR) << "Failed to extract";
42     return false;
43   }
44   return true;
45 }
46
47 bool WgtArchiveInfo::GetPackageInfo(
48     const wgt::parse::WidgetConfigParser& parser) {
49   auto widget_info =
50       std::static_pointer_cast<const wgt::parse::WidgetInfo>(
51           parser.GetManifestData(wgt::parse::WidgetInfo::Key()));
52   if (!widget_info) {
53     LOG(ERROR) << "WidgetInfo not found";
54     return false;
55   }
56
57   type_ = "wgt";
58   version_ =  widget_info->version().c_str();
59   author_ = widget_info->author().c_str();
60
61   return true;
62 }
63
64 bool WgtArchiveInfo::GetApplicationInfo(
65     const wgt::parse::WidgetConfigParser& parser) {
66   auto app_info =
67       std::static_pointer_cast<const wgt::parse::TizenApplicationInfo>(
68           parser.GetManifestData(wgt::parse::TizenApplicationInfo::Key()));
69   if (!app_info)
70     return false;
71
72   name_ = app_info->package().c_str();
73   pkgid_ = app_info->package().c_str();
74   api_version_ = app_info->required_version().c_str();
75
76   return true;
77 }
78
79 bool WgtArchiveInfo::GetAddonInfo(
80     const wgt::parse::WidgetConfigParser& parser) {
81   auto addon_info =
82       std::static_pointer_cast<const wgt::parse::AddonInfo>(
83           parser.GetManifestData(wgt::parse::AddonInfo::Key()));
84   if (!addon_info)
85     return false;
86
87   name_ = addon_info->package().c_str();
88   pkgid_ = addon_info->package().c_str();
89   api_version_ = addon_info->required_version().c_str();
90
91   return true;
92 }
93
94 bool WgtArchiveInfo::GetPrivilegesInfo(
95     const wgt::parse::WidgetConfigParser& parser) {
96   auto privileges_info =
97       std::static_pointer_cast<const wgt::parse::PermissionsInfo>(
98           parser.GetManifestData(wgt::parse::PermissionsInfo::Key()));
99   if (!privileges_info)
100     return false;
101
102   const auto& privileges = privileges_info->GetAPIPermissions();
103   for (auto& priv : privileges)
104     privileges_.emplace_back("wgt", priv);
105
106   return true;
107 }
108
109 bool WgtArchiveInfo::GetIconInfo(
110     const wgt::parse::WidgetConfigParser& parser) {
111   auto icons_info =
112       std::static_pointer_cast<const wgt::parse::ApplicationIconsInfo>(
113           parser.GetManifestData(wgt::parse::ApplicationIconsInfo::Key()));
114   if (!icons_info || icons_info->icons().empty())
115     return false;
116
117   icon_ = icons_info->icons().front().path();
118
119   return true;
120 }
121
122 bool WgtArchiveInfo::ReadIcon(const bf::path& icon, const bf::path& tmp_dir) {
123   bf::path icon_path = tmp_dir / icon;
124
125   LOG(INFO) << "Icon file path: " << icon_path;
126
127   if (!bf::exists(icon_path)) {
128     LOG(WARNING) << "Icon file doesn't actually exist, skip reading icon";
129     return true;
130   }
131
132   std::ifstream ifs(icon_path.c_str(),
133       std::ifstream::in | std::ifstream::binary);
134   ifs.seekg(0, ifs.end);
135   std::streamoff len = ifs.tellg();
136   ifs.seekg(0, ifs.beg);
137
138   if (len < 0)
139     return false;
140
141   icon_buf_.resize(len / sizeof(unsigned char));
142   ifs.read(reinterpret_cast<char*>(icon_buf_.data()), len);
143   if (static_cast<size_t>(len) != icon_buf_.size()) {
144     LOG(ERROR) << "Reading icon failed, icon size is: " << len
145                << ", but read size is: " << icon_buf_.size();
146     return false;
147   }
148
149   LOG(INFO) << "Reading icon file, " << icon_buf_.size() << " bytes";
150
151   return true;
152 }
153
154 bool WgtArchiveInfo::GetLabelInfo(const wgt::parse::WidgetConfigParser& parser,
155     const char* locale) {
156   auto widget_info =
157       std::static_pointer_cast<const wgt::parse::WidgetInfo>(
158           parser.GetManifestData(wgt::parse::WidgetInfo::Key()));
159   if (!widget_info)
160     return false;
161
162   std::string name;
163   const auto& labels = widget_info->name_set();
164   if (labels.find(locale) != labels.end()) {
165     name = labels.find(locale)->second;
166     label_ = name;
167     return true;
168   } else if (labels.find("") != labels.end()) {
169     name = labels.find("")->second;
170     label_ = name;
171     return true;
172   }
173
174   return false;
175 }
176
177 bool WgtArchiveInfo::GetDescriptionInfo(
178     const wgt::parse::WidgetConfigParser& parser, const char* locale) {
179   auto widget_info =
180       std::static_pointer_cast<const wgt::parse::WidgetInfo>(
181           parser.GetManifestData(wgt::parse::WidgetInfo::Key()));
182   if (!widget_info)
183     return false;
184
185   std::string desc;
186   const auto& descriptions = widget_info->description_set();
187   if (descriptions.find(locale) != descriptions.end()) {
188     desc = descriptions.find(locale)->second;
189     description_ = desc;
190     return true;
191   } else if (descriptions.find("") != descriptions.end()) {
192     desc = descriptions.find("")->second;
193     description_ = desc;
194     return true;
195   }
196
197   return false;
198 }
199
200 bool WgtArchiveInfo::LoadArchiveInfo() {
201   bf::path tmp_dir = ci::GenerateTmpDir("/tmp");
202   if (!ci::CreateDir(tmp_dir))
203     return false;
204   LOG(DEBUG) << "Unpack at temporary dir: " << tmp_dir;
205   bool is_hybrid = false;
206   if (!ExtractPackageArchive(path_, kHybridConfigFileName, tmp_dir.string()))
207     return false;
208   if (bf::exists(tmp_dir / kHybridConfigFileName)) {
209     is_hybrid = true;
210   } else {
211     if (!ExtractPackageArchive(path_, kConfigFileName, tmp_dir.string()))
212       return false;
213   }
214
215   wgt::parse::WidgetConfigParser parser;
216   bf::path manifest_path;
217   if (is_hybrid)
218     manifest_path = tmp_dir / kHybridConfigFileName;
219   else
220     manifest_path = tmp_dir / kConfigFileName;
221   if (!parser.ParseManifest(manifest_path)) {
222     LOG(ERROR) << "Failed to parse";
223     RemoveTmpDir(tmp_dir.string());
224     return false;
225   }
226
227   if (!GetPackageInfo(parser)) {
228     LOG(ERROR) << "Failed to get package info";
229     RemoveTmpDir(tmp_dir.string());
230     return false;
231   }
232   if (!GetApplicationInfo(parser)) {
233     if (!GetAddonInfo(parser)) {
234       LOG(ERROR) << "Failed to get application info nor addon info. "
235                  << "At least one of them must exist";
236       RemoveTmpDir(tmp_dir.string());
237       return false;
238     }
239   }
240
241   if (!GetPrivilegesInfo(parser))
242     LOG(WARNING) << "Failed to get privileges info";
243   if (!GetIconInfo(parser))
244     LOG(WARNING) << "Failed to get icon info";
245   if (!icon_.empty()) {
246     std::string icon_path;
247     if (is_hybrid)
248       icon_path = "res/wgt/" + icon_;
249     else
250       icon_path = icon_;
251     if (!ExtractPackageArchive(path_, icon_path, tmp_dir.string())) {
252       RemoveTmpDir(tmp_dir.string());
253       return false;
254     }
255     if (!ReadIcon(icon_path, tmp_dir)) {
256       LOG(WARNING) << "Failed to get icon info";
257       RemoveTmpDir(tmp_dir.string());
258       return false;
259     }
260   }
261
262   char* locale = vconf_get_str(kVconfLanguageKey);
263   if (!locale)
264     locale = strdup("");
265   if (!GetLabelInfo(parser, locale))
266     LOG(WARNING) << "Failed to get label info";
267   if (!GetDescriptionInfo(parser, locale))
268     LOG(WARNING) << "Failed to get description info";
269
270   free(locale);
271   RemoveTmpDir(tmp_dir.string());
272
273
274   return true;
275 }