Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(429)

Unified Diff: chrome/browser/extensions/extension_service.cc

Issue 14973007: Auto-install/uninstall shared module dependencies for extensions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/extension_service.cc
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 89e50cdd342c4208cafade1080e597e23759a141..4c432d1a54d4473133ad5846135a70d1bf483476 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -80,6 +80,7 @@
#include "chrome/common/extensions/api/plugins/plugins_handler.h"
#include "chrome/common/extensions/background_info.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
#include "chrome/common/extensions/extension_messages.h"
@@ -88,6 +89,7 @@
#include "chrome/common/extensions/incognito_handler.h"
#include "chrome/common/extensions/manifest.h"
#include "chrome/common/extensions/manifest_handlers/app_isolation_info.h"
+#include "chrome/common/extensions/manifest_handlers/shared_module_info.h"
#include "chrome/common/extensions/manifest_url_handler.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/startup_metric_utils.h"
@@ -130,6 +132,7 @@ using extensions::Manifest;
using extensions::PermissionMessage;
using extensions::PermissionMessages;
using extensions::PermissionSet;
+using extensions::SharedModuleInfo;
using extensions::UnloadedExtensionInfo;
namespace errors = extension_manifest_errors;
@@ -165,6 +168,10 @@ static bool IsSyncableApp(const Extension& extension) {
return extension.GetSyncType() == Extension::SYNC_TYPE_APP;
}
+static bool IsSharedModule(const Extension& extension) {
+ return SharedModuleInfo::IsSharedModule(&extension);
+}
+
} // namespace
ExtensionService::ExtensionRuntimeData::ExtensionRuntimeData()
@@ -872,6 +879,8 @@ bool ExtensionService::UninstallExtension(
delayed_updates_for_idle_.Remove(extension_id);
delayed_installs_.Remove(extension_id);
+ PruneSharedModulesOnUninstall(extension);
+
// Track the uninstallation.
UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUninstalled", 1, 2);
@@ -2028,6 +2037,8 @@ void ExtensionService::OnLoadedInstalledExtensions() {
OnBlacklistUpdated();
SetReadyAndNotifyListeners();
+
+ CheckImportsOnAllExtensions();
}
void ExtensionService::AddExtension(const Extension* extension) {
@@ -2277,6 +2288,103 @@ void ExtensionService::ScheduleLaunchOnLoad(const std::string& extension_id) {
on_load_events_[extension_id] = EVENT_LAUNCHED;
}
+bool ExtensionService::CheckImports(const Extension* extension) {
+ bool import_failed = false;
+ if (SharedModuleInfo::ImportsModules(extension)) {
+ const std::vector<SharedModuleInfo::ImportInfo>& imports =
+ SharedModuleInfo::GetImports(extension);
+ std::vector<SharedModuleInfo::ImportInfo>::const_iterator i;
+ for (i = imports.begin(); i != imports.end(); ++i) {
+ Version version_required(i->minimum_version);
+ const Extension* imported_module =
+ GetExtensionById(i->extension_id, true);
+ if (!imported_module ||
+ (version_required.IsValid() &&
+ imported_module->version()->CompareTo(version_required) < 0)) {
+ import_failed = true;
+ if (extension->from_webstore()) {
+ if (pending_extension_manager()->AddFromExtensionImport(
asargent_no_longer_on_chrome 2013/05/17 17:13:49 in the implementation of PendingExtensionManager::
+ i->extension_id,
+ extension_urls::GetWebstoreUpdateUrl(),
+ IsSharedModule)) {
+ CheckForUpdatesSoon();
+ }
+ }
+ }
+ if (imported_module &&
+ !SharedModuleInfo::IsSharedModule(imported_module)) {
+ import_failed = true;
+ }
+ }
+ }
+ const std::string& id = extension->id();
+ if (import_failed) {
+ extension_prefs_->AddDisableReason(
+ id, Extension::DISABLE_MISSING_IMPORT);
+ } else if (extension_prefs_->GetDisableReasons(id) ==
+ Extension::DISABLE_MISSING_IMPORT) {
+ EnableExtension(id);
+ }
+ return !import_failed;
+}
+
+void ExtensionService::CheckImportsOnAllExtensions() {
+ std::vector<const Extension*> extensions_to_check;
+ for (ExtensionSet::const_iterator iter = disabled_extensions_.begin();
+ iter != disabled_extensions_.end(); ++iter) {
+ extensions_to_check.push_back(*iter);
+ }
+ for (ExtensionSet::const_iterator iter = extensions_.begin();
+ iter != extensions_.end(); ++iter) {
+ extensions_to_check.push_back(*iter);
+ }
+ std::vector<const Extension*>::const_iterator iter;
+ for (iter = extensions_to_check.begin();
+ iter != extensions_to_check.end();
+ ++iter) {
+ CheckImports(*iter);
+ }
+}
+
+void ExtensionService::PruneSharedModulesOnUninstall(
+ const Extension* extension) {
+ if (SharedModuleInfo::ImportsModules(extension)) {
+ const std::vector<SharedModuleInfo::ImportInfo>& imports =
+ SharedModuleInfo::GetImports(extension);
+ std::vector<SharedModuleInfo::ImportInfo>::const_iterator i;
+ for (i = imports.begin(); i != imports.end(); ++i) {
+ const Extension* imported_module =
+ GetExtensionById(i->extension_id, true);
+ if (!imported_module)
+ continue;
+ if (SharedModuleInfo::IsSharedModule(imported_module)) {
+ bool is_referenced = false;
+ for (ExtensionSet::const_iterator iter = disabled_extensions_.begin();
+ iter != disabled_extensions_.end(); ++iter) {
+ if (SharedModuleInfo::ImportsExtensionById(*iter, i->extension_id)) {
+ is_referenced = true;
+ break;
+ }
+ }
+ if (!is_referenced) {
+ for (ExtensionSet::const_iterator iter = extensions_.begin();
+ iter != extensions_.end(); ++iter) {
+ if (SharedModuleInfo::ImportsExtensionById(*iter,
+ i->extension_id)) {
+ is_referenced = true;
+ break;
+ }
+ }
+ }
+ if (!is_referenced) {
+ UninstallExtension(i->extension_id, false, NULL);
+ }
+ }
+ }
+ }
+}
+
+
void ExtensionService::OnExtensionInstalled(
const Extension* extension,
const syncer::StringOrdinal& page_ordinal,
@@ -2337,6 +2445,10 @@ void ExtensionService::OnExtensionInstalled(
extension_prefs_->ClearDisableReasons(id);
}
+ if (!CheckImports(extension)) {
+ initial_enable = false;
+ }
+
if (!GetInstalledExtension(extension->id())) {
UMA_HISTOGRAM_ENUMERATION("Extensions.InstallType",
extension->GetType(), 100);
@@ -2464,6 +2576,27 @@ void ExtensionService::FinishInstallation(const Extension* extension) {
EXTERNAL_EXTENSION_INSTALLED,
EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
}
+
+ // Check extensions that may be disabled only because this shared module was
+ // not available.
+ if (SharedModuleInfo::IsSharedModule(extension)) {
+ // Build a list of extensions to check because they can't be checked
+ // within the loop iterating over disabled_extensions_ because contents
+ // of that set may change as we CheckImports.
+ std::vector<const Extension*> extensions_to_check;
+ for (ExtensionSet::const_iterator iter = disabled_extensions_.begin();
+ iter != disabled_extensions_.end(); ++iter) {
+ if (SharedModuleInfo::ImportsExtensionById((*iter), extension->id())) {
+ extensions_to_check.push_back(*iter);
+ }
+ }
+ std::vector<const Extension*>::const_iterator iter;
+ for (iter = extensions_to_check.begin();
+ iter != extensions_to_check.end();
+ ++iter) {
+ CheckImports(*iter);
+ }
+ }
}
const Extension* ExtensionService::GetPendingExtensionUpdate(
« no previous file with comments | « chrome/browser/extensions/extension_service.h ('k') | chrome/browser/extensions/pending_extension_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698