| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/common/extensions/manifest_handlers/ui_overrides_handler.h" | 5 #include "chrome/common/extensions/manifest_handlers/ui_overrides_handler.h" |
| 6 | 6 |
| 7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
| 8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 9 #include "base/strings/stringprintf.h" | |
| 10 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 11 #include "base/values.h" | 10 #include "base/values.h" |
| 12 #include "chrome/common/extensions/extension_messages.h" | 11 #include "chrome/common/extensions/extension_messages.h" |
| 13 #include "chrome/common/extensions/permissions/settings_override_permission.h" | |
| 14 #include "extensions/common/error_utils.h" | 12 #include "extensions/common/error_utils.h" |
| 15 #include "extensions/common/feature_switch.h" | 13 #include "extensions/common/feature_switch.h" |
| 16 #include "extensions/common/manifest_constants.h" | 14 #include "extensions/common/manifest_constants.h" |
| 17 #include "extensions/common/permissions/api_permission_set.h" | |
| 18 #include "extensions/common/permissions/manifest_permission.h" | 15 #include "extensions/common/permissions/manifest_permission.h" |
| 19 #include "extensions/common/permissions/permissions_data.h" | 16 #include "extensions/common/permissions/permissions_data.h" |
| 20 #include "extensions/common/permissions/permissions_info.h" | 17 #include "extensions/common/permissions/permissions_info.h" |
| 21 #include "grit/generated_resources.h" | 18 #include "grit/generated_resources.h" |
| 22 #include "ipc/ipc_message.h" | 19 #include "ipc/ipc_message.h" |
| 23 #include "ui/base/l10n/l10n_util.h" | 20 #include "ui/base/l10n/l10n_util.h" |
| 24 #include "url/gurl.h" | |
| 25 | 21 |
| 26 using extensions::api::manifest_types::ChromeSettingsOverrides; | 22 using extensions::api::manifest_types::ChromeUIOverrides; |
| 27 | 23 |
| 28 namespace extensions { | 24 namespace extensions { |
| 29 namespace { | |
| 30 | |
| 31 const char* kWwwPrefix = "www."; | |
| 32 | |
| 33 scoped_ptr<GURL> CreateManifestURL(const std::string& url) { | |
| 34 scoped_ptr<GURL> manifest_url(new GURL(url)); | |
| 35 if (!manifest_url->is_valid() || | |
| 36 !manifest_url->SchemeIsHTTPOrHTTPS()) | |
| 37 return scoped_ptr<GURL>(); | |
| 38 return manifest_url.Pass(); | |
| 39 } | |
| 40 | |
| 41 scoped_ptr<GURL> ParseHomepage(const ChromeSettingsOverrides& overrides, | |
| 42 base::string16* error) { | |
| 43 if (!overrides.homepage) | |
| 44 return scoped_ptr<GURL>(); | |
| 45 scoped_ptr<GURL> manifest_url = CreateManifestURL(*overrides.homepage); | |
| 46 if (!manifest_url) { | |
| 47 *error = extensions::ErrorUtils::FormatErrorMessageUTF16( | |
| 48 manifest_errors::kInvalidHomepageOverrideURL, *overrides.homepage); | |
| 49 } | |
| 50 return manifest_url.Pass(); | |
| 51 } | |
| 52 | |
| 53 std::vector<GURL> ParseStartupPage(const ChromeSettingsOverrides& overrides, | |
| 54 base::string16* error) { | |
| 55 std::vector<GURL> urls; | |
| 56 if (!overrides.startup_pages) | |
| 57 return urls; | |
| 58 | |
| 59 for (std::vector<std::string>::const_iterator i = | |
| 60 overrides.startup_pages->begin(); i != overrides.startup_pages->end(); | |
| 61 ++i) { | |
| 62 scoped_ptr<GURL> manifest_url = CreateManifestURL(*i); | |
| 63 if (!manifest_url) { | |
| 64 *error = extensions::ErrorUtils::FormatErrorMessageUTF16( | |
| 65 manifest_errors::kInvalidStartupOverrideURL, *i); | |
| 66 } else { | |
| 67 urls.push_back(GURL()); | |
| 68 urls.back().Swap(manifest_url.get()); | |
| 69 } | |
| 70 } | |
| 71 return urls; | |
| 72 } | |
| 73 | |
| 74 scoped_ptr<ChromeSettingsOverrides::Search_provider> ParseSearchEngine( | |
| 75 ChromeSettingsOverrides* overrides, | |
| 76 base::string16* error) { | |
| 77 if (!overrides->search_provider) | |
| 78 return scoped_ptr<ChromeSettingsOverrides::Search_provider>(); | |
| 79 if (!CreateManifestURL(overrides->search_provider->favicon_url)) { | |
| 80 *error = extensions::ErrorUtils::FormatErrorMessageUTF16( | |
| 81 manifest_errors::kInvalidSearchEngineURL, | |
| 82 overrides->search_provider->favicon_url); | |
| 83 return scoped_ptr<ChromeSettingsOverrides::Search_provider>(); | |
| 84 } | |
| 85 if (!CreateManifestURL(overrides->search_provider->search_url)) { | |
| 86 *error = extensions::ErrorUtils::FormatErrorMessageUTF16( | |
| 87 manifest_errors::kInvalidSearchEngineURL, | |
| 88 overrides->search_provider->search_url); | |
| 89 return scoped_ptr<ChromeSettingsOverrides::Search_provider>(); | |
| 90 } | |
| 91 return overrides->search_provider.Pass(); | |
| 92 } | |
| 93 | |
| 94 // A www. prefix is not informative and thus not worth the limited real estate | |
| 95 // in the permissions UI. | |
| 96 std::string RemoveWwwPrefix(const std::string& url) { | |
| 97 if (StartsWithASCII(url, kWwwPrefix, false)) | |
| 98 return url.substr(strlen(kWwwPrefix)); | |
| 99 return url; | |
| 100 } | |
| 101 | |
| 102 } // namespace | |
| 103 | 25 |
| 104 // The manifest permission implementation supports a permission for overriding | 26 // The manifest permission implementation supports a permission for overriding |
| 105 // the bookmark UI. | 27 // the bookmark UI. |
| 106 class SettingsOverridesHandler::ManifestPermissionImpl | 28 class UIOverridesHandler::ManifestPermissionImpl : public ManifestPermission { |
| 107 : public ManifestPermission { | |
| 108 public: | 29 public: |
| 109 explicit ManifestPermissionImpl(bool override_bookmarks_ui_permission) | 30 explicit ManifestPermissionImpl(bool override_bookmarks_ui_permission) |
| 110 : override_bookmarks_ui_permission_(override_bookmarks_ui_permission) {} | 31 : override_bookmarks_ui_permission_(override_bookmarks_ui_permission) {} |
| 111 | 32 |
| 112 // extensions::ManifestPermission overrides. | 33 // extensions::ManifestPermission overrides. |
| 113 virtual std::string name() const OVERRIDE { | 34 virtual std::string name() const OVERRIDE { |
| 114 return manifest_keys::kSettingsOverride; | 35 return manifest_keys::kUIOverride; |
| 115 } | 36 } |
| 116 | 37 |
| 117 virtual std::string id() const OVERRIDE { | 38 virtual std::string id() const OVERRIDE { |
| 118 return name(); | 39 return name(); |
| 119 } | 40 } |
| 120 | 41 |
| 121 virtual bool HasMessages() const OVERRIDE { | 42 virtual bool HasMessages() const OVERRIDE { |
| 122 return override_bookmarks_ui_permission_; | 43 return override_bookmarks_ui_permission_; |
| 123 } | 44 } |
| 124 | 45 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 } | 124 } |
| 204 | 125 |
| 205 virtual void Log(std::string* log) const OVERRIDE { | 126 virtual void Log(std::string* log) const OVERRIDE { |
| 206 IPC::LogParam(override_bookmarks_ui_permission_, log); | 127 IPC::LogParam(override_bookmarks_ui_permission_, log); |
| 207 } | 128 } |
| 208 | 129 |
| 209 private: | 130 private: |
| 210 bool override_bookmarks_ui_permission_; | 131 bool override_bookmarks_ui_permission_; |
| 211 }; | 132 }; |
| 212 | 133 |
| 213 SettingsOverrides::SettingsOverrides() {} | 134 UIOverrides::UIOverrides() {} |
| 214 | 135 |
| 215 SettingsOverrides::~SettingsOverrides() {} | 136 UIOverrides::~UIOverrides() {} |
| 216 | 137 |
| 217 const SettingsOverrides* SettingsOverrides::Get( | 138 const UIOverrides* UIOverrides::Get(const Extension* extension) { |
| 218 const Extension* extension) { | 139 return static_cast<UIOverrides*>( |
| 219 return static_cast<SettingsOverrides*>( | 140 extension->GetManifestData(manifest_keys::kUIOverride)); |
| 220 extension->GetManifestData(manifest_keys::kSettingsOverride)); | |
| 221 } | 141 } |
| 222 | 142 |
| 223 bool SettingsOverrides::RemovesBookmarkButton( | 143 bool UIOverrides::RemovesBookmarkButton(const UIOverrides& ui_overrides) { |
| 224 const SettingsOverrides& settings_overrides) { | 144 return ui_overrides.bookmarks_ui && |
| 225 return settings_overrides.bookmarks_ui && | 145 ui_overrides.bookmarks_ui->remove_button && |
| 226 settings_overrides.bookmarks_ui->remove_button && | 146 *ui_overrides.bookmarks_ui->remove_button; |
| 227 *settings_overrides.bookmarks_ui->remove_button; | |
| 228 } | 147 } |
| 229 | 148 |
| 230 bool SettingsOverrides::RemovesBookmarkShortcut( | 149 bool UIOverrides::RemovesBookmarkShortcut(const UIOverrides& ui_overrides) { |
| 231 const SettingsOverrides& settings_overrides) { | 150 return ui_overrides.bookmarks_ui && |
| 232 return settings_overrides.bookmarks_ui && | 151 ui_overrides.bookmarks_ui->remove_bookmark_shortcut && |
| 233 settings_overrides.bookmarks_ui->remove_bookmark_shortcut && | 152 *ui_overrides.bookmarks_ui->remove_bookmark_shortcut; |
| 234 *settings_overrides.bookmarks_ui->remove_bookmark_shortcut; | |
| 235 } | 153 } |
| 236 | 154 |
| 237 SettingsOverridesHandler::SettingsOverridesHandler() {} | 155 UIOverridesHandler::UIOverridesHandler() {} |
| 238 | 156 |
| 239 SettingsOverridesHandler::~SettingsOverridesHandler() {} | 157 UIOverridesHandler::~UIOverridesHandler() {} |
| 240 | 158 |
| 241 bool SettingsOverridesHandler::Parse(Extension* extension, | 159 bool UIOverridesHandler::Parse(Extension* extension, base::string16* error) { |
| 242 base::string16* error) { | |
| 243 const base::Value* dict = NULL; | 160 const base::Value* dict = NULL; |
| 244 CHECK(extension->manifest()->Get(manifest_keys::kSettingsOverride, &dict)); | 161 CHECK(extension->manifest()->Get(manifest_keys::kUIOverride, &dict)); |
| 245 scoped_ptr<ChromeSettingsOverrides> settings( | 162 scoped_ptr<ChromeUIOverrides> overrides( |
| 246 ChromeSettingsOverrides::FromValue(*dict, error)); | 163 ChromeUIOverrides::FromValue(*dict, error)); |
| 247 if (!settings) | 164 if (!overrides) |
| 248 return false; | 165 return false; |
| 249 | 166 |
| 250 scoped_ptr<SettingsOverrides> info(new SettingsOverrides); | 167 scoped_ptr<UIOverrides> info(new UIOverrides); |
| 251 info->bookmarks_ui.swap(settings->bookmarks_ui); | 168 info->bookmarks_ui.swap(overrides->bookmarks_ui); |
| 252 // Support backward compatibility for deprecated key | 169 if (!info->bookmarks_ui) { |
| 253 // chrome_settings_overrides.bookmarks_ui.hide_bookmark_button. | 170 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 254 if (info->bookmarks_ui && !info->bookmarks_ui->remove_button && | 171 manifest_errors::kInvalidEmptyDictionary, |
| 255 info->bookmarks_ui->hide_bookmark_button) { | 172 manifest_keys::kUIOverride); |
| 256 info->bookmarks_ui->remove_button.reset( | |
| 257 new bool(*info->bookmarks_ui->hide_bookmark_button)); | |
| 258 } | |
| 259 info->homepage = ParseHomepage(*settings, error); | |
| 260 info->search_engine = ParseSearchEngine(settings.get(), error); | |
| 261 info->startup_pages = ParseStartupPage(*settings, error); | |
| 262 if (!info->bookmarks_ui && !info->homepage && | |
| 263 !info->search_engine && info->startup_pages.empty()) { | |
| 264 *error = | |
| 265 base::ASCIIToUTF16(manifest_errors::kInvalidEmptySettingsOverrides); | |
| 266 return false; | 173 return false; |
| 267 } | 174 } |
| 268 info->manifest_permission.reset(new ManifestPermissionImpl( | 175 info->manifest_permission.reset(new ManifestPermissionImpl( |
| 269 SettingsOverrides::RemovesBookmarkButton(*info))); | 176 UIOverrides::RemovesBookmarkButton(*info))); |
| 270 | 177 extension->SetManifestData(manifest_keys::kUIOverride, info.release()); |
| 271 APIPermissionSet* permission_set = | |
| 272 PermissionsData::GetInitialAPIPermissions(extension); | |
| 273 DCHECK(permission_set); | |
| 274 if (info->search_engine) { | |
| 275 permission_set->insert(new SettingsOverrideAPIPermission( | |
| 276 PermissionsInfo::GetInstance()->GetByID(APIPermission::kSearchProvider), | |
| 277 RemoveWwwPrefix(CreateManifestURL(info->search_engine->search_url)-> | |
| 278 GetOrigin().host()))); | |
| 279 } | |
| 280 if (!info->startup_pages.empty()) { | |
| 281 permission_set->insert(new SettingsOverrideAPIPermission( | |
| 282 PermissionsInfo::GetInstance()->GetByID(APIPermission::kStartupPages), | |
| 283 // We only support one startup page even though the type of the manifest | |
| 284 // property is a list, only the first one is used. | |
| 285 RemoveWwwPrefix(info->startup_pages[0].GetContent()))); | |
| 286 } | |
| 287 if (info->homepage) { | |
| 288 permission_set->insert(new SettingsOverrideAPIPermission( | |
| 289 PermissionsInfo::GetInstance()->GetByID(APIPermission::kHomepage), | |
| 290 RemoveWwwPrefix(info->homepage.get()->GetContent()))); | |
| 291 } | |
| 292 extension->SetManifestData(manifest_keys::kSettingsOverride, | |
| 293 info.release()); | |
| 294 return true; | 178 return true; |
| 295 } | 179 } |
| 296 | 180 |
| 297 bool SettingsOverridesHandler::Validate( | 181 bool UIOverridesHandler::Validate(const Extension* extension, |
| 298 const Extension* extension, | 182 std::string* error, |
| 299 std::string* error, | 183 std::vector<InstallWarning>* warnings) const { |
| 300 std::vector<InstallWarning>* warnings) const { | 184 const UIOverrides* ui_overrides = UIOverrides::Get(extension); |
| 301 const SettingsOverrides* settings_overrides = | |
| 302 SettingsOverrides::Get(extension); | |
| 303 | 185 |
| 304 if (settings_overrides && settings_overrides->bookmarks_ui) { | 186 if (ui_overrides && ui_overrides->bookmarks_ui) { |
| 305 if (!FeatureSwitch::enable_override_bookmarks_ui()->IsEnabled()) { | 187 if (!FeatureSwitch::enable_override_bookmarks_ui()->IsEnabled()) { |
| 306 warnings->push_back(InstallWarning( | 188 warnings->push_back(InstallWarning( |
| 307 ErrorUtils::FormatErrorMessage( | 189 ErrorUtils::FormatErrorMessage( |
| 308 manifest_errors::kUnrecognizedManifestKey, | 190 manifest_errors::kUnrecognizedManifestKey, |
| 309 manifest_keys::kBookmarkUI))); | 191 manifest_keys::kBookmarkUI))); |
| 310 } else if (settings_overrides->bookmarks_ui->hide_bookmark_button) { | |
| 311 warnings->push_back(InstallWarning( | |
| 312 ErrorUtils::FormatErrorMessage( | |
| 313 manifest_errors::kKeyIsDeprecatedWithReplacement, | |
| 314 manifest_keys::kHideBookmarkButton, | |
| 315 manifest_keys::kRemoveButton))); | |
| 316 } | 192 } |
| 317 } | 193 } |
| 318 | 194 |
| 319 return true; | 195 return true; |
| 320 } | 196 } |
| 321 | 197 |
| 322 ManifestPermission* SettingsOverridesHandler::CreatePermission() { | 198 ManifestPermission* UIOverridesHandler::CreatePermission() { |
| 323 return new ManifestPermissionImpl(false); | 199 return new ManifestPermissionImpl(false); |
| 324 } | 200 } |
| 325 | 201 |
| 326 ManifestPermission* SettingsOverridesHandler::CreateInitialRequiredPermission( | 202 ManifestPermission* UIOverridesHandler::CreateInitialRequiredPermission( |
| 327 const Extension* extension) { | 203 const Extension* extension) { |
| 328 const SettingsOverrides* data = SettingsOverrides::Get(extension); | 204 const UIOverrides* data = UIOverrides::Get(extension); |
| 329 if (data) | 205 if (data) |
| 330 return data->manifest_permission->Clone(); | 206 return data->manifest_permission->Clone(); |
| 331 return NULL; | 207 return NULL; |
| 332 } | 208 } |
| 333 const std::vector<std::string> SettingsOverridesHandler::Keys() const { | 209 const std::vector<std::string> UIOverridesHandler::Keys() const { |
| 334 return SingleKey(manifest_keys::kSettingsOverride); | 210 return SingleKey(manifest_keys::kUIOverride); |
| 335 } | 211 } |
| 336 | 212 |
| 337 } // namespace extensions | 213 } // namespace extensions |
| OLD | NEW |