[email protected] | c333e79 | 2012-01-06 16:57:39 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 6014d67 | 2008-12-05 00:38:25 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | eaa7dd18 | 2010-12-14 11:09:00 | [diff] [blame] | 5 | #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_H_ |
| 6 | #define CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_H_ |
[email protected] | 6014d67 | 2008-12-05 00:38:25 | [diff] [blame] | 7 | |
[email protected] | da50530a | 2009-06-15 17:43:01 | [diff] [blame] | 8 | #include <map> |
asargent | 56282ab7 | 2016-09-09 16:58:03 | [diff] [blame] | 9 | #include <memory> |
[email protected] | 31bb5ee6 | 2012-09-12 22:58:40 | [diff] [blame] | 10 | #include <set> |
[email protected] | b0beaa66 | 2009-02-26 00:04:15 | [diff] [blame] | 11 | #include <string> |
[email protected] | 6014d67 | 2008-12-05 00:38:25 | [diff] [blame] | 12 | #include <vector> |
| 13 | |
[email protected] | e078590 | 2011-05-19 23:34:17 | [diff] [blame] | 14 | #include "base/compiler_specific.h" |
[email protected] | 5799981 | 2013-02-24 05:40:52 | [diff] [blame] | 15 | #include "base/files/file_path.h" |
[email protected] | a918f87 | 2010-06-01 14:30:51 | [diff] [blame] | 16 | #include "base/gtest_prod_util.h" |
avi | a2f4804a | 2015-12-24 23:11:13 | [diff] [blame] | 17 | #include "base/macros.h" |
[email protected] | 3b63f8f4 | 2011-03-28 01:54:15 | [diff] [blame] | 18 | #include "base/memory/ref_counted.h" |
[email protected] | 14908b7 | 2011-04-20 06:54:36 | [diff] [blame] | 19 | #include "base/memory/weak_ptr.h" |
[email protected] | 00e7bef | 2013-06-10 20:35:17 | [diff] [blame] | 20 | #include "base/strings/string16.h" |
[email protected] | fdd679b | 2012-11-15 20:49:39 | [diff] [blame] | 21 | #include "chrome/browser/extensions/blacklist.h" |
binjin | 1569c9b | 2014-09-05 13:33:18 | [diff] [blame] | 22 | #include "chrome/browser/extensions/extension_management.h" |
xiyuan | f6a4c6a6 | 2016-04-19 18:14:54 | [diff] [blame] | 23 | #include "chrome/browser/extensions/install_gate.h" |
[email protected] | f3d3b38 | 2014-03-14 21:19:28 | [diff] [blame] | 24 | #include "chrome/browser/extensions/pending_extension_manager.h" |
weidongg | 0469523 | 2017-06-09 00:01:05 | [diff] [blame] | 25 | #include "chrome/browser/upgrade_observer.h" |
skym | 7160384 | 2016-10-10 18:17:31 | [diff] [blame] | 26 | #include "components/sync/model/string_ordinal.h" |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 27 | #include "content/public/browser/notification_observer.h" |
| 28 | #include "content/public/browser/notification_registrar.h" |
ginkage | 553af320 | 2015-02-04 12:39:09 | [diff] [blame] | 29 | #include "extensions/browser/crx_file_info.h" |
xiyuan | f6a4c6a6 | 2016-04-19 18:14:54 | [diff] [blame] | 30 | #include "extensions/browser/extension_prefs.h" |
[email protected] | 301116c6 | 2013-11-26 10:37:45 | [diff] [blame] | 31 | #include "extensions/browser/external_provider_interface.h" |
[email protected] | 4a1d9c0d | 2014-06-13 12:50:11 | [diff] [blame] | 32 | #include "extensions/browser/install_flag.h" |
[email protected] | 98b6d94 | 2013-11-10 00:34:07 | [diff] [blame] | 33 | #include "extensions/browser/process_manager.h" |
[email protected] | e43c61f | 2014-07-20 21:46:34 | [diff] [blame] | 34 | #include "extensions/browser/uninstall_reason.h" |
[email protected] | e4452d3 | 2013-11-15 23:07:41 | [diff] [blame] | 35 | #include "extensions/common/extension.h" |
[email protected] | 289c44b | 2013-12-17 03:26:57 | [diff] [blame] | 36 | #include "extensions/common/extension_set.h" |
[email protected] | d42c1115 | 2013-08-22 19:36:32 | [diff] [blame] | 37 | #include "extensions/common/manifest.h" |
brettw | 00899e6 | 2016-11-12 02:10:17 | [diff] [blame] | 38 | #include "extensions/features/features.h" |
[email protected] | 6014d67 | 2008-12-05 00:38:25 | [diff] [blame] | 39 | |
brettw | 00899e6 | 2016-11-12 02:10:17 | [diff] [blame] | 40 | #if !BUILDFLAG(ENABLE_EXTENSIONS) |
thestig | 44b9ce2 | 2014-10-17 03:19:28 | [diff] [blame] | 41 | #error "Extensions must be enabled" |
| 42 | #endif |
| 43 | |
mukai | 87a8d40 | 2014-09-15 20:15:09 | [diff] [blame] | 44 | class HostContentSettingsMap; |
[email protected] | 81e6378 | 2009-02-27 19:35:09 | [diff] [blame] | 45 | class Profile; |
[email protected] | aa14270 | 2010-03-26 01:26:33 | [diff] [blame] | 46 | |
[email protected] | 7f8f24f | 2012-11-15 19:40:14 | [diff] [blame] | 47 | namespace base { |
[email protected] | 2f3b1cc | 2014-03-17 23:07:15 | [diff] [blame] | 48 | class CommandLine; |
[email protected] | 7f8f24f | 2012-11-15 19:40:14 | [diff] [blame] | 49 | class SequencedTaskRunner; |
| 50 | } |
| 51 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 52 | namespace content { |
| 53 | class DevToolsAgentHost; |
| 54 | } |
| 55 | |
[email protected] | 9c70e0d9 | 2012-07-16 08:39:44 | [diff] [blame] | 56 | namespace extensions { |
ryanackley | 48bedbd | 2015-01-27 23:12:14 | [diff] [blame] | 57 | class AppDataMigrator; |
[email protected] | d8c8f25f | 2011-11-02 18:18:01 | [diff] [blame] | 58 | class ComponentLoader; |
[email protected] | bf3d9df | 2012-07-24 23:20:27 | [diff] [blame] | 59 | class CrxInstaller; |
[email protected] | c77f235 | 2012-08-08 22:07:58 | [diff] [blame] | 60 | class ExtensionActionStorageManager; |
[email protected] | 373daf97 | 2014-04-10 01:50:44 | [diff] [blame] | 61 | class ExtensionErrorController; |
[email protected] | bb1bc9b3 | 2013-12-21 03:09:14 | [diff] [blame] | 62 | class ExtensionRegistry; |
[email protected] | bd30672 | 2012-07-11 20:43:59 | [diff] [blame] | 63 | class ExtensionSystem; |
[email protected] | 42a0816 | 2012-03-16 18:09:11 | [diff] [blame] | 64 | class ExtensionUpdater; |
[email protected] | 2894a51 | 2014-06-26 19:03:56 | [diff] [blame] | 65 | class ExternalInstallManager; |
rdevlin.cronin | f5863da | 2015-09-10 19:21:45 | [diff] [blame] | 66 | class OneShotEvent; |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 67 | class RendererStartupHelper; |
[email protected] | 90878c5 | 2014-04-04 18:21:02 | [diff] [blame] | 68 | class SharedModuleService; |
[email protected] | a9aa62b31 | 2013-11-29 05:35:06 | [diff] [blame] | 69 | class UpdateObserver; |
[email protected] | 9f4e4f08 | 2013-06-21 07:11:19 | [diff] [blame] | 70 | } // namespace extensions |
[email protected] | 163ed19 | 2012-07-24 19:31:07 | [diff] [blame] | 71 | |
[email protected] | d1ca0ed1 | 2009-07-01 18:24:32 | [diff] [blame] | 72 | // This is an interface class to encapsulate the dependencies that |
[email protected] | 2859946f | 2011-04-04 18:18:06 | [diff] [blame] | 73 | // various classes have on ExtensionService. This allows easy mocking. |
[email protected] | f8aefb13 | 2013-10-30 09:29:52 | [diff] [blame] | 74 | class ExtensionServiceInterface |
| 75 | : public base::SupportsWeakPtr<ExtensionServiceInterface> { |
[email protected] | d1ca0ed1 | 2009-07-01 18:24:32 | [diff] [blame] | 76 | public: |
[email protected] | 2859946f | 2011-04-04 18:18:06 | [diff] [blame] | 77 | virtual ~ExtensionServiceInterface() {} |
[email protected] | ca97594 | 2014-01-07 12:06:47 | [diff] [blame] | 78 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 79 | // Gets the object managing the set of pending extensions. |
[email protected] | 3f213ad | 2012-07-26 23:39:41 | [diff] [blame] | 80 | virtual extensions::PendingExtensionManager* pending_extension_manager() = 0; |
[email protected] | 420a0ec | 2011-06-01 01:07:03 | [diff] [blame] | 81 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 82 | // Installs an update with the contents from |extension_path|. Returns true if |
| 83 | // the install can be started. Sets |out_crx_installer| to the installer if |
| 84 | // one was started. |
| 85 | // TODO(aa): This method can be removed. ExtensionUpdater could use |
| 86 | // CrxInstaller directly instead. |
[email protected] | 420a0ec | 2011-06-01 01:07:03 | [diff] [blame] | 87 | virtual bool UpdateExtension( |
ginkage | 553af320 | 2015-02-04 12:39:09 | [diff] [blame] | 88 | const extensions::CRXFileInfo& file, |
[email protected] | 044e8699 | 2014-01-24 22:59:11 | [diff] [blame] | 89 | bool file_ownership_passed, |
[email protected] | bf3d9df | 2012-07-24 23:20:27 | [diff] [blame] | 90 | extensions::CrxInstaller** out_crx_installer) = 0; |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 91 | |
[email protected] | eb24538 | 2014-07-28 22:23:14 | [diff] [blame] | 92 | // DEPRECATED. Use ExtensionRegistry instead. |
| 93 | // |
| 94 | // Looks up an extension by its ID. |
| 95 | // |
| 96 | // If |include_disabled| is false then this will only include enabled |
| 97 | // extensions. Use instead: |
| 98 | // |
| 99 | // ExtensionRegistry::enabled_extensions().GetByID(id). |
| 100 | // |
| 101 | // If |include_disabled| is true then this will also include disabled and |
| 102 | // blacklisted extensions (not terminated extensions). Use instead: |
| 103 | // |
| 104 | // ExtensionRegistry::GetExtensionById( |
| 105 | // id, ExtensionRegistry::ENABLED | |
| 106 | // ExtensionRegistry::DISABLED | |
| 107 | // ExtensionRegistry::BLACKLISTED) |
| 108 | // |
| 109 | // Or don't, because it's probably not something you ever need to know. |
[email protected] | f574c40 | 2012-12-04 23:20:31 | [diff] [blame] | 110 | virtual const extensions::Extension* GetExtensionById( |
| 111 | const std::string& id, |
| 112 | bool include_disabled) const = 0; |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 113 | |
[email protected] | eb24538 | 2014-07-28 22:23:14 | [diff] [blame] | 114 | // DEPRECATED: Use ExtensionRegistry instead. |
| 115 | // |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 116 | // Looks up an extension by ID, regardless of whether it's enabled, |
[email protected] | eb24538 | 2014-07-28 22:23:14 | [diff] [blame] | 117 | // disabled, blacklisted, or terminated. Use instead: |
| 118 | // |
sudarsana.nagineni | db93178 | 2015-06-05 12:01:50 | [diff] [blame] | 119 | // ExtensionRegistry::GetInstalledExtension(id). |
[email protected] | 1c321ee | 2012-05-21 03:02:34 | [diff] [blame] | 120 | virtual const extensions::Extension* GetInstalledExtension( |
[email protected] | 8001df2 | 2011-04-28 19:59:47 | [diff] [blame] | 121 | const std::string& id) const = 0; |
[email protected] | 2859946f | 2011-04-04 18:18:06 | [diff] [blame] | 122 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 123 | // Returns an update for an extension with the specified id, if installation |
| 124 | // of that update was previously delayed because the extension was in use. If |
| 125 | // no updates are pending for the extension returns NULL. |
[email protected] | 76b6544 | 2012-11-17 14:11:48 | [diff] [blame] | 126 | virtual const extensions::Extension* GetPendingExtensionUpdate( |
| 127 | const std::string& extension_id) const = 0; |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 128 | |
| 129 | // Finishes installation of an update for an extension with the specified id, |
| 130 | // when installation of that extension was previously delayed because the |
| 131 | // extension was in use. |
[email protected] | 6f610183 | 2012-11-27 22:10:48 | [diff] [blame] | 132 | virtual void FinishDelayedInstallation(const std::string& extension_id) = 0; |
[email protected] | 76b6544 | 2012-11-17 14:11:48 | [diff] [blame] | 133 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 134 | // Returns true if the extension with the given |extension_id| is enabled. |
mfoltz | 96f329c | 2016-01-13 18:16:58 | [diff] [blame] | 135 | // This will only return a valid answer for installed extensions (regardless |
| 136 | // of whether it is currently loaded or not). Loaded extensions return true |
| 137 | // if they are currently loaded or terminated. Unloaded extensions will |
| 138 | // return true if they are not blocked, disabled, blacklisted or uninstalled |
| 139 | // (for external extensions). |
[email protected] | c3cfb01 | 2011-04-06 22:07:35 | [diff] [blame] | 140 | virtual bool IsExtensionEnabled(const std::string& extension_id) const = 0; |
[email protected] | 2859946f | 2011-04-04 18:18:06 | [diff] [blame] | 141 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 142 | // Go through each extension and unload those that are not allowed to run by |
| 143 | // management policy providers (ie. network admin and Google-managed |
| 144 | // blacklist). |
[email protected] | 4ee07c6 | 2012-08-21 12:40:42 | [diff] [blame] | 145 | virtual void CheckManagementPolicy() = 0; |
[email protected] | 5ef47ec | 2010-01-28 05:58:05 | [diff] [blame] | 146 | |
[email protected] | 3120660 | 2011-04-13 23:07:32 | [diff] [blame] | 147 | // Safe to call multiple times in a row. |
| 148 | // |
[email protected] | 90310d9 | 2011-04-17 07:35:04 | [diff] [blame] | 149 | // TODO(akalin): Remove this method (and others) once we refactor |
| 150 | // themes sync to not use it directly. |
[email protected] | 3120660 | 2011-04-13 23:07:32 | [diff] [blame] | 151 | virtual void CheckForUpdatesSoon() = 0; |
[email protected] | 25ae015 | 2011-11-18 14:40:02 | [diff] [blame] | 152 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 153 | // Adds |extension| to this ExtensionService and notifies observers that the |
| 154 | // extensions have been loaded. |
[email protected] | 1c321ee | 2012-05-21 03:02:34 | [diff] [blame] | 155 | virtual void AddExtension(const extensions::Extension* extension) = 0; |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 156 | |
| 157 | // Check if we have preferences for the component extension and, if not or if |
| 158 | // the stored version differs, install the extension (without requirements |
| 159 | // checking) before calling AddExtension. |
[email protected] | 8c484b74 | 2012-11-29 06:05:36 | [diff] [blame] | 160 | virtual void AddComponentExtension( |
| 161 | const extensions::Extension* extension) = 0; |
[email protected] | 25ae015 | 2011-11-18 14:40:02 | [diff] [blame] | 162 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 163 | // Unload the specified extension. |
limasdf | 0deef204 | 2017-05-03 19:17:17 | [diff] [blame] | 164 | virtual void UnloadExtension(const std::string& extension_id, |
| 165 | extensions::UnloadedExtensionReason reason) = 0; |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 166 | |
| 167 | // Remove the specified component extension. |
[email protected] | 8b1ec20 | 2013-09-05 02:09:50 | [diff] [blame] | 168 | virtual void RemoveComponentExtension(const std::string& extension_id) = 0; |
[email protected] | 25ae015 | 2011-11-18 14:40:02 | [diff] [blame] | 169 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 170 | // Whether the extension service is ready. |
[email protected] | 25ae015 | 2011-11-18 14:40:02 | [diff] [blame] | 171 | virtual bool is_ready() = 0; |
[email protected] | 7f8f24f | 2012-11-15 19:40:14 | [diff] [blame] | 172 | |
| 173 | // Returns task runner for crx installation file I/O operations. |
| 174 | virtual base::SequencedTaskRunner* GetFileTaskRunner() = 0; |
[email protected] | d1ca0ed1 | 2009-07-01 18:24:32 | [diff] [blame] | 175 | }; |
[email protected] | fbcc4030 | 2009-06-12 20:45:45 | [diff] [blame] | 176 | |
[email protected] | fafdc84 | 2014-01-17 18:09:08 | [diff] [blame] | 177 | // Manages installed and running Chromium extensions. An instance is shared |
| 178 | // between normal and incognito profiles. |
[email protected] | eaa7dd18 | 2010-12-14 11:09:00 | [diff] [blame] | 179 | class ExtensionService |
[email protected] | 14908b7 | 2011-04-20 06:54:36 | [diff] [blame] | 180 | : public ExtensionServiceInterface, |
[email protected] | 5df038b | 2012-07-16 19:03:27 | [diff] [blame] | 181 | public extensions::ExternalProviderInterface::VisitorInterface, |
[email protected] | fdd679b | 2012-11-15 20:49:39 | [diff] [blame] | 182 | public content::NotificationObserver, |
binjin | 1569c9b | 2014-09-05 13:33:18 | [diff] [blame] | 183 | public extensions::Blacklist::Observer, |
weidongg | 0469523 | 2017-06-09 00:01:05 | [diff] [blame] | 184 | public extensions::ExtensionManagement::Observer, |
| 185 | public UpgradeObserver { |
[email protected] | 4f313d5 | 2009-05-21 00:42:29 | [diff] [blame] | 186 | public: |
[email protected] | 6aeac834 | 2010-10-01 20:21:18 | [diff] [blame] | 187 | // Attempts to uninstall an extension from a given ExtensionService. Returns |
| 188 | // true iff the target extension exists. |
[email protected] | eaa7dd18 | 2010-12-14 11:09:00 | [diff] [blame] | 189 | static bool UninstallExtensionHelper(ExtensionService* extensions_service, |
[email protected] | cc2f55c | 2014-07-08 02:19:04 | [diff] [blame] | 190 | const std::string& extension_id, |
[email protected] | e43c61f | 2014-07-20 21:46:34 | [diff] [blame] | 191 | extensions::UninstallReason reason); |
[email protected] | 6aeac834 | 2010-10-01 20:21:18 | [diff] [blame] | 192 | |
[email protected] | 73c4793 | 2010-12-06 18:13:43 | [diff] [blame] | 193 | // Constructor stores pointers to |profile| and |extension_prefs| but |
| 194 | // ownership remains at caller. |
[email protected] | eaa7dd18 | 2010-12-14 11:09:00 | [diff] [blame] | 195 | ExtensionService(Profile* profile, |
[email protected] | 2f3b1cc | 2014-03-17 23:07:15 | [diff] [blame] | 196 | const base::CommandLine* command_line, |
[email protected] | 650b2d5 | 2013-02-10 03:41:45 | [diff] [blame] | 197 | const base::FilePath& install_directory, |
[email protected] | 4575961 | 2012-07-10 17:21:23 | [diff] [blame] | 198 | extensions::ExtensionPrefs* extension_prefs, |
[email protected] | fdd679b | 2012-11-15 20:49:39 | [diff] [blame] | 199 | extensions::Blacklist* blacklist, |
[email protected] | 0436b10 | 2011-04-15 18:30:03 | [diff] [blame] | 200 | bool autoupdate_enabled, |
[email protected] | 4a10006a | 2013-05-17 23:18:35 | [diff] [blame] | 201 | bool extensions_enabled, |
| 202 | extensions::OneShotEvent* ready); |
[email protected] | 6014d67 | 2008-12-05 00:38:25 | [diff] [blame] | 203 | |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 204 | ~ExtensionService() override; |
[email protected] | 14908b7 | 2011-04-20 06:54:36 | [diff] [blame] | 205 | |
[email protected] | eb24538 | 2014-07-28 22:23:14 | [diff] [blame] | 206 | // ExtensionServiceInterface implementation. |
| 207 | // |
| 208 | // NOTE: Many of these methods are DEPRECATED. See the interface for details. |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 209 | extensions::PendingExtensionManager* pending_extension_manager() override; |
| 210 | const extensions::Extension* GetExtensionById( |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 211 | const std::string& id, |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 212 | bool include_disabled) const override; |
| 213 | const extensions::Extension* GetInstalledExtension( |
| 214 | const std::string& id) const override; |
ginkage | 553af320 | 2015-02-04 12:39:09 | [diff] [blame] | 215 | bool UpdateExtension(const extensions::CRXFileInfo& file, |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 216 | bool file_ownership_passed, |
| 217 | extensions::CrxInstaller** out_crx_installer) override; |
| 218 | bool IsExtensionEnabled(const std::string& extension_id) const override; |
limasdf | 0deef204 | 2017-05-03 19:17:17 | [diff] [blame] | 219 | void UnloadExtension(const std::string& extension_id, |
| 220 | extensions::UnloadedExtensionReason reason) override; |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 221 | void RemoveComponentExtension(const std::string& extension_id) override; |
| 222 | void AddExtension(const extensions::Extension* extension) override; |
| 223 | void AddComponentExtension(const extensions::Extension* extension) override; |
| 224 | const extensions::Extension* GetPendingExtensionUpdate( |
mostynb | a15bee1 | 2014-10-04 00:40:32 | [diff] [blame] | 225 | const std::string& extension_id) const override; |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 226 | void FinishDelayedInstallation(const std::string& extension_id) override; |
| 227 | void CheckManagementPolicy() override; |
| 228 | void CheckForUpdatesSoon() override; |
| 229 | bool is_ready() override; |
| 230 | base::SequencedTaskRunner* GetFileTaskRunner() override; |
[email protected] | aa14270 | 2010-03-26 01:26:33 | [diff] [blame] | 231 | |
lazyboy | e863417 | 2016-01-28 00:10:48 | [diff] [blame] | 232 | // ExternalProvider::VisitorInterface implementation. |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 233 | // Exposed for testing. |
lazyboy | e863417 | 2016-01-28 00:10:48 | [diff] [blame] | 234 | bool OnExternalExtensionFileFound( |
| 235 | const extensions::ExternalInstallInfoFile& info) override; |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 236 | bool OnExternalExtensionUpdateUrlFound( |
lazyboy | e863417 | 2016-01-28 00:10:48 | [diff] [blame] | 237 | const extensions::ExternalInstallInfoUpdateUrl& info, |
| 238 | bool is_initial_load) override; |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 239 | void OnExternalProviderReady( |
mostynb | a15bee1 | 2014-10-04 00:40:32 | [diff] [blame] | 240 | const extensions::ExternalProviderInterface* provider) override; |
lazyboy | e863417 | 2016-01-28 00:10:48 | [diff] [blame] | 241 | void OnExternalProviderUpdateComplete( |
| 242 | const extensions::ExternalProviderInterface* provider, |
lazyboy | 4aeef20 | 2016-09-07 21:28:59 | [diff] [blame] | 243 | const std::vector< |
| 244 | std::unique_ptr<extensions::ExternalInstallInfoUpdateUrl>>& |
lazyboy | e863417 | 2016-01-28 00:10:48 | [diff] [blame] | 245 | external_update_url_extensions, |
lazyboy | 4aeef20 | 2016-09-07 21:28:59 | [diff] [blame] | 246 | const std::vector<std::unique_ptr<extensions::ExternalInstallInfoFile>>& |
lazyboy | e863417 | 2016-01-28 00:10:48 | [diff] [blame] | 247 | external_file_extensions, |
| 248 | const std::set<std::string>& removed_extensions) override; |
[email protected] | ec5b50d | 2010-10-09 16:35:18 | [diff] [blame] | 249 | |
binjin | 1569c9b | 2014-09-05 13:33:18 | [diff] [blame] | 250 | // ExtensionManagement::Observer implementation: |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 251 | void OnExtensionManagementSettingsChanged() override; |
binjin | 1569c9b | 2014-09-05 13:33:18 | [diff] [blame] | 252 | |
[email protected] | 6014d67 | 2008-12-05 00:38:25 | [diff] [blame] | 253 | // Initialize and start all installed extensions. |
[email protected] | 9f1087e | 2009-06-15 17:29:32 | [diff] [blame] | 254 | void Init(); |
[email protected] | 6014d67 | 2008-12-05 00:38:25 | [diff] [blame] | 255 | |
[email protected] | 47b89656 | 2012-08-22 23:55:15 | [diff] [blame] | 256 | // Called when the associated Profile is going to be destroyed. |
| 257 | void Shutdown(); |
| 258 | |
[email protected] | 2380c6b | 2013-01-09 02:33:13 | [diff] [blame] | 259 | // Reloads the specified extension, sending the onLaunched() event to it if it |
| 260 | // currently has any window showing. |
[email protected] | bca4b83 | 2014-07-17 20:22:34 | [diff] [blame] | 261 | // Allows noisy failures. |
thestig | 7b4bd93 | 2014-09-09 22:44:31 | [diff] [blame] | 262 | // NOTE: Reloading an extension can invalidate |extension_id| and Extension |
| 263 | // pointers for the given extension. Consider making a copy of |extension_id| |
| 264 | // first and retrieving a new Extension pointer afterwards. |
[email protected] | 757d60a | 2014-05-23 00:11:44 | [diff] [blame] | 265 | void ReloadExtension(const std::string& extension_id); |
[email protected] | 9cddd470 | 2009-07-27 22:09:40 | [diff] [blame] | 266 | |
[email protected] | bca4b83 | 2014-07-17 20:22:34 | [diff] [blame] | 267 | // Suppresses noisy failures. |
| 268 | void ReloadExtensionWithQuietFailure(const std::string& extension_id); |
| 269 | |
[email protected] | 631cf82 | 2009-05-15 07:01:25 | [diff] [blame] | 270 | // Uninstalls the specified extension. Callers should only call this method |
[email protected] | cc2f55c | 2014-07-08 02:19:04 | [diff] [blame] | 271 | // with extensions that exist. |reason| lets the caller specify why the |
| 272 | // extension is uninstalled. |
[email protected] | 42d58f6 | 2014-07-31 01:32:45 | [diff] [blame] | 273 | // |
| 274 | // If the return value is true, |deletion_done_callback| is invoked when data |
| 275 | // deletion is done or at least is scheduled. |
[email protected] | 0bb29bd | 2014-04-30 21:39:18 | [diff] [blame] | 276 | virtual bool UninstallExtension(const std::string& extension_id, |
[email protected] | e43c61f | 2014-07-20 21:46:34 | [diff] [blame] | 277 | extensions::UninstallReason reason, |
[email protected] | 42d58f6 | 2014-07-31 01:32:45 | [diff] [blame] | 278 | const base::Closure& deletion_done_callback, |
[email protected] | 439f1e3 | 2013-12-09 20:09:09 | [diff] [blame] | 279 | base::string16* error); |
[email protected] | 631cf82 | 2009-05-15 07:01:25 | [diff] [blame] | 280 | |
[email protected] | 06f9256 | 2011-04-29 19:27:31 | [diff] [blame] | 281 | // Enables the extension. If the extension is already enabled, does |
| 282 | // nothing. |
[email protected] | 2859946f | 2011-04-04 18:18:06 | [diff] [blame] | 283 | virtual void EnableExtension(const std::string& extension_id); |
[email protected] | 06f9256 | 2011-04-29 19:27:31 | [diff] [blame] | 284 | |
treib | c119232 | 2015-05-20 12:56:07 | [diff] [blame] | 285 | // Disables the extension. If the extension is already disabled, just adds |
| 286 | // the |disable_reasons| (a bitmask of Extension::DisableReason - there can |
| 287 | // be multiple DisableReasons e.g. when an extension comes in disabled from |
| 288 | // Sync). If the extension cannot be disabled (due to policy), does nothing. |
| 289 | virtual void DisableExtension(const std::string& extension_id, |
| 290 | int disable_reasons); |
[email protected] | 0c6da50 | 2009-08-14 22:32:39 | [diff] [blame] | 291 | |
[email protected] | 3082fe3 | 2013-08-06 11:12:38 | [diff] [blame] | 292 | // Disable non-default and non-managed extensions with ids not in |
| 293 | // |except_ids|. Default extensions are those from the Web Store with |
| 294 | // |was_installed_by_default| flag. |
mtomasz | 294bb3e | 2017-01-24 02:17:52 | [diff] [blame] | 295 | void DisableUserExtensionsExcept(const std::vector<std::string>& except_ids); |
[email protected] | e516e4c | 2013-06-12 17:41:14 | [diff] [blame] | 296 | |
mlerman | 6a37b6a4 | 2014-11-26 22:10:53 | [diff] [blame] | 297 | // Puts all extensions in a blocked state: Unloading every extension, and |
| 298 | // preventing them from ever loading until UnblockAllExtensions is called. |
| 299 | // This state is stored in preferences, so persists until Chrome restarts. |
| 300 | // |
| 301 | // Component, external component and whitelisted policy installed extensions |
| 302 | // are exempt from being Blocked (see CanBlockExtension). |
| 303 | void BlockAllExtensions(); |
| 304 | |
| 305 | // All blocked extensions are reverted to their previous state, and are |
| 306 | // reloaded. Newly added extensions are no longer automatically blocked. |
| 307 | void UnblockAllExtensions(); |
| 308 | |
[email protected] | 8d888c1 | 2010-11-30 00:00:25 | [diff] [blame] | 309 | // Updates the |extension|'s granted permissions lists to include all |
[email protected] | 8d888c1 | 2010-11-30 00:00:25 | [diff] [blame] | 310 | // permissions in the |extension|'s manifest and re-enables the |
| 311 | // extension. |
[email protected] | 1c321ee | 2012-05-21 03:02:34 | [diff] [blame] | 312 | void GrantPermissionsAndEnableExtension( |
[email protected] | 009633c | 2013-03-07 22:08:28 | [diff] [blame] | 313 | const extensions::Extension* extension); |
[email protected] | 8d888c1 | 2010-11-30 00:00:25 | [diff] [blame] | 314 | |
[email protected] | be08386 | 2012-09-01 03:53:45 | [diff] [blame] | 315 | // Updates the |extension|'s granted permissions lists to include all |
| 316 | // permissions in the |extensions|'s manifest. |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 317 | void GrantPermissions(const extensions::Extension* extension); |
[email protected] | be08386 | 2012-09-01 03:53:45 | [diff] [blame] | 318 | |
[email protected] | 9f1087e | 2009-06-15 17:29:32 | [diff] [blame] | 319 | // Check for updates (or potentially new extensions from external providers) |
[email protected] | 93fd78f4 | 2009-07-10 16:43:17 | [diff] [blame] | 320 | void CheckForExternalUpdates(); |
[email protected] | 9f1087e | 2009-06-15 17:29:32 | [diff] [blame] | 321 | |
[email protected] | bc151cf9 | 2013-02-12 04:57:26 | [diff] [blame] | 322 | // Informs the service that an extension's files are in place for loading. |
| 323 | // |
[email protected] | 4a1d9c0d | 2014-06-13 12:50:11 | [diff] [blame] | 324 | // |extension| the extension |
| 325 | // |page_ordinal| the location of the extension in the app launcher |
| 326 | // |install_flags| a bitmask of extensions::InstallFlags |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 327 | void OnExtensionInstalled(const extensions::Extension* extension, |
| 328 | const syncer::StringOrdinal& page_ordinal, |
[email protected] | 4a1d9c0d | 2014-06-13 12:50:11 | [diff] [blame] | 329 | int install_flags); |
| 330 | void OnExtensionInstalled(const extensions::Extension* extension, |
| 331 | const syncer::StringOrdinal& page_ordinal) { |
| 332 | OnExtensionInstalled(extension, |
| 333 | page_ordinal, |
| 334 | static_cast<int>(extensions::kInstallFlagNone)); |
| 335 | } |
[email protected] | 0db124b0 | 2012-11-07 04:55:05 | [diff] [blame] | 336 | |
[email protected] | 9f4e4f08 | 2013-06-21 07:11:19 | [diff] [blame] | 337 | // Checks for delayed installation for all pending installs. |
| 338 | void MaybeFinishDelayedInstallations(); |
| 339 | |
[email protected] | 406027c0 | 2010-09-27 08:03:18 | [diff] [blame] | 340 | // ExtensionHost of background page calls this method right after its render |
| 341 | // view has been created. |
[email protected] | 3a1dc57 | 2012-07-31 22:25:13 | [diff] [blame] | 342 | void DidCreateRenderViewForBackgroundPage(extensions::ExtensionHost* host); |
[email protected] | 406027c0 | 2010-09-27 08:03:18 | [diff] [blame] | 343 | |
[email protected] | fe2dd774 | 2011-04-19 22:52:49 | [diff] [blame] | 344 | // Record a histogram using the PermissionMessage enum values for each |
| 345 | // permission in |e|. |
| 346 | // NOTE: If this is ever called with high frequency, the implementation may |
| 347 | // need to be made more efficient. |
| 348 | static void RecordPermissionMessagesHistogram( |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 349 | const extensions::Extension* extension, const char* histogram); |
[email protected] | fe2dd774 | 2011-04-19 22:52:49 | [diff] [blame] | 350 | |
[email protected] | e9d7496e | 2014-04-18 01:25:46 | [diff] [blame] | 351 | // Unloads the given extension and mark the extension as terminated. This |
| 352 | // doesn't notify the user that the extension was terminated, if such a |
| 353 | // notification is desired the calling code is responsible for doing that. |
| 354 | void TerminateExtension(const std::string& extension_id); |
| 355 | |
mukai | 87a8d40 | 2014-09-15 20:15:09 | [diff] [blame] | 356 | // Register self and content settings API with the specified map. |
mmenke | ad5094ab | 2017-05-15 19:01:14 | [diff] [blame] | 357 | static void RegisterContentSettings( |
| 358 | HostContentSettingsMap* host_content_settings_map, |
| 359 | Profile* profile); |
mukai | 87a8d40 | 2014-09-15 20:15:09 | [diff] [blame] | 360 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 361 | // Adds/Removes update observers. |
| 362 | void AddUpdateObserver(extensions::UpdateObserver* observer); |
| 363 | void RemoveUpdateObserver(extensions::UpdateObserver* observer); |
[email protected] | a51c9e9 | 2012-12-09 09:19:20 | [diff] [blame] | 364 | |
xiyuan | f6a4c6a6 | 2016-04-19 18:14:54 | [diff] [blame] | 365 | // Register/unregister an InstallGate with the service. |
| 366 | void RegisterInstallGate(extensions::ExtensionPrefs::DelayReason reason, |
| 367 | extensions::InstallGate* install_delayer); |
| 368 | void UnregisterInstallGate(extensions::InstallGate* install_delayer); |
| 369 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 370 | ////////////////////////////////////////////////////////////////////////////// |
| 371 | // Simple Accessors |
[email protected] | fa2416f | 2011-05-03 08:41:20 | [diff] [blame] | 372 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 373 | // Returns a WeakPtr to the ExtensionService. |
[email protected] | 77e4dc088 | 2012-06-20 18:53:50 | [diff] [blame] | 374 | base::WeakPtr<ExtensionService> AsWeakPtr() { return base::AsWeakPtr(this); } |
| 375 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 376 | // Returns profile_ as a BrowserContext. |
| 377 | content::BrowserContext* GetBrowserContext() const; |
| 378 | |
| 379 | bool extensions_enabled() const { return extensions_enabled_; } |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 380 | |
| 381 | const base::FilePath& install_directory() const { return install_directory_; } |
| 382 | |
| 383 | const extensions::ExtensionSet* delayed_installs() const { |
| 384 | return &delayed_installs_; |
| 385 | } |
| 386 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 387 | Profile* profile() { return profile_; } |
| 388 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 389 | // Note that this may return NULL if autoupdate is not turned on. |
| 390 | extensions::ExtensionUpdater* updater() { return updater_.get(); } |
| 391 | |
| 392 | extensions::ComponentLoader* component_loader() { |
| 393 | return component_loader_.get(); |
| 394 | } |
| 395 | |
[email protected] | 3c4abc8 | 2012-10-22 22:25:54 | [diff] [blame] | 396 | bool browser_terminating() const { return browser_terminating_; } |
| 397 | |
[email protected] | 90878c5 | 2014-04-04 18:21:02 | [diff] [blame] | 398 | extensions::SharedModuleService* shared_module_service() { |
| 399 | return shared_module_service_.get(); |
| 400 | } |
| 401 | |
[email protected] | 2894a51 | 2014-06-26 19:03:56 | [diff] [blame] | 402 | extensions::ExternalInstallManager* external_install_manager() { |
| 403 | return external_install_manager_.get(); |
| 404 | } |
| 405 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 406 | ////////////////////////////////////////////////////////////////////////////// |
| 407 | // For Testing |
| 408 | |
| 409 | // Unload all extensions. Does not send notifications. |
| 410 | void UnloadAllExtensionsForTest(); |
| 411 | |
| 412 | // Reloads all extensions. Does not notify that extensions are ready. |
| 413 | void ReloadExtensionsForTest(); |
| 414 | |
| 415 | // Clear all ExternalProviders. |
| 416 | void ClearProvidersForTesting(); |
| 417 | |
| 418 | // Adds an ExternalProviderInterface for the service to use during testing. |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 419 | void AddProviderForTesting( |
lazyboy | f33109d | 2016-08-31 00:37:08 | [diff] [blame] | 420 | std::unique_ptr<extensions::ExternalProviderInterface> test_provider); |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 421 | |
[email protected] | 8f959f52 | 2014-08-06 06:26:28 | [diff] [blame] | 422 | // Simulate an extension being blacklisted for tests. |
| 423 | void BlacklistExtensionForTest(const std::string& extension_id); |
| 424 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 425 | #if defined(UNIT_TEST) |
| 426 | void TrackTerminatedExtensionForTest(const extensions::Extension* extension) { |
xiyuan | e87def2e | 2015-06-04 22:50:22 | [diff] [blame] | 427 | TrackTerminatedExtension(extension->id()); |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 428 | } |
| 429 | |
| 430 | void FinishInstallationForTest(const extensions::Extension* extension) { |
benwells | 1dd4acd | 2015-12-09 02:20:24 | [diff] [blame] | 431 | FinishInstallation(extension); |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 432 | } |
Takumi Fujimoto | 43c8c00f | 2017-07-26 22:48:56 | [diff] [blame^] | 433 | |
| 434 | void UninstallMigratedExtensionsForTest() { UninstallMigratedExtensions(); } |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 435 | #endif |
| 436 | |
[email protected] | 3c4abc8 | 2012-10-22 22:25:54 | [diff] [blame] | 437 | void set_browser_terminating_for_test(bool value) { |
| 438 | browser_terminating_ = value; |
| 439 | } |
| 440 | |
[email protected] | 4e9b59d | 2013-12-18 06:47:14 | [diff] [blame] | 441 | // Set a callback to be called when all external providers are ready and their |
| 442 | // extensions have been installed. |
| 443 | void set_external_updates_finished_callback_for_test( |
| 444 | const base::Closure& callback) { |
| 445 | external_updates_finished_callback_ = callback; |
| 446 | } |
| 447 | |
lazyboy | 77214d3c | 2017-04-04 16:46:12 | [diff] [blame] | 448 | void set_external_updates_disabled_for_test(bool value) { |
| 449 | external_updates_disabled_for_test_ = value; |
| 450 | } |
| 451 | |
[email protected] | 14908b7 | 2011-04-20 06:54:36 | [diff] [blame] | 452 | private: |
catmullings | 98cd194 | 2016-08-30 22:31:59 | [diff] [blame] | 453 | // Loads extensions specified via a command line flag/switch. |
| 454 | void LoadExtensionsFromCommandLineFlag(const char* switch_name); |
| 455 | |
[email protected] | bca4b83 | 2014-07-17 20:22:34 | [diff] [blame] | 456 | // Reloads the specified extension, sending the onLaunched() event to it if it |
| 457 | // currently has any window showing. |be_noisy| determines whether noisy |
| 458 | // failures are allowed for unpacked extension installs. |
| 459 | void ReloadExtensionImpl(const std::string& extension_id, bool be_noisy); |
| 460 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 461 | // content::NotificationObserver implementation: |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 462 | void Observe(int type, |
| 463 | const content::NotificationSource& source, |
| 464 | const content::NotificationDetails& details) override; |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 465 | |
| 466 | // extensions::Blacklist::Observer implementation. |
dcheng | ae36a4a | 2014-10-21 12:36:36 | [diff] [blame] | 467 | void OnBlacklistUpdated() override; |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 468 | |
weidongg | 0469523 | 2017-06-09 00:01:05 | [diff] [blame] | 469 | // UpgradeObserver implementation. |
| 470 | void OnUpgradeRecommended() override; |
| 471 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 472 | // Similar to FinishInstallation, but first checks if there still is an update |
| 473 | // pending for the extension, and makes sure the extension is still idle. |
| 474 | void MaybeFinishDelayedInstallation(const std::string& extension_id); |
| 475 | |
| 476 | // For the extension in |version_path| with |id|, check to see if it's an |
| 477 | // externally managed extension. If so, uninstall it. |
| 478 | void CheckExternalUninstall(const std::string& id); |
| 479 | |
rkaplow | a8fd8d3 | 2015-02-25 21:27:56 | [diff] [blame] | 480 | // Attempt to enable all disabled extensions which the only disabled reason is |
| 481 | // reloading. |
| 482 | void EnabledReloadableExtensions(); |
| 483 | |
| 484 | // Finish install (if possible) of extensions that were still delayed while |
| 485 | // the browser was shut down. |
| 486 | void MaybeFinishShutdownDelayed(); |
| 487 | |
[email protected] | 2d19eb6e | 2014-01-27 17:30:00 | [diff] [blame] | 488 | // Populates greylist_. |
| 489 | void LoadGreylistFromPrefs(); |
| 490 | |
[email protected] | 4a10006a | 2013-05-17 23:18:35 | [diff] [blame] | 491 | // Signals *ready_ and sends a notification to the listeners. |
[email protected] | 820d9bd | 2013-04-03 03:46:03 | [diff] [blame] | 492 | void SetReadyAndNotifyListeners(); |
| 493 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 494 | // Returns true if all the external extension providers are ready. |
| 495 | bool AreAllExternalProvidersReady() const; |
| 496 | |
| 497 | // Called once all external providers are ready. Checks for unclaimed |
| 498 | // external extensions. |
| 499 | void OnAllExternalProvidersReady(); |
| 500 | |
xiyuan | e87def2e | 2015-06-04 22:50:22 | [diff] [blame] | 501 | // Adds the given extension id to the list of terminated extensions if |
[email protected] | fa2416f | 2011-05-03 08:41:20 | [diff] [blame] | 502 | // it is not already there and unloads it. |
xiyuan | e87def2e | 2015-06-04 22:50:22 | [diff] [blame] | 503 | void TrackTerminatedExtension(const std::string& extension_id); |
[email protected] | fa2416f | 2011-05-03 08:41:20 | [diff] [blame] | 504 | |
| 505 | // Removes the extension with the given id from the list of |
| 506 | // terminated extensions if it is there. |
[email protected] | bb7f4095 | 2011-01-13 00:21:20 | [diff] [blame] | 507 | void UntrackTerminatedExtension(const std::string& id); |
| 508 | |
[email protected] | 8c484b74 | 2012-11-29 06:05:36 | [diff] [blame] | 509 | // Update preferences for a new or updated extension; notify observers that |
| 510 | // the extension is installed, e.g., to update event handlers on background |
| 511 | // pages; and perform other extension install tasks before calling |
| 512 | // AddExtension. |
[email protected] | 4a1d9c0d | 2014-06-13 12:50:11 | [diff] [blame] | 513 | // |install_flags| is a bitmask of extensions::InstallFlags. |
[email protected] | d8fd0fd | 2014-03-24 13:16:06 | [diff] [blame] | 514 | void AddNewOrUpdatedExtension(const extensions::Extension* extension, |
| 515 | extensions::Extension::State initial_state, |
[email protected] | 4a1d9c0d | 2014-06-13 12:50:11 | [diff] [blame] | 516 | int install_flags, |
[email protected] | d8fd0fd | 2014-03-24 13:16:06 | [diff] [blame] | 517 | const syncer::StringOrdinal& page_ordinal, |
| 518 | const std::string& install_parameter); |
[email protected] | 8c484b74 | 2012-11-29 06:05:36 | [diff] [blame] | 519 | |
[email protected] | 62d30f4 | 2009-10-01 22:36:06 | [diff] [blame] | 520 | // Handles sending notification that |extension| was loaded. |
[email protected] | 1c321ee | 2012-05-21 03:02:34 | [diff] [blame] | 521 | void NotifyExtensionLoaded(const extensions::Extension* extension); |
[email protected] | 62d30f4 | 2009-10-01 22:36:06 | [diff] [blame] | 522 | |
rockot | 494f007 | 2015-07-29 17:58:07 | [diff] [blame] | 523 | // Completes extension loading after URLRequestContexts have been updated |
| 524 | // on the IO thread. |
| 525 | void OnExtensionRegisteredWithRequestContexts( |
| 526 | scoped_refptr<const extensions::Extension> extension); |
| 527 | |
[email protected] | 62d30f4 | 2009-10-01 22:36:06 | [diff] [blame] | 528 | // Handles sending notification that |extension| was unloaded. |
limasdf | 0deef204 | 2017-05-03 19:17:17 | [diff] [blame] | 529 | void NotifyExtensionUnloaded(const extensions::Extension* extension, |
| 530 | extensions::UnloadedExtensionReason reason); |
[email protected] | 62d30f4 | 2009-10-01 22:36:06 | [diff] [blame] | 531 | |
benwells | 1dd4acd | 2015-12-09 02:20:24 | [diff] [blame] | 532 | // Common helper to finish installing the given extension. |
| 533 | void FinishInstallation(const extensions::Extension* extension); |
[email protected] | 6f610183 | 2012-11-27 22:10:48 | [diff] [blame] | 534 | |
[email protected] | b914e295 | 2013-04-26 07:10:03 | [diff] [blame] | 535 | // Disables the extension if the privilege level has increased |
| 536 | // (e.g., due to an upgrade). |
| 537 | void CheckPermissionsIncrease(const extensions::Extension* extension, |
treib | 6e51bca | 2016-06-15 10:26:03 | [diff] [blame] | 538 | bool is_extension_loaded); |
[email protected] | b914e295 | 2013-04-26 07:10:03 | [diff] [blame] | 539 | |
[email protected] | aab98a5 | 2009-12-02 03:22:35 | [diff] [blame] | 540 | // Helper that updates the active extension list used for crash reporting. |
| 541 | void UpdateActiveExtensionsInCrashReporter(); |
| 542 | |
binjin | 47947f84 | 2014-11-18 12:10:24 | [diff] [blame] | 543 | // Helper to get the disable reasons for an installed (or upgraded) extension. |
| 544 | // A return value of Extension::DISABLE_NONE indicates that we should enable |
| 545 | // this extension initially. |
| 546 | int GetDisableReasonsOnInstalled(const extensions::Extension* extension); |
[email protected] | 612a1cb1 | 2012-10-17 13:18:03 | [diff] [blame] | 547 | |
mlerman | 6a37b6a4 | 2014-11-26 22:10:53 | [diff] [blame] | 548 | // Helper method to determine if an extension can be blocked. |
| 549 | bool CanBlockExtension(const extensions::Extension* extension) const; |
| 550 | |
xiyuan | f6a4c6a6 | 2016-04-19 18:14:54 | [diff] [blame] | 551 | // Helper to determine if installing an extensions should proceed immediately, |
| 552 | // or if we should delay the install until further notice, or if the install |
| 553 | // should be aborted. A pending install is delayed or aborted when any of the |
| 554 | // delayers say so and only proceeds when all delayers return INSTALL. |
| 555 | // |extension| is the extension to be installed. |install_immediately| is the |
| 556 | // install flag set with the install. |reason| is the reason associated with |
| 557 | // the install delayer that wants to defer or abort the install. |
| 558 | extensions::InstallGate::Action ShouldDelayExtensionInstall( |
| 559 | const extensions::Extension* extension, |
| 560 | bool install_immediately, |
| 561 | extensions::ExtensionPrefs::DelayReason* reason) const; |
[email protected] | e7aa7b7e | 2012-11-27 04:51:22 | [diff] [blame] | 562 | |
[email protected] | 695b571 | 2012-12-06 23:55:28 | [diff] [blame] | 563 | // Manages the blacklisted extensions, intended as callback from |
| 564 | // Blacklist::GetBlacklistedIDs. |
[email protected] | 2d19eb6e | 2014-01-27 17:30:00 | [diff] [blame] | 565 | void ManageBlacklist( |
| 566 | const extensions::Blacklist::BlacklistStateMap& blacklisted_ids); |
| 567 | |
mlerman | 6a37b6a4 | 2014-11-26 22:10:53 | [diff] [blame] | 568 | // Add extensions in |blacklisted| to blacklisted_extensions, remove |
| 569 | // extensions that are neither in |blacklisted|, nor in |unchanged|. |
| 570 | void UpdateBlacklistedExtensions( |
| 571 | const extensions::ExtensionIdSet& to_blacklist, |
| 572 | const extensions::ExtensionIdSet& unchanged); |
[email protected] | 2d19eb6e | 2014-01-27 17:30:00 | [diff] [blame] | 573 | |
| 574 | void UpdateGreylistedExtensions( |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 575 | const extensions::ExtensionIdSet& greylist, |
| 576 | const extensions::ExtensionIdSet& unchanged, |
[email protected] | 2d19eb6e | 2014-01-27 17:30:00 | [diff] [blame] | 577 | const extensions::Blacklist::BlacklistStateMap& state_map); |
[email protected] | 695b571 | 2012-12-06 23:55:28 | [diff] [blame] | 578 | |
[email protected] | bb1bc9b3 | 2013-12-21 03:09:14 | [diff] [blame] | 579 | // Used only by test code. |
| 580 | void UnloadAllExtensionsInternal(); |
| 581 | |
[email protected] | ebe0777 | 2014-05-22 04:16:06 | [diff] [blame] | 582 | // Disable apps & extensions now to stop them from running after a profile |
| 583 | // has been conceptually deleted. Don't wait for full browser shutdown and |
| 584 | // the actual profile objects to be destroyed. |
| 585 | void OnProfileDestructionStarted(); |
| 586 | |
[email protected] | 5a145e8 | 2014-05-29 22:19:07 | [diff] [blame] | 587 | // Called on file task runner thread to uninstall extension. |
| 588 | static void UninstallExtensionOnFileThread( |
| 589 | const std::string& id, |
| 590 | Profile* profile, |
| 591 | const base::FilePath& install_dir, |
| 592 | const base::FilePath& extension_path); |
| 593 | |
rdevlin.cronin | f2e1cb01 | 2017-05-27 01:27:59 | [diff] [blame] | 594 | // Called when the initial extensions load has completed. |
| 595 | void OnInstalledExtensionsLoaded(); |
| 596 | |
lazyboy | 75b9def | 2017-06-06 18:56:59 | [diff] [blame] | 597 | // Upon reloading an extension, spins up its lazy background page if |
| 598 | // necessary. |
| 599 | void MaybeSpinUpLazyBackgroundPage(const extensions::Extension* extension_id); |
| 600 | |
Takumi Fujimoto | 43c8c00f | 2017-07-26 22:48:56 | [diff] [blame^] | 601 | // Uninstall extensions that have been migrated to component extensions. |
| 602 | void UninstallMigratedExtensions(); |
| 603 | |
catmullings | 98cd194 | 2016-08-30 22:31:59 | [diff] [blame] | 604 | const base::CommandLine* command_line_ = nullptr; |
| 605 | |
[email protected] | 31d8f5f2 | 2012-04-02 15:22:08 | [diff] [blame] | 606 | // The normal profile associated with this ExtensionService. |
achuith | 2f5578b | 2016-02-26 21:57:13 | [diff] [blame] | 607 | Profile* profile_ = nullptr; |
[email protected] | 6ef635e4 | 2009-07-26 06:16:12 | [diff] [blame] | 608 | |
[email protected] | 31d8f5f2 | 2012-04-02 15:22:08 | [diff] [blame] | 609 | // The ExtensionSystem for the profile above. |
achuith | 2f5578b | 2016-02-26 21:57:13 | [diff] [blame] | 610 | extensions::ExtensionSystem* system_ = nullptr; |
[email protected] | 31d8f5f2 | 2012-04-02 15:22:08 | [diff] [blame] | 611 | |
[email protected] | 695b571 | 2012-12-06 23:55:28 | [diff] [blame] | 612 | // Preferences for the owning profile. |
achuith | 2f5578b | 2016-02-26 21:57:13 | [diff] [blame] | 613 | extensions::ExtensionPrefs* extension_prefs_ = nullptr; |
[email protected] | 894bb50 | 2009-05-21 22:39:57 | [diff] [blame] | 614 | |
[email protected] | 695b571 | 2012-12-06 23:55:28 | [diff] [blame] | 615 | // Blacklist for the owning profile. |
achuith | 2f5578b | 2016-02-26 21:57:13 | [diff] [blame] | 616 | extensions::Blacklist* blacklist_ = nullptr; |
[email protected] | 695b571 | 2012-12-06 23:55:28 | [diff] [blame] | 617 | |
[email protected] | 5fdfa56 | 2013-12-27 17:43:59 | [diff] [blame] | 618 | // Sets of enabled/disabled/terminated/blacklisted extensions. Not owned. |
achuith | 2f5578b | 2016-02-26 21:57:13 | [diff] [blame] | 619 | extensions::ExtensionRegistry* registry_ = nullptr; |
[email protected] | 695b571 | 2012-12-06 23:55:28 | [diff] [blame] | 620 | |
[email protected] | 2d19eb6e | 2014-01-27 17:30:00 | [diff] [blame] | 621 | // Set of greylisted extensions. These extensions are disabled if they are |
| 622 | // already installed in Chromium at the time when they are added to |
| 623 | // the greylist. Unlike blacklisted extensions, greylisted ones are visible |
| 624 | // to the user and if user re-enables such an extension, they remain enabled. |
| 625 | // |
| 626 | // These extensions should appear in registry_. |
| 627 | extensions::ExtensionSet greylist_; |
| 628 | |
catmullings | 98cd194 | 2016-08-30 22:31:59 | [diff] [blame] | 629 | // Set of whitelisted enabled extensions loaded from the |
| 630 | // --disable-extensions-except command line flag. |
| 631 | std::set<std::string> disable_flag_exempted_extensions_; |
| 632 | |
[email protected] | 9f4e4f08 | 2013-06-21 07:11:19 | [diff] [blame] | 633 | // The list of extension installs delayed for various reasons. The reason |
[email protected] | bb1bc9b3 | 2013-12-21 03:09:14 | [diff] [blame] | 634 | // for delayed install is stored in ExtensionPrefs. These are not part of |
| 635 | // ExtensionRegistry because they are not yet installed. |
[email protected] | 289c44b | 2013-12-17 03:26:57 | [diff] [blame] | 636 | extensions::ExtensionSet delayed_installs_; |
[email protected] | 0db124b0 | 2012-11-07 04:55:05 | [diff] [blame] | 637 | |
[email protected] | b2907fd | 2011-03-25 16:43:37 | [diff] [blame] | 638 | // Hold the set of pending extensions. |
[email protected] | 3f213ad | 2012-07-26 23:39:41 | [diff] [blame] | 639 | extensions::PendingExtensionManager pending_extension_manager_; |
[email protected] | aa14270 | 2010-03-26 01:26:33 | [diff] [blame] | 640 | |
[email protected] | 6014d67 | 2008-12-05 00:38:25 | [diff] [blame] | 641 | // The full path to the directory where extensions are installed. |
[email protected] | 650b2d5 | 2013-02-10 03:41:45 | [diff] [blame] | 642 | base::FilePath install_directory_; |
[email protected] | 6014d67 | 2008-12-05 00:38:25 | [diff] [blame] | 643 | |
[email protected] | e2eb4311 | 2009-05-29 21:19:54 | [diff] [blame] | 644 | // Whether or not extensions are enabled. |
achuith | 2f5578b | 2016-02-26 21:57:13 | [diff] [blame] | 645 | bool extensions_enabled_ = true; |
[email protected] | e2eb4311 | 2009-05-29 21:19:54 | [diff] [blame] | 646 | |
[email protected] | 4a10006a | 2013-05-17 23:18:35 | [diff] [blame] | 647 | // Signaled when all extensions are loaded. |
| 648 | extensions::OneShotEvent* const ready_; |
[email protected] | e81dba3 | 2009-06-19 20:19:13 | [diff] [blame] | 649 | |
[email protected] | 93fd78f4 | 2009-07-10 16:43:17 | [diff] [blame] | 650 | // Our extension updater, if updates are turned on. |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 651 | std::unique_ptr<extensions::ExtensionUpdater> updater_; |
[email protected] | 93fd78f4 | 2009-07-10 16:43:17 | [diff] [blame] | 652 | |
[email protected] | 1eb17508 | 2010-02-10 09:26:16 | [diff] [blame] | 653 | // Map unloaded extensions' ids to their paths. When a temporarily loaded |
[email protected] | 5fb88938 | 2011-06-03 00:29:20 | [diff] [blame] | 654 | // extension is unloaded, we lose the information about it and don't have |
[email protected] | 1eb17508 | 2010-02-10 09:26:16 | [diff] [blame] | 655 | // any in the extension preferences file. |
achuith | 2f5578b | 2016-02-26 21:57:13 | [diff] [blame] | 656 | using UnloadedExtensionPathMap = std::map<std::string, base::FilePath>; |
[email protected] | 1eb17508 | 2010-02-10 09:26:16 | [diff] [blame] | 657 | UnloadedExtensionPathMap unloaded_extension_paths_; |
| 658 | |
[email protected] | 04ea1bb | 2013-07-10 09:26:09 | [diff] [blame] | 659 | // Map of DevToolsAgentHost instances that are detached, |
| 660 | // waiting for an extension to be reloaded. |
achuith | 2f5578b | 2016-02-26 21:57:13 | [diff] [blame] | 661 | using OrphanedDevTools = |
| 662 | std::map<std::string, scoped_refptr<content::DevToolsAgentHost>>; |
[email protected] | 4814b51 | 2009-11-07 00:12:29 | [diff] [blame] | 663 | OrphanedDevTools orphaned_dev_tools_; |
| 664 | |
[email protected] | 6c2381d | 2011-10-19 02:52:53 | [diff] [blame] | 665 | content::NotificationRegistrar registrar_; |
[email protected] | 4814b51 | 2009-11-07 00:12:29 | [diff] [blame] | 666 | |
[email protected] | d8c8f25f | 2011-11-02 18:18:01 | [diff] [blame] | 667 | // Keeps track of loading and unloading component extensions. |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 668 | std::unique_ptr<extensions::ComponentLoader> component_loader_; |
[email protected] | d8c8f25f | 2011-11-02 18:18:01 | [diff] [blame] | 669 | |
[email protected] | 8e4560b6 | 2011-01-14 10:09:14 | [diff] [blame] | 670 | // A collection of external extension providers. Each provider reads |
| 671 | // a source of external extension information. Examples include the |
| 672 | // windows registry and external_extensions.json. |
[email protected] | 5df038b | 2012-07-16 19:03:27 | [diff] [blame] | 673 | extensions::ProviderCollection external_extension_providers_; |
[email protected] | 8e4560b6 | 2011-01-14 10:09:14 | [diff] [blame] | 674 | |
| 675 | // Set to true by OnExternalExtensionUpdateUrlFound() when an external |
[email protected] | 94fde23 | 2012-04-27 10:22:30 | [diff] [blame] | 676 | // extension URL is found, and by CheckForUpdatesSoon() when an update check |
| 677 | // has to wait for the external providers. Used in |
| 678 | // OnAllExternalProvidersReady() to determine if an update check is needed to |
| 679 | // install pending extensions. |
achuith | 2f5578b | 2016-02-26 21:57:13 | [diff] [blame] | 680 | bool update_once_all_providers_are_ready_ = false; |
[email protected] | 8e4560b6 | 2011-01-14 10:09:14 | [diff] [blame] | 681 | |
[email protected] | 4e9b59d | 2013-12-18 06:47:14 | [diff] [blame] | 682 | // A callback to be called when all external providers are ready and their |
| 683 | // extensions have been installed. Normally this is a null callback, but |
| 684 | // is used in external provider related tests. |
| 685 | base::Closure external_updates_finished_callback_; |
| 686 | |
[email protected] | 3c4abc8 | 2012-10-22 22:25:54 | [diff] [blame] | 687 | // Set when the browser is terminating. Prevents us from installing or |
| 688 | // updating additional extensions and allows in-progress installations to |
| 689 | // decide to abort. |
achuith | 2f5578b | 2016-02-26 21:57:13 | [diff] [blame] | 690 | bool browser_terminating_ = false; |
[email protected] | 3c4abc8 | 2012-10-22 22:25:54 | [diff] [blame] | 691 | |
lazyboy | 77214d3c | 2017-04-04 16:46:12 | [diff] [blame] | 692 | // If set, call to CheckForExternalUpdates() will bail out. |
| 693 | bool external_updates_disabled_for_test_ = false; |
| 694 | |
[email protected] | 460c671 | 2013-04-24 07:20:01 | [diff] [blame] | 695 | // Set to true if this is the first time this ExtensionService has run. |
| 696 | // Used for specially handling external extensions that are installed the |
| 697 | // first time. |
achuith | 2f5578b | 2016-02-26 21:57:13 | [diff] [blame] | 698 | bool is_first_run_ = false; |
[email protected] | 460c671 | 2013-04-24 07:20:01 | [diff] [blame] | 699 | |
mlerman | 6a37b6a4 | 2014-11-26 22:10:53 | [diff] [blame] | 700 | // Set to true if extensions are all to be blocked. |
achuith | 2f5578b | 2016-02-26 21:57:13 | [diff] [blame] | 701 | bool block_extensions_ = false; |
mlerman | 6a37b6a4 | 2014-11-26 22:10:53 | [diff] [blame] | 702 | |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 703 | // Store the ids of reloading extensions. We use this to re-enable extensions |
| 704 | // which were disabled for a reload. |
| 705 | std::set<std::string> reloading_extensions_; |
[email protected] | e178ad9 | 2013-06-28 02:29:25 | [diff] [blame] | 706 | |
[email protected] | 3964e57 | 2014-02-13 21:57:41 | [diff] [blame] | 707 | // A set of the extension ids currently being terminated. We use this to |
| 708 | // avoid trying to unload the same extension twice. |
| 709 | std::set<std::string> extensions_being_terminated_; |
| 710 | |
[email protected] | 373daf97 | 2014-04-10 01:50:44 | [diff] [blame] | 711 | // The controller for the UI that alerts the user about any blacklisted |
| 712 | // extensions. |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 713 | std::unique_ptr<extensions::ExtensionErrorController> error_controller_; |
[email protected] | 373daf97 | 2014-04-10 01:50:44 | [diff] [blame] | 714 | |
[email protected] | 2894a51 | 2014-06-26 19:03:56 | [diff] [blame] | 715 | // The manager for extensions that were externally installed that is |
| 716 | // responsible for prompting the user about suspicious extensions. |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 717 | std::unique_ptr<extensions::ExternalInstallManager> external_install_manager_; |
[email protected] | 2894a51 | 2014-06-26 19:03:56 | [diff] [blame] | 718 | |
[email protected] | 7f8f24f | 2012-11-15 19:40:14 | [diff] [blame] | 719 | // Sequenced task runner for extension related file operations. |
fdoray | 71c48e72 | 2017-05-17 22:37:09 | [diff] [blame] | 720 | const scoped_refptr<base::SequencedTaskRunner> file_task_runner_; |
[email protected] | a9aa593 | 2012-01-25 08:27:40 | [diff] [blame] | 721 | |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 722 | std::unique_ptr<extensions::ExtensionActionStorageManager> |
[email protected] | c77f235 | 2012-08-08 22:07:58 | [diff] [blame] | 723 | extension_action_storage_manager_; |
| 724 | |
[email protected] | 90878c5 | 2014-04-04 18:21:02 | [diff] [blame] | 725 | // The SharedModuleService used to check for import dependencies. |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 726 | std::unique_ptr<extensions::SharedModuleService> shared_module_service_; |
[email protected] | 90878c5 | 2014-04-04 18:21:02 | [diff] [blame] | 727 | |
rdevlin.cronin | 5e510e80 | 2016-07-26 15:09:20 | [diff] [blame] | 728 | // The associated RendererStartupHelper. Guaranteed to outlive the |
| 729 | // ExtensionSystem, and thus us. |
| 730 | extensions::RendererStartupHelper* renderer_helper_; |
| 731 | |
brettw | d195c95 | 2015-06-02 17:31:12 | [diff] [blame] | 732 | base::ObserverList<extensions::UpdateObserver, true> update_observers_; |
[email protected] | efdb7f1a | 2014-03-28 20:43:38 | [diff] [blame] | 733 | |
ryanackley | 48bedbd | 2015-01-27 23:12:14 | [diff] [blame] | 734 | // Migrates app data when upgrading a legacy packaged app to a platform app |
dcheng | c963c714 | 2016-04-08 03:55:22 | [diff] [blame] | 735 | std::unique_ptr<extensions::AppDataMigrator> app_data_migrator_; |
ryanackley | 48bedbd | 2015-01-27 23:12:14 | [diff] [blame] | 736 | |
xiyuan | f6a4c6a6 | 2016-04-19 18:14:54 | [diff] [blame] | 737 | using InstallGateRegistry = std::map<extensions::ExtensionPrefs::DelayReason, |
| 738 | extensions::InstallGate*>; |
| 739 | InstallGateRegistry install_delayer_registry_; |
| 740 | |
[email protected] | eaa7dd18 | 2010-12-14 11:09:00 | [diff] [blame] | 741 | FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 742 | DestroyingProfileClearsExtensions); |
[email protected] | f71b582c | 2014-01-10 17:03:15 | [diff] [blame] | 743 | FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, SetUnsetBlacklistInPrefs); |
| 744 | FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, |
| 745 | BlacklistedExtensionWillNotInstall); |
| 746 | FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, |
| 747 | UnloadBlacklistedExtensionPolicy); |
| 748 | FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, |
| 749 | WillNotLoadBlacklistedExtensionsFromDirectory); |
[email protected] | 757d60a | 2014-05-23 00:11:44 | [diff] [blame] | 750 | FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, ReloadBlacklistedExtension); |
atuchin | 6dc7c44 | 2016-07-20 07:04:34 | [diff] [blame] | 751 | FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, |
| 752 | RemoveExtensionFromBlacklist); |
[email protected] | 757d60a | 2014-05-23 00:11:44 | [diff] [blame] | 753 | FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, BlacklistedInPrefsFromStartup); |
[email protected] | 2d19eb6e | 2014-01-27 17:30:00 | [diff] [blame] | 754 | FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, |
| 755 | GreylistedExtensionDisabled); |
| 756 | FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, |
| 757 | GreylistDontEnableManuallyDisabled); |
| 758 | FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, |
| 759 | GreylistUnknownDontChange); |
binjin | 47947f84 | 2014-11-18 12:10:24 | [diff] [blame] | 760 | FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, |
| 761 | ManagementPolicyProhibitsEnableOnInstalled); |
mlerman | 6a37b6a4 | 2014-11-26 22:10:53 | [diff] [blame] | 762 | FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, |
| 763 | BlockAndUnblockBlacklistedExtension); |
[email protected] | dccba4f8 | 2014-05-29 00:52:56 | [diff] [blame] | 764 | |
[email protected] | eaa7dd18 | 2010-12-14 11:09:00 | [diff] [blame] | 765 | DISALLOW_COPY_AND_ASSIGN(ExtensionService); |
[email protected] | 6014d67 | 2008-12-05 00:38:25 | [diff] [blame] | 766 | }; |
| 767 | |
[email protected] | eaa7dd18 | 2010-12-14 11:09:00 | [diff] [blame] | 768 | #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_SERVICE_H_ |