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

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

Issue 10581043: Merge 142921 - Use an infobar instead of alert box for extension install (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1180/src/
Patch Set: Created 8 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/crx_installer.h" 5 #include "chrome/browser/extensions/crx_installer.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 BrowserThread::FILE, FROM_HERE, 165 BrowserThread::FILE, FROM_HERE,
166 base::Bind(&CrxInstaller::ConvertUserScriptOnFileThread, this))) 166 base::Bind(&CrxInstaller::ConvertUserScriptOnFileThread, this)))
167 NOTREACHED(); 167 NOTREACHED();
168 } 168 }
169 169
170 void CrxInstaller::ConvertUserScriptOnFileThread() { 170 void CrxInstaller::ConvertUserScriptOnFileThread() {
171 string16 error; 171 string16 error;
172 scoped_refptr<Extension> extension = 172 scoped_refptr<Extension> extension =
173 ConvertUserScriptToExtension(source_file_, download_url_, &error); 173 ConvertUserScriptToExtension(source_file_, download_url_, &error);
174 if (!extension) { 174 if (!extension) {
175 ReportFailureFromFileThread(error); 175 ReportFailureFromFileThread(CrxInstallerError(error));
176 return; 176 return;
177 } 177 }
178 178
179 OnUnpackSuccess(extension->path(), extension->path(), NULL, extension); 179 OnUnpackSuccess(extension->path(), extension->path(), NULL, extension);
180 } 180 }
181 181
182 void CrxInstaller::InstallWebApp(const WebApplicationInfo& web_app) { 182 void CrxInstaller::InstallWebApp(const WebApplicationInfo& web_app) {
183 if (!BrowserThread::PostTask( 183 if (!BrowserThread::PostTask(
184 BrowserThread::FILE, FROM_HERE, 184 BrowserThread::FILE, FROM_HERE,
185 base::Bind(&CrxInstaller::ConvertWebAppOnFileThread, this, web_app))) 185 base::Bind(&CrxInstaller::ConvertWebAppOnFileThread, this, web_app)))
186 NOTREACHED(); 186 NOTREACHED();
187 } 187 }
188 188
189 void CrxInstaller::ConvertWebAppOnFileThread( 189 void CrxInstaller::ConvertWebAppOnFileThread(
190 const WebApplicationInfo& web_app) { 190 const WebApplicationInfo& web_app) {
191 string16 error; 191 string16 error;
192 scoped_refptr<Extension> extension( 192 scoped_refptr<Extension> extension(
193 ConvertWebAppToExtension(web_app, base::Time::Now())); 193 ConvertWebAppToExtension(web_app, base::Time::Now()));
194 if (!extension) { 194 if (!extension) {
195 // Validation should have stopped any potential errors before getting here. 195 // Validation should have stopped any potential errors before getting here.
196 NOTREACHED() << "Could not convert web app to extension."; 196 NOTREACHED() << "Could not convert web app to extension.";
197 return; 197 return;
198 } 198 }
199 199
200 // TODO(aa): conversion data gets lost here :( 200 // TODO(aa): conversion data gets lost here :(
201 201
202 OnUnpackSuccess(extension->path(), extension->path(), NULL, extension); 202 OnUnpackSuccess(extension->path(), extension->path(), NULL, extension);
203 } 203 }
204 204
205 bool CrxInstaller::AllowInstall(const Extension* extension, 205 CrxInstallerError CrxInstaller::AllowInstall(const Extension* extension) {
206 string16* error) {
207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
208 DCHECK(error);
209 207
210 // Make sure the expected ID matches if one was supplied or if we want to 208 // Make sure the expected ID matches if one was supplied or if we want to
211 // bypass the prompt. 209 // bypass the prompt.
212 if ((approved_ || !expected_id_.empty()) && 210 if ((approved_ || !expected_id_.empty()) &&
213 expected_id_ != extension->id()) { 211 expected_id_ != extension->id()) {
214 *error = l10n_util::GetStringFUTF16(IDS_EXTENSION_INSTALL_UNEXPECTED_ID, 212 return CrxInstallerError(
215 ASCIIToUTF16(expected_id_), 213 l10n_util::GetStringFUTF16(IDS_EXTENSION_INSTALL_UNEXPECTED_ID,
216 ASCIIToUTF16(extension->id())); 214 ASCIIToUTF16(expected_id_),
217 return false; 215 ASCIIToUTF16(extension->id())));
218 } 216 }
219 217
220 if (expected_version_.get() && 218 if (expected_version_.get() &&
221 !expected_version_->Equals(*extension->version())) { 219 !expected_version_->Equals(*extension->version())) {
222 *error = l10n_util::GetStringFUTF16( 220 return CrxInstallerError(
223 IDS_EXTENSION_INSTALL_UNEXPECTED_VERSION, 221 l10n_util::GetStringFUTF16(
224 ASCIIToUTF16(expected_version_->GetString()), 222 IDS_EXTENSION_INSTALL_UNEXPECTED_VERSION,
225 ASCIIToUTF16(extension->version()->GetString())); 223 ASCIIToUTF16(expected_version_->GetString()),
226 return false; 224 ASCIIToUTF16(extension->version()->GetString())));
227 } 225 }
228 226
229 // Make sure the manifests match if we want to bypass the prompt. 227 // Make sure the manifests match if we want to bypass the prompt.
230 if (approved_ && 228 if (approved_ &&
231 (!expected_manifest_.get() || 229 (!expected_manifest_.get() ||
232 !expected_manifest_->Equals(original_manifest_.get()))) { 230 !expected_manifest_->Equals(original_manifest_.get()))) {
233 *error = l10n_util::GetStringUTF16(IDS_EXTENSION_MANIFEST_INVALID); 231 return CrxInstallerError(
234 return false; 232 l10n_util::GetStringUTF16(IDS_EXTENSION_MANIFEST_INVALID));
235 } 233 }
236 234
237 // The checks below are skipped for themes and external installs. 235 // The checks below are skipped for themes and external installs.
238 // TODO(pamg): After ManagementPolicy refactoring is complete, remove this 236 // TODO(pamg): After ManagementPolicy refactoring is complete, remove this
239 // and other uses of install_source_ that are no longer needed now that the 237 // and other uses of install_source_ that are no longer needed now that the
240 // SandboxedExtensionUnpacker sets extension->location. 238 // SandboxedExtensionUnpacker sets extension->location.
241 if (extension->is_theme() || Extension::IsExternalLocation(install_source_)) 239 if (extension->is_theme() || Extension::IsExternalLocation(install_source_))
242 return true; 240 return CrxInstallerError();
243 241
244 if (!extensions_enabled_) { 242 if (!extensions_enabled_) {
245 *error = l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_NOT_ENABLED); 243 return CrxInstallerError(
246 return false; 244 l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_NOT_ENABLED));
247 } 245 }
248 246
249 if (install_cause_ == extension_misc::INSTALL_CAUSE_USER_DOWNLOAD) { 247 if (install_cause_ == extension_misc::INSTALL_CAUSE_USER_DOWNLOAD) {
250 if (extensions::switch_utils::IsEasyOffStoreInstallEnabled()) { 248 if (extensions::switch_utils::IsEasyOffStoreInstallEnabled()) {
251 const char* kHistogramName = "Extensions.OffStoreInstallDecisionEasy"; 249 const char* kHistogramName = "Extensions.OffStoreInstallDecisionEasy";
252 if (is_gallery_install()) { 250 if (is_gallery_install()) {
253 UMA_HISTOGRAM_ENUMERATION(kHistogramName, OnStoreInstall, 251 UMA_HISTOGRAM_ENUMERATION(kHistogramName, OnStoreInstall,
254 NumOffStoreInstallDecision); 252 NumOffStoreInstallDecision);
255 } else { 253 } else {
256 UMA_HISTOGRAM_ENUMERATION(kHistogramName, OffStoreInstallAllowed, 254 UMA_HISTOGRAM_ENUMERATION(kHistogramName, OffStoreInstallAllowed,
257 NumOffStoreInstallDecision); 255 NumOffStoreInstallDecision);
258 } 256 }
259 } else { 257 } else {
260 const char* kHistogramName = "Extensions.OffStoreInstallDecisionHard"; 258 const char* kHistogramName = "Extensions.OffStoreInstallDecisionHard";
261 if (is_gallery_install()) { 259 if (is_gallery_install()) {
262 UMA_HISTOGRAM_ENUMERATION(kHistogramName, OnStoreInstall, 260 UMA_HISTOGRAM_ENUMERATION(kHistogramName, OnStoreInstall,
263 NumOffStoreInstallDecision); 261 NumOffStoreInstallDecision);
264 } else if (off_store_install_allow_reason_ != OffStoreInstallDisallowed) { 262 } else if (off_store_install_allow_reason_ != OffStoreInstallDisallowed) {
265 UMA_HISTOGRAM_ENUMERATION(kHistogramName, OffStoreInstallAllowed, 263 UMA_HISTOGRAM_ENUMERATION(kHistogramName, OffStoreInstallAllowed,
266 NumOffStoreInstallDecision); 264 NumOffStoreInstallDecision);
267 UMA_HISTOGRAM_ENUMERATION("Extensions.OffStoreInstallAllowReason", 265 UMA_HISTOGRAM_ENUMERATION("Extensions.OffStoreInstallAllowReason",
268 off_store_install_allow_reason_, 266 off_store_install_allow_reason_,
269 NumOffStoreInstallAllowReasons); 267 NumOffStoreInstallAllowReasons);
270 } else { 268 } else {
271 UMA_HISTOGRAM_ENUMERATION(kHistogramName, OffStoreInstallDisallowed, 269 UMA_HISTOGRAM_ENUMERATION(kHistogramName, OffStoreInstallDisallowed,
272 NumOffStoreInstallDecision); 270 NumOffStoreInstallDecision);
273 *error = l10n_util::GetStringUTF16(
274 IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE);
275 // Don't delete source in this case so that the user can install 271 // Don't delete source in this case so that the user can install
276 // manually if they want. 272 // manually if they want.
277 delete_source_ = false; 273 delete_source_ = false;
278 did_handle_successfully_ = false; 274 did_handle_successfully_ = false;
279 return false; 275
276 return CrxInstallerError(
277 CrxInstallerError::ERROR_OFF_STORE,
278 l10n_util::GetStringUTF16(
279 IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE));
280 } 280 }
281 } 281 }
282 } 282 }
283 283
284 if (extension_->is_app()) { 284 if (extension_->is_app()) {
285 // If the app was downloaded, apps_require_extension_mime_type_ 285 // If the app was downloaded, apps_require_extension_mime_type_
286 // will be set. In this case, check that it was served with the 286 // will be set. In this case, check that it was served with the
287 // right mime type. Make an exception for file URLs, which come 287 // right mime type. Make an exception for file URLs, which come
288 // from the users computer and have no headers. 288 // from the users computer and have no headers.
289 if (!download_url_.SchemeIsFile() && 289 if (!download_url_.SchemeIsFile() &&
290 apps_require_extension_mime_type_ && 290 apps_require_extension_mime_type_ &&
291 original_mime_type_ != Extension::kMimeType) { 291 original_mime_type_ != Extension::kMimeType) {
292 *error = l10n_util::GetStringFUTF16( 292 return CrxInstallerError(
293 IDS_EXTENSION_INSTALL_INCORRECT_APP_CONTENT_TYPE, 293 l10n_util::GetStringFUTF16(
294 ASCIIToUTF16(Extension::kMimeType)); 294 IDS_EXTENSION_INSTALL_INCORRECT_APP_CONTENT_TYPE,
295 return false; 295 ASCIIToUTF16(Extension::kMimeType)));
296 } 296 }
297 297
298 // If the client_ is NULL, then the app is either being installed via 298 // If the client_ is NULL, then the app is either being installed via
299 // an internal mechanism like sync, external_extensions, or default apps. 299 // an internal mechanism like sync, external_extensions, or default apps.
300 // In that case, we don't want to enforce things like the install origin. 300 // In that case, we don't want to enforce things like the install origin.
301 if (!is_gallery_install() && client_) { 301 if (!is_gallery_install() && client_) {
302 // For apps with a gallery update URL, require that they be installed 302 // For apps with a gallery update URL, require that they be installed
303 // from the gallery. 303 // from the gallery.
304 // TODO(erikkay) Apply this rule for paid extensions and themes as well. 304 // TODO(erikkay) Apply this rule for paid extensions and themes as well.
305 if (extension->UpdatesFromGallery()) { 305 if (extension->UpdatesFromGallery()) {
306 *error = l10n_util::GetStringFUTF16( 306 return CrxInstallerError(
307 IDS_EXTENSION_DISALLOW_NON_DOWNLOADED_GALLERY_INSTALLS, 307 l10n_util::GetStringFUTF16(
308 l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE)); 308 IDS_EXTENSION_DISALLOW_NON_DOWNLOADED_GALLERY_INSTALLS,
309 return false; 309 l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE)));
310 } 310 }
311 311
312 // For self-hosted apps, verify that the entire extent is on the same 312 // For self-hosted apps, verify that the entire extent is on the same
313 // host (or a subdomain of the host) the download happened from. There's 313 // host (or a subdomain of the host) the download happened from. There's
314 // no way for us to verify that the app controls any other hosts. 314 // no way for us to verify that the app controls any other hosts.
315 URLPattern pattern(UserScript::kValidUserScriptSchemes); 315 URLPattern pattern(UserScript::kValidUserScriptSchemes);
316 pattern.SetHost(download_url_.host()); 316 pattern.SetHost(download_url_.host());
317 pattern.SetMatchSubdomains(true); 317 pattern.SetMatchSubdomains(true);
318 318
319 URLPatternSet patterns = extension_->web_extent(); 319 URLPatternSet patterns = extension_->web_extent();
320 for (URLPatternSet::const_iterator i = patterns.begin(); 320 for (URLPatternSet::const_iterator i = patterns.begin();
321 i != patterns.end(); ++i) { 321 i != patterns.end(); ++i) {
322 if (!pattern.MatchesHost(i->host())) { 322 if (!pattern.MatchesHost(i->host())) {
323 *error = l10n_util::GetStringUTF16( 323 return CrxInstallerError(
324 IDS_EXTENSION_INSTALL_INCORRECT_INSTALL_HOST); 324 l10n_util::GetStringUTF16(
325 return false; 325 IDS_EXTENSION_INSTALL_INCORRECT_INSTALL_HOST));
326 } 326 }
327 } 327 }
328 } 328 }
329 } 329 }
330 330
331 return true; 331 return CrxInstallerError();
332 } 332 }
333 333
334 void CrxInstaller::OnUnpackFailure(const string16& error_message) { 334 void CrxInstaller::OnUnpackFailure(const string16& error_message) {
335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
336 336
337 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackFailureInstallSource", 337 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackFailureInstallSource",
338 install_source(), Extension::NUM_LOCATIONS); 338 install_source(), Extension::NUM_LOCATIONS);
339 339
340 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackFailureInstallCause", 340 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackFailureInstallCause",
341 install_cause(), 341 install_cause(),
342 extension_misc::NUM_INSTALL_CAUSES); 342 extension_misc::NUM_INSTALL_CAUSES);
343 343
344 ReportFailureFromFileThread(error_message); 344 ReportFailureFromFileThread(CrxInstallerError(error_message));
345 } 345 }
346 346
347 void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir, 347 void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir,
348 const FilePath& extension_dir, 348 const FilePath& extension_dir,
349 const DictionaryValue* original_manifest, 349 const DictionaryValue* original_manifest,
350 const Extension* extension) { 350 const Extension* extension) {
351 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 351 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
352 352
353 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallSource", 353 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallSource",
354 install_source(), Extension::NUM_LOCATIONS); 354 install_source(), Extension::NUM_LOCATIONS);
355 355
356 356
357 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallCause", 357 UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallCause",
358 install_cause(), 358 install_cause(),
359 extension_misc::NUM_INSTALL_CAUSES); 359 extension_misc::NUM_INSTALL_CAUSES);
360 360
361 // Note: We take ownership of |extension| and |temp_dir|. 361 // Note: We take ownership of |extension| and |temp_dir|.
362 extension_ = extension; 362 extension_ = extension;
363 temp_dir_ = temp_dir; 363 temp_dir_ = temp_dir;
364 364
365 if (original_manifest) 365 if (original_manifest)
366 original_manifest_.reset(original_manifest->DeepCopy()); 366 original_manifest_.reset(original_manifest->DeepCopy());
367 367
368 // We don't have to delete the unpack dir explicity since it is a child of 368 // We don't have to delete the unpack dir explicity since it is a child of
369 // the temp dir. 369 // the temp dir.
370 unpacked_extension_root_ = extension_dir; 370 unpacked_extension_root_ = extension_dir;
371 371
372 string16 error; 372 CrxInstallerError error = AllowInstall(extension);
373 if (!AllowInstall(extension, &error)) { 373 if (error.type() != CrxInstallerError::ERROR_NONE) {
374 ReportFailureFromFileThread(error); 374 ReportFailureFromFileThread(error);
375 return; 375 return;
376 } 376 }
377 377
378 if (client_) { 378 if (client_) {
379 Extension::DecodeIcon(extension_.get(), 379 Extension::DecodeIcon(extension_.get(),
380 ExtensionIconSet::EXTENSION_ICON_LARGE, 380 ExtensionIconSet::EXTENSION_ICON_LARGE,
381 ExtensionIconSet::MATCH_BIGGER, 381 ExtensionIconSet::MATCH_BIGGER,
382 &install_icon_); 382 &install_icon_);
383 } 383 }
384 384
385 if (!BrowserThread::PostTask( 385 if (!BrowserThread::PostTask(
386 BrowserThread::UI, FROM_HERE, 386 BrowserThread::UI, FROM_HERE,
387 base::Bind(&CrxInstaller::ConfirmInstall, this))) 387 base::Bind(&CrxInstaller::ConfirmInstall, this)))
388 NOTREACHED(); 388 NOTREACHED();
389 } 389 }
390 390
391 void CrxInstaller::ConfirmInstall() { 391 void CrxInstaller::ConfirmInstall() {
392 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 392 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
393 if (!frontend_weak_.get()) 393 if (!frontend_weak_.get())
394 return; 394 return;
395 395
396 if (frontend_weak_->extension_prefs() 396 if (frontend_weak_->extension_prefs()
397 ->IsExtensionBlacklisted(extension_->id())) { 397 ->IsExtensionBlacklisted(extension_->id())) {
398 VLOG(1) << "This extension: " << extension_->id() 398 VLOG(1) << "This extension: " << extension_->id()
399 << " is blacklisted. Install failed."; 399 << " is blacklisted. Install failed.";
400 ReportFailureFromUIThread( 400 ReportFailureFromUIThread(
401 l10n_util::GetStringUTF16(IDS_EXTENSION_CANT_INSTALL_BLACKLISTED)); 401 CrxInstallerError(
402 l10n_util::GetStringUTF16(IDS_EXTENSION_CANT_INSTALL_BLACKLISTED)));
402 return; 403 return;
403 } 404 }
404 405
405 string16 error; 406 string16 error;
406 if (!ExtensionSystem::Get(profile_)->management_policy()->UserMayLoad( 407 if (!ExtensionSystem::Get(profile_)->management_policy()->UserMayLoad(
407 extension_, &error)) { 408 extension_, &error)) {
408 ReportFailureFromUIThread(error); 409 ReportFailureFromUIThread(CrxInstallerError(error));
409 return; 410 return;
410 } 411 }
411 412
412 GURL overlapping_url; 413 GURL overlapping_url;
413 const Extension* overlapping_extension = 414 const Extension* overlapping_extension =
414 frontend_weak_->extensions()-> 415 frontend_weak_->extensions()->
415 GetHostedAppByOverlappingWebExtent(extension_->web_extent()); 416 GetHostedAppByOverlappingWebExtent(extension_->web_extent());
416 if (overlapping_extension && 417 if (overlapping_extension &&
417 overlapping_extension->id() != extension_->id()) { 418 overlapping_extension->id() != extension_->id()) {
418 ReportFailureFromUIThread(l10n_util::GetStringFUTF16( 419 ReportFailureFromUIThread(
419 IDS_EXTENSION_OVERLAPPING_WEB_EXTENT, 420 CrxInstallerError(
420 UTF8ToUTF16(overlapping_extension->name()))); 421 l10n_util::GetStringFUTF16(
422 IDS_EXTENSION_OVERLAPPING_WEB_EXTENT,
423 UTF8ToUTF16(overlapping_extension->name()))));
421 return; 424 return;
422 } 425 }
423 426
424 current_version_ = 427 current_version_ =
425 frontend_weak_->extension_prefs()->GetVersionString(extension_->id()); 428 frontend_weak_->extension_prefs()->GetVersionString(extension_->id());
426 429
427 if (client_ && (!allow_silent_install_ || !approved_)) { 430 if (client_ && (!allow_silent_install_ || !approved_)) {
428 AddRef(); // Balanced in Proceed() and Abort(). 431 AddRef(); // Balanced in Proceed() and Abort().
429 client_->ConfirmInstall(this, extension_.get()); 432 client_->ConfirmInstall(this, extension_.get());
430 } else { 433 } else {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 } 470 }
468 471
469 void CrxInstaller::CompleteInstall() { 472 void CrxInstaller::CompleteInstall() {
470 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
471 474
472 if (!current_version_.empty()) { 475 if (!current_version_.empty()) {
473 scoped_ptr<Version> current_version( 476 scoped_ptr<Version> current_version(
474 Version::GetVersionFromString(current_version_)); 477 Version::GetVersionFromString(current_version_));
475 if (current_version->CompareTo(*(extension_->version())) > 0) { 478 if (current_version->CompareTo(*(extension_->version())) > 0) {
476 ReportFailureFromFileThread( 479 ReportFailureFromFileThread(
477 l10n_util::GetStringUTF16(IDS_EXTENSION_CANT_DOWNGRADE_VERSION)); 480 CrxInstallerError(
481 l10n_util::GetStringUTF16(IDS_EXTENSION_CANT_DOWNGRADE_VERSION)));
478 return; 482 return;
479 } 483 }
480 } 484 }
481 485
482 // See how long extension install paths are. This is important on 486 // See how long extension install paths are. This is important on
483 // windows, because file operations may fail if the path to a file 487 // windows, because file operations may fail if the path to a file
484 // exceeds a small constant. See crbug.com/69693 . 488 // exceeds a small constant. See crbug.com/69693 .
485 UMA_HISTOGRAM_CUSTOM_COUNTS( 489 UMA_HISTOGRAM_CUSTOM_COUNTS(
486 "Extensions.CrxInstallDirPathLength", 490 "Extensions.CrxInstallDirPathLength",
487 install_directory_.value().length(), 0, 500, 100); 491 install_directory_.value().length(), 0, 500, 100);
488 492
489 FilePath version_dir = extension_file_util::InstallExtension( 493 FilePath version_dir = extension_file_util::InstallExtension(
490 unpacked_extension_root_, 494 unpacked_extension_root_,
491 extension_->id(), 495 extension_->id(),
492 extension_->VersionString(), 496 extension_->VersionString(),
493 install_directory_); 497 install_directory_);
494 if (version_dir.empty()) { 498 if (version_dir.empty()) {
495 ReportFailureFromFileThread( 499 ReportFailureFromFileThread(
496 l10n_util::GetStringUTF16( 500 CrxInstallerError(
497 IDS_EXTENSION_MOVE_DIRECTORY_TO_PROFILE_FAILED)); 501 l10n_util::GetStringUTF16(
502 IDS_EXTENSION_MOVE_DIRECTORY_TO_PROFILE_FAILED)));
498 return; 503 return;
499 } 504 }
500 505
501 // This is lame, but we must reload the extension because absolute paths 506 // This is lame, but we must reload the extension because absolute paths
502 // inside the content scripts are established inside InitFromValue() and we 507 // inside the content scripts are established inside InitFromValue() and we
503 // just moved the extension. 508 // just moved the extension.
504 // TODO(aa): All paths to resources inside extensions should be created 509 // TODO(aa): All paths to resources inside extensions should be created
505 // lazily and based on the Extension's root path at that moment. 510 // lazily and based on the Extension's root path at that moment.
506 // TODO(rdevlin.cronin): Continue removing std::string errors and replacing 511 // TODO(rdevlin.cronin): Continue removing std::string errors and replacing
507 // with string16 512 // with string16
508 std::string error; 513 std::string error;
509 extension_ = extension_file_util::LoadExtension( 514 extension_ = extension_file_util::LoadExtension(
510 version_dir, 515 version_dir,
511 install_source_, 516 install_source_,
512 extension_->creation_flags() | Extension::REQUIRE_KEY, 517 extension_->creation_flags() | Extension::REQUIRE_KEY,
513 &error); 518 &error);
514 CHECK(error.empty()) << error; 519 CHECK(error.empty()) << error;
515 520
516 ReportSuccessFromFileThread(); 521 ReportSuccessFromFileThread();
517 } 522 }
518 523
519 void CrxInstaller::ReportFailureFromFileThread(const string16& error) { 524 void CrxInstaller::ReportFailureFromFileThread(const CrxInstallerError& error) {
520 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 525 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
521 if (!BrowserThread::PostTask( 526 if (!BrowserThread::PostTask(
522 BrowserThread::UI, FROM_HERE, 527 BrowserThread::UI, FROM_HERE,
523 base::Bind(&CrxInstaller::ReportFailureFromUIThread, this, error))) 528 base::Bind(&CrxInstaller::ReportFailureFromUIThread, this, error))) {
524 NOTREACHED(); 529 NOTREACHED();
530 }
525 } 531 }
526 532
527 void CrxInstaller::ReportFailureFromUIThread(const string16& error) { 533 void CrxInstaller::ReportFailureFromUIThread(const CrxInstallerError& error) {
528 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 534 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
529 535
530 content::NotificationService* service = 536 content::NotificationService* service =
531 content::NotificationService::current(); 537 content::NotificationService::current();
532 service->Notify(chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR, 538 service->Notify(chrome::NOTIFICATION_EXTENSION_INSTALL_ERROR,
533 content::Source<CrxInstaller>(this), 539 content::Source<CrxInstaller>(this),
534 content::Details<const string16>(&error)); 540 content::Details<const string16>(&error.message()));
535 541
536 // This isn't really necessary, it is only used because unit tests expect to 542 // This isn't really necessary, it is only used because unit tests expect to
537 // see errors get reported via this interface. 543 // see errors get reported via this interface.
538 // 544 //
539 // TODO(aa): Need to go through unit tests and clean them up too, probably get 545 // TODO(aa): Need to go through unit tests and clean them up too, probably get
540 // rid of this line. 546 // rid of this line.
541 ExtensionErrorReporter::GetInstance()->ReportError(error, false); // quiet 547 ExtensionErrorReporter::GetInstance()->ReportError(
548 error.message(), false); // quiet
542 549
543 if (client_) 550 if (client_)
544 client_->OnInstallFailure(error); 551 client_->OnInstallFailure(error);
545 552
546 NotifyCrxInstallComplete(NULL); 553 NotifyCrxInstallComplete(NULL);
547 } 554 }
548 555
549 void CrxInstaller::ReportSuccessFromFileThread() { 556 void CrxInstaller::ReportSuccessFromFileThread() {
550 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 557 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
551 558
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 // Some users (such as the download shelf) need to know when a 612 // Some users (such as the download shelf) need to know when a
606 // CRXInstaller is done. Listening for the EXTENSION_* events 613 // CRXInstaller is done. Listening for the EXTENSION_* events
607 // is problematic because they don't know anything about the 614 // is problematic because they don't know anything about the
608 // extension before it is unpacked, so they cannot filter based 615 // extension before it is unpacked, so they cannot filter based
609 // on the extension. 616 // on the extension.
610 content::NotificationService::current()->Notify( 617 content::NotificationService::current()->Notify(
611 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 618 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
612 content::Source<CrxInstaller>(this), 619 content::Source<CrxInstaller>(this),
613 content::Details<const Extension>(extension)); 620 content::Details<const Extension>(extension));
614 } 621 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/crx_installer.h ('k') | chrome/browser/extensions/crx_installer_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698