Replace the "origins" key in the manifest with "extent". The items in the extent are URLPatterns, like other parts of the extension system.

Review URL: http://codereview.chromium.org/552209

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37559 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 08b9707..0846dada 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -458,7 +458,7 @@
               new ChromeURLRequestContext::ExtensionInfo(
                   extension->path(),
                   extension->default_locale(),
-                  extension->app_origins(),
+                  extension->app_extent(),
                   extension->api_permissions())));
     }
   }
diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc
index a50013d..4e9b0ec 100644
--- a/chrome/browser/net/chrome_url_request_context.cc
+++ b/chrome/browser/net/chrome_url_request_context.cc
@@ -690,10 +690,10 @@
   }
 
   // Check that the extension declares the source URL in its extent.
-  std::vector<GURL>& origins = info->second->web_origins;
-  for (std::vector<GURL>::iterator origin = origins.begin();
-       origin != origins.end(); ++origin) {
-    if (url.GetOrigin() == *origin)
+  Extension::URLPatternList& extent = info->second->extent;
+  for (Extension::URLPatternList::iterator pattern = extent.begin();
+       pattern != extent.end(); ++pattern) {
+    if (pattern->MatchesUrl(url))
       return true;
   }
 
@@ -877,7 +877,7 @@
               new ChromeURLRequestContext::ExtensionInfo(
                   (*iter)->path(),
                   (*iter)->default_locale(),
-                  (*iter)->app_origins(),
+                  (*iter)->app_extent(),
                   (*iter)->api_permissions()));
     }
   }
diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h
index d1953ef..f3d1a14b 100644
--- a/chrome/browser/net/chrome_url_request_context.h
+++ b/chrome/browser/net/chrome_url_request_context.h
@@ -11,6 +11,7 @@
 #include "chrome/browser/host_zoom_map.h"
 #include "chrome/browser/net/url_request_context_getter.h"
 #include "chrome/common/appcache/chrome_appcache_service.h"
+#include "chrome/common/extensions/extension.h"
 #include "chrome/common/notification_registrar.h"
 #include "chrome/common/pref_service.h"
 #include "net/url_request/url_request_context.h"
@@ -40,14 +41,14 @@
   // both threads. There is only a small amount of mutable state in Extension.
   struct ExtensionInfo {
     ExtensionInfo(const FilePath& path, const std::string& default_locale,
-                  const std::vector<GURL>& web_origins,
+                  const Extension::URLPatternList& extent,
                   const std::vector<std::string>& api_permissions)
         : path(path), default_locale(default_locale),
-          web_origins(web_origins), api_permissions(api_permissions) {
+          extent(extent), api_permissions(api_permissions) {
     }
     FilePath path;
     std::string default_locale;
-    std::vector<GURL> web_origins;
+    Extension::URLPatternList extent;
     std::vector<std::string> api_permissions;
   };
 
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index 4b2992d9..7bc46b6 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -536,31 +536,38 @@
     *error = errors::kInvalidAppLaunchUrl;
     return false;
   }
-  // The launch URL is automatically an allowed origin.
-  app_origins_.push_back(app_launch_url_.GetOrigin());
 
-  // origins
-  ListValue* origins;
-  if (!app->GetList(keys::kAppOrigins, &origins) || origins->GetSize() == 0) {
-    *error = errors::kInvalidAppOrigin;
-    return false;
-  }
-  for (ListValue::const_iterator iter = origins->begin();
-       iter != origins->end(); ++iter) {
-    std::string url_str;
-    if (!(*iter)->GetAsString(&url_str) || url_str.empty()) {
-      *error = ExtensionErrorUtils::FormatErrorMessage(
-          errors::kInvalidAppOrigin, url_str);
+  // The launch URL is automatically added to the extent.
+  URLPattern pattern;
+  pattern.set_scheme(app_launch_url_.scheme());
+  pattern.set_host(app_launch_url_.host());
+  pattern.set_path(app_launch_url_.path());
+  app_extent_.push_back(pattern);
+
+  // extent
+  if (app->HasKey(keys::kAppExtent)) {
+    ListValue* extent;
+    if (!app->GetList(keys::kAppExtent, &extent)) {
+      *error = errors::kInvalidAppExtent;
       return false;
     }
-    GURL url(url_str);
-    if (!url.is_valid() || url != url.GetOrigin()) {
-      *error = ExtensionErrorUtils::FormatErrorMessage(
-          errors::kInvalidAppOrigin, url_str);
-      return false;
+    for (ListValue::const_iterator iter = extent->begin();
+         iter != extent->end(); ++iter) {
+      std::string item;
+      if (!(*iter)->GetAsString(&item) || item.empty()) {
+        *error = ExtensionErrorUtils::FormatErrorMessage(
+            errors::kInvalidAppExtentPattern, item);
+        return false;
+      }
+      if (!pattern.Parse(item)) {
+        *error = ExtensionErrorUtils::FormatErrorMessage(
+            errors::kInvalidAppExtentPattern, item);
+        return false;
+      }
+      app_extent_.push_back(pattern);
     }
-    app_origins_.push_back(url);
   }
+
   return true;
 }
 
@@ -1357,7 +1364,7 @@
 }
 
 bool Extension::CanAccessHost(const GURL& url) const {
-  for (HostPermissions::const_iterator host = host_permissions_.begin();
+  for (URLPatternList::const_iterator host = host_permissions_.begin();
        host != host_permissions_.end(); ++host) {
     if (host->MatchesUrl(url))
       return true;
@@ -1369,7 +1376,7 @@
 const std::set<std::string> Extension::GetEffectiveHostPermissions() const {
   std::set<std::string> effective_hosts;
 
-  for (HostPermissions::const_iterator host = host_permissions_.begin();
+  for (URLPatternList::const_iterator host = host_permissions_.begin();
        host != host_permissions_.end(); ++host)
     effective_hosts.insert(host->host());
 
@@ -1385,7 +1392,7 @@
 }
 
 bool Extension::HasAccessToAllHosts() const {
-  for (HostPermissions::const_iterator host = host_permissions_.begin();
+  for (URLPatternList::const_iterator host = host_permissions_.begin();
        host != host_permissions_.end(); ++host) {
     if (host->match_subdomains() && host->host().empty())
       return true;
diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h
index 81759488..c0c5a53 100644
--- a/chrome/common/extensions/extension.h
+++ b/chrome/common/extensions/extension.h
@@ -24,7 +24,7 @@
 // Represents a Chrome extension.
 class Extension {
  public:
-  typedef std::vector<URLPattern> HostPermissions;
+  typedef std::vector<URLPattern> URLPatternList;
   typedef std::map<const std::string, GURL> URLOverrideMap;
 
   // What an extension was loaded from.
@@ -211,7 +211,7 @@
   const std::vector<std::string>& api_permissions() const {
     return api_permissions_;
   }
-  const HostPermissions& host_permissions() const {
+  const URLPatternList& host_permissions() const {
     return host_permissions_;
   }
 
@@ -280,7 +280,7 @@
   void SetBackgroundPageReady();
 
   // App stuff.
-  const std::vector<GURL>& app_origins() const { return app_origins_; }
+  const URLPatternList& app_extent() const { return app_extent_; }
   const GURL& app_launch_url() const { return app_launch_url_; }
   bool IsApp() const { return !app_launch_url_.is_empty(); }
 
@@ -392,7 +392,7 @@
   std::vector<std::string> api_permissions_;
 
   // The sites this extension has permission to talk to (using XHR, etc).
-  HostPermissions host_permissions_;
+  URLPatternList host_permissions_;
 
   // The paths to the icons the extension contains mapped by their width.
   std::map<int, std::string> icons_;
@@ -410,8 +410,8 @@
   // which override the handling of those URLs.
   URLOverrideMap chrome_url_overrides_;
 
-  // The vector of origin URLs associated with an app.
-  std::vector<GURL> app_origins_;
+  // Describes the space of URLs that are displayed in the app's custom frame.
+  URLPatternList app_extent_;
 
   // The URL an app should launch to.
   GURL app_launch_url_;
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc
index 3621b9f..a75d4b6 100644
--- a/chrome/common/extensions/extension_constants.cc
+++ b/chrome/common/extensions/extension_constants.cc
@@ -8,7 +8,7 @@
 
 const wchar_t* kAllFrames = L"all_frames";
 const wchar_t* kApp = L"app";
-const wchar_t* kAppOrigins = L"origins";
+const wchar_t* kAppExtent = L"extent";
 const wchar_t* kAppLaunchUrl = L"launch.url";
 const wchar_t* kBackground = L"background_page";
 const wchar_t* kBrowserAction = L"browser_action";
@@ -76,7 +76,8 @@
 const char* kInvalidAllFrames =
     "Invalid value for 'content_scripts[*].all_frames'.";
 const char* kInvalidApp = "Invalid app.";
-const char* kInvalidAppOrigin = "Invalid app origin[*].";
+const char* kInvalidAppExtent = "Invalid value for app.extent.";
+const char* kInvalidAppExtentPattern = "Invalid value for app.extent[*].";
 const char* kInvalidAppLaunchUrl =
     "Required value 'app.launch.url' is missing or invalid.";
 const char* kInvalidBrowserAction =
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h
index 113cfda3..57de540 100644
--- a/chrome/common/extensions/extension_constants.h
+++ b/chrome/common/extensions/extension_constants.h
@@ -9,7 +9,7 @@
 namespace extension_manifest_keys {
   extern const wchar_t* kAllFrames;
   extern const wchar_t* kApp;
-  extern const wchar_t* kAppOrigins;
+  extern const wchar_t* kAppExtent;
   extern const wchar_t* kAppLaunchUrl;
   extern const wchar_t* kBackground;
   extern const wchar_t* kBrowserAction;
@@ -73,7 +73,8 @@
   extern const char* kChromeVersionTooLow;
   extern const char* kInvalidAllFrames;
   extern const char* kInvalidApp;
-  extern const char* kInvalidAppOrigin;
+  extern const char* kInvalidAppExtent;
+  extern const char* kInvalidAppExtentPattern;
   extern const char* kInvalidAppLaunchUrl;
   extern const char* kInvalidBackground;
   extern const char* kInvalidBrowserAction;
diff --git a/chrome/common/extensions/url_pattern.h b/chrome/common/extensions/url_pattern.h
index 6b020c47..dba393a 100644
--- a/chrome/common/extensions/url_pattern.h
+++ b/chrome/common/extensions/url_pattern.h
@@ -87,13 +87,16 @@
   // Get the scheme the pattern matches. This will always return a valid scheme
   // if is_valid() returns true.
   std::string scheme() const { return scheme_; }
+  void set_scheme(const std::string& scheme) { scheme_ = scheme; }
 
   // Gets the host the pattern matches. This can be an empty string if the
   // pattern matches all hosts (the input was <scheme>://*/<whatever>).
   std::string host() const { return host_; }
+  void set_host(const std::string& host) { host_ = host; }
 
   // Gets whether to match subdomains of host().
   bool match_subdomains() const { return match_subdomains_; }
+  void set_match_subdomains(bool val) { match_subdomains_ = val; }
 
   // Gets the path the pattern matches with the leading slash. This can have
   // embedded asterisks which are interpreted using glob rules.