#include "xwalk/application/common/manifest_handler.h"
#include "xwalk/application/common/manifest_handlers/permissions_handler.h"
#include "xwalk/application/common/manifest_handlers/widget_handler.h"
+#include "xwalk/application/common/manifest_handlers/tizen_application_handler.h"
#include "xwalk/application/common/permission_policy_manager.h"
#include "content/public/common/url_constants.h"
#include "url/url_util.h"
// static
scoped_refptr<ApplicationData> ApplicationData::Create(
- const base::FilePath& path,
- Manifest::SourceType source_type,
- const base::DictionaryValue& manifest_data,
- const std::string& explicit_id,
+ const base::FilePath& path, const std::string& explicit_id,
+ SourceType source_type, scoped_ptr<Manifest> manifest,
std::string* error_message) {
DCHECK(error_message);
base::string16 error;
- scoped_ptr<xwalk::application::Manifest> manifest(
- new xwalk::application::Manifest(source_type,
- scoped_ptr<base::DictionaryValue>(manifest_data.DeepCopy())));
-
- if (!InitApplicationID(manifest.get(), path, explicit_id, &error)) {
- *error_message = base::UTF16ToUTF8(error);
- return NULL;
- }
-
- std::vector<InstallWarning> install_warnings;
- if (!manifest->ValidateManifest(error_message, &install_warnings)) {
+ if (!manifest->ValidateManifest(error_message))
return NULL;
- }
- scoped_refptr<ApplicationData> application = new ApplicationData(path,
- manifest.Pass());
- application->install_warnings_.swap(install_warnings);
-
- if (!application->Init(&error)) {
+ scoped_refptr<ApplicationData> app_data =
+ new ApplicationData(path, source_type, manifest.Pass());
+ if (!app_data->Init(explicit_id, &error)) {
*error_message = base::UTF16ToUTF8(error);
return NULL;
}
- return application;
-}
-
-// static
-bool ApplicationData::IsIDValid(const std::string& id) {
- std::string temp = StringToLowerASCII(id);
-
-#if defined(OS_TIZEN)
- // An ID with 10 characters is most likely a legacy Tizen ID.
- if (temp.size() == kLegacyTizenIdSize) {
- for (size_t i = 0; i < kLegacyTizenIdSize; ++i) {
- const char c = temp[i];
- const bool valid = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z');
- if (!valid)
- return false;
- }
-
- return true;
- }
-#endif
-
- // Verify that the id is legal.
- if (temp.size() != (kIdSize * 2))
- return false;
+ ManifestHandlerRegistry* registry =
+ ManifestHandlerRegistry::GetInstance(app_data->manifest_type());
- // We only support lowercase IDs, because IDs can be used as URL components
- // (where GURL will lowercase it).
- for (size_t i = 0; i < temp.size(); ++i)
- if (temp[i] < 'a' || temp[i] > 'p')
- return false;
+ if (!registry->ValidateAppManifest(app_data, error_message))
+ return NULL;
- return true;
+ return app_data;
}
// static
GURL ApplicationData::GetBaseURLFromApplicationId(
const std::string& application_id) {
- return GURL(std::string(xwalk::application::kApplicationScheme) +
- content::kStandardSchemeSeparator + application_id + "/");
+ return GURL(std::string(kApplicationScheme) +
+ url::kStandardSchemeSeparator + application_id + "/");
}
ApplicationData::ManifestData* ApplicationData::GetManifestData(
manifest_data_[key] = linked_ptr<ManifestData>(data);
}
-Manifest::SourceType ApplicationData::GetSourceType() const {
- return manifest_->GetSourceType();
-}
-
-const std::string& ApplicationData::ID() const {
- return manifest_->GetApplicationID();
+#if defined(OS_TIZEN)
+std::string ApplicationData::GetPackageID() const {
+ return AppIdToPkgId(application_id_);
}
+#endif
const std::string ApplicationData::VersionString() const {
if (!version_->components().empty())
return "";
}
-bool ApplicationData::IsPlatformApp() const {
- return manifest_->IsPackaged();
-}
-
bool ApplicationData::IsHostedApp() const {
- return GetManifest()->IsHosted();
-}
-
-// static
-bool ApplicationData::InitApplicationID(xwalk::application::Manifest* manifest,
- const base::FilePath& path,
- const std::string& explicit_id,
- base::string16* error) {
- std::string application_id;
+ bool hosted = source_type_ == EXTERNAL_URL;
#if defined(OS_TIZEN)
- if (manifest->HasKey(keys::kTizenAppIdKey)) {
- if (!manifest->GetString(keys::kTizenAppIdKey, &application_id)) {
- NOTREACHED() << "Could not get Tizen application key";
- return false;
- }
- }
-
- if (!application_id.empty()) {
- manifest->SetApplicationID(application_id);
- return true;
+ if (manifest_->HasPath(widget_keys::kContentNamespace)) {
+ std::string ns;
+ if (manifest_->GetString(widget_keys::kContentNamespace, &ns) &&
+ ns == widget_keys::kTizenNamespacePrefix)
+ hosted = true;
}
#endif
-
- if (!explicit_id.empty()) {
- manifest->SetApplicationID(explicit_id);
- return true;
- }
-
- application_id = GenerateIdForPath(path);
- if (application_id.empty()) {
- NOTREACHED() << "Could not create ID from path.";
- return false;
- }
- manifest->SetApplicationID(application_id);
- return true;
+ return hosted;
}
ApplicationData::ApplicationData(const base::FilePath& path,
- scoped_ptr<xwalk::application::Manifest> manifest)
+ SourceType source_type, scoped_ptr<Manifest> manifest)
: manifest_version_(0),
+ path_(path),
manifest_(manifest.release()),
- finished_parsing_manifest_(false) {
- DCHECK(path.empty() || path.IsAbsolute());
- path_ = path;
- if (manifest_->HasPath(widget_keys::kWidgetKey))
- package_type_ = Package::WGT;
- else
- package_type_ = Package::XPK;
+ finished_parsing_manifest_(false),
+ source_type_(source_type) {
+ DCHECK(path_.empty() || path_.IsAbsolute());
}
ApplicationData::~ApplicationData() {
// static
GURL ApplicationData::GetResourceURL(const GURL& application_url,
const std::string& relative_path) {
- DCHECK(application_url.SchemeIs(xwalk::application::kApplicationScheme));
+ DCHECK(application_url.SchemeIs(kApplicationScheme));
DCHECK_EQ("/", application_url.path());
std::string path = relative_path;
return ret_val;
}
-Manifest::Type ApplicationData::GetType() const {
- return manifest_->GetType();
+GURL ApplicationData::GetResourceURL(const std::string& relative_path) const {
+#if defined (OS_WIN)
+ if (!base::PathExists(path_.Append(base::UTF8ToWide(relative_path)))) {
+#else
+ if (!base::PathExists(path_.Append(relative_path))) {
+#endif
+ LOG(ERROR) << "The path does not exist in the application directory: "
+ << relative_path;
+ return GURL();
+ }
+
+ return GetResourceURL(URL(), relative_path);
}
-bool ApplicationData::Init(base::string16* error) {
+bool ApplicationData::Init(const std::string& explicit_id,
+ base::string16* error) {
DCHECK(error);
+ ManifestHandlerRegistry* registry =
+ ManifestHandlerRegistry::GetInstance(manifest_type());
+ if (!registry->ParseAppManifest(this, error))
+ return false;
+ if (!LoadID(explicit_id, error))
+ return false;
if (!LoadName(error))
return false;
if (!LoadVersion(error))
- return false;
+ return false;
if (!LoadDescription(error))
- return false;
- if (!LoadManifestVersion(error))
return false;
application_url_ = ApplicationData::GetBaseURLFromApplicationId(ID());
- ManifestHandlerRegistry* registry =
- ManifestHandlerRegistry::GetInstance(GetPackageType());
- if (!registry->ParseAppManifest(this, error))
- return false;
-
finished_parsing_manifest_ = true;
return true;
}
+bool ApplicationData::LoadID(const std::string& explicit_id,
+ base::string16* error) {
+ std::string application_id;
+#if defined(OS_TIZEN)
+ if (manifest_type() == Manifest::TYPE_WIDGET) {
+ const TizenApplicationInfo* tizen_app_info =
+ static_cast<TizenApplicationInfo*>(GetManifestData(
+ widget_keys::kTizenApplicationKey));
+ CHECK(tizen_app_info);
+ application_id = tizen_app_info->id();
+ } else if (manifest_->HasKey(keys::kTizenAppIdKey)) {
+ if (!manifest_->GetString(keys::kTizenAppIdKey, &application_id)) {
+ NOTREACHED() << "Could not get Tizen application key";
+ return false;
+ }
+ }
+
+ if (!application_id.empty()) {
+ application_id_ = application_id;
+ return true;
+ }
+#endif
+
+ if (!explicit_id.empty()) {
+ application_id_ = explicit_id;
+ return true;
+ }
+
+ application_id = GenerateIdForPath(path_);
+ if (application_id.empty()) {
+ NOTREACHED() << "Could not create ID from path.";
+ return false;
+ }
+ application_id_ = application_id;
+ return true;
+}
+
bool ApplicationData::LoadName(base::string16* error) {
DCHECK(error);
base::string16 localized_name;
- std::string name_key(GetNameKey(GetPackageType()));
+ std::string name_key(GetNameKey(manifest_type()));
if (!manifest_->GetString(name_key, &localized_name) &&
- package_type_ == Package::XPK) {
+ manifest_type() == Manifest::TYPE_MANIFEST) {
*error = base::ASCIIToUTF16(errors::kInvalidName);
return false;
}
bool ApplicationData::LoadVersion(base::string16* error) {
DCHECK(error);
std::string version_str;
- std::string version_key(GetVersionKey(GetPackageType()));
- if (!manifest_->GetString(version_key, &version_str) &&
- package_type_ == Package::XPK) {
- *error = base::ASCIIToUTF16(errors::kInvalidVersion);
- return false;
+ version_.reset(new base::Version());
+
+ if (manifest_type() == Manifest::TYPE_WIDGET) {
+ bool ok = manifest_->GetString(widget_keys::kVersionKey, &version_str);
+ if (!ok) {
+ *error = base::ASCIIToUTF16(errors::kInvalidVersion);
+ return true;
+ }
+
+ version_.reset(new base::Version(version_str));
+ return true;
+ }
+
+ // W3C Manifest (XPK and hosted):
+
+ bool hasDeprecatedKey = manifest_->HasKey(keys::kDeprecatedVersionKey);
+ bool hasKey = manifest_->HasKey(keys::kXWalkVersionKey);
+
+ if (!hasKey && !hasDeprecatedKey) {
+ // xwalk_version is optional.
+ return true;
+ }
+
+ bool ok = false;
+ if (hasKey) {
+ if (hasDeprecatedKey) {
+ LOG(WARNING) << "Deprecated key '" << keys::kDeprecatedVersionKey
+ << "' found in addition to '" << keys::kXWalkVersionKey
+ << "'. Consider removing.";
+ }
+ ok = manifest_->GetString(keys::kXWalkVersionKey, &version_str);
+ }
+
+ if (!hasKey && hasDeprecatedKey) {
+ LOG(WARNING) << "Deprecated key '" << keys::kDeprecatedVersionKey
+ << "' found. Please migrate to using '" << keys::kXWalkVersionKey
+ << "' instead.";
+ ok = manifest_->GetString(keys::kDeprecatedVersionKey, &version_str);
}
+
version_.reset(new base::Version(version_str));
- if (package_type_ == Package::XPK &&
- (!version_->IsValid() || version_->components().size() > 4)) {
+
+ if (!ok || !version_->IsValid() || version_->components().size() > 4) {
*error = base::ASCIIToUTF16(errors::kInvalidVersion);
+ version_.reset(new base::Version());
return false;
}
- return true;
+
+ return ok;
}
bool ApplicationData::LoadDescription(base::string16* error) {
DCHECK(error);
- if (manifest_->HasKey(keys::kDescriptionKey) &&
- !manifest_->GetString(keys::kDescriptionKey, &description_) &&
- package_type_ == Package::XPK) {
- *error = base::ASCIIToUTF16(errors::kInvalidDescription);
- return false;
+ // FIXME: Better to assert on use from Widget.
+ if (manifest_type() != Manifest::TYPE_MANIFEST)
+ return true; // No error.
+
+ bool hasDeprecatedKey = manifest_->HasKey(keys::kDeprecatedDescriptionKey);
+ bool hasKey = manifest_->HasKey(keys::kXWalkDescriptionKey);
+
+ if (hasKey) {
+ if (hasDeprecatedKey) {
+ LOG(WARNING) << "Deprecated key '" << keys::kDeprecatedDescriptionKey
+ << "' found in addition to '" << keys::kXWalkDescriptionKey
+ << "'. Consider removing.";
+ }
+ bool ok = manifest_->GetString(keys::kXWalkDescriptionKey, &description_);
+ if (!ok)
+ *error = base::ASCIIToUTF16(errors::kInvalidDescription);
+ return ok;
}
- return true;
-}
-bool ApplicationData::LoadManifestVersion(base::string16* error) {
- DCHECK(error);
- // Get the original value out of the dictionary so that we can validate it
- // more strictly.
- if (manifest_->value()->HasKey(keys::kManifestVersionKey)) {
- int manifest_version = 1;
- if (!manifest_->GetInteger(keys::kManifestVersionKey, &manifest_version) ||
- manifest_version < 1) {
- if (package_type_ == Package::XPK) {
- *error = base::ASCIIToUTF16(errors::kInvalidManifestVersion);
- return false;
- }
- }
+ if (hasDeprecatedKey) {
+ LOG(WARNING) << "Deprecated key '" << keys::kDeprecatedDescriptionKey
+ << "' found. Please migrate to using '" << keys::kXWalkDescriptionKey
+ << "' instead.";
+ bool ok = manifest_->GetString(
+ keys::kDeprecatedDescriptionKey, &description_);
+ if (!ok)
+ *error = base::ASCIIToUTF16(errors::kInvalidDescription);
+ return ok;
}
- manifest_version_ = manifest_->GetManifestVersion();
+ // No error but also no description found.
return true;
}
bool ApplicationData::HasCSPDefined() const {
#if defined(OS_TIZEN)
- return manifest_->HasPath(GetCSPKey(package_type_)) ||
+ return manifest_->HasPath(GetCSPKey(manifest_type())) ||
manifest_->HasPath(widget_keys::kCSPReportOnlyKey) ||
manifest_->HasPath(widget_keys::kAllowNavigationKey);
#else
- return manifest_->HasPath(GetCSPKey(package_type_));
+ return manifest_->HasPath(GetCSPKey(manifest_type()));
#endif
}