1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_COMMON_EXTENSIONS_EXTENSION_H_ 6 #define CHROME_COMMON_EXTENSIONS_EXTENSION_H_ 7 #pragma once 8 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <vector> 13 14 #include "base/file_path.h" 15 #include "base/gtest_prod_util.h" 16 #include "base/memory/linked_ptr.h" 17 #include "base/memory/ref_counted.h" 18 #include "base/memory/scoped_ptr.h" 19 #include "chrome/common/extensions/extension_constants.h" 20 #include "chrome/common/extensions/extension_extent.h" 21 #include "chrome/common/extensions/extension_icon_set.h" 22 #include "chrome/common/extensions/user_script.h" 23 #include "chrome/common/extensions/url_pattern.h" 24 #include "googleurl/src/gurl.h" 25 #include "ui/gfx/size.h" 26 27 class DictionaryValue; 28 class ExtensionAction; 29 class ExtensionResource; 30 class ExtensionSidebarDefaults; 31 class FileBrowserHandler; 32 class ListValue; 33 class SkBitmap; 34 class Version; 35 36 // Represents a Chrome extension. 37 class Extension : public base::RefCountedThreadSafe<Extension> { 38 public: 39 typedef std::map<const std::string, GURL> URLOverrideMap; 40 typedef std::vector<std::string> ScriptingWhitelist; 41 typedef std::vector<linked_ptr<FileBrowserHandler> > FileBrowserHandlerList; 42 43 // What an extension was loaded from. 44 // NOTE: These values are stored as integers in the preferences and used 45 // in histograms so don't remove or reorder existing items. Just append 46 // to the end. 47 enum Location { 48 INVALID, 49 INTERNAL, // A crx file from the internal Extensions directory. 50 EXTERNAL_PREF, // A crx file from an external directory (via prefs). 51 EXTERNAL_REGISTRY, // A crx file from an external directory (via eg the 52 // registry on Windows). 53 LOAD, // --load-extension. 54 COMPONENT, // An integral component of Chrome itself, which 55 // happens to be implemented as an extension. We don't 56 // show these in the management UI. 57 EXTERNAL_PREF_DOWNLOAD, // A crx file from an external directory (via 58 // prefs), installed from an update URL. 59 EXTERNAL_POLICY_DOWNLOAD, // A crx file from an external directory (via 60 // admin policies), installed from an update URL. 61 62 NUM_LOCATIONS 63 }; 64 65 enum State { 66 DISABLED = 0, 67 ENABLED, 68 // An external extension that the user uninstalled. We should not reinstall 69 // such extensions on startup. 70 EXTERNAL_EXTENSION_UNINSTALLED, 71 NUM_STATES 72 }; 73 74 enum InstallType { 75 INSTALL_ERROR, 76 DOWNGRADE, 77 REINSTALL, 78 UPGRADE, 79 NEW_INSTALL 80 }; 81 82 // NOTE: If you change this list, you should also change kIconSizes in the cc 83 // file. 84 enum Icons { 85 EXTENSION_ICON_LARGE = 128, 86 EXTENSION_ICON_MEDIUM = 48, 87 EXTENSION_ICON_SMALL = 32, 88 EXTENSION_ICON_SMALLISH = 24, 89 EXTENSION_ICON_BITTY = 16, 90 }; 91 92 // Do not change the order of entries or remove entries in this list 93 // as this is used in UMA_HISTOGRAM_ENUMERATIONs about extensions. 94 enum Type { 95 TYPE_UNKNOWN = 0, 96 TYPE_EXTENSION, 97 TYPE_THEME, 98 TYPE_USER_SCRIPT, 99 TYPE_HOSTED_APP, 100 TYPE_PACKAGED_APP 101 }; 102 103 // An NPAPI plugin included in the extension. 104 struct PluginInfo { 105 FilePath path; // Path to the plugin. 106 bool is_public; // False if only this extension can load this plugin. 107 }; 108 109 // An NaCl module included in the extension. 110 struct NaClModuleInfo { 111 GURL url; 112 std::string mime_type; 113 }; 114 115 struct TtsVoice { 116 std::string voice_name; 117 std::string locale; 118 std::string gender; 119 }; 120 121 // When prompting the user to install or approve permissions, we display 122 // messages describing the effects of the permissions and not the permissions 123 // themselves. Each PermissionMessage represents one of the messages that is 124 // shown to the user. 125 class PermissionMessage { 126 public: 127 // Do not reorder or add new enumerations in this list. If you need to add a 128 // new enum, add it just prior to ID_ENUM_BOUNDARY and enter its l10n 129 // message in kMessageIds. 130 enum MessageId { 131 ID_UNKNOWN, 132 ID_NONE, 133 ID_BOOKMARKS, 134 ID_GEOLOCATION, 135 ID_BROWSING_HISTORY, 136 ID_TABS, 137 ID_MANAGEMENT, 138 ID_DEBUGGER, 139 ID_HOSTS_1, 140 ID_HOSTS_2, 141 ID_HOSTS_3, 142 ID_HOSTS_4_OR_MORE, 143 ID_HOSTS_ALL, 144 ID_FULL_ACCESS, 145 ID_ENUM_BOUNDARY 146 }; 147 148 // Creates a permission message with the given |message_id| and initializes 149 // its message to the appropriate value. 150 static PermissionMessage CreateFromMessageId(MessageId message_id); 151 152 // Creates the corresponding permission message for a list of hosts. This 153 // method exists because the hosts are presented as one message that depends 154 // on what and how many hosts there are. 155 static PermissionMessage CreateFromHostList( 156 const std::vector<std::string> hosts); 157 158 // Gets the id of the permission message, which can be used in UMA 159 // histograms. 160 MessageId message_id() const { return message_id_; } 161 162 // Gets a localized message describing this permission. Please note that 163 // the message will be empty for message types TYPE_NONE and TYPE_UNKNOWN. 164 const string16& message() const { return message_; } 165 166 // Comparator to work with std::set. 167 bool operator<(const PermissionMessage& that) const { 168 return message_id_ < that.message_id_; 169 } 170 171 private: 172 PermissionMessage(MessageId message_id, string16 message_); 173 174 // The index of the id in the array is its enum value. The first two values 175 // are non-existent message ids to act as placeholders for "unknown" and 176 // "none". 177 // Note: Do not change the order of the items in this list since they 178 // are used in a histogram. The order must match the MessageId order. 179 static const int kMessageIds[]; 180 181 MessageId message_id_; 182 string16 message_; 183 }; 184 185 typedef std::vector<PermissionMessage> PermissionMessages; 186 187 // A permission is defined by its |name| (what is used in the manifest), 188 // and the |message_id| that's used by install/update UI. 189 struct Permission { 190 const char* const name; 191 const PermissionMessage::MessageId message_id; 192 }; 193 194 enum InitFromValueFlags { 195 NO_FLAGS = 0, 196 197 // Usually, the id of an extension is generated by the "key" property of 198 // its manifest, but if |REQUIRE_KEY| is not set, a temporary ID will be 199 // generated based on the path. 200 REQUIRE_KEY = 1 << 0, 201 202 // |STRICT_ERROR_CHECKS| enables extra error checking, such as 203 // checks that URL patterns do not contain ports. This error 204 // checking may find an error that a previous version of 205 // Chrome did not flag. To avoid errors in installed extensions 206 // when Chrome is upgraded, strict error checking is only enabled 207 // when loading extensions as a developer would (such as loading 208 // an unpacked extension), or when loading an extension that is 209 // tied to a specific version of Chrome (such as a component 210 // extension). Most callers will set the |STRICT_ERROR_CHECKS| bit when 211 // Extension::ShouldDoStrictErrorChecking(location) returns true. 212 STRICT_ERROR_CHECKS = 1 << 1, 213 214 // |ALLOW_FILE_ACCESS| indicates that the user is allowing this extension 215 // to have file access. If it's not present, then permissions and content 216 // scripts that match file:/// URLs will be filtered out. 217 ALLOW_FILE_ACCESS = 1 << 2, 218 }; 219 220 static scoped_refptr<Extension> Create(const FilePath& path, 221 Location location, 222 const DictionaryValue& value, 223 int flags, 224 std::string* error); 225 226 // Return the update url used by gallery/webstore extensions. 227 static GURL GalleryUpdateUrl(bool secure); 228 229 // Given two install sources, return the one which should take priority 230 // over the other. If an extension is installed from two sources A and B, 231 // its install source should be set to GetHigherPriorityLocation(A, B). 232 static Location GetHigherPriorityLocation(Location loc1, Location loc2); 233 234 // Get's the install message id for |permission|. Returns 235 // MessageId::TYPE_NONE if none exists. 236 static PermissionMessage::MessageId GetPermissionMessageId( 237 const std::string& permission); 238 239 // Returns the full list of permission messages that this extension 240 // should display at install time. 241 PermissionMessages GetPermissionMessages() const; 242 243 // Returns the full list of permission messages that this extension 244 // should display at install time. The messages are returned as strings 245 // for convenience. 246 std::vector<string16> GetPermissionMessageStrings() const; 247 248 // Returns the distinct hosts that should be displayed in the install UI 249 // for the URL patterns |list|. This discards some of the detail that is 250 // present in the manifest to make it as easy as possible to process by 251 // users. In particular we disregard the scheme and path components of 252 // URLPatterns and de-dupe the result, which includes filtering out common 253 // hosts with differing RCDs (aka Registry Controlled Domains, most of which 254 // are Top Level Domains but also include exceptions like co.uk). 255 // NOTE: when de-duping hosts the preferred RCD will be returned, given this 256 // order of preference: .com, .net, .org, first in list. 257 static std::vector<std::string> GetDistinctHostsForDisplay( 258 const URLPatternList& list); 259 260 // Compares two URLPatternLists for security equality by returning whether 261 // the URL patterns in |new_list| contain additional distinct hosts compared 262 // to |old_list|. 263 static bool IsElevatedHostList( 264 const URLPatternList& old_list, const URLPatternList& new_list); 265 266 // Icon sizes used by the extension system. 267 static const int kIconSizes[]; 268 269 // Max size (both dimensions) for browser and page actions. 270 static const int kPageActionIconMaxSize; 271 static const int kBrowserActionIconMaxSize; 272 static const int kSidebarIconMaxSize; 273 274 // Each permission is a module that the extension is permitted to use. 275 // 276 // NOTE: To add a new permission, define it here, and add an entry to 277 // Extension::kPermissions. 278 static const char kBackgroundPermission[]; 279 static const char kBookmarkPermission[]; 280 static const char kContentSettingsPermission[]; 281 static const char kContextMenusPermission[]; 282 static const char kCookiePermission[]; 283 static const char kChromeosInfoPrivatePermissions[]; 284 static const char kDebuggerPermission[]; 285 static const char kExperimentalPermission[]; 286 static const char kFileBrowserHandlerPermission[]; 287 static const char kFileBrowserPrivatePermission[]; 288 static const char kGeolocationPermission[]; 289 static const char kHistoryPermission[]; 290 static const char kIdlePermission[]; 291 static const char kManagementPermission[]; 292 static const char kNotificationPermission[]; 293 static const char kProxyPermission[]; 294 static const char kTabPermission[]; 295 static const char kUnlimitedStoragePermission[]; 296 static const char kWebstorePrivatePermission[]; 297 298 static const Permission kPermissions[]; 299 static const size_t kNumPermissions; 300 static const char* const kHostedAppPermissionNames[]; 301 static const size_t kNumHostedAppPermissions; 302 static const char* const kComponentPrivatePermissionNames[]; 303 static const size_t kNumComponentPrivatePermissions; 304 305 // The old name for the unlimited storage permission, which is deprecated but 306 // still accepted as meaning the same thing as kUnlimitedStoragePermission. 307 static const char kOldUnlimitedStoragePermission[]; 308 309 // Valid schemes for web extent URLPatterns. 310 static const int kValidWebExtentSchemes; 311 312 // Valid schemes for host permission URLPatterns. 313 static const int kValidHostPermissionSchemes; 314 315 // Returns true if the string is one of the known hosted app permissions (see 316 // kHostedAppPermissionNames). 317 static bool IsHostedAppPermission(const std::string& permission); 318 319 // The name of the manifest inside an extension. 320 static const FilePath::CharType kManifestFilename[]; 321 322 // The name of locale folder inside an extension. 323 static const FilePath::CharType kLocaleFolder[]; 324 325 // The name of the messages file inside an extension. 326 static const FilePath::CharType kMessagesFilename[]; 327 328 #if defined(OS_WIN) 329 static const char kExtensionRegistryPath[]; 330 #endif 331 332 // The number of bytes in a legal id. 333 static const size_t kIdSize; 334 335 // The mimetype used for extensions. 336 static const char kMimeType[]; 337 338 // Checks to see if the extension has a valid ID. 339 static bool IdIsValid(const std::string& id); 340 341 // Generate an ID for an extension in the given path. 342 // Used while developing extensions, before they have a key. 343 static std::string GenerateIdForPath(const FilePath& file_name); 344 345 // Returns true if the specified file is an extension. 346 static bool IsExtension(const FilePath& file_name); 347 348 // Whether the |location| is external or not. 349 static inline bool IsExternalLocation(Location location) { 350 return location == Extension::EXTERNAL_PREF || 351 location == Extension::EXTERNAL_REGISTRY || 352 location == Extension::EXTERNAL_PREF_DOWNLOAD || 353 location == Extension::EXTERNAL_POLICY_DOWNLOAD; 354 } 355 356 // Whether extensions with |location| are auto-updatable or not. 357 static inline bool IsAutoUpdateableLocation(Location location) { 358 // Only internal and external extensions can be autoupdated. 359 return location == Extension::INTERNAL || 360 IsExternalLocation(location); 361 } 362 363 // Whether extensions with |location| can be uninstalled or not. Policy 364 // controlled extensions are silently auto-installed and updated, and cannot 365 // be disabled by the user. The same applies for internal components. 366 static inline bool UserMayDisable(Location location) { 367 return location != Extension::EXTERNAL_POLICY_DOWNLOAD && 368 location != Extension::COMPONENT; 369 } 370 371 // Whether extensions with |location| should be loaded with strict 372 // error checking. Strict error checks may flag errors older versions 373 // of chrome did not detect. To avoid breaking installed extensions, 374 // strict checks are disabled unless the location indicates that the 375 // developer is loading the extension, or the extension is a component 376 // of chrome. 377 static inline bool ShouldDoStrictErrorChecking(Location location) { 378 return location == Extension::LOAD || 379 location == Extension::COMPONENT; 380 } 381 382 // Unpacked extensions start off with file access since they are a developer 383 // feature. 384 static inline bool ShouldAlwaysAllowFileAccess(Location location) { 385 return location == Extension::LOAD; 386 } 387 388 // See Type definition above. 389 Type GetType() const; 390 391 // Returns an absolute url to a resource inside of an extension. The 392 // |extension_url| argument should be the url() from an Extension object. The 393 // |relative_path| can be untrusted user input. The returned URL will either 394 // be invalid() or a child of |extension_url|. 395 // NOTE: Static so that it can be used from multiple threads. 396 static GURL GetResourceURL(const GURL& extension_url, 397 const std::string& relative_path); 398 GURL GetResourceURL(const std::string& relative_path) const { 399 return GetResourceURL(url(), relative_path); 400 } 401 402 // Returns an extension resource object. |relative_path| should be UTF8 403 // encoded. 404 ExtensionResource GetResource(const std::string& relative_path) const; 405 406 // As above, but with |relative_path| following the file system's encoding. 407 ExtensionResource GetResource(const FilePath& relative_path) const; 408 409 // |input| is expected to be the text of an rsa public or private key. It 410 // tolerates the presence or absence of bracking header/footer like this: 411 // -----(BEGIN|END) [RSA PUBLIC/PRIVATE] KEY----- 412 // and may contain newlines. 413 static bool ParsePEMKeyBytes(const std::string& input, std::string* output); 414 415 // Does a simple base64 encoding of |input| into |output|. 416 static bool ProducePEM(const std::string& input, std::string* output); 417 418 // Generates an extension ID from arbitrary input. The same input string will 419 // always generate the same output ID. 420 static bool GenerateId(const std::string& input, std::string* output); 421 422 // Expects base64 encoded |input| and formats into |output| including 423 // the appropriate header & footer. 424 static bool FormatPEMForFileOutput(const std::string& input, 425 std::string* output, 426 bool is_public); 427 428 // Determine whether |new_extension| has increased privileges compared to 429 // its previously granted permissions, specified by |granted_apis|, 430 // |granted_extent| and |granted_full_access|. 431 static bool IsPrivilegeIncrease(const bool granted_full_access, 432 const std::set<std::string>& granted_apis, 433 const ExtensionExtent& granted_extent, 434 const Extension* new_extension); 435 436 // Given an extension and icon size, read it if present and decode it into 437 // result. In the browser process, this will DCHECK if not called on the 438 // file thread. To easily load extension images on the UI thread, see 439 // ImageLoadingTracker. 440 static void DecodeIcon(const Extension* extension, 441 Icons icon_size, 442 scoped_ptr<SkBitmap>* result); 443 444 // Given an icon_path and icon size, read it if present and decode it into 445 // result. In the browser process, this will DCHECK if not called on the 446 // file thread. To easily load extension images on the UI thread, see 447 // ImageLoadingTracker. 448 static void DecodeIconFromPath(const FilePath& icon_path, 449 Icons icon_size, 450 scoped_ptr<SkBitmap>* result); 451 452 // Returns the default extension/app icon (for extensions or apps that don't 453 // have one). 454 static const SkBitmap& GetDefaultIcon(bool is_app); 455 456 // Returns the base extension url for a given |extension_id|. 457 static GURL GetBaseURLFromExtensionId(const std::string& extension_id); 458 459 // Returns the url prefix for the extension/apps gallery. Can be set via the 460 // --apps-gallery-url switch. The URL returned will not contain a trailing 461 // slash. Do not use this as a prefix/extent for the store. Instead see 462 // ExtensionService::GetWebStoreApp or 463 // ExtensionService::IsDownloadFromGallery 464 static std::string ChromeStoreLaunchURL(); 465 466 // Adds an extension to the scripting whitelist. Used for testing only. 467 static void SetScriptingWhitelist(const ScriptingWhitelist& whitelist); 468 static const ScriptingWhitelist* GetScriptingWhitelist(); 469 470 // Returns true if the extension has the specified API permission. 471 static bool HasApiPermission(const std::set<std::string>& api_permissions, 472 const std::string& function_name); 473 474 // Whether the |effective_host_permissions| and |api_permissions| include 475 // effective access to all hosts. See the non-static version of the method 476 // for more details. 477 static bool HasEffectiveAccessToAllHosts( 478 const ExtensionExtent& effective_host_permissions, 479 const std::set<std::string>& api_permissions); 480 481 bool HasApiPermission(const std::string& function_name) const { 482 return HasApiPermission(this->api_permissions(), function_name); 483 } 484 485 const ExtensionExtent& GetEffectiveHostPermissions() const { 486 return effective_host_permissions_; 487 } 488 489 // Whether or not the extension is allowed permission for a URL pattern from 490 // the manifest. http, https, and chrome://favicon/ is allowed for all 491 // extensions, while component extensions are allowed access to 492 // chrome://resources. 493 bool CanSpecifyHostPermission(const URLPattern& pattern) const; 494 495 // Whether the extension has access to the given URL. 496 bool HasHostPermission(const GURL& url) const; 497 498 // Whether the extension has effective access to all hosts. This is true if 499 // there is a content script that matches all hosts, if there is a host 500 // permission grants access to all hosts (like <all_urls>) or an api 501 // permission that effectively grants access to all hosts (e.g. proxy, 502 // network, etc.) 503 bool HasEffectiveAccessToAllHosts() const; 504 505 // Whether the extension effectively has all permissions (for example, by 506 // having an NPAPI plugin). 507 bool HasFullPermissions() const; 508 509 // Whether context menu should be shown for page and browser actions. 510 bool ShowConfigureContextMenus() const; 511 512 // Returns the Homepage URL for this extension. If homepage_url was not 513 // specified in the manifest, this returns the Google Gallery URL. For 514 // third-party extensions, this returns a blank GURL. 515 GURL GetHomepageURL() const; 516 517 // Returns a list of paths (relative to the extension dir) for images that 518 // the browser might load (like themes and page action icons). 519 std::set<FilePath> GetBrowserImages() const; 520 521 // Get an extension icon as a resource or URL. 522 ExtensionResource GetIconResource( 523 int size, ExtensionIconSet::MatchType match_type) const; 524 GURL GetIconURL(int size, ExtensionIconSet::MatchType match_type) const; 525 526 // Gets the fully resolved absolute launch URL. 527 GURL GetFullLaunchURL() const; 528 529 // Image cache related methods. These are only valid on the UI thread and 530 // not maintained by this class. See ImageLoadingTracker for usage. The 531 // |original_size| parameter should be the size of the image at |source| 532 // before any scaling may have been done to produce the pixels in |image|. 533 void SetCachedImage(const ExtensionResource& source, 534 const SkBitmap& image, 535 const gfx::Size& original_size) const; 536 bool HasCachedImage(const ExtensionResource& source, 537 const gfx::Size& max_size) const; 538 SkBitmap GetCachedImage(const ExtensionResource& source, 539 const gfx::Size& max_size) const; 540 541 // Returns true if this extension can execute script on a page. If a 542 // UserScript object is passed, permission to run that specific script is 543 // checked (using its matches list). Otherwise, permission to execute script 544 // programmatically is checked (using the extension's host permission). 545 // 546 // This method is also aware of certain special pages that extensions are 547 // usually not allowed to run script on. 548 bool CanExecuteScriptOnPage(const GURL& page_url, 549 const UserScript* script, 550 std::string* error) const; 551 552 // Returns true if this extension is a COMPONENT extension, or if it is 553 // on the whitelist of extensions that can script all pages. 554 bool CanExecuteScriptEverywhere() const; 555 556 // Returns true if this extension is allowed to obtain the contents of a 557 // page as an image. Since a page may contain sensitive information, this 558 // is restricted to the extension's host permissions as well as the 559 // extension page itself. 560 bool CanCaptureVisiblePage(const GURL& page_url, std::string* error) const; 561 562 // Returns true if this extension updates itself using the extension 563 // gallery. 564 bool UpdatesFromGallery() const; 565 566 // Returns true if this extension or app includes areas within |origin|. 567 bool OverlapsWithOrigin(const GURL& origin) const; 568 569 // Accessors: 570 571 const FilePath& path() const { return path_; } 572 const GURL& url() const { return extension_url_; } 573 Location location() const { return location_; } 574 const std::string& id() const { return id_; } 575 const Version* version() const { return version_.get(); } 576 const std::string VersionString() const; 577 const std::string& name() const { return name_; } 578 const std::string& public_key() const { return public_key_; } 579 const std::string& description() const { return description_; } 580 bool converted_from_user_script() const { 581 return converted_from_user_script_; 582 } 583 const UserScriptList& content_scripts() const { return content_scripts_; } 584 ExtensionAction* page_action() const { return page_action_.get(); } 585 ExtensionAction* browser_action() const { return browser_action_.get(); } 586 ExtensionSidebarDefaults* sidebar_defaults() const { 587 return sidebar_defaults_.get(); 588 } 589 const FileBrowserHandlerList* file_browser_handlers() const { 590 return file_browser_handlers_.get(); 591 } 592 const std::vector<PluginInfo>& plugins() const { return plugins_; } 593 const std::vector<NaClModuleInfo>& nacl_modules() const { 594 return nacl_modules_; 595 } 596 const GURL& background_url() const { return background_url_; } 597 const GURL& options_url() const { return options_url_; } 598 const GURL& devtools_url() const { return devtools_url_; } 599 const std::vector<GURL>& toolstrips() const { return toolstrips_; } 600 const std::set<std::string>& api_permissions() const { 601 return api_permissions_; 602 } 603 const URLPatternList& host_permissions() const { return host_permissions_; } 604 const GURL& update_url() const { return update_url_; } 605 const ExtensionIconSet& icons() const { return icons_; } 606 const DictionaryValue* manifest_value() const { 607 return manifest_value_.get(); 608 } 609 const std::string default_locale() const { return default_locale_; } 610 const URLOverrideMap& GetChromeURLOverrides() const { 611 return chrome_url_overrides_; 612 } 613 const std::string omnibox_keyword() const { return omnibox_keyword_; } 614 bool incognito_split_mode() const { return incognito_split_mode_; } 615 const std::vector<TtsVoice>& tts_voices() const { return tts_voices_; } 616 617 bool wants_file_access() const { return wants_file_access_; } 618 619 // App-related. 620 bool is_app() const { return is_app_; } 621 bool is_hosted_app() const { return is_app() && !web_extent().is_empty(); } 622 bool is_packaged_app() const { return is_app() && web_extent().is_empty(); } 623 bool is_storage_isolated() const { return is_app() && is_storage_isolated_; } 624 const ExtensionExtent& web_extent() const { return extent_; } 625 const std::string& launch_local_path() const { return launch_local_path_; } 626 const std::string& launch_web_url() const { return launch_web_url_; } 627 extension_misc::LaunchContainer launch_container() const { 628 return launch_container_; 629 } 630 int launch_width() const { return launch_width_; } 631 int launch_height() const { return launch_height_; } 632 633 // Theme-related. 634 bool is_theme() const { return is_theme_; } 635 DictionaryValue* GetThemeImages() const { return theme_images_.get(); } 636 DictionaryValue* GetThemeColors() const {return theme_colors_.get(); } 637 DictionaryValue* GetThemeTints() const { return theme_tints_.get(); } 638 DictionaryValue* GetThemeDisplayProperties() const { 639 return theme_display_properties_.get(); 640 } 641 642 private: 643 friend class base::RefCountedThreadSafe<Extension>; 644 645 // We keep a cache of images loaded from extension resources based on their 646 // path and a string representation of a size that may have been used to 647 // scale it (or the empty string if the image is at its original size). 648 typedef std::pair<FilePath, std::string> ImageCacheKey; 649 typedef std::map<ImageCacheKey, SkBitmap> ImageCache; 650 651 // Normalize the path for use by the extension. On Windows, this will make 652 // sure the drive letter is uppercase. 653 static FilePath MaybeNormalizePath(const FilePath& path); 654 655 // Returns the distinct hosts that can be displayed in the install UI or be 656 // used for privilege comparisons. This discards some of the detail that is 657 // present in the manifest to make it as easy as possible to process by users. 658 // In particular we disregard the scheme and path components of URLPatterns 659 // and de-dupe the result, which includes filtering out common hosts with 660 // differing RCDs. If |include_rcd| is true, then the de-duped result 661 // will be the first full entry, including its RCD. So if the list was 662 // "*.google.co.uk" and "*.google.com", the returned value would just be 663 // "*.google.co.uk". Keeping the RCD in the result is useful for display 664 // purposes when you want to show the user one sample hostname from the list. 665 // If you need to compare two URLPatternLists for security equality, then set 666 // |include_rcd| to false, which will return a result like "*.google.", 667 // regardless of the order of the patterns. 668 static std::vector<std::string> GetDistinctHosts( 669 const URLPatternList& host_patterns, bool include_rcd); 670 671 Extension(const FilePath& path, Location location); 672 ~Extension(); 673 674 // Initialize the extension from a parsed manifest. 675 bool InitFromValue(const DictionaryValue& value, int flags, 676 std::string* error); 677 678 // Helper function for implementing HasCachedImage/GetCachedImage. A return 679 // value of NULL means there is no matching image cached (we allow caching an 680 // empty SkBitmap). 681 SkBitmap* GetCachedImageImpl(const ExtensionResource& source, 682 const gfx::Size& max_size) const; 683 684 // Helper method that loads a UserScript object from a 685 // dictionary in the content_script list of the manifest. 686 bool LoadUserScriptHelper(const DictionaryValue* content_script, 687 int definition_index, 688 int flags, 689 std::string* error, 690 UserScript* result); 691 692 // Helper method that loads either the include_globs or exclude_globs list 693 // from an entry in the content_script lists of the manifest. 694 bool LoadGlobsHelper(const DictionaryValue* content_script, 695 int content_script_index, 696 const char* globs_property_name, 697 std::string* error, 698 void(UserScript::*add_method)(const std::string& glob), 699 UserScript *instance); 700 701 // Helpers to load various chunks of the manifest. 702 bool LoadIsApp(const DictionaryValue* manifest, std::string* error); 703 bool LoadExtent(const DictionaryValue* manifest, 704 const char* key, 705 ExtensionExtent* extent, 706 const char* list_error, 707 const char* value_error, 708 URLPattern::ParseOption parse_strictness, 709 std::string* error); 710 bool LoadLaunchContainer(const DictionaryValue* manifest, std::string* error); 711 bool LoadLaunchURL(const DictionaryValue* manifest, std::string* error); 712 bool LoadAppIsolation(const DictionaryValue* manifest, std::string* error); 713 bool EnsureNotHybridApp(const DictionaryValue* manifest, std::string* error); 714 715 // Helper method to load an ExtensionAction from the page_action or 716 // browser_action entries in the manifest. 717 ExtensionAction* LoadExtensionActionHelper( 718 const DictionaryValue* extension_action, std::string* error); 719 720 // Helper method to load an FileBrowserHandlerList from the manifest. 721 FileBrowserHandlerList* LoadFileBrowserHandlers( 722 const ListValue* extension_actions, std::string* error); 723 // Helper method to load an FileBrowserHandler from manifest. 724 FileBrowserHandler* LoadFileBrowserHandler( 725 const DictionaryValue* file_browser_handlers, std::string* error); 726 727 // Helper method to load an ExtensionSidebarDefaults from the sidebar manifest 728 // entry. 729 ExtensionSidebarDefaults* LoadExtensionSidebarDefaults( 730 const DictionaryValue* sidebar, std::string* error); 731 732 // Calculates the effective host permissions from the permissions and content 733 // script petterns. 734 void InitEffectiveHostPermissions(); 735 736 // Returns true if the extension has more than one "UI surface". For example, 737 // an extension that has a browser action and a page action. 738 bool HasMultipleUISurfaces() const; 739 740 // Figures out if a source contains keys not associated with themes - we 741 // don't want to allow scripts and such to be bundled with themes. 742 bool ContainsNonThemeKeys(const DictionaryValue& source) const; 743 744 // Returns true if the string is one of the known api permissions (see 745 // kPermissions). 746 bool IsAPIPermission(const std::string& permission) const; 747 748 // Returns true if this is a component, or we are not attempting to access a 749 // component-private permission. 750 bool IsComponentOnlyPermission(const std::string& permission) const; 751 752 // The set of unique API install messages that the extension has. 753 // NOTE: This only includes messages related to permissions declared in the 754 // "permissions" key in the manifest. Permissions implied from other features 755 // of the manifest, like plugins and content scripts are not included. 756 std::set<PermissionMessage> GetSimplePermissionMessages() const; 757 758 // Cached images for this extension. This should only be touched on the UI 759 // thread. 760 mutable ImageCache image_cache_; 761 762 // A persistent, globally unique ID. An extension's ID is used in things 763 // like directory structures and URLs, and is expected to not change across 764 // versions. It is generated as a SHA-256 hash of the extension's public 765 // key, or as a hash of the path in the case of unpacked extensions. 766 std::string id_; 767 768 // The extension's human-readable name. Name is used for display purpose. It 769 // might be wrapped with unicode bidi control characters so that it is 770 // displayed correctly in RTL context. 771 // NOTE: Name is UTF-8 and may contain non-ascii characters. 772 std::string name_; 773 774 // The absolute path to the directory the extension is stored in. 775 FilePath path_; 776 777 // Default locale for fall back. Can be empty if extension is not localized. 778 std::string default_locale_; 779 780 // If true, a separate process will be used for the extension in incognito 781 // mode. 782 bool incognito_split_mode_; 783 784 // Defines the set of URLs in the extension's web content. 785 ExtensionExtent extent_; 786 787 // The set of host permissions that the extension effectively has access to, 788 // which is a merge of host_permissions_ and all of the match patterns in 789 // any content scripts the extension has. This is used to determine which 790 // URLs have the ability to load an extension's resources via embedded 791 // chrome-extension: URLs (see extension_protocols.cc). 792 ExtensionExtent effective_host_permissions_; 793 794 // The set of module-level APIs this extension can use. 795 std::set<std::string> api_permissions_; 796 797 // The icons for the extension. 798 ExtensionIconSet icons_; 799 800 // The base extension url for the extension. 801 GURL extension_url_; 802 803 // The location the extension was loaded from. 804 Location location_; 805 806 // The extension's version. 807 scoped_ptr<Version> version_; 808 809 // An optional longer description of the extension. 810 std::string description_; 811 812 // True if the extension was generated from a user script. (We show slightly 813 // different UI if so). 814 bool converted_from_user_script_; 815 816 // Paths to the content scripts the extension contains. 817 UserScriptList content_scripts_; 818 819 // The extension's page action, if any. 820 scoped_ptr<ExtensionAction> page_action_; 821 822 // The extension's browser action, if any. 823 scoped_ptr<ExtensionAction> browser_action_; 824 825 // The extension's file browser actions, if any. 826 scoped_ptr<FileBrowserHandlerList> file_browser_handlers_; 827 828 // The extension's sidebar, if any. 829 scoped_ptr<ExtensionSidebarDefaults> sidebar_defaults_; 830 831 // Optional list of NPAPI plugins and associated properties. 832 std::vector<PluginInfo> plugins_; 833 834 // Optional list of NaCl modules and associated properties. 835 std::vector<NaClModuleInfo> nacl_modules_; 836 837 // Optional URL to a master page of which a single instance should be always 838 // loaded in the background. 839 GURL background_url_; 840 841 // Optional URL to a page for setting options/preferences. 842 GURL options_url_; 843 844 // Optional URL to a devtools extension page. 845 GURL devtools_url_; 846 847 // Optional list of toolstrips and associated properties. 848 std::vector<GURL> toolstrips_; 849 850 // The public key used to sign the contents of the crx package. 851 std::string public_key_; 852 853 // A map of resource id's to relative file paths. 854 scoped_ptr<DictionaryValue> theme_images_; 855 856 // A map of color names to colors. 857 scoped_ptr<DictionaryValue> theme_colors_; 858 859 // A map of color names to colors. 860 scoped_ptr<DictionaryValue> theme_tints_; 861 862 // A map of display properties. 863 scoped_ptr<DictionaryValue> theme_display_properties_; 864 865 // Whether the extension is a theme. 866 bool is_theme_; 867 868 // The sites this extension has permission to talk to (using XHR, etc). 869 URLPatternList host_permissions_; 870 871 // The homepage for this extension. Useful if it is not hosted by Google and 872 // therefore does not have a Gallery URL. 873 GURL homepage_url_; 874 875 // URL for fetching an update manifest 876 GURL update_url_; 877 878 // A copy of the manifest that this extension was created from. 879 scoped_ptr<DictionaryValue> manifest_value_; 880 881 // A map of chrome:// hostnames (newtab, downloads, etc.) to Extension URLs 882 // which override the handling of those URLs. (see ExtensionOverrideUI). 883 URLOverrideMap chrome_url_overrides_; 884 885 // Whether this extension uses app features. 886 bool is_app_; 887 888 // Whether this extension requests isolated storage. 889 bool is_storage_isolated_; 890 891 // The local path inside the extension to use with the launcher. 892 std::string launch_local_path_; 893 894 // A web url to use with the launcher. Note that this might be relative or 895 // absolute. If relative, it is relative to web_origin. 896 std::string launch_web_url_; 897 898 // The window type that an app's manifest specifies to launch into. 899 // This is not always the window type an app will open into, because 900 // users can override the way each app launches. See 901 // ExtensionPrefs::GetLaunchContainer(), which looks at a per-app pref 902 // to decide what container an app will launch in. 903 extension_misc::LaunchContainer launch_container_; 904 905 // The default size of the container when launching. Only respected for 906 // containers like panels and windows. 907 int launch_width_; 908 int launch_height_; 909 910 // The Omnibox keyword for this extension, or empty if there is none. 911 std::string omnibox_keyword_; 912 913 // List of text-to-speech voices that this extension provides, if any. 914 std::vector<TtsVoice> tts_voices_; 915 916 // Whether the extension has host permissions or user script patterns that 917 // imply access to file:/// scheme URLs (the user may not have actually 918 // granted it that access). 919 bool wants_file_access_; 920 921 FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, 922 UpdateExtensionPreservesLocation); 923 FRIEND_TEST_ALL_PREFIXES(ExtensionTest, LoadPageActionHelper); 924 FRIEND_TEST_ALL_PREFIXES(ExtensionTest, InitFromValueInvalid); 925 FRIEND_TEST_ALL_PREFIXES(ExtensionTest, InitFromValueValid); 926 FRIEND_TEST_ALL_PREFIXES(ExtensionTest, InitFromValueValidNameInRTL); 927 FRIEND_TEST_ALL_PREFIXES(TabStripModelTest, Apps); 928 929 DISALLOW_COPY_AND_ASSIGN(Extension); 930 }; 931 932 typedef std::vector< scoped_refptr<const Extension> > ExtensionList; 933 typedef std::set<std::string> ExtensionIdSet; 934 935 // Handy struct to pass core extension info around. 936 struct ExtensionInfo { 937 ExtensionInfo(const DictionaryValue* manifest, 938 const std::string& id, 939 const FilePath& path, 940 Extension::Location location); 941 ~ExtensionInfo(); 942 943 scoped_ptr<DictionaryValue> extension_manifest; 944 std::string extension_id; 945 FilePath extension_path; 946 Extension::Location extension_location; 947 948 private: 949 DISALLOW_COPY_AND_ASSIGN(ExtensionInfo); 950 }; 951 952 // Struct used for the details of the EXTENSION_UNINSTALLED 953 // notification. 954 struct UninstalledExtensionInfo { 955 explicit UninstalledExtensionInfo(const Extension& extension); 956 ~UninstalledExtensionInfo(); 957 958 std::string extension_id; 959 std::set<std::string> extension_api_permissions; 960 Extension::Type extension_type; 961 GURL update_url; 962 }; 963 964 struct UnloadedExtensionInfo { 965 enum Reason { 966 DISABLE, // The extension is being disabled. 967 UPDATE, // The extension is being updated to a newer version. 968 UNINSTALL, // The extension is being uninstalled. 969 }; 970 971 Reason reason; 972 973 // Was the extension already disabled? 974 bool already_disabled; 975 976 // The extension being unloaded - this should always be non-NULL. 977 const Extension* extension; 978 979 UnloadedExtensionInfo(const Extension* extension, Reason reason); 980 }; 981 982 #endif // CHROME_COMMON_EXTENSIONS_EXTENSION_H_ 983