Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2157)

Unified Diff: chrome/common/extensions/app_launcher_info.cc

Issue 12316077: Move the parsing of app.launch related keys out of Extension class. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/common/extensions/app_launcher_info.h ('k') | chrome/common/extensions/extension.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/common/extensions/app_launcher_info.cc
diff --git a/chrome/common/extensions/app_launcher_info.cc b/chrome/common/extensions/app_launcher_info.cc
new file mode 100644
index 0000000000000000000000000000000000000000..afe54db0880e1f21bf1b7bdc44791972180aea90
--- /dev/null
+++ b/chrome/common/extensions/app_launcher_info.cc
@@ -0,0 +1,325 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/extensions/app_launcher_info.h"
+
+#include "base/command_line.h"
+#include "base/lazy_instance.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/extensions/extension_manifest_constants.h"
+#include "chrome/common/url_constants.h"
+#include "extensions/common/error_utils.h"
+
+namespace keys = extension_manifest_keys;
+namespace values = extension_manifest_values;
+namespace errors = extension_manifest_errors;
+
+namespace extensions {
+
+namespace {
+
+bool ReadLaunchDimension(const extensions::Manifest* manifest,
+ const char* key,
+ int* target,
+ bool is_valid_container,
+ string16* error) {
+ const 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<AppLauncherInfo> g_empty_app_launch_info =
+ LAZY_INSTANCE_INITIALIZER;
+
+const AppLauncherInfo& GetAppLauncherInfo(const Extension* extension) {
+ AppLauncherInfo* info = static_cast<AppLauncherInfo*>(
+ extension->GetManifestData(keys::kLaunch));
+ return info ? *info : g_empty_app_launch_info.Get();
+}
+
+} // namespace
+
+AppLauncherInfo::AppLauncherInfo()
+ : launch_container_(extension_misc::LAUNCH_TAB),
+ launch_width_(0),
+ launch_height_(0) {
+}
+
+AppLauncherInfo::~AppLauncherInfo() {
+}
+
+// static
+const std::string& AppLauncherInfo::GetLaunchLocalPath(
+ const Extension* extension) {
+ return GetAppLauncherInfo(extension).launch_local_path_;
+}
+
+// static
+const std::string& AppLauncherInfo::GetLaunchWebURL(
+ const Extension* extension) {
+ return GetAppLauncherInfo(extension).launch_web_url_;
+}
+
+// static
+extension_misc::LaunchContainer AppLauncherInfo::GetLaunchContainer(
+ const Extension* extension) {
+ return GetAppLauncherInfo(extension).launch_container_;
+}
+
+// static
+int AppLauncherInfo::GetLaunchWidth(const Extension* extension) {
+ return GetAppLauncherInfo(extension).launch_width_;
+}
+
+// static
+int AppLauncherInfo::GetLaunchHeight(const Extension* extension) {
+ return GetAppLauncherInfo(extension).launch_height_;
+}
+
+// static
+GURL AppLauncherInfo::GetFullLaunchURL(const Extension* extension) {
+ const AppLauncherInfo& info = GetAppLauncherInfo(extension);
+ if (info.launch_local_path_.empty())
+ return GURL(info.launch_web_url_);
+ else
+ return extension->url().Resolve(info.launch_local_path_);
+}
+
+bool AppLauncherInfo::Parse(Extension* extension, string16* error) {
+ if (!LoadLaunchURL(extension, error) ||
+ !LoadLaunchContainer(extension, error))
+ return false;
+ return true;
+}
+
+bool AppLauncherInfo::LoadLaunchURL(Extension* extension, string16* error) {
+ const Value* temp = NULL;
+
+ // Launch URL can be either local (to chrome-extension:// root) or an absolute
+ // web URL.
+ if (extension->manifest()->Get(keys::kLaunchLocalPath, &temp)) {
+ if (extension->manifest()->Get(keys::kLaunchWebURL, NULL)) {
+ *error = ASCIIToUTF16(errors::kLaunchPathAndURLAreExclusive);
+ return false;
+ }
+
+ if (extension->manifest()->Get(keys::kWebURLs, NULL)) {
+ *error = ASCIIToUTF16(errors::kLaunchPathAndExtentAreExclusive);
+ return false;
+ }
+
+ std::string launch_path;
+ if (!temp->GetAsString(&launch_path)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidLaunchValue,
+ keys::kLaunchLocalPath);
+ return false;
+ }
+
+ // Ensure the launch path is a valid relative URL.
+ 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;
+ }
+
+ // Ensure the launch URL is a valid absolute URL and web extent scheme.
+ 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_ = launch_url;
+ } else if (extension->is_legacy_packaged_app()) {
+ *error = ASCIIToUTF16(errors::kLaunchURLRequired);
+ return false;
+ }
+
+ // If there is no extent, we default the extent based on the launch URL.
+ if (extension->web_extent().is_empty() && !launch_web_url_.empty()) {
+ GURL launch_url(launch_web_url_);
+ URLPattern pattern(Extension::kValidWebExtentSchemes);
+ if (!pattern.SetScheme("*")) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidLaunchValue,
+ keys::kLaunchWebURL);
+ return false;
+ }
+ pattern.SetHost(launch_url.host());
+ pattern.SetPath("/*");
+ extension->AddWebExtentPattern(pattern);
+ }
+
+ // In order for the --apps-gallery-url switch to work with the gallery
+ // process isolation, we must insert any provided value into the component
+ // app's launch url and web extent.
+ if (extension->id() == extension_misc::kWebStoreAppId) {
+ std::string gallery_url_str = CommandLine::ForCurrentProcess()->
+ GetSwitchValueASCII(switches::kAppsGalleryURL);
+
+ // Empty string means option was not used.
+ if (!gallery_url_str.empty()) {
+ GURL gallery_url(gallery_url_str);
+ OverrideLaunchURL(extension, gallery_url);
+ }
+ } else if (extension->id() == extension_misc::kCloudPrintAppId) {
+ // In order for the --cloud-print-service switch to work, we must update
+ // the launch URL and web extent.
+ // TODO(sanjeevr): Ideally we want to use CloudPrintURL here but that is
+ // currently under chrome/browser.
+ 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);
+ }
+ } else if (extension->id() == extension_misc::kChromeAppId) {
+ // Override launch url to new tab.
+ launch_web_url_ = chrome::kChromeUINewTabURL;
+ extension->ClearWebExtentPatterns();
+ }
+
+ return true;
+}
+
+bool AppLauncherInfo::LoadLaunchContainer(Extension* extension,
+ string16* error) {
+ const 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 = ASCIIToUTF16(errors::kInvalidLaunchContainer);
+ return false;
+ }
+
+ if (launch_container_string == values::kLaunchContainerPanel) {
+ launch_container_ = extension_misc::LAUNCH_PANEL;
+ } else if (launch_container_string == values::kLaunchContainerTab) {
+ launch_container_ = extension_misc::LAUNCH_TAB;
+ } else {
+ *error = ASCIIToUTF16(errors::kInvalidLaunchContainer);
+ return false;
+ }
+
+ bool can_specify_initial_size =
+ launch_container_ == extension_misc::LAUNCH_PANEL ||
+ launch_container_ == extension_misc::LAUNCH_WINDOW;
+
+ // Validate the container width if present.
+ if (!ReadLaunchDimension(extension->manifest(),
+ keys::kLaunchWidth,
+ &launch_width_,
+ can_specify_initial_size,
+ error)) {
+ return false;
+ }
+
+ // Validate container height if present.
+ if (!ReadLaunchDimension(extension->manifest(),
+ keys::kLaunchHeight,
+ &launch_height_,
+ can_specify_initial_size,
+ error)) {
+ return false;
+ }
+
+ return true;
+}
+
+void AppLauncherInfo::OverrideLaunchURL(Extension* extension,
+ GURL override_url) {
+ if (!override_url.is_valid()) {
+ DLOG(WARNING) << "Invalid override url given for " << extension->name();
+ } else {
+ 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.spec();
+
+ 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, string16* error) {
+ scoped_ptr<AppLauncherInfo> info(new AppLauncherInfo);
+ 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));
+}
+
+} // namespace extensions
« no previous file with comments | « chrome/common/extensions/app_launcher_info.h ('k') | chrome/common/extensions/extension.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698