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

Side by Side Diff: chrome/browser/extensions/extension_file_util.cc

Issue 174036: Get rid of the extension's "Current Version" file. (Closed)
Patch Set: merge conflicts Created 11 years, 4 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 unified diff | Download patch
OLDNEW
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/extension_file_util.h" 5 #include "chrome/browser/extensions/extension_file_util.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/scoped_temp_dir.h" 9 #include "base/scoped_temp_dir.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
11 #include "chrome/browser/extensions/extension_prefs.h"
11 #include "chrome/browser/extensions/extension_l10n_util.h" 12 #include "chrome/browser/extensions/extension_l10n_util.h"
12 #include "chrome/common/extensions/extension.h" 13 #include "chrome/common/extensions/extension.h"
13 #include "chrome/common/extensions/extension_constants.h" 14 #include "chrome/common/extensions/extension_constants.h"
14 #include "chrome/common/json_value_serializer.h" 15 #include "chrome/common/json_value_serializer.h"
15 #include "net/base/file_stream.h" 16 #include "net/base/file_stream.h"
16 17
17 namespace extension_file_util { 18 namespace extension_file_util {
18 19
19 const char kInstallDirectoryName[] = "Extensions"; 20 const char kInstallDirectoryName[] = "Extensions";
21 // TODO(mpcomplete): obsolete. remove after migration period.
22 // http://code.google.com/p/chromium/issues/detail?id=19733
20 const char kCurrentVersionFileName[] = "Current Version"; 23 const char kCurrentVersionFileName[] = "Current Version";
21 24
22 bool MoveDirSafely(const FilePath& source_dir, const FilePath& dest_dir) { 25 bool MoveDirSafely(const FilePath& source_dir, const FilePath& dest_dir) {
23 if (file_util::PathExists(dest_dir)) { 26 if (file_util::PathExists(dest_dir)) {
24 if (!file_util::Delete(dest_dir, true)) 27 if (!file_util::Delete(dest_dir, true))
25 return false; 28 return false;
26 } else { 29 } else {
27 FilePath parent = dest_dir.DirName(); 30 FilePath parent = dest_dir.DirName();
28 if (!file_util::DirectoryExists(parent)) { 31 if (!file_util::DirectoryExists(parent)) {
29 if (!file_util::CreateDirectory(parent)) 32 if (!file_util::CreateDirectory(parent))
30 return false; 33 return false;
31 } 34 }
32 } 35 }
33 36
34 if (!file_util::Move(source_dir, dest_dir)) 37 if (!file_util::Move(source_dir, dest_dir))
35 return false; 38 return false;
36 39
37 return true; 40 return true;
38 } 41 }
39 42
40 bool SetCurrentVersion(const FilePath& dest_dir, const std::string& version, 43 Extension::InstallType CompareToInstalledVersion(
41 std::string* error) { 44 const FilePath& extensions_dir,
42 // Write out the new CurrentVersion file. 45 const std::string& extension_id,
43 // <profile>/Extension/<name>/CurrentVersion 46 const std::string& current_version_str,
44 FilePath current_version = dest_dir.AppendASCII(kCurrentVersionFileName); 47 const std::string& new_version_str,
45 FilePath current_version_old = 48 FilePath* version_dir) {
46 current_version.InsertBeforeExtension(FILE_PATH_LITERAL("_old")); 49 FilePath dest_dir = extensions_dir.AppendASCII(extension_id);
47 if (file_util::PathExists(current_version_old)) { 50 FilePath current_version_dir = dest_dir.AppendASCII(current_version_str);
48 if (!file_util::Delete(current_version_old, false)) { 51 *version_dir = dest_dir.AppendASCII(new_version_str);
49 *error = "Couldn't remove CurrentVersion_old file.";
50 return false;
51 }
52 }
53 52
54 if (file_util::PathExists(current_version)) { 53 if (current_version_str.empty())
55 if (!file_util::Move(current_version, current_version_old)) {
56 *error = "Couldn't move CurrentVersion file.";
57 return false;
58 }
59 }
60 net::FileStream stream;
61 int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE;
62 if (stream.Open(current_version, flags) != 0)
63 return false;
64 if (stream.Write(version.c_str(), version.size(), NULL) < 0) {
65 // Restore the old CurrentVersion.
66 if (file_util::PathExists(current_version_old)) {
67 if (!file_util::Move(current_version_old, current_version)) {
68 LOG(WARNING) << "couldn't restore " << current_version_old.value() <<
69 " to " << current_version.value();
70
71 // TODO(erikkay): This is an ugly state to be in. Try harder?
72 }
73 }
74 *error = "Couldn't create CurrentVersion file.";
75 return false;
76 }
77 return true;
78 }
79
80 bool ReadCurrentVersion(const FilePath& dir, std::string* version_string) {
81 FilePath current_version = dir.AppendASCII(kCurrentVersionFileName);
82 if (file_util::PathExists(current_version)) {
83 if (file_util::ReadFileToString(current_version, version_string)) {
84 TrimWhitespaceASCII(*version_string, TRIM_ALL, version_string);
85 return true;
86 }
87 }
88 return false;
89 }
90
91 Extension::InstallType CompareToInstalledVersion(
92 const FilePath& install_directory, const std::string& id,
93 const std::string& new_version_str, std::string *current_version_str) {
94 CHECK(current_version_str);
95 FilePath dir(install_directory.AppendASCII(id.c_str()));
96 if (!ReadCurrentVersion(dir, current_version_str))
97 return Extension::NEW_INSTALL; 54 return Extension::NEW_INSTALL;
98 55
99 scoped_ptr<Version> current_version( 56 scoped_ptr<Version> current_version(
100 Version::GetVersionFromString(*current_version_str)); 57 Version::GetVersionFromString(current_version_str));
101 scoped_ptr<Version> new_version( 58 scoped_ptr<Version> new_version(
102 Version::GetVersionFromString(new_version_str)); 59 Version::GetVersionFromString(new_version_str));
103 int comp = new_version->CompareTo(*current_version); 60 int comp = new_version->CompareTo(*current_version);
104 if (comp > 0) 61 if (comp > 0)
105 return Extension::UPGRADE; 62 return Extension::UPGRADE;
106 else if (comp == 0) 63 if (comp < 0)
107 return Extension::REINSTALL;
108 else
109 return Extension::DOWNGRADE; 64 return Extension::DOWNGRADE;
65
66 // Same version. Treat corrupted existing installation as new install case.
67 if (!SanityCheckExtension(current_version_dir))
68 return Extension::NEW_INSTALL;
69
70 return Extension::REINSTALL;
110 } 71 }
111 72
112 bool SanityCheckExtension(const FilePath& dir) { 73 bool SanityCheckExtension(const FilePath& dir) {
113 // Verify that the directory actually exists. 74 // Verify that the directory actually exists.
114 // TODO(erikkay): A further step would be to verify that the extension 75 // TODO(erikkay): A further step would be to verify that the extension
115 // has actually loaded successfully. 76 // has actually loaded successfully.
116 FilePath manifest_file(dir.AppendASCII(Extension::kManifestFilename)); 77 FilePath manifest_file(dir.AppendASCII(Extension::kManifestFilename));
117 return file_util::PathExists(dir) && file_util::PathExists(manifest_file); 78 return file_util::PathExists(dir) && file_util::PathExists(manifest_file);
118 } 79 }
119 80
120 bool InstallExtension(const FilePath& src_dir, 81 bool InstallExtension(const FilePath& src_dir,
121 const FilePath& extensions_dir, 82 const FilePath& version_dir,
122 const std::string& extension_id,
123 const std::string& extension_version,
124 FilePath* version_dir,
125 Extension::InstallType* install_type,
126 std::string* error) { 83 std::string* error) {
127 FilePath dest_dir = extensions_dir.AppendASCII(extension_id);
128 *version_dir = dest_dir.AppendASCII(extension_version);
129
130 std::string current_version;
131 *install_type = CompareToInstalledVersion(
132 extensions_dir, extension_id, extension_version, &current_version);
133
134 // Do not allow downgrade.
135 if (*install_type == Extension::DOWNGRADE)
136 return true;
137
138 if (*install_type == Extension::REINSTALL) {
139 if (!SanityCheckExtension(*version_dir)) {
140 // Treat corrupted existing installation as new install case.
141 *install_type = Extension::NEW_INSTALL;
142 } else {
143 return true;
144 }
145 }
146
147 // If anything fails after this, we want to delete the extension dir. 84 // If anything fails after this, we want to delete the extension dir.
148 ScopedTempDir scoped_version_dir; 85 ScopedTempDir scoped_version_dir;
149 scoped_version_dir.Set(*version_dir); 86 scoped_version_dir.Set(version_dir);
150 87
151 if (!MoveDirSafely(src_dir, *version_dir)) { 88 if (!MoveDirSafely(src_dir, version_dir)) {
152 *error = "Could not move extension directory into profile."; 89 *error = "Could not move extension directory into profile.";
153 return false; 90 return false;
154 } 91 }
155 92
156 if (!SetCurrentVersion(dest_dir, extension_version, error))
157 return false;
158
159 scoped_version_dir.Take(); 93 scoped_version_dir.Take();
160 return true; 94 return true;
161 } 95 }
162 96
163 Extension* LoadExtension(const FilePath& extension_path, bool require_key, 97 Extension* LoadExtension(const FilePath& extension_path, bool require_key,
164 std::string* error) { 98 std::string* error) {
165 FilePath manifest_path = 99 FilePath manifest_path =
166 extension_path.AppendASCII(Extension::kManifestFilename); 100 extension_path.AppendASCII(Extension::kManifestFilename);
167 if (!file_util::PathExists(manifest_path)) { 101 if (!file_util::PathExists(manifest_path)) {
168 *error = extension_manifest_errors::kInvalidManifest; 102 *error = extension_manifest_errors::kInvalidManifest;
169 return NULL; 103 return NULL;
170 } 104 }
171 105
172 JSONFileValueSerializer serializer(manifest_path); 106 JSONFileValueSerializer serializer(manifest_path);
173 scoped_ptr<Value> root(serializer.Deserialize(error)); 107 scoped_ptr<Value> root(serializer.Deserialize(error));
174 if (!root.get()) 108 if (!root.get())
175 return NULL; 109 return NULL;
176 110
177 if (!root->IsType(Value::TYPE_DICTIONARY)) { 111 if (!root->IsType(Value::TYPE_DICTIONARY)) {
178 *error = extension_manifest_errors::kInvalidManifest; 112 *error = extension_manifest_errors::kInvalidManifest;
179 return NULL; 113 return NULL;
180 } 114 }
181 115
182 scoped_ptr<Extension> extension(new Extension(extension_path)); 116 scoped_ptr<Extension> extension(new Extension(extension_path));
183 if (!extension->InitFromValue(*static_cast<DictionaryValue*>(root.get()), 117 if (!extension->InitFromValue(*static_cast<DictionaryValue*>(root.get()),
184 require_key, error)) 118 require_key, error))
185 return NULL; 119 return NULL;
186 120
121 if (!ValidateExtension(extension.get(), error))
122 return NULL;
123
124 return extension.release();
125 }
126
127 bool ValidateExtension(Extension* extension, std::string* error) {
187 // Validate icons exist. 128 // Validate icons exist.
188 for (std::map<int, std::string>::const_iterator iter = 129 for (std::map<int, std::string>::const_iterator iter =
189 extension->icons().begin(); iter != extension->icons().end(); ++iter) { 130 extension->icons().begin(); iter != extension->icons().end(); ++iter) {
190 if (!file_util::PathExists(extension->GetResourcePath(iter->second))) { 131 if (!file_util::PathExists(extension->GetResourcePath(iter->second))) {
191 *error = StringPrintf("Could not load extension icon '%s'.", 132 *error = StringPrintf("Could not load extension icon '%s'.",
192 iter->second.c_str()); 133 iter->second.c_str());
193 return NULL; 134 return false;
194 } 135 }
195 } 136 }
196 137
197 // Theme resource validation. 138 // Theme resource validation.
198 if (extension->IsTheme()) { 139 if (extension->IsTheme()) {
199 DictionaryValue* images_value = extension->GetThemeImages(); 140 DictionaryValue* images_value = extension->GetThemeImages();
200 if (images_value) { 141 if (images_value) {
201 for (DictionaryValue::key_iterator iter = images_value->begin_keys(); 142 for (DictionaryValue::key_iterator iter = images_value->begin_keys();
202 iter != images_value->end_keys(); ++iter) { 143 iter != images_value->end_keys(); ++iter) {
203 std::string val; 144 std::string val;
204 if (images_value->GetString(*iter, &val)) { 145 if (images_value->GetString(*iter, &val)) {
205 FilePath image_path = extension->path().AppendASCII(val); 146 FilePath image_path = extension->path().AppendASCII(val);
206 if (!file_util::PathExists(image_path)) { 147 if (!file_util::PathExists(image_path)) {
207 *error = StringPrintf( 148 *error = StringPrintf(
208 "Could not load '%s' for theme.", 149 "Could not load '%s' for theme.",
209 WideToUTF8(image_path.ToWStringHack()).c_str()); 150 WideToUTF8(image_path.ToWStringHack()).c_str());
210 return NULL; 151 return false;
211 } 152 }
212 } 153 }
213 } 154 }
214 } 155 }
215 156
216 // Themes cannot contain other extension types. 157 // Themes cannot contain other extension types.
217 return extension.release(); 158 return true;
218 } 159 }
219 160
220 // Validate that claimed script resources actually exist. 161 // Validate that claimed script resources actually exist.
221 for (size_t i = 0; i < extension->content_scripts().size(); ++i) { 162 for (size_t i = 0; i < extension->content_scripts().size(); ++i) {
222 const UserScript& script = extension->content_scripts()[i]; 163 const UserScript& script = extension->content_scripts()[i];
223 164
224 for (size_t j = 0; j < script.js_scripts().size(); j++) { 165 for (size_t j = 0; j < script.js_scripts().size(); j++) {
225 const FilePath& path = script.js_scripts()[j].path(); 166 const FilePath& path = script.js_scripts()[j].path();
226 if (!file_util::PathExists(path)) { 167 if (!file_util::PathExists(path)) {
227 *error = StringPrintf("Could not load '%s' for content script.", 168 *error = StringPrintf("Could not load '%s' for content script.",
228 WideToUTF8(path.ToWStringHack()).c_str()); 169 WideToUTF8(path.ToWStringHack()).c_str());
229 return NULL; 170 return false;
230 } 171 }
231 } 172 }
232 173
233 for (size_t j = 0; j < script.css_scripts().size(); j++) { 174 for (size_t j = 0; j < script.css_scripts().size(); j++) {
234 const FilePath& path = script.css_scripts()[j].path(); 175 const FilePath& path = script.css_scripts()[j].path();
235 if (!file_util::PathExists(path)) { 176 if (!file_util::PathExists(path)) {
236 *error = StringPrintf("Could not load '%s' for content script.", 177 *error = StringPrintf("Could not load '%s' for content script.",
237 WideToUTF8(path.ToWStringHack()).c_str()); 178 WideToUTF8(path.ToWStringHack()).c_str());
238 return NULL; 179 return false;
239 } 180 }
240 } 181 }
241 } 182 }
242 183
243 // Validate claimed plugin paths. 184 // Validate claimed plugin paths.
244 for (size_t i = 0; i < extension->plugins().size(); ++i) { 185 for (size_t i = 0; i < extension->plugins().size(); ++i) {
245 const Extension::PluginInfo& plugin = extension->plugins()[i]; 186 const Extension::PluginInfo& plugin = extension->plugins()[i];
246 if (!file_util::PathExists(plugin.path)) { 187 if (!file_util::PathExists(plugin.path)) {
247 *error = StringPrintf("Could not load '%s' for plugin.", 188 *error = StringPrintf("Could not load '%s' for plugin.",
248 WideToUTF8(plugin.path.ToWStringHack()).c_str()); 189 WideToUTF8(plugin.path.ToWStringHack()).c_str());
249 return NULL; 190 return false;
250 } 191 }
251 } 192 }
252 193
253 // Validate claimed privacy blacklists paths. 194 // Validate claimed privacy blacklists paths.
254 for (size_t i = 0; i < extension->privacy_blacklists().size(); ++i) { 195 for (size_t i = 0; i < extension->privacy_blacklists().size(); ++i) {
255 const Extension::PrivacyBlacklistInfo& blacklist = 196 const Extension::PrivacyBlacklistInfo& blacklist =
256 extension->privacy_blacklists()[i]; 197 extension->privacy_blacklists()[i];
257 if (!file_util::PathExists(blacklist.path)) { 198 if (!file_util::PathExists(blacklist.path)) {
258 *error = StringPrintf("Could not load '%s' for privacy blacklist.", 199 *error = StringPrintf("Could not load '%s' for privacy blacklist.",
259 WideToUTF8(blacklist.path.ToWStringHack()).c_str()); 200 WideToUTF8(blacklist.path.ToWStringHack()).c_str());
260 return NULL; 201 return false;
261 } 202 }
262 } 203 }
263 204
264 // Validate icon location for page actions. 205 // Validate icon location for page actions.
265 const PageActionMap& page_actions = extension->page_actions(); 206 const PageActionMap& page_actions = extension->page_actions();
266 for (PageActionMap::const_iterator i(page_actions.begin()); 207 for (PageActionMap::const_iterator i(page_actions.begin());
267 i != page_actions.end(); ++i) { 208 i != page_actions.end(); ++i) {
268 PageAction* page_action = i->second; 209 PageAction* page_action = i->second;
269 const std::vector<std::string>& icon_paths = page_action->icon_paths(); 210 const std::vector<std::string>& icon_paths = page_action->icon_paths();
270 for (std::vector<std::string>::const_iterator iter = icon_paths.begin(); 211 for (std::vector<std::string>::const_iterator iter = icon_paths.begin();
271 iter != icon_paths.end(); ++iter) { 212 iter != icon_paths.end(); ++iter) {
272 if (!file_util::PathExists(extension->GetResourcePath(*iter))) { 213 if (!file_util::PathExists(extension->GetResourcePath(*iter))) {
273 *error = StringPrintf("Could not load icon '%s' for page action.", 214 *error = StringPrintf("Could not load icon '%s' for page action.",
274 iter->c_str()); 215 iter->c_str());
275 return NULL; 216 return false;
276 } 217 }
277 } 218 }
278 } 219 }
279 220
280 // Load locale information if available. 221 // Load locale information if available.
281 FilePath locale_path = extension_path.AppendASCII(Extension::kLocaleFolder); 222 FilePath locale_path =
223 extension->path().AppendASCII(Extension::kLocaleFolder);
282 if (file_util::PathExists(locale_path)) { 224 if (file_util::PathExists(locale_path)) {
283 if (!extension_l10n_util::AddValidLocales(locale_path, 225 if (!extension_l10n_util::AddValidLocales(locale_path,
284 extension.get(), 226 extension,
285 error)) { 227 error)) {
286 return NULL; 228 return false;
287 } 229 }
288 230
289 if (!extension_l10n_util::ValidateDefaultLocale(extension.get())) { 231 if (!extension_l10n_util::ValidateDefaultLocale(extension)) {
290 *error = extension_manifest_errors::kLocalesNoDefaultLocaleSpecified; 232 *error = extension_manifest_errors::kLocalesNoDefaultLocaleSpecified;
291 return NULL; 233 return false;
292 } 234 }
293 } 235 }
294 236
295 // Check children of extension root to see if any of them start with _ and is 237 // Check children of extension root to see if any of them start with _ and is
296 // not on the reserved list. 238 // not on the reserved list.
297 if (!CheckForIllegalFilenames(extension_path, error)) { 239 if (!CheckForIllegalFilenames(extension->path(), error)) {
298 return NULL; 240 return false;
299 } 241 }
300 242
301 return extension.release(); 243 return true;
302 } 244 }
303 245
304 void UninstallExtension(const std::string& id, const FilePath& extensions_dir) { 246 void UninstallExtension(const std::string& id, const FilePath& extensions_dir) {
305 // First, delete the Current Version file. If the directory delete fails, then 247 // First, delete the Current Version file. If the directory delete fails, then
306 // at least the extension won't be loaded again. 248 // at least the extension won't be loaded again.
307 FilePath extension_root = extensions_dir.AppendASCII(id); 249 FilePath extension_root = extensions_dir.AppendASCII(id);
308 250
309 if (!file_util::PathExists(extension_root)) { 251 if (!file_util::PathExists(extension_root)) {
310 LOG(WARNING) << "Asked to remove a non-existent extension " << id; 252 LOG(WARNING) << "Asked to remove a non-existent extension " << id;
311 return; 253 return;
312 } 254 }
313 255
314 FilePath current_version_file = extension_root.AppendASCII( 256 FilePath current_version_file = extension_root.AppendASCII(
315 kCurrentVersionFileName); 257 kCurrentVersionFileName);
316 if (!file_util::PathExists(current_version_file)) { 258 if (!file_util::PathExists(current_version_file)) {
317 LOG(WARNING) << "Extension " << id 259 // This is OK, since we're phasing out the current version file.
318 << " does not have a Current Version file.";
319 } else { 260 } else {
320 if (!file_util::Delete(current_version_file, false)) { 261 if (!file_util::Delete(current_version_file, false)) {
321 LOG(WARNING) << "Could not delete Current Version file for extension " 262 LOG(WARNING) << "Could not delete Current Version file for extension "
322 << id; 263 << id;
323 return; 264 return;
324 } 265 }
325 } 266 }
326 267
327 // OK, now try and delete the entire rest of the directory. One major place 268 // OK, now try and delete the entire rest of the directory. One major place
328 // this can fail is if the extension contains a plugin (stupid plugins). It's 269 // this can fail is if the extension contains a plugin (stupid plugins). It's
329 // not a big deal though, because we'll notice next time we startup that the 270 // not a big deal though, because we'll notice next time we startup that the
330 // Current Version file is gone and finish the delete then. 271 // Current Version file is gone and finish the delete then.
331 if (!file_util::Delete(extension_root, true)) 272 if (!file_util::Delete(extension_root, true))
332 LOG(WARNING) << "Could not delete directory for extension " << id; 273 LOG(WARNING) << "Could not delete directory for extension " << id;
333 } 274 }
334 275
335 void GarbageCollectExtensions(const FilePath& install_directory) { 276 void GarbageCollectExtensions(const FilePath& install_directory,
277 const std::set<std::string>& installed_ids) {
336 // Nothing to clean up if it doesn't exist. 278 // Nothing to clean up if it doesn't exist.
337 if (!file_util::DirectoryExists(install_directory)) 279 if (!file_util::DirectoryExists(install_directory))
338 return; 280 return;
339 281
340 LOG(INFO) << "Loading installed extensions..."; 282 LOG(INFO) << "Loading installed extensions...";
341 file_util::FileEnumerator enumerator(install_directory, 283 file_util::FileEnumerator enumerator(install_directory,
342 false, // Not recursive. 284 false, // Not recursive.
343 file_util::FileEnumerator::DIRECTORIES); 285 file_util::FileEnumerator::DIRECTORIES);
344 FilePath extension_path; 286 FilePath extension_path;
345 for (extension_path = enumerator.Next(); !extension_path.value().empty(); 287 for (extension_path = enumerator.Next(); !extension_path.value().empty();
346 extension_path = enumerator.Next()) { 288 extension_path = enumerator.Next()) {
347 std::string extension_id = WideToASCII( 289 std::string extension_id = WideToASCII(
348 extension_path.BaseName().ToWStringHack()); 290 extension_path.BaseName().ToWStringHack());
349 291
350 // If there is no Current Version file, just delete the directory and move 292 // If there is no entry in the prefs file, just delete the directory and
351 // on. This can legitimately happen when an uninstall does not complete, for 293 // move on. This can legitimately happen when an uninstall does not
352 // example, when a plugin is in use at uninstall time. 294 // complete, for example, when a plugin is in use at uninstall time.
353 FilePath current_version_path = extension_path.AppendASCII( 295 if (installed_ids.count(extension_id) == 0) {
354 kCurrentVersionFileName); 296 LOG(INFO) << "Deleting unreferenced install for directory "
355 if (!file_util::PathExists(current_version_path)) {
356 LOG(INFO) << "Deleting incomplete install for directory "
357 << WideToASCII(extension_path.ToWStringHack()) << "."; 297 << WideToASCII(extension_path.ToWStringHack()) << ".";
358 file_util::Delete(extension_path, true); // Recursive. 298 file_util::Delete(extension_path, true); // Recursive.
359 continue; 299 continue;
360 } 300 }
361 301
362 // Ignore directories that aren't valid IDs. 302 // Ignore directories that aren't valid IDs.
363 if (!Extension::IdIsValid(extension_id)) { 303 if (!Extension::IdIsValid(extension_id)) {
364 LOG(WARNING) << "Invalid extension ID encountered in extensions " 304 LOG(WARNING) << "Invalid extension ID encountered in extensions "
365 "directory: " << extension_id; 305 "directory: " << extension_id;
366 LOG(INFO) << "Deleting invalid extension directory " 306 LOG(INFO) << "Deleting invalid extension directory "
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 "Cannot load extension with file or directory name %s." 342 "Cannot load extension with file or directory name %s."
403 "Filenames starting with \"_\" are reserved for use by the system", 343 "Filenames starting with \"_\" are reserved for use by the system",
404 filename.c_str()); 344 filename.c_str());
405 return false; 345 return false;
406 } 346 }
407 } 347 }
408 348
409 return true; 349 return true;
410 } 350 }
411 351
412 } // extensionfile_util 352 } // extension_file_util
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_file_util.h ('k') | chrome/browser/extensions/extension_file_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698