PKG_CHECK_MODULES(TZPLATFORM_CONFIG_DEPS REQUIRED libtzplatform-config)
PKG_CHECK_MODULES(LIBXML_DEPS REQUIRED libxml-2.0)
PKG_CHECK_MODULES(XMLSEC1_DEPS REQUIRED xmlsec1)
-PKG_CHECK_MODULES(WIDGET_MANIFEST_PARSER_DEPS REQUIRED widget-manifest-parser)
PKG_CHECK_MODULES(SECURITY_MANAGER_DEPS REQUIRED security-manager)
PKG_CHECK_MODULES(VCONF_DEPS REQUIRED vconf)
BuildRequires: pkgconfig(libzip)
BuildRequires: pkgconfig(libtzplatform-config)
BuildRequires: pkgconfig(xmlsec1)
-BuildRequires: pkgconfig(widget-manifest-parser)
BuildRequires: pkgconfig(vconf)
Requires: ca-certificates-tizen
SET(SRCS
system_locale.cc
utf_converter.cc
+ string_util.cc
values.cc
)
# Target - definition
--- /dev/null
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#include "utils/string_util.h"
+
+#include <string>
+
+namespace common_installer {
+namespace utils {
+
+#define WHITESPACE_UNICODE \
+ 0x0009, /* CHARACTER TABULATION */ \
+ 0x000A, /* LINE FEED (LF) */ \
+ 0x000B, /* LINE TABULATION */ \
+ 0x000C, /* FORM FEED (FF) */ \
+ 0x000D, /* CARRIAGE RETURN (CR) */ \
+ 0x0020, /* SPACE */ \
+ 0x0085, /* NEXT LINE (NEL) */ \
+ 0x00A0, /* NO-BREAK SPACE */ \
+ 0x1680, /* OGHAM SPACE MARK */ \
+ 0x2000, /* EN QUAD */ \
+ 0x2001, /* EM QUAD */ \
+ 0x2002, /* EN SPACE */ \
+ 0x2003, /* EM SPACE */ \
+ 0x2004, /* THREE-PER-EM SPACE */ \
+ 0x2005, /* FOUR-PER-EM SPACE */ \
+ 0x2006, /* SIX-PER-EM SPACE */ \
+ 0x2007, /* FIGURE SPACE */ \
+ 0x2008, /* PUNCTUATION SPACE */ \
+ 0x2009, /* THIN SPACE */ \
+ 0x200A, /* HAIR SPACE */ \
+ 0x2028, /* LINE SEPARATOR */ \
+ 0x2029, /* PARAGRAPH SEPARATOR */ \
+ 0x202F, /* NARROW NO-BREAK SPACE */ \
+ 0x205F, /* MEDIUM MATHEMATICAL SPACE */ \
+ 0x3000, /* IDEOGRAPHIC SPACE */ \
+ 0
+
+const char16_t kRightToLeftMark = 0x200F;
+const char16_t kLeftToRightMark = 0x200E;
+const char16_t kLeftToRightEmbeddingMark = 0x202A;
+const char16_t kRightToLeftEmbeddingMark = 0x202B;
+const char16_t kPopDirectionalFormatting = 0x202C;
+const char16_t kLeftToRightOverride = 0x202D;
+const char16_t kRightToLeftOverride = 0x202E;
+
+const char kDirLTRKey[] = "ltr";
+const char kDirRTLKey[] = "rtl";
+const char kDirLROKey[] = "lro";
+const char kDirRLOKey[] = "rlo";
+
+namespace {
+const wchar_t kWhitespaceWide[] = {
+ WHITESPACE_UNICODE
+};
+
+// Returns true if it's a whitespace character.
+inline bool IsWhitespace(wchar_t c) {
+ return wcschr(kWhitespaceWide, c) != nullptr;
+}
+
+template<typename STR>
+STR CollapseWhitespaceT(const STR& text,
+ bool trim_sequences_with_line_breaks) {
+ STR result;
+ result.resize(text.size());
+
+ // Set flags to pretend we're already in a trimmed whitespace sequence, so we
+ // will trim any leading whitespace.
+ bool in_whitespace = true;
+ bool already_trimmed = true;
+
+ int chars_written = 0;
+ for (typename STR::const_iterator i(text.begin()); i != text.end(); ++i) {
+ if (IsWhitespace(*i)) {
+ if (!in_whitespace) {
+ // Reduce all whitespace sequences to a single space.
+ in_whitespace = true;
+ result[chars_written++] = L' ';
+ }
+ if (trim_sequences_with_line_breaks && !already_trimmed &&
+ ((*i == '\n') || (*i == '\r'))) {
+ // Whitespace sequences containing CR or LF are eliminated entirely.
+ already_trimmed = true;
+ --chars_written;
+ }
+ } else {
+ // Non-whitespace chracters are copied straight across.
+ in_whitespace = false;
+ already_trimmed = false;
+ result[chars_written++] = *i;
+ }
+ }
+
+ if (in_whitespace && !already_trimmed) {
+ // Any trailing whitespace is eliminated.
+ --chars_written;
+ }
+
+ result.resize(chars_written);
+ return result;
+}
+} // namespace
+
+std::string CollapseWhitespace(const std::string& text,
+ bool trim_sequences_with_line_breaks) {
+ return CollapseWhitespaceT(text, trim_sequences_with_line_breaks);
+}
+
+std::u16string CollapseWhitespace(const std::u16string& text,
+ bool trim_sequences_with_line_breaks) {
+ return CollapseWhitespaceT(text, trim_sequences_with_line_breaks);
+}
+
+std::u16string StripWrappingBidiControlCharacters(const std::u16string& text) {
+ if (text.empty())
+ return text;
+ size_t begin_index = 0;
+ char16_t begin = text[begin_index];
+ if (begin == kLeftToRightEmbeddingMark ||
+ begin == kRightToLeftEmbeddingMark ||
+ begin == kLeftToRightOverride ||
+ begin == kRightToLeftOverride)
+ ++begin_index;
+ size_t end_index = text.length() - 1;
+ if (text[end_index] == kPopDirectionalFormatting)
+ --end_index;
+ return text.substr(begin_index, end_index - begin_index + 1);
+}
+
+std::u16string GetDirText(const std::u16string& text, const std::string& dir) {
+ if (dir == kDirLTRKey)
+ return kLeftToRightEmbeddingMark
+ + text
+ + kPopDirectionalFormatting;
+
+ if (dir == kDirRTLKey)
+ return kRightToLeftEmbeddingMark
+ + text
+ + kPopDirectionalFormatting;
+
+ if (dir == kDirLROKey)
+ return kLeftToRightOverride
+ + text
+ + kPopDirectionalFormatting;
+
+ if (dir == kDirRLOKey)
+ return kRightToLeftOverride
+ + text
+ + kPopDirectionalFormatting;
+
+ return text;
+}
+
+} // namespace utils
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#ifndef UTILS_STRING_UTIL_H_
+#define UTILS_STRING_UTIL_H_
+
+#include <string>
+
+namespace common_installer {
+namespace utils {
+
+std::string CollapseWhitespace(const std::string& text,
+ bool trim_sequences_with_line_breaks);
+std::u16string CollapseWhitespace(const std::u16string& text,
+ bool trim_sequences_with_line_breaks);
+std::u16string StripWrappingBidiControlCharacters(const std::u16string& text);
+std::u16string GetDirText(const std::u16string& text, const std::string& dir);
+void WrapStringWithLTRFormatting(std::u16string* text);
+bool AdjustStringForLocaleDirection(std::u16string* text);
+} // namespace utils
+} // namespace common_installer
+
+#endif // UTILS_STRING_UTIL_H_
# Target - deps
APPLY_PKG_CONFIG(${TARGET_WGT_BACKEND} PUBLIC
PKGMGR_INSTALLER_DEPS
- WIDGET_MANIFEST_PARSER_DEPS
)
# Target - in-package deps
TARGET_LINK_LIBRARIES(${TARGET_WGT_BACKEND} PUBLIC ${TARGET_LIBNAME_COMMON})
+TARGET_LINK_LIBRARIES(${TARGET_WGT_BACKEND} PUBLIC ${TARGET_LIBNAME_WIDGET_MANIFEST_PARSER})
# Install
INSTALL(TARGETS ${TARGET_WGT_BACKEND} DESTINATION ${BINDIR})
#include <boost/filesystem.hpp>
-#include <widget-manifest-parser/widget-manifest-parser.h>
+#include <widget-manifest-parser/widget_manifest_parser.h>
#include "common/app_installer.h"
#include "common/context_installer.h"
# Target - sources
SET(SRCS
+ application_data.cc
application_manifest_constants.cc
manifest.cc
+ manifest_handler.cc
+ manifest_handlers/permissions_handler.cc
+ manifest_handlers/tizen_application_handler.cc
+ manifest_handlers/widget_handler.cc
+ manifest_util.cc
+ widget_manifest_parser.cc
)
# Target - definition
ADD_LIBRARY(${TARGET_LIBNAME_WIDGET_MANIFEST_PARSER} SHARED ${SRCS})
--- /dev/null
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#include "widget-manifest-parser/application_data.h"
+
+#include <cassert>
+#include <iostream>
+#include <regex>
+
+#include "utils/logging.h"
+#include "utils/utf_converter.h"
+#include "widget-manifest-parser/application_manifest_constants.h"
+#include "widget-manifest-parser/manifest.h"
+#include "widget-manifest-parser/manifest_handler.h"
+#include "widget-manifest-parser/manifest_handlers/permissions_handler.h"
+#include "widget-manifest-parser/manifest_handlers/widget_handler.h"
+#include "widget-manifest-parser/manifest_handlers/tizen_application_handler.h"
+
+namespace keys = common_installer::application_manifest_keys;
+namespace widget_keys = common_installer::application_widget_keys;
+namespace errors = common_installer::application_manifest_errors;
+
+namespace {
+const char kApplicationScheme[] = "app";
+const char kWGTAppIdPattern[] = "\\A([0-9a-zA-Z]{10})[.][0-9a-zA-Z]{1,52}\\z";
+const std::string kAppIdPrefix("xwalk.");
+
+const size_t kIdSize = 16;
+
+bool IsValidWGTID(const std::string& id) {
+ std::regex regex(kWGTAppIdPattern);
+ return std::regex_match (id, regex);
+}
+
+std::string AppIdToPkgId(const std::string& id) {
+ std::string package_id;
+ if (!IsValidWGTID(id)) {
+ LOG(WARNING) << "Cannot get package_id from invalid app id";
+ return std::string();
+ }
+ return package_id;
+}
+
+} // namespace
+
+namespace common_installer {
+namespace widget_manifest_parser {
+
+// static
+std::shared_ptr<ApplicationData> ApplicationData::Create(
+ const bf::path& path, const std::string& explicit_id,
+ SourceType source_type, std::unique_ptr<Manifest> manifest,
+ std::string* error_message) {
+ assert(error_message);
+ std::u16string error;
+ if (!manifest->ValidateManifest(error_message))
+ return nullptr;
+
+ std::shared_ptr<ApplicationData> app_data(
+ new ApplicationData(path, source_type, std::move(manifest)));
+ if (!app_data->Init(explicit_id, &error)) {
+ *error_message = utils::utf_converter::UTF16ToUTF8(error);
+ return nullptr;
+ }
+
+ ManifestHandlerRegistry* registry =
+ ManifestHandlerRegistry::GetInstance(app_data->manifest_type());
+
+ if (!registry->ValidateAppManifest(app_data, error_message))
+ return nullptr;
+ return app_data;
+}
+
+// static
+std::string ApplicationData::GetBaseURLFromApplicationId(
+ const std::string& application_id) {
+ return (std::string(kApplicationScheme) +
+ "://" + application_id + "/");
+}
+
+ApplicationData::ManifestData* ApplicationData::GetManifestData(
+ const std::string& key) const {
+ assert(finished_parsing_manifest_);
+ ManifestDataMap::const_iterator iter = manifest_data_.find(key);
+ if (iter != manifest_data_.end())
+ return iter->second.get();
+ return nullptr;
+}
+
+void ApplicationData::SetManifestData(const std::string& key,
+ std::shared_ptr<ApplicationData::ManifestData> data) {
+ assert(!finished_parsing_manifest_);
+ manifest_data_[key] = data;
+}
+
+std::string ApplicationData::GetPackageID() const {
+ return AppIdToPkgId(application_id_);
+}
+
+const std::string ApplicationData::VersionString() const {
+ if (!version_.empty())
+ return Version();
+ return "";
+}
+
+bool ApplicationData::IsHostedApp() const {
+ bool hosted = source_type_ == EXTERNAL_URL;
+ if (manifest_->HasPath(widget_keys::kContentNamespace)) {
+ std::string ns;
+ if (manifest_->GetString(widget_keys::kContentNamespace, &ns) &&
+ ns == widget_keys::kTizenNamespacePrefix)
+ hosted = true;
+ }
+ return hosted;
+}
+
+ApplicationData::ApplicationData(const bf::path& path,
+ SourceType source_type, std::unique_ptr<Manifest> manifest)
+ : manifest_version_(0),
+ path_(path),
+ manifest_(std::move(manifest)),
+ finished_parsing_manifest_(false),
+ source_type_(source_type) {
+ assert(path_.empty() || path_.is_absolute());
+}
+
+ApplicationData::~ApplicationData() {
+}
+
+bool ApplicationData::Init(const std::string& explicit_id,
+ std::u16string* error) {
+ assert(error);
+ ManifestHandlerRegistry* registry =
+ ManifestHandlerRegistry::GetInstance(manifest_type());
+ if (!registry->ParseAppManifest(shared_from_this(), error))
+ return false;
+
+ if (!LoadID(explicit_id, error))
+ return false;
+ if (!LoadName(error))
+ return false;
+ if (!LoadVersion(error))
+ return false;
+
+ application_url_ = ApplicationData::GetBaseURLFromApplicationId(ID());
+ finished_parsing_manifest_ = true;
+ return true;
+}
+
+bool ApplicationData::LoadID(const std::string& explicit_id,
+ std::u16string* error) {
+ std::string application_id;
+ auto iter = manifest_data_.find(widget_keys::kTizenApplicationKey);
+ if (iter == manifest_data_.end())
+ return false;
+ const TizenApplicationInfo* tizen_app_info =
+ static_cast<TizenApplicationInfo*>(iter->second.get());
+ assert(tizen_app_info);
+ application_id = tizen_app_info->id();
+ if (!application_id.empty()) {
+ application_id_ = application_id;
+ return true;
+ }
+ if (!explicit_id.empty()) {
+ application_id_ = explicit_id;
+ return true;
+ }
+ return false;
+}
+
+bool ApplicationData::LoadName(std::u16string* error) {
+ assert(error);
+ std::u16string localized_name;
+ std::string name_key(GetNameKey(manifest_type()));
+
+ if (!manifest_->GetString(name_key, &localized_name) &&
+ manifest_type() == Manifest::TYPE_MANIFEST) {
+ *error = errors::kInvalidName;
+ return false;
+ }
+ non_localized_name_ = common_installer::utils::utf_converter::UTF16ToUTF8(
+ localized_name);
+
+ // TODO(jizydorczyk): This needs to be implemented
+ // utils::AdjustStringForLocaleDirection(&localized_name);
+ name_ = common_installer::utils::utf_converter::UTF16ToUTF8(localized_name);
+ return true;
+}
+
+bool ApplicationData::LoadVersion(std::u16string* error) {
+ assert(error);
+ std::string version_str;
+
+ version_ = "";
+
+ bool ok = manifest_->GetString(widget_keys::kVersionKey, &version_str);
+ if (!ok) {
+ *error = errors::kInvalidVersion;
+ return true;
+ }
+
+ version_ = std::string(version_str);
+ return true;
+}
+
+bool ApplicationData::SetApplicationLocale(const std::string& locale,
+ std::u16string* error) {
+ manifest_->SetSystemLocale(locale);
+ if (!LoadName(error))
+ return false;
+
+ if (WidgetInfo* widget_info = static_cast<WidgetInfo*>(
+ GetManifestData(widget_keys::kWidgetKey))) {
+ std::string string_value;
+ if (manifest_->GetString(widget_keys::kNameKey, &string_value))
+ widget_info->SetName(string_value);
+ if (manifest_->GetString(widget_keys::kShortNameKey, &string_value))
+ widget_info->SetShortName(string_value);
+ if (manifest_->GetString(widget_keys::kDescriptionKey, &string_value))
+ widget_info->SetDescription(string_value);
+ }
+ return true;
+}
+
+} // namespace widget_manifest_parser
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#ifndef WIDGET_MANIFEST_PARSER_APPLICATION_DATA_H_
+#define WIDGET_MANIFEST_PARSER_APPLICATION_DATA_H_
+
+#include <boost/filesystem/path.hpp>
+#include <string.h>
+
+#include <algorithm>
+#include <iosfwd>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "utils/values.h"
+#include "widget-manifest-parser/manifest.h"
+#include "widget-manifest-parser/permission_types.h"
+// TODO(jizydorczyk) Conver package from xwalk for our needs
+// #include "widget-manifest-parser/package/package.h"
+
+namespace bf = boost::filesystem;
+
+namespace common_installer {
+namespace widget_manifest_parser {
+
+// TODO(t.iwanek): there should be private inheritence
+// FIX ME!
+class ApplicationData : public std::enable_shared_from_this<ApplicationData> {
+ public:
+ // Where an application was loaded from.
+ enum SourceType {
+ INTERNAL, // From internal application registry.
+ LOCAL_DIRECTORY, // From a persistently stored unpacked application
+ TEMP_DIRECTORY, // From a temporary folder
+ EXTERNAL_URL // From an arbitrary URL
+ };
+
+ struct ManifestData;
+
+ struct ApplicationIdCompare {
+ bool operator()(const std::string& s1, const std::string& s2) const {
+ return strcasecmp(s1.c_str(), s2.c_str()) < 0;
+ }
+ };
+
+ typedef std::map<const std::string, std::shared_ptr<ManifestData> >
+ ManifestDataMap;
+ typedef std::map<std::string,
+ std::shared_ptr<ApplicationData>, ApplicationIdCompare>
+ ApplicationDataMap;
+ typedef ApplicationDataMap::iterator ApplicationDataMapIterator;
+
+ // A base class for parsed manifest data that APIs want to store on
+ // the application. Related to base::SupportsUserData, but with an immutable
+ // thread-safe interface to match Application.
+ struct ManifestData {
+ virtual ~ManifestData() {}
+ };
+
+ static std::shared_ptr<ApplicationData> Create(const bf::path& app_path,
+ const std::string& explicit_id, SourceType source_type,
+ std::unique_ptr<Manifest> manifest, std::string* error_message);
+
+ // Returns the base application url for a given |application_id|.
+ static std::string GetBaseURLFromApplicationId(
+ const std::string& application_id);
+
+ // Get the manifest data associated with the key, or NULL if there is none.
+ // Can only be called after InitValue is finished.
+ ManifestData* GetManifestData(const std::string& key) const;
+
+ // Sets |data| to be associated with the key. Takes ownership of |data|.
+ // Can only be called before InitValue is finished. Not thread-safe;
+ // all SetManifestData calls should be on only one thread.
+ void SetManifestData(const std::string& key,
+ std::shared_ptr<ManifestData> data);
+
+ // Accessors:
+ const bf::path& path() const { return path_; }
+ const std::string& URL() const { return application_url_; }
+ SourceType source_type() const { return source_type_; }
+ Manifest::Type manifest_type() const { return manifest_->type(); }
+ const std::string& ID() const { return application_id_; }
+ std::string GetPackageID() const;
+ const std::string Version() const { return version_; }
+ const std::string VersionString() const;
+ const std::string& Name() const { return name_; }
+ const std::string& NonLocalizedName() const { return non_localized_name_; }
+ const std::string& Description() const { return description_; }
+
+ const Manifest* GetManifest() const {
+ return manifest_.get();
+ }
+
+ // App-related.
+ bool IsHostedApp() const;
+
+ bool SetApplicationLocale(const std::string& locale, std::u16string* error);
+
+ virtual ~ApplicationData();
+
+ private:
+ ApplicationData(const bf::path& path,
+ SourceType source_type, std::unique_ptr<Manifest> manifest);
+
+ // Initialize the application from a parsed manifest.
+ bool Init(const std::string& explicit_id, std::u16string* error);
+
+ // Chooses the application ID for an application based on a variety of
+ // criteria. The chosen ID will be set in |manifest|.
+ bool LoadID(const std::string& explicit_id, std::u16string* error);
+ // The following are helpers for InitFromValue to load various features of the
+ // application from the manifest.
+ bool LoadName(std::u16string* error);
+ bool LoadVersion(std::u16string* error);
+
+ // The application's human-readable name. Name is used for display purpose. It
+ // might be wrapped with unicode bidi control characters so that it is
+ // displayed correctly in RTL context.
+ // NOTE: Name is UTF-8 and may contain non-ascii characters.
+ std::string name_;
+
+ // A non-localized version of the application's name. This is useful for
+ // debug output.
+ std::string non_localized_name_;
+
+ // The version of this application's manifest. We increase the manifest
+ // version when making breaking changes to the application system.
+ // Version 1 was the first manifest version (implied by a lack of a
+ // manifest_version attribute in the application's manifest). We initialize
+ // this member variable to 0 to distinguish the "uninitialized" case from
+ // the case when we know the manifest version actually is 1.
+ int manifest_version_;
+
+ // The absolute path to the directory the application is stored in.
+ bf::path path_;
+
+ // A persistent, globally unique ID. An application's ID is used in things
+ // like directory structures and URLs, and is expected to not change across
+ // versions.
+ std::string application_id_;
+
+ // The base application url for the application.
+ std::string application_url_;
+
+ // The application's version.
+ std::string version_;
+
+ // An optional longer description of the application.
+ std::string description_;
+
+ // The manifest from which this application was created.
+ std::unique_ptr<Manifest> manifest_;
+
+ // Stored parsed manifest data.
+ ManifestDataMap manifest_data_;
+
+ // Set to true at the end of InitValue when initialization is finished.
+ bool finished_parsing_manifest_;
+
+ // The source the application was loaded from.
+ SourceType source_type_;
+
+// DISALLOW_COPY_AND_ASSIGN(ApplicationData);
+};
+
+} // namespace widget_manifest_parser
+} // namespace common_installer
+
+#endif // WIDGET_MANIFEST_PARSER_APPLICATION_DATA_H_
--- /dev/null
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#include "widget-manifest-parser/manifest_handler.h"
+
+#include <cassert>
+#include <set>
+
+#include "widget-manifest-parser/application_manifest_constants.h"
+
+#include "widget-manifest-parser/manifest_handlers/permissions_handler.h"
+#include "widget-manifest-parser/manifest_handlers/tizen_application_handler.h"
+#include "widget-manifest-parser/manifest_handlers/widget_handler.h"
+
+// TODO(t.iwanek): add following handlers
+// #include "widget-manifest-parser/manifest_handlers/tizen_appwidget_handler.h"
+// #include "widget-manifest-parser/manifest_handlers/tizen_category_handler.h"
+// #include "widget-manifest-parser/manifest_handlers/tizen_ime_handler.h"
+// #include "widget-manifest-parser/manifest_handlers/tizen_metadata_handler.h"
+// #include "widget-manifest-parser/manifest_handlers/tizen_navigation_handler.h"
+// #include "widget-manifest-parser/manifest_handlers/tizen_setting_handler.h"
+// #include "widget-manifest-parser/manifest_handlers/tizen_splash_screen_handler.h"
+
+namespace common_installer {
+namespace widget_manifest_parser {
+
+namespace {
+
+bool ValidateImeCategory(
+ const common_installer::widget_manifest_parser::ApplicationData&
+ application,
+ std::string* error) {
+ namespace keys = common_installer::application_widget_keys;
+ // if config contains tizen:ime tag, proper category should be specified
+
+ // TODO(t.iwanek): fix me - add IME handler and uncomment
+
+// if (application.GetManifestData(keys::kTizenImeKey)) {
+// const common_installer::widget_manifest_parser::CategoryInfoList*
+// categories_list =
+// static_cast<const CategoryInfoList*>(
+// application.GetManifestData(keys::kTizenCategoryKey));
+
+// if (categories_list) {
+// const char imeCategory[] = "http://tizen.org/category/ime";
+// for (const std::string& category : categories_list->categories) {
+// if (category == imeCategory)
+// return true;
+// }
+// }
+// *error = "tizen:ime is specified but not proper category added";
+// return false;
+// }
+ return true;
+}
+
+} // namespace
+
+ManifestHandler::~ManifestHandler() {
+}
+
+bool ManifestHandler::Validate(
+ std::shared_ptr<const ApplicationData> application,
+ std::string* error) const {
+ return true;
+}
+
+bool ManifestHandler::AlwaysParseForType(Manifest::Type type) const {
+ return false;
+}
+
+bool ManifestHandler::AlwaysValidateForType(Manifest::Type type) const {
+ return false;
+}
+
+std::vector<std::string> ManifestHandler::PrerequisiteKeys() const {
+ return std::vector<std::string>();
+}
+
+ManifestHandlerRegistry* ManifestHandlerRegistry::widget_registry_ = NULL;
+
+ManifestHandlerRegistry::ManifestHandlerRegistry(
+ const std::vector<ManifestHandler*>& handlers) {
+ for (std::vector<ManifestHandler*>::const_iterator it = handlers.begin();
+ it != handlers.end(); ++it) {
+ Register(*it);
+ }
+
+ ReorderHandlersGivenDependencies();
+}
+
+ManifestHandlerRegistry::~ManifestHandlerRegistry() {
+}
+
+ManifestHandlerRegistry*
+ManifestHandlerRegistry::GetInstance(Manifest::Type type) {
+ return GetInstanceForWGT();
+}
+
+ManifestHandlerRegistry*
+ManifestHandlerRegistry::GetInstanceForWGT() {
+ if (widget_registry_)
+ return widget_registry_;
+
+ std::vector<ManifestHandler*> handlers;
+ // We can put WGT specific manifest handlers here.
+ handlers.push_back(new WidgetHandler);
+ handlers.push_back(new TizenApplicationHandler);
+ handlers.push_back(new PermissionsHandler);
+
+ widget_registry_ = new ManifestHandlerRegistry(handlers);
+ return widget_registry_;
+}
+
+void ManifestHandlerRegistry::Register(ManifestHandler* handler) {
+ const std::vector<std::string>& keys = handler->Keys();
+ for (size_t i = 0; i < keys.size(); ++i) {
+ handlers_[keys[i]] = handler;
+ }
+}
+
+bool ManifestHandlerRegistry::ParseAppManifest(
+ std::shared_ptr<ApplicationData> application, std::u16string* error) {
+ std::map<int, ManifestHandler*> handlers_by_order;
+ for (ManifestHandlerMap::iterator iter = handlers_.begin();
+ iter != handlers_.end(); ++iter) {
+ ManifestHandler* handler = iter->second;
+ if (application->GetManifest()->HasPath(iter->first) ||
+ handler->AlwaysParseForType(application->manifest_type())) {
+ handlers_by_order[order_map_[handler]] = handler;
+ }
+ }
+ for (std::map<int, ManifestHandler*>::iterator iter =
+ handlers_by_order.begin();
+ iter != handlers_by_order.end(); ++iter) {
+ if (!(iter->second)->Parse(application, error)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ManifestHandlerRegistry::ValidateAppManifest(
+ std::shared_ptr<const ApplicationData> application,
+ std::string* error) {
+ for (ManifestHandlerMap::iterator iter = handlers_.begin();
+ iter != handlers_.end(); ++iter) {
+ ManifestHandler* handler = iter->second;
+ if ((application->GetManifest()->HasPath(iter->first) ||
+ handler->AlwaysValidateForType(application->manifest_type())) &&
+ !handler->Validate(application, error))
+ return false;
+ }
+
+ if (!ValidateImeCategory(*application, error))
+ return false;
+
+ return true;
+}
+
+// static
+void ManifestHandlerRegistry::SetInstanceForTesting(
+ ManifestHandlerRegistry* registry, Manifest::Type type) {
+ widget_registry_ = registry;
+ return;
+}
+
+void ManifestHandlerRegistry::ReorderHandlersGivenDependencies() {
+ std::set<ManifestHandler*> unsorted_handlers;
+ for (ManifestHandlerMap::const_iterator iter = handlers_.begin();
+ iter != handlers_.end(); ++iter) {
+ unsorted_handlers.insert(iter->second);
+ }
+
+ int order = 0;
+ while (true) {
+ std::set<ManifestHandler*> next_unsorted_handlers;
+ for (std::set<ManifestHandler*>::const_iterator iter =
+ unsorted_handlers.begin();
+ iter != unsorted_handlers.end(); ++iter) {
+ ManifestHandler* handler = *iter;
+ const std::vector<std::string>& prerequisites =
+ handler->PrerequisiteKeys();
+ int unsatisfied = prerequisites.size();
+ for (size_t i = 0; i < prerequisites.size(); ++i) {
+ ManifestHandlerMap::const_iterator prereq_iter =
+ handlers_.find(prerequisites[i]);
+ assert(prereq_iter != handlers_.end() &&
+ "Application manifest handler depends on unrecognized key ");
+ // Prerequisite is in our map.
+ if (order_map_.find(prereq_iter->second) != order_map_.end())
+ unsatisfied--;
+ }
+ if (unsatisfied == 0) {
+ order_map_[handler] = order;
+ order++;
+ } else {
+ // Put in the list for next time.
+ next_unsorted_handlers.insert(handler);
+ }
+ }
+ if (next_unsorted_handlers.size() == unsorted_handlers.size())
+ break;
+ unsorted_handlers.swap(next_unsorted_handlers);
+ }
+
+ // If there are any leftover unsorted handlers, they must have had
+ // circular dependencies.
+ assert(unsorted_handlers.empty() &&
+ "Application manifest handlers have circular dependencies!");
+}
+
+} // namespace widget_manifest_parser
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#ifndef WIDGET_MANIFEST_PARSER_MANIFEST_HANDLER_H_
+#define WIDGET_MANIFEST_PARSER_MANIFEST_HANDLER_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "widget-manifest-parser/manifest.h"
+#include "widget-manifest-parser/application_data.h"
+
+namespace common_installer {
+namespace widget_manifest_parser {
+
+class ManifestHandler {
+ public:
+ virtual ~ManifestHandler();
+
+ // Returns false in case of failure and sets writes error message
+ // in |error| if present.
+ virtual bool Parse(std::shared_ptr<ApplicationData> application,
+ std::u16string* error) = 0;
+
+ // Returns false in case of failure and sets writes error message
+ // in |error| if present.
+ virtual bool Validate(std::shared_ptr<const ApplicationData> application,
+ std::string* error) const;
+
+ // If false (the default), only parse the manifest if a registered
+ // key is present in the manifest. If true, always attempt to parse
+ // the manifest for this application type, even if no registered keys
+ // are present. This allows specifying a default parsed value for
+ // application that don't declare our key in the manifest.
+ virtual bool AlwaysParseForType(Manifest::Type type) const;
+
+ // Same as AlwaysParseForType, but for Validate instead of Parse.
+ virtual bool AlwaysValidateForType(Manifest::Type type) const;
+
+ // The list of keys that, if present, should be parsed before calling our
+ // Parse (typically, because our Parse needs to read those keys).
+ // Defaults to empty.
+ virtual std::vector<std::string> PrerequisiteKeys() const;
+
+ // The keys to register handler for (in Register).
+ virtual std::vector<std::string> Keys() const = 0;
+};
+
+class ManifestHandlerRegistry final {
+ public:
+ ~ManifestHandlerRegistry();
+
+ static ManifestHandlerRegistry* GetInstance(Manifest::Type type);
+
+ bool ParseAppManifest(
+ std::shared_ptr<ApplicationData> application, std::u16string* error);
+ bool ValidateAppManifest(std::shared_ptr<const ApplicationData> application,
+ std::string* error);
+
+ private:
+ friend class ScopedTestingManifestHandlerRegistry;
+ explicit ManifestHandlerRegistry(
+ const std::vector<ManifestHandler*>& handlers);
+
+ // Register a manifest handler for keys, which are provided by Keys() method
+ // in ManifestHandler implementer.
+ void Register(ManifestHandler* handler);
+
+ void ReorderHandlersGivenDependencies();
+
+ // Sets a new global registry, for testing purposes.
+ static void SetInstanceForTesting(ManifestHandlerRegistry* registry,
+ Manifest::Type type);
+
+ static ManifestHandlerRegistry* GetInstanceForWGT();
+ static ManifestHandlerRegistry* GetInstanceForXPK();
+
+ typedef std::map<std::string, ManifestHandler*> ManifestHandlerMap;
+ typedef std::map<ManifestHandler*, int> ManifestHandlerOrderMap;
+
+ ManifestHandlerMap handlers_;
+
+ // Handlers are executed in order; lowest order first.
+ ManifestHandlerOrderMap order_map_;
+
+ static ManifestHandlerRegistry* xpk_registry_;
+ static ManifestHandlerRegistry* widget_registry_;
+};
+
+} // namespace widget_manifest_parser
+} // namespace common_installer
+
+#endif // WIDGET_MANIFEST_PARSER_MANIFEST_HANDLER_H_
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#include "widget-manifest-parser/manifest_handlers/permissions_handler.h"
+
+#include <iostream>
+
+#include "utils/logging.h"
+#include "utils/values.h"
+#include "widget-manifest-parser/application_manifest_constants.h"
+
+namespace common_installer {
+
+namespace keys = application_widget_keys;
+
+namespace widget_manifest_parser {
+
+PermissionsInfo::PermissionsInfo() {
+}
+
+PermissionsInfo::~PermissionsInfo() {
+}
+
+PermissionsHandler::PermissionsHandler() {
+}
+
+PermissionsHandler::~PermissionsHandler() {
+}
+
+bool PermissionsHandler::Parse(
+ std::shared_ptr<ApplicationData> application, std::u16string* error) {
+ std::shared_ptr<PermissionsInfo> permissions_info(new PermissionsInfo);
+ if (!application->GetManifest()->HasPath(keys::kTizenPermissionsKey)) {
+ application->SetManifestData(
+ keys::kTizenPermissionsKey, permissions_info);
+ return true;
+ }
+
+ utils::Value* value;
+ if (!application->GetManifest()->Get(keys::kTizenPermissionsKey, &value)) {
+ *error = u"Invalid value of tizen permissions.";
+ return false;
+ }
+
+ std::unique_ptr<utils::ListValue> permission_list;
+ if (value->IsType(utils::Value::TYPE_DICTIONARY)) {
+ permission_list.reset(new utils::ListValue);
+ permission_list->Append(value->DeepCopy());
+ } else {
+ utils::ListValue* list = nullptr;
+ value->GetAsList(&list);
+ if (list)
+ permission_list.reset(list->DeepCopy());
+ }
+
+ if (!permission_list) {
+ *error = u"Invalid value of permissions.";
+ return false;
+ }
+ PermissionSet api_permissions;
+ for (utils::ListValue::const_iterator it = permission_list->begin();
+ it != permission_list->end(); ++it) {
+ utils::DictionaryValue* dictionary_value = nullptr;
+ (*it)->GetAsDictionary(&dictionary_value);
+
+ std::string permission;
+ if (!dictionary_value ||
+ !dictionary_value->GetString(
+ keys::kTizenPermissionsNameKey, &permission) ||
+ permission.empty())
+ continue;
+
+ if (api_permissions.find(permission) != api_permissions.end())
+ LOG(WARNING) << "Duplicated permission names found.";
+
+ api_permissions.insert(permission);
+ }
+
+ permissions_info->SetAPIPermissions(api_permissions);
+ application->SetManifestData(keys::kTizenPermissionsKey,
+ permissions_info);
+
+ return true;
+}
+
+bool PermissionsHandler::AlwaysParseForType(Manifest::Type type) const {
+ return type == Manifest::TYPE_WIDGET;
+}
+
+std::vector<std::string> PermissionsHandler::Keys() const {
+ return std::vector<std::string>(1, keys::kTizenPermissionsKey);
+}
+
+} // namespace widget_manifest_parser
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#ifndef WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_PERMISSIONS_HANDLER_H_
+#define WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_PERMISSIONS_HANDLER_H_
+
+#include <string>
+#include <vector>
+
+#include "utils/macros.h"
+
+#include "widget-manifest-parser/manifest_handler.h"
+#include "widget-manifest-parser/permission_types.h"
+
+namespace common_installer {
+namespace widget_manifest_parser {
+
+class PermissionsInfo: public ApplicationData::ManifestData {
+ public:
+ PermissionsInfo();
+ virtual ~PermissionsInfo();
+
+ const PermissionSet& GetAPIPermissions() const {
+ return api_permissions_;}
+ void SetAPIPermissions(const PermissionSet& api_permissions) {
+ api_permissions_ = api_permissions;
+ }
+
+ private:
+ PermissionSet api_permissions_;
+ DISALLOW_COPY_AND_ASSIGN(PermissionsInfo);
+};
+
+class PermissionsHandler: public ManifestHandler {
+ public:
+ PermissionsHandler();
+ virtual ~PermissionsHandler();
+
+ bool Parse(std::shared_ptr<ApplicationData> application,
+ std::u16string* error) override;
+ bool AlwaysParseForType(Manifest::Type type) const override;
+ std::vector<std::string> Keys() const override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PermissionsHandler);
+};
+
+} // namespace widget_manifest_parser
+} // namespace common_installer
+
+#endif // WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_PERMISSIONS_HANDLER_H_
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#include "widget-manifest-parser/manifest_handlers/tizen_application_handler.h"
+
+#include <cassert>
+#include <map>
+#include <regex>
+#include <utility>
+
+#include "utils/values.h"
+#include "widget-manifest-parser/application_manifest_constants.h"
+
+namespace {
+const char kTizenWebAPIVersion[] = "2.2";
+}
+
+namespace common_installer {
+
+namespace keys = application_widget_keys;
+
+namespace widget_manifest_parser {
+
+TizenApplicationInfo::TizenApplicationInfo() {
+}
+
+TizenApplicationInfo::~TizenApplicationInfo() {
+}
+
+TizenApplicationHandler::TizenApplicationHandler() {}
+
+TizenApplicationHandler::~TizenApplicationHandler() {}
+
+bool TizenApplicationHandler::Parse(
+ std::shared_ptr<ApplicationData> application, std::u16string* error) {
+ std::shared_ptr<TizenApplicationInfo> app_info(new TizenApplicationInfo);
+ const Manifest* manifest = application->GetManifest();
+ assert(manifest);
+
+ utils::Value* app_value = nullptr;
+ manifest->Get(keys::kTizenApplicationKey, &app_value);
+ // Find an application element with tizen namespace
+ utils::DictionaryValue* app_dict;
+ std::string value;
+ bool find = false;
+ if (app_value && app_value->IsType(utils::Value::TYPE_DICTIONARY)) {
+ app_value->GetAsDictionary(&app_dict);
+ find = app_dict->GetString(keys::kNamespaceKey, &value);
+ find = find && (value == keys::kTizenNamespacePrefix);
+ } else if (app_value && app_value->IsType(utils::Value::TYPE_LIST)) {
+ utils::ListValue* list;
+ app_value->GetAsList(&list);
+ for (utils::ListValue::iterator it = list->begin();
+ it != list->end(); ++it) {
+ (*it)->GetAsDictionary(&app_dict);
+ find = app_dict->GetString(keys::kNamespaceKey, &value);
+ find = find && (value == keys::kTizenNamespacePrefix);
+ if (find)
+ break;
+ }
+ }
+
+ if (!find) {
+ *error = u"Cannot find application element with tizen namespace "
+ u"or the tizen namespace prefix is incorrect.\n";
+ return false;
+ }
+ if (app_dict->GetString(keys::kTizenApplicationIdKey, &value))
+ app_info->set_id(value);
+ if (app_dict->GetString(keys::kTizenApplicationPackageKey, &value)) {
+ app_info->set_package(value);
+ }
+ if (app_dict->GetString(keys::kTizenApplicationRequiredVersionKey, &value))
+ app_info->set_required_version(value);
+
+ application->SetManifestData(keys::kTizenApplicationKey,
+ app_info);
+ return true;
+}
+
+bool TizenApplicationHandler::Validate(
+ std::shared_ptr<const ApplicationData> application,
+ std::string* error) const {
+ const TizenApplicationInfo* app_info =
+ static_cast<const TizenApplicationInfo*>(
+ application->GetManifestData(keys::kTizenApplicationKey));
+
+ const char kIdPattern[] = "\\A[0-9a-zA-Z]{10}[.][0-9a-zA-Z]{1,52}\\z";
+ const char kPackagePattern[] = "\\A[0-9a-zA-Z]{10}\\z";
+ std::regex package_regex(kPackagePattern);
+ std::regex id_regex(kIdPattern);
+ if (std::regex_search(app_info->id(), id_regex)) {
+ *error = "The id property of application element "
+ "does not match the format\n";
+ return false;
+ }
+ if (std::regex_search(app_info->package(), package_regex)) {
+ *error = "The package property of application element "
+ "does not match the format\n";
+ return false;
+ }
+ if (app_info->id().find(app_info->package()) != 0) {
+ *error = "The application element property id "
+ "does not start with package.\n";
+ fprintf(stderr, "app_info->id() = %s\n", app_info->id().c_str());
+ fprintf(stderr, "app_info->package() = %s\n", app_info->package().c_str());
+ return false;
+ }
+ if (app_info->required_version().empty()) {
+ *error = "The required_version property of application "
+ "element does not exist.\n";
+ return false;
+ }
+
+ const std::string supported_version = kTizenWebAPIVersion;
+ if (supported_version.compare(app_info->required_version()) < 0) {
+ *error = "The required_version of Tizen Web API "
+ "is not supported.\n";
+ return false;
+ }
+
+ return true;
+}
+
+std::vector<std::string> TizenApplicationHandler::Keys() const {
+ return std::vector<std::string>(1, keys::kTizenApplicationKey);
+}
+
+bool TizenApplicationHandler::AlwaysParseForType(Manifest::Type type) const {
+ return true;
+}
+
+} // namespace widget_manifest_parser
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#ifndef WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_TIZEN_APPLICATION_HANDLER_H_
+#define WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_TIZEN_APPLICATION_HANDLER_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "utils/macros.h"
+#include "utils/values.h"
+#include "widget-manifest-parser/application_manifest_constants.h"
+#include "widget-manifest-parser/manifest_handler.h"
+
+namespace common_installer {
+namespace widget_manifest_parser {
+
+class TizenApplicationInfo : public ApplicationData::ManifestData {
+ public:
+ TizenApplicationInfo();
+ virtual ~TizenApplicationInfo();
+
+ void set_id(const std::string& id) {
+ id_ = id;
+ }
+ void set_package(const std::string& package) {
+ package_ = package;
+ }
+ void set_required_version(
+ const std::string& required_version) {
+ required_version_ = required_version;
+ }
+ const std::string& id() const {
+ return id_;
+ }
+ const std::string& package() const {
+ return package_;
+ }
+ const std::string& required_version() const {
+ return required_version_;
+ }
+
+ private:
+ std::string id_;
+ std::string package_;
+ std::string required_version_;
+};
+
+class TizenApplicationHandler : public ManifestHandler {
+ public:
+ TizenApplicationHandler();
+ virtual ~TizenApplicationHandler();
+
+ bool Parse(std::shared_ptr<ApplicationData> application,
+ std::u16string* error) override;
+ bool Validate(std::shared_ptr<const ApplicationData> application,
+ std::string* error) const override;
+ bool AlwaysParseForType(Manifest::Type type) const override;
+ std::vector<std::string> Keys() const override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TizenApplicationHandler);
+};
+
+} // namespace widget_manifest_parser
+} // namespace common_installer
+
+#endif // WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_TIZEN_APPLICATION_HANDLER_H_
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#include "widget-manifest-parser/manifest_handlers/widget_handler.h"
+
+#include <string.h>
+
+#include <cassert>
+#include <map>
+#include <utility>
+#include <set>
+
+#include "utils/utf_converter.h"
+#include "utils/values.h"
+#include "widget-manifest-parser/application_manifest_constants.h"
+
+namespace common_installer {
+
+namespace keys = application_widget_keys;
+
+namespace {
+// Below key names are readable from Javascript widget interface.
+const char kAuthor[] = "author";
+const char kDecription[] = "description";
+const char kName[] = "name";
+const char kShortName[] = "shortName";
+const char kVersion[] = "version";
+const char kID[] = "id";
+const char kAuthorEmail[] = "authorEmail";
+const char kAuthorHref[] = "authorHref";
+const char kHeight[] = "height";
+const char kWidth[] = "width";
+const char kPreferences[] = "preferences";
+
+// Child keys inside 'preferences' key.
+const char kPreferencesName[] = "name";
+const char kPreferencesValue[] = "value";
+const char kPreferencesReadonly[] = "readonly";
+
+typedef std::map<std::string, std::string> KeyMap;
+typedef std::map<std::string, std::string>::const_iterator KeyMapIterator;
+typedef std::pair<std::string, std::string> KeyPair;
+
+const KeyMap& GetWidgetKeyPairs() {
+ static KeyMap map;
+ if (map.empty()) {
+ map.insert(KeyPair(keys::kAuthorKey, kAuthor));
+ map.insert(KeyPair(keys::kDescriptionKey, kDecription));
+ map.insert(KeyPair(keys::kNameKey, kName));
+ map.insert(KeyPair(keys::kShortNameKey, kShortName));
+ map.insert(KeyPair(keys::kVersionKey, kVersion));
+ map.insert(KeyPair(keys::kIDKey, kID));
+ map.insert(KeyPair(keys::kAuthorEmailKey, kAuthorEmail));
+ map.insert(KeyPair(keys::kAuthorHrefKey, kAuthorHref));
+ map.insert(KeyPair(keys::kHeightKey, kHeight));
+ map.insert(KeyPair(keys::kWidthKey, kWidth));
+ }
+
+ return map;
+}
+
+bool ParsePreferenceItem(const utils::DictionaryValue* in_value,
+ utils::DictionaryValue* out_value,
+ std::set<std::string>* used) {
+ assert(in_value && in_value->IsType(utils::Value::TYPE_DICTIONARY));
+
+ std::string pref_name;
+ std::string pref_value;
+ std::string pref_readonly;
+ if (in_value->GetString(keys::kPreferencesNameKey, &pref_name)
+ && used->find(pref_name) == used->end()) {
+ out_value->SetString(kPreferencesName, pref_name);
+ used->insert(pref_name);
+ } else {
+ return false;
+ }
+
+ if (in_value->GetString(keys::kPreferencesValueKey, &pref_value))
+ out_value->SetString(kPreferencesValue, pref_value);
+
+ if (in_value->GetString(keys::kPreferencesReadonlyKey, &pref_readonly))
+ out_value->SetBoolean(kPreferencesReadonly, pref_readonly == "true");
+ return true;
+}
+
+} // namespace
+
+namespace widget_manifest_parser {
+
+WidgetInfo::WidgetInfo()
+ : value_(new utils::DictionaryValue) {}
+
+WidgetInfo::~WidgetInfo() {}
+
+void WidgetInfo::SetString(const std::string& key, const std::string& value) {
+ value_->SetString(key, value);
+}
+
+void WidgetInfo::Set(const std::string& key, utils::Value* value) {
+ value_->Set(key, value);
+}
+
+void WidgetInfo::SetName(const std::string& name) {
+ value_->SetString(kName, name);
+}
+
+void WidgetInfo::SetShortName(const std::string& short_name) {
+ fprintf(stderr, "setting short name: %s\n", short_name.c_str());
+ value_->SetString(kShortName, short_name);
+}
+
+void WidgetInfo::SetDescription(const std::string& description) {
+ value_->SetString(kDecription, description);
+}
+
+WidgetHandler::WidgetHandler() {}
+
+WidgetHandler::~WidgetHandler() {}
+
+bool WidgetHandler::Parse(std::shared_ptr<ApplicationData> application,
+ std::u16string* error) {
+ std::shared_ptr<WidgetInfo> widget_info(new WidgetInfo());
+ const Manifest* manifest = application->GetManifest();
+ assert(manifest);
+
+ const KeyMap& map = GetWidgetKeyPairs();
+
+ for (KeyMapIterator iter = map.begin(); iter != map.end(); ++iter) {
+ std::string string;
+ bool result = manifest->GetString(iter->first, &string);
+ if (result && !string.empty() && iter->first == keys::kAuthorHrefKey)
+ // When authorhref is an invalid URI, reset it an empty string.
+ string.clear();
+ widget_info->SetString(iter->second, result ? string : "");
+ }
+
+ utils::Value* pref_value = nullptr;
+ manifest->Get(keys::kPreferencesKey, &pref_value);
+
+ std::set<std::string> preference_names_used;
+ if (pref_value && pref_value->IsType(utils::Value::TYPE_DICTIONARY)) {
+ utils::DictionaryValue* preferences = new utils::DictionaryValue;
+ utils::DictionaryValue* dict;
+ pref_value->GetAsDictionary(&dict);
+ if (ParsePreferenceItem(dict, preferences, &preference_names_used))
+ widget_info->Set(kPreferences, preferences);
+ } else if (pref_value && pref_value->IsType(utils::Value::TYPE_LIST)) {
+ utils::ListValue* preferences = new utils::ListValue;
+ utils::ListValue* list;
+ pref_value->GetAsList(&list);
+
+ for (utils::ListValue::iterator it = list->begin();
+ it != list->end(); ++it) {
+ utils::DictionaryValue* pref = new utils::DictionaryValue;
+ utils::DictionaryValue* dict;
+ (*it)->GetAsDictionary(&dict);
+ if (ParsePreferenceItem(dict, pref, &preference_names_used))
+ preferences->Append(pref);
+ }
+ widget_info->Set(kPreferences, preferences);
+ }
+
+ application->SetManifestData(keys::kWidgetKey, widget_info);
+ return true;
+}
+
+bool WidgetHandler::Validate(
+ std::shared_ptr<const ApplicationData> application,
+ std::string* error) const {
+ const Manifest* manifest = application->GetManifest();
+ assert(manifest);
+ std::string ns_value;
+ if (!manifest->GetString(keys::kWidgetNamespaceKey, &ns_value)) {
+ *error = "Failed to retrieve the widget's namespace.";
+ return false;
+ }
+ if (strcasecmp(keys::kWidgetNamespacePrefix, ns_value.c_str()) != 0) {
+ *error = "The widget namespace is invalid.";
+ return false;
+ }
+ return true;
+}
+
+bool WidgetHandler::AlwaysParseForType(Manifest::Type type) const {
+ return true;
+}
+
+std::vector<std::string> WidgetHandler::Keys() const {
+ return std::vector<std::string>(1, keys::kWidgetKey);
+}
+
+} // namespace widget_manifest_parser
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#ifndef WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_WIDGET_HANDLER_H_
+#define WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_WIDGET_HANDLER_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "utils/macros.h"
+#include "utils/values.h"
+#include "widget-manifest-parser/application_data.h"
+#include "widget-manifest-parser/manifest_handler.h"
+
+namespace common_installer {
+namespace widget_manifest_parser {
+
+class WidgetInfo : public ApplicationData::ManifestData {
+ public:
+ WidgetInfo();
+ virtual ~WidgetInfo();
+ void SetString(const std::string& key, const std::string& value);
+ void Set(const std::string& key, utils::Value* value);
+
+ // Name, shrot name and description are i18n items, they will be set
+ // if their value were changed after loacle was changed.
+ void SetName(const std::string& name);
+ void SetShortName(const std::string& short_name);
+ void SetDescription(const std::string& description);
+
+ utils::DictionaryValue* GetWidgetInfo() {
+ return value_.get();
+ }
+
+ private:
+ std::unique_ptr<utils::DictionaryValue> value_;
+};
+
+class WidgetHandler : public ManifestHandler {
+ public:
+ WidgetHandler();
+ virtual ~WidgetHandler();
+
+ bool Parse(std::shared_ptr<ApplicationData> application,
+ std::u16string* error) override;
+ bool AlwaysParseForType(Manifest::Type type) const override;
+ std::vector<std::string> Keys() const override;
+
+ bool Validate(std::shared_ptr<const ApplicationData> application,
+ std::string* error) const override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WidgetHandler);
+};
+
+} // namespace widget_manifest_parser
+} // namespace common_installer
+
+#endif // WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_WIDGET_HANDLER_H_
--- /dev/null
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#include "widget-manifest-parser/manifest_util.h"
+
+#include <boost/filesystem/operations.hpp>
+#include <libxml2/libxml/tree.h>
+
+#include <algorithm>
+#include <cassert>
+#include <map>
+#include <vector>
+
+#include "utils/string_util.h"
+#include "utils/utf_converter.h"
+#include "utils/values.h"
+#include "widget-manifest-parser/application_data.h"
+#include "widget-manifest-parser/application_manifest_constants.h"
+#include "widget-manifest-parser/manifest.h"
+#include "widget-manifest-parser/manifest_handler.h"
+
+namespace errors = common_installer::application_manifest_errors;
+namespace keys = common_installer::application_manifest_keys;
+namespace widget_keys = common_installer::application_widget_keys;
+
+namespace bf = boost::filesystem;
+
+namespace {
+const char kAttributePrefix[] = "@";
+const char kNamespaceKey[] = "@namespace";
+const char kTextKey[] = "#text";
+
+const char kContentKey[] = "content";
+
+const xmlChar kWidgetNodeKey[] = "widget";
+const xmlChar kNameNodeKey[] = "name";
+const xmlChar kDescriptionNodeKey[] = "description";
+const xmlChar kAuthorNodeKey[] = "author";
+const xmlChar kLicenseNodeKey[] = "license";
+const xmlChar kIconNodeKey[] = "icon";
+
+const xmlChar kVersionAttributeKey[] = "version";
+const xmlChar kShortAttributeKey[] = "short";
+const xmlChar kDirAttributeKey[] = "dir";
+const xmlChar kEmailAttributeKey[] = "email";
+const xmlChar kHrefAttributeKey[] = "href";
+const xmlChar kIdAttributeKey[] = "id";
+const xmlChar kDefaultLocaleAttributeKey[] = "defaultlocale";
+const xmlChar kPathAttributeKey[] = "path";
+
+const char* kSingletonElements[] = {
+ "allow-navigation",
+ "author",
+ "content-security-policy-report-only",
+ "content-security-policy",
+ "content"
+};
+
+inline char* ToCharPointer(void* ptr) {
+ return reinterpret_cast<char *>(ptr);
+}
+
+inline const char* ToConstCharPointer(const void* ptr) {
+ return reinterpret_cast<const char*>(ptr);
+}
+
+std::u16string ToSting16(const xmlChar* string_ptr) {
+ return common_installer::utils::utf_converter::UTF8ToUTF16(
+ std::string(ToConstCharPointer(string_ptr)));
+}
+
+std::string GetNodeDir(xmlNode* node, const std::string& inherit_dir) {
+ assert(node);
+ std::string dir(inherit_dir);
+
+ xmlAttr* prop = nullptr;
+ for (prop = node->properties; prop; prop = prop->next) {
+ if (xmlStrEqual(prop->name, kDirAttributeKey)) {
+ char* prop_value = ToCharPointer(xmlNodeListGetString(
+ node->doc, prop->children, 1));
+ dir = prop_value;
+ xmlFree(prop_value);
+ break;
+ }
+ }
+ return dir;
+}
+
+std::u16string GetNodeText(xmlNode* root, const std::string& inherit_dir) {
+ assert(root);
+ if (root->type != XML_ELEMENT_NODE)
+ return std::u16string();
+
+ std::string current_dir(GetNodeDir(root, inherit_dir));
+ std::u16string text;
+ for (xmlNode* node = root->children; node; node = node->next) {
+// TODO(jizydorczyk):
+// i18n support is needed
+ if (node->type == XML_TEXT_NODE || node->type == XML_CDATA_SECTION_NODE) {
+ text = text + common_installer::utils::StripWrappingBidiControlCharacters(
+ ToSting16(node->content));
+ } else {
+ text = text + GetNodeText(node, current_dir);
+ }
+ }
+ return common_installer::utils::GetDirText(text, current_dir);
+}
+
+// According to widget specification, this two prop need to support dir.
+// see detail on http://www.w3.org/TR/widgets/#the-dir-attribute
+inline bool IsPropSupportDir(xmlNode* root, xmlAttr* prop) {
+ if (xmlStrEqual(root->name, kWidgetNodeKey)
+ && xmlStrEqual(prop->name, kVersionAttributeKey))
+ return true;
+ if (xmlStrEqual(root->name, kNameNodeKey)
+ && xmlStrEqual(prop->name, kShortAttributeKey))
+ return true;
+ return false;
+}
+
+// Only this four items need to support span and ignore other element.
+// Besides xmlNodeListGetString can not support dir prop of span.
+// See http://www.w3.org/TR/widgets/#the-span-element-and-its-attributes
+inline bool IsElementSupportSpanAndDir(xmlNode* root) {
+ if (xmlStrEqual(root->name, kNameNodeKey)
+ || xmlStrEqual(root->name, kDescriptionNodeKey)
+ || xmlStrEqual(root->name, kAuthorNodeKey)
+ || xmlStrEqual(root->name, kLicenseNodeKey))
+ return true;
+ return false;
+}
+
+bool IsSingletonElement(const std::string& name) {
+ for (const char* str : kSingletonElements)
+ if (name == str)
+ return name != kContentKey;
+ return false;
+}
+
+// According to spec 'name' and 'author' should be result of applying the rule
+// for getting text content with normalized white space to this element.
+// http://www.w3.org/TR/widgets/#rule-for-getting-text-content-with-normalized-white-space-0
+inline bool IsTrimRequiredForElement(xmlNode* root) {
+ if (xmlStrEqual(root->name, kNameNodeKey) ||
+ xmlStrEqual(root->name, kAuthorNodeKey)) {
+ return true;
+ }
+ return false;
+}
+
+// According to spec some attributes requaire applying the rule for getting
+// a single attribute value.
+// http://www.w3.org/TR/widgets/#rule-for-getting-a-single-attribute-value-0
+inline bool IsTrimRequiredForProp(xmlNode* root, xmlAttr* prop) {
+ if (xmlStrEqual(root->name, kWidgetNodeKey) &&
+ (xmlStrEqual(prop->name, kIdAttributeKey) ||
+ xmlStrEqual(prop->name, kVersionAttributeKey) ||
+ xmlStrEqual(prop->name, kDefaultLocaleAttributeKey))) {
+ return true;
+ }
+ if (xmlStrEqual(root->name, kNameNodeKey) &&
+ xmlStrEqual(prop->name, kShortAttributeKey)) {
+ return true;
+ }
+ if (xmlStrEqual(root->name, kAuthorNodeKey) &&
+ (xmlStrEqual(prop->name, kEmailAttributeKey) ||
+ xmlStrEqual(prop->name, kHrefAttributeKey))) {
+ return true;
+ }
+ if (xmlStrEqual(root->name, kLicenseNodeKey) &&
+ xmlStrEqual(prop->name, kHrefAttributeKey)) {
+ return true;
+ }
+ if (xmlStrEqual(root->name, kIconNodeKey) &&
+ xmlStrEqual(prop->name, kPathAttributeKey)) {
+ return true;
+ }
+ return false;
+}
+
+} // namespace
+
+namespace common_installer {
+namespace widget_manifest_parser {
+
+namespace {
+
+// Load XML node into Dictionary structure.
+// The keys for the XML node to Dictionary mapping are described below:
+// XML Dictionary
+// <e></e> "e":{"#text": ""}
+// <e>textA</e> "e":{"#text":"textA"}
+// <e attr="val">textA</e> "e":{ "@attr":"val", "#text": "textA"}
+// <e> <a>textA</a> <b>textB</b> </e> "e":{
+// "a":{"#text":"textA"}
+// "b":{"#text":"textB"}
+// }
+// <e> <a>textX</a> <a>textY</a> </e> "e":{
+// "a":[ {"#text":"textX"},
+// {"#text":"textY"}]
+// }
+// <e> textX <a>textY</a> </e> "e":{ "#text":"textX",
+// "a":{"#text":"textY"}
+// }
+//
+// For elements that are specified under a namespace, the dictionary
+// will add '@namespace' key for them, e.g.,
+// XML:
+// <e xmln="linkA" xmlns:N="LinkB">
+// <sub-e1> text1 </sub-e>
+// <N:sub-e2 text2 />
+// </e>
+// will be saved in Dictionary as,
+// "e":{
+// "#text": "",
+// "@namespace": "linkA"
+// "sub-e1": {
+// "#text": "text1",
+// "@namespace": "linkA"
+// },
+// "sub-e2": {
+// "#text":"text2"
+// "@namespace": "linkB"
+// }
+// }
+
+// converting dictionaryvalue to std::map<
+// std::u16string*, std::map<std::u16string*,std::u16string*>> or
+// std::map<std::u16string*, std::map<std::u16string*,std::u16string>>
+
+std::unique_ptr<utils::DictionaryValue> LoadXMLNode(
+ xmlNode* root, const std::string& inherit_dir = "") {
+ std::unique_ptr<utils::DictionaryValue> value(new utils::DictionaryValue());
+ if (root->type != XML_ELEMENT_NODE)
+ return nullptr;
+
+ std::string current_dir(GetNodeDir(root, inherit_dir));
+
+ xmlAttr* prop = nullptr;
+ for (prop = root->properties; prop; prop = prop->next) {
+ xmlChar* value_ptr = xmlNodeListGetString(root->doc, prop->children, 1);
+ std::u16string prop_value(ToSting16(value_ptr));
+ xmlFree(value_ptr);
+
+ if (IsPropSupportDir(root, prop))
+ prop_value = utils::GetDirText(prop_value, current_dir);
+
+ if (IsTrimRequiredForProp(root, prop))
+ prop_value = utils::CollapseWhitespace(prop_value, false);
+
+ value->SetString(
+ std::string(kAttributePrefix) + ToConstCharPointer(prop->name),
+ prop_value);
+ }
+
+ if (root->ns)
+ value->SetString(kNamespaceKey, ToConstCharPointer(root->ns->href));
+
+ for (xmlNode* node = root->children; node; node = node->next) {
+ std::string sub_node_name(ToConstCharPointer(node->name));
+ std::unique_ptr<utils::DictionaryValue> sub_value =
+ LoadXMLNode(node, current_dir);
+ if (!sub_value)
+ continue;
+
+ if (!value->HasKey(sub_node_name)) {
+ value->Set(sub_node_name, sub_value.release());
+ continue;
+ } else if (IsSingletonElement(sub_node_name)) {
+ continue;
+ } else if (sub_node_name == kContentKey) {
+ std::string current_namespace, new_namespace;
+ utils::DictionaryValue* current_value;
+ value->GetDictionary(sub_node_name, ¤t_value);
+
+ current_value->GetString(kNamespaceKey, ¤t_namespace);
+ sub_value->GetString(kNamespaceKey, &new_namespace);
+ if (current_namespace != new_namespace &&
+ new_namespace == widget_keys::kTizenNamespacePrefix)
+ value->Set(sub_node_name, sub_value.release());
+ continue;
+ }
+
+ utils::Value* temp;
+ value->Get(sub_node_name, &temp);
+ assert(temp);
+
+ if (temp->IsType(utils::Value::TYPE_LIST)) {
+ utils::ListValue* list;
+ temp->GetAsList(&list);
+ list->Append(sub_value.release());
+ } else {
+ assert(temp->IsType(utils::Value::TYPE_DICTIONARY));
+ utils::DictionaryValue* dict;
+ temp->GetAsDictionary(&dict);
+ utils::DictionaryValue* prev_value = dict->DeepCopy();
+
+ utils::ListValue* list = new utils::ListValue();
+ list->Append(prev_value);
+ list->Append(sub_value.release());
+ value->Set(sub_node_name, list);
+ }
+ }
+
+ std::u16string text;
+ if (IsElementSupportSpanAndDir(root)) {
+ text = GetNodeText(root, current_dir);
+ } else {
+ xmlChar* text_ptr = xmlNodeListGetString(root->doc, root->children, 1);
+ if (text_ptr) {
+ text = ToSting16(text_ptr);
+ xmlFree(text_ptr);
+ }
+ }
+
+ if (IsTrimRequiredForElement(root))
+ text = utils::CollapseWhitespace(text, false);
+
+ if (!text.empty())
+ value->SetString(kTextKey, text);
+
+ return value;
+}
+
+} // namespace
+
+std::unique_ptr<Manifest> LoadManifest(const std::string& manifest_path,
+ Manifest::Type type, std::string* error) {
+ xmlDoc * doc = nullptr;
+ xmlNode* root_node = nullptr;
+ doc = xmlReadFile(manifest_path.c_str(), nullptr, 0);
+ if (!doc) {
+ *error = errors::kManifestUnreadable;
+ return nullptr;
+ }
+ root_node = xmlDocGetRootElement(doc);
+ std::unique_ptr<utils::DictionaryValue> dv = LoadXMLNode(root_node);
+ std::unique_ptr<utils::DictionaryValue> result(new utils::DictionaryValue);
+ if (dv)
+ result->Set(ToConstCharPointer(root_node->name), dv.release());
+
+ return std::unique_ptr<Manifest>(
+ new Manifest(std::move(result), Manifest::TYPE_WIDGET));
+}
+
+bf::path ApplicationURLToRelativeFilePath(const std::string& url) {
+ std::string url_path = url;
+ if (url_path.empty() || url_path[0] != '/')
+ return bf::path();
+
+ // TODO(jizydorczyk):
+ // We need to unescappe %-encoded UTF8 chars here
+ // for now its left undone
+ // Drop the leading slashes and convert %-encoded UTF8 to regular UTF8.
+// std::string file_path = net::UnescapeURLComponent(url_path,
+// net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS);
+// size_t skip = file_path.find_first_not_of("/\\");
+// if (skip != file_path.npos)
+// file_path = file_path.substr(skip);
+
+ std::string file_path = url_path;
+ bf::path path(file_path);
+
+ // It's still possible for someone to construct an annoying URL whose path
+ // would still wind up not being considered relative at this point.
+ // For example: app://id/c:////foo.html
+ if (path.is_absolute())
+ return bf::path();
+
+ return path;
+}
+
+} // namespace widget_manifest_parser
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#ifndef WIDGET_MANIFEST_PARSER_MANIFEST_UTIL_H_
+#define WIDGET_MANIFEST_PARSER_MANIFEST_UTIL_H_
+
+#include <boost/filesystem/path.hpp>
+
+#include <string>
+#include <map>
+#include <memory>
+
+#include "widget-manifest-parser/application_data.h"
+
+// Utilities for manipulating the on-disk storage of applications.
+namespace common_installer {
+namespace widget_manifest_parser {
+
+// Loads an application manifest from the specified directory. Returns NULL
+// on failure, with a description of the error in |error|.
+std::unique_ptr<Manifest> LoadManifest(
+ const std::string& file_path, Manifest::Type type, std::string* error);
+
+} // namespace widget_manifest_parser
+} // namespace common_installer
+
+#endif // WIDGET_MANIFEST_PARSER_MANIFEST_UTIL_H_
--- /dev/null
+// Copyright (c) 2013 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#ifndef WIDGET_MANIFEST_PARSER_PERMISSION_TYPES_H_
+#define WIDGET_MANIFEST_PARSER_PERMISSION_TYPES_H_
+
+#include <map>
+#include <set>
+#include <string>
+
+namespace common_installer {
+namespace widget_manifest_parser {
+
+enum PermissionType {
+ SESSION_PERMISSION,
+ PERSISTENT_PERMISSION,
+};
+
+enum RuntimePermission {
+ ALLOW_ONCE = 0,
+ ALLOW_SESSION,
+ ALLOW_ALWAYS,
+ DENY_ONCE,
+ DENY_SESSION,
+ DENY_ALWAYS,
+ UNDEFINED_RUNTIME_PERM,
+};
+
+enum StoredPermission {
+ ALLOW = 0,
+ DENY,
+ PROMPT,
+ UNDEFINED_STORED_PERM,
+};
+
+typedef std::map<std::string, StoredPermission> StoredPermissionMap;
+typedef std::set<std::string> PermissionSet;
+
+} // namespace widget_manifest_parser
+} // namespace common_installer
+
+#endif // WIDGET_MANIFEST_PARSER_PERMISSION_TYPES_H_
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#include "widget-manifest-parser/widget_manifest_parser.h"
+
+#include <boost/filesystem/path.hpp>
+
+#include <algorithm>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "utils/macros.h"
+#include "utils/values.h"
+
+#include "widget-manifest-parser/application_data.h"
+#include "widget-manifest-parser/application_manifest_constants.h"
+#include "widget-manifest-parser/manifest_util.h"
+#include "widget-manifest-parser/manifest_handlers/permissions_handler.h"
+#include "widget-manifest-parser/manifest_handlers/tizen_application_handler.h"
+#include "widget-manifest-parser/manifest_handlers/widget_handler.h"
+#include "widget-manifest-parser/permission_types.h"
+
+#define API_EXPORT __attribute__((visibility("default")))
+
+namespace bf = boost::filesystem;
+namespace keys = common_installer::application_widget_keys;
+
+namespace {
+
+const char kErrMsgNoPath[] =
+ "Path not specified.";
+const char kErrMsgInvalidPath[] =
+ "Invalid path.";
+const char kErrMsgValueNotFound[] =
+ "Value not found. Value name: ";
+const char kErrMsgInvalidDictionary[] =
+ "Cannot get key value as a dictionary. Key name: ";
+const char kErrMsgInvalidList[] =
+ "Cannot get key value as a list. Key name: ";
+const char kErrMsgNoMandatoryKey[] =
+ "Cannot find mandatory key. Key name: ";
+
+const char kName[] = "name";
+const char kShortName[] = "shortName";
+const char kVersion[] = "version";
+const char kWidgetPrivilegeFullKey[] = "widget.privilege";
+const char kWidgetPrivilegeNameKey[] = "@name";
+const char kWidgetIconFullKey[] = "widget.icon";
+const char kWidgetIconSrcKey[] = "@src";
+
+class LocalManifestData {
+ public:
+ LocalManifestData() {
+ data_.package = package_.c_str();
+ data_.id = id_.c_str();
+ data_.name = name_.c_str();
+ data_.short_name = short_name_.c_str();
+ data_.version = version_.c_str();
+ data_.icon = icon_.c_str();
+ data_.api_version = api_version_.c_str();
+ data_.privilege_count = privilege_list_.size();
+ data_.privilege_list = privilege_list_.data();
+ }
+
+ void SetPackage(const std::string& value) {
+ package_ = value;
+ data_.package = package_.c_str();
+ }
+
+ void SetId(const std::string& value) {
+ id_ = value;
+ data_.id = id_.c_str();
+ }
+
+ void SetName(const std::string& value) {
+ name_ = value;
+ data_.name = name_.c_str();
+ }
+
+ void SetShortName(const std::string& value) {
+ short_name_ = value;
+ data_.short_name = short_name_.c_str();
+ }
+
+ void SetVersion(const std::string& value) {
+ version_ = value;
+ data_.version = version_.c_str();
+ }
+
+ void SetIcon(const std::string& value) {
+ icon_ = value;
+ data_.icon = icon_.c_str();
+ }
+
+ void SetApiVersion(const std::string& value) {
+ api_version_ = value;
+ data_.api_version = api_version_.c_str();
+ }
+
+ void SetPrivileges(const std::set<std::string>& value) {
+ std::copy(value.begin(), value.end(), std::back_inserter(privileges_));
+ privilege_list_.clear();
+ for (const std::string& p : privileges_)
+ privilege_list_.push_back(p.c_str());
+ data_.privilege_count = privilege_list_.size();
+ data_.privilege_list = privilege_list_.data();
+ }
+
+ const ManifestData* GetManifestData() const {
+ return &data_;
+ }
+
+ private:
+ std::string package_;
+ std::string id_;
+ std::string name_;
+ std::string short_name_;
+ std::string version_;
+ std::string icon_;
+ std::string api_version_;
+ std::vector<std::string> privileges_;
+ std::vector<const char*> privilege_list_;
+ ManifestData data_;
+
+ DISALLOW_COPY_AND_ASSIGN(LocalManifestData);
+};
+
+typedef std::string LocalError;
+
+class LocalStorage {
+ public:
+ static LocalStorage* GetInstance() {
+ static LocalStorage instance;
+ return &instance;
+ }
+
+ const ManifestData* Add(std::shared_ptr<LocalManifestData> data) {
+ const ManifestData* result = data->GetManifestData();
+ data_vector_.push_back(data);
+ return result;
+ }
+
+ bool Remove(const ManifestData* data) {
+ LocalManifestDataVector::iterator it;
+ for (it = data_vector_.begin(); it != data_vector_.end(); ++it)
+ if ((*it)->GetManifestData() == data) {
+ data_vector_.erase(it);
+ return true;
+ }
+ return false;
+ }
+
+ const char* Add(LocalError* error) {
+ const char* result = error->c_str();
+ error_vector_.push_back(std::shared_ptr<LocalError>(error));
+ return result;
+ }
+
+ bool Remove(const char* error) {
+ ErrorVector::iterator it;
+ for (it = error_vector_.begin(); it != error_vector_.end(); ++it)
+ if ((*it)->c_str() == error) {
+ error_vector_.erase(it);
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ typedef std::vector<std::shared_ptr<LocalManifestData>>
+ LocalManifestDataVector;
+ typedef std::vector<std::shared_ptr<LocalError>> ErrorVector;
+
+ LocalManifestDataVector data_vector_;
+ ErrorVector error_vector_;
+
+ LocalStorage() { }
+
+ DISALLOW_COPY_AND_ASSIGN(LocalStorage);
+};
+
+void SetError(const std::string& message, const char** error) {
+ if (error)
+ *error = LocalStorage::GetInstance()->Add(new std::string(message));
+}
+
+void SetError(const std::string& message, const std::string& arg,
+ const char** error) {
+ if (error)
+ *error = LocalStorage::GetInstance()->Add(new std::string(message + arg));
+}
+
+bool ExtractPackage(
+ const common_installer::widget_manifest_parser::ApplicationData& app_data,
+ std::string* value) {
+ common_installer::widget_manifest_parser::TizenApplicationInfo* info =
+ static_cast<
+ common_installer::widget_manifest_parser::TizenApplicationInfo*>(
+ app_data.GetManifestData(keys::kTizenApplicationKey));
+ if (!info)
+ return false;
+ *value = info->package();
+ return true;
+}
+
+bool ExtractId(
+ const common_installer::widget_manifest_parser::ApplicationData& app_data,
+ std::string* value) {
+ common_installer::widget_manifest_parser::TizenApplicationInfo* info =
+ static_cast<
+ common_installer::widget_manifest_parser::TizenApplicationInfo*>(
+ app_data.GetManifestData(keys::kTizenApplicationKey));
+ if (!info)
+ return false;
+ *value = info->id();
+ return true;
+}
+
+bool ExtractName(
+ const common_installer::widget_manifest_parser::ApplicationData& app_data,
+ std::string* value) {
+ common_installer::widget_manifest_parser::WidgetInfo* info =
+ static_cast<common_installer::widget_manifest_parser::WidgetInfo*>(
+ app_data.GetManifestData(keys::kWidgetKey));
+ if (!info)
+ return false;
+
+ return info->GetWidgetInfo()->GetString(kName, value);
+}
+
+bool ExtractShortName(
+ const common_installer::widget_manifest_parser::ApplicationData& app_data,
+ std::string* value) {
+ common_installer::widget_manifest_parser::WidgetInfo* info =
+ static_cast<common_installer::widget_manifest_parser::WidgetInfo*>(
+ app_data.GetManifestData(keys::kWidgetKey));
+ if (!info)
+ return false;
+ return info->GetWidgetInfo()->GetString(kShortName, value);
+}
+
+bool ExtractVersion(
+ const common_installer::widget_manifest_parser::ApplicationData& app_data,
+ std::string* value) {
+ common_installer::widget_manifest_parser::WidgetInfo* info =
+ static_cast<common_installer::widget_manifest_parser::WidgetInfo*>(
+ app_data.GetManifestData(keys::kWidgetKey));
+ if (!info)
+ return false;
+ return info->GetWidgetInfo()->GetString(kVersion, value);
+}
+
+bool ExtractIconSrc(const common_installer::utils::Value& dict,
+ std::string* value, const char** error) {
+ const common_installer::utils::DictionaryValue* inner_dict;
+ if (!dict.GetAsDictionary(&inner_dict)) {
+ SetError(kErrMsgInvalidDictionary, kWidgetIconFullKey, error);
+ return false;
+ }
+ std::string src;
+ if (!inner_dict->GetString(kWidgetIconSrcKey, &src)) {
+ SetError(kErrMsgNoMandatoryKey, kWidgetIconSrcKey, error);
+ return false;
+ }
+ *value = src;
+ return true;
+}
+
+bool ExtractIcons(
+ const common_installer::widget_manifest_parser::Manifest& manifest,
+ std::vector<std::string>* value, const char** error) {
+ common_installer::utils::Value* key_value;
+ if (!manifest.Get(kWidgetIconFullKey, &key_value)) {
+ value->clear();
+ return true; // no icon, no error
+ }
+
+ std::vector<std::string> icons;
+ if (key_value->IsType(common_installer::utils::Value::TYPE_DICTIONARY)) {
+ std::string icon;
+ if (!ExtractIconSrc(*key_value, &icon, error))
+ return false;
+ icons.push_back(icon);
+ } else if (key_value->IsType(common_installer::utils::Value::TYPE_LIST)) {
+ const common_installer::utils::ListValue* list;
+ if (!key_value->GetAsList(&list)) {
+ SetError(kErrMsgInvalidList, kWidgetIconFullKey, error);
+ return false;
+ }
+ for (const common_installer::utils::Value* list_value : *list) {
+ std::string icon;
+ if (!ExtractIconSrc(*list_value, &icon, error))
+ return false;
+ icons.push_back(icon);
+ }
+ }
+
+ value->swap(icons);
+ return true;
+}
+
+bool ExtractApiVersion(
+ const common_installer::widget_manifest_parser::ApplicationData& app_data,
+ std::string* value) {
+ common_installer::widget_manifest_parser::TizenApplicationInfo* info =
+ static_cast<
+ common_installer::widget_manifest_parser::TizenApplicationInfo*>(
+ app_data.GetManifestData(keys::kTizenApplicationKey));
+ if (!info)
+ return false;
+ *value = info->required_version();
+ return true;
+}
+
+bool ExtractPrivileges(
+ const common_installer::widget_manifest_parser::ApplicationData& app_data,
+ std::set<std::string>* value, const char** error) {
+ const common_installer::widget_manifest_parser::PermissionsInfo* perm_info =
+ static_cast<common_installer::widget_manifest_parser::PermissionsInfo*>(
+ app_data.GetManifestData(keys::kTizenPermissionsKey));
+ common_installer::widget_manifest_parser::PermissionSet permissions =
+ perm_info->GetAPIPermissions();
+ *value = permissions;
+ return true;
+}
+
+} // namespace
+
+extern "C" {
+
+API_EXPORT bool ParseManifest(const char* path,
+ const ManifestData** data, const char** error) {
+ if (!path) {
+ SetError(kErrMsgNoPath, error);
+ return false;
+ }
+ std::string str_path = path;
+ if (str_path.empty()) {
+ SetError(kErrMsgInvalidPath, error);
+ return false;
+ }
+
+ std::string local_error;
+
+ std::unique_ptr<common_installer::widget_manifest_parser::Manifest> manifest =
+ common_installer::widget_manifest_parser::LoadManifest(
+ path, common_installer::widget_manifest_parser::Manifest::TYPE_WIDGET,
+ &local_error);
+ if (!manifest) {
+ SetError(local_error, error);
+ return false;
+ }
+
+ std::shared_ptr<common_installer::widget_manifest_parser::ApplicationData>
+ app_data =
+ common_installer::widget_manifest_parser::ApplicationData::Create(
+ bf::path(), std::string(),
+ common_installer::widget_manifest_parser::ApplicationData::INTERNAL,
+ std::move(manifest), &local_error);
+ if (!app_data.get()) {
+ SetError(local_error, error);
+ return false;
+ }
+
+ std::string package;
+ if (!ExtractPackage(*app_data, &package)) {
+ SetError(kErrMsgValueNotFound, "package id", error);
+ return false;
+ }
+
+ std::string id;
+ if (!ExtractId(*app_data, &id)) {
+ SetError(kErrMsgValueNotFound, "application id", error);
+ return false;
+ }
+
+ std::string name;
+ if (!ExtractName(*app_data, &name)) {
+ SetError(kErrMsgValueNotFound, "application name", error);
+ return false;
+ }
+
+ std::string short_name;
+ if (!ExtractShortName(*app_data, &short_name)) {
+ SetError(kErrMsgValueNotFound, "application short name", error);
+ return false;
+ }
+
+ std::string version;
+ if (!ExtractVersion(*app_data, &version)) {
+ SetError(kErrMsgValueNotFound, "application version", error);
+ return false;
+ }
+
+ std::vector<std::string> icons;
+ if (!ExtractIcons(*app_data->GetManifest(), &icons, error))
+ return false;
+
+ std::string api_version;
+ if (!ExtractApiVersion(*app_data, &api_version)) {
+ SetError(kErrMsgValueNotFound, "required api version", error);
+ return false;
+ }
+
+ std::set<std::string> privileges;
+ if (!ExtractPrivileges(*app_data, &privileges, error))
+ return false;
+
+ if (data) {
+ std::shared_ptr<LocalManifestData> local_manifest_data(
+ new LocalManifestData);
+ local_manifest_data->SetPackage(package);
+ local_manifest_data->SetId(id);
+ local_manifest_data->SetName(name);
+ local_manifest_data->SetShortName(short_name);
+ local_manifest_data->SetVersion(version);
+ local_manifest_data->SetIcon(icons.empty() ? "" : icons.front());
+ local_manifest_data->SetApiVersion(api_version);
+ local_manifest_data->SetPrivileges(privileges);
+ *data = LocalStorage::GetInstance()->Add(local_manifest_data);
+ }
+
+ return true;
+}
+
+API_EXPORT bool ReleaseData(const ManifestData* data, const char* error) {
+ bool result = true;
+ if (data)
+ result = result && LocalStorage::GetInstance()->Remove(data);
+ if (error)
+ result = result && LocalStorage::GetInstance()->Remove(error);
+ return result;
+}
+
+} // extern "C"
--- /dev/null
+// Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#ifndef WIDGET_MANIFEST_PARSER_WIDGET_MANIFEST_PARSER_H_
+#define WIDGET_MANIFEST_PARSER_WIDGET_MANIFEST_PARSER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Represents a manifest data
+struct ManifestData {
+ const char* package;
+ const char* id;
+ const char* name;
+ const char* short_name;
+ const char* version;
+ const char* icon;
+ const char* api_version;
+ unsigned int privilege_count;
+ const char** privilege_list;
+};
+
+// Reads manifest from specified file and filles specified data argument
+// with read data. Returns true on success or false otherwise. If the error
+// parameter is specified, it is also filled with proper message.
+bool ParseManifest(const char* path,
+ const ManifestData** data, const char** error);
+
+// Releses the data and the error returned by ParseManifest.
+// Returns true on success or false otherwise.
+bool ReleaseData(const ManifestData* data, const char* error);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // WIDGET_MANIFEST_PARSER_WIDGET_MANIFEST_PARSER_H_