• 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_BROWSER_EXTENSIONS_EXTENSION_SERVICE_H_
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_H_
7 #pragma once
8 
9 #include <map>
10 #include <set>
11 #include <string>
12 #include <vector>
13 
14 #include "base/command_line.h"
15 #include "base/file_path.h"
16 #include "base/gtest_prod_util.h"
17 #include "base/memory/linked_ptr.h"
18 #include "base/memory/ref_counted.h"
19 #include "base/task.h"
20 #include "base/time.h"
21 #include "base/tuple.h"
22 #include "base/version.h"
23 #include "chrome/browser/extensions/apps_promo.h"
24 #include "chrome/browser/extensions/extension_icon_manager.h"
25 #include "chrome/browser/extensions/extension_menu_manager.h"
26 #include "chrome/browser/extensions/extension_prefs.h"
27 #include "chrome/browser/extensions/extension_process_manager.h"
28 #include "chrome/browser/extensions/extension_toolbar_model.h"
29 #include "chrome/browser/extensions/extensions_quota_service.h"
30 #include "chrome/browser/extensions/external_extension_provider_interface.h"
31 #include "chrome/browser/extensions/pending_extension_manager.h"
32 #include "chrome/browser/extensions/sandboxed_extension_unpacker.h"
33 #include "chrome/browser/prefs/pref_change_registrar.h"
34 #include "chrome/common/extensions/extension.h"
35 #include "content/browser/browser_thread.h"
36 #include "content/common/notification_observer.h"
37 #include "content/common/notification_registrar.h"
38 #include "content/common/property_bag.h"
39 
40 class ExtensionBrowserEventRouter;
41 class ExtensionPreferenceEventRouter;
42 class ExtensionServiceBackend;
43 struct ExtensionSyncData;
44 class ExtensionToolbarModel;
45 class ExtensionUpdater;
46 class GURL;
47 class PendingExtensionManager;
48 class Profile;
49 class Version;
50 
51 // This is an interface class to encapsulate the dependencies that
52 // various classes have on ExtensionService. This allows easy mocking.
53 class ExtensionServiceInterface {
54  public:
~ExtensionServiceInterface()55   virtual ~ExtensionServiceInterface() {}
56   virtual const ExtensionList* extensions() const = 0;
57   virtual const ExtensionList* disabled_extensions() const = 0;
58   virtual PendingExtensionManager* pending_extension_manager() = 0;
59   virtual void UpdateExtension(const std::string& id,
60                                const FilePath& path,
61                                const GURL& download_url) = 0;
62   virtual const Extension* GetExtensionById(const std::string& id,
63                                             bool include_disabled) const = 0;
64 
65   virtual bool UninstallExtension(const std::string& extension_id,
66                                   bool external_uninstall,
67                                   std::string* error) = 0;
68 
69   virtual bool IsExtensionEnabled(const std::string& extension_id) const = 0;
70   virtual bool IsExternalExtensionUninstalled(
71       const std::string& extension_id) const = 0;
72   virtual void EnableExtension(const std::string& extension_id) = 0;
73   virtual void DisableExtension(const std::string& extension_id) = 0;
74 
75   virtual void UpdateExtensionBlacklist(
76     const std::vector<std::string>& blacklist) = 0;
77   virtual void CheckAdminBlacklist() = 0;
78 
79   virtual bool IsIncognitoEnabled(const std::string& extension_id) const = 0;
80   virtual void SetIsIncognitoEnabled(const std::string& extension_id,
81                                      bool enabled) = 0;
82 
83   // Safe to call multiple times in a row.
84   //
85   // TODO(akalin): Remove this method (and others) once we refactor
86   // themes sync to not use it directly.
87   virtual void CheckForUpdatesSoon() = 0;
88 
89   // Take any actions required to make the local state of the
90   // extension match the state in |extension_sync_data| (including
91   // installing/uninstalling the extension).
92   //
93   // TODO(akalin): We'll eventually need a separate method for app
94   // sync.  See http://crbug.com/58077 and http://crbug.com/61447.
95   virtual void ProcessSyncData(
96       const ExtensionSyncData& extension_sync_data,
97       PendingExtensionInfo::ShouldAllowInstallPredicate should_allow) = 0;
98 
99   // TODO(akalin): Add a method like:
100   //
101   //   virtual void
102   //     GetInitialSyncData(bool (*filter)(Extension),
103   //                        map<string, ExtensionSyncData>* out) const;
104   //
105   // which would fill |out| with sync data for the extensions that
106   // match |filter|.  Sync would use this for the initial syncing
107   // step.
108 };
109 
110 // Manages installed and running Chromium extensions.
111 class ExtensionService
112     : public base::RefCountedThreadSafe<ExtensionService,
113                                         BrowserThread::DeleteOnUIThread>,
114       public ExtensionServiceInterface,
115       public ExternalExtensionProviderInterface::VisitorInterface,
116       public NotificationObserver {
117  public:
118   // Information about a registered component extension.
119   struct ComponentExtensionInfo {
ComponentExtensionInfoComponentExtensionInfo120     ComponentExtensionInfo(const std::string& manifest,
121                            const FilePath& root_directory)
122         : manifest(manifest),
123           root_directory(root_directory) {
124     }
125 
126     // The extension's manifest. This is required for component extensions so
127     // that ExtensionService doesn't need to go to disk to load them.
128     std::string manifest;
129 
130     // Directory where the extension is stored.
131     FilePath root_directory;
132   };
133 
134   // The name of the directory inside the profile where extensions are
135   // installed to.
136   static const char* kInstallDirectoryName;
137 
138   // If auto-updates are turned on, default to running every 5 hours.
139   static const int kDefaultUpdateFrequencySeconds = 60 * 60 * 5;
140 
141   // The name of the file that the current active version number is stored in.
142   static const char* kCurrentVersionFileName;
143 
144   // Determine if a given extension download should be treated as if it came
145   // from the gallery. Note that this is requires *both* that the download_url
146   // match and that the download was referred from a gallery page.
147   bool IsDownloadFromGallery(const GURL& download_url,
148                              const GURL& referrer_url);
149 
150   // Determine if the downloaded extension came from the theme mini-gallery,
151   // Used to test if we need to show the "Loading" dialog for themes.
152   static bool IsDownloadFromMiniGallery(const GURL& download_url);
153 
154   // Returns the Extension of hosted or packaged apps, NULL otherwise.
155   const Extension* GetInstalledApp(const GURL& url);
156 
157   // Returns whether the URL is from either a hosted or packaged app.
158   bool IsInstalledApp(const GURL& url);
159 
160   // Attempts to uninstall an extension from a given ExtensionService. Returns
161   // true iff the target extension exists.
162   static bool UninstallExtensionHelper(ExtensionService* extensions_service,
163                                        const std::string& extension_id);
164 
165   // Constructor stores pointers to |profile| and |extension_prefs| but
166   // ownership remains at caller.
167   ExtensionService(Profile* profile,
168                    const CommandLine* command_line,
169                    const FilePath& install_directory,
170                    ExtensionPrefs* extension_prefs,
171                    bool autoupdate_enabled,
172                    bool extensions_enabled);
173 
174   // Gets the list of currently installed extensions.
175   virtual const ExtensionList* extensions() const;
176   virtual const ExtensionList* disabled_extensions() const;
177   virtual const ExtensionList* terminated_extensions() const;
178 
179   // Gets the object managing the set of pending extensions.
180   virtual PendingExtensionManager* pending_extension_manager();
181 
182   // Registers an extension to be loaded as a component extension.
register_component_extension(const ComponentExtensionInfo & info)183   void register_component_extension(const ComponentExtensionInfo& info) {
184     component_extension_manifests_.push_back(info);
185   }
186 
install_directory()187   const FilePath& install_directory() const { return install_directory_; }
188 
apps_promo()189   AppsPromo* apps_promo() { return &apps_promo_; }
190 
191   // Whether this extension can run in an incognito window.
192   virtual bool IsIncognitoEnabled(const std::string& extension_id) const;
193   virtual void SetIsIncognitoEnabled(const std::string& extension_id,
194                                      bool enabled);
195 
196   // Returns true if the given extension can see events and data from another
197   // sub-profile (incognito to original profile, or vice versa).
198   bool CanCrossIncognito(const Extension* extension);
199 
200   // Whether this extension can inject scripts into pages with file URLs.
201   bool AllowFileAccess(const Extension* extension);
202   // Will reload the extension since this permission is applied at loading time
203   // only.
204   void SetAllowFileAccess(const Extension* extension, bool allow);
205 
206   // Getter and setter for the Browser Action visibility in the toolbar.
207   bool GetBrowserActionVisibility(const Extension* extension);
208   void SetBrowserActionVisibility(const Extension* extension, bool visible);
209 
210   // Whether the background page, if any, is ready. We don't load other
211   // components until then. If there is no background page, we consider it to
212   // be ready.
213   bool IsBackgroundPageReady(const Extension* extension);
214   void SetBackgroundPageReady(const Extension* extension);
215 
216   // Getter and setter for the flag that specifies whether the extension is
217   // being upgraded.
218   bool IsBeingUpgraded(const Extension* extension);
219   void SetBeingUpgraded(const Extension* extension, bool value);
220 
221   // Getter for the extension's runtime data PropertyBag.
222   PropertyBag* GetPropertyBag(const Extension* extension);
223 
224   // Initialize and start all installed extensions.
225   void Init();
226 
227   // Start up the extension event routers.
228   void InitEventRouters();
229 
230   // Look up an extension by ID.
231   virtual const Extension* GetExtensionById(const std::string& id,
232                                             bool include_disabled) const;
233 
234   // Looks up a terminated (crashed) extension by ID. GetExtensionById does
235   // not include terminated extensions.
236   virtual const Extension* GetTerminatedExtension(const std::string& id);
237 
238   // Updates a currently-installed extension with the contents from
239   // |extension_path|.
240   // TODO(aa): This method can be removed. ExtensionUpdater could use
241   // CrxInstaller directly instead.
242   virtual void UpdateExtension(const std::string& id,
243                                const FilePath& extension_path,
244                                const GURL& download_url);
245 
246   // Reloads the specified extension.
247   void ReloadExtension(const std::string& extension_id);
248 
249   // Uninstalls the specified extension. Callers should only call this method
250   // with extensions that exist. |external_uninstall| is a magical parameter
251   // that is only used to send information to ExtensionPrefs, which external
252   // callers should never set to true.
253   // TODO(aa): Remove |external_uninstall| -- this information should be passed
254   // to ExtensionPrefs some other way.
255   virtual bool UninstallExtension(const std::string& extension_id,
256                                   bool external_uninstall,
257                                   std::string* error);
258 
259   virtual bool IsExtensionEnabled(const std::string& extension_id) const;
260   virtual bool IsExternalExtensionUninstalled(
261       const std::string& extension_id) const;
262 
263   // Enable or disable an extension. No action if the extension is already
264   // enabled/disabled.
265   virtual void EnableExtension(const std::string& extension_id);
266   virtual void DisableExtension(const std::string& extension_id);
267 
268   // Updates the |extension|'s granted permissions lists to include all
269   // permissions in the |extension|'s manifest.
270   void GrantPermissions(const Extension* extension);
271 
272   // Updates the |extension|'s granted permissions lists to include all
273   // permissions in the |extension|'s manifest and re-enables the
274   // extension.
275   void GrantPermissionsAndEnableExtension(const Extension* extension);
276 
277   // Loads the extension from the directory |extension_path|.
278   void LoadExtension(const FilePath& extension_path);
279 
280   // Loads any component extensions.
281   void LoadComponentExtensions();
282 
283   // Loads particular component extension.
284   const Extension* LoadComponentExtension(const ComponentExtensionInfo& info);
285 
286   // Loads all known extensions (used by startup and testing code).
287   void LoadAllExtensions();
288 
289   // Continues loading all know extensions. It can be called from
290   // LoadAllExtensions or from file thread if we had to relocalize manifest
291   // (write_to_prefs is true in that case).
292   void ContinueLoadAllExtensions(ExtensionPrefs::ExtensionsInfo* info,
293                                  base::TimeTicks start_time,
294                                  bool write_to_prefs);
295 
296   // Check for updates (or potentially new extensions from external providers)
297   void CheckForExternalUpdates();
298 
299   // Unload the specified extension.
300   void UnloadExtension(const std::string& extension_id,
301                        UnloadedExtensionInfo::Reason reason);
302 
303   // Unload all extensions. This is currently only called on shutdown, and
304   // does not send notifications.
305   void UnloadAllExtensions();
306 
307   // Called only by testing.
308   void ReloadExtensions();
309 
310   // Scan the extension directory and clean up the cruft.
311   void GarbageCollectExtensions();
312 
313   // The App that represents the web store.
314   const Extension* GetWebStoreApp();
315 
316   // Lookup an extension by |url|.
317   const Extension* GetExtensionByURL(const GURL& url);
318 
319   // If there is an extension for the specified url it is returned. Otherwise
320   // returns the extension whose web extent contains |url|.
321   const Extension* GetExtensionByWebExtent(const GURL& url);
322 
323   // Returns an extension that contains any URL that overlaps with the given
324   // extent, if one exists.
325   const Extension* GetExtensionByOverlappingWebExtent(
326       const ExtensionExtent& extent);
327 
328   // Returns true if |url| should get extension api bindings and be permitted
329   // to make api calls. Note that this is independent of what extension
330   // permissions the given extension has been granted.
331   bool ExtensionBindingsAllowed(const GURL& url);
332 
333   // Returns the icon to display in the omnibox for the given extension.
334   const SkBitmap& GetOmniboxIcon(const std::string& extension_id);
335 
336   // Returns the icon to display in the omnibox popup window for the given
337   // extension.
338   const SkBitmap& GetOmniboxPopupIcon(const std::string& extension_id);
339 
340   // Called when the initial extensions load has completed.
341   virtual void OnLoadedInstalledExtensions();
342 
343   // Adds |extension| to this ExtensionService and notifies observers than an
344   // extension has been loaded.  Called by the backend after an extension has
345   // been loaded from a file and installed.
346   void AddExtension(const Extension* extension);
347 
348   // Called by the backend when an extension has been installed.
349   void OnExtensionInstalled(const Extension* extension);
350 
351   // Checks if the privileges requested by |extension| have increased, and if
352   // so, disables the extension and prompts the user to approve the change.
353   void DisableIfPrivilegeIncrease(const Extension* extension);
354 
355   // Go through each extensions in pref, unload blacklisted extensions
356   // and update the blacklist state in pref.
357   virtual void UpdateExtensionBlacklist(
358     const std::vector<std::string>& blacklist);
359 
360   // Go through each extension and unload those that the network admin has
361   // put on the blacklist (not to be confused with the Google managed blacklist
362   // set of extensions.
363   virtual void CheckAdminBlacklist();
364 
365   virtual void CheckForUpdatesSoon();
366 
367   virtual void ProcessSyncData(
368       const ExtensionSyncData& extension_sync_data,
369       PendingExtensionInfo::ShouldAllowInstallPredicate
370           should_allow_install);
371 
set_extensions_enabled(bool enabled)372   void set_extensions_enabled(bool enabled) { extensions_enabled_ = enabled; }
extensions_enabled()373   bool extensions_enabled() { return extensions_enabled_; }
374 
set_show_extensions_prompts(bool enabled)375   void set_show_extensions_prompts(bool enabled) {
376     show_extensions_prompts_ = enabled;
377   }
378 
show_extensions_prompts()379   bool show_extensions_prompts() {
380     return show_extensions_prompts_;
381   }
382 
383   Profile* profile();
384 
385   // Profile calls this when it is being destroyed so that we know not to call
386   // it.
387   void DestroyingProfile();
388 
389   // TODO(skerner): Change to const ExtensionPrefs& extension_prefs() const,
390   // ExtensionPrefs* mutable_extension_prefs().
391   ExtensionPrefs* extension_prefs();
392 
393   // Whether the extension service is ready.
394   // TODO(skerner): Get rid of this method.  crbug.com/63756
is_ready()395   bool is_ready() { return ready_; }
396 
397   // Note that this may return NULL if autoupdate is not turned on.
398   ExtensionUpdater* updater();
399 
toolbar_model()400   ExtensionToolbarModel* toolbar_model() { return &toolbar_model_; }
401 
quota_service()402   ExtensionsQuotaService* quota_service() { return &quota_service_; }
403 
menu_manager()404   ExtensionMenuManager* menu_manager() { return &menu_manager_; }
405 
browser_event_router()406   ExtensionBrowserEventRouter* browser_event_router() {
407     return browser_event_router_.get();
408   }
409 
410   // Notify the frontend that there was an error loading an extension.
411   // This method is public because ExtensionServiceBackend can post to here.
412   void ReportExtensionLoadError(const FilePath& extension_path,
413                                 const std::string& error,
414                                 NotificationType type,
415                                 bool be_noisy);
416 
417   // ExtensionHost of background page calls this method right after its render
418   // view has been created.
419   void DidCreateRenderViewForBackgroundPage(ExtensionHost* host);
420 
421   // For the extension in |version_path| with |id|, check to see if it's an
422   // externally managed extension.  If so, uninstall it.
423   void CheckExternalUninstall(const std::string& id);
424 
425   // Clear all ExternalExtensionProviders.
426   void ClearProvidersForTesting();
427 
428   // Adds an ExternalExtensionProviderInterface for the service to use during
429   // testing. Takes ownership of |test_provider|.
430   void AddProviderForTesting(ExternalExtensionProviderInterface* test_provider);
431 
432   // ExternalExtensionProvider::Visitor implementation.
433   virtual void OnExternalExtensionFileFound(const std::string& id,
434                                             const Version* version,
435                                             const FilePath& path,
436                                             Extension::Location location);
437 
438   virtual void OnExternalExtensionUpdateUrlFound(const std::string& id,
439                                                  const GURL& update_url,
440                                                  Extension::Location location);
441 
442   virtual void OnExternalProviderReady();
443 
444   // NotificationObserver
445   virtual void Observe(NotificationType type,
446                        const NotificationSource& source,
447                        const NotificationDetails& details);
448 
449   // Whether there are any apps installed. Component apps are not included.
450   bool HasApps() const;
451 
452   // Gets the set of loaded app ids. Component apps are not included.
453   ExtensionIdSet GetAppIds() const;
454 
455   // Record a histogram using the PermissionMessage enum values for each
456   // permission in |e|.
457   // NOTE: If this is ever called with high frequency, the implementation may
458   // need to be made more efficient.
459   static void RecordPermissionMessagesHistogram(
460       const Extension* e, const char* histogram);
461 
462  private:
463   friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
464   friend class DeleteTask<ExtensionService>;
465 
466   // Contains Extension data that can change during the life of the process,
467   // but does not persist across restarts.
468   struct ExtensionRuntimeData {
469     // True if the background page is ready.
470     bool background_page_ready;
471 
472     // True while the extension is being upgraded.
473     bool being_upgraded;
474 
475     // Generic bag of runtime data that users can associate with extensions.
476     PropertyBag property_bag;
477 
478     ExtensionRuntimeData();
479     ~ExtensionRuntimeData();
480   };
481   typedef std::map<std::string, ExtensionRuntimeData> ExtensionRuntimeDataMap;
482 
483   struct NaClModuleInfo {
484     NaClModuleInfo();
485     ~NaClModuleInfo();
486 
487     GURL url;
488     std::string mime_type;
489   };
490   typedef std::list<NaClModuleInfo> NaClModuleInfoList;
491 
492   virtual ~ExtensionService();
493 
494   // Clear all persistent data that may have been stored by the extension.
495   void ClearExtensionData(const GURL& extension_url);
496 
497   // Look up an extension by ID, optionally including either or both of enabled
498   // and disabled extensions.
499   const Extension* GetExtensionByIdInternal(const std::string& id,
500                                             bool include_enabled,
501                                             bool include_disabled) const;
502 
503 
504   // Keep track of terminated extensions.
505   void TrackTerminatedExtension(const Extension* extension);
506   void UntrackTerminatedExtension(const std::string& id);
507 
508   // Handles sending notification that |extension| was loaded.
509   void NotifyExtensionLoaded(const Extension* extension);
510 
511   // Handles sending notification that |extension| was unloaded.
512   void NotifyExtensionUnloaded(const Extension* extension,
513                                UnloadedExtensionInfo::Reason reason);
514 
515   // Helper that updates the active extension list used for crash reporting.
516   void UpdateActiveExtensionsInCrashReporter();
517 
518   // Helper method. Loads extension from prefs.
519   void LoadInstalledExtension(const ExtensionInfo& info, bool write_to_prefs);
520 
521   // We implement some Pepper plug-ins using NaCl to take advantage of NaCl's
522   // strong sandbox. Typically, these NaCl modules are stored in extensions
523   // and registered here. Not all NaCl modules need to register for a MIME
524   // type, just the ones that are responsible for rendering a particular MIME
525   // type, like application/pdf. Note: We only register NaCl modules in the
526   // browser process.
527   void RegisterNaClModule(const GURL& url, const std::string& mime_type);
528   void UnregisterNaClModule(const GURL& url);
529 
530   // Call UpdatePluginListWithNaClModules() after registering or unregistering
531   // a NaCl module to see those changes reflected in the PluginList.
532   void UpdatePluginListWithNaClModules();
533 
534   NaClModuleInfoList::iterator FindNaClModule(const GURL& url);
535 
536   // The profile this ExtensionService is part of.
537   Profile* profile_;
538 
539   // Preferences for the owning profile (weak reference).
540   ExtensionPrefs* extension_prefs_;
541 
542   // The current list of installed extensions.
543   // TODO(aa): This should use chrome/common/extensions/extension_set.h.
544   ExtensionList extensions_;
545 
546   // The list of installed extensions that have been disabled.
547   ExtensionList disabled_extensions_;
548 
549   // The list of installed extensions that have been terminated.
550   ExtensionList terminated_extensions_;
551 
552   // Used to quickly check if an extension was terminated.
553   std::set<std::string> terminated_extension_ids_;
554 
555   // Hold the set of pending extensions.
556   PendingExtensionManager pending_extension_manager_;
557 
558   // The map of extension IDs to their runtime data.
559   ExtensionRuntimeDataMap extension_runtime_data_;
560 
561   // The full path to the directory where extensions are installed.
562   FilePath install_directory_;
563 
564   // Whether or not extensions are enabled.
565   bool extensions_enabled_;
566 
567   // Whether to notify users when they attempt to install an extension.
568   bool show_extensions_prompts_;
569 
570   // The backend that will do IO on behalf of this instance.
571   scoped_refptr<ExtensionServiceBackend> backend_;
572 
573   // Used by dispatchers to limit API quota for individual extensions.
574   ExtensionsQuotaService quota_service_;
575 
576   // Record that Init() has been called, and NotificationType::EXTENSIONS_READY
577   // has fired.
578   bool ready_;
579 
580   // Our extension updater, if updates are turned on.
581   scoped_ptr<ExtensionUpdater> updater_;
582 
583   // The model that tracks extensions with BrowserAction buttons.
584   ExtensionToolbarModel toolbar_model_;
585 
586   // Map unloaded extensions' ids to their paths. When a temporarily loaded
587   // extension is unloaded, we lose the infomation about it and don't have
588   // any in the extension preferences file.
589   typedef std::map<std::string, FilePath> UnloadedExtensionPathMap;
590   UnloadedExtensionPathMap unloaded_extension_paths_;
591 
592   // Map disabled extensions' ids to their paths. When a temporarily loaded
593   // extension is disabled before it is reloaded, keep track of the path so that
594   // it can be re-enabled upon a successful load.
595   typedef std::map<std::string, FilePath> DisabledExtensionPathMap;
596   DisabledExtensionPathMap disabled_extension_paths_;
597 
598   // Map of inspector cookies that are detached, waiting for an extension to be
599   // reloaded.
600   typedef std::map<std::string, int> OrphanedDevTools;
601   OrphanedDevTools orphaned_dev_tools_;
602 
603   NotificationRegistrar registrar_;
604   PrefChangeRegistrar pref_change_registrar_;
605 
606   // Keeps track of menu items added by extensions.
607   ExtensionMenuManager menu_manager_;
608 
609   // Keeps track of favicon-sized omnibox icons for extensions.
610   ExtensionIconManager omnibox_icon_manager_;
611   ExtensionIconManager omnibox_popup_icon_manager_;
612 
613   // List of registered component extensions (see Extension::Location).
614   typedef std::vector<ComponentExtensionInfo> RegisteredComponentExtensions;
615   RegisteredComponentExtensions component_extension_manifests_;
616 
617   // Manages the promotion of the web store.
618   AppsPromo apps_promo_;
619 
620   // Flag to make sure event routers are only initialized once.
621   bool event_routers_initialized_;
622 
623   scoped_ptr<ExtensionBrowserEventRouter> browser_event_router_;
624 
625   scoped_ptr<ExtensionPreferenceEventRouter> preference_event_router_;
626 
627   // A collection of external extension providers.  Each provider reads
628   // a source of external extension information.  Examples include the
629   // windows registry and external_extensions.json.
630   ProviderCollection external_extension_providers_;
631 
632   // Set to true by OnExternalExtensionUpdateUrlFound() when an external
633   // extension URL is found.  Used in CheckForExternalUpdates() to see
634   // if an update check is needed to install pending extensions.
635   bool external_extension_url_added_;
636 
637   NaClModuleInfoList nacl_module_list_;
638 
639   FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
640                            InstallAppsWithUnlimtedStorage);
641   FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest,
642                            InstallAppsAndCheckStorageProtection);
643   DISALLOW_COPY_AND_ASSIGN(ExtensionService);
644 };
645 
646 #endif  // CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_H_
647