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