• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
message_id()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.
message()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.
IsExternalLocation(Location location)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.
IsAutoUpdateableLocation(Location location)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.
UserMayDisable(Location location)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.
ShouldDoStrictErrorChecking(Location location)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.
ShouldAlwaysAllowFileAccess(Location location)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);
GetResourceURL(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 
HasApiPermission(const std::string & function_name)481   bool HasApiPermission(const std::string& function_name) const {
482     return HasApiPermission(this->api_permissions(), function_name);
483   }
484 
GetEffectiveHostPermissions()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 
path()571   const FilePath& path() const { return path_; }
url()572   const GURL& url() const { return extension_url_; }
location()573   Location location() const { return location_; }
id()574   const std::string& id() const { return id_; }
version()575   const Version* version() const { return version_.get(); }
576   const std::string VersionString() const;
name()577   const std::string& name() const { return name_; }
public_key()578   const std::string& public_key() const { return public_key_; }
description()579   const std::string& description() const { return description_; }
converted_from_user_script()580   bool converted_from_user_script() const {
581     return converted_from_user_script_;
582   }
content_scripts()583   const UserScriptList& content_scripts() const { return content_scripts_; }
page_action()584   ExtensionAction* page_action() const { return page_action_.get(); }
browser_action()585   ExtensionAction* browser_action() const { return browser_action_.get(); }
sidebar_defaults()586   ExtensionSidebarDefaults* sidebar_defaults() const {
587     return sidebar_defaults_.get();
588   }
file_browser_handlers()589   const FileBrowserHandlerList* file_browser_handlers() const {
590     return file_browser_handlers_.get();
591   }
plugins()592   const std::vector<PluginInfo>& plugins() const { return plugins_; }
nacl_modules()593   const std::vector<NaClModuleInfo>& nacl_modules() const {
594     return nacl_modules_;
595   }
background_url()596   const GURL& background_url() const { return background_url_; }
options_url()597   const GURL& options_url() const { return options_url_; }
devtools_url()598   const GURL& devtools_url() const { return devtools_url_; }
toolstrips()599   const std::vector<GURL>& toolstrips() const { return toolstrips_; }
api_permissions()600   const std::set<std::string>& api_permissions() const {
601     return api_permissions_;
602   }
host_permissions()603   const URLPatternList& host_permissions() const { return host_permissions_; }
update_url()604   const GURL& update_url() const { return update_url_; }
icons()605   const ExtensionIconSet& icons() const { return icons_; }
manifest_value()606   const DictionaryValue* manifest_value() const {
607     return manifest_value_.get();
608   }
default_locale()609   const std::string default_locale() const { return default_locale_; }
GetChromeURLOverrides()610   const URLOverrideMap& GetChromeURLOverrides() const {
611     return chrome_url_overrides_;
612   }
omnibox_keyword()613   const std::string omnibox_keyword() const { return omnibox_keyword_; }
incognito_split_mode()614   bool incognito_split_mode() const { return incognito_split_mode_; }
tts_voices()615   const std::vector<TtsVoice>& tts_voices() const { return tts_voices_; }
616 
wants_file_access()617   bool wants_file_access() const { return wants_file_access_; }
618 
619   // App-related.
is_app()620   bool is_app() const { return is_app_; }
is_hosted_app()621   bool is_hosted_app() const { return is_app() && !web_extent().is_empty(); }
is_packaged_app()622   bool is_packaged_app() const { return is_app() && web_extent().is_empty(); }
is_storage_isolated()623   bool is_storage_isolated() const { return is_app() && is_storage_isolated_; }
web_extent()624   const ExtensionExtent& web_extent() const { return extent_; }
launch_local_path()625   const std::string& launch_local_path() const { return launch_local_path_; }
launch_web_url()626   const std::string& launch_web_url() const { return launch_web_url_; }
launch_container()627   extension_misc::LaunchContainer launch_container() const {
628     return launch_container_;
629   }
launch_width()630   int launch_width() const { return launch_width_; }
launch_height()631   int launch_height() const { return launch_height_; }
632 
633   // Theme-related.
is_theme()634   bool is_theme() const { return is_theme_; }
GetThemeImages()635   DictionaryValue* GetThemeImages() const { return theme_images_.get(); }
GetThemeColors()636   DictionaryValue* GetThemeColors() const {return theme_colors_.get(); }
GetThemeTints()637   DictionaryValue* GetThemeTints() const { return theme_tints_.get(); }
GetThemeDisplayProperties()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