1 // Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
2 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE-xwalk file.
6 #include "widget-manifest-parser/widget_manifest_parser.h"
8 #include <boost/filesystem/path.hpp>
16 #include "utils/macros.h"
17 #include "utils/values.h"
19 #include "widget-manifest-parser/application_data.h"
20 #include "widget-manifest-parser/application_manifest_constants.h"
21 #include "widget-manifest-parser/manifest_util.h"
22 #include "widget-manifest-parser/manifest_handlers/permissions_handler.h"
23 #include "widget-manifest-parser/manifest_handlers/tizen_application_handler.h"
24 #include "widget-manifest-parser/manifest_handlers/widget_handler.h"
25 #include "widget-manifest-parser/permission_types.h"
27 #define API_EXPORT __attribute__((visibility("default")))
29 namespace bf = boost::filesystem;
30 namespace keys = common_installer::application_widget_keys;
31 namespace parser = common_installer::widget_manifest_parser;
35 const char kErrMsgNoPath[] =
36 "Path not specified.";
37 const char kErrMsgInvalidPath[] =
39 const char kErrMsgValueNotFound[] =
40 "Value not found. Value name: ";
41 const char kErrMsgInvalidDictionary[] =
42 "Cannot get key value as a dictionary. Key name: ";
43 const char kErrMsgInvalidList[] =
44 "Cannot get key value as a list. Key name: ";
45 const char kErrMsgNoMandatoryKey[] =
46 "Cannot find mandatory key. Key name: ";
48 const char kName[] = "name";
49 const char kShortName[] = "shortName";
50 const char kVersion[] = "version";
51 const char kWidgetIconFullKey[] = "widget.icon";
52 const char kWidgetIconSrcKey[] = "@src";
54 typedef std::string LocalError;
56 void SetError(const std::string& message, const char** error) {
58 *error = strdup(message.c_str());
61 void SetError(const std::string& message, const std::string& arg,
64 *error = strdup((message + arg).c_str());
68 const parser::ApplicationData& app_data, std::string* value) {
69 parser::TizenApplicationInfo* info =
70 static_cast<parser::TizenApplicationInfo*>(
71 app_data.GetManifestData(keys::kTizenApplicationKey));
73 *value = info->package();
78 const parser::ApplicationData& app_data, std::string* value) {
79 parser::TizenApplicationInfo* info =
80 static_cast<parser::TizenApplicationInfo*>(
81 app_data.GetManifestData(keys::kTizenApplicationKey));
87 bool ExtractName(const parser::ApplicationData& app_data, std::string* value) {
88 parser::WidgetInfo* info = static_cast<parser::WidgetInfo*>(
89 app_data.GetManifestData(keys::kWidgetKey));
92 return info->GetWidgetInfo()->GetString(kName, value);
95 bool ExtractShortName(const parser::ApplicationData& app_data,
97 parser::WidgetInfo* info = static_cast<parser::WidgetInfo*>(
98 app_data.GetManifestData(keys::kWidgetKey));
101 return info->GetWidgetInfo()->GetString(kShortName, value);
104 bool ExtractVersion(const parser::ApplicationData& app_data,
105 std::string* value) {
106 parser::WidgetInfo* info = static_cast<parser::WidgetInfo*>(
107 app_data.GetManifestData(keys::kWidgetKey));
110 return info->GetWidgetInfo()->GetString(kVersion, value);
113 bool ExtractIconSrc(const common_installer::utils::Value& dict,
114 std::string* value, const char** error) {
115 const common_installer::utils::DictionaryValue* inner_dict;
116 if (!dict.GetAsDictionary(&inner_dict)) {
117 SetError(kErrMsgInvalidDictionary, kWidgetIconFullKey, error);
121 if (!inner_dict->GetString(kWidgetIconSrcKey, &src)) {
122 SetError(kErrMsgNoMandatoryKey, kWidgetIconSrcKey, error);
129 bool ExtractIcons(const parser::Manifest& manifest,
130 std::vector<std::string>* value, const char** error) {
131 common_installer::utils::Value* key_value;
132 if (!manifest.Get(kWidgetIconFullKey, &key_value)) {
134 return true; // no icon, no error
137 std::vector<std::string> icons;
138 if (key_value->IsType(common_installer::utils::Value::TYPE_DICTIONARY)) {
140 if (!ExtractIconSrc(*key_value, &icon, error))
142 icons.push_back(icon);
143 } else if (key_value->IsType(common_installer::utils::Value::TYPE_LIST)) {
144 const common_installer::utils::ListValue* list;
145 if (!key_value->GetAsList(&list)) {
146 SetError(kErrMsgInvalidList, kWidgetIconFullKey, error);
149 for (const common_installer::utils::Value* list_value : *list) {
151 if (!ExtractIconSrc(*list_value, &icon, error))
153 icons.push_back(icon);
161 bool ExtractApiVersion(const parser::ApplicationData& app_data,
162 std::string* value) {
163 parser::TizenApplicationInfo* info =
164 static_cast<parser::TizenApplicationInfo*>(
165 app_data.GetManifestData(keys::kTizenApplicationKey));
168 *value = info->required_version();
172 bool ExtractPrivileges(const parser::ApplicationData& app_data,
173 std::set<std::string>* value, const char** error) {
174 const parser::PermissionsInfo* perm_info =
175 static_cast<parser::PermissionsInfo*>(
176 app_data.GetManifestData(keys::kTizenPermissionsKey));
177 parser::PermissionSet permissions = perm_info->GetAPIPermissions();
178 *value = permissions;
186 API_EXPORT bool ParseManifest(const char* path,
187 const ManifestData** data, const char** error) {
189 SetError(kErrMsgNoPath, error);
192 std::string str_path = path;
193 if (str_path.empty()) {
194 SetError(kErrMsgInvalidPath, error);
198 std::string local_error;
200 std::unique_ptr<parser::Manifest> manifest = parser::LoadManifest(
201 path, parser::Manifest::TYPE_WIDGET, &local_error);
203 SetError(local_error, error);
207 std::shared_ptr<parser::ApplicationData> app_data =
208 parser::ApplicationData::Create(bf::path(), std::string(),
209 parser::ApplicationData::INTERNAL,
210 std::move(manifest), &local_error);
211 if (!app_data.get()) {
212 SetError(local_error, error);
217 if (!ExtractPackage(*app_data, &package)) {
218 SetError(kErrMsgValueNotFound, "package id", error);
223 if (!ExtractId(*app_data, &id)) {
224 SetError(kErrMsgValueNotFound, "application id", error);
229 if (!ExtractName(*app_data, &name)) {
230 SetError(kErrMsgValueNotFound, "application name", error);
234 std::string short_name;
235 if (!ExtractShortName(*app_data, &short_name)) {
236 SetError(kErrMsgValueNotFound, "application short name", error);
241 if (!ExtractVersion(*app_data, &version)) {
242 SetError(kErrMsgValueNotFound, "application version", error);
246 std::vector<std::string> icons;
247 if (!ExtractIcons(*app_data->GetManifest(), &icons, error))
250 std::string api_version;
251 if (!ExtractApiVersion(*app_data, &api_version)) {
252 SetError(kErrMsgValueNotFound, "required api version", error);
256 std::set<std::string> privileges;
257 if (!ExtractPrivileges(*app_data, &privileges, error))
261 ManifestData* manifest_data = new ManifestData;
262 manifest_data->package = strdup(package.c_str());
263 manifest_data->id = strdup(id.c_str());
264 manifest_data->name = strdup(name.c_str());
265 manifest_data->short_name = strdup(short_name.c_str());
266 manifest_data->version = strdup(version.c_str());
267 manifest_data->icon =
268 icons.empty() ? strdup("") : strdup(icons.front().c_str());
269 manifest_data->api_version = strdup(api_version.c_str());
270 manifest_data->privilege_count = privileges.size();
271 manifest_data->privilege_list = new char*[privileges.size()];
272 char** privileges_it = manifest_data->privilege_list;
273 for (const std::string& p : privileges) {
274 *privileges_it = strdup(p.c_str());
277 *data = manifest_data;
283 API_EXPORT void ReleaseData(const ManifestData* data, const char* error) {
287 free(data->short_name);
290 free(data->api_version);
291 for (int i = 0; i < data->privilege_count; ++i)
292 free(data->privilege_list[i]);
293 delete[] data->privilege_list;