This source file includes following definitions.
- ReadLaunchDimension
- GetAppLaunchInfo
- launch_height_
- GetLaunchLocalPath
- GetLaunchWebURL
- GetLaunchContainer
- GetLaunchWidth
- GetLaunchHeight
- GetFullLaunchURL
- Parse
- LoadLaunchURL
- LoadLaunchContainer
- OverrideLaunchURL
- Parse
- AlwaysParseForType
- Keys
#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/url_constants.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/manifest_constants.h"
namespace extensions {
namespace keys = manifest_keys;
namespace values = manifest_values;
namespace errors = manifest_errors;
namespace {
bool ReadLaunchDimension(const extensions::Manifest* manifest,
const char* key,
int* target,
bool is_valid_container,
base::string16* error) {
const base::Value* temp = NULL;
if (manifest->Get(key, &temp)) {
if (!is_valid_container) {
*error = ErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidLaunchValueContainer,
key);
return false;
}
if (!temp->GetAsInteger(target) || *target < 0) {
*target = 0;
*error = ErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidLaunchValue,
key);
return false;
}
}
return true;
}
static base::LazyInstance<AppLaunchInfo> g_empty_app_launch_info =
LAZY_INSTANCE_INITIALIZER;
const AppLaunchInfo& GetAppLaunchInfo(const Extension* extension) {
AppLaunchInfo* info = static_cast<AppLaunchInfo*>(
extension->GetManifestData(keys::kLaunch));
return info ? *info : g_empty_app_launch_info.Get();
}
}
AppLaunchInfo::AppLaunchInfo()
: launch_container_(LAUNCH_CONTAINER_TAB),
launch_width_(0),
launch_height_(0) {
}
AppLaunchInfo::~AppLaunchInfo() {
}
const std::string& AppLaunchInfo::GetLaunchLocalPath(
const Extension* extension) {
return GetAppLaunchInfo(extension).launch_local_path_;
}
const GURL& AppLaunchInfo::GetLaunchWebURL(
const Extension* extension) {
return GetAppLaunchInfo(extension).launch_web_url_;
}
extensions::LaunchContainer AppLaunchInfo::GetLaunchContainer(
const Extension* extension) {
return GetAppLaunchInfo(extension).launch_container_;
}
int AppLaunchInfo::GetLaunchWidth(const Extension* extension) {
return GetAppLaunchInfo(extension).launch_width_;
}
int AppLaunchInfo::GetLaunchHeight(const Extension* extension) {
return GetAppLaunchInfo(extension).launch_height_;
}
GURL AppLaunchInfo::GetFullLaunchURL(const Extension* extension) {
const AppLaunchInfo& info = GetAppLaunchInfo(extension);
if (info.launch_local_path_.empty())
return info.launch_web_url_;
else
return extension->url().Resolve(info.launch_local_path_);
}
bool AppLaunchInfo::Parse(Extension* extension, base::string16* error) {
if (!LoadLaunchURL(extension, error) ||
!LoadLaunchContainer(extension, error))
return false;
return true;
}
bool AppLaunchInfo::LoadLaunchURL(Extension* extension, base::string16* error) {
const base::Value* temp = NULL;
if (extension->manifest()->Get(keys::kLaunchLocalPath, &temp)) {
if (extension->manifest()->Get(keys::kLaunchWebURL, NULL)) {
*error = base::ASCIIToUTF16(errors::kLaunchPathAndURLAreExclusive);
return false;
}
if (extension->manifest()->Get(keys::kWebURLs, NULL)) {
*error = base::ASCIIToUTF16(errors::kLaunchPathAndExtentAreExclusive);
return false;
}
std::string launch_path;
if (!temp->GetAsString(&launch_path)) {
*error = ErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidLaunchValue,
keys::kLaunchLocalPath);
return false;
}
GURL resolved = extension->url().Resolve(launch_path);
if (!resolved.is_valid() || resolved.GetOrigin() != extension->url()) {
*error = ErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidLaunchValue,
keys::kLaunchLocalPath);
return false;
}
launch_local_path_ = launch_path;
} else if (extension->manifest()->Get(keys::kLaunchWebURL, &temp)) {
std::string launch_url;
if (!temp->GetAsString(&launch_url)) {
*error = ErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidLaunchValue,
keys::kLaunchWebURL);
return false;
}
GURL url(launch_url);
URLPattern pattern(Extension::kValidWebExtentSchemes);
if (!url.is_valid() || !pattern.SetScheme(url.scheme())) {
*error = ErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidLaunchValue,
keys::kLaunchWebURL);
return false;
}
launch_web_url_ = url;
} else if (extension->is_legacy_packaged_app()) {
*error = base::ASCIIToUTF16(errors::kLaunchURLRequired);
return false;
}
if (extension->id() == extension_misc::kChromeAppId) {
launch_web_url_ = GURL(chrome::kChromeUINewTabURL);
return true;
}
if (extension->web_extent().is_empty() && !launch_web_url_.is_empty()) {
URLPattern pattern(Extension::kValidWebExtentSchemes);
if (!pattern.SetScheme("*")) {
*error = ErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidLaunchValue,
keys::kLaunchWebURL);
return false;
}
pattern.SetHost(launch_web_url_.host());
pattern.SetPath("/*");
extension->AddWebExtentPattern(pattern);
}
if (extension->id() == extension_misc::kWebStoreAppId) {
std::string gallery_url_str = CommandLine::ForCurrentProcess()->
GetSwitchValueASCII(switches::kAppsGalleryURL);
if (!gallery_url_str.empty()) {
GURL gallery_url(gallery_url_str);
OverrideLaunchURL(extension, gallery_url);
}
} else if (extension->id() == extension_misc::kCloudPrintAppId) {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
GURL cloud_print_service_url = GURL(command_line.GetSwitchValueASCII(
switches::kCloudPrintServiceURL));
if (!cloud_print_service_url.is_empty()) {
std::string path(
cloud_print_service_url.path() + "/enable_chrome_connector");
GURL::Replacements replacements;
replacements.SetPathStr(path);
GURL cloud_print_enable_connector_url =
cloud_print_service_url.ReplaceComponents(replacements);
OverrideLaunchURL(extension, cloud_print_enable_connector_url);
}
}
return true;
}
bool AppLaunchInfo::LoadLaunchContainer(Extension* extension,
base::string16* error) {
const base::Value* tmp_launcher_container = NULL;
if (!extension->manifest()->Get(keys::kLaunchContainer,
&tmp_launcher_container))
return true;
std::string launch_container_string;
if (!tmp_launcher_container->GetAsString(&launch_container_string)) {
*error = base::ASCIIToUTF16(errors::kInvalidLaunchContainer);
return false;
}
if (launch_container_string == values::kLaunchContainerPanel) {
launch_container_ = LAUNCH_CONTAINER_PANEL;
} else if (launch_container_string == values::kLaunchContainerTab) {
launch_container_ = LAUNCH_CONTAINER_TAB;
} else {
*error = base::ASCIIToUTF16(errors::kInvalidLaunchContainer);
return false;
}
bool can_specify_initial_size = launch_container_ == LAUNCH_CONTAINER_PANEL;
if (!ReadLaunchDimension(extension->manifest(),
keys::kLaunchWidth,
&launch_width_,
can_specify_initial_size,
error)) {
return false;
}
if (!ReadLaunchDimension(extension->manifest(),
keys::kLaunchHeight,
&launch_height_,
can_specify_initial_size,
error)) {
return false;
}
return true;
}
void AppLaunchInfo::OverrideLaunchURL(Extension* extension,
GURL override_url) {
if (!override_url.is_valid()) {
DLOG(WARNING) << "Invalid override url given for " << extension->name();
return;
}
if (override_url.has_port()) {
DLOG(WARNING) << "Override URL passed for " << extension->name()
<< " should not contain a port. Removing it.";
GURL::Replacements remove_port;
remove_port.ClearPort();
override_url = override_url.ReplaceComponents(remove_port);
}
launch_web_url_ = override_url;
URLPattern pattern(Extension::kValidWebExtentSchemes);
URLPattern::ParseResult result = pattern.Parse(override_url.spec());
DCHECK_EQ(result, URLPattern::PARSE_SUCCESS);
pattern.SetPath(pattern.path() + '*');
extension->AddWebExtentPattern(pattern);
}
AppLaunchManifestHandler::AppLaunchManifestHandler() {
}
AppLaunchManifestHandler::~AppLaunchManifestHandler() {
}
bool AppLaunchManifestHandler::Parse(Extension* extension,
base::string16* error) {
scoped_ptr<AppLaunchInfo> info(new AppLaunchInfo);
if (!info->Parse(extension, error))
return false;
extension->SetManifestData(keys::kLaunch, info.release());
return true;
}
bool AppLaunchManifestHandler::AlwaysParseForType(Manifest::Type type) const {
return type == Manifest::TYPE_LEGACY_PACKAGED_APP;
}
const std::vector<std::string> AppLaunchManifestHandler::Keys() const {
static const char* keys[] = {
keys::kLaunchLocalPath,
keys::kLaunchWebURL,
keys::kLaunchContainer,
keys::kLaunchHeight,
keys::kLaunchWidth
};
return std::vector<std::string>(keys, keys + arraysize(keys));
}
}