OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extensions_service.h" | 5 #include "chrome/browser/extensions/extensions_service.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
11 #include "chrome/browser/extensions/crx_installer.h" | 11 #include "chrome/browser/extensions/crx_installer.h" |
12 #include "chrome/browser/extensions/extension_browser_event_router.h" | 12 #include "chrome/browser/extensions/extension_browser_event_router.h" |
13 #include "chrome/browser/extensions/extension_file_util.h" | 13 #include "chrome/browser/extensions/extension_file_util.h" |
14 #include "chrome/browser/extensions/extension_updater.h" | 14 #include "chrome/browser/extensions/extension_updater.h" |
15 #include "chrome/browser/extensions/external_extension_provider.h" | 15 #include "chrome/browser/extensions/external_extension_provider.h" |
16 #include "chrome/browser/extensions/external_pref_extension_provider.h" | 16 #include "chrome/browser/extensions/external_pref_extension_provider.h" |
17 #include "chrome/browser/extensions/theme_preview_infobar_delegate.h" | |
18 #include "chrome/browser/profile.h" | 17 #include "chrome/browser/profile.h" |
19 #include "chrome/browser/tab_contents/tab_contents.h" | |
20 #include "chrome/common/chrome_switches.h" | 18 #include "chrome/common/chrome_switches.h" |
21 #include "chrome/common/extensions/extension.h" | 19 #include "chrome/common/extensions/extension.h" |
22 #include "chrome/common/extensions/extension_error_reporter.h" | 20 #include "chrome/common/extensions/extension_error_reporter.h" |
23 #include "chrome/common/notification_service.h" | 21 #include "chrome/common/notification_service.h" |
24 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
25 #include "chrome/common/pref_service.h" | 23 #include "chrome/common/pref_service.h" |
26 #include "chrome/common/url_constants.h" | 24 #include "chrome/common/url_constants.h" |
27 | 25 |
28 #if defined(OS_WIN) | 26 #if defined(OS_WIN) |
29 #include "chrome/browser/extensions/external_registry_extension_provider_win.h" | 27 #include "chrome/browser/extensions/external_registry_extension_provider_win.h" |
30 #endif | 28 #endif |
31 | 29 |
32 // ExtensionsService. | 30 // ExtensionsService. |
33 | 31 |
34 const char* ExtensionsService::kInstallDirectoryName = "Extensions"; | 32 const char* ExtensionsService::kInstallDirectoryName = "Extensions"; |
35 const char* ExtensionsService::kCurrentVersionFileName = "Current Version"; | 33 const char* ExtensionsService::kCurrentVersionFileName = "Current Version"; |
36 | 34 |
| 35 /* |
37 const char* ExtensionsService::kGalleryDownloadURLPrefix = | 36 const char* ExtensionsService::kGalleryDownloadURLPrefix = |
38 "https://dl-ssl.google.com/chrome/"; | 37 "https://dl-ssl.google.com/chrome/"; |
39 const char* ExtensionsService::kGalleryURLPrefix = | 38 const char* ExtensionsService::kGalleryURLPrefix = |
40 "https://tools.google.com/chrome/"; | 39 "https://tools.google.com/chrome/"; |
| 40 */ |
| 41 const char* ExtensionsService::kGalleryDownloadURLPrefix = |
| 42 "http://www.corp.google.com/~glen/chrome/"; |
| 43 const char* ExtensionsService::kGalleryURLPrefix = |
| 44 "http://www.corp.google.com/~glen/chrome/"; |
41 | 45 |
42 // static | 46 // static |
43 bool ExtensionsService::IsDownloadFromGallery(const GURL& download_url, | 47 bool ExtensionsService::IsDownloadFromGallery(const GURL& download_url, |
44 const GURL& referrer_url) { | 48 const GURL& referrer_url) { |
45 if (StartsWithASCII(download_url.spec(), kGalleryDownloadURLPrefix, false) && | 49 if (StartsWithASCII(download_url.spec(), kGalleryDownloadURLPrefix, false) && |
46 StartsWithASCII(referrer_url.spec(), kGalleryURLPrefix, false)) { | 50 StartsWithASCII(referrer_url.spec(), kGalleryURLPrefix, false)) { |
47 return true; | 51 return true; |
48 } else { | 52 } else { |
49 return false; | 53 return false; |
50 } | 54 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 | 105 |
102 // TODO(erikkay) this should probably be deferred to a future point | 106 // TODO(erikkay) this should probably be deferred to a future point |
103 // rather than running immediately at startup. | 107 // rather than running immediately at startup. |
104 CheckForExternalUpdates(); | 108 CheckForExternalUpdates(); |
105 | 109 |
106 // TODO(erikkay) this should probably be deferred as well. | 110 // TODO(erikkay) this should probably be deferred as well. |
107 GarbageCollectExtensions(); | 111 GarbageCollectExtensions(); |
108 } | 112 } |
109 | 113 |
110 void ExtensionsService::InstallExtension(const FilePath& extension_path) { | 114 void ExtensionsService::InstallExtension(const FilePath& extension_path) { |
111 InstallExtension(extension_path, GURL(), GURL()); | 115 CrxInstaller::Start(extension_path, install_directory_, Extension::INTERNAL, |
112 } | 116 "", // no expected id |
113 | 117 false, // don't delete crx when complete |
114 void ExtensionsService::InstallExtension(const FilePath& extension_path, | 118 backend_loop_, |
115 const GURL& download_url, | 119 this, |
116 const GURL& referrer_url) { | 120 NULL); // no client (silent install) |
117 new CrxInstaller(extension_path, install_directory_, Extension::INTERNAL, | |
118 "", // no expected id | |
119 extensions_enabled_, | |
120 IsDownloadFromGallery(download_url, referrer_url), | |
121 show_extensions_prompts(), | |
122 false, // don't delete crx when complete | |
123 backend_loop_, | |
124 this); | |
125 } | 121 } |
126 | 122 |
127 void ExtensionsService::UpdateExtension(const std::string& id, | 123 void ExtensionsService::UpdateExtension(const std::string& id, |
128 const FilePath& extension_path) { | 124 const FilePath& extension_path) { |
129 if (!GetExtensionById(id)) { | 125 if (!GetExtensionById(id)) { |
130 LOG(WARNING) << "Will not update extension " << id << " because it is not " | 126 LOG(WARNING) << "Will not update extension " << id << " because it is not " |
131 << "installed"; | 127 << "installed"; |
132 return; | 128 return; |
133 } | 129 } |
134 | 130 |
135 new CrxInstaller(extension_path, install_directory_, Extension::INTERNAL, | 131 CrxInstaller::Start(extension_path, install_directory_, Extension::INTERNAL, |
136 id, extensions_enabled_, | 132 id, |
137 false, // not from gallery | 133 true, // delete crx when complete |
138 show_extensions_prompts(), | 134 backend_loop_, |
139 true, // delete crx when complete | 135 this, |
140 backend_loop_, | 136 NULL); // no client (silent install) |
141 this); | |
142 } | 137 } |
143 | 138 |
144 void ExtensionsService::ReloadExtension(const std::string& extension_id) { | 139 void ExtensionsService::ReloadExtension(const std::string& extension_id) { |
145 Extension* extension = GetExtensionById(extension_id); | 140 Extension* extension = GetExtensionById(extension_id); |
146 FilePath extension_path = extension->path(); | 141 FilePath extension_path = extension->path(); |
147 | 142 |
148 UnloadExtension(extension_id); | 143 UnloadExtension(extension_id); |
149 LoadExtension(extension_path); | 144 LoadExtension(extension_path); |
150 } | 145 } |
151 | 146 |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 } | 299 } |
305 } | 300 } |
306 } | 301 } |
307 | 302 |
308 void ExtensionsService::OnExtensionInstalled(Extension* extension) { | 303 void ExtensionsService::OnExtensionInstalled(Extension* extension) { |
309 extension_prefs_->OnExtensionInstalled(extension); | 304 extension_prefs_->OnExtensionInstalled(extension); |
310 | 305 |
311 // If the extension is a theme, tell the profile (and therefore ThemeProvider) | 306 // If the extension is a theme, tell the profile (and therefore ThemeProvider) |
312 // to apply it. | 307 // to apply it. |
313 if (extension->IsTheme()) { | 308 if (extension->IsTheme()) { |
314 ShowThemePreviewInfobar(extension); | |
315 NotificationService::current()->Notify( | 309 NotificationService::current()->Notify( |
316 NotificationType::THEME_INSTALLED, | 310 NotificationType::THEME_INSTALLED, |
317 Source<ExtensionsService>(this), | 311 Source<ExtensionsService>(this), |
318 Details<Extension>(extension)); | 312 Details<Extension>(extension)); |
319 } else { | 313 } else { |
320 NotificationService::current()->Notify( | 314 NotificationService::current()->Notify( |
321 NotificationType::EXTENSION_INSTALLED, | 315 NotificationType::EXTENSION_INSTALLED, |
322 Source<ExtensionsService>(this), | 316 Source<ExtensionsService>(this), |
323 Details<Extension>(extension)); | 317 Details<Extension>(extension)); |
324 } | 318 } |
325 | 319 |
326 // Also load the extension. | 320 // Also load the extension. |
327 ExtensionList* list = new ExtensionList; | 321 ExtensionList* list = new ExtensionList; |
328 list->push_back(extension); | 322 list->push_back(extension); |
329 OnExtensionsLoaded(list); | 323 OnExtensionsLoaded(list); |
330 } | 324 } |
331 | 325 |
332 | 326 |
333 void ExtensionsService::OnExtensionOverinstallAttempted(const std::string& id) { | 327 void ExtensionsService::OnExtensionOverinstallAttempted(const std::string& id) { |
334 Extension* extension = GetExtensionById(id); | 328 Extension* extension = GetExtensionById(id); |
335 if (extension && extension->IsTheme()) { | 329 if (extension && extension->IsTheme()) { |
336 ShowThemePreviewInfobar(extension); | |
337 NotificationService::current()->Notify( | 330 NotificationService::current()->Notify( |
338 NotificationType::THEME_INSTALLED, | 331 NotificationType::THEME_INSTALLED, |
339 Source<ExtensionsService>(this), | 332 Source<ExtensionsService>(this), |
340 Details<Extension>(extension)); | 333 Details<Extension>(extension)); |
341 } | 334 } |
342 } | 335 } |
343 | 336 |
344 Extension* ExtensionsService::GetExtensionById(const std::string& id) { | 337 Extension* ExtensionsService::GetExtensionById(const std::string& id) { |
345 std::string lowercase_id = StringToLowerASCII(id); | 338 std::string lowercase_id = StringToLowerASCII(id); |
346 for (ExtensionList::const_iterator iter = extensions_.begin(); | 339 for (ExtensionList::const_iterator iter = extensions_.begin(); |
(...skipping 14 matching lines...) Expand all Loading... |
361 &ExtensionsServiceBackend::ClearProvidersForTesting)); | 354 &ExtensionsServiceBackend::ClearProvidersForTesting)); |
362 } | 355 } |
363 | 356 |
364 void ExtensionsService::SetProviderForTesting( | 357 void ExtensionsService::SetProviderForTesting( |
365 Extension::Location location, ExternalExtensionProvider* test_provider) { | 358 Extension::Location location, ExternalExtensionProvider* test_provider) { |
366 backend_loop_->PostTask(FROM_HERE, NewRunnableMethod(backend_.get(), | 359 backend_loop_->PostTask(FROM_HERE, NewRunnableMethod(backend_.get(), |
367 &ExtensionsServiceBackend::SetProviderForTesting, | 360 &ExtensionsServiceBackend::SetProviderForTesting, |
368 location, test_provider)); | 361 location, test_provider)); |
369 } | 362 } |
370 | 363 |
371 bool ExtensionsService::ShowThemePreviewInfobar(Extension* extension) { | |
372 if (!profile_) | |
373 return false; | |
374 | |
375 Browser* browser = BrowserList::GetLastActiveWithProfile(profile_); | |
376 if (!browser) | |
377 return false; | |
378 | |
379 TabContents* tab_contents = browser->GetSelectedTabContents(); | |
380 if (!tab_contents) | |
381 return false; | |
382 | |
383 tab_contents->AddInfoBar(new ThemePreviewInfobarDelegate(tab_contents, | |
384 extension->name())); | |
385 return true; | |
386 } | |
387 | |
388 void ExtensionsService::OnExternalExtensionFound(const std::string& id, | 364 void ExtensionsService::OnExternalExtensionFound(const std::string& id, |
389 const std::string& version, | 365 const std::string& version, |
390 const FilePath& path, | 366 const FilePath& path, |
391 Extension::Location location) { | 367 Extension::Location location) { |
392 // Before even bothering to unpack, check and see if we already have this | 368 // Before even bothering to unpack, check and see if we already have this |
393 // version. This is important because these extensions are going to get | 369 // version. This is important because these extensions are going to get |
394 // installed on every startup. | 370 // installed on every startup. |
395 Extension* existing = GetExtensionById(id); | 371 Extension* existing = GetExtensionById(id); |
396 if (existing) { | 372 if (existing) { |
397 switch (existing->version()->CompareTo( | 373 switch (existing->version()->CompareTo( |
398 *Version::GetVersionFromString(version))) { | 374 *Version::GetVersionFromString(version))) { |
399 case -1: // existing version is older, we should upgrade | 375 case -1: // existing version is older, we should upgrade |
400 break; | 376 break; |
401 case 0: // existing version is same, do nothing | 377 case 0: // existing version is same, do nothing |
402 return; | 378 return; |
403 case 1: // existing version is newer, uh-oh | 379 case 1: // existing version is newer, uh-oh |
404 LOG(WARNING) << "Found external version of extension " << id | 380 LOG(WARNING) << "Found external version of extension " << id |
405 << "that is older than current version. Current version " | 381 << "that is older than current version. Current version " |
406 << "is: " << existing->VersionString() << ". New version " | 382 << "is: " << existing->VersionString() << ". New version " |
407 << "is: " << version << ". Keeping current version."; | 383 << "is: " << version << ". Keeping current version."; |
408 return; | 384 return; |
409 } | 385 } |
410 } | 386 } |
411 | 387 |
412 new CrxInstaller(path, install_directory_, location, id, extensions_enabled_, | 388 CrxInstaller::Start(path, install_directory_, location, id, |
413 false, // not from gallery | 389 false, // don't delete crx when complete |
414 show_extensions_prompts(), | 390 backend_loop_, |
415 false, // don't delete crx when complete | 391 this, |
416 backend_loop_, | 392 NULL); // no client (silent install) |
417 this); | |
418 } | 393 } |
419 | 394 |
420 | 395 |
421 // ExtensionsServicesBackend | 396 // ExtensionsServicesBackend |
422 | 397 |
423 ExtensionsServiceBackend::ExtensionsServiceBackend( | 398 ExtensionsServiceBackend::ExtensionsServiceBackend( |
424 const FilePath& install_directory, MessageLoop* frontend_loop) | 399 const FilePath& install_directory, MessageLoop* frontend_loop) |
425 : frontend_(NULL), | 400 : frontend_(NULL), |
426 install_directory_(install_directory), | 401 install_directory_(install_directory), |
427 alert_on_error_(false), | 402 alert_on_error_(false), |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 linked_ptr<ExternalExtensionProvider>(test_provider); | 581 linked_ptr<ExternalExtensionProvider>(test_provider); |
607 } | 582 } |
608 | 583 |
609 void ExtensionsServiceBackend::OnExternalExtensionFound( | 584 void ExtensionsServiceBackend::OnExternalExtensionFound( |
610 const std::string& id, const Version* version, const FilePath& path, | 585 const std::string& id, const Version* version, const FilePath& path, |
611 Extension::Location location) { | 586 Extension::Location location) { |
612 frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(frontend_, | 587 frontend_loop_->PostTask(FROM_HERE, NewRunnableMethod(frontend_, |
613 &ExtensionsService::OnExternalExtensionFound, id, version->GetString(), | 588 &ExtensionsService::OnExternalExtensionFound, id, version->GetString(), |
614 path, location)); | 589 path, location)); |
615 } | 590 } |
OLD | NEW |