Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / common / extensions / manifest_url_handler.cc
blob557c1c2296abe3ff459c856c952b7a1ed2f8fc70
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/common/extensions/manifest_url_handler.h"
7 #include "base/file_util.h"
8 #include "base/lazy_instance.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "chrome/common/chrome_constants.h"
15 #include "chrome/common/extensions/extension_constants.h"
16 #include "chrome/common/url_constants.h"
17 #include "extensions/common/error_utils.h"
18 #include "extensions/common/file_util.h"
19 #include "extensions/common/manifest.h"
20 #include "extensions/common/manifest_constants.h"
21 #include "extensions/common/permissions/api_permission.h"
22 #include "extensions/common/permissions/api_permission_set.h"
23 #include "extensions/common/permissions/permissions_data.h"
24 #include "grit/generated_resources.h"
25 #include "ui/base/l10n/l10n_util.h"
27 #if defined(USE_AURA)
28 #include "ui/keyboard/keyboard_constants.h"
29 #endif
31 namespace extensions {
33 namespace keys = manifest_keys;
34 namespace errors = manifest_errors;
36 namespace {
38 const char kOverrideExtentUrlPatternFormat[] = "chrome://%s/*";
40 const GURL& GetManifestURL(const Extension* extension,
41 const std::string& key) {
42 ManifestURL* manifest_url =
43 static_cast<ManifestURL*>(extension->GetManifestData(key));
44 return manifest_url ? manifest_url->url_ : GURL::EmptyGURL();
47 } // namespace
49 // static
50 const GURL& ManifestURL::GetDevToolsPage(const Extension* extension) {
51 return GetManifestURL(extension, keys::kDevToolsPage);
54 // static
55 const GURL ManifestURL::GetHomepageURL(const Extension* extension) {
56 const GURL& homepage_url = GetManifestURL(extension, keys::kHomepageURL);
57 if (homepage_url.is_valid())
58 return homepage_url;
59 return UpdatesFromGallery(extension) ?
60 GURL(extension_urls::GetWebstoreItemDetailURLPrefix() + extension->id()) :
61 GURL::EmptyGURL();
64 // static
65 const GURL& ManifestURL::GetUpdateURL(const Extension* extension) {
66 return GetManifestURL(extension, keys::kUpdateURL);
69 // static
70 bool ManifestURL::UpdatesFromGallery(const Extension* extension) {
71 return extension_urls::IsWebstoreUpdateUrl(GetUpdateURL(extension));
74 // static
75 bool ManifestURL::UpdatesFromGallery(const base::DictionaryValue* manifest) {
76 std::string url;
77 if (!manifest->GetString(keys::kUpdateURL, &url))
78 return false;
79 return extension_urls::IsWebstoreUpdateUrl(GURL(url));
82 // static
83 const GURL& ManifestURL::GetOptionsPage(const Extension* extension) {
84 return GetManifestURL(extension, keys::kOptionsPage);
87 // static
88 const GURL ManifestURL::GetDetailsURL(const Extension* extension) {
89 return extension->from_webstore() ?
90 GURL(extension_urls::GetWebstoreItemDetailURLPrefix() + extension->id()) :
91 GURL::EmptyGURL();
94 URLOverrides::URLOverrides() {
97 URLOverrides::~URLOverrides() {
100 static base::LazyInstance<URLOverrides::URLOverrideMap> g_empty_url_overrides =
101 LAZY_INSTANCE_INITIALIZER;
103 // static
104 const URLOverrides::URLOverrideMap&
105 URLOverrides::GetChromeURLOverrides(const Extension* extension) {
106 URLOverrides* url_overrides = static_cast<URLOverrides*>(
107 extension->GetManifestData(keys::kChromeURLOverrides));
108 return url_overrides ?
109 url_overrides->chrome_url_overrides_ :
110 g_empty_url_overrides.Get();
113 DevToolsPageHandler::DevToolsPageHandler() {
116 DevToolsPageHandler::~DevToolsPageHandler() {
119 bool DevToolsPageHandler::Parse(Extension* extension, base::string16* error) {
120 scoped_ptr<ManifestURL> manifest_url(new ManifestURL);
121 std::string devtools_str;
122 if (!extension->manifest()->GetString(keys::kDevToolsPage, &devtools_str)) {
123 *error = base::ASCIIToUTF16(errors::kInvalidDevToolsPage);
124 return false;
126 manifest_url->url_ = extension->GetResourceURL(devtools_str);
127 extension->SetManifestData(keys::kDevToolsPage, manifest_url.release());
128 PermissionsData::GetInitialAPIPermissions(extension)->insert(
129 APIPermission::kDevtools);
130 return true;
133 const std::vector<std::string> DevToolsPageHandler::Keys() const {
134 return SingleKey(keys::kDevToolsPage);
137 HomepageURLHandler::HomepageURLHandler() {
140 HomepageURLHandler::~HomepageURLHandler() {
143 bool HomepageURLHandler::Parse(Extension* extension, base::string16* error) {
144 scoped_ptr<ManifestURL> manifest_url(new ManifestURL);
145 std::string homepage_url_str;
146 if (!extension->manifest()->GetString(keys::kHomepageURL,
147 &homepage_url_str)) {
148 *error = ErrorUtils::FormatErrorMessageUTF16(errors::kInvalidHomepageURL,
149 std::string());
150 return false;
152 manifest_url->url_ = GURL(homepage_url_str);
153 if (!manifest_url->url_.is_valid() ||
154 !manifest_url->url_.SchemeIsHTTPOrHTTPS()) {
155 *error = ErrorUtils::FormatErrorMessageUTF16(
156 errors::kInvalidHomepageURL, homepage_url_str);
157 return false;
159 extension->SetManifestData(keys::kHomepageURL, manifest_url.release());
160 return true;
163 const std::vector<std::string> HomepageURLHandler::Keys() const {
164 return SingleKey(keys::kHomepageURL);
167 UpdateURLHandler::UpdateURLHandler() {
170 UpdateURLHandler::~UpdateURLHandler() {
173 bool UpdateURLHandler::Parse(Extension* extension, base::string16* error) {
174 scoped_ptr<ManifestURL> manifest_url(new ManifestURL);
175 std::string tmp_update_url;
177 if (!extension->manifest()->GetString(keys::kUpdateURL, &tmp_update_url)) {
178 *error = ErrorUtils::FormatErrorMessageUTF16(errors::kInvalidUpdateURL,
179 std::string());
180 return false;
183 manifest_url->url_ = GURL(tmp_update_url);
184 if (!manifest_url->url_.is_valid() ||
185 manifest_url->url_.has_ref()) {
186 *error = ErrorUtils::FormatErrorMessageUTF16(
187 errors::kInvalidUpdateURL, tmp_update_url);
188 return false;
191 extension->SetManifestData(keys::kUpdateURL, manifest_url.release());
192 return true;
195 const std::vector<std::string> UpdateURLHandler::Keys() const {
196 return SingleKey(keys::kUpdateURL);
199 OptionsPageHandler::OptionsPageHandler() {
202 OptionsPageHandler::~OptionsPageHandler() {
205 bool OptionsPageHandler::Parse(Extension* extension, base::string16* error) {
206 scoped_ptr<ManifestURL> manifest_url(new ManifestURL);
207 std::string options_str;
208 if (!extension->manifest()->GetString(keys::kOptionsPage, &options_str)) {
209 *error = base::ASCIIToUTF16(errors::kInvalidOptionsPage);
210 return false;
213 if (extension->is_hosted_app()) {
214 // hosted apps require an absolute URL.
215 GURL options_url(options_str);
216 if (!options_url.is_valid() ||
217 !options_url.SchemeIsHTTPOrHTTPS()) {
218 *error = base::ASCIIToUTF16(errors::kInvalidOptionsPageInHostedApp);
219 return false;
221 manifest_url->url_ = options_url;
222 } else {
223 GURL absolute(options_str);
224 if (absolute.is_valid()) {
225 *error =
226 base::ASCIIToUTF16(errors::kInvalidOptionsPageExpectUrlInPackage);
227 return false;
229 manifest_url->url_ = extension->GetResourceURL(options_str);
230 if (!manifest_url->url_.is_valid()) {
231 *error = base::ASCIIToUTF16(errors::kInvalidOptionsPage);
232 return false;
236 extension->SetManifestData(keys::kOptionsPage, manifest_url.release());
237 return true;
240 bool OptionsPageHandler::Validate(const Extension* extension,
241 std::string* error,
242 std::vector<InstallWarning>* warnings) const {
243 // Validate path to the options page. Don't check the URL for hosted apps,
244 // because they are expected to refer to an external URL.
245 if (!extensions::ManifestURL::GetOptionsPage(extension).is_empty() &&
246 !extension->is_hosted_app()) {
247 const base::FilePath options_path =
248 extensions::file_util::ExtensionURLToRelativeFilePath(
249 extensions::ManifestURL::GetOptionsPage(extension));
250 const base::FilePath path =
251 extension->GetResource(options_path).GetFilePath();
252 if (path.empty() || !base::PathExists(path)) {
253 *error =
254 l10n_util::GetStringFUTF8(
255 IDS_EXTENSION_LOAD_OPTIONS_PAGE_FAILED,
256 options_path.LossyDisplayName());
257 return false;
260 return true;
263 const std::vector<std::string> OptionsPageHandler::Keys() const {
264 return SingleKey(keys::kOptionsPage);
267 URLOverridesHandler::URLOverridesHandler() {
270 URLOverridesHandler::~URLOverridesHandler() {
273 bool URLOverridesHandler::Parse(Extension* extension, base::string16* error) {
274 const base::DictionaryValue* overrides = NULL;
275 if (!extension->manifest()->GetDictionary(keys::kChromeURLOverrides,
276 &overrides)) {
277 *error = base::ASCIIToUTF16(errors::kInvalidChromeURLOverrides);
278 return false;
280 scoped_ptr<URLOverrides> url_overrides(new URLOverrides);
281 // Validate that the overrides are all strings
282 for (base::DictionaryValue::Iterator iter(*overrides); !iter.IsAtEnd();
283 iter.Advance()) {
284 std::string page = iter.key();
285 std::string val;
286 // Restrict override pages to a list of supported URLs.
287 bool is_override = (page != chrome::kChromeUINewTabHost &&
288 page != chrome::kChromeUIBookmarksHost &&
289 page != chrome::kChromeUIHistoryHost);
290 #if defined(OS_CHROMEOS)
291 is_override = (is_override &&
292 page != chrome::kChromeUIActivationMessageHost);
293 #endif
294 #if defined(OS_CHROMEOS)
295 is_override = (is_override && page != keyboard::kKeyboardHost);
296 #endif
298 if (is_override || !iter.value().GetAsString(&val)) {
299 *error = base::ASCIIToUTF16(errors::kInvalidChromeURLOverrides);
300 return false;
302 // Replace the entry with a fully qualified chrome-extension:// URL.
303 url_overrides->chrome_url_overrides_[page] = extension->GetResourceURL(val);
305 // For component extensions, add override URL to extent patterns.
306 if (extension->is_legacy_packaged_app() &&
307 extension->location() == Manifest::COMPONENT) {
308 URLPattern pattern(URLPattern::SCHEME_CHROMEUI);
309 std::string url = base::StringPrintf(kOverrideExtentUrlPatternFormat,
310 page.c_str());
311 if (pattern.Parse(url) != URLPattern::PARSE_SUCCESS) {
312 *error = ErrorUtils::FormatErrorMessageUTF16(
313 errors::kInvalidURLPatternError, url);
314 return false;
316 extension->AddWebExtentPattern(pattern);
320 // An extension may override at most one page.
321 if (overrides->size() > 1) {
322 *error = base::ASCIIToUTF16(errors::kMultipleOverrides);
323 return false;
325 extension->SetManifestData(keys::kChromeURLOverrides,
326 url_overrides.release());
327 return true;
330 const std::vector<std::string> URLOverridesHandler::Keys() const {
331 return SingleKey(keys::kChromeURLOverrides);
334 } // namespace extensions