OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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. | |
4 | |
5 #include "extensions/common/manifest_handlers/options_page_info.h" | |
6 | |
7 #include "base/file_util.h" | |
8 #include "base/lazy_instance.h" | |
9 #include "base/memory/scoped_ptr.h" | |
10 #include "base/strings/utf_string_conversions.h" | |
11 #include "extensions/common/api/extensions_manifest_types.h" | |
12 #include "extensions/common/file_util.h" | |
13 #include "extensions/common/manifest_constants.h" | |
14 #include "extensions/strings/grit/extensions_strings.h" | |
15 #include "ui/base/l10n/l10n_util.h" | |
16 | |
17 using base::ASCIIToUTF16; | |
18 using base::DictionaryValue; | |
19 | |
20 namespace extensions { | |
21 | |
22 namespace keys = manifest_keys; | |
23 namespace values = manifest_values; | |
24 namespace errors = manifest_errors; | |
25 | |
26 using core_api::extensions_manifest_types::OptionsUI; | |
27 | |
28 namespace { | |
29 // Parses |url_string| into a GURL |result| if it is a valid options page for | |
30 // this app/extension. If not, it returns the reason in |error|. Because this | |
31 // handles URLs for both "options_page" and "options_ui.page", the | |
32 // OptionsUrlType must be passed to this function to send the correct error | |
33 // message. Returns true on success, false otherwise. | |
34 bool ParseOptionsUrl(Extension* extension, | |
35 std::string url_string, | |
not at google - send to devlin
2014/08/29 05:39:24
const std::string&
ericzeng
2014/08/29 22:08:51
Done.
| |
36 OptionsPageInfo::OptionsUrlType url_type, | |
not at google - send to devlin
2014/08/29 05:39:24
Rather than having this enum type, you could param
ericzeng
2014/08/29 16:52:22
Doesn't that mean moving the errors out of manifes
ericzeng
2014/08/29 22:08:51
Changed from enum to parameterized string
| |
37 base::string16* error, | |
38 GURL* result) { | |
39 if (extension->is_hosted_app()) { | |
40 // hosted apps require an absolute URL. | |
41 GURL options_url(url_string); | |
42 if (!options_url.is_valid() || !options_url.SchemeIsHTTPOrHTTPS()) { | |
43 if (url_type == OptionsPageInfo::OPTIONS_PAGE) | |
44 *error = base::ASCIIToUTF16(errors::kInvalidOptionsPageInHostedApp); | |
45 else if (url_type == OptionsPageInfo::OPTIONS_UI_PAGE) | |
46 *error = base::ASCIIToUTF16(errors::kInvalidOptionsUIPageInHostedApp); | |
not at google - send to devlin
2014/08/29 05:39:24
This shouldn't even be possible, hosted apps can't
ericzeng
2014/08/29 22:08:51
Removed OptionsUI errors
| |
47 return false; | |
48 } | |
49 *result = options_url; | |
not at google - send to devlin
2014/08/29 05:39:25
You should probably early-return in the hosted app
ericzeng
2014/08/29 22:08:51
Done.
| |
50 | |
51 } else { | |
52 GURL absolute(url_string); | |
53 if (absolute.is_valid()) { | |
54 if (url_type == OptionsPageInfo::OPTIONS_PAGE) { | |
55 *error = | |
56 base::ASCIIToUTF16(errors::kInvalidOptionsPageExpectUrlInPackage); | |
57 } else if (url_type == OptionsPageInfo::OPTIONS_UI_PAGE) { | |
58 *error = | |
59 base::ASCIIToUTF16(errors::kInvalidOptionsUIPageExpectUrlInPackage); | |
60 } | |
61 return false; | |
62 } | |
63 | |
64 GURL resource_url = extension->GetResourceURL(url_string); | |
65 if (!resource_url.is_valid()) { | |
66 if (url_type == OptionsPageInfo::OPTIONS_PAGE) | |
67 *error = base::ASCIIToUTF16(errors::kInvalidOptionsUIPage); | |
68 else if (url_type == OptionsPageInfo::OPTIONS_UI_PAGE) | |
69 *error = base::ASCIIToUTF16(errors::kInvalidOptionsUIPage); | |
not at google - send to devlin
2014/08/29 05:39:25
These are the same?
ericzeng
2014/08/29 22:08:50
Replaced with parameterized error
| |
70 return false; | |
71 } | |
72 *result = resource_url; | |
73 } | |
74 return true; | |
75 } | |
76 | |
77 OptionsPageInfo* GetOptionsPageInfo(const Extension* extension) { | |
78 return static_cast<OptionsPageInfo*>( | |
79 extension->GetManifestData(keys::kOptionsUI)); | |
80 } | |
81 | |
82 } // namespace | |
83 | |
84 OptionsPageInfo::OptionsPageInfo(GURL options_page, | |
85 GURL options_ui_page, | |
86 bool chrome_styles, | |
87 bool open_in_tab) | |
88 : options_page_(options_page), | |
89 options_ui_page_(options_ui_page), | |
90 chrome_styles_(chrome_styles), | |
91 open_in_tab_(open_in_tab) { | |
92 } | |
93 | |
94 OptionsPageInfo::~OptionsPageInfo() { | |
95 } | |
96 | |
97 // static | |
98 GURL OptionsPageInfo::GetOptionsPage(const Extension* extension) { | |
99 OptionsPageInfo* info = GetOptionsPageInfo(extension); | |
100 if (!info) { | |
101 return GURL::EmptyGURL(); | |
102 } | |
103 | |
104 if (info->options_ui_page_.is_valid()) { | |
105 return info->options_ui_page_; | |
106 } | |
107 return info->options_page_; | |
108 } | |
109 | |
110 // static | |
111 bool OptionsPageInfo::ChromeStyle(const Extension* extension) { | |
112 return GetOptionsPageInfo(extension)->chrome_styles_; | |
not at google - send to devlin
2014/08/29 05:39:24
Shouldn't you be checking for an empty info here?
ericzeng
2014/08/29 22:08:51
Done.
| |
113 } | |
114 | |
115 // static | |
116 bool OptionsPageInfo::OpenInTab(const Extension* extension) { | |
117 return GetOptionsPageInfo(extension)->open_in_tab_; | |
not at google - send to devlin
2014/08/29 05:39:24
And here?
And for both of the above: we should ma
ericzeng
2014/08/29 22:08:51
Done.
| |
118 } | |
119 | |
120 scoped_ptr<OptionsPageInfo> OptionsPageInfo::FromValues( | |
not at google - send to devlin
2014/08/29 05:39:24
FromValues looks kinda odd, and besides this is a
ericzeng
2014/08/29 22:08:50
Done.
| |
121 Extension* extension, | |
122 const base::Value* options_ui_value, | |
123 const base::Value* options_page_value, | |
124 std::vector<InstallWarning>* install_warnings, | |
125 base::string16* error) { | |
126 GURL options_page; | |
127 GURL options_ui_page; | |
128 bool chrome_style = false; | |
129 bool open_in_tab = false; | |
130 | |
131 // Parse the options_ui object | |
132 if (options_ui_value) { | |
133 scoped_ptr<OptionsUI> options_ui = | |
134 OptionsUI::FromValue(*options_ui_value, error); | |
135 if (options_ui) { | |
136 if (!ParseOptionsUrl(extension, | |
137 options_ui->page, | |
138 OptionsUrlType::OPTIONS_UI_PAGE, | |
139 error, | |
140 &options_ui_page)) { | |
141 return scoped_ptr<OptionsPageInfo>(); | |
142 } | |
143 chrome_style = | |
144 options_ui->chrome_style.get() && *options_ui->chrome_style; | |
145 open_in_tab = options_ui->open_in_tab.get() && *options_ui->open_in_tab; | |
146 } else { | |
147 *error = base::ASCIIToUTF16(errors::kInvalidOptionsUIPage); | |
148 return scoped_ptr<OptionsPageInfo>(); | |
149 } | |
150 } | |
151 | |
152 // Parse the options_page entry | |
153 if (options_page_value) { | |
154 std::string options_page_string; | |
155 if (!options_page_value->GetAsString(&options_page_string)) { | |
156 *error = ASCIIToUTF16(errors::kInvalidOptionsPage); | |
157 return scoped_ptr<OptionsPageInfo>(); | |
158 } | |
159 if (!ParseOptionsUrl(extension, | |
160 options_page_string, | |
161 OptionsUrlType::OPTIONS_PAGE, | |
162 error, | |
163 &options_page)) { | |
164 return scoped_ptr<OptionsPageInfo>(); | |
165 } | |
166 } | |
167 return make_scoped_ptr(new OptionsPageInfo( | |
168 options_page, options_ui_page, chrome_style, open_in_tab)); | |
169 } | |
170 | |
171 OptionsPageManifestHandler::OptionsPageManifestHandler() { | |
172 } | |
173 | |
174 OptionsPageManifestHandler::~OptionsPageManifestHandler() { | |
175 } | |
176 | |
177 bool OptionsPageManifestHandler::Parse(Extension* extension, | |
not at google - send to devlin
2014/08/29 05:39:24
Generally speaking: everywhere, try to show instal
ericzeng
2014/08/29 16:52:22
Does you mean that in places where I set *error =
| |
178 base::string16* error) { | |
179 const base::Value* options_ui_value = NULL; | |
180 const base::Value* options_page_value = NULL; | |
181 if (!extension->manifest()->Get(keys::kOptionsUI, &options_ui_value) && | |
182 !extension->manifest()->Get(keys::kOptionsPage, &options_page_value)) { | |
183 // Note: extension->manifest()->Get returns false both when the value is | |
184 // malformed or missing. Therefore we can't determine which one is at fault, | |
185 // so for now return the error message for just options_page. | |
186 *error = base::ASCIIToUTF16(errors::kInvalidOptionsPage); | |
187 return false; | |
188 } | |
not at google - send to devlin
2014/08/29 05:39:24
Keeping the parse logic in OptionsPageInfo is good
ericzeng
2014/08/29 22:08:51
Done.
| |
189 | |
190 std::vector<InstallWarning> install_warnings; | |
191 | |
192 scoped_ptr<OptionsPageInfo> info = | |
193 OptionsPageInfo::FromValues(extension, | |
194 options_ui_value, | |
195 options_page_value, | |
196 &install_warnings, | |
197 error); | |
198 | |
199 if (!info) | |
200 return false; | |
201 | |
202 extension->AddInstallWarnings(install_warnings); | |
203 extension->SetManifestData(keys::kOptionsUI, info.release()); | |
204 return true; | |
205 } | |
206 | |
207 bool OptionsPageManifestHandler::Validate( | |
208 const Extension* extension, | |
209 std::string* error, | |
210 std::vector<InstallWarning>* warnings) const { | |
211 // Validate path to the options page. Don't check the URL for hosted apps, | |
212 // because they are expected to refer to an external URL. | |
213 if (!OptionsPageInfo::GetOptionsPage(extension).is_empty() && | |
not at google - send to devlin
2014/08/29 05:39:24
HasOptionsPage would look so much nicer in places
ericzeng
2014/08/29 22:08:51
Done.
| |
214 !extension->is_hosted_app()) { | |
215 const base::FilePath options_path = | |
216 extensions::file_util::ExtensionURLToRelativeFilePath( | |
217 OptionsPageInfo::GetOptionsPage(extension)); | |
218 const base::FilePath path = | |
not at google - send to devlin
2014/08/29 05:39:24
const base::FilePath&
ericzeng
2014/08/29 22:08:51
Done.
| |
219 extension->GetResource(options_path).GetFilePath(); | |
220 if (path.empty() || !base::PathExists(path)) { | |
221 *error = l10n_util::GetStringFUTF8(IDS_EXTENSION_LOAD_OPTIONS_PAGE_FAILED, | |
222 options_path.LossyDisplayName()); | |
223 return false; | |
224 } | |
225 } | |
226 return true; | |
227 } | |
228 | |
229 const std::vector<std::string> OptionsPageManifestHandler::Keys() const { | |
230 static const char* keys[] = {keys::kOptionsPage, keys::kOptionsUI}; | |
231 return std::vector<std::string>(keys, keys + arraysize(keys)); | |
232 } | |
233 | |
234 } // namespace extensions | |
OLD | NEW |