blob: 7def6f142ce0e264023be00a9478cdc294d7f5a5 [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]a1257b12009-06-12 02:51:348#include <list>
[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]e2eb43112009-05-29 21:19:5413#include "base/command_line.h"
[email protected]6014d672008-12-05 00:38:2514#include "base/file_path.h"
15#include "base/message_loop.h"
16#include "base/ref_counted.h"
17#include "base/task.h"
[email protected]69f1be82009-04-16 22:27:2118#include "base/values.h"
[email protected]a1257b12009-06-12 02:51:3419#include "chrome/browser/extensions/external_extension_provider.h"
[email protected]e2eb43112009-05-29 21:19:5420#include "chrome/common/chrome_switches.h"
[email protected]25b34332009-06-05 21:53:1921#include "chrome/common/extensions/extension.h"
[email protected]6014d672008-12-05 00:38:2522
[email protected]69f1be82009-04-16 22:27:2123class Browser;
[email protected]25b34332009-06-05 21:53:1924class DictionaryValue;
[email protected]69f1be82009-04-16 22:27:2125class Extension;
[email protected]6014d672008-12-05 00:38:2526class ExtensionsServiceBackend;
[email protected]69f1be82009-04-16 22:27:2127class GURL;
[email protected]894bb502009-05-21 22:39:5728class PrefService;
[email protected]81e63782009-02-27 19:35:0929class Profile;
[email protected]1fca1492009-05-15 22:23:4330class ResourceDispatcherHost;
[email protected]902f7cd2009-05-22 19:02:1931class SkBitmap;
[email protected]69f1be82009-04-16 22:27:2132class SiteInstance;
[email protected]bdbc87c2009-01-25 05:08:5433class UserScriptMaster;
[email protected]a82325a42009-06-10 16:43:0934
[email protected]69f1be82009-04-16 22:27:2135typedef std::vector<Extension*> ExtensionList;
[email protected]6014d672008-12-05 00:38:2536
[email protected]fbcc40302009-06-12 20:45:4537
[email protected]4f313d52009-05-21 00:42:2938// Manages installed and running Chromium extensions.
[email protected]894bb502009-05-21 22:39:5739class ExtensionsService
40 : public base::RefCountedThreadSafe<ExtensionsService> {
[email protected]4f313d52009-05-21 00:42:2941 public:
[email protected]fbcc40302009-06-12 20:45:4542
43 // TODO(port): Move Crx package definitions to ExtentionCreator. They are
44 // currently here because ExtensionCreator is excluded on linux & mac.
45
46 // The size of the magic character sequence at the beginning of each crx
47 // file, in bytes. This should be a multiple of 4.
48 static const size_t kExtensionHeaderMagicSize = 4;
49
50 // The maximum size the crx parser will tolerate for a public key.
51 static const size_t kMaxPublicKeySize = 1 << 16;
52
53 // The maximum size the crx parser will tolerate for a signature.
54 static const size_t kMaxSignatureSize = 1 << 16;
55
56 // The magic character sequence at the beginning of each crx file.
57 static const char kExtensionHeaderMagic[];
58
59 // The current version of the crx format.
60 static const uint32 kCurrentVersion = 2;
61
62 // This header is the first data at the beginning of an extension. Its
63 // contents are purposely 32-bit aligned so that it can just be slurped into
64 // a struct without manual parsing.
65 struct ExtensionHeader {
66 char magic[kExtensionHeaderMagicSize];
67 uint32 version;
68 size_t key_size; // The size of the public key, in bytes.
69 size_t signature_size; // The size of the signature, in bytes.
70 // An ASN.1-encoded PublicKeyInfo structure follows.
71 // The signature follows.
72 };
73
[email protected]894bb502009-05-21 22:39:5774 ExtensionsService(Profile* profile,
75 MessageLoop* frontend_loop,
[email protected]a1257b12009-06-12 02:51:3476 MessageLoop* backend_loop);
[email protected]6014d672008-12-05 00:38:2577 ~ExtensionsService();
78
79 // Gets the list of currently installed extensions.
80 const ExtensionList* extensions() const {
81 return &extensions_;
82 }
83
84 // Initialize and start all installed extensions.
85 bool Init();
86
[email protected]631cf822009-05-15 07:01:2587 // Install the extension file at |extension_path|. Will install as an
88 // update if an older version is already installed.
89 // For fresh installs, this method also causes the extension to be
90 // immediately loaded.
91 void InstallExtension(const FilePath& extension_path);
92
93 // Uninstalls the specified extension. Callers should only call this method
94 // with extensions that exist and are "internal".
95 void UninstallExtension(const std::string& extension_id);
96
97 // Load the extension from the directory |extension_path|.
98 void LoadExtension(const FilePath& extension_path);
99
100 // Lookup an extension by |id|.
[email protected]894bb502009-05-21 22:39:57101 Extension* GetExtensionByID(std::string id);
[email protected]cc655912009-01-29 23:19:19102
[email protected]25b34332009-06-05 21:53:19103 // Gets a list of external extensions. If |external_extensions| is non-null,
104 // a dictionary with all external extensions (including extensions installed
105 // through the registry on Windows builds) and their preferences are
106 // returned. If |killed_extensions| is non-null, a set of string IDs
107 // containing all external extension IDs with the killbit set are returned.
108 void GetExternalExtensions(DictionaryValue* external_extensions,
109 std::set<std::string>* killed_extensions);
110
111 // Gets the settings for an extension from preferences. If the key doesn't
112 // exist, this function creates it (don't need to check return for NULL).
113 DictionaryValue* GetOrCreateExtensionPref(const std::wstring& extension_id);
114
115 // Writes a preference value for a particular extension |extension_id| under
116 // the |key| specified. If |schedule_save| is true, it will also ask the
117 // preference system to schedule a save to disk.
118 bool UpdateExtensionPref(const std::wstring& extension_id,
119 const std::wstring& key,
120 Value* data_value,
121 bool schedule_save);
122
[email protected]a1257b12009-06-12 02:51:34123 // Clear all ExternalExtensionProviders.
124 void ClearProvidersForTesting();
125
126 // Sets an ExternalExtensionProvider for the service to use during testing.
127 // |location| specifies what type of provider should be added.
128 void SetProviderForTesting(Extension::Location location,
129 ExternalExtensionProvider* test_provider);
130
[email protected]cc655912009-01-29 23:19:19131 // The name of the file that the current active version number is stored in.
132 static const char* kCurrentVersionFileName;
[email protected]6014d672008-12-05 00:38:25133
[email protected]e2eb43112009-05-29 21:19:54134 void set_extensions_enabled(bool enabled) { extensions_enabled_ = enabled; }
[email protected]0e34d7892009-06-05 19:17:40135 void set_show_extensions_prompts(bool enabled) {
136 show_extensions_prompts_ = enabled;
[email protected]e2eb43112009-05-29 21:19:54137 }
138
139 bool extensions_enabled() { return extensions_enabled_; }
[email protected]0e34d7892009-06-05 19:17:40140 bool show_extensions_prompts() {
141 return show_extensions_prompts_;
[email protected]e2eb43112009-05-29 21:19:54142 }
143
[email protected]6014d672008-12-05 00:38:25144 private:
[email protected]894bb502009-05-21 22:39:57145 // For OnExtensionLoaded, OnExtensionInstalled, and
146 // OnExtensionVersionReinstalled.
147 friend class ExtensionsServiceBackend;
148
149 // Called by the backend when extensions have been loaded.
150 void OnExtensionsLoaded(ExtensionList* extensions);
151
152 // Called by the backend when an extensoin hsa been installed.
[email protected]fbcc40302009-06-12 20:45:45153 void OnExtensionInstalled(Extension* extension,
154 Extension::InstallType install_type);
[email protected]e2eb43112009-05-29 21:19:54155
[email protected]25b34332009-06-05 21:53:19156 // Called by the backend when an external extension has been installed.
157 void OnExternalExtensionInstalled(
158 const std::string& id, Extension::Location location);
159
[email protected]fbcc40302009-06-12 20:45:45160 // Called by the backend when an attempt was made to reinstall the same
161 // version of an existing extension.
162 void OnExtensionOverinstallAttempted(const std::string& id);
[email protected]894bb502009-05-21 22:39:57163
[email protected]6014d672008-12-05 00:38:25164 // The name of the directory inside the profile where extensions are
165 // installed to.
[email protected]cc655912009-01-29 23:19:19166 static const char* kInstallDirectoryName;
[email protected]6014d672008-12-05 00:38:25167
[email protected]894bb502009-05-21 22:39:57168 // Preferences for the owning profile.
169 PrefService* prefs_;
170
171 // The message loop to use with the backend.
172 MessageLoop* backend_loop_;
[email protected]6014d672008-12-05 00:38:25173
[email protected]6014d672008-12-05 00:38:25174 // The current list of installed extensions.
175 ExtensionList extensions_;
176
177 // The full path to the directory where extensions are installed.
178 FilePath install_directory_;
179
[email protected]e2eb43112009-05-29 21:19:54180 // Whether or not extensions are enabled.
181 bool extensions_enabled_;
182
[email protected]0e34d7892009-06-05 19:17:40183 // Whether to notify users when they attempt to install an extension.
184 bool show_extensions_prompts_;
[email protected]e2eb43112009-05-29 21:19:54185
[email protected]cc5da332009-03-04 08:02:51186 // The backend that will do IO on behalf of this instance.
187 scoped_refptr<ExtensionsServiceBackend> backend_;
188
[email protected]6014d672008-12-05 00:38:25189 DISALLOW_COPY_AND_ASSIGN(ExtensionsService);
190};
191
192// Implements IO for the ExtensionsService.
[email protected]894bb502009-05-21 22:39:57193// TODO(aa): This can probably move into the .cc file.
[email protected]6014d672008-12-05 00:38:25194class ExtensionsServiceBackend
[email protected]a1257b12009-06-12 02:51:34195 : public base::RefCountedThreadSafe<ExtensionsServiceBackend>,
196 public ExternalExtensionProvider::Visitor {
[email protected]6014d672008-12-05 00:38:25197 public:
[email protected]894bb502009-05-21 22:39:57198 // |rdh| can be NULL in the case of test environment.
[email protected]a1257b12009-06-12 02:51:34199 // |extension_prefs| contains a dictionary value that points to the extension
200 // preferences.
[email protected]894bb502009-05-21 22:39:57201 ExtensionsServiceBackend(const FilePath& install_directory,
[email protected]a1257b12009-06-12 02:51:34202 ResourceDispatcherHost* rdh,
203 MessageLoop* frontend_loop,
204 DictionaryValue* extension_prefs);
205
206 virtual ~ExtensionsServiceBackend();
[email protected]6014d672008-12-05 00:38:25207
[email protected]cc5da332009-03-04 08:02:51208 // Loads extensions from the install directory. The extensions are assumed to
209 // be unpacked in directories that are direct children of the specified path.
[email protected]bb28e062009-02-27 17:19:18210 // Errors are reported through ExtensionErrorReporter. On completion,
[email protected]cc5da332009-03-04 08:02:51211 // OnExtensionsLoaded() is called with any successfully loaded extensions.
212 void LoadExtensionsFromInstallDirectory(
[email protected]25b34332009-06-05 21:53:19213 scoped_refptr<ExtensionsService> frontend,
214 DictionaryValue* extension_prefs);
[email protected]6014d672008-12-05 00:38:25215
[email protected]0877fd92009-02-03 16:34:06216 // Loads a single extension from |path| where |path| is the top directory of
217 // a specific extension where its manifest file lives.
[email protected]bb28e062009-02-27 17:19:18218 // Errors are reported through ExtensionErrorReporter. On completion,
[email protected]0877fd92009-02-03 16:34:06219 // OnExtensionsLoadedFromDirectory() is called with any successfully loaded
220 // extensions.
[email protected]3cf4f0992009-02-03 23:00:30221 // TODO(erikkay): It might be useful to be able to load a packed extension
222 // (presumably into memory) without installing it.
[email protected]894bb502009-05-21 22:39:57223 void LoadSingleExtension(const FilePath &path,
224 scoped_refptr<ExtensionsService> frontend);
[email protected]0877fd92009-02-03 16:34:06225
[email protected]cc5da332009-03-04 08:02:51226 // Install the extension file at |extension_path|. Errors are reported through
[email protected]894bb502009-05-21 22:39:57227 // ExtensionErrorReporter. OnExtensionInstalled is called in the frontend on
228 // success.
229 void InstallExtension(const FilePath& extension_path,
230 scoped_refptr<ExtensionsService> frontend);
[email protected]b0beaa662009-02-26 00:04:15231
232 // Check externally updated extensions for updates and install if necessary.
[email protected]894bb502009-05-21 22:39:57233 // Errors are reported through ExtensionErrorReporter. Succcess is not
234 // reported.
235 void CheckForExternalUpdates(std::set<std::string> ids_to_ignore,
236 scoped_refptr<ExtensionsService> frontend);
[email protected]cc655912009-01-29 23:19:19237
[email protected]631cf822009-05-15 07:01:25238 // Deletes all versions of the extension from the filesystem. Note that only
239 // extensions whose location() == INTERNAL can be uninstalled. Attempting to
240 // uninstall other extensions will silently fail.
241 void UninstallExtension(const std::string& extension_id);
242
[email protected]a1257b12009-06-12 02:51:34243 // Clear all ExternalExtensionProviders.
244 void ClearProvidersForTesting();
245
246 // Sets an ExternalExtensionProvider for the service to use during testing.
247 // |location| specifies what type of provider should be added.
248 void SetProviderForTesting(Extension::Location location,
249 ExternalExtensionProvider* test_provider);
250
251 // ExternalExtensionProvider::Visitor implementation.
252 virtual void OnExternalExtensionFound(const std::string& id,
253 const Version* version,
254 const FilePath& path);
[email protected]6014d672008-12-05 00:38:25255 private:
[email protected]1fca1492009-05-15 22:23:43256 class UnpackerClient;
257 friend class UnpackerClient;
258
[email protected]fbcc40302009-06-12 20:45:45259 // Utility function to read an extension manifest and return it as a
260 // DictionaryValue. If it fails, NULL is returned and |error| contains an
261 // appropriate message.
262 DictionaryValue* ReadManifest(FilePath manifest_path, std::string* error);
263
[email protected]cc5da332009-03-04 08:02:51264 // Load a single extension from |extension_path|, the top directory of
[email protected]0877fd92009-02-03 16:34:06265 // a specific extension where its manifest file lives.
[email protected]a1257b12009-06-12 02:51:34266 Extension* LoadExtension(const FilePath& extension_path,
267 Extension::Location location,
268 bool require_id);
[email protected]b0beaa662009-02-26 00:04:15269
[email protected]cc5da332009-03-04 08:02:51270 // Load a single extension from |extension_path|, the top directory of
[email protected]b0beaa662009-02-26 00:04:15271 // a versioned extension where its Current Version file lives.
[email protected]cc5da332009-03-04 08:02:51272 Extension* LoadExtensionCurrentVersion(const FilePath& extension_path);
[email protected]b0beaa662009-02-26 00:04:15273
[email protected]1fca1492009-05-15 22:23:43274 // Install a crx file at |extension_path|. If |expected_id| is not empty, it's
275 // verified against the extension's manifest before installation. If
276 // |from_external| is true, this extension install is from an external source,
277 // ie the Windows registry, and will be marked as such. If the extension is
278 // already installed, install the new version only if its version number is
279 // greater than the current installed version.
280 void InstallOrUpdateExtension(const FilePath& extension_path,
[email protected]cc5da332009-03-04 08:02:51281 const std::string& expected_id,
[email protected]1fca1492009-05-15 22:23:43282 bool from_external);
283
[email protected]fbcc40302009-06-12 20:45:45284 // Validates the signature of the extension in |extension_path|. Returns true
285 // and the public key (in |key|) if the signature validates, false otherwise.
286 bool ValidateSignature(const FilePath& extension_path, std::string* key_out);
287
[email protected]1fca1492009-05-15 22:23:43288 // Finish installing an extension after it has been unpacked to
289 // |temp_extension_dir| by our utility process. If |expected_id| is not
290 // empty, it's verified against the extension's manifest before installation.
[email protected]902f7cd2009-05-22 19:02:19291 // |manifest| and |images| are parsed information from the extension that
292 // we want to write to disk in the browser process.
293 void OnExtensionUnpacked(
294 const FilePath& extension_path,
295 const FilePath& temp_extension_dir,
296 const std::string expected_id,
297 bool from_external,
298 const DictionaryValue& manifest,
299 const std::vector< Tuple2<SkBitmap, FilePath> >& images);
[email protected]0877fd92009-02-03 16:34:06300
[email protected]cc5da332009-03-04 08:02:51301 // Notify the frontend that there was an error loading an extension.
302 void ReportExtensionLoadError(const FilePath& extension_path,
303 const std::string& error);
[email protected]6014d672008-12-05 00:38:25304
[email protected]cc5da332009-03-04 08:02:51305 // Notify the frontend that extensions were loaded.
[email protected]b0beaa662009-02-26 00:04:15306 void ReportExtensionsLoaded(ExtensionList* extensions);
[email protected]6014d672008-12-05 00:38:25307
[email protected]cc5da332009-03-04 08:02:51308 // Notify the frontend that there was an error installing an extension.
309 void ReportExtensionInstallError(const FilePath& extension_path,
310 const std::string& error);
[email protected]cc655912009-01-29 23:19:19311
[email protected]fbcc40302009-06-12 20:45:45312 // Notify the frontend that an attempt was made (but not carried out) to
313 // install the same version of an existing extension.
314 void ReportExtensionOverinstallAttempted(const std::string& id);
[email protected]4a190632009-05-09 01:07:42315
[email protected]25b34332009-06-05 21:53:19316 // Checks a set of strings (containing id's to ignore) in order to determine
317 // if the extension should be installed.
318 bool ShouldSkipInstallingExtension(const std::set<std::string>& ids_to_ignore,
319 const std::string& id);
320
321 // Installs the extension if the extension is a newer version or if the
322 // extension hasn't been installed before.
323 void CheckVersionAndInstallExtension(const std::string& id,
[email protected]a1257b12009-06-12 02:51:34324 const Version* extension_version,
[email protected]25b34332009-06-05 21:53:19325 const FilePath& extension_path,
326 bool from_external);
327
[email protected]a1257b12009-06-12 02:51:34328 // Lookup an external extension by |id| by going through all registered
329 // external extension providers until we find a provider that contains an
330 // extension that matches. If |version| is not NULL, the extension version
331 // will be returned (caller is responsible for deleting that pointer).
332 // |location| can also be null, if not needed. Returns true if extension is
333 // found, false otherwise.
334 bool LookupExternalExtension(const std::string& id,
335 Version** version,
336 Extension::Location* location);
337
[email protected]e2eb43112009-05-29 21:19:54338 // Read the manifest from the front of the extension file.
339 // Caller takes ownership of return value.
340 DictionaryValue* ReadManifest(const FilePath& extension_path);
341
[email protected]b0beaa662009-02-26 00:04:15342 // Reads the Current Version file from |dir| into |version_string|.
343 bool ReadCurrentVersion(const FilePath& dir, std::string* version_string);
[email protected]18a12352009-01-31 01:33:28344
[email protected]fbcc40302009-06-12 20:45:45345 // Look for an existing installation of the extension |id| & return
346 // an InstallType that would result from installing |new_version_str|.
347 Extension::InstallType CompareToInstalledVersion(const std::string& id,
348 const std::string& new_version_str, std::string* current_version_str);
349
350 // Does an existing installed extension need to be reinstalled.
351 bool NeedsReinstall(const std::string& id,
352 const std::string& current_version);
[email protected]cc655912009-01-29 23:19:19353
354 // Install the extension dir by moving it from |source| to |dest| safely.
[email protected]b0beaa662009-02-26 00:04:15355 bool InstallDirSafely(const FilePath& source,
356 const FilePath& dest);
[email protected]cc655912009-01-29 23:19:19357
358 // Update the CurrentVersion file in |dest_dir| to |version|.
[email protected]b0beaa662009-02-26 00:04:15359 bool SetCurrentVersion(const FilePath& dest_dir,
360 std::string version);
361
[email protected]894bb502009-05-21 22:39:57362 // For the extension in |version_path| with |id|, check to see if it's an
[email protected]b0beaa662009-02-26 00:04:15363 // externally managed extension. If so return true if it should be
364 // uninstalled.
[email protected]25b34332009-06-05 21:53:19365 bool CheckExternalUninstall(DictionaryValue* extension_prefs,
366 const FilePath& version_path,
[email protected]894bb502009-05-21 22:39:57367 const std::string& id);
[email protected]b0beaa662009-02-26 00:04:15368
[email protected]b0beaa662009-02-26 00:04:15369 // Should an extension of |id| and |version| be installed?
370 // Returns true if no extension of type |id| is installed or if |version|
371 // is greater than the current installed version.
[email protected]a1257b12009-06-12 02:51:34372 bool ShouldInstall(const std::string& id, const Version* version);
[email protected]cc655912009-01-29 23:19:19373
374 // The name of a temporary directory to install an extension into for
375 // validation before finalizing install.
376 static const char* kTempExtensionName;
377
[email protected]b0beaa662009-02-26 00:04:15378 // This is a naked pointer which is set by each entry point.
379 // The entry point is responsible for ensuring lifetime.
[email protected]894bb502009-05-21 22:39:57380 ExtensionsService* frontend_;
[email protected]b0beaa662009-02-26 00:04:15381
[email protected]b0beaa662009-02-26 00:04:15382 // The top-level extensions directory being installed to.
383 FilePath install_directory_;
384
[email protected]1fca1492009-05-15 22:23:43385 // We only need a pointer to this to pass along to other interfaces.
386 ResourceDispatcherHost* resource_dispatcher_host_;
387
[email protected]b0beaa662009-02-26 00:04:15388 // Whether errors result in noisy alerts.
389 bool alert_on_error_;
390
[email protected]894bb502009-05-21 22:39:57391 // The message loop to use to call the frontend.
392 MessageLoop* frontend_loop_;
393
[email protected]a1257b12009-06-12 02:51:34394 // A map of all external extension providers.
395 typedef std::map<Extension::Location, ExternalExtensionProvider*> ProviderMap;
396 ProviderMap external_extension_providers_;
[email protected]894bb502009-05-21 22:39:57397
[email protected]6014d672008-12-05 00:38:25398 DISALLOW_COPY_AND_ASSIGN(ExtensionsServiceBackend);
399};
400
401#endif // CHROME_BROWSER_EXTENSIONS_EXTENSIONS_SERVICE_H_