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