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