OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 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/background_info.h" |
| 6 |
| 7 #include "base/command_line.h" |
| 8 #include "base/lazy_instance.h" |
| 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/string_number_conversions.h" |
| 11 #include "base/utf_string_conversions.h" |
| 12 #include "chrome/common/chrome_switches.h" |
| 13 #include "chrome/common/extensions/extension_constants.h" |
| 14 #include "chrome/common/extensions/extension_manifest_constants.h" |
| 15 #include "chrome/common/extensions/permissions/api_permission_set.h" |
| 16 #include "extensions/common/error_utils.h" |
| 17 |
| 18 using base::DictionaryValue; |
| 19 namespace keys = extension_manifest_keys; |
| 20 namespace values = extension_manifest_values; |
| 21 namespace errors = extension_manifest_errors; |
| 22 |
| 23 namespace extensions { |
| 24 |
| 25 namespace { |
| 26 |
| 27 const char kBackground[] = "background"; |
| 28 |
| 29 static base::LazyInstance<BackgroundInfo> g_empty_background_info = |
| 30 LAZY_INSTANCE_INITIALIZER; |
| 31 |
| 32 const BackgroundInfo& GetBackgroundInfo(const Extension* extension) { |
| 33 BackgroundInfo* info = static_cast<BackgroundInfo*>( |
| 34 extension->GetManifestData(kBackground)); |
| 35 if (!info) |
| 36 return g_empty_background_info.Get(); |
| 37 return *info; |
| 38 } |
| 39 |
| 40 bool LoadBackgroundScripts(const Extension* extension, |
| 41 const std::string& key, |
| 42 string16* error, |
| 43 BackgroundInfo* info) { |
| 44 const Value* background_scripts_value = NULL; |
| 45 if (!extension->manifest()->Get(key, &background_scripts_value)) |
| 46 return true; |
| 47 |
| 48 CHECK(background_scripts_value); |
| 49 if (background_scripts_value->GetType() != Value::TYPE_LIST) { |
| 50 *error = ASCIIToUTF16(errors::kInvalidBackgroundScripts); |
| 51 return false; |
| 52 } |
| 53 |
| 54 const ListValue* background_scripts = NULL; |
| 55 background_scripts_value->GetAsList(&background_scripts); |
| 56 for (size_t i = 0; i < background_scripts->GetSize(); ++i) { |
| 57 std::string script; |
| 58 if (!background_scripts->GetString(i, &script)) { |
| 59 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 60 errors::kInvalidBackgroundScript, base::IntToString(i)); |
| 61 return false; |
| 62 } |
| 63 info->background_scripts.push_back(script); |
| 64 } |
| 65 |
| 66 return true; |
| 67 } |
| 68 |
| 69 bool LoadBackgroundPage(Extension* extension, |
| 70 const std::string& key, |
| 71 string16* error, |
| 72 BackgroundInfo* info) { |
| 73 const base::Value* background_page_value = NULL; |
| 74 if (!extension->manifest()->Get(key, &background_page_value)) |
| 75 return true; |
| 76 |
| 77 if (!info->background_scripts.empty()) { |
| 78 *error = ASCIIToUTF16(errors::kInvalidBackgroundCombination); |
| 79 return false; |
| 80 } |
| 81 |
| 82 std::string background_str; |
| 83 if (!background_page_value->GetAsString(&background_str)) { |
| 84 *error = ASCIIToUTF16(errors::kInvalidBackground); |
| 85 return false; |
| 86 } |
| 87 |
| 88 if (extension->is_hosted_app()) { |
| 89 info->background_url = GURL(background_str); |
| 90 |
| 91 if (!extension->initial_api_permissions()->count( |
| 92 APIPermission::kBackground)) { |
| 93 *error = ASCIIToUTF16(errors::kBackgroundPermissionNeeded); |
| 94 return false; |
| 95 } |
| 96 // Hosted apps require an absolute URL. |
| 97 if (!info->background_url.is_valid()) { |
| 98 *error = ASCIIToUTF16(errors::kInvalidBackgroundInHostedApp); |
| 99 return false; |
| 100 } |
| 101 |
| 102 if (!(info->background_url.SchemeIs("https") || |
| 103 (CommandLine::ForCurrentProcess()->HasSwitch( |
| 104 switches::kAllowHTTPBackgroundPage) && |
| 105 info->background_url.SchemeIs("http")))) { |
| 106 *error = ASCIIToUTF16(errors::kInvalidBackgroundInHostedApp); |
| 107 return false; |
| 108 } |
| 109 } else { |
| 110 info->background_url = extension->GetResourceURL(background_str); |
| 111 } |
| 112 |
| 113 return true; |
| 114 } |
| 115 |
| 116 bool LoadBackgroundPage(Extension* extension, |
| 117 string16* error, |
| 118 BackgroundInfo* info) { |
| 119 if (extension->is_platform_app()) { |
| 120 return LoadBackgroundPage( |
| 121 extension, keys::kPlatformAppBackgroundPage, error, info); |
| 122 } |
| 123 |
| 124 if (!LoadBackgroundPage( |
| 125 extension, keys::kBackgroundPage, error, info)) { |
| 126 return false; |
| 127 } |
| 128 if (info->background_url.is_empty()) { |
| 129 return LoadBackgroundPage( |
| 130 extension, keys::kBackgroundPageLegacy, error, info); |
| 131 } |
| 132 return true; |
| 133 } |
| 134 |
| 135 bool LoadBackgroundPersistent(const Extension* extension, |
| 136 string16* error, |
| 137 BackgroundInfo* info) { |
| 138 if (extension->is_platform_app()) { |
| 139 info->is_persistent = false; |
| 140 return true; |
| 141 } |
| 142 |
| 143 const Value* background_persistent = NULL; |
| 144 if (!extension->manifest()->Get(keys::kBackgroundPersistent, |
| 145 &background_persistent)) |
| 146 return true; |
| 147 |
| 148 if (!background_persistent->GetAsBoolean(&info->is_persistent)) { |
| 149 *error = ASCIIToUTF16(errors::kInvalidBackgroundPersistent); |
| 150 return false; |
| 151 } |
| 152 |
| 153 if (!info->has_background_page()) { |
| 154 *error = ASCIIToUTF16(errors::kInvalidBackgroundPersistentNoPage); |
| 155 return false; |
| 156 } |
| 157 |
| 158 return true; |
| 159 } |
| 160 |
| 161 bool LoadBackgroundAllowJSAccess(const Extension* extension, |
| 162 string16* error, |
| 163 BackgroundInfo* info) { |
| 164 const Value* allow_js_access = NULL; |
| 165 if (!extension->manifest()->Get(keys::kBackgroundAllowJsAccess, |
| 166 &allow_js_access)) |
| 167 return true; |
| 168 |
| 169 if (!allow_js_access->IsType(Value::TYPE_BOOLEAN) || |
| 170 !allow_js_access->GetAsBoolean(&info->allow_js_access)) { |
| 171 *error = ASCIIToUTF16(errors::kInvalidBackgroundAllowJsAccess); |
| 172 return false; |
| 173 } |
| 174 |
| 175 return true; |
| 176 } |
| 177 |
| 178 } // namespace |
| 179 |
| 180 BackgroundInfo::BackgroundInfo() |
| 181 : is_persistent(true), |
| 182 allow_js_access(true) { |
| 183 } |
| 184 |
| 185 BackgroundInfo::~BackgroundInfo() { |
| 186 } |
| 187 |
| 188 // static |
| 189 GURL BackgroundInfo::GetBackgroundURL(const Extension* extension) { |
| 190 const BackgroundInfo& info = GetBackgroundInfo(extension); |
| 191 if (info.background_scripts.empty()) |
| 192 return info.background_url; |
| 193 return extension->GetResourceURL( |
| 194 extension_filenames::kGeneratedBackgroundPageFilename); |
| 195 } |
| 196 |
| 197 // static |
| 198 const std::vector<std::string>& BackgroundInfo::GetBackgroundScripts( |
| 199 const Extension* extension) { |
| 200 return GetBackgroundInfo(extension).background_scripts; |
| 201 } |
| 202 |
| 203 // static |
| 204 bool BackgroundInfo::HasBackgroundPage(const Extension* extension) { |
| 205 return GetBackgroundInfo(extension).has_background_page(); |
| 206 } |
| 207 |
| 208 // static |
| 209 bool BackgroundInfo::AllowJSAccess(const Extension* extension) { |
| 210 return GetBackgroundInfo(extension).allow_js_access; |
| 211 } |
| 212 |
| 213 // static |
| 214 bool BackgroundInfo::HasPersistentBackgroundPage(const Extension* extension) { |
| 215 const BackgroundInfo& info = GetBackgroundInfo(extension); |
| 216 return info.has_background_page() && info.is_persistent; |
| 217 } |
| 218 |
| 219 // static |
| 220 bool BackgroundInfo::HasLazyBackgroundPage(const Extension* extension) { |
| 221 const BackgroundInfo& info = GetBackgroundInfo(extension); |
| 222 return info.has_background_page() && !info.is_persistent; |
| 223 } |
| 224 |
| 225 BackgroundManifestHandler::BackgroundManifestHandler() { |
| 226 } |
| 227 |
| 228 BackgroundManifestHandler::~BackgroundManifestHandler() { |
| 229 } |
| 230 |
| 231 bool BackgroundManifestHandler::Parse(Extension* extension, string16* error) { |
| 232 scoped_ptr<BackgroundInfo> info(new BackgroundInfo); |
| 233 const std::string& bg_scripts_key = extension->is_platform_app() ? |
| 234 keys::kPlatformAppBackgroundScripts : keys::kBackgroundScripts; |
| 235 if (!LoadBackgroundScripts(extension, bg_scripts_key, error, info.get()) || |
| 236 !LoadBackgroundPage(extension, error, info.get()) || |
| 237 !LoadBackgroundPersistent(extension, error, info.get()) || |
| 238 !LoadBackgroundAllowJSAccess(extension, error, info.get())) { |
| 239 return false; |
| 240 } |
| 241 |
| 242 extension->SetManifestData(kBackground, info.release()); |
| 243 return true; |
| 244 } |
| 245 |
| 246 // static |
| 247 const std::vector<std::string> BackgroundManifestHandler::keys() { |
| 248 static const char* keys[] = { |
| 249 keys::kBackgroundAllowJsAccess, |
| 250 keys::kBackgroundPage, |
| 251 keys::kBackgroundPageLegacy, |
| 252 keys::kBackgroundPersistent, |
| 253 keys::kBackgroundScripts, |
| 254 keys::kPlatformAppBackgroundPage, |
| 255 keys::kPlatformAppBackgroundScripts |
| 256 }; |
| 257 return std::vector<std::string>(keys, keys + arraysize(keys)); |
| 258 } |
| 259 |
| 260 } // extensions |
OLD | NEW |