Home | History | Annotate | Download | only in extensions
      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