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/chrome_manifest_url_handlers.h"
7 #include "base/lazy_instance.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "chrome/common/chrome_constants.h"
14 #include "chrome/common/url_constants.h"
15 #include "extensions/common/error_utils.h"
16 #include "extensions/common/manifest.h"
17 #include "extensions/common/manifest_constants.h"
18 #include "extensions/common/manifest_handlers/permissions_parser.h"
19 #include "extensions/common/manifest_handlers/shared_module_info.h"
20 #include "extensions/common/manifest_url_handlers.h"
21 #include "extensions/common/permissions/api_permission.h"
24 #include "ui/keyboard/keyboard_constants.h"
27 namespace extensions
{
29 namespace keys
= manifest_keys
;
30 namespace errors
= manifest_errors
;
34 const char kOverrideExtentUrlPatternFormat
[] = "chrome://%s/*";
38 namespace chrome_manifest_urls
{
39 const GURL
& GetDevToolsPage(const Extension
* extension
) {
40 return ManifestURL::Get(extension
, keys::kDevToolsPage
);
44 URLOverrides::URLOverrides() {
47 URLOverrides::~URLOverrides() {
50 static base::LazyInstance
<URLOverrides::URLOverrideMap
> g_empty_url_overrides
=
51 LAZY_INSTANCE_INITIALIZER
;
54 const URLOverrides::URLOverrideMap
& URLOverrides::GetChromeURLOverrides(
55 const Extension
* extension
) {
56 URLOverrides
* url_overrides
= static_cast<URLOverrides
*>(
57 extension
->GetManifestData(keys::kChromeURLOverrides
));
58 return url_overrides
? url_overrides
->chrome_url_overrides_
59 : g_empty_url_overrides
.Get();
62 DevToolsPageHandler::DevToolsPageHandler() {
65 DevToolsPageHandler::~DevToolsPageHandler() {
68 bool DevToolsPageHandler::Parse(Extension
* extension
, base::string16
* error
) {
69 scoped_ptr
<ManifestURL
> manifest_url(new ManifestURL
);
70 std::string devtools_str
;
71 if (!extension
->manifest()->GetString(keys::kDevToolsPage
, &devtools_str
)) {
72 *error
= base::ASCIIToUTF16(errors::kInvalidDevToolsPage
);
75 manifest_url
->url_
= extension
->GetResourceURL(devtools_str
);
76 extension
->SetManifestData(keys::kDevToolsPage
, manifest_url
.release());
77 PermissionsParser::AddAPIPermission(extension
, APIPermission::kDevtools
);
81 const std::vector
<std::string
> DevToolsPageHandler::Keys() const {
82 return SingleKey(keys::kDevToolsPage
);
85 URLOverridesHandler::URLOverridesHandler() {
88 URLOverridesHandler::~URLOverridesHandler() {
91 bool URLOverridesHandler::Parse(Extension
* extension
, base::string16
* error
) {
92 const base::DictionaryValue
* overrides
= NULL
;
93 if (!extension
->manifest()->GetDictionary(keys::kChromeURLOverrides
,
95 *error
= base::ASCIIToUTF16(errors::kInvalidChromeURLOverrides
);
98 scoped_ptr
<URLOverrides
> url_overrides(new URLOverrides
);
99 // Validate that the overrides are all strings
100 for (base::DictionaryValue::Iterator
iter(*overrides
); !iter
.IsAtEnd();
102 std::string page
= iter
.key();
104 // Restrict override pages to a list of supported URLs.
105 bool is_override
= (page
!= chrome::kChromeUINewTabHost
&&
106 page
!= chrome::kChromeUIBookmarksHost
&&
107 page
!= chrome::kChromeUIHistoryHost
);
108 #if defined(OS_CHROMEOS)
110 (is_override
&& page
!= chrome::kChromeUIActivationMessageHost
);
112 #if defined(OS_CHROMEOS)
113 is_override
= (is_override
&& page
!= keyboard::kKeyboardHost
);
116 if (is_override
|| !iter
.value().GetAsString(&val
)) {
117 *error
= base::ASCIIToUTF16(errors::kInvalidChromeURLOverrides
);
120 // Replace the entry with a fully qualified chrome-extension:// URL.
121 url_overrides
->chrome_url_overrides_
[page
] = extension
->GetResourceURL(val
);
123 // For component extensions, add override URL to extent patterns.
124 if (extension
->is_legacy_packaged_app() &&
125 extension
->location() == Manifest::COMPONENT
) {
126 URLPattern
pattern(URLPattern::SCHEME_CHROMEUI
);
128 base::StringPrintf(kOverrideExtentUrlPatternFormat
, page
.c_str());
129 if (pattern
.Parse(url
) != URLPattern::PARSE_SUCCESS
) {
130 *error
= ErrorUtils::FormatErrorMessageUTF16(
131 errors::kInvalidURLPatternError
, url
);
134 extension
->AddWebExtentPattern(pattern
);
138 // An extension may override at most one page.
139 if (overrides
->size() > 1) {
140 *error
= base::ASCIIToUTF16(errors::kMultipleOverrides
);
143 extension
->SetManifestData(keys::kChromeURLOverrides
,
144 url_overrides
.release());
148 const std::vector
<std::string
> URLOverridesHandler::Keys() const {
149 return SingleKey(keys::kChromeURLOverrides
);
152 } // namespace extensions