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

Side by Side Diff: chrome/installer/setup/setup_main.cc

Issue 10665002: Implement installation of the Chrome App Host. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: A basic working app host installer/uninstaller. Created 8 years, 5 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 <windows.h> 5 #include <windows.h>
6 #include <msi.h> 6 #include <msi.h>
7 #include <shellapi.h> 7 #include <shellapi.h>
8 #include <shlobj.h> 8 #include <shlobj.h>
9 9
10 #include "base/at_exit.h" 10 #include "base/at_exit.h"
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 InstallerState* installer_state, 349 InstallerState* installer_state,
350 installer::InstallStatus* status) { 350 installer::InstallStatus* status) {
351 const Products& products = installer_state->products(); 351 const Products& products = installer_state->products();
352 DCHECK(products.size()); 352 DCHECK(products.size());
353 353
354 const bool system_level = installer_state->system_install(); 354 const bool system_level = installer_state->system_install();
355 355
356 if (installer_state->is_multi_install()) { 356 if (installer_state->is_multi_install()) {
357 const Product* chrome = 357 const Product* chrome =
358 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER); 358 installer_state->FindProduct(BrowserDistribution::CHROME_BROWSER);
359 const Product* binaries =
360 installer_state->FindProduct(BrowserDistribution::CHROME_BINARIES);
359 const Product* chrome_frame = 361 const Product* chrome_frame =
360 installer_state->FindProduct(BrowserDistribution::CHROME_FRAME); 362 installer_state->FindProduct(BrowserDistribution::CHROME_FRAME);
361 const ProductState* cf_state = 363 const ProductState* cf_state =
362 original_state.GetProductState(system_level, 364 original_state.GetProductState(system_level,
363 BrowserDistribution::CHROME_FRAME); 365 BrowserDistribution::CHROME_FRAME);
364 if (chrome != NULL) { 366 if (chrome != NULL) {
365 if (chrome_frame != NULL && 367 if (chrome_frame != NULL &&
366 chrome_frame->HasOption(installer::kOptionReadyMode)) { 368 chrome_frame->HasOption(installer::kOptionReadyMode)) {
367 // We're being asked to install Chrome with Chrome Frame in ready-mode. 369 // We're being asked to install Chrome with Chrome Frame in ready-mode.
368 // This is an optimistic operation: if a SxS install of Chrome Frame 370 // This is an optimistic operation: if a SxS install of Chrome Frame
369 // is already present, don't touch it; if a multi-install of Chrome 371 // is already present, don't touch it; if a multi-install of Chrome
370 // Frame is present, preserve its settings (ready-mode). 372 // Frame is present, preserve its settings (ready-mode).
371 if (cf_state != NULL) { 373 if (cf_state != NULL) {
372 installer_state->RemoveProduct(chrome_frame); 374 installer_state->RemoveProduct(chrome_frame);
373 chrome_frame = NULL; 375 chrome_frame = NULL;
374 if (cf_state->is_multi_install()) { 376 if (cf_state->is_multi_install()) {
375 chrome_frame = installer_state->AddProductFromState( 377 chrome_frame = installer_state->AddProductFromState(
376 BrowserDistribution::CHROME_FRAME, *cf_state); 378 BrowserDistribution::CHROME_FRAME, *cf_state);
377 VLOG(1) << "Upgrading existing multi-install Chrome Frame rather " 379 VLOG(1) << "Upgrading existing multi-install Chrome Frame rather "
378 "than installing in ready-mode."; 380 "than installing in ready-mode.";
379 } else { 381 } else {
380 VLOG(1) << "Skipping upgrade of single-install Chrome Frame rather " 382 VLOG(1) << "Skipping upgrade of single-install Chrome Frame rather "
381 "than installing in ready-mode."; 383 "than installing in ready-mode.";
382 } 384 }
383 } else { 385 } else {
384 VLOG(1) << "Performing initial install of Chrome Frame ready-mode."; 386 VLOG(1) << "Performing initial install of Chrome Frame ready-mode.";
385 } 387 }
386 } 388 }
387 } else if (chrome_frame != NULL) { 389 } else if (binaries != NULL) {
388 // We're being asked to install or update Chrome Frame alone. 390 // We're being asked to install or update the binaries without Chrome.
389 const ProductState* chrome_state = 391 const ProductState* chrome_state =
390 original_state.GetProductState(system_level, 392 original_state.GetProductState(system_level,
391 BrowserDistribution::CHROME_BROWSER); 393 BrowserDistribution::CHROME_BROWSER);
392 if (chrome_state != NULL) { 394 if (chrome_state != NULL) {
393 // Add Chrome to the set of products (making it multi-install in the 395 // Add Chrome to the set of products (making it multi-install in the
394 // process) so that it is updated, too. 396 // process) so that it is updated, too.
395 scoped_ptr<Product> multi_chrome(new Product( 397 scoped_ptr<Product> multi_chrome(new Product(
396 BrowserDistribution::GetSpecificDistribution( 398 BrowserDistribution::GetSpecificDistribution(
397 BrowserDistribution::CHROME_BROWSER))); 399 BrowserDistribution::CHROME_BROWSER)));
398 multi_chrome->SetOption(installer::kOptionMultiInstall, true); 400 multi_chrome->SetOption(installer::kOptionMultiInstall, true);
399 chrome = installer_state->AddProduct(&multi_chrome); 401 chrome = installer_state->AddProduct(&multi_chrome);
400 VLOG(1) << "Upgrading existing multi-install Chrome browser along with " 402 VLOG(1) << "Upgrading existing Chrome browser in multi-install mode.";
401 << chrome_frame->distribution()->GetAppShortCutName(); 403 } else if (chrome_frame && chrome_frame->HasOption(installer::kOptionReady Mode)) {
grt (UTC plus 2) 2012/07/12 18:37:10 80 cols
erikwright (departed) 2012/07/16 20:13:11 Done.
402 } else if (chrome_frame->HasOption(installer::kOptionReadyMode)) {
403 // Chrome Frame with ready-mode is to be installed, yet Chrome is 404 // Chrome Frame with ready-mode is to be installed, yet Chrome is
404 // neither installed nor being installed. Fail. 405 // neither installed nor being installed. Fail.
405 LOG(ERROR) << "Cannot install Chrome Frame in ready mode without " 406 LOG(ERROR) << "Cannot install Chrome Frame in ready mode without "
406 "Chrome."; 407 "Chrome.";
407 *status = installer::READY_MODE_REQUIRES_CHROME; 408 *status = installer::READY_MODE_REQUIRES_CHROME;
408 installer_state->WriteInstallerResult(*status, 409 installer_state->WriteInstallerResult(*status,
409 IDS_INSTALL_READY_MODE_REQUIRES_CHROME_BASE, NULL); 410 IDS_INSTALL_READY_MODE_REQUIRES_CHROME_BASE, NULL);
410 return false; 411 return false;
411 } 412 }
412 } 413 }
(...skipping 14 matching lines...) Expand all
427 } else if (DCHECK_IS_ON()) { 428 } else if (DCHECK_IS_ON()) {
428 // It isn't possible to stuff two products into a single-install 429 // It isn't possible to stuff two products into a single-install
429 // InstallerState. Abort the process here in debug builds just in case 430 // InstallerState. Abort the process here in debug builds just in case
430 // someone finds a way. 431 // someone finds a way.
431 DCHECK_EQ(1U, products.size()); 432 DCHECK_EQ(1U, products.size());
432 } 433 }
433 434
434 return true; 435 return true;
435 } 436 }
436 437
438 bool CheckAppHostPreconditions(const InstallationState& original_state,
grt (UTC plus 2) 2012/07/12 18:37:10 please document the failure modes and side effects
erikwright (departed) 2012/07/16 20:13:11 The logic you refer to moved to InstallerState.
439 InstallerState* installer_state) {
440 if (!installer_state->FindProduct(BrowserDistribution::CHROME_APP_HOST))
441 return true;
442
443 if (installer_state->level() == InstallerState::SYSTEM_LEVEL)
444 return false;
grt (UTC plus 2) 2012/07/12 18:37:10 VLOG(1) the reason for failure
erikwright (departed) 2012/07/16 20:13:11 Done.
445
grt (UTC plus 2) 2012/07/12 18:37:10 if (instaler_state->package_type() != InstallerSta
erikwright (departed) 2012/07/16 20:13:11 Done.
446 const ProductState* chrome_state = original_state.GetProductState(
447 true /* system level */, BrowserDistribution::CHROME_BROWSER);
tommi (sloooow) - chröme 2012/07/12 08:11:31 nit: I think we avoid /**/ comments in general. in
grt (UTC plus 2) 2012/07/12 18:37:10 InstallerState::Level could be moved up into the "
erikwright (departed) 2012/07/16 20:13:11 Done.
erikwright (departed) 2012/07/16 20:13:11 Not done for this CL.
448 if (chrome_state) {
449 // Chrome is at system-level, multi- or otherwise. We'll use it.
450 return true;
451 }
452
453 const ProductState* binaries_state = original_state.GetProductState(
454 false /* system level */, BrowserDistribution::CHROME_BINARIES);
grt (UTC plus 2) 2012/07/12 18:37:10 should the comment be "!system level"? i find it
erikwright (departed) 2012/07/16 20:13:11 This particular instance is gone.
455 if (!binaries_state) {
456 binaries_state = original_state.GetProductState(
457 true /* system level */, BrowserDistribution::CHROME_BINARIES);
458 }
459
460 if (binaries_state) {
461 // Binaries are installed somewhere. We'll use 'em.
462 return true;
463 }
464
465 if (!binaries_state && ! installer_state->is_multi_install()) {
grt (UTC plus 2) 2012/07/12 18:37:10 remove this block as discussed
erikwright (departed) 2012/07/16 20:13:11 Done.
466 // Can't install binaries because this isn't a multi install.
467 return false;
468 }
469
470 if (!installer_state->FindProduct(BrowserDistribution::CHROME_BINARIES)) {
471 // Force binaries to be installed.
472 scoped_ptr<Product> binaries_product(new Product(
473 BrowserDistribution::GetSpecificDistribution(
474 BrowserDistribution::CHROME_BINARIES)));
475 binaries_product->SetOption(installer::kOptionMultiInstall, true);
476 if (!installer_state->AddProduct(&binaries_product)) {
477 // Can't install binaries for some reason.
478 return false;
479 }
480 }
481
482 return true;
483 }
484
437 // Checks for compatibility between the current state of the system and the 485 // Checks for compatibility between the current state of the system and the
438 // desired operation. Also applies policy that mutates the desired operation; 486 // desired operation. Also applies policy that mutates the desired operation;
439 // specifically, the |installer_state| object. 487 // specifically, the |installer_state| object.
440 // Also blocks simultaneous user-level and system-level installs. In the case 488 // Also blocks simultaneous user-level and system-level installs. In the case
441 // of trying to install user-level Chrome when system-level exists, the 489 // of trying to install user-level Chrome when system-level exists, the
442 // existing system-level Chrome is launched. 490 // existing system-level Chrome is launched.
443 // When the pre-install conditions are not satisfied, the result is written to 491 // When the pre-install conditions are not satisfied, the result is written to
444 // the registry (via WriteInstallerResult), |status| is set appropriately, and 492 // the registry (via WriteInstallerResult), |status| is set appropriately, and
445 // false is returned. 493 // false is returned.
446 bool CheckPreInstallConditions(const InstallationState& original_state, 494 bool CheckPreInstallConditions(const InstallationState& original_state,
447 InstallerState* installer_state, 495 InstallerState* installer_state,
448 installer::InstallStatus* status) { 496 installer::InstallStatus* status) {
497 if (!CheckAppHostPreconditions(original_state, installer_state))
498 return false;
499
449 // See what products are already installed in multi mode. When we do multi 500 // See what products are already installed in multi mode. When we do multi
450 // installs, we must upgrade all installations since they share the binaries. 501 // installs, we must upgrade all installations since they share the binaries.
451 AddExistingMultiInstalls(original_state, installer_state); 502 AddExistingMultiInstalls(original_state, installer_state);
452 503
453 const Products& products = installer_state->products(); 504 const Products& products = installer_state->products();
454 if (products.empty()) { 505 if (products.empty()) {
455 // We haven't been given any products on which to operate. 506 // We haven't been given any products on which to operate.
456 LOG(ERROR) 507 LOG(ERROR)
457 << "Not given any products to install and no products found to update."; 508 << "Not given any products to install and no products found to update.";
458 *status = installer::CHROME_NOT_INSTALLED; 509 *status = installer::CHROME_NOT_INSTALLED;
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 if (product_state != NULL && 668 if (product_state != NULL &&
618 (product_state->version().CompareTo(*installer_version) > 0)) { 669 (product_state->version().CompareTo(*installer_version) > 0)) {
619 LOG(ERROR) << "Higher version of " 670 LOG(ERROR) << "Higher version of "
620 << product->distribution()->GetAppShortCutName() 671 << product->distribution()->GetAppShortCutName()
621 << " is already installed."; 672 << " is already installed.";
622 higher_products |= (1 << product->distribution()->GetType()); 673 higher_products |= (1 << product->distribution()->GetType());
623 } 674 }
624 } 675 }
625 676
626 if (higher_products != 0) { 677 if (higher_products != 0) {
627 COMPILE_ASSERT(BrowserDistribution::NUM_TYPES == 3, 678 COMPILE_ASSERT(BrowserDistribution::NUM_TYPES == 4,
628 add_support_for_new_products_here_); 679 add_support_for_new_products_here_);
629 const uint32 kBrowserBit = 1 << BrowserDistribution::CHROME_BROWSER; 680 const uint32 kBrowserBit = 1 << BrowserDistribution::CHROME_BROWSER;
630 const uint32 kGCFBit = 1 << BrowserDistribution::CHROME_FRAME; 681 const uint32 kGCFBit = 1 << BrowserDistribution::CHROME_FRAME;
682 const uint32 kAppHostBit = 1 << BrowserDistribution::CHROME_APP_HOST;
631 int message_id = 0; 683 int message_id = 0;
632 684
633 proceed_with_installation = false; 685 proceed_with_installation = false;
634 install_status = installer::HIGHER_VERSION_EXISTS; 686 install_status = installer::HIGHER_VERSION_EXISTS;
635 if ((higher_products & kBrowserBit) != 0) { 687 switch (higher_products) {
636 if ((higher_products & kGCFBit) != 0) 688 case kBrowserBit:
689 message_id = IDS_INSTALL_HIGHER_VERSION_BASE;
690 break;
691 case kGCFBit:
692 message_id = IDS_INSTALL_HIGHER_VERSION_CF_BASE;
693 break;
694 case kGCFBit & kBrowserBit:
grt (UTC plus 2) 2012/07/12 18:37:10 i think you mean "kGCFBit | kBrowserBit" here.
erikwright (departed) 2012/07/16 20:13:11 Done.
637 message_id = IDS_INSTALL_HIGHER_VERSION_CB_CF_BASE; 695 message_id = IDS_INSTALL_HIGHER_VERSION_CB_CF_BASE;
638 else 696 break;
639 message_id = IDS_INSTALL_HIGHER_VERSION_BASE; 697 default:
640 } else { 698 message_id = IDS_INSTALL_HIGHER_VERSION_APP_HOST_BASE;
641 DCHECK(higher_products == kGCFBit); 699 break;
642 message_id = IDS_INSTALL_HIGHER_VERSION_CF_BASE;
643 } 700 }
644 701
645 installer_state.WriteInstallerResult(install_status, message_id, NULL); 702 installer_state.WriteInstallerResult(install_status, message_id, NULL);
646 } 703 }
647 704
648 proceed_with_installation = 705 proceed_with_installation =
649 proceed_with_installation && 706 proceed_with_installation &&
650 CheckGroupPolicySettings(original_state, installer_state, 707 CheckGroupPolicySettings(original_state, installer_state,
651 *installer_version, &install_status); 708 *installer_version, &install_status);
652 709
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 933
877 installer::InstallStatus UninstallProducts( 934 installer::InstallStatus UninstallProducts(
878 const InstallationState& original_state, 935 const InstallationState& original_state,
879 const InstallerState& installer_state, 936 const InstallerState& installer_state,
880 const CommandLine& cmd_line) { 937 const CommandLine& cmd_line) {
881 const Products& products = installer_state.products(); 938 const Products& products = installer_state.products();
882 // InstallerState::Initialize always puts Chrome first, and we rely on that 939 // InstallerState::Initialize always puts Chrome first, and we rely on that
883 // here for this reason: if Chrome is in-use, the user will be prompted to 940 // here for this reason: if Chrome is in-use, the user will be prompted to
884 // confirm uninstallation. Upon cancel, we should not continue with the 941 // confirm uninstallation. Upon cancel, we should not continue with the
885 // other products. 942 // other products.
886 DCHECK(products.size() < 2 || products[0]->is_chrome()); 943 // TODO(erikwright): if product 0 is not chrome, assert chrome not in products
tommi (sloooow) - chröme 2012/07/12 08:11:31 do you intend to do that before checkin?
erikwright (departed) 2012/07/16 20:13:11 Done.
887 installer::InstallStatus install_status = installer::UNINSTALL_SUCCESSFUL; 944 installer::InstallStatus install_status = installer::UNINSTALL_SUCCESSFUL;
888 installer::InstallStatus prod_status = installer::UNKNOWN_STATUS; 945 installer::InstallStatus prod_status = installer::UNKNOWN_STATUS;
889 const bool force = cmd_line.HasSwitch(installer::switches::kForceUninstall); 946 const bool force = cmd_line.HasSwitch(installer::switches::kForceUninstall);
890 const bool remove_all = !cmd_line.HasSwitch( 947 const bool remove_all = !cmd_line.HasSwitch(
891 installer::switches::kDoNotRemoveSharedItems); 948 installer::switches::kDoNotRemoveSharedItems);
892 949
893 for (size_t i = 0; 950 for (size_t i = 0;
894 install_status != installer::UNINSTALL_CANCELLED && 951 install_status != installer::UNINSTALL_CANCELLED &&
895 i < products.size(); 952 i < products.size();
896 ++i) { 953 ++i) {
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 if (!(installer_state.is_msi() && is_uninstall)) 1445 if (!(installer_state.is_msi() && is_uninstall))
1389 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT 1446 // Note that we allow the status installer::UNINSTALL_REQUIRES_REBOOT
1390 // to pass through, since this is only returned on uninstall which is 1447 // to pass through, since this is only returned on uninstall which is
1391 // never invoked directly by Google Update. 1448 // never invoked directly by Google Update.
1392 return_code = InstallUtil::GetInstallReturnCode(install_status); 1449 return_code = InstallUtil::GetInstallReturnCode(install_status);
1393 1450
1394 VLOG(1) << "Installation complete, returning: " << return_code; 1451 VLOG(1) << "Installation complete, returning: " << return_code;
1395 1452
1396 return return_code; 1453 return return_code;
1397 } 1454 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698