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 "a_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