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 3 // found in the LICENSE file. 4 5 #include "chrome/common/extensions/manifest_handlers/ui_overrides_handler.h" 6 7 #include "base/memory/scoped_ptr.h" 8 #include "base/strings/string_util.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "base/values.h" 11 #include "chrome/grit/generated_resources.h" 12 #include "extensions/common/error_utils.h" 13 #include "extensions/common/feature_switch.h" 14 #include "extensions/common/manifest_constants.h" 15 #include "extensions/common/permissions/manifest_permission.h" 16 #include "extensions/common/permissions/permissions_data.h" 17 #include "extensions/common/permissions/permissions_info.h" 18 #include "ipc/ipc_message.h" 19 #include "ui/base/l10n/l10n_util.h" 20 21 using extensions::api::manifest_types::ChromeUIOverrides; 22 23 namespace extensions { 24 25 // The manifest permission implementation supports a permission for overriding 26 // the bookmark UI. 27 class UIOverridesHandler::ManifestPermissionImpl : public ManifestPermission { 28 public: 29 explicit ManifestPermissionImpl(bool override_bookmarks_ui_permission) 30 : override_bookmarks_ui_permission_(override_bookmarks_ui_permission) {} 31 32 // extensions::ManifestPermission overrides. 33 virtual std::string name() const OVERRIDE { 34 return manifest_keys::kUIOverride; 35 } 36 37 virtual std::string id() const OVERRIDE { 38 return name(); 39 } 40 41 virtual bool HasMessages() const OVERRIDE { 42 return override_bookmarks_ui_permission_; 43 } 44 45 virtual PermissionMessages GetMessages() const OVERRIDE { 46 PermissionMessages result; 47 if (override_bookmarks_ui_permission_) { 48 result.push_back(PermissionMessage( 49 PermissionMessage::kOverrideBookmarksUI, 50 l10n_util::GetStringUTF16( 51 IDS_EXTENSION_PROMPT_WARNING_OVERRIDE_BOOKMARKS_UI))); 52 } 53 return result; 54 } 55 56 virtual bool FromValue(const base::Value* value) OVERRIDE { 57 return value && value->GetAsBoolean(&override_bookmarks_ui_permission_); 58 } 59 60 virtual scoped_ptr<base::Value> ToValue() const OVERRIDE { 61 return scoped_ptr<base::Value>( 62 new base::FundamentalValue(override_bookmarks_ui_permission_)).Pass(); 63 } 64 65 virtual ManifestPermission* Diff(const ManifestPermission* rhs) const 66 OVERRIDE { 67 const ManifestPermissionImpl* other = 68 static_cast<const ManifestPermissionImpl*>(rhs); 69 70 return scoped_ptr<ManifestPermissionImpl>(new ManifestPermissionImpl( 71 override_bookmarks_ui_permission_ && 72 !other->override_bookmarks_ui_permission_)).release(); 73 } 74 75 virtual ManifestPermission* Union(const ManifestPermission* rhs) const 76 OVERRIDE { 77 const ManifestPermissionImpl* other = 78 static_cast<const ManifestPermissionImpl*>(rhs); 79 80 return scoped_ptr<ManifestPermissionImpl>(new ManifestPermissionImpl( 81 override_bookmarks_ui_permission_ || 82 other->override_bookmarks_ui_permission_)).release(); 83 } 84 85 virtual ManifestPermission* Intersect(const ManifestPermission* rhs) const 86 OVERRIDE { 87 const ManifestPermissionImpl* other = 88 static_cast<const ManifestPermissionImpl*>(rhs); 89 90 return scoped_ptr<ManifestPermissionImpl>(new ManifestPermissionImpl( 91 override_bookmarks_ui_permission_ && 92 other->override_bookmarks_ui_permission_)).release(); 93 } 94 95 private: 96 bool override_bookmarks_ui_permission_; 97 }; 98 99 UIOverrides::UIOverrides() {} 100 101 UIOverrides::~UIOverrides() {} 102 103 const UIOverrides* UIOverrides::Get(const Extension* extension) { 104 return static_cast<UIOverrides*>( 105 extension->GetManifestData(manifest_keys::kUIOverride)); 106 } 107 108 bool UIOverrides::RemovesBookmarkButton(const Extension* extension) { 109 const UIOverrides* ui_overrides = Get(extension); 110 return ui_overrides && ui_overrides->bookmarks_ui && 111 ui_overrides->bookmarks_ui->remove_button && 112 *ui_overrides->bookmarks_ui->remove_button; 113 } 114 115 bool UIOverrides::RemovesBookmarkShortcut(const Extension* extension) { 116 const UIOverrides* ui_overrides = Get(extension); 117 return ui_overrides && ui_overrides->bookmarks_ui && 118 ui_overrides->bookmarks_ui->remove_bookmark_shortcut && 119 *ui_overrides->bookmarks_ui->remove_bookmark_shortcut; 120 } 121 122 bool UIOverrides::RemovesBookmarkOpenPagesShortcut(const Extension* extension) { 123 const UIOverrides* ui_overrides = Get(extension); 124 return ui_overrides && ui_overrides->bookmarks_ui && 125 ui_overrides->bookmarks_ui->remove_bookmark_open_pages_shortcut && 126 *ui_overrides->bookmarks_ui->remove_bookmark_open_pages_shortcut; 127 } 128 129 UIOverridesHandler::UIOverridesHandler() {} 130 131 UIOverridesHandler::~UIOverridesHandler() {} 132 133 bool UIOverridesHandler::Parse(Extension* extension, base::string16* error) { 134 const base::Value* dict = NULL; 135 CHECK(extension->manifest()->Get(manifest_keys::kUIOverride, &dict)); 136 scoped_ptr<ChromeUIOverrides> overrides( 137 ChromeUIOverrides::FromValue(*dict, error)); 138 if (!overrides) 139 return false; 140 141 scoped_ptr<UIOverrides> info(new UIOverrides); 142 info->bookmarks_ui.swap(overrides->bookmarks_ui); 143 if (!info->bookmarks_ui) { 144 *error = ErrorUtils::FormatErrorMessageUTF16( 145 manifest_errors::kInvalidEmptyDictionary, 146 manifest_keys::kUIOverride); 147 return false; 148 } 149 info->manifest_permission.reset(new ManifestPermissionImpl( 150 info->bookmarks_ui.get() != NULL)); 151 extension->SetManifestData(manifest_keys::kUIOverride, info.release()); 152 return true; 153 } 154 155 bool UIOverridesHandler::Validate(const Extension* extension, 156 std::string* error, 157 std::vector<InstallWarning>* warnings) const { 158 const UIOverrides* ui_overrides = UIOverrides::Get(extension); 159 160 if (ui_overrides && ui_overrides->bookmarks_ui) { 161 if (!FeatureSwitch::enable_override_bookmarks_ui()->IsEnabled()) { 162 warnings->push_back(InstallWarning( 163 ErrorUtils::FormatErrorMessage( 164 manifest_errors::kUnrecognizedManifestProperty, 165 manifest_keys::kBookmarkUI, 166 manifest_keys::kUIOverride))); 167 } 168 } 169 170 return true; 171 } 172 173 ManifestPermission* UIOverridesHandler::CreatePermission() { 174 return new ManifestPermissionImpl(false); 175 } 176 177 ManifestPermission* UIOverridesHandler::CreateInitialRequiredPermission( 178 const Extension* extension) { 179 const UIOverrides* data = UIOverrides::Get(extension); 180 if (data) 181 return data->manifest_permission->Clone(); 182 return NULL; 183 } 184 const std::vector<std::string> UIOverridesHandler::Keys() const { 185 return SingleKey(manifest_keys::kUIOverride); 186 } 187 188 } // namespace extensions 189