| OLD | NEW |
| 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 #import "chrome/browser/mac/keystone_glue.h" | 5 #import "chrome/browser/mac/keystone_glue.h" |
| 6 | 6 |
| 7 #include <sys/mount.h> | 7 #include <sys/mount.h> |
| 8 #include <sys/param.h> | 8 #include <sys/param.h> |
| 9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
| 10 | 10 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 | 118 |
| 119 // Called when Keystone registration completes. | 119 // Called when Keystone registration completes. |
| 120 - (void)registrationComplete:(NSNotification*)notification; | 120 - (void)registrationComplete:(NSNotification*)notification; |
| 121 | 121 |
| 122 // Called periodically to announce activity by pinging the Keystone server. | 122 // Called periodically to announce activity by pinging the Keystone server. |
| 123 - (void)markActive:(NSTimer*)timer; | 123 - (void)markActive:(NSTimer*)timer; |
| 124 | 124 |
| 125 // Called when an update check or update installation is complete. Posts the | 125 // Called when an update check or update installation is complete. Posts the |
| 126 // kAutoupdateStatusNotification notification to the default notification | 126 // kAutoupdateStatusNotification notification to the default notification |
| 127 // center. | 127 // center. |
| 128 - (void)updateStatus:(AutoupdateStatus)status version:(NSString*)version; | 128 - (void)updateStatus:(keystone_glue::AutoupdateStatus)status |
| 129 version:(NSString*)version; |
| 129 | 130 |
| 130 // Returns the version of the currently-installed application on disk. | 131 // Returns the version of the currently-installed application on disk. |
| 131 - (NSString*)currentlyInstalledVersion; | 132 - (NSString*)currentlyInstalledVersion; |
| 132 | 133 |
| 133 // These three methods are used to determine the version of the application | 134 // These three methods are used to determine the version of the application |
| 134 // currently installed on disk, compare that to the currently-running version, | 135 // currently installed on disk, compare that to the currently-running version, |
| 135 // decide whether any updates have been installed, and call | 136 // decide whether any updates have been installed, and call |
| 136 // -updateStatus:version:. | 137 // -updateStatus:version:. |
| 137 // | 138 // |
| 138 // In order to check the version on disk, the installed application's | 139 // In order to check the version on disk, the installed application's |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 preserveTTToken, ksr::KSRegistrationPreserveTrustedTesterTokenKey, | 486 preserveTTToken, ksr::KSRegistrationPreserveTrustedTesterTokenKey, |
| 486 tagValue, ksr::KSRegistrationTagKey, | 487 tagValue, ksr::KSRegistrationTagKey, |
| 487 appInfoPlistPath, ksr::KSRegistrationTagPathKey, | 488 appInfoPlistPath, ksr::KSRegistrationTagPathKey, |
| 488 tagKey, ksr::KSRegistrationTagKeyKey, | 489 tagKey, ksr::KSRegistrationTagKeyKey, |
| 489 brandPath, ksr::KSRegistrationBrandPathKey, | 490 brandPath, ksr::KSRegistrationBrandPathKey, |
| 490 brandKey, ksr::KSRegistrationBrandKeyKey, | 491 brandKey, ksr::KSRegistrationBrandKeyKey, |
| 491 nil]; | 492 nil]; |
| 492 } | 493 } |
| 493 | 494 |
| 494 - (void)registerWithKeystone { | 495 - (void)registerWithKeystone { |
| 495 [self updateStatus:kAutoupdateRegistering version:nil]; | 496 [self updateStatus:keystone_glue::kAutoupdateRegistering version:nil]; |
| 496 | 497 |
| 497 NSDictionary* parameters = [self keystoneParameters]; | 498 NSDictionary* parameters = [self keystoneParameters]; |
| 498 BOOL result; | 499 BOOL result; |
| 499 { | 500 { |
| 500 // TODO(shess): Allows Keystone to throw an exception when | 501 // TODO(shess): Allows Keystone to throw an exception when |
| 501 // /usr/bin/python does not exist (really!). | 502 // /usr/bin/python does not exist (really!). |
| 502 // http://crbug.com/86221 and http://crbug.com/87931 | 503 // http://crbug.com/86221 and http://crbug.com/87931 |
| 503 base::mac::ScopedNSExceptionEnabler enabler; | 504 base::mac::ScopedNSExceptionEnabler enabler; |
| 504 result = [registration_ registerWithParameters:parameters]; | 505 result = [registration_ registerWithParameters:parameters]; |
| 505 } | 506 } |
| 506 if (!result) { | 507 if (!result) { |
| 507 [self updateStatus:kAutoupdateRegisterFailed version:nil]; | 508 [self updateStatus:keystone_glue::kAutoupdateRegisterFailed version:nil]; |
| 508 return; | 509 return; |
| 509 } | 510 } |
| 510 | 511 |
| 511 // Upon completion, ksr::KSRegistrationDidCompleteNotification will be | 512 // Upon completion, ksr::KSRegistrationDidCompleteNotification will be |
| 512 // posted, and -registrationComplete: will be called. | 513 // posted, and -registrationComplete: will be called. |
| 513 | 514 |
| 514 // Mark an active RIGHT NOW; don't wait an hour for the first one. | 515 // Mark an active RIGHT NOW; don't wait an hour for the first one. |
| 515 [registration_ setActive]; | 516 [registration_ setActive]; |
| 516 | 517 |
| 517 // Set up hourly activity pings. | 518 // Set up hourly activity pings. |
| 518 timer_ = [NSTimer scheduledTimerWithTimeInterval:60 * 60 // One hour | 519 timer_ = [NSTimer scheduledTimerWithTimeInterval:60 * 60 // One hour |
| 519 target:self | 520 target:self |
| 520 selector:@selector(markActive:) | 521 selector:@selector(markActive:) |
| 521 userInfo:registration_ | 522 userInfo:registration_ |
| 522 repeats:YES]; | 523 repeats:YES]; |
| 523 } | 524 } |
| 524 | 525 |
| 525 - (void)registrationComplete:(NSNotification*)notification { | 526 - (void)registrationComplete:(NSNotification*)notification { |
| 526 NSDictionary* userInfo = [notification userInfo]; | 527 NSDictionary* userInfo = [notification userInfo]; |
| 527 if ([[userInfo objectForKey:ksr::KSRegistrationStatusKey] boolValue]) { | 528 if ([[userInfo objectForKey:ksr::KSRegistrationStatusKey] boolValue]) { |
| 528 if ([self isSystemTicketDoomed]) { | 529 if ([self isSystemTicketDoomed]) { |
| 529 [self updateStatus:kAutoupdateNeedsPromotion version:nil]; | 530 [self updateStatus:keystone_glue::kAutoupdateNeedsPromotion version:nil]; |
| 530 } else { | 531 } else { |
| 531 [self updateStatus:kAutoupdateRegistered version:nil]; | 532 [self updateStatus:keystone_glue::kAutoupdateRegistered version:nil]; |
| 532 } | 533 } |
| 533 } else { | 534 } else { |
| 534 // Dump registration_? | 535 // Dump registration_? |
| 535 [self updateStatus:kAutoupdateRegisterFailed version:nil]; | 536 [self updateStatus:keystone_glue::kAutoupdateRegisterFailed version:nil]; |
| 536 } | 537 } |
| 537 } | 538 } |
| 538 | 539 |
| 539 - (void)stopTimer { | 540 - (void)stopTimer { |
| 540 [timer_ invalidate]; | 541 [timer_ invalidate]; |
| 541 } | 542 } |
| 542 | 543 |
| 543 - (void)markActive:(NSTimer*)timer { | 544 - (void)markActive:(NSTimer*)timer { |
| 544 KSRegistration* ksr = [timer userInfo]; | 545 KSRegistration* ksr = [timer userInfo]; |
| 545 [ksr setActive]; | 546 [ksr setActive]; |
| 546 } | 547 } |
| 547 | 548 |
| 548 - (void)checkForUpdate { | 549 - (void)checkForUpdate { |
| 549 DCHECK(![self asyncOperationPending]); | 550 DCHECK(![self asyncOperationPending]); |
| 550 | 551 |
| 551 if (!registration_) { | 552 if (!registration_) { |
| 552 [self updateStatus:kAutoupdateCheckFailed version:nil]; | 553 [self updateStatus:keystone_glue::kAutoupdateCheckFailed version:nil]; |
| 553 return; | 554 return; |
| 554 } | 555 } |
| 555 | 556 |
| 556 [self updateStatus:kAutoupdateChecking version:nil]; | 557 [self updateStatus:keystone_glue::kAutoupdateChecking version:nil]; |
| 557 | 558 |
| 558 [registration_ checkForUpdate]; | 559 [registration_ checkForUpdate]; |
| 559 | 560 |
| 560 // Upon completion, ksr::KSRegistrationCheckForUpdateNotification will be | 561 // Upon completion, ksr::KSRegistrationCheckForUpdateNotification will be |
| 561 // posted, and -checkForUpdateComplete: will be called. | 562 // posted, and -checkForUpdateComplete: will be called. |
| 562 } | 563 } |
| 563 | 564 |
| 564 - (void)checkForUpdateComplete:(NSNotification*)notification { | 565 - (void)checkForUpdateComplete:(NSNotification*)notification { |
| 565 NSDictionary* userInfo = [notification userInfo]; | 566 NSDictionary* userInfo = [notification userInfo]; |
| 566 | 567 |
| 567 if ([[userInfo objectForKey:ksr::KSRegistrationUpdateCheckErrorKey] | 568 if ([[userInfo objectForKey:ksr::KSRegistrationUpdateCheckErrorKey] |
| 568 boolValue]) { | 569 boolValue]) { |
| 569 [self updateStatus:kAutoupdateCheckFailed version:nil]; | 570 [self updateStatus:keystone_glue::kAutoupdateCheckFailed version:nil]; |
| 570 } else if ([[userInfo objectForKey:ksr::KSRegistrationStatusKey] boolValue]) { | 571 } else if ([[userInfo objectForKey:ksr::KSRegistrationStatusKey] boolValue]) { |
| 571 // If an update is known to be available, go straight to | 572 // If an update is known to be available, go straight to |
| 572 // -updateStatus:version:. It doesn't matter what's currently on disk. | 573 // -updateStatus:version:. It doesn't matter what's currently on disk. |
| 573 NSString* version = [userInfo objectForKey:ksr::KSRegistrationVersionKey]; | 574 NSString* version = [userInfo objectForKey:ksr::KSRegistrationVersionKey]; |
| 574 [self updateStatus:kAutoupdateAvailable version:version]; | 575 [self updateStatus:keystone_glue::kAutoupdateAvailable version:version]; |
| 575 } else { | 576 } else { |
| 576 // If no updates are available, check what's on disk, because an update | 577 // If no updates are available, check what's on disk, because an update |
| 577 // may have already been installed. This check happens on another thread, | 578 // may have already been installed. This check happens on another thread, |
| 578 // and -updateStatus:version: will be called on the main thread when done. | 579 // and -updateStatus:version: will be called on the main thread when done. |
| 579 [self determineUpdateStatusAsync]; | 580 [self determineUpdateStatusAsync]; |
| 580 } | 581 } |
| 581 } | 582 } |
| 582 | 583 |
| 583 - (void)installUpdate { | 584 - (void)installUpdate { |
| 584 DCHECK(![self asyncOperationPending]); | 585 DCHECK(![self asyncOperationPending]); |
| 585 | 586 |
| 586 if (!registration_) { | 587 if (!registration_) { |
| 587 [self updateStatus:kAutoupdateInstallFailed version:nil]; | 588 [self updateStatus:keystone_glue::kAutoupdateInstallFailed version:nil]; |
| 588 return; | 589 return; |
| 589 } | 590 } |
| 590 | 591 |
| 591 [self updateStatus:kAutoupdateInstalling version:nil]; | 592 [self updateStatus:keystone_glue::kAutoupdateInstalling version:nil]; |
| 592 | 593 |
| 593 [registration_ startUpdate]; | 594 [registration_ startUpdate]; |
| 594 | 595 |
| 595 // Upon completion, ksr::KSRegistrationStartUpdateNotification will be | 596 // Upon completion, ksr::KSRegistrationStartUpdateNotification will be |
| 596 // posted, and -installUpdateComplete: will be called. | 597 // posted, and -installUpdateComplete: will be called. |
| 597 } | 598 } |
| 598 | 599 |
| 599 - (void)installUpdateComplete:(NSNotification*)notification { | 600 - (void)installUpdateComplete:(NSNotification*)notification { |
| 600 NSDictionary* userInfo = [notification userInfo]; | 601 NSDictionary* userInfo = [notification userInfo]; |
| 601 | 602 |
| 602 // http://crbug.com/160308 and b/7517358: when using system Keystone and on | 603 // http://crbug.com/160308 and b/7517358: when using system Keystone and on |
| 603 // a user ticket, KSUpdateCheckSuccessfulKey will be NO even when an update | 604 // a user ticket, KSUpdateCheckSuccessfulKey will be NO even when an update |
| 604 // was installed correctly, so don't check it. It should be redudnant when | 605 // was installed correctly, so don't check it. It should be redudnant when |
| 605 // KSUpdateCheckSuccessfullyInstalledKey is checked. | 606 // KSUpdateCheckSuccessfullyInstalledKey is checked. |
| 606 if (![[userInfo objectForKey:ksr::KSUpdateCheckSuccessfullyInstalledKey] | 607 if (![[userInfo objectForKey:ksr::KSUpdateCheckSuccessfullyInstalledKey] |
| 607 intValue]) { | 608 intValue]) { |
| 608 [self updateStatus:kAutoupdateInstallFailed version:nil]; | 609 [self updateStatus:keystone_glue::kAutoupdateInstallFailed version:nil]; |
| 609 } else { | 610 } else { |
| 610 updateSuccessfullyInstalled_ = YES; | 611 updateSuccessfullyInstalled_ = YES; |
| 611 | 612 |
| 612 // Nothing in the notification dictionary reports the version that was | 613 // Nothing in the notification dictionary reports the version that was |
| 613 // installed. Figure it out based on what's on disk. | 614 // installed. Figure it out based on what's on disk. |
| 614 [self determineUpdateStatusAsync]; | 615 [self determineUpdateStatusAsync]; |
| 615 } | 616 } |
| 616 } | 617 } |
| 617 | 618 |
| 618 - (NSString*)currentlyInstalledVersion { | 619 - (NSString*)currentlyInstalledVersion { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 637 | 638 |
| 638 [self performSelectorOnMainThread:@selector(determineUpdateStatusForVersion:) | 639 [self performSelectorOnMainThread:@selector(determineUpdateStatusForVersion:) |
| 639 withObject:version | 640 withObject:version |
| 640 waitUntilDone:NO]; | 641 waitUntilDone:NO]; |
| 641 } | 642 } |
| 642 | 643 |
| 643 // Runs on the main thread. | 644 // Runs on the main thread. |
| 644 - (void)determineUpdateStatusForVersion:(NSString*)version { | 645 - (void)determineUpdateStatusForVersion:(NSString*)version { |
| 645 DCHECK([NSThread isMainThread]); | 646 DCHECK([NSThread isMainThread]); |
| 646 | 647 |
| 647 AutoupdateStatus status; | 648 keystone_glue::AutoupdateStatus status; |
| 648 if (updateSuccessfullyInstalled_) { | 649 if (updateSuccessfullyInstalled_) { |
| 649 // If an update was successfully installed and this object saw it happen, | 650 // If an update was successfully installed and this object saw it happen, |
| 650 // then don't even bother comparing versions. | 651 // then don't even bother comparing versions. |
| 651 status = kAutoupdateInstalled; | 652 status = keystone_glue::kAutoupdateInstalled; |
| 652 } else { | 653 } else { |
| 653 NSString* currentVersion = | 654 NSString* currentVersion = |
| 654 [NSString stringWithUTF8String:chrome::kChromeVersion]; | 655 [NSString stringWithUTF8String:chrome::kChromeVersion]; |
| 655 if (!version) { | 656 if (!version) { |
| 656 // If the version on disk could not be determined, assume that | 657 // If the version on disk could not be determined, assume that |
| 657 // whatever's running is current. | 658 // whatever's running is current. |
| 658 version = currentVersion; | 659 version = currentVersion; |
| 659 status = kAutoupdateCurrent; | 660 status = keystone_glue::kAutoupdateCurrent; |
| 660 } else if ([version isEqualToString:currentVersion]) { | 661 } else if ([version isEqualToString:currentVersion]) { |
| 661 status = kAutoupdateCurrent; | 662 status = keystone_glue::kAutoupdateCurrent; |
| 662 } else { | 663 } else { |
| 663 // If the version on disk doesn't match what's currently running, an | 664 // If the version on disk doesn't match what's currently running, an |
| 664 // update must have been applied in the background, without this app's | 665 // update must have been applied in the background, without this app's |
| 665 // direct participation. Leave updateSuccessfullyInstalled_ alone | 666 // direct participation. Leave updateSuccessfullyInstalled_ alone |
| 666 // because there's no direct knowledge of what actually happened. | 667 // because there's no direct knowledge of what actually happened. |
| 667 status = kAutoupdateInstalled; | 668 status = keystone_glue::kAutoupdateInstalled; |
| 668 } | 669 } |
| 669 } | 670 } |
| 670 | 671 |
| 671 [self updateStatus:status version:version]; | 672 [self updateStatus:status version:version]; |
| 672 } | 673 } |
| 673 | 674 |
| 674 - (void)updateStatus:(AutoupdateStatus)status version:(NSString*)version { | 675 - (void)updateStatus:(keystone_glue::AutoupdateStatus)status |
| 676 version:(NSString*)version { |
| 677 DCHECK([NSThread isMainThread]); |
| 675 NSNumber* statusNumber = [NSNumber numberWithInt:status]; | 678 NSNumber* statusNumber = [NSNumber numberWithInt:status]; |
| 676 NSMutableDictionary* dictionary = | 679 NSMutableDictionary* dictionary = |
| 677 [NSMutableDictionary dictionaryWithObject:statusNumber | 680 [NSMutableDictionary dictionaryWithObject:statusNumber |
| 678 forKey:kAutoupdateStatusStatus]; | 681 forKey:kAutoupdateStatusStatus]; |
| 679 if (version) { | 682 if (version) { |
| 680 [dictionary setObject:version forKey:kAutoupdateStatusVersion]; | 683 [dictionary setObject:version forKey:kAutoupdateStatusVersion]; |
| 681 } | 684 } |
| 682 | 685 |
| 683 NSNotification* notification = | 686 NSNotification* notification = |
| 684 [NSNotification notificationWithName:kAutoupdateStatusNotification | 687 [NSNotification notificationWithName:kAutoupdateStatusNotification |
| 685 object:self | 688 object:self |
| 686 userInfo:dictionary]; | 689 userInfo:dictionary]; |
| 687 recentNotification_.reset([notification retain]); | 690 recentNotification_.reset([notification retain]); |
| 688 | 691 |
| 689 [[NSNotificationCenter defaultCenter] postNotification:notification]; | 692 [[NSNotificationCenter defaultCenter] postNotification:notification]; |
| 690 } | 693 } |
| 691 | 694 |
| 692 - (NSNotification*)recentNotification { | 695 - (NSNotification*)recentNotification { |
| 693 return [[recentNotification_ retain] autorelease]; | 696 return [[recentNotification_ retain] autorelease]; |
| 694 } | 697 } |
| 695 | 698 |
| 696 - (AutoupdateStatus)recentStatus { | 699 - (keystone_glue::AutoupdateStatus)recentStatus { |
| 697 NSDictionary* dictionary = [recentNotification_ userInfo]; | 700 NSDictionary* dictionary = [recentNotification_ userInfo]; |
| 698 return static_cast<AutoupdateStatus>( | 701 return static_cast<keystone_glue::AutoupdateStatus>( |
| 699 [[dictionary objectForKey:kAutoupdateStatusStatus] intValue]); | 702 [[dictionary objectForKey:kAutoupdateStatusStatus] intValue]); |
| 700 } | 703 } |
| 701 | 704 |
| 702 - (BOOL)asyncOperationPending { | 705 - (BOOL)asyncOperationPending { |
| 703 AutoupdateStatus status = [self recentStatus]; | 706 keystone_glue::AutoupdateStatus status = [self recentStatus]; |
| 704 return status == kAutoupdateRegistering || | 707 return status == keystone_glue::kAutoupdateRegistering || |
| 705 status == kAutoupdateChecking || | 708 status == keystone_glue::kAutoupdateChecking || |
| 706 status == kAutoupdateInstalling || | 709 status == keystone_glue::kAutoupdateInstalling || |
| 707 status == kAutoupdatePromoting; | 710 status == keystone_glue::kAutoupdatePromoting; |
| 708 } | 711 } |
| 709 | 712 |
| 710 - (BOOL)isUserTicket { | 713 - (BOOL)isUserTicket { |
| 711 return [registration_ ticketType] == ksr::kKSRegistrationUserTicket; | 714 return [registration_ ticketType] == ksr::kKSRegistrationUserTicket; |
| 712 } | 715 } |
| 713 | 716 |
| 714 - (BOOL)isSystemKeystone { | 717 - (BOOL)isSystemKeystone { |
| 715 struct stat statbuf; | 718 struct stat statbuf; |
| 716 if (stat("/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/" | 719 if (stat("/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/" |
| 717 "Contents/MacOS/ksadmin", | 720 "Contents/MacOS/ksadmin", |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 } | 828 } |
| 826 if (!synchronous && ![self wantsPromotion]) { | 829 if (!synchronous && ![self wantsPromotion]) { |
| 827 // If operating synchronously, the call came from the installer, which | 830 // If operating synchronously, the call came from the installer, which |
| 828 // means that a system ticket is required. Otherwise, only allow | 831 // means that a system ticket is required. Otherwise, only allow |
| 829 // promotion if it's wanted. | 832 // promotion if it's wanted. |
| 830 return; | 833 return; |
| 831 } | 834 } |
| 832 | 835 |
| 833 synchronousPromotion_ = synchronous; | 836 synchronousPromotion_ = synchronous; |
| 834 | 837 |
| 835 [self updateStatus:kAutoupdatePromoting version:nil]; | 838 [self updateStatus:keystone_glue::kAutoupdatePromoting version:nil]; |
| 836 | 839 |
| 837 // TODO(mark): Remove when able! | 840 // TODO(mark): Remove when able! |
| 838 // | 841 // |
| 839 // keystone_promote_preflight will copy the current brand information out to | 842 // keystone_promote_preflight will copy the current brand information out to |
| 840 // the system level so all users can share the data as part of the ticket | 843 // the system level so all users can share the data as part of the ticket |
| 841 // promotion. | 844 // promotion. |
| 842 // | 845 // |
| 843 // It will also ensure that the Keystone system ticket store is in a usable | 846 // It will also ensure that the Keystone system ticket store is in a usable |
| 844 // state for all users on the system. Ideally, Keystone's installer or | 847 // state for all users on the system. Ideally, Keystone's installer or |
| 845 // another part of Keystone would handle this. The underlying problem is | 848 // another part of Keystone would handle this. The underlying problem is |
| (...skipping 28 matching lines...) Expand all Loading... |
| 874 OSStatus status = base::mac::ExecuteWithPrivilegesAndWait( | 877 OSStatus status = base::mac::ExecuteWithPrivilegesAndWait( |
| 875 authorization, | 878 authorization, |
| 876 preflightPathC, | 879 preflightPathC, |
| 877 kAuthorizationFlagDefaults, | 880 kAuthorizationFlagDefaults, |
| 878 arguments, | 881 arguments, |
| 879 NULL, // pipe | 882 NULL, // pipe |
| 880 &exit_status); | 883 &exit_status); |
| 881 if (status != errAuthorizationSuccess) { | 884 if (status != errAuthorizationSuccess) { |
| 882 OSSTATUS_LOG(ERROR, status) | 885 OSSTATUS_LOG(ERROR, status) |
| 883 << "AuthorizationExecuteWithPrivileges preflight"; | 886 << "AuthorizationExecuteWithPrivileges preflight"; |
| 884 [self updateStatus:kAutoupdatePromoteFailed version:nil]; | 887 [self updateStatus:keystone_glue::kAutoupdatePromoteFailed version:nil]; |
| 885 return; | 888 return; |
| 886 } | 889 } |
| 887 if (exit_status != 0) { | 890 if (exit_status != 0) { |
| 888 LOG(ERROR) << "keystone_promote_preflight status " << exit_status; | 891 LOG(ERROR) << "keystone_promote_preflight status " << exit_status; |
| 889 [self updateStatus:kAutoupdatePromoteFailed version:nil]; | 892 [self updateStatus:keystone_glue::kAutoupdatePromoteFailed version:nil]; |
| 890 return; | 893 return; |
| 891 } | 894 } |
| 892 | 895 |
| 893 // Hang on to the AuthorizationRef so that it can be used once promotion is | 896 // Hang on to the AuthorizationRef so that it can be used once promotion is |
| 894 // complete. Do this before asking Keystone to promote the ticket, because | 897 // complete. Do this before asking Keystone to promote the ticket, because |
| 895 // -promotionComplete: may be called from inside the Keystone promotion | 898 // -promotionComplete: may be called from inside the Keystone promotion |
| 896 // call. | 899 // call. |
| 897 authorization_.swap(authorization); | 900 authorization_.swap(authorization); |
| 898 | 901 |
| 899 NSDictionary* parameters = [self keystoneParameters]; | 902 NSDictionary* parameters = [self keystoneParameters]; |
| 900 | 903 |
| 901 // If the brand file is user level, update parameters to point to the new | 904 // If the brand file is user level, update parameters to point to the new |
| 902 // system level file during promotion. | 905 // system level file during promotion. |
| 903 if (brandFileType_ == kBrandFileTypeUser) { | 906 if (brandFileType_ == kBrandFileTypeUser) { |
| 904 NSMutableDictionary* temp_parameters = | 907 NSMutableDictionary* temp_parameters = |
| 905 [[parameters mutableCopy] autorelease]; | 908 [[parameters mutableCopy] autorelease]; |
| 906 [temp_parameters setObject:SystemBrandFilePath() | 909 [temp_parameters setObject:SystemBrandFilePath() |
| 907 forKey:ksr::KSRegistrationBrandPathKey]; | 910 forKey:ksr::KSRegistrationBrandPathKey]; |
| 908 parameters = temp_parameters; | 911 parameters = temp_parameters; |
| 909 } | 912 } |
| 910 | 913 |
| 911 if (![registration_ promoteWithParameters:parameters | 914 if (![registration_ promoteWithParameters:parameters |
| 912 authorization:authorization_]) { | 915 authorization:authorization_]) { |
| 913 [self updateStatus:kAutoupdatePromoteFailed version:nil]; | 916 [self updateStatus:keystone_glue::kAutoupdatePromoteFailed version:nil]; |
| 914 authorization_.reset(); | 917 authorization_.reset(); |
| 915 return; | 918 return; |
| 916 } | 919 } |
| 917 | 920 |
| 918 // Upon completion, ksr::KSRegistrationPromotionDidCompleteNotification will | 921 // Upon completion, ksr::KSRegistrationPromotionDidCompleteNotification will |
| 919 // be posted, and -promotionComplete: will be called. | 922 // be posted, and -promotionComplete: will be called. |
| 920 | 923 |
| 921 // If synchronous, see to it that this happens immediately. Give it a | 924 // If synchronous, see to it that this happens immediately. Give it a |
| 922 // 10-second deadline. | 925 // 10-second deadline. |
| 923 if (synchronous) { | 926 if (synchronous) { |
| 924 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, false); | 927 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, false); |
| 925 } | 928 } |
| 926 } | 929 } |
| 927 | 930 |
| 928 - (void)promotionComplete:(NSNotification*)notification { | 931 - (void)promotionComplete:(NSNotification*)notification { |
| 929 NSDictionary* userInfo = [notification userInfo]; | 932 NSDictionary* userInfo = [notification userInfo]; |
| 930 if ([[userInfo objectForKey:ksr::KSRegistrationStatusKey] boolValue]) { | 933 if ([[userInfo objectForKey:ksr::KSRegistrationStatusKey] boolValue]) { |
| 931 if (synchronousPromotion_) { | 934 if (synchronousPromotion_) { |
| 932 // Short-circuit: if performing a synchronous promotion, the promotion | 935 // Short-circuit: if performing a synchronous promotion, the promotion |
| 933 // came from the installer, which already set the permissions properly. | 936 // came from the installer, which already set the permissions properly. |
| 934 // Rather than run a duplicate permission-changing operation, jump | 937 // Rather than run a duplicate permission-changing operation, jump |
| 935 // straight to "done." | 938 // straight to "done." |
| 936 [self changePermissionsForPromotionComplete]; | 939 [self changePermissionsForPromotionComplete]; |
| 937 } else { | 940 } else { |
| 938 [self changePermissionsForPromotionAsync]; | 941 [self changePermissionsForPromotionAsync]; |
| 939 } | 942 } |
| 940 } else { | 943 } else { |
| 941 authorization_.reset(); | 944 authorization_.reset(); |
| 942 [self updateStatus:kAutoupdatePromoteFailed version:nil]; | 945 [self updateStatus:keystone_glue::kAutoupdatePromoteFailed version:nil]; |
| 943 } | 946 } |
| 944 | 947 |
| 945 if (synchronousPromotion_) { | 948 if (synchronousPromotion_) { |
| 946 // The run loop doesn't need to wait for this any longer. | 949 // The run loop doesn't need to wait for this any longer. |
| 947 CFRunLoopRef runLoop = CFRunLoopGetCurrent(); | 950 CFRunLoopRef runLoop = CFRunLoopGetCurrent(); |
| 948 CFRunLoopStop(runLoop); | 951 CFRunLoopStop(runLoop); |
| 949 CFRunLoopWakeUp(runLoop); | 952 CFRunLoopWakeUp(runLoop); |
| 950 } | 953 } |
| 951 } | 954 } |
| 952 | 955 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 | 991 |
| 989 SEL selector = @selector(changePermissionsForPromotionComplete); | 992 SEL selector = @selector(changePermissionsForPromotionComplete); |
| 990 [self performSelectorOnMainThread:selector | 993 [self performSelectorOnMainThread:selector |
| 991 withObject:nil | 994 withObject:nil |
| 992 waitUntilDone:NO]; | 995 waitUntilDone:NO]; |
| 993 } | 996 } |
| 994 | 997 |
| 995 - (void)changePermissionsForPromotionComplete { | 998 - (void)changePermissionsForPromotionComplete { |
| 996 authorization_.reset(); | 999 authorization_.reset(); |
| 997 | 1000 |
| 998 [self updateStatus:kAutoupdatePromoted version:nil]; | 1001 [self updateStatus:keystone_glue::kAutoupdatePromoted version:nil]; |
| 999 } | 1002 } |
| 1000 | 1003 |
| 1001 - (void)setAppPath:(NSString*)appPath { | 1004 - (void)setAppPath:(NSString*)appPath { |
| 1002 if (appPath != appPath_) { | 1005 if (appPath != appPath_) { |
| 1003 [appPath_ release]; | 1006 [appPath_ release]; |
| 1004 appPath_ = [appPath copy]; | 1007 appPath_ = [appPath copy]; |
| 1005 } | 1008 } |
| 1006 } | 1009 } |
| 1007 | 1010 |
| 1008 - (BOOL)wantsFullInstaller { | 1011 - (BOOL)wantsFullInstaller { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 return [KeystoneGlue defaultKeystoneGlue] != nil; | 1083 return [KeystoneGlue defaultKeystoneGlue] != nil; |
| 1081 } | 1084 } |
| 1082 | 1085 |
| 1083 base::string16 CurrentlyInstalledVersion() { | 1086 base::string16 CurrentlyInstalledVersion() { |
| 1084 KeystoneGlue* keystoneGlue = [KeystoneGlue defaultKeystoneGlue]; | 1087 KeystoneGlue* keystoneGlue = [KeystoneGlue defaultKeystoneGlue]; |
| 1085 NSString* version = [keystoneGlue currentlyInstalledVersion]; | 1088 NSString* version = [keystoneGlue currentlyInstalledVersion]; |
| 1086 return base::SysNSStringToUTF16(version); | 1089 return base::SysNSStringToUTF16(version); |
| 1087 } | 1090 } |
| 1088 | 1091 |
| 1089 } // namespace keystone_glue | 1092 } // namespace keystone_glue |
| OLD | NEW |