Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / shared_module_service.cc
blob583bbe1036b511fbb3b208f2fa47c3bea7a8be58
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/shared_module_service.h"
7 #include <set>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/version.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/pending_extension_manager.h"
15 #include "extensions/browser/extension_registry.h"
16 #include "extensions/browser/extension_system.h"
17 #include "extensions/browser/uninstall_reason.h"
18 #include "extensions/common/extension.h"
19 #include "extensions/common/extension_urls.h"
21 namespace extensions {
23 namespace {
25 typedef std::vector<SharedModuleInfo::ImportInfo> ImportInfoVector;
26 typedef std::list<SharedModuleInfo::ImportInfo> ImportInfoList;
28 } // namespace
30 SharedModuleService::SharedModuleService(content::BrowserContext* context)
31 : extension_registry_observer_(this), browser_context_(context) {
32 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
35 SharedModuleService::~SharedModuleService() {
38 SharedModuleService::ImportStatus SharedModuleService::CheckImports(
39 const Extension* extension,
40 ImportInfoList* missing_modules,
41 ImportInfoList* outdated_modules) {
42 DCHECK(extension);
43 DCHECK(missing_modules && missing_modules->empty());
44 DCHECK(outdated_modules && outdated_modules->empty());
46 ImportStatus status = IMPORT_STATUS_OK;
48 // TODO(crbug.com/420147): Code like this lives in CrxInstaller and
49 // UnpackedInstaller. If a change is made here that is important to enforce
50 // at install time, those locations need to be updated.
51 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
52 const ImportInfoVector& imports = SharedModuleInfo::GetImports(extension);
53 for (ImportInfoVector::const_iterator iter = imports.begin();
54 iter != imports.end();
55 ++iter) {
56 base::Version version_required(iter->minimum_version);
57 const Extension* imported_module =
58 registry->GetExtensionById(iter->extension_id,
59 ExtensionRegistry::EVERYTHING);
60 if (!imported_module) {
61 if (extension->from_webstore()) {
62 status = IMPORT_STATUS_UNSATISFIED;
63 missing_modules->push_back(*iter);
64 } else {
65 return IMPORT_STATUS_UNRECOVERABLE;
67 } else if (!SharedModuleInfo::IsSharedModule(imported_module)) {
68 return IMPORT_STATUS_UNRECOVERABLE;
69 } else if (version_required.IsValid() &&
70 imported_module->version()->CompareTo(version_required) < 0) {
71 if (imported_module->from_webstore()) {
72 outdated_modules->push_back(*iter);
73 status = IMPORT_STATUS_UNSATISFIED;
74 } else {
75 return IMPORT_STATUS_UNRECOVERABLE;
80 return status;
83 SharedModuleService::ImportStatus SharedModuleService::SatisfyImports(
84 const Extension* extension) {
85 ImportInfoList missing_modules;
86 ImportInfoList outdated_modules;
87 ImportStatus status =
88 CheckImports(extension, &missing_modules, &outdated_modules);
90 ExtensionService* service =
91 ExtensionSystem::Get(browser_context_)->extension_service();
93 PendingExtensionManager* pending_extension_manager =
94 service->pending_extension_manager();
95 DCHECK(pending_extension_manager);
97 if (status == IMPORT_STATUS_UNSATISFIED) {
98 for (ImportInfoList::const_iterator iter = missing_modules.begin();
99 iter != missing_modules.end();
100 ++iter) {
101 pending_extension_manager->AddFromExtensionImport(
102 iter->extension_id,
103 extension_urls::GetWebstoreUpdateUrl(),
104 SharedModuleInfo::IsSharedModule);
106 service->CheckForUpdatesSoon();
108 return status;
111 scoped_ptr<ExtensionSet> SharedModuleService::GetDependentExtensions(
112 const Extension* extension) {
113 scoped_ptr<ExtensionSet> dependents(new ExtensionSet());
115 if (SharedModuleInfo::IsSharedModule(extension)) {
116 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
117 ExtensionService* service =
118 ExtensionSystem::Get(browser_context_)->extension_service();
120 ExtensionSet set_to_check;
121 set_to_check.InsertAll(registry->enabled_extensions());
122 set_to_check.InsertAll(registry->disabled_extensions());
123 set_to_check.InsertAll(*service->delayed_installs());
125 for (ExtensionSet::const_iterator iter = set_to_check.begin();
126 iter != set_to_check.end();
127 ++iter) {
128 if (SharedModuleInfo::ImportsExtensionById(iter->get(),
129 extension->id())) {
130 dependents->Insert(*iter);
134 return dependents.Pass();
137 void SharedModuleService::PruneSharedModules() {
138 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_);
139 ExtensionService* service =
140 ExtensionSystem::Get(browser_context_)->extension_service();
142 ExtensionSet set_to_check;
143 set_to_check.InsertAll(registry->enabled_extensions());
144 set_to_check.InsertAll(registry->disabled_extensions());
145 set_to_check.InsertAll(*service->delayed_installs());
147 std::vector<std::string> shared_modules;
148 std::set<std::string> used_shared_modules;
150 for (ExtensionSet::const_iterator iter = set_to_check.begin();
151 iter != set_to_check.end();
152 ++iter) {
153 if (SharedModuleInfo::IsSharedModule(iter->get()))
154 shared_modules.push_back(iter->get()->id());
156 const ImportInfoVector& imports = SharedModuleInfo::GetImports(iter->get());
157 for (ImportInfoVector::const_iterator imports_iter = imports.begin();
158 imports_iter != imports.end();
159 ++imports_iter) {
160 used_shared_modules.insert(imports_iter->extension_id);
164 std::vector<std::string>::const_iterator shared_modules_iter;
165 for (shared_modules_iter = shared_modules.begin();
166 shared_modules_iter != shared_modules.end();
167 shared_modules_iter++) {
168 if (used_shared_modules.count(*shared_modules_iter))
169 continue;
170 service->UninstallExtension(
171 *shared_modules_iter,
172 extensions::UNINSTALL_REASON_ORPHANED_SHARED_MODULE,
173 base::Bind(&base::DoNothing),
174 NULL); // Ignore error.
178 void SharedModuleService::OnExtensionInstalled(
179 content::BrowserContext* browser_context,
180 const Extension* extension,
181 bool is_update) {
182 if (is_update)
183 PruneSharedModules();
186 void SharedModuleService::OnExtensionUninstalled(
187 content::BrowserContext* browser_context,
188 const Extension* extension,
189 extensions::UninstallReason reason) {
190 PruneSharedModules();
193 } // namespace extensions