1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 28ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Use of this source code is governed by a BSD-style license that can be 38ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// found in the LICENSE file. 48ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 58ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "chrome/common/extensions/extension.h" 68ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 78ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include <algorithm> 88ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 98ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "base/base64.h" 108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "base/basictypes.h" 118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "base/command_line.h" 128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "base/file_path.h" 138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "base/file_util.h" 148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "base/i18n/rtl.h" 158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "base/logging.h" 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h" 178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "base/stl_util-inl.h" 1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/string16.h" 198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "base/string_number_conversions.h" 208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "base/utf_string_conversions.h" 218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "base/values.h" 228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "base/version.h" 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/sha2.h" 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/third_party/nss/blapi.h" 258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "chrome/common/chrome_constants.h" 268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "chrome/common/chrome_switches.h" 278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "chrome/common/chrome_version_info.h" 288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "chrome/common/extensions/extension_action.h" 298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "chrome/common/extensions/extension_constants.h" 308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "chrome/common/extensions/extension_error_utils.h" 318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "chrome/common/extensions/extension_l10n_util.h" 328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "chrome/common/extensions/extension_resource.h" 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/common/extensions/extension_sidebar_defaults.h" 3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/common/extensions/extension_sidebar_utils.h" 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/extensions/file_browser_handler.h" 368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "chrome/common/extensions/user_script.h" 378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "chrome/common/url_constants.h" 38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "googleurl/src/url_util.h" 398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "grit/chromium_strings.h" 408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "grit/generated_resources.h" 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "grit/theme_resources.h" 42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/base/registry_controlled_domain.h" 438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "third_party/skia/include/core/SkBitmap.h" 4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/base/resource/resource_bundle.h" 468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#include "webkit/glue/image_decoder.h" 478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsennamespace keys = extension_manifest_keys; 498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsennamespace values = extension_manifest_values; 508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsennamespace errors = extension_manifest_errors; 518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsennamespace { 538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst int kPEMOutputColumns = 65; 558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// KEY MARKERS 578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char kKeyBeginHeaderMarker[] = "-----BEGIN"; 588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char kKeyBeginFooterMarker[] = "-----END"; 598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char kKeyInfoEndMarker[] = "KEY-----"; 608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char kPublic[] = "PUBLIC"; 618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char kPrivate[] = "PRIVATE"; 628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst int kRSAKeySize = 1024; 648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Converts a normal hexadecimal string into the alphabet used by extensions. 668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// We use the characters 'a'-'p' instead of '0'-'f' to avoid ever having a 678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// completely numeric host, since some software interprets that as an IP 688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// address. 698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenstatic void ConvertHexadecimalToIDAlphabet(std::string* id) { 708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < id->size(); ++i) { 718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen int val; 72513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (base::HexStringToInt(id->begin() + i, id->begin() + i + 1, &val)) 738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen (*id)[i] = val + 'a'; 748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen else 758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen (*id)[i] = 'a'; 768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// These keys are allowed by all crx files (apps, extensions, themes, etc). 808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenstatic const char* kBaseCrxKeys[] = { 818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen keys::kCurrentLocale, 828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen keys::kDefaultLocale, 838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen keys::kDescription, 848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen keys::kIcons, 858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen keys::kName, 868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen keys::kPublicKey, 878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen keys::kSignature, 888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen keys::kVersion, 898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen keys::kUpdateURL 908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}; 918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool IsBaseCrxKey(const std::string& key) { 938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < arraysize(kBaseCrxKeys); ++i) { 948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (key == kBaseCrxKeys[i]) 958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 1008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Constant used to represent an undefined l10n message id. 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst int kUndefinedMessageId = -1; 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Names of API modules that do not require a permission. 1058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char kBrowserActionModuleName[] = "browserAction"; 1068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char kBrowserActionsModuleName[] = "browserActions"; 1078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char kDevToolsModuleName[] = "devtools"; 1088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char kExtensionModuleName[] = "extension"; 1098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char kI18NModuleName[] = "i18n"; 1104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst char kOmniboxModuleName[] = "omnibox"; 1118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char kPageActionModuleName[] = "pageAction"; 1128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char kPageActionsModuleName[] = "pageActions"; 1138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char kTestModuleName[] = "test"; 1148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Names of modules that can be used without listing it in the permissions 1168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// section of the manifest. 1178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char* kNonPermissionModuleNames[] = { 1188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen kBrowserActionModuleName, 1198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen kBrowserActionsModuleName, 1208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen kDevToolsModuleName, 1218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen kExtensionModuleName, 1228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen kI18NModuleName, 1234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch kOmniboxModuleName, 1248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen kPageActionModuleName, 1258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen kPageActionsModuleName, 1268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen kTestModuleName 1278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}; 1288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst size_t kNumNonPermissionModuleNames = 1298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen arraysize(kNonPermissionModuleNames); 1308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Names of functions (within modules requiring permissions) that can be used 1328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// without asking for the module permission. In other words, functions you can 1338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// use with no permissions specified. 1348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char* kNonPermissionFunctionNames[] = { 1358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen "tabs.create", 1368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen "tabs.update" 1378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}; 1388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst size_t kNumNonPermissionFunctionNames = 1398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen arraysize(kNonPermissionFunctionNames); 1408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// A singleton object containing global data needed by the extension objects. 142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass ExtensionConfig { 1438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen public: 14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen static ExtensionConfig* GetInstance() { 145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return Singleton<ExtensionConfig>::get(); 1468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 1478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Extension::PermissionMessage::MessageId GetPermissionMessageId( 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& permission) { 1508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return Extension::kPermissions[permission_map_[permission]].message_id; 1518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 1528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Extension::ScriptingWhitelist* whitelist() { return &scripting_whitelist_; } 154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen private: 156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick friend struct DefaultSingletonTraits<ExtensionConfig>; 1578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ExtensionConfig() { 1598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < Extension::kNumPermissions; ++i) 1608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen permission_map_[Extension::kPermissions[i].name] = i; 1618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen }; 1628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ~ExtensionConfig() { } 1648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::map<const std::string, size_t> permission_map_; 1668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 167731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // A whitelist of extensions that can script anywhere. Do not add to this 168731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // list (except in tests) without consulting the Extensions team first. 169731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Note: Component extensions have this right implicitly and do not need to be 170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // added to this list. 171731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Extension::ScriptingWhitelist scripting_whitelist_; 172731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}; 1738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Aliased to kTabPermission for purposes of API checks, but not allowed 1758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// in the permissions field of the manifest. 1768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenstatic const char kWindowPermission[] = "windows"; 1778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Rank extension locations in a way that allows 179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Extension::GetHigherPriorityLocation() to compare locations. 180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// An extension installed from two locations will have the location 181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// with the higher rank, as returned by this function. The actual 182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// integer values may change, and should never be persisted. 183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint GetLocationRank(Extension::Location location) { 184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const int kInvalidRank = -1; 185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int rank = kInvalidRank; // Will CHECK that rank is not kInvalidRank. 186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen switch (location) { 188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Component extensions can not be overriden by any other type. 189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case Extension::COMPONENT: 190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rank = 6; 191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Policy controlled extensions may not be overridden by any type 194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // that is not part of chrome. 195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case Extension::EXTERNAL_POLICY_DOWNLOAD: 196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rank = 5; 197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // A developer-loaded extension should override any installed type 200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // that a user can disable. 201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case Extension::LOAD: 202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rank = 4; 203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The relative priority of various external sources is not important, 206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // but having some order ensures deterministic behavior. 207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case Extension::EXTERNAL_REGISTRY: 208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rank = 3; 209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case Extension::EXTERNAL_PREF: 212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rank = 2; 213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case Extension::EXTERNAL_PREF_DOWNLOAD: 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rank = 1; 217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // User installed extensions are overridden by any external type. 220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case Extension::INTERNAL: 221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rank = 0; 222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen default: 225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED() << "Need to add new extension locaton " << location; 226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CHECK(rank != kInvalidRank); 229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return rank; 230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 2328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} // namespace 2338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst FilePath::CharType Extension::kManifestFilename[] = 2358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen FILE_PATH_LITERAL("manifest.json"); 2368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst FilePath::CharType Extension::kLocaleFolder[] = 2378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen FILE_PATH_LITERAL("_locales"); 2388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst FilePath::CharType Extension::kMessagesFilename[] = 2398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen FILE_PATH_LITERAL("messages.json"); 2408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#if defined(OS_WIN) 2428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kExtensionRegistryPath[] = 2438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen "Software\\Google\\Chrome\\Extensions"; 2448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#endif 2458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// first 16 bytes of SHA256 hashed public key. 2478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst size_t Extension::kIdSize = 16; 2488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kMimeType[] = "application/x-chrome-extension"; 2508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst int Extension::kIconSizes[] = { 2528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen EXTENSION_ICON_LARGE, 2538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen EXTENSION_ICON_MEDIUM, 2548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen EXTENSION_ICON_SMALL, 2558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen EXTENSION_ICON_SMALLISH, 2568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen EXTENSION_ICON_BITTY 2578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}; 2588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst int Extension::kPageActionIconMaxSize = 19; 2608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst int Extension::kBrowserActionIconMaxSize = 19; 26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int Extension::kSidebarIconMaxSize = 16; 2628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Explicit permissions -- permission declaration required. 2648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kBackgroundPermission[] = "background"; 2658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kBookmarkPermission[] = "bookmarks"; 266dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst char Extension::kContextMenusPermission[] = "contextMenus"; 267dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenconst char Extension::kContentSettingsPermission[] = "contentSettings"; 2688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kCookiePermission[] = "cookies"; 269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char Extension::kChromeosInfoPrivatePermissions[] = "chromeosInfoPrivate"; 270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char Extension::kDebuggerPermission[] = "debugger"; 2718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kExperimentalPermission[] = "experimental"; 272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char Extension::kFileBrowserHandlerPermission[] = "fileBrowserHandler"; 273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char Extension::kFileBrowserPrivatePermission[] = "fileBrowserPrivate"; 2748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kGeolocationPermission[] = "geolocation"; 2758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kHistoryPermission[] = "history"; 2768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kIdlePermission[] = "idle"; 277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst char Extension::kManagementPermission[] = "management"; 2788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kNotificationPermission[] = "notifications"; 2798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kProxyPermission[] = "proxy"; 2808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kTabPermission[] = "tabs"; 2818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kUnlimitedStoragePermission[] = "unlimitedStorage"; 2828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kWebstorePrivatePermission[] = "webstorePrivate"; 2838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// In general, all permissions should have an install message. 2858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// See ExtensionsTest.PermissionMessages for an explanation of each 2868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// exception. 2878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst Extension::Permission Extension::kPermissions[] = { 288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kBackgroundPermission, PermissionMessage::ID_NONE }, 289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kBookmarkPermission, PermissionMessage::ID_BOOKMARKS }, 290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kChromeosInfoPrivatePermissions, PermissionMessage::ID_NONE }, 291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kContentSettingsPermission, PermissionMessage::ID_NONE }, 292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kContextMenusPermission, PermissionMessage::ID_NONE }, 293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kCookiePermission, PermissionMessage::ID_NONE }, 294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kDebuggerPermission, PermissionMessage::ID_DEBUGGER }, 295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kExperimentalPermission, PermissionMessage::ID_NONE }, 296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kFileBrowserHandlerPermission, PermissionMessage::ID_NONE }, 297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kFileBrowserPrivatePermission, PermissionMessage::ID_NONE }, 298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kGeolocationPermission, PermissionMessage::ID_GEOLOCATION }, 299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kIdlePermission, PermissionMessage::ID_NONE }, 300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kHistoryPermission, PermissionMessage::ID_BROWSING_HISTORY }, 301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kManagementPermission, PermissionMessage::ID_MANAGEMENT }, 302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kNotificationPermission, PermissionMessage::ID_NONE }, 303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kProxyPermission, PermissionMessage::ID_NONE }, 304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kTabPermission, PermissionMessage::ID_TABS }, 305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kUnlimitedStoragePermission, PermissionMessage::ID_NONE }, 306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen { kWebstorePrivatePermission, PermissionMessage::ID_NONE } 3078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}; 3088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst size_t Extension::kNumPermissions = 3098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen arraysize(Extension::kPermissions); 3108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 3118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char* const Extension::kHostedAppPermissionNames[] = { 3128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Extension::kBackgroundPermission, 3138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Extension::kGeolocationPermission, 3148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Extension::kNotificationPermission, 3158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Extension::kUnlimitedStoragePermission, 3168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Extension::kWebstorePrivatePermission, 3178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen}; 3188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst size_t Extension::kNumHostedAppPermissions = 3198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen arraysize(Extension::kHostedAppPermissionNames); 3208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst char* const Extension::kComponentPrivatePermissionNames[] = { 322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Extension::kFileBrowserPrivatePermission, 323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Extension::kWebstorePrivatePermission, 324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Extension::kChromeosInfoPrivatePermissions, 325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}; 326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst size_t Extension::kNumComponentPrivatePermissions = 327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen arraysize(Extension::kComponentPrivatePermissionNames); 328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 3298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// We purposefully don't put this into kPermissionNames. 3308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst char Extension::kOldUnlimitedStoragePermission[] = "unlimited_storage"; 3318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 332201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst int Extension::kValidWebExtentSchemes = 333201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS; 334201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 335201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst int Extension::kValidHostPermissionSchemes = 336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UserScript::kValidUserScriptSchemes | URLPattern::SCHEME_CHROMEUI; 337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// 339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// PermissionMessage 340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// 341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenExtension::PermissionMessage Extension::PermissionMessage::CreateFromMessageId( 344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Extension::PermissionMessage::MessageId message_id) { 345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_GT(PermissionMessage::ID_NONE, PermissionMessage::ID_UNKNOWN); 346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (message_id <= ID_NONE) 347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return PermissionMessage(message_id, string16()); 348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen string16 message = l10n_util::GetStringUTF16(kMessageIds[message_id]); 350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return PermissionMessage(message_id, message); 351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenExtension::PermissionMessage Extension::PermissionMessage::CreateFromHostList( 355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::vector<std::string> hosts) { 356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CHECK(hosts.size() > 0); 357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MessageId message_id; 359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen string16 message; 360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen switch (hosts.size()) { 361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case 1: 362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen message_id = ID_HOSTS_1; 363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen message = l10n_util::GetStringFUTF16(kMessageIds[message_id], 364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UTF8ToUTF16(hosts[0])); 365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case 2: 367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen message_id = ID_HOSTS_2; 368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen message = l10n_util::GetStringFUTF16(kMessageIds[message_id], 369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UTF8ToUTF16(hosts[0]), 370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UTF8ToUTF16(hosts[1])); 371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case 3: 373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen message_id = ID_HOSTS_3; 374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen message = l10n_util::GetStringFUTF16(kMessageIds[message_id], 375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UTF8ToUTF16(hosts[0]), 376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UTF8ToUTF16(hosts[1]), 377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UTF8ToUTF16(hosts[2])); 378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen default: 380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen message_id = ID_HOSTS_4_OR_MORE; 381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen message = l10n_util::GetStringFUTF16( 382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen kMessageIds[message_id], 383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UTF8ToUTF16(hosts[0]), 384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen UTF8ToUTF16(hosts[1]), 385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::IntToString16(hosts.size() - 2)); 386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return PermissionMessage(message_id, message); 390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenExtension::PermissionMessage::PermissionMessage( 393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Extension::PermissionMessage::MessageId message_id, string16 message) 394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : message_id_(message_id), 395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen message_(message) { 396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst int Extension::PermissionMessage::kMessageIds[] = { 399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen kUndefinedMessageId, // "unknown" 400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen kUndefinedMessageId, // "none" 401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IDS_EXTENSION_PROMPT_WARNING_BOOKMARKS, 402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IDS_EXTENSION_PROMPT_WARNING_GEOLOCATION, 403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IDS_EXTENSION_PROMPT_WARNING_BROWSING_HISTORY, 404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IDS_EXTENSION_PROMPT_WARNING_TABS, 405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IDS_EXTENSION_PROMPT_WARNING_MANAGEMENT, 406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IDS_EXTENSION_PROMPT_WARNING_DEBUGGER, 407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IDS_EXTENSION_PROMPT_WARNING_1_HOST, 408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IDS_EXTENSION_PROMPT_WARNING_2_HOSTS, 409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IDS_EXTENSION_PROMPT_WARNING_3_HOSTS, 410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IDS_EXTENSION_PROMPT_WARNING_4_OR_MORE_HOSTS, 411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS, 412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS 413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}; 414201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 415731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// 416513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Extension 417731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// 418731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 419513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 420513209b27ff55e2841eac0e4120199c23acce758Ben Murdochscoped_refptr<Extension> Extension::Create(const FilePath& path, 421513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch Location location, 422513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const DictionaryValue& value, 423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int flags, 424513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string* error) { 425513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch scoped_refptr<Extension> extension = new Extension(path, location); 426dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!extension->InitFromValue(value, flags, error)) 428513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return NULL; 429513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return extension; 430731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 431731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 432201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochnamespace { 433201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char* kGalleryUpdateHttpUrl = 434201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "http://clients2.google.com/service/update2/crx"; 435201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char* kGalleryUpdateHttpsUrl = 436201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch "https://clients2.google.com/service/update2/crx"; 437201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} // namespace 438201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 439201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// static 440201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochGURL Extension::GalleryUpdateUrl(bool secure) { 441201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch CommandLine* cmdline = CommandLine::ForCurrentProcess(); 442201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (cmdline->HasSwitch(switches::kAppsGalleryUpdateURL)) 443201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return GURL(cmdline->GetSwitchValueASCII(switches::kAppsGalleryUpdateURL)); 444201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch else 445201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return GURL(secure ? kGalleryUpdateHttpsUrl : kGalleryUpdateHttpUrl); 446201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 447201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 4488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// static 449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenExtension::Location Extension::GetHigherPriorityLocation( 450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Extension::Location loc1, Extension::Location loc2) { 451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (loc1 == loc2) 452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return loc1; 453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int loc1_rank = GetLocationRank(loc1); 455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int loc2_rank = GetLocationRank(loc2); 456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If two different locations have the same rank, then we can not 458ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // deterministicly choose a location. 459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CHECK(loc1_rank != loc2_rank); 460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Lowest rank has highest priority. 462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return (loc1_rank > loc2_rank ? loc1 : loc2 ); 463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenExtension::PermissionMessage::MessageId Extension::GetPermissionMessageId( 467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& permission) { 46821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return ExtensionConfig::GetInstance()->GetPermissionMessageId(permission); 4698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 4708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenExtension::PermissionMessages Extension::GetPermissionMessages() const { 472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PermissionMessages messages; 473731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!plugins().empty()) { 474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen messages.push_back(PermissionMessage::CreateFromMessageId( 475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PermissionMessage::ID_FULL_ACCESS)); 4768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return messages; 4778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 4788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (HasEffectiveAccessToAllHosts()) { 480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen messages.push_back(PermissionMessage::CreateFromMessageId( 481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PermissionMessage::ID_HOSTS_ALL)); 482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<std::string> hosts = GetDistinctHostsForDisplay( 484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GetEffectiveHostPermissions().patterns()); 485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!hosts.empty()) 486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen messages.push_back(PermissionMessage::CreateFromHostList(hosts)); 487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 4888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::set<PermissionMessage> simple_msgs = GetSimplePermissionMessages(); 4908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen messages.insert(messages.end(), simple_msgs.begin(), simple_msgs.end()); 4918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 4928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return messages; 4938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 4948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstd::vector<string16> Extension::GetPermissionMessageStrings() const { 496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<string16> messages; 497ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PermissionMessages permissions = GetPermissionMessages(); 498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (PermissionMessages::const_iterator i = permissions.begin(); 499ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen i != permissions.end(); ++i) 500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen messages.push_back(i->message()); 501ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return messages; 502ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 503ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 504ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstd::set<Extension::PermissionMessage> 505ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Extension::GetSimplePermissionMessages() const { 506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::set<PermissionMessage> messages; 507731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::set<std::string>::const_iterator i; 508731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (i = api_permissions().begin(); i != api_permissions().end(); ++i) { 509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen PermissionMessage::MessageId message_id = GetPermissionMessageId(*i); 510ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_GT(PermissionMessage::ID_NONE, PermissionMessage::ID_UNKNOWN); 511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (message_id > PermissionMessage::ID_NONE) 512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen messages.insert(PermissionMessage::CreateFromMessageId(message_id)); 5138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 5148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return messages; 5158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 5168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 517201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// static 518201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstd::vector<std::string> Extension::GetDistinctHostsForDisplay( 519201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const URLPatternList& list) { 520201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return GetDistinctHosts(list, true); 5218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 5228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 5238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// static 524201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool Extension::IsElevatedHostList( 525201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const URLPatternList& old_list, const URLPatternList& new_list) { 526201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // TODO(jstritar): This is overly conservative with respect to subdomains. 527201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // For example, going from *.google.com to www.google.com will be 528201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // considered an elevation, even though it is not (http://crbug.com/65337). 529201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 530201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::vector<std::string> new_hosts = GetDistinctHosts(new_list, false); 531201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::vector<std::string> old_hosts = GetDistinctHosts(old_list, false); 5328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 533201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::set<std::string> old_hosts_set(old_hosts.begin(), old_hosts.end()); 534201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::set<std::string> new_hosts_set(new_hosts.begin(), new_hosts.end()); 535201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::set<std::string> new_hosts_only; 536201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 537201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::set_difference(new_hosts_set.begin(), new_hosts_set.end(), 538201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch old_hosts_set.begin(), old_hosts_set.end(), 539201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::inserter(new_hosts_only, new_hosts_only.begin())); 540201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 541dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return !new_hosts_only.empty(); 542201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 543201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 544ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Helper for GetDistinctHosts(): com > net > org > everything else. 545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic bool RcdBetterThan(const std::string& a, const std::string& b) { 546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (a == b) 547ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 548ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (a == "com") 549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (a == "net") 551ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return b != "com"; 552ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (a == "org") 553ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return b != "com" && b != "net"; 554ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 555ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 557201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// static 558201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstd::vector<std::string> Extension::GetDistinctHosts( 559201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const URLPatternList& host_patterns, bool include_rcd) { 560ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Use a vector to preserve order (also faster than a map on small sets). 561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Each item is a host split into two parts: host without RCDs and 562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // current best RCD. 563ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen typedef std::vector<std::pair<std::string, std::string> > HostVector; 564ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HostVector hosts_best_rcd; 5658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < host_patterns.size(); ++i) { 566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string host = host_patterns[i].host(); 567201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 568201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Add the subdomain wildcard back to the host, if necessary. 569201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (host_patterns[i].match_subdomains()) 570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen host = "*." + host; 571201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If the host has an RCD, split it off so we can detect duplicates. 573ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string rcd; 574ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t reg_len = net::RegistryControlledDomainService::GetRegistryLength( 575ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen host, false); 576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (reg_len && reg_len != std::string::npos) { 577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (include_rcd) // else leave rcd empty 578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rcd = host.substr(host.size() - reg_len); 579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen host = host.substr(0, host.size() - reg_len); 580731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 581ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 582ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Check if we've already seen this host. 583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HostVector::iterator it = hosts_best_rcd.begin(); 584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (; it != hosts_best_rcd.end(); ++it) { 585ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (it->first == host) 586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen break; 587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // If this host was found, replace the RCD if this one is better. 589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (it != hosts_best_rcd.end()) { 590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (include_rcd && RcdBetterThan(rcd, it->second)) 591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen it->second = rcd; 592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { // Previously unseen host, append it. 593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen hosts_best_rcd.push_back(std::make_pair(host, rcd)); 5948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 5958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 5968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Build up the final vector by concatenating hosts and RCDs. 598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<std::string> distinct_hosts; 599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (HostVector::iterator it = hosts_best_rcd.begin(); 600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen it != hosts_best_rcd.end(); ++it) 601ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen distinct_hosts.push_back(it->first + it->second); 6028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return distinct_hosts; 6038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 6048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 605731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickFilePath Extension::MaybeNormalizePath(const FilePath& path) { 606731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#if defined(OS_WIN) 607731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Normalize any drive letter to upper-case. We do this for consistency with 608731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // net_utils::FilePathToFileURL(), which does the same thing, to make string 609731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // comparisons simpler. 610731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::wstring path_str = path.value(); 611731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (path_str.size() >= 2 && path_str[0] >= L'a' && path_str[0] <= L'z' && 612731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick path_str[1] == ':') 613731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick path_str[0] += ('A' - 'a'); 614731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 615731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return FilePath(path_str); 616731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#else 617731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return path; 618731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#endif 619731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 620731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 6218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// static 6228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::IsHostedAppPermission(const std::string& str) { 6238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < Extension::kNumHostedAppPermissions; ++i) { 6248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (str == Extension::kHostedAppPermissionNames[i]) { 6258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 6268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 6278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 6288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 6298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 6308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 6318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenconst std::string Extension::VersionString() const { 632731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return version()->GetString(); 6338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 6348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 6358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// static 6368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::IsExtension(const FilePath& file_name) { 6378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return file_name.MatchesExtension(chrome::kExtensionFileExtension); 6388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 6398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 6408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// static 6418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::IdIsValid(const std::string& id) { 6428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Verify that the id is legal. 6438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (id.size() != (kIdSize * 2)) 6448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 6458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 6468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // We only support lowercase IDs, because IDs can be used as URL components 6478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // (where GURL will lowercase it). 6488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string temp = StringToLowerASCII(id); 6498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < temp.size(); i++) 6508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (temp[i] < 'a' || temp[i] > 'p') 6518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 6528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 6538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 6548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 6558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 6568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// static 657731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstd::string Extension::GenerateIdForPath(const FilePath& path) { 658731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick FilePath new_path = Extension::MaybeNormalizePath(path); 659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string path_bytes = 660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string(reinterpret_cast<const char*>(new_path.value().data()), 661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new_path.value().size() * sizeof(FilePath::CharType)); 662731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string id; 663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!GenerateId(path_bytes, &id)) 664731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ""; 665731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return id; 666731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 667731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 66821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenExtension::Type Extension::GetType() const { 669731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (is_theme()) 670731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return TYPE_THEME; 671731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (converted_from_user_script()) 672731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return TYPE_USER_SCRIPT; 673731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (is_hosted_app()) 674731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return TYPE_HOSTED_APP; 675731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (is_packaged_app()) 676731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return TYPE_PACKAGED_APP; 677731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return TYPE_EXTENSION; 678731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 679731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 680731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// static 6818ae428e0fb7feea16d79853f29447469a93bedffKristian MonsenGURL Extension::GetResourceURL(const GURL& extension_url, 6828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const std::string& relative_path) { 6838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen DCHECK(extension_url.SchemeIs(chrome::kExtensionScheme)); 6848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen DCHECK_EQ("/", extension_url.path()); 6858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 6868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen GURL ret_val = GURL(extension_url.spec() + relative_path); 6878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen DCHECK(StartsWithASCII(ret_val.spec(), extension_url.spec(), false)); 6888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 6898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return ret_val; 6908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 6918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 6928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::GenerateId(const std::string& input, std::string* output) { 6938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen CHECK(output); 6948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen uint8 hash[Extension::kIdSize]; 695ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen crypto::SHA256HashString(input, hash, sizeof(hash)); 6968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *output = StringToLowerASCII(base::HexEncode(hash, sizeof(hash))); 6978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ConvertHexadecimalToIDAlphabet(output); 6988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 6998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 7008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 7018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 7028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// Helper method that loads a UserScript object from a dictionary in the 7038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// content_script list of the manifest. 7048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::LoadUserScriptHelper(const DictionaryValue* content_script, 705dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int definition_index, 706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int flags, 707dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string* error, 7088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen UserScript* result) { 709ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // When strict error checks are enabled, make URL pattern parsing strict. 710ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen URLPattern::ParseOption parse_strictness = 711ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (flags & STRICT_ERROR_CHECKS ? URLPattern::PARSE_STRICT 712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : URLPattern::PARSE_LENIENT); 713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 7148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // run_at 7158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (content_script->HasKey(keys::kRunAt)) { 7168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string run_location; 7178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!content_script->GetString(keys::kRunAt, &run_location)) { 7188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage(errors::kInvalidRunAt, 7198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(definition_index)); 7208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 7218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 7228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 7238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (run_location == values::kRunAtDocumentStart) { 7248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->set_run_location(UserScript::DOCUMENT_START); 7258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else if (run_location == values::kRunAtDocumentEnd) { 7268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->set_run_location(UserScript::DOCUMENT_END); 7278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else if (run_location == values::kRunAtDocumentIdle) { 7288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->set_run_location(UserScript::DOCUMENT_IDLE); 7298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else { 7308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage(errors::kInvalidRunAt, 7318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(definition_index)); 7328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 7338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 7348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 7358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 7368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // all frames 7378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (content_script->HasKey(keys::kAllFrames)) { 7388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen bool all_frames = false; 7398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!content_script->GetBoolean(keys::kAllFrames, &all_frames)) { 7408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 7418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidAllFrames, base::IntToString(definition_index)); 7428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 7438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 7448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->set_match_all_frames(all_frames); 7458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 7468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 7478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // matches 7488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ListValue* matches = NULL; 7498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!content_script->GetList(keys::kMatches, &matches)) { 7508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage(errors::kInvalidMatches, 7518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(definition_index)); 7528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 7538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 7548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 7558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (matches->GetSize() == 0) { 7568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage(errors::kInvalidMatchCount, 7578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(definition_index)); 7588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 7598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 7608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t j = 0; j < matches->GetSize(); ++j) { 7618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string match_str; 7628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!matches->GetString(j, &match_str)) { 763dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 764dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen errors::kInvalidMatch, 765dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::IntToString(definition_index), 766dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::IntToString(j), 767dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen errors::kExpectString); 7688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 7698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 7708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 771513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch URLPattern pattern(UserScript::kValidUserScriptSchemes); 772731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (CanExecuteScriptEverywhere()) 773513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch pattern.set_valid_schemes(URLPattern::SCHEME_ALL); 774513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 775dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen URLPattern::ParseResult parse_result = pattern.Parse(match_str, 776dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen parse_strictness); 777dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (parse_result != URLPattern::PARSE_SUCCESS) { 778dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 779dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen errors::kInvalidMatch, 780dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::IntToString(definition_index), 781dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::IntToString(j), 782dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen URLPattern::GetParseResultString(parse_result)); 7838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 7848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 7858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 786ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (pattern.MatchesScheme(chrome::kFileScheme) && 787ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !CanExecuteScriptEverywhere()) { 788ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen wants_file_access_ = true; 789ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!(flags & ALLOW_FILE_ACCESS)) 790ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pattern.set_valid_schemes( 791ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); 792ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 793ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 7948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->add_url_pattern(pattern); 7958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 7968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 7978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // include/exclude globs (mostly for Greasemonkey compatibility) 7988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!LoadGlobsHelper(content_script, definition_index, keys::kIncludeGlobs, 7998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen error, &UserScript::add_glob, result)) { 8008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 8018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 8028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 8038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!LoadGlobsHelper(content_script, definition_index, keys::kExcludeGlobs, 8048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen error, &UserScript::add_exclude_glob, result)) { 8058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 8068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 8078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 8088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // js and css keys 8098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ListValue* js = NULL; 8108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (content_script->HasKey(keys::kJs) && 8118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen !content_script->GetList(keys::kJs, &js)) { 8128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage(errors::kInvalidJsList, 8138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(definition_index)); 8148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 8158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 8168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 8178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ListValue* css = NULL; 8188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (content_script->HasKey(keys::kCss) && 8198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen !content_script->GetList(keys::kCss, &css)) { 8208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage(errors::kInvalidCssList, 8218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(definition_index)); 8228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 8238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 8248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 8258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // The manifest needs to have at least one js or css user script definition. 8268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (((js ? js->GetSize() : 0) + (css ? css->GetSize() : 0)) == 0) { 8278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage(errors::kMissingFile, 8288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(definition_index)); 8298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 8308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 8318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 8328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (js) { 8338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t script_index = 0; script_index < js->GetSize(); 8348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ++script_index) { 8358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Value* value; 8368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string relative; 8378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!js->Get(script_index, &value) || !value->GetAsString(&relative)) { 8388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage(errors::kInvalidJs, 8398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(definition_index), 8408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(script_index)); 8418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 8428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 8438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen GURL url = GetResourceURL(relative); 8448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ExtensionResource resource = GetResource(relative); 8458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->js_scripts().push_back(UserScript::File( 8468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen resource.extension_root(), resource.relative_path(), url)); 8478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 8488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 8498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 8508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (css) { 8518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t script_index = 0; script_index < css->GetSize(); 8528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ++script_index) { 8538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Value* value; 8548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string relative; 8558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!css->Get(script_index, &value) || !value->GetAsString(&relative)) { 8568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage(errors::kInvalidCss, 8578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(definition_index), 8588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(script_index)); 8598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 8608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 8618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen GURL url = GetResourceURL(relative); 8628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ExtensionResource resource = GetResource(relative); 8638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->css_scripts().push_back(UserScript::File( 8648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen resource.extension_root(), resource.relative_path(), url)); 8658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 8668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 8678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 8688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 8698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 8708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 8718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::LoadGlobsHelper( 8728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const DictionaryValue* content_script, 8738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen int content_script_index, 8748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const char* globs_property_name, 8758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string* error, 8768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen void(UserScript::*add_method)(const std::string& glob), 8778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen UserScript *instance) { 8788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!content_script->HasKey(globs_property_name)) 8798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; // they are optional 8808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 8818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ListValue* list = NULL; 8828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!content_script->GetList(globs_property_name, &list)) { 8838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage(errors::kInvalidGlobList, 8848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(content_script_index), 8858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen globs_property_name); 8868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 8878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 8888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 8898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < list->GetSize(); ++i) { 8908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string glob; 8918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!list->GetString(i, &glob)) { 8928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage(errors::kInvalidGlob, 8938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(content_script_index), 8948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen globs_property_name, 8958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(i)); 8968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 8978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 8988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 8998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen (instance->*add_method)(glob); 9008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 9018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 9028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 9038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 9048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 9058ae428e0fb7feea16d79853f29447469a93bedffKristian MonsenExtensionAction* Extension::LoadExtensionActionHelper( 9068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const DictionaryValue* extension_action, std::string* error) { 9078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen scoped_ptr<ExtensionAction> result(new ExtensionAction()); 9088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->set_extension_id(id()); 9098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 9108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Page actions are hidden by default, and browser actions ignore 9118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // visibility. 9128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->SetIsVisible(ExtensionAction::kDefaultTabId, false); 9138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 9148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // TODO(EXTENSIONS_DEPRECATED): icons list is obsolete. 9158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ListValue* icons = NULL; 9168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (extension_action->HasKey(keys::kPageActionIcons) && 9178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen extension_action->GetList(keys::kPageActionIcons, &icons)) { 9188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (ListValue::const_iterator iter = icons->begin(); 9198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen iter != icons->end(); ++iter) { 9208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string path; 9218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!(*iter)->GetAsString(&path) || path.empty()) { 9228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidPageActionIconPath; 9238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return NULL; 9248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 9258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 9268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->icon_paths()->push_back(path); 9278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 9288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 9298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 9308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // TODO(EXTENSIONS_DEPRECATED): Read the page action |id| (optional). 9318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string id; 9328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (extension_action->HasKey(keys::kPageActionId)) { 9338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!extension_action->GetString(keys::kPageActionId, &id)) { 9348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidPageActionId; 9358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return NULL; 9368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 9378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->set_id(id); 9388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 9398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 9408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string default_icon; 9418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Read the page action |default_icon| (optional). 9428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (extension_action->HasKey(keys::kPageActionDefaultIcon)) { 9438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!extension_action->GetString(keys::kPageActionDefaultIcon, 9448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen &default_icon) || 9458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen default_icon.empty()) { 9468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidPageActionIconPath; 9478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return NULL; 9488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 9498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->set_default_icon_path(default_icon); 9508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 9518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 9528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Read the page action title from |default_title| if present, |name| if not 9538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // (both optional). 9548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string title; 9558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (extension_action->HasKey(keys::kPageActionDefaultTitle)) { 9568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!extension_action->GetString(keys::kPageActionDefaultTitle, &title)) { 9578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidPageActionDefaultTitle; 9588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return NULL; 9598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 9608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else if (extension_action->HasKey(keys::kName)) { 9618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!extension_action->GetString(keys::kName, &title)) { 9628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidPageActionName; 9638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return NULL; 9648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 9658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 9668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->SetTitle(ExtensionAction::kDefaultTabId, title); 9678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 9688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Read the action's |popup| (optional). 9698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const char* popup_key = NULL; 9708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (extension_action->HasKey(keys::kPageActionDefaultPopup)) 9718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen popup_key = keys::kPageActionDefaultPopup; 9728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 9738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // For backward compatibility, alias old key "popup" to new 9748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // key "default_popup". 9758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (extension_action->HasKey(keys::kPageActionPopup)) { 9768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (popup_key) { 9778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 9788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidPageActionOldAndNewKeys, 9798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen keys::kPageActionDefaultPopup, 9808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen keys::kPageActionPopup); 9818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return NULL; 9828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 9838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen popup_key = keys::kPageActionPopup; 9848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 9858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 9868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (popup_key) { 9878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen DictionaryValue* popup = NULL; 9888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string url_str; 9898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 9908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (extension_action->GetString(popup_key, &url_str)) { 9918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // On success, |url_str| is set. Nothing else to do. 9928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else if (extension_action->GetDictionary(popup_key, &popup)) { 9938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // TODO(EXTENSIONS_DEPRECATED): popup is now a string only. 9948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Support the old dictionary format for backward compatibility. 9958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!popup->GetString(keys::kPageActionPopupPath, &url_str)) { 9968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 9978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidPageActionPopupPath, "<missing>"); 9988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return NULL; 9998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 10008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else { 10018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidPageActionPopup; 10028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return NULL; 10038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 10048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 10058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!url_str.empty()) { 10068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // An empty string is treated as having no popup. 10078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen GURL url = GetResourceURL(url_str); 10088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!url.is_valid()) { 10098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 10108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidPageActionPopupPath, url_str); 10118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return NULL; 10128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 10138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->SetPopupUrl(ExtensionAction::kDefaultTabId, url); 10148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else { 10158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen DCHECK(!result->HasPopup(ExtensionAction::kDefaultTabId)) 10168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen << "Shouldn't be posible for the popup to be set."; 10178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 10188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 10198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 10208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return result.release(); 10218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 10228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1023ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenExtension::FileBrowserHandlerList* Extension::LoadFileBrowserHandlers( 1024ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const ListValue* extension_actions, std::string* error) { 1025ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<FileBrowserHandlerList> result( 1026ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new FileBrowserHandlerList()); 1027ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (ListValue::const_iterator iter = extension_actions->begin(); 1028ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen iter != extension_actions->end(); 1029ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ++iter) { 1030ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!(*iter)->IsType(Value::TYPE_DICTIONARY)) { 1031ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = errors::kInvalidFileBrowserHandler; 1032ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return NULL; 1033ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1034ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<FileBrowserHandler> action( 1035ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LoadFileBrowserHandler( 1036ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen reinterpret_cast<DictionaryValue*>(*iter), error)); 1037ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!action.get()) 1038ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return NULL; // Failed to parse file browser action definition. 1039ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result->push_back(linked_ptr<FileBrowserHandler>(action.release())); 1040ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1041ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result.release(); 1042ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1043ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1044ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenFileBrowserHandler* Extension::LoadFileBrowserHandler( 1045ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const DictionaryValue* file_browser_handler, std::string* error) { 1046ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<FileBrowserHandler> result( 1047ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new FileBrowserHandler()); 1048ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result->set_extension_id(id()); 1049ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1050ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string id; 1051ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Read the file action |id| (mandatory). 1052ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!file_browser_handler->HasKey(keys::kPageActionId) || 1053ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !file_browser_handler->GetString(keys::kPageActionId, &id)) { 1054ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = errors::kInvalidPageActionId; 1055ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return NULL; 1056ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1057ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result->set_id(id); 1058ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1059ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Read the page action title from |default_title| (mandatory). 1060ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string title; 1061ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!file_browser_handler->HasKey(keys::kPageActionDefaultTitle) || 1062ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !file_browser_handler->GetString(keys::kPageActionDefaultTitle, &title)) { 1063ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = errors::kInvalidPageActionDefaultTitle; 1064ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return NULL; 1065ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1066ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result->set_title(title); 1067ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1068ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Initialize file filters (mandatory). 1069ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* list_value = NULL; 1070ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!file_browser_handler->HasKey(keys::kFileFilters) || 1071ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !file_browser_handler->GetList(keys::kFileFilters, &list_value) || 1072ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen list_value->empty()) { 1073ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = errors::kInvalidFileFiltersList; 1074ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return NULL; 1075ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1076ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < list_value->GetSize(); ++i) { 1077ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string filter; 1078ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!list_value->GetString(i, &filter)) { 1079ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 1080ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen errors::kInvalidFileFilterValue, base::IntToString(i)); 1081ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return NULL; 1082ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1083ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen URLPattern pattern(URLPattern::SCHEME_FILESYSTEM); 1084ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (URLPattern::PARSE_SUCCESS != pattern.Parse(filter, 1085ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen URLPattern::PARSE_STRICT)) { 1086ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 1087ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen errors::kInvalidURLPatternError, filter); 1088ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return NULL; 1089ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1090ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result->AddPattern(pattern); 1091ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1092ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1093ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string default_icon; 1094ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Read the file browser action |default_icon| (optional). 1095ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (file_browser_handler->HasKey(keys::kPageActionDefaultIcon)) { 1096ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!file_browser_handler->GetString( 1097ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen keys::kPageActionDefaultIcon,&default_icon) || 1098ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen default_icon.empty()) { 1099ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = errors::kInvalidPageActionIconPath; 1100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return NULL; 1101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result->set_icon_path(default_icon); 1103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result.release(); 1106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 110872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenExtensionSidebarDefaults* Extension::LoadExtensionSidebarDefaults( 110972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const DictionaryValue* extension_sidebar, std::string* error) { 111072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<ExtensionSidebarDefaults> result(new ExtensionSidebarDefaults()); 111172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 111272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string default_icon; 111372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Read sidebar's |default_icon| (optional). 111472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (extension_sidebar->HasKey(keys::kSidebarDefaultIcon)) { 111572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!extension_sidebar->GetString(keys::kSidebarDefaultIcon, 111672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &default_icon) || 111772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen default_icon.empty()) { 111872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *error = errors::kInvalidSidebarDefaultIconPath; 111972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return NULL; 112072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 112172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen result->set_default_icon_path(default_icon); 112272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 112372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 112472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Read sidebar's |default_title| (optional). 112572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 default_title; 112672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (extension_sidebar->HasKey(keys::kSidebarDefaultTitle)) { 112772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!extension_sidebar->GetString(keys::kSidebarDefaultTitle, 112872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &default_title)) { 112972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *error = errors::kInvalidSidebarDefaultTitle; 113072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return NULL; 113172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 113272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 113372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen result->set_default_title(default_title); 113472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 113572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Read sidebar's |default_page| (optional). 113672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string default_page; 113772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (extension_sidebar->HasKey(keys::kSidebarDefaultPage)) { 113872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!extension_sidebar->GetString(keys::kSidebarDefaultPage, 113972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &default_page) || 114072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen default_page.empty()) { 114172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *error = errors::kInvalidSidebarDefaultPage; 114272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return NULL; 114372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 114472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen GURL url = extension_sidebar_utils::ResolveRelativePath( 114572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen default_page, this, error); 114672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!url.is_valid()) 114772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return NULL; 114872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen result->set_default_page(url); 114972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 115072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 115172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result.release(); 115272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 115372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1154513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool Extension::ContainsNonThemeKeys(const DictionaryValue& source) const { 11558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (DictionaryValue::key_iterator key = source.begin_keys(); 11568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen key != source.end_keys(); ++key) { 11578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!IsBaseCrxKey(*key) && *key != keys::kTheme) 11588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 11598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 11608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 11618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 11628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 11638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::LoadIsApp(const DictionaryValue* manifest, 11648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string* error) { 1165731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (manifest->HasKey(keys::kApp)) 1166513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch is_app_ = true; 11678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 11688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 11698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 11708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 11718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::LoadExtent(const DictionaryValue* manifest, 11728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const char* key, 11738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ExtensionExtent* extent, 11748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const char* list_error, 11758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const char* value_error, 1176dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen URLPattern::ParseOption parse_strictness, 11778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string* error) { 11788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Value* temp = NULL; 11798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!manifest->Get(key, &temp)) 11808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 11818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 11828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (temp->GetType() != Value::TYPE_LIST) { 11838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = list_error; 11848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 11858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 11868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 11878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ListValue* pattern_list = static_cast<ListValue*>(temp); 11888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < pattern_list->GetSize(); ++i) { 11898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string pattern_string; 11908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!pattern_list->GetString(i, &pattern_string)) { 11918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage(value_error, 1192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::UintToString(i), 1193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen errors::kExpectString); 11948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 11958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 11968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 11978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen URLPattern pattern(kValidWebExtentSchemes); 1198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen URLPattern::ParseResult parse_result = pattern.Parse(pattern_string, 1199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen parse_strictness); 1200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (parse_result == URLPattern::PARSE_ERROR_EMPTY_PATH) { 1201513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch pattern_string += "/"; 1202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen parse_result = pattern.Parse(pattern_string, parse_strictness); 1203513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 1204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (parse_result != URLPattern::PARSE_SUCCESS) { 1206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 1207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen value_error, 1208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::UintToString(i), 1209dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen URLPattern::GetParseResultString(parse_result)); 12108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 12118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 12128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1213dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Do not allow authors to claim "<all_urls>". 1214731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (pattern.match_all_urls()) { 1215dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 1216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen value_error, 1217dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::UintToString(i), 1218dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen errors::kCannotClaimAllURLsInExtent); 1219dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 1220dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 1221dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Do not allow authors to claim "*" for host. 1223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (pattern.host().empty()) { 1224dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 1225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen value_error, 1226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::UintToString(i), 1227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen errors::kCannotClaimAllHostsInExtent); 1228731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 1229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1230731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 12318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // We do not allow authors to put wildcards in their paths. Instead, we 12328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // imply one at the end. 12338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (pattern.path().find('*') != std::string::npos) { 1234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 1235dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen value_error, 1236dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::UintToString(i), 1237dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen errors::kNoWildCardsInPaths); 12388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 12398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 1240dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pattern.SetPath(pattern.path() + '*'); 12418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 12428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen extent->AddPattern(pattern); 12438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 12448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 12458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 12468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 12478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 12488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::LoadLaunchURL(const DictionaryValue* manifest, 12498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string* error) { 12508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Value* temp = NULL; 12518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 12528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // launch URL can be either local (to chrome-extension:// root) or an absolute 12538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // web URL. 12548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (manifest->Get(keys::kLaunchLocalPath, &temp)) { 12558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (manifest->Get(keys::kLaunchWebURL, NULL)) { 12568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kLaunchPathAndURLAreExclusive; 12578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 12588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 12598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 12608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string launch_path; 12618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!temp->GetAsString(&launch_path)) { 12628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidLaunchLocalPath; 12638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 12648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 12658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 12668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Ensure the launch path is a valid relative URL. 1267731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GURL resolved = url().Resolve(launch_path); 1268731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!resolved.is_valid() || resolved.GetOrigin() != url()) { 12698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidLaunchLocalPath; 12708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 12718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 12728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1273513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch launch_local_path_ = launch_path; 12748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else if (manifest->Get(keys::kLaunchWebURL, &temp)) { 12758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string launch_url; 12768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!temp->GetAsString(&launch_url)) { 12778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidLaunchWebURL; 12788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 12798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 12808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Ensure the launch URL is a valid absolute URL and web extent scheme. 1282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL url(launch_url); 1283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen URLPattern pattern(kValidWebExtentSchemes); 1284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!url.is_valid() || !pattern.SetScheme(url.scheme())) { 12858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidLaunchWebURL; 12868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 12878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 12888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1289513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch launch_web_url_ = launch_url; 1290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } else if (is_app()) { 12918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kLaunchURLRequired; 12928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 12938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 12948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 12958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // If there is no extent, we default the extent based on the launch URL. 1296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (web_extent().is_empty() && !launch_web_url().empty()) { 1297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GURL launch_url(launch_web_url()); 12988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen URLPattern pattern(kValidWebExtentSchemes); 12998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!pattern.SetScheme("*")) { 13008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidLaunchWebURL; 13018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 13028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 13038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen pattern.set_host(launch_url.host()); 1304dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pattern.SetPath("/*"); 1305513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch extent_.AddPattern(pattern); 1306731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 1307731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // In order for the --apps-gallery-url switch to work with the gallery 1309731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // process isolation, we must insert any provided value into the component 1310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // app's launch url and web extent. 1311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (id() == extension_misc::kWebStoreAppId) { 1312dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string gallery_url_str = CommandLine::ForCurrentProcess()-> 1313dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen GetSwitchValueASCII(switches::kAppsGalleryURL); 1314dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1315dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Empty string means option was not used. 1316dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!gallery_url_str.empty()) { 1317dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen GURL gallery_url(gallery_url_str); 1318dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!gallery_url.is_valid()) { 1319dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(WARNING) << "Invalid url given in switch " 1320dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << switches::kAppsGalleryURL; 1321dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 1322dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (gallery_url.has_port()) { 1323dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(WARNING) << "URLs passed to switch " << switches::kAppsGalleryURL 1324dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << " should not contain a port. Removing it."; 1325731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1326dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen GURL::Replacements remove_port; 1327dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen remove_port.ClearPort(); 1328dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen gallery_url = gallery_url.ReplaceComponents(remove_port); 1329dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 1330dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1331dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen launch_web_url_ = gallery_url.spec(); 1332dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1333dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen URLPattern pattern(kValidWebExtentSchemes); 1334dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pattern.Parse(gallery_url.spec(), URLPattern::PARSE_STRICT); 1335dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pattern.SetPath(pattern.path() + '*'); 1336dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen extent_.AddPattern(pattern); 1337dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 1338731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 13398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 13408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 13418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 13428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 13438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 13448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::LoadLaunchContainer(const DictionaryValue* manifest, 13458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string* error) { 13468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Value* temp = NULL; 13478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!manifest->Get(keys::kLaunchContainer, &temp)) 13488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 13498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 13508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string launch_container_string; 13518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!temp->GetAsString(&launch_container_string)) { 13528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidLaunchContainer; 13538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 13548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 13558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 13568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (launch_container_string == values::kLaunchContainerPanel) { 1357513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch launch_container_ = extension_misc::LAUNCH_PANEL; 13588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else if (launch_container_string == values::kLaunchContainerTab) { 1359513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch launch_container_ = extension_misc::LAUNCH_TAB; 13608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else { 13618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidLaunchContainer; 13628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 13638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 13648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 13658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Validate the container width if present. 13668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (manifest->Get(keys::kLaunchWidth, &temp)) { 1367731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (launch_container() != extension_misc::LAUNCH_PANEL && 1368731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick launch_container() != extension_misc::LAUNCH_WINDOW) { 13698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidLaunchWidthContainer; 13708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 13718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 1372513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!temp->GetAsInteger(&launch_width_) || 1373513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch launch_width_ < 0) { 1374513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch launch_width_ = 0; 13758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidLaunchWidth; 13768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 13778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 13788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 13798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 13808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Validate container height if present. 13818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (manifest->Get(keys::kLaunchHeight, &temp)) { 1382731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (launch_container() != extension_misc::LAUNCH_PANEL && 1383731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick launch_container() != extension_misc::LAUNCH_WINDOW) { 13848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidLaunchHeightContainer; 13858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 13868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 1387513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!temp->GetAsInteger(&launch_height_) || launch_height_ < 0) { 1388513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch launch_height_ = 0; 13898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidLaunchHeight; 13908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 13918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 13928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 13938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 13948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 13958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 13968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool Extension::LoadAppIsolation(const DictionaryValue* manifest, 1398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string* error) { 1399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Only parse app isolation features if this switch is present. 1400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!CommandLine::ForCurrentProcess()->HasSwitch( 1401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen switches::kEnableExperimentalAppManifests)) 1402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 1403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Value* temp = NULL; 1405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!manifest->Get(keys::kIsolation, &temp)) 1406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 1407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (temp->GetType() != Value::TYPE_LIST) { 1409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = errors::kInvalidIsolation; 1410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 1411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* isolation_list = static_cast<ListValue*>(temp); 1414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < isolation_list->GetSize(); ++i) { 1415ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string isolation_string; 1416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!isolation_list->GetString(i, &isolation_string)) { 1417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 1418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen errors::kInvalidIsolationValue, 1419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::UintToString(i)); 1420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 1421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Check for isolated storage. 1424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (isolation_string == values::kIsolatedStorage) { 1425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen is_storage_isolated_ = true; 1426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 1427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LOG(WARNING) << "Did not recognize isolation type: " 1428ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen << isolation_string; 1429ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1431ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 1432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 14348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::EnsureNotHybridApp(const DictionaryValue* manifest, 14358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string* error) { 14368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (web_extent().is_empty()) 14378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 14388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 14398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (DictionaryValue::key_iterator key = manifest->begin_keys(); 14408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen key != manifest->end_keys(); ++key) { 14418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!IsBaseCrxKey(*key) && 14428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *key != keys::kApp && 14438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *key != keys::kPermissions && 1444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *key != keys::kOptionsPage && 1445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *key != keys::kBackground) { 1446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 1447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen errors::kHostedAppsCannotIncludeExtensionFeatures, *key); 14488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 14498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 14508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 14518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 14528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 14538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 14548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1455513209b27ff55e2841eac0e4120199c23acce758Ben MurdochExtension::Extension(const FilePath& path, Location location) 1456513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch : incognito_split_mode_(false), 1457513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch location_(location), 1458513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch converted_from_user_script_(false), 1459513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch is_theme_(false), 1460513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch is_app_(false), 1461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen is_storage_isolated_(false), 1462513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch launch_container_(extension_misc::LAUNCH_TAB), 1463513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch launch_width_(0), 1464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen launch_height_(0), 1465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen wants_file_access_(false) { 1466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK(path.empty() || path.IsAbsolute()); 1467513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch path_ = MaybeNormalizePath(path); 14688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 1469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1470513209b27ff55e2841eac0e4120199c23acce758Ben MurdochExtension::~Extension() { 1471513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 1472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1473513209b27ff55e2841eac0e4120199c23acce758Ben MurdochExtensionResource Extension::GetResource( 1474513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const std::string& relative_path) const { 14758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#if defined(OS_POSIX) 14768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen FilePath relative_file_path(relative_path); 14778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#elif defined(OS_WIN) 14788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen FilePath relative_file_path(UTF8ToWide(relative_path)); 14798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#endif 14808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return ExtensionResource(id(), path(), relative_file_path); 14818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 14828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1483513209b27ff55e2841eac0e4120199c23acce758Ben MurdochExtensionResource Extension::GetResource( 1484513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const FilePath& relative_file_path) const { 14858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return ExtensionResource(id(), path(), relative_file_path); 14868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 14878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 14888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// TODO(rafaelw): Move ParsePEMKeyBytes, ProducePEM & FormatPEMForOutput to a 14898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// util class in base: 14908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// http://code.google.com/p/chromium/issues/detail?id=13572 14918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::ParsePEMKeyBytes(const std::string& input, 14928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string* output) { 14938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen DCHECK(output); 14948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!output) 14958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 14968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (input.length() == 0) 14978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 14988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 14998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string working = input; 15008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (StartsWithASCII(working, kKeyBeginHeaderMarker, true)) { 15018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen working = CollapseWhitespaceASCII(working, true); 15028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen size_t header_pos = working.find(kKeyInfoEndMarker, 15038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen sizeof(kKeyBeginHeaderMarker) - 1); 15048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (header_pos == std::string::npos) 15058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 15068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen size_t start_pos = header_pos + sizeof(kKeyInfoEndMarker) - 1; 15078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen size_t end_pos = working.rfind(kKeyBeginFooterMarker); 15088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (end_pos == std::string::npos) 15098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 15108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (start_pos >= end_pos) 15118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 15128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 15138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen working = working.substr(start_pos, end_pos - start_pos); 15148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (working.length() == 0) 15158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 15168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 15178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 15188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return base::Base64Decode(working, output); 15198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 15208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool Extension::ProducePEM(const std::string& input, std::string* output) { 15228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen CHECK(output); 15238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (input.length() == 0) 15248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 15258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 15268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return base::Base64Encode(input, output); 15278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 15288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1529ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool Extension::FormatPEMForFileOutput(const std::string& input, 15308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string* output, 15318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen bool is_public) { 15328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen CHECK(output); 15338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (input.length() == 0) 15348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 15358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *output = ""; 15368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen output->append(kKeyBeginHeaderMarker); 15378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen output->append(" "); 15388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen output->append(is_public ? kPublic : kPrivate); 15398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen output->append(" "); 15408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen output->append(kKeyInfoEndMarker); 15418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen output->append("\n"); 15428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < input.length(); ) { 15438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen int slice = std::min<int>(input.length() - i, kPEMOutputColumns); 15448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen output->append(input.substr(i, slice)); 15458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen output->append("\n"); 15468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen i += slice; 15478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 15488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen output->append(kKeyBeginFooterMarker); 15498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen output->append(" "); 15508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen output->append(is_public ? kPublic : kPrivate); 15518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen output->append(" "); 15528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen output->append(kKeyInfoEndMarker); 15538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen output->append("\n"); 15548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 15558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 15568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 15578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 15588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// static 1559201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool Extension::IsPrivilegeIncrease(const bool granted_full_access, 1560201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const std::set<std::string>& granted_apis, 1561201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const ExtensionExtent& granted_extent, 1562513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const Extension* new_extension) { 1563201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // If the extension had native code access, we don't need to go any further. 1564201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Things can't get any worse. 1565201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (granted_full_access) 15668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 15678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 15688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Otherwise, if the new extension has a plugin, it's a privilege increase. 1569201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (new_extension->HasFullPermissions()) 15708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 15718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1572201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // If the extension hadn't been granted access to all hosts in the past, then 1573201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // see if the extension requires more host permissions. 1574201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!HasEffectiveAccessToAllHosts(granted_extent, granted_apis)) { 15758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (new_extension->HasEffectiveAccessToAllHosts()) 15768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 15778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1578201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const ExtensionExtent new_extent = 1579201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new_extension->GetEffectiveHostPermissions(); 1580201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1581201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (IsElevatedHostList(granted_extent.patterns(), new_extent.patterns())) 15828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 15838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 15848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1585201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::set<std::string> new_apis = new_extension->api_permissions(); 1586201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::set<std::string> new_apis_only; 1587201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::set_difference(new_apis.begin(), new_apis.end(), 1588201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch granted_apis.begin(), granted_apis.end(), 1589201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch std::inserter(new_apis_only, new_apis_only.begin())); 1590201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 1591201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Ignore API permissions that don't require user approval when deciding if 1592201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // an extension has increased its privileges. 1593201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch size_t new_api_count = 0; 1594201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (std::set<std::string>::iterator i = new_apis_only.begin(); 1595201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch i != new_apis_only.end(); ++i) { 1596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DCHECK_GT(PermissionMessage::ID_NONE, PermissionMessage::ID_UNKNOWN); 1597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (GetPermissionMessageId(*i) > PermissionMessage::ID_NONE) 1598201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch new_api_count++; 1599201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 16008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1601201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (new_api_count) 16028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 16038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 16048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 16058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 16068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 16078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// static 1608513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid Extension::DecodeIcon(const Extension* extension, 16098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Icons icon_size, 16108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen scoped_ptr<SkBitmap>* result) { 16118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen FilePath icon_path = extension->GetIconResource( 16128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen icon_size, ExtensionIconSet::MATCH_EXACTLY).GetFilePath(); 16138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen DecodeIconFromPath(icon_path, icon_size, result); 16148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 16158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 16168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// static 16178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvoid Extension::DecodeIconFromPath(const FilePath& icon_path, 16188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Icons icon_size, 16198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen scoped_ptr<SkBitmap>* result) { 16208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (icon_path.empty()) 16218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return; 16228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 16238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string file_contents; 16248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!file_util::ReadFileToString(icon_path, &file_contents)) { 162572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LOG(ERROR) << "Could not read icon file: " << icon_path.LossyDisplayName(); 16268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return; 16278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 16288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 16298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Decode the image using WebKit's image decoder. 16308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const unsigned char* data = 16318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen reinterpret_cast<const unsigned char*>(file_contents.data()); 16328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen webkit_glue::ImageDecoder decoder; 16338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen scoped_ptr<SkBitmap> decoded(new SkBitmap()); 16348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *decoded = decoder.Decode(data, file_contents.length()); 16358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (decoded->empty()) { 16368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen LOG(ERROR) << "Could not decode icon file: " 163772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen << icon_path.LossyDisplayName(); 16388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return; 16398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 16408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 16418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (decoded->width() != icon_size || decoded->height() != icon_size) { 16428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen LOG(ERROR) << "Icon file has unexpected size: " 16438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen << base::IntToString(decoded->width()) << "x" 16448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen << base::IntToString(decoded->height()); 16458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return; 16468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 16478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 16488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen result->swap(decoded); 16498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 16508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 1652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst SkBitmap& Extension::GetDefaultIcon(bool is_app) { 1653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (is_app) { 1654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return *ResourceBundle::GetSharedInstance().GetBitmapNamed( 1655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IDR_APP_DEFAULT_ICON); 1656ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 1657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return *ResourceBundle::GetSharedInstance().GetBitmapNamed( 1658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IDR_EXTENSION_DEFAULT_ICON); 1659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 1661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 16628ae428e0fb7feea16d79853f29447469a93bedffKristian MonsenGURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) { 16638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return GURL(std::string(chrome::kExtensionScheme) + 16648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen chrome::kStandardSchemeSeparator + extension_id + "/"); 16658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 16668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool Extension::InitFromValue(const DictionaryValue& source, int flags, 1668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string* error) { 1669dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // When strict error checks are enabled, make URL pattern parsing strict. 1670dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen URLPattern::ParseOption parse_strictness = 1671ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (flags & STRICT_ERROR_CHECKS ? URLPattern::PARSE_STRICT 1672ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : URLPattern::PARSE_LENIENT); 1673dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 16748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kPublicKey)) { 16758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string public_key_bytes; 1676731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!source.GetString(keys::kPublicKey, 1677513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &public_key_) || 1678513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch !ParsePEMKeyBytes(public_key_, 1679731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &public_key_bytes) || 1680513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch !GenerateId(public_key_bytes, &id_)) { 16818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidKey; 16828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 16838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 1684ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else if (flags & REQUIRE_KEY) { 16858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidKey; 16868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 16878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else { 16888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // If there is a path, we generate the ID from it. This is useful for 16898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // development mode, because it keeps the ID stable across restarts and 16908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // reloading the extension. 1691513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch id_ = Extension::GenerateIdForPath(path()); 1692513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (id_.empty()) { 16938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen NOTREACHED() << "Could not create ID from path."; 16948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 16958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 16968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 16978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 16988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Make a copy of the manifest so we can store it in prefs. 169972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen manifest_value_.reset(source.DeepCopy()); 17008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 17018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize the URL. 1702dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen extension_url_ = Extension::GetBaseURLFromExtensionId(id()); 17038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 17048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize version. 17058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string version_str; 17068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetString(keys::kVersion, &version_str)) { 17078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidVersion; 17088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 17098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 171021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen version_.reset(Version::GetVersionFromString(version_str)); 1711513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!version_.get() || 1712513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch version_->components().size() > 4) { 17138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidVersion; 17148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 17158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 17168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 17178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize name. 17188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen string16 localized_name; 17198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetString(keys::kName, &localized_name)) { 17208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidName; 17218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 17228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 1723201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch base::i18n::AdjustStringForLocaleDirection(&localized_name); 1724513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch name_ = UTF16ToUTF8(localized_name); 17258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 17268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize description (if present). 17278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kDescription)) { 1728731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!source.GetString(keys::kDescription, 1729513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &description_)) { 17308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidDescription; 17318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 17328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 17338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 17348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1735513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Initialize homepage url (if present). 1736513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (source.HasKey(keys::kHomepageURL)) { 1737513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch std::string tmp; 1738513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!source.GetString(keys::kHomepageURL, &tmp)) { 1739513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch *error = ExtensionErrorUtils::FormatErrorMessage( 1740513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch errors::kInvalidHomepageURL, ""); 1741513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 1742513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 1743513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch homepage_url_ = GURL(tmp); 1744513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!homepage_url_.is_valid()) { 1745513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch *error = ExtensionErrorUtils::FormatErrorMessage( 1746513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch errors::kInvalidHomepageURL, tmp); 1747513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return false; 1748513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 1749513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 1750513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 17518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize update url (if present). 17528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kUpdateURL)) { 17538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string tmp; 17548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetString(keys::kUpdateURL, &tmp)) { 17558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 17568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidUpdateURL, ""); 17578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 17588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 1759513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch update_url_ = GURL(tmp); 1760513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!update_url_.is_valid() || 1761513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch update_url_.has_ref()) { 17628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 17638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidUpdateURL, tmp); 17648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 17658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 17668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 17678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 17688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Validate minimum Chrome version (if present). We don't need to store this, 17698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // since the extension is not valid if it is incorrect. 17708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kMinimumChromeVersion)) { 17718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string minimum_version_string; 17728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetString(keys::kMinimumChromeVersion, 17738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen &minimum_version_string)) { 17748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidMinimumChromeVersion; 17758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 17768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 17778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 17788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen scoped_ptr<Version> minimum_version( 17798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Version::GetVersionFromString(minimum_version_string)); 17808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!minimum_version.get()) { 17818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidMinimumChromeVersion; 17828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 17838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 17848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 17858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen chrome::VersionInfo current_version_info; 17868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!current_version_info.is_valid()) { 17878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen NOTREACHED(); 17888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 17898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 17908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 17918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen scoped_ptr<Version> current_version( 17928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Version::GetVersionFromString(current_version_info.Version())); 17938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!current_version.get()) { 17948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen DCHECK(false); 17958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 17968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 17978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 17988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (current_version->CompareTo(*minimum_version) < 0) { 17998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 18008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kChromeVersionTooLow, 18018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen l10n_util::GetStringUTF8(IDS_PRODUCT_NAME), 18028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen minimum_version_string); 18038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 18048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 18058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 18068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 18078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize converted_from_user_script (if present) 18088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen source.GetBoolean(keys::kConvertedFromUserScript, 1809513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &converted_from_user_script_); 18108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 18118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize icons (if present). 18128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kIcons)) { 18138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen DictionaryValue* icons_value = NULL; 18148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetDictionary(keys::kIcons, &icons_value)) { 18158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidIcons; 18168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 18178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 18188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 18198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < arraysize(kIconSizes); ++i) { 18208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string key = base::IntToString(kIconSizes[i]); 18218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (icons_value->HasKey(key)) { 18228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string icon_path; 18238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!icons_value->GetString(key, &icon_path)) { 18248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 18258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidIconPath, key); 18268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 18278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 18288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1829dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!icon_path.empty() && icon_path[0] == '/') 18308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen icon_path = icon_path.substr(1); 18318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 18328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (icon_path.empty()) { 18338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 18348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidIconPath, key); 18358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 18368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 18378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1838513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch icons_.Add(kIconSizes[i], icon_path); 18398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 18408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 18418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 18428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 18438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize themes (if present). 1844513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch is_theme_ = false; 18458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kTheme)) { 18468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Themes cannot contain extension keys. 18478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (ContainsNonThemeKeys(source)) { 18488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kThemesCannotContainExtensions; 18498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 18508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 18518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1852ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* theme_value = NULL; 18538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetDictionary(keys::kTheme, &theme_value)) { 18548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidTheme; 18558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 18568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 1857513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch is_theme_ = true; 18588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1859ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* images_value = NULL; 18608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (theme_value->GetDictionary(keys::kThemeImages, &images_value)) { 18618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Validate that the images are all strings 18628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (DictionaryValue::key_iterator iter = images_value->begin_keys(); 18638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen iter != images_value->end_keys(); ++iter) { 18648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string val; 18658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!images_value->GetString(*iter, &val)) { 18668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidThemeImages; 18678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 18688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 18698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 187072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen theme_images_.reset(images_value->DeepCopy()); 18718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 18728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1873ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* colors_value = NULL; 18748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (theme_value->GetDictionary(keys::kThemeColors, &colors_value)) { 18758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Validate that the colors are RGB or RGBA lists 18768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (DictionaryValue::key_iterator iter = colors_value->begin_keys(); 18778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen iter != colors_value->end_keys(); ++iter) { 1878ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* color_list = NULL; 1879ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen double alpha = 0.0; 1880ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int alpha_int = 0; 1881ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int color = 0; 18828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // The color must be a list 18838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!colors_value->GetListWithoutPathExpansion(*iter, &color_list) || 18848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // And either 3 items (RGB) or 4 (RGBA) 18858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ((color_list->GetSize() != 3) && 18868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ((color_list->GetSize() != 4) || 18878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // For RGBA, the fourth item must be a real or int alpha value 188872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen (!color_list->GetDouble(3, &alpha) && 18898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen !color_list->GetInteger(3, &alpha_int)))) || 18908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // For both RGB and RGBA, the first three items must be ints (R,G,B) 18918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen !color_list->GetInteger(0, &color) || 18928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen !color_list->GetInteger(1, &color) || 18938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen !color_list->GetInteger(2, &color)) { 18948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidThemeColors; 18958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 18968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 18978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 189872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen theme_colors_.reset(colors_value->DeepCopy()); 18998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 19008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1901ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* tints_value = NULL; 19028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (theme_value->GetDictionary(keys::kThemeTints, &tints_value)) { 19038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Validate that the tints are all reals. 19048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (DictionaryValue::key_iterator iter = tints_value->begin_keys(); 19058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen iter != tints_value->end_keys(); ++iter) { 1906ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* tint_list = NULL; 1907ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen double v = 0.0; 1908ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int vi = 0; 19098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!tints_value->GetListWithoutPathExpansion(*iter, &tint_list) || 19108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen tint_list->GetSize() != 3 || 191172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen !(tint_list->GetDouble(0, &v) || tint_list->GetInteger(0, &vi)) || 191272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen !(tint_list->GetDouble(1, &v) || tint_list->GetInteger(1, &vi)) || 191372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen !(tint_list->GetDouble(2, &v) || tint_list->GetInteger(2, &vi))) { 19148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidThemeTints; 19158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 19168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 19178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 191872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen theme_tints_.reset(tints_value->DeepCopy()); 19198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 19208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1921ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* display_properties_value = NULL; 19228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (theme_value->GetDictionary(keys::kThemeDisplayProperties, 19238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen &display_properties_value)) { 1924513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch theme_display_properties_.reset( 192572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen display_properties_value->DeepCopy()); 19268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 19278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 19288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 19298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 19308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 19318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize plugins (optional). 19328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kPlugins)) { 1933ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* list_value = NULL; 19348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetList(keys::kPlugins, &list_value)) { 19358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidPlugins; 19368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 19378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 19388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 19398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < list_value->GetSize(); ++i) { 1940ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* plugin_value = NULL; 1941731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string path_str; 19428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen bool is_public = false; 19438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 19448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!list_value->GetDictionary(i, &plugin_value)) { 19458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidPlugins; 19468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 19478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 19488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 19498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Get plugins[i].path. 1950731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!plugin_value->GetString(keys::kPluginsPath, &path_str)) { 19518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 19528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidPluginsPath, base::IntToString(i)); 19538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 19548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 19558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 19568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Get plugins[i].content (optional). 19578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (plugin_value->HasKey(keys::kPluginsPublic)) { 19588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!plugin_value->GetBoolean(keys::kPluginsPublic, &is_public)) { 19598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 19608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidPluginsPublic, base::IntToString(i)); 19618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 19628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 19638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 19648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1965ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We don't allow extension plugins to run on Chrome OS. We still 1966ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // parse the manifest entry so that error messages are consistently 1967ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // displayed across platforms. 1968ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if !defined(OS_CHROMEOS) 1969513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch plugins_.push_back(PluginInfo()); 1970513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch plugins_.back().path = path().AppendASCII(path_str); 1971513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch plugins_.back().is_public = is_public; 1972ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif 19738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 19748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 19758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 1976ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (CommandLine::ForCurrentProcess()->HasSwitch( 1977ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen switches::kEnableExperimentalExtensionApis) && 1978ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen source.HasKey(keys::kNaClModules)) { 1979ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* list_value = NULL; 1980ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!source.GetList(keys::kNaClModules, &list_value)) { 1981ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = errors::kInvalidNaClModules; 19828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 19838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 1984ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1985ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < list_value->GetSize(); ++i) { 1986ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* module_value = NULL; 1987ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string path_str; 1988ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string mime_type; 1989ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1990ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!list_value->GetDictionary(i, &module_value)) { 1991ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = errors::kInvalidNaClModules; 1992ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 1993ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 1994ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 1995ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Get nacl_modules[i].path. 1996ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!module_value->GetString(keys::kNaClModulesPath, &path_str)) { 1997ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 1998ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen errors::kInvalidNaClModulesPath, base::IntToString(i)); 1999ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 2000ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2001ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 2002ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Get nacl_modules[i].mime_type. 2003ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!module_value->GetString(keys::kNaClModulesMIMEType, &mime_type)) { 2004ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 2005ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen errors::kInvalidNaClModulesMIMEType, base::IntToString(i)); 2006ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 2007ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2008ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 2009ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen nacl_modules_.push_back(NaClModuleInfo()); 2010ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen nacl_modules_.back().url = GetResourceURL(path_str); 2011ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen nacl_modules_.back().mime_type = mime_type; 2012ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 20138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 20148ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 20158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize toolstrips. This is deprecated for public use. 20168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // NOTE(erikkay) Although deprecated, we intend to preserve this parsing 20178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // code indefinitely. Please contact me or Joi for details as to why. 20188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (CommandLine::ForCurrentProcess()->HasSwitch( 20198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen switches::kEnableExperimentalExtensionApis) && 20208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen source.HasKey(keys::kToolstrips)) { 2021ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* list_value = NULL; 20228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetList(keys::kToolstrips, &list_value)) { 20238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidToolstrips; 20248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 20258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 20268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 20278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < list_value->GetSize(); ++i) { 20288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen GURL toolstrip; 2029ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* toolstrip_value = NULL; 20308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string toolstrip_path; 20318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (list_value->GetString(i, &toolstrip_path)) { 20328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Support a simple URL value for backwards compatibility. 20338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen toolstrip = GetResourceURL(toolstrip_path); 20348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else if (list_value->GetDictionary(i, &toolstrip_value)) { 20358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!toolstrip_value->GetString(keys::kToolstripPath, 20368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen &toolstrip_path)) { 20378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 20388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidToolstrip, base::IntToString(i)); 20398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 20408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 20418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen toolstrip = GetResourceURL(toolstrip_path); 20428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else { 20438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 20448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidToolstrip, base::IntToString(i)); 20458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 20468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 2047513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch toolstrips_.push_back(toolstrip); 20488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 20498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 20508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 20518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize content scripts (optional). 20528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kContentScripts)) { 20538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ListValue* list_value; 20548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetList(keys::kContentScripts, &list_value)) { 20558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidContentScriptsList; 20568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 20578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 20588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 20598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < list_value->GetSize(); ++i) { 2060ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* content_script = NULL; 20618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!list_value->GetDictionary(i, &content_script)) { 20628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 20638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidContentScript, base::IntToString(i)); 20648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 20658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 20668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 20678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen UserScript script; 2068ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!LoadUserScriptHelper(content_script, i, flags, error, &script)) 2069731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; // Failed to parse script context definition. 20708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen script.set_extension_id(id()); 2071513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (converted_from_user_script_) { 20728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen script.set_emulate_greasemonkey(true); 2073731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick script.set_match_all_frames(true); // Greasemonkey matches all frames. 20748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 2075513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch content_scripts_.push_back(script); 20768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 20778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 20788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 20798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize page action (optional). 20808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen DictionaryValue* page_action_value = NULL; 20818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 20828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kPageActions)) { 2083ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* list_value = NULL; 20848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetList(keys::kPageActions, &list_value)) { 20858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidPageActionsList; 20868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 20878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 20888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 20898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen size_t list_value_length = list_value->GetSize(); 20908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 20918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (list_value_length == 0u) { 20928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // A list with zero items is allowed, and is equivalent to not having 20938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // a page_actions key in the manifest. Don't set |page_action_value|. 20948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else if (list_value_length == 1u) { 20958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!list_value->GetDictionary(0, &page_action_value)) { 20968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidPageAction; 20978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 20988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 20998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else { // list_value_length > 1u. 21008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidPageActionsListSize; 21018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 21028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 21038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else if (source.HasKey(keys::kPageAction)) { 21048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetDictionary(keys::kPageAction, &page_action_value)) { 21058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidPageAction; 21068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 21078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 21088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 21098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 21108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // If page_action_value is not NULL, then there was a valid page action. 21118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (page_action_value) { 2112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch page_action_.reset( 21138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen LoadExtensionActionHelper(page_action_value, error)); 2114513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!page_action_.get()) 21158ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; // Failed to parse page action definition. 21168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 21178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 21188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize browser action (optional). 21198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kBrowserAction)) { 2120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* browser_action_value = NULL; 21218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetDictionary(keys::kBrowserAction, &browser_action_value)) { 21228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidBrowserAction; 21238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 21248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 21258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2126513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch browser_action_.reset( 21278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen LoadExtensionActionHelper(browser_action_value, error)); 2128513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!browser_action_.get()) 21298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; // Failed to parse browser action definition. 21308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 21318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Initialize file browser actions (optional). 2133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (source.HasKey(keys::kFileBrowserHandlers)) { 2134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* file_browser_handlers_value = NULL; 2135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!source.GetList(keys::kFileBrowserHandlers, 2136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen &file_browser_handlers_value)) { 2137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = errors::kInvalidFileBrowserHandler; 2138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 2139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 2141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_browser_handlers_.reset( 2142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen LoadFileBrowserHandlers(file_browser_handlers_value, error)); 2143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!file_browser_handlers_.get()) 2144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; // Failed to parse file browser actions definition. 2145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 21478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Load App settings. 2148513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!LoadIsApp(manifest_value_.get(), error) || 2149513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch !LoadExtent(manifest_value_.get(), keys::kWebURLs, 2150513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch &extent_, 2151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen errors::kInvalidWebURLs, errors::kInvalidWebURL, 2152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen parse_strictness, error) || 2153513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch !EnsureNotHybridApp(manifest_value_.get(), error) || 2154513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch !LoadLaunchURL(manifest_value_.get(), error) || 2155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !LoadLaunchContainer(manifest_value_.get(), error) || 2156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !LoadAppIsolation(manifest_value_.get(), error)) { 21578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 21588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 21598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 21608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize options page url (optional). 2161513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Funtion LoadIsApp() set is_app_ above. 21628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kOptionsPage)) { 21638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string options_str; 21648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetString(keys::kOptionsPage, &options_str)) { 21658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidOptionsPage; 21668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 21678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 21688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 21698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (is_hosted_app()) { 21708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // hosted apps require an absolute URL. 21718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen GURL options_url(options_str); 21728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!options_url.is_valid() || 21738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen !(options_url.SchemeIs("http") || options_url.SchemeIs("https"))) { 21748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidOptionsPageInHostedApp; 21758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 21768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 2177513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch options_url_ = options_url; 21788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else { 21798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen GURL absolute(options_str); 21808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (absolute.is_valid()) { 21818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidOptionsPageExpectUrlInPackage; 21828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 21838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 2184513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch options_url_ = GetResourceURL(options_str); 2185513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!options_url_.is_valid()) { 21868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidOptionsPage; 21878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 21888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 21898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 21908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 21918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 21928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize the permissions (optional). 21938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kPermissions)) { 21948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen ListValue* permissions = NULL; 21958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetList(keys::kPermissions, &permissions)) { 21968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 21978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidPermissions, ""); 21988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 21998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 22008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 22018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < permissions->GetSize(); ++i) { 22028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string permission_str; 22038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!permissions->GetString(i, &permission_str)) { 22048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage( 22058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen errors::kInvalidPermission, base::IntToString(i)); 22068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 22078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 22088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Only COMPONENT extensions can use private APIs. 22108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // TODO(asargent) - We want a more general purpose mechanism for this, 22118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // and better error messages. (http://crbug.com/54013) 2212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!IsComponentOnlyPermission(permission_str) 2213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifndef NDEBUG 2214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen && !CommandLine::ForCurrentProcess()->HasSwitch( 2215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen switches::kExposePrivateExtensionApi) 2216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif 2217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ) { 22188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen continue; 22198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 22208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 22218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Remap the old unlimited storage permission name. 22228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (permission_str == kOldUnlimitedStoragePermission) 22238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen permission_str = kUnlimitedStoragePermission; 22248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 22258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (web_extent().is_empty() || location() == Extension::COMPONENT) { 22268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Check if it's a module permission. If so, enable that permission. 22278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (IsAPIPermission(permission_str)) { 222821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Only allow the experimental API permission if the command line 222921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // flag is present, or if the extension is a component of Chrome. 223021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (permission_str == Extension::kExperimentalPermission && 223121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen !CommandLine::ForCurrentProcess()->HasSwitch( 223221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen switches::kEnableExperimentalExtensionApis) && 223321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen location() != Extension::COMPONENT) { 223421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen *error = errors::kExperimentalFlagRequired; 223521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 223621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 2237513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch api_permissions_.insert(permission_str); 22388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen continue; 22398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 22408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else { 22418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Hosted apps only get access to a subset of the valid permissions. 22428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (IsHostedAppPermission(permission_str)) { 2243513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch api_permissions_.insert(permission_str); 22448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen continue; 22458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 22468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 22478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2248201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Check if it's a host pattern permission. 2249731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick URLPattern pattern = URLPattern(CanExecuteScriptEverywhere() ? 2250201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch URLPattern::SCHEME_ALL : kValidHostPermissionSchemes); 2251731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2252dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen URLPattern::ParseResult parse_result = pattern.Parse(permission_str, 2253dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen parse_strictness); 2254dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (parse_result == URLPattern::PARSE_SUCCESS) { 2255201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!CanSpecifyHostPermission(pattern)) { 2256201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch *error = ExtensionErrorUtils::FormatErrorMessage( 2257201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch errors::kInvalidPermissionScheme, base::IntToString(i)); 2258201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return false; 2259201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 22608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2261201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // The path component is not used for host permissions, so we force it 2262201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // to match all paths. 2263dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen pattern.SetPath("/*"); 2264201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (pattern.MatchesScheme(chrome::kFileScheme) && 2266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !CanExecuteScriptEverywhere()) { 2267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen wants_file_access_ = true; 2268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!(flags & ALLOW_FILE_ACCESS)) 2269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pattern.set_valid_schemes( 2270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); 2271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 2273201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch host_permissions_.push_back(pattern); 2274201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 22758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2276201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // If it's not a host permission, then it's probably an unknown API 2277201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // permission. Do not throw an error so extensions can retain 2278201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // backwards compatability (http://crbug.com/42742). 2279201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // TODO(jstritar): We can improve error messages by adding better 2280201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // validation of API permissions here. 2281dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // TODO(skerner): Consider showing the reason |permission_str| is not 2282dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // a valid URL pattern if it is almost valid. For example, if it has 2283dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // a valid scheme, and failed to parse because it has a port, show an 2284dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // error. 22858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 22868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 22878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Initialize background url (optional). 2289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (source.HasKey(keys::kBackground)) { 2290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::string background_str; 2291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!source.GetString(keys::kBackground, &background_str)) { 2292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = errors::kInvalidBackground; 2293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 2294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 2296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (is_hosted_app()) { 2297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Make sure "background" permission is set. 2298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (api_permissions_.find(kBackgroundPermission) == 2299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen api_permissions_.end()) { 2300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = errors::kBackgroundPermissionNeeded; 2301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 2302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Hosted apps require an absolute URL. 2304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL bg_page(background_str); 2305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!bg_page.is_valid()) { 2306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = errors::kInvalidBackgroundInHostedApp; 2307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 2308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 2310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!(bg_page.SchemeIs("https") || 2311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (CommandLine::ForCurrentProcess()->HasSwitch( 2312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen switches::kAllowHTTPBackgroundPage) && 2313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bg_page.SchemeIs("http")))) { 2314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *error = errors::kInvalidBackgroundInHostedApp; 2315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 2316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen background_url_ = bg_page; 2318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 2319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen background_url_ = GetResourceURL(background_str); 2320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 23238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kDefaultLocale)) { 232421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!source.GetString(keys::kDefaultLocale, &default_locale_) || 232521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen !l10n_util::IsValidLocaleSyntax(default_locale_)) { 23268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidDefaultLocale; 23278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 23288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 23298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 23308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 23318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Chrome URL overrides (optional) 23328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kChromeURLOverrides)) { 2333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* overrides = NULL; 23348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetDictionary(keys::kChromeURLOverrides, &overrides)) { 23358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidChromeURLOverrides; 23368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 23378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 23388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 23398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Validate that the overrides are all strings 23408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (DictionaryValue::key_iterator iter = overrides->begin_keys(); 23418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen iter != overrides->end_keys(); ++iter) { 23428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string page = *iter; 23438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string val; 23448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Restrict override pages to a list of supported URLs. 23458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if ((page != chrome::kChromeUINewTabHost && 23468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#if defined(TOUCH_UI) 23478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen page != chrome::kChromeUIKeyboardHost && 23488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen#endif 234972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined(OS_CHROMEOS) 235072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen page != chrome::kChromeUIActivationMessageHost && 235172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif 23528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen page != chrome::kChromeUIBookmarksHost && 23538ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen page != chrome::kChromeUIHistoryHost) || 23548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen !overrides->GetStringWithoutPathExpansion(*iter, &val)) { 23558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidChromeURLOverrides; 23568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 23578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 23588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Replace the entry with a fully qualified chrome-extension:// URL. 2359513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch chrome_url_overrides_[page] = GetResourceURL(val); 23608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 23618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 23628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // An extension may override at most one page. 23638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (overrides->size() > 1) { 23648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kMultipleOverrides; 23658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 23668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 23678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 23688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 23694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (source.HasKey(keys::kOmnibox)) { 23704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!source.GetString(keys::kOmniboxKeyword, &omnibox_keyword_) || 2371513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch omnibox_keyword_.empty()) { 23728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidOmniboxKeyword; 23738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 23748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 23758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 23768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 23778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize devtools page url (optional). 23788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kDevToolsPage)) { 23798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string devtools_str; 23808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetString(keys::kDevToolsPage, &devtools_str)) { 23818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidDevToolsPage; 23828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 23838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 23848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!HasApiPermission(Extension::kExperimentalPermission)) { 23858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kDevToolsExperimental; 23868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 23878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 2388513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch devtools_url_ = GetResourceURL(devtools_str); 23898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 23908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 239172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Initialize sidebar action (optional). 239272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (source.HasKey(keys::kSidebar)) { 2393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* sidebar_value = NULL; 239472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!source.GetDictionary(keys::kSidebar, &sidebar_value)) { 239572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *error = errors::kInvalidSidebar; 239672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 239772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 239872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!HasApiPermission(Extension::kExperimentalPermission)) { 239972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen *error = errors::kSidebarExperimental; 240072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 240172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 240272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sidebar_defaults_.reset(LoadExtensionSidebarDefaults(sidebar_value, error)); 240372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!sidebar_defaults_.get()) 240472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; // Failed to parse sidebar definition. 240572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 240672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 240721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Initialize text-to-speech voices (optional). 240821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (source.HasKey(keys::kTts)) { 2409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* tts_dict = NULL; 241021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!source.GetDictionary(keys::kTts, &tts_dict)) { 241121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen *error = errors::kInvalidTts; 241221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 241321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 241421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 241521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (tts_dict->HasKey(keys::kTtsVoices)) { 2416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ListValue* tts_voices = NULL; 241721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!tts_dict->GetList(keys::kTtsVoices, &tts_voices)) { 241821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen *error = errors::kInvalidTtsVoices; 241921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 242021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 242121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 242221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen for (size_t i = 0; i < tts_voices->GetSize(); i++) { 2423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DictionaryValue* one_tts_voice = NULL; 242421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!tts_voices->GetDictionary(i, &one_tts_voice)) { 242521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen *error = errors::kInvalidTtsVoices; 242621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 242721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 242821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 242921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen TtsVoice voice_data; 243021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (one_tts_voice->HasKey(keys::kTtsVoicesVoiceName)) { 243121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!one_tts_voice->GetString( 243221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen keys::kTtsVoicesVoiceName, &voice_data.voice_name)) { 243321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen *error = errors::kInvalidTtsVoicesVoiceName; 243421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 243521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 243621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 243721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (one_tts_voice->HasKey(keys::kTtsVoicesLocale)) { 243821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!one_tts_voice->GetString( 243921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen keys::kTtsVoicesLocale, &voice_data.locale) || 244021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen !l10n_util::IsValidLocaleSyntax(voice_data.locale)) { 244121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen *error = errors::kInvalidTtsVoicesLocale; 244221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 244321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 244421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 244521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (one_tts_voice->HasKey(keys::kTtsVoicesGender)) { 244621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!one_tts_voice->GetString( 244721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen keys::kTtsVoicesGender, &voice_data.gender) || 244821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen (voice_data.gender != keys::kTtsGenderMale && 244921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen voice_data.gender != keys::kTtsGenderFemale)) { 245021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen *error = errors::kInvalidTtsVoicesGender; 245121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 245221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 245321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 245421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 245521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen tts_voices_.push_back(voice_data); 245621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 245721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 245821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 245921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 24608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Initialize incognito behavior. Apps default to split mode, extensions 24618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // default to spanning. 2462513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch incognito_split_mode_ = is_app(); 24638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (source.HasKey(keys::kIncognito)) { 24648ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string value; 24658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (!source.GetString(keys::kIncognito, &value)) { 24668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidIncognitoBehavior; 24678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 24688ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 24698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (value == values::kIncognitoSpanning) { 2470513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch incognito_split_mode_ = false; 24718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else if (value == values::kIncognitoSplit) { 2472513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch incognito_split_mode_ = true; 24738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else { 24748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen *error = errors::kInvalidIncognitoBehavior; 24758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 24768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 24778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 24788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2479731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (HasMultipleUISurfaces()) { 2480731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick *error = errors::kOneUISurfaceOnly; 2481731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 2482731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 2483731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2484731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick InitEffectiveHostPermissions(); 2485731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 24868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Although |source| is passed in as a const, it's still possible to modify 24878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // it. This is dangerous since the utility process re-uses |source| after 24888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // it calls InitFromValue, passing it up to the browser process which calls 24898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // InitFromValue again. As a result, we need to make sure that nobody 24908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // accidentally modifies it. 2491513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch DCHECK(source.Equals(manifest_value_.get())); 24928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 24938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 24948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 24958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 24968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen// static 2497731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstd::string Extension::ChromeStoreLaunchURL() { 24988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string gallery_prefix = extension_urls::kGalleryBrowsePrefix; 24998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAppsGalleryURL)) 25008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen gallery_prefix = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 25018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen switches::kAppsGalleryURL); 25028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (EndsWith(gallery_prefix, "/", true)) 25038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen gallery_prefix = gallery_prefix.substr(0, gallery_prefix.length() - 1); 25048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return gallery_prefix; 25058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 25068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2507513209b27ff55e2841eac0e4120199c23acce758Ben MurdochGURL Extension::GetHomepageURL() const { 2508513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (homepage_url_.is_valid()) 2509513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return homepage_url_; 2510513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 25114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!UpdatesFromGallery()) 25128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return GURL(); 25138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2514731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO(erikkay): This may not be entirely correct with the webstore. 2515731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // I think it will have a mixture of /extensions/detail and /webstore/detail 2516731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // URLs. Perhaps they'll handle this nicely with redirects? 2517731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick GURL url(ChromeStoreLaunchURL() + std::string("/detail/") + id()); 25188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return url; 25198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 25208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2521513209b27ff55e2841eac0e4120199c23acce758Ben Murdochstd::set<FilePath> Extension::GetBrowserImages() const { 25228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::set<FilePath> image_paths; 25238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // TODO(viettrungluu): These |FilePath::FromWStringHack(UTF8ToWide())| 25248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // indicate that we're doing something wrong. 25258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 25268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Extension icons. 2527731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (ExtensionIconSet::IconMap::const_iterator iter = icons().map().begin(); 2528731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick iter != icons().map().end(); ++iter) { 25298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(iter->second))); 25308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 25318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 25328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Theme images. 25338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen DictionaryValue* theme_images = GetThemeImages(); 25348ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (theme_images) { 25358ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (DictionaryValue::key_iterator it = theme_images->begin_keys(); 25368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen it != theme_images->end_keys(); ++it) { 25378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string val; 25388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (theme_images->GetStringWithoutPathExpansion(*it, &val)) 25398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(val))); 25408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 25418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 25428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 25438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Page action icons. 2544731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (page_action()) { 2545731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::vector<std::string>* icon_paths = page_action()->icon_paths(); 25468ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (std::vector<std::string>::iterator iter = icon_paths->begin(); 25478ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen iter != icon_paths->end(); ++iter) { 25488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(*iter))); 25498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 25508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 25518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 25528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Browser action icons. 2553731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (browser_action()) { 2554731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::vector<std::string>* icon_paths = browser_action()->icon_paths(); 25558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (std::vector<std::string>::iterator iter = icon_paths->begin(); 25568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen iter != icon_paths->end(); ++iter) { 25578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen image_paths.insert(FilePath::FromWStringHack(UTF8ToWide(*iter))); 25588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 25598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 25608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 25618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return image_paths; 25628ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 25638ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 25648ae428e0fb7feea16d79853f29447469a93bedffKristian MonsenGURL Extension::GetFullLaunchURL() const { 2565731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!launch_local_path().empty()) 2566731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return url().Resolve(launch_local_path()); 25678ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen else 2568731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return GURL(launch_web_url()); 25698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 25708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 25718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenstatic std::string SizeToString(const gfx::Size& max_size) { 25728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return base::IntToString(max_size.width()) + "x" + 25738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen base::IntToString(max_size.height()); 25748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 25758ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2576731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// static 2577731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid Extension::SetScriptingWhitelist( 257872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const Extension::ScriptingWhitelist& whitelist) { 2579731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ScriptingWhitelist* current_whitelist = 258021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ExtensionConfig::GetInstance()->whitelist(); 2581731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick current_whitelist->clear(); 2582731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (ScriptingWhitelist::const_iterator it = whitelist.begin(); 2583731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick it != whitelist.end(); ++it) { 2584731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick current_whitelist->push_back(*it); 2585731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 2586731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 2587731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 258872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static 258972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst Extension::ScriptingWhitelist* Extension::GetScriptingWhitelist() { 259072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return ExtensionConfig::GetInstance()->whitelist(); 259172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 259272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 25938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenvoid Extension::SetCachedImage(const ExtensionResource& source, 25948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const SkBitmap& image, 2595513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const gfx::Size& original_size) const { 25968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen DCHECK(source.extension_root() == path()); // The resource must come from 25978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // this extension. 25988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const FilePath& path = source.relative_path(); 25998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen gfx::Size actual_size(image.width(), image.height()); 26008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (actual_size == original_size) { 2601513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch image_cache_[ImageCacheKey(path, std::string())] = image; 26028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } else { 2603513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch image_cache_[ImageCacheKey(path, SizeToString(actual_size))] = image; 26048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 26058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 26068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 26078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::HasCachedImage(const ExtensionResource& source, 2608513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const gfx::Size& max_size) const { 26098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen DCHECK(source.extension_root() == path()); // The resource must come from 26108ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // this extension. 26118ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return GetCachedImageImpl(source, max_size) != NULL; 26128ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 26138ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 26148ae428e0fb7feea16d79853f29447469a93bedffKristian MonsenSkBitmap Extension::GetCachedImage(const ExtensionResource& source, 2615513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const gfx::Size& max_size) const { 26168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen DCHECK(source.extension_root() == path()); // The resource must come from 26178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // this extension. 26188ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen SkBitmap* image = GetCachedImageImpl(source, max_size); 26198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return image ? *image : SkBitmap(); 26208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 26218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 26228ae428e0fb7feea16d79853f29447469a93bedffKristian MonsenSkBitmap* Extension::GetCachedImageImpl(const ExtensionResource& source, 2623513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const gfx::Size& max_size) const { 26248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const FilePath& path = source.relative_path(); 26258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 26268ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Look for exact size match. 2627513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ImageCache::iterator i = image_cache_.find( 2628513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ImageCacheKey(path, SizeToString(max_size))); 2629513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (i != image_cache_.end()) 26308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return &(i->second); 26318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 26328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // If we have the original size version cached, return that if it's small 26338ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // enough. 2634513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch i = image_cache_.find(ImageCacheKey(path, std::string())); 2635513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (i != image_cache_.end()) { 26368ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen SkBitmap& image = i->second; 26378ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (image.width() <= max_size.width() && 26388ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen image.height() <= max_size.height()) 26398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return &(i->second); 26408ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 26418ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 26428ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return NULL; 26438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 26448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 26458ae428e0fb7feea16d79853f29447469a93bedffKristian MonsenExtensionResource Extension::GetIconResource( 2646513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch int size, ExtensionIconSet::MatchType match_type) const { 2647731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string path = icons().Get(size, match_type); 26488ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (path.empty()) 26498ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return ExtensionResource(); 26508ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return GetResource(path); 26518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 26528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2653513209b27ff55e2841eac0e4120199c23acce758Ben MurdochGURL Extension::GetIconURL(int size, 2654513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ExtensionIconSet::MatchType match_type) const { 2655731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string path = icons().Get(size, match_type); 26568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (path.empty()) 26578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return GURL(); 26588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen else 26598ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return GetResourceURL(path); 26608ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 26618ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2662513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool Extension::CanSpecifyHostPermission(const URLPattern& pattern) const { 2663731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!pattern.match_all_urls() && 2664731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick pattern.MatchesScheme(chrome::kChromeUIScheme)) { 26658ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Only allow access to chrome://favicon to regular extensions. Component 26668ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // extensions can have access to all of chrome://*. 2667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return (pattern.host() == chrome::kChromeUIFaviconHost || 2668731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CanExecuteScriptEverywhere()); 26698ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 26708ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 26718ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Otherwise, the valid schemes were handled by URLPattern. 26728ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 26738ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 26748ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2675513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 26768ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::HasApiPermission( 26778ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const std::set<std::string>& api_permissions, 26788ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const std::string& function_name) { 26798ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen std::string permission_name = function_name; 26808ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 26818ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < kNumNonPermissionFunctionNames; ++i) { 26828ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (permission_name == kNonPermissionFunctionNames[i]) 26838ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 26848ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 26858ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 26868ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // See if this is a function or event name first and strip out the package. 26878ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Functions will be of the form package.function 26888ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // Events will be of the form package/id or package.optional.stuff 26898ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen size_t separator = function_name.find_first_of("./"); 26908ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (separator != std::string::npos) 26918ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen permission_name = function_name.substr(0, separator); 26928ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 26938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen // windows and tabs are the same permission. 26948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (permission_name == kWindowPermission) 26958ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen permission_name = Extension::kTabPermission; 26968ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 26978ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (api_permissions.count(permission_name)) 26988ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 26998ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 27008ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < kNumNonPermissionModuleNames; ++i) { 27018ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (permission_name == kNonPermissionModuleNames[i]) { 27028ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 27038ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 27048ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 27058ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 27068ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 27078ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 27088ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 27098ae428e0fb7feea16d79853f29447469a93bedffKristian Monsenbool Extension::HasHostPermission(const GURL& url) const { 2710731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (URLPatternList::const_iterator host = host_permissions().begin(); 2711731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick host != host_permissions().end(); ++host) { 2712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Non-component extensions can only access chrome://favicon and no other 2713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // chrome:// scheme urls. 2714ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (url.SchemeIs(chrome::kChromeUIScheme) && 2715ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen url.host() != chrome::kChromeUIFaviconHost && 2716ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen location() != Extension::COMPONENT) 2717ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 2718ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 27198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (host->MatchesUrl(url)) 27208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 27218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 27228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 27238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 27248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2725731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid Extension::InitEffectiveHostPermissions() { 2726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Some APIs effectively grant access to every site. New ones should be 2727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // added here. (I'm looking at you, network API) 2728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (HasApiPermission(api_permissions_, kProxyPermission) || 2729ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !devtools_url_.is_empty()) { 2730ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen URLPattern all_urls(URLPattern::SCHEME_ALL); 2731ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen all_urls.set_match_all_urls(true); 2732ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen effective_host_permissions_.AddPattern(all_urls); 2733ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return; 2734ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2735ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 2736731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (URLPatternList::const_iterator host = host_permissions().begin(); 2737731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick host != host_permissions().end(); ++host) 2738513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch effective_host_permissions_.AddPattern(*host); 27398ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2740731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (UserScriptList::const_iterator content_script = 2741731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick content_scripts().begin(); 2742731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick content_script != content_scripts().end(); ++content_script) { 27438ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen UserScript::PatternList::const_iterator pattern = 27448ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen content_script->url_patterns().begin(); 27458ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (; pattern != content_script->url_patterns().end(); ++pattern) 2746513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch effective_host_permissions_.AddPattern(*pattern); 2747731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 2748731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 2749731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2750ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool Extension::IsComponentOnlyPermission 2751ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (const std::string& permission) const { 2752ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (location() == Extension::COMPONENT) 2753ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 2754ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 2755ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Non-component extensions are not allowed to access private apis. 2756ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < Extension::kNumComponentPrivatePermissions; ++i) { 2757ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (permission == Extension::kComponentPrivatePermissionNames[i]) 2758ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 2759ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 2760ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 2761ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 2762ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 2763731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool Extension::HasMultipleUISurfaces() const { 2764731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int num_surfaces = 0; 2765731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2766731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (page_action()) 2767731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ++num_surfaces; 2768731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2769731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (browser_action()) 2770731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ++num_surfaces; 2771731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2772731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (is_app()) 2773731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ++num_surfaces; 2774731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2775731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return num_surfaces > 1; 2776731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 2777731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 277872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool Extension::CanExecuteScriptOnPage(const GURL& page_url, 2779ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const UserScript* script, 278072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::string* error) const { 2781731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // The gallery is special-cased as a restricted URL for scripting to prevent 2782731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // access to special JS bindings we expose to the gallery (and avoid things 2783731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // like extensions removing the "report abuse" link). 2784731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // TODO(erikkay): This seems like the wrong test. Shouldn't we we testing 2785731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // against the store app extent? 2786731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if ((page_url.host() == GURL(Extension::ChromeStoreLaunchURL()).host()) && 278772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen !CanExecuteScriptEverywhere() && 2788731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick !CommandLine::ForCurrentProcess()->HasSwitch( 2789731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick switches::kAllowScriptingGallery)) { 2790731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (error) 2791731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick *error = errors::kCannotScriptGallery; 2792731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 27938ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 27948ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2795ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (page_url.SchemeIs(chrome::kChromeUIScheme) && 2796ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !CanExecuteScriptEverywhere()) 2797ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 2798ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 279972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // If a script is specified, use its matches. 280072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (script) 280172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return script->MatchesUrl(page_url); 280272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 280372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Otherwise, see if this extension has permission to execute script 280472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // programmatically on pages. 280572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (size_t i = 0; i < host_permissions_.size(); ++i) { 280672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (host_permissions_[i].MatchesUrl(page_url)) 2807731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 2808731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 2809731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2810731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (error) { 2811731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick *error = ExtensionErrorUtils::FormatErrorMessage(errors::kCannotAccessPage, 2812731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick page_url.spec()); 2813731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 2814731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2815731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 28168ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 28178ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2818201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// static 2819201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool Extension::HasEffectiveAccessToAllHosts( 2820201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const ExtensionExtent& effective_host_permissions, 2821201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const std::set<std::string>& api_permissions) { 2822201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const URLPatternList patterns = effective_host_permissions.patterns(); 2823201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (URLPatternList::const_iterator host = patterns.begin(); 2824201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch host != patterns.end(); ++host) { 2825ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (host->match_all_urls() || 2826ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen (host->match_subdomains() && host->host().empty())) 28278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return true; 28288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 28298ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 28308ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 28318ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 28328ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2833201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool Extension::HasEffectiveAccessToAllHosts() const { 2834201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return HasEffectiveAccessToAllHosts(GetEffectiveHostPermissions(), 2835201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch api_permissions()); 2836201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 2837201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 2838201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool Extension::HasFullPermissions() const { 2839dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return !plugins().empty(); 2840201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 2841201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 284272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool Extension::ShowConfigureContextMenus() const { 284372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Don't show context menu for component extensions. We might want to show 284472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // options for component extension button but now there is no component 284572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // extension with options. All other menu items like uninstall have 284672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // no sense for component extensions. 284772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return location() != Extension::COMPONENT; 284872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 284972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2850513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool Extension::IsAPIPermission(const std::string& str) const { 28518ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen for (size_t i = 0; i < Extension::kNumPermissions; ++i) { 28528ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (str == Extension::kPermissions[i].name) { 285321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return true; 28548ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 28558ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen } 28568ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen return false; 28578ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 28588ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2859731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool Extension::CanExecuteScriptEverywhere() const { 2860ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (location() == Extension::COMPONENT 2861ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifndef NDEBUG 2862ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen || CommandLine::ForCurrentProcess()->HasSwitch( 2863ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen switches::kExposePrivateExtensionApi) 2864ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif 2865ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ) 2866731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 2867731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2868731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ScriptingWhitelist* whitelist = 286921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ExtensionConfig::GetInstance()->whitelist(); 2870731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2871731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick for (ScriptingWhitelist::const_iterator it = whitelist->begin(); 2872731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick it != whitelist->end(); ++it) { 2873731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (id() == *it) { 2874731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return true; 2875731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 2876731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 2877731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2878731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return false; 2879731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 2880731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2881dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool Extension::CanCaptureVisiblePage(const GURL& page_url, 2882dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string *error) const { 2883dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (HasHostPermission(page_url) || page_url.GetOrigin() == url()) 2884dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return true; 2885dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 2886dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (error) { 2887dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen *error = ExtensionErrorUtils::FormatErrorMessage(errors::kCannotAccessPage, 2888dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen page_url.spec()); 2889dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 2890dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 2891dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 2892dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 28934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochbool Extension::UpdatesFromGallery() const { 2894201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return update_url() == GalleryUpdateUrl(false) || 2895201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch update_url() == GalleryUpdateUrl(true); 28964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 28974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 2898dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool Extension::OverlapsWithOrigin(const GURL& origin) const { 2899dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (url() == origin) 2900dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return true; 2901dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 2902dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (web_extent().is_empty()) 2903dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 2904dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 2905dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Note: patterns and extents ignore port numbers. 2906dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen URLPattern origin_only_pattern(kValidWebExtentSchemes); 2907dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!origin_only_pattern.SetScheme(origin.scheme())) 2908dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 2909dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen origin_only_pattern.set_host(origin.host()); 2910dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen origin_only_pattern.SetPath("/*"); 2911dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 2912dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ExtensionExtent origin_only_pattern_list; 2913dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen origin_only_pattern_list.AddPattern(origin_only_pattern); 2914dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 2915dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return web_extent().OverlapsWith(origin_only_pattern_list); 2916dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 2917dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 29188ae428e0fb7feea16d79853f29447469a93bedffKristian MonsenExtensionInfo::ExtensionInfo(const DictionaryValue* manifest, 29198ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const std::string& id, 29208ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen const FilePath& path, 29218ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen Extension::Location location) 29228ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen : extension_id(id), 29238ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen extension_path(path), 29248ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen extension_location(location) { 29258ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen if (manifest) 292672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen extension_manifest.reset(manifest->DeepCopy()); 29278ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen} 29288ae428e0fb7feea16d79853f29447469a93bedffKristian Monsen 2929731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickExtensionInfo::~ExtensionInfo() {} 2930731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2931731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickUninstalledExtensionInfo::UninstalledExtensionInfo( 2932731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const Extension& extension) 2933731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : extension_id(extension.id()), 2934731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick extension_api_permissions(extension.api_permissions()), 293521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen extension_type(extension.GetType()), 2936731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick update_url(extension.update_url()) {} 2937731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 2938731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickUninstalledExtensionInfo::~UninstalledExtensionInfo() {} 293921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 294021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 294121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenUnloadedExtensionInfo::UnloadedExtensionInfo( 294221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const Extension* extension, 294321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen Reason reason) 294421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen : reason(reason), 294521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen already_disabled(false), 294621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen extension(extension) {} 2947