blob: 4235c22f6b2c4f95a420657b6efa94915e574bbb [file] [log] [blame]
[email protected]ce5c4502009-05-06 16:46:111// Copyright (c) 2009 The Chromium Authors. All rights reserved.
[email protected]6014d672008-12-05 00:38:252// 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_EXTENSIONS_SERVICE_H_
6#define CHROME_BROWSER_EXTENSIONS_EXTENSIONS_SERVICE_H_
7
[email protected]da50530a2009-06-15 17:43:018#include <map>
[email protected]894bb502009-05-21 22:39:579#include <set>
[email protected]b0beaa662009-02-26 00:04:1510#include <string>
[email protected]6014d672008-12-05 00:38:2511#include <vector>
12
[email protected]36a784c2009-06-23 06:21:0813#include "base/command_line.h"
[email protected]6014d672008-12-05 00:38:2514#include "base/file_path.h"
[email protected]da50530a2009-06-15 17:43:0115#include "base/linked_ptr.h"
[email protected]6014d672008-12-05 00:38:2516#include "base/ref_counted.h"
[email protected]e957fe52009-06-23 16:51:0517#include "base/task.h"
[email protected]f5c016b2009-06-16 17:12:3118#include "base/tuple.h"
[email protected]69f1be82009-04-16 22:27:2119#include "base/values.h"
[email protected]e72e8eb82009-06-18 17:21:5120#include "chrome/browser/extensions/extension_prefs.h"
[email protected]c6e4a3412009-06-24 15:45:2921#include "chrome/browser/extensions/extension_process_manager.h"
[email protected]a1257b12009-06-12 02:51:3422#include "chrome/browser/extensions/external_extension_provider.h"
[email protected]af1277b2009-07-28 00:47:5323#include "chrome/browser/extensions/sandboxed_extension_unpacker.h"
[email protected]25b34332009-06-05 21:53:1924#include "chrome/common/extensions/extension.h"
[email protected]6014d672008-12-05 00:38:2525
[email protected]69f1be82009-04-16 22:27:2126class Browser;
[email protected]25b34332009-06-05 21:53:1927class DictionaryValue;
[email protected]69f1be82009-04-16 22:27:2128class Extension;
[email protected]6014d672008-12-05 00:38:2529class ExtensionsServiceBackend;
[email protected]93fd78f42009-07-10 16:43:1730class ExtensionUpdater;
[email protected]69f1be82009-04-16 22:27:2131class GURL;
[email protected]f5c016b2009-06-16 17:12:3132class MessageLoop;
[email protected]894bb502009-05-21 22:39:5733class PrefService;
[email protected]81e63782009-02-27 19:35:0934class Profile;
[email protected]1fca1492009-05-15 22:23:4335class ResourceDispatcherHost;
[email protected]69f1be82009-04-16 22:27:2136class SiteInstance;
[email protected]a82325a42009-06-10 16:43:0937
[email protected]69f1be82009-04-16 22:27:2138typedef std::vector<Extension*> ExtensionList;
[email protected]6014d672008-12-05 00:38:2539
[email protected]d1ca0ed12009-07-01 18:24:3240// This is an interface class to encapsulate the dependencies that
41// ExtensionUpdater has on ExtensionsService. This allows easy mocking.
42class ExtensionUpdateService {
43 public:
44 virtual ~ExtensionUpdateService() {}
45 virtual const ExtensionList* extensions() const = 0;
[email protected]7577a5c52009-07-30 06:21:5846 virtual void UpdateExtension(const std::string& id, const FilePath& path) = 0;
[email protected]d1ca0ed12009-07-01 18:24:3247 virtual Extension* GetExtensionById(const std::string& id) = 0;
[email protected]6b75ec32009-08-14 06:37:1848 virtual void UpdateExtensionBlacklist(
49 const std::vector<std::string>& blacklist) = 0;
[email protected]d1ca0ed12009-07-01 18:24:3250};
[email protected]fbcc40302009-06-12 20:45:4551
[email protected]4f313d52009-05-21 00:42:2952// Manages installed and running Chromium extensions.
[email protected]894bb502009-05-21 22:39:5753class ExtensionsService
[email protected]d1ca0ed12009-07-01 18:24:3254 : public ExtensionUpdateService,
55 public base::RefCountedThreadSafe<ExtensionsService> {
[email protected]4f313d52009-05-21 00:42:2956 public:
[email protected]fbcc40302009-06-12 20:45:4557
[email protected]a9b00ac2009-06-25 21:03:2358 // The name of the directory inside the profile where extensions are
59 // installed to.
60 static const char* kInstallDirectoryName;
61
[email protected]93fd78f42009-07-10 16:43:1762 // If auto-updates are turned on, default to running every 5 hours.
63 static const int kDefaultUpdateFrequencySeconds = 60 * 60 * 5;
64
[email protected]4289d9b2009-07-25 21:17:3465 // The name of the file that the current active version number is stored in.
66 static const char* kCurrentVersionFileName;
67
68 // Hack:
69 // Extensions downloaded from kGalleryDownloadURLPrefix initiated from pages
70 // with kGalleryURLPrefix will not require --enable-extensions and will be
71 // prompt-free.
72 static const char* kGalleryDownloadURLPrefix;
73 static const char* kGalleryURLPrefix;
74
75 // Determine if a given extension download should be treated as if it came
76 // from the gallery.
77 static bool IsDownloadFromGallery(const GURL& download_url,
78 const GURL& referrer_url);
79
[email protected]894bb502009-05-21 22:39:5780 ExtensionsService(Profile* profile,
[email protected]36a784c2009-06-23 06:21:0881 const CommandLine* command_line,
[email protected]a9b00ac2009-06-25 21:03:2382 PrefService* prefs,
83 const FilePath& install_directory,
[email protected]894bb502009-05-21 22:39:5784 MessageLoop* frontend_loop,
[email protected]93fd78f42009-07-10 16:43:1785 MessageLoop* backend_loop,
86 bool autoupdate_enabled);
[email protected]d1ca0ed12009-07-01 18:24:3287 virtual ~ExtensionsService();
[email protected]6014d672008-12-05 00:38:2588
89 // Gets the list of currently installed extensions.
[email protected]0c6da502009-08-14 22:32:3990 virtual const ExtensionList* extensions() const { return &extensions_; }
91 virtual const ExtensionList* disabled_extensions() const {
92 return &disabled_extensions_;
[email protected]6014d672008-12-05 00:38:2593 }
94
[email protected]2a464a92009-08-01 17:58:3595 const FilePath& install_directory() const { return install_directory_; }
96
[email protected]6014d672008-12-05 00:38:2597 // Initialize and start all installed extensions.
[email protected]9f1087e2009-06-15 17:29:3298 void Init();
[email protected]6014d672008-12-05 00:38:2599
[email protected]0c6da502009-08-14 22:32:39100 // Look up an extension by ID.
101 Extension* GetExtensionById(const std::string& id) {
102 return GetExtensionByIdInternal(id, true, false);
103 }
104
[email protected]671e6c1ce2009-09-26 03:18:46105 // Retrieves a vector of all page actions, irrespective of which extension
106 // they belong to.
[email protected]ba69a7d2009-09-28 21:09:56107 std::vector<ExtensionAction*> GetPageActions() const;
[email protected]671e6c1ce2009-09-26 03:18:46108
109 // Retrieves a vector of all browser actions, irrespective of which extension
110 // they belong to.
[email protected]ad6ff1a2009-10-06 16:36:39111 std::vector<ExtensionAction*> GetBrowserActions(bool include_popups) const;
[email protected]10fb8122009-09-10 22:25:16112
[email protected]631cf822009-05-15 07:01:25113 // Install the extension file at |extension_path|. Will install as an
114 // update if an older version is already installed.
115 // For fresh installs, this method also causes the extension to be
116 // immediately loaded.
[email protected]2a464a92009-08-01 17:58:35117 // TODO(aa): This method can be removed. It is only used by the unit tests,
118 // and they could use CrxInstaller directly instead.
[email protected]631cf822009-05-15 07:01:25119 void InstallExtension(const FilePath& extension_path);
120
[email protected]e957fe52009-06-23 16:51:05121 // Updates a currently-installed extension with the contents from
[email protected]7577a5c52009-07-30 06:21:58122 // |extension_path|.
[email protected]2a464a92009-08-01 17:58:35123 // TODO(aa): This method can be removed. ExtensionUpdater could use
124 // CrxInstaller directly instead.
[email protected]d1ca0ed12009-07-01 18:24:32125 virtual void UpdateExtension(const std::string& id,
[email protected]7577a5c52009-07-30 06:21:58126 const FilePath& extension_path);
[email protected]e957fe52009-06-23 16:51:05127
[email protected]9cddd4702009-07-27 22:09:40128 // Reloads the specified extension.
129 void ReloadExtension(const std::string& extension_id);
130
[email protected]631cf822009-05-15 07:01:25131 // Uninstalls the specified extension. Callers should only call this method
[email protected]17c4f3c2009-07-04 16:36:25132 // with extensions that exist. |external_uninstall| is a magical parameter
133 // that is only used to send information to ExtensionPrefs, which external
134 // callers should never set to true.
135 // TODO(aa): Remove |external_uninstall| -- this information should be passed
136 // to ExtensionPrefs some other way.
[email protected]27b985d2009-06-25 17:53:15137 void UninstallExtension(const std::string& extension_id,
138 bool external_uninstall);
[email protected]631cf822009-05-15 07:01:25139
[email protected]1784e83a2009-09-08 21:01:52140 // Enable or disable an extension. The extension must be in the opposite state
141 // before calling.
[email protected]0c6da502009-08-14 22:32:39142 void EnableExtension(const std::string& extension_id);
[email protected]1784e83a2009-09-08 21:01:52143 void DisableExtension(const std::string& extension_id);
[email protected]0c6da502009-08-14 22:32:39144
[email protected]631cf822009-05-15 07:01:25145 // Load the extension from the directory |extension_path|.
146 void LoadExtension(const FilePath& extension_path);
147
[email protected]9f1087e2009-06-15 17:29:32148 // Load all known extensions (used by startup and testing code).
149 void LoadAllExtensions();
150
151 // Check for updates (or potentially new extensions from external providers)
[email protected]93fd78f42009-07-10 16:43:17152 void CheckForExternalUpdates();
[email protected]9f1087e2009-06-15 17:29:32153
154 // Unload the specified extension.
155 void UnloadExtension(const std::string& extension_id);
156
[email protected]57f71b92009-09-11 19:31:38157 // Unload all extensions. This is currently only called on shutdown, and
158 // does not send notifications.
[email protected]9f1087e2009-06-15 17:29:32159 void UnloadAllExtensions();
160
161 // Called only by testing.
162 void ReloadExtensions();
163
164 // Scan the extension directory and clean up the cruft.
165 void GarbageCollectExtensions();
166
[email protected]9f1087e2009-06-15 17:29:32167 // Lookup an extension by |url|. This uses the host of the URL as the id.
168 Extension* GetExtensionByURL(const GURL& url);
[email protected]cc655912009-01-29 23:19:19169
[email protected]a1257b12009-06-12 02:51:34170 // Clear all ExternalExtensionProviders.
171 void ClearProvidersForTesting();
172
173 // Sets an ExternalExtensionProvider for the service to use during testing.
174 // |location| specifies what type of provider should be added.
175 void SetProviderForTesting(Extension::Location location,
176 ExternalExtensionProvider* test_provider);
177
[email protected]7577a5c52009-07-30 06:21:58178 // Called by the backend when the initial extension load has completed.
179 void OnLoadedInstalledExtensions();
180
[email protected]ae09ca62009-08-21 19:46:46181 // Called by the backend when an extension has been loaded.
[email protected]2a409532009-08-28 19:39:44182 void OnExtensionLoaded(Extension* extension,
183 bool allow_privilege_increase);
[email protected]7577a5c52009-07-30 06:21:58184
185 // Called by the backend when an extension has been installed.
[email protected]2a409532009-08-28 19:39:44186 void OnExtensionInstalled(Extension* extension,
187 bool allow_privilege_increase);
[email protected]7577a5c52009-07-30 06:21:58188
189 // Called by the backend when an attempt was made to reinstall the same
190 // version of an existing extension.
191 void OnExtensionOverinstallAttempted(const std::string& id);
192
193 // Called by the backend when an external extension is found.
194 void OnExternalExtensionFound(const std::string& id,
195 const std::string& version,
196 const FilePath& path,
197 Extension::Location location);
198
[email protected]6b75ec32009-08-14 06:37:18199 // Go through each extensions in pref, unload blacklisted extensions
200 // and update the blacklist state in pref.
201 virtual void UpdateExtensionBlacklist(
202 const std::vector<std::string>& blacklist);
203
[email protected]7577a5c52009-07-30 06:21:58204 void set_extensions_enabled(bool enabled) { extensions_enabled_ = enabled; }
[email protected]abe7a8942009-06-23 05:14:29205 bool extensions_enabled() { return extensions_enabled_; }
206
[email protected]0e34d7892009-06-05 19:17:40207 void set_show_extensions_prompts(bool enabled) {
208 show_extensions_prompts_ = enabled;
[email protected]e2eb43112009-05-29 21:19:54209 }
210
[email protected]0e34d7892009-06-05 19:17:40211 bool show_extensions_prompts() {
212 return show_extensions_prompts_;
[email protected]e2eb43112009-05-29 21:19:54213 }
214
[email protected]6ef635e42009-07-26 06:16:12215 // Profile calls this when it is destroyed so that we know not to call it.
216 void ProfileDestroyed() { profile_ = NULL; }
217
[email protected]e81dba32009-06-19 20:19:13218 ExtensionPrefs* extension_prefs() { return extension_prefs_.get(); }
219
220 // Whether the extension service is ready.
221 bool is_ready() { return ready_; }
222
[email protected]1fab8452009-09-03 02:23:39223 // Note that this may return NULL if autoupdate is not turned on.
224 ExtensionUpdater* updater() { return updater_.get(); }
225
[email protected]d11c8e92009-10-20 23:26:40226 // Notify the frontend that there was an error loading an extension.
227 // This method is public because ExtensionsServiceBackend can post to here.
228 void ReportExtensionLoadError(const FilePath& extension_path,
229 const std::string& error,
230 NotificationType type,
231 bool be_noisy);
232
[email protected]6014d672008-12-05 00:38:25233 private:
[email protected]0c6da502009-08-14 22:32:39234 // Look up an extension by ID, optionally including either or both of enabled
235 // and disabled extensions.
236 Extension* GetExtensionByIdInternal(const std::string& id,
237 bool include_enabled,
238 bool include_disabled);
239
[email protected]ae09ca62009-08-21 19:46:46240 // Load a single extension from the prefs. This can be done on the UI thread
241 // because we don't touch the disk.
242 void LoadInstalledExtension(
243 DictionaryValue* manifest, const std::string& id,
244 const FilePath& path, Extension::Location location);
245
[email protected]62d30f42009-10-01 22:36:06246 // Handles sending notification that |extension| was loaded.
247 void NotifyExtensionLoaded(Extension* extension);
248
249 // Handles sending notification that |extension| was unloaded.
250 void NotifyExtensionUnloaded(Extension* extension);
251
[email protected]671e6c1ce2009-09-26 03:18:46252 // Retrieves a vector of all page actions or browser actions, irrespective of
[email protected]ad6ff1a2009-10-06 16:36:39253 // which extension they belong to. If |include_popups| is false, actions that
254 // are popups are excluded.
[email protected]ba69a7d2009-09-28 21:09:56255 std::vector<ExtensionAction*> GetExtensionActions(
[email protected]ad6ff1a2009-10-06 16:36:39256 ExtensionAction::ExtensionActionType action_type,
257 bool include_popups) const;
[email protected]671e6c1ce2009-09-26 03:18:46258
[email protected]6ef635e42009-07-26 06:16:12259 // The profile this ExtensionsService is part of.
260 Profile* profile_;
261
[email protected]894bb502009-05-21 22:39:57262 // Preferences for the owning profile.
[email protected]e72e8eb82009-06-18 17:21:51263 scoped_ptr<ExtensionPrefs> extension_prefs_;
[email protected]894bb502009-05-21 22:39:57264
265 // The message loop to use with the backend.
266 MessageLoop* backend_loop_;
[email protected]6014d672008-12-05 00:38:25267
[email protected]6014d672008-12-05 00:38:25268 // The current list of installed extensions.
269 ExtensionList extensions_;
270
[email protected]0c6da502009-08-14 22:32:39271 // The list of installed extensions that have been disabled.
272 ExtensionList disabled_extensions_;
273
[email protected]6014d672008-12-05 00:38:25274 // The full path to the directory where extensions are installed.
275 FilePath install_directory_;
276
[email protected]e2eb43112009-05-29 21:19:54277 // Whether or not extensions are enabled.
278 bool extensions_enabled_;
279
[email protected]0e34d7892009-06-05 19:17:40280 // Whether to notify users when they attempt to install an extension.
281 bool show_extensions_prompts_;
[email protected]e2eb43112009-05-29 21:19:54282
[email protected]cc5da332009-03-04 08:02:51283 // The backend that will do IO on behalf of this instance.
284 scoped_refptr<ExtensionsServiceBackend> backend_;
285
[email protected]e81dba32009-06-19 20:19:13286 // Is the service ready to go?
287 bool ready_;
288
[email protected]93fd78f42009-07-10 16:43:17289 // Our extension updater, if updates are turned on.
290 scoped_refptr<ExtensionUpdater> updater_;
291
[email protected]6014d672008-12-05 00:38:25292 DISALLOW_COPY_AND_ASSIGN(ExtensionsService);
293};
294
295// Implements IO for the ExtensionsService.
[email protected]894bb502009-05-21 22:39:57296// TODO(aa): This can probably move into the .cc file.
[email protected]6014d672008-12-05 00:38:25297class ExtensionsServiceBackend
[email protected]a1257b12009-06-12 02:51:34298 : public base::RefCountedThreadSafe<ExtensionsServiceBackend>,
299 public ExternalExtensionProvider::Visitor {
[email protected]6014d672008-12-05 00:38:25300 public:
[email protected]894bb502009-05-21 22:39:57301 // |rdh| can be NULL in the case of test environment.
[email protected]a1257b12009-06-12 02:51:34302 // |extension_prefs| contains a dictionary value that points to the extension
303 // preferences.
[email protected]894bb502009-05-21 22:39:57304 ExtensionsServiceBackend(const FilePath& install_directory,
[email protected]7577a5c52009-07-30 06:21:58305 MessageLoop* frontend_loop);
[email protected]a1257b12009-06-12 02:51:34306
307 virtual ~ExtensionsServiceBackend();
[email protected]6014d672008-12-05 00:38:25308
[email protected]0877fd92009-02-03 16:34:06309 // Loads a single extension from |path| where |path| is the top directory of
310 // a specific extension where its manifest file lives.
[email protected]ae09ca62009-08-21 19:46:46311 // Errors are reported through ExtensionErrorReporter. On success,
312 // OnExtensionLoaded() is called.
[email protected]3cf4f0992009-02-03 23:00:30313 // TODO(erikkay): It might be useful to be able to load a packed extension
314 // (presumably into memory) without installing it.
[email protected]894bb502009-05-21 22:39:57315 void LoadSingleExtension(const FilePath &path,
316 scoped_refptr<ExtensionsService> frontend);
[email protected]0877fd92009-02-03 16:34:06317
[email protected]b0beaa662009-02-26 00:04:15318 // Check externally updated extensions for updates and install if necessary.
[email protected]894bb502009-05-21 22:39:57319 // Errors are reported through ExtensionErrorReporter. Succcess is not
320 // reported.
321 void CheckForExternalUpdates(std::set<std::string> ids_to_ignore,
322 scoped_refptr<ExtensionsService> frontend);
[email protected]cc655912009-01-29 23:19:19323
[email protected]ae09ca62009-08-21 19:46:46324 // For the extension in |version_path| with |id|, check to see if it's an
325 // externally managed extension. If so, tell the frontend to uninstall it.
326 void CheckExternalUninstall(scoped_refptr<ExtensionsService> frontend,
327 const std::string& id,
328 Extension::Location location);
329
[email protected]a1257b12009-06-12 02:51:34330 // Clear all ExternalExtensionProviders.
331 void ClearProvidersForTesting();
332
333 // Sets an ExternalExtensionProvider for the service to use during testing.
334 // |location| specifies what type of provider should be added.
335 void SetProviderForTesting(Extension::Location location,
336 ExternalExtensionProvider* test_provider);
337
338 // ExternalExtensionProvider::Visitor implementation.
339 virtual void OnExternalExtensionFound(const std::string& id,
340 const Version* version,
[email protected]7577a5c52009-07-30 06:21:58341 const FilePath& path,
342 Extension::Location location);
[email protected]6014d672008-12-05 00:38:25343 private:
[email protected]af1277b2009-07-28 00:47:53344 // Finish installing the extension in |crx_path| after it has been unpacked to
345 // |unpacked_path|. If |expected_id| is not empty, it's verified against the
346 // extension's manifest before installation. If |silent| is true, there will
347 // be no install confirmation dialog. |from_gallery| indicates whether the
348 // crx was installed from our gallery, which results in different UI.
349 //
350 // Note: We take ownership of |extension|.
[email protected]902f7cd2009-05-22 19:02:19351 void OnExtensionUnpacked(
[email protected]af1277b2009-07-28 00:47:53352 const FilePath& crx_path,
353 const FilePath& unpacked_path,
354 Extension* extension,
[email protected]7577a5c52009-07-30 06:21:58355 const std::string expected_id);
[email protected]0877fd92009-02-03 16:34:06356
[email protected]cc5da332009-03-04 08:02:51357 // Notify the frontend that there was an error loading an extension.
358 void ReportExtensionLoadError(const FilePath& extension_path,
359 const std::string& error);
[email protected]6014d672008-12-05 00:38:25360
[email protected]ae09ca62009-08-21 19:46:46361 // Notify the frontend that an extension was loaded.
362 void ReportExtensionLoaded(Extension* extension);
[email protected]6014d672008-12-05 00:38:25363
[email protected]a1257b12009-06-12 02:51:34364 // Lookup an external extension by |id| by going through all registered
365 // external extension providers until we find a provider that contains an
366 // extension that matches. If |version| is not NULL, the extension version
367 // will be returned (caller is responsible for deleting that pointer).
368 // |location| can also be null, if not needed. Returns true if extension is
369 // found, false otherwise.
370 bool LookupExternalExtension(const std::string& id,
371 Version** version,
372 Extension::Location* location);
373
[email protected]b0beaa662009-02-26 00:04:15374 // This is a naked pointer which is set by each entry point.
375 // The entry point is responsible for ensuring lifetime.
[email protected]894bb502009-05-21 22:39:57376 ExtensionsService* frontend_;
[email protected]b0beaa662009-02-26 00:04:15377
[email protected]b0beaa662009-02-26 00:04:15378 // The top-level extensions directory being installed to.
379 FilePath install_directory_;
380
381 // Whether errors result in noisy alerts.
382 bool alert_on_error_;
383
[email protected]894bb502009-05-21 22:39:57384 // The message loop to use to call the frontend.
385 MessageLoop* frontend_loop_;
386
[email protected]a1257b12009-06-12 02:51:34387 // A map of all external extension providers.
[email protected]da50530a2009-06-15 17:43:01388 typedef std::map<Extension::Location,
389 linked_ptr<ExternalExtensionProvider> > ProviderMap;
[email protected]a1257b12009-06-12 02:51:34390 ProviderMap external_extension_providers_;
[email protected]894bb502009-05-21 22:39:57391
[email protected]6014d672008-12-05 00:38:25392 DISALLOW_COPY_AND_ASSIGN(ExtensionsServiceBackend);
393};
394
395#endif // CHROME_BROWSER_EXTENSIONS_EXTENSIONS_SERVICE_H_