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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
120 | 120 |
121 // Set the registration active and pass profile count parameters. | 121 // Set the registration active and pass profile count parameters. |
122 - (void)setRegistrationActive; | 122 - (void)setRegistrationActive; |
123 | 123 |
124 // Called periodically to announce activity by pinging the Keystone server. | 124 // Called periodically to announce activity by pinging the Keystone server. |
125 - (void)markActive:(NSTimer*)timer; | 125 - (void)markActive:(NSTimer*)timer; |
126 | 126 |
127 // Called when an update check or update installation is complete. Posts the | 127 // Called when an update check or update installation is complete. Posts the |
128 // kAutoupdateStatusNotification notification to the default notification | 128 // kAutoupdateStatusNotification notification to the default notification |
129 // center. | 129 // center. |
130 - (void)updateStatus:(AutoupdateStatus)status version:(NSString*)version; | 130 - (void)updateStatus:(AutoupdateStatus)status |
131 version:(NSString*)version | |
132 error:(NSString *)error; | |
Boris Vidolov
2016/03/08 22:32:51
Fix the spaces around NSString pointer type. I bel
Ryan Myers (chromium)
2016/03/22 22:39:22
Done.
| |
131 | 133 |
132 // Returns the version of the currently-installed application on disk. | 134 // Returns the version of the currently-installed application on disk. |
133 - (NSString*)currentlyInstalledVersion; | 135 - (NSString*)currentlyInstalledVersion; |
134 | 136 |
135 // These three methods are used to determine the version of the application | 137 // These three methods are used to determine the version of the application |
136 // currently installed on disk, compare that to the currently-running version, | 138 // currently installed on disk, compare that to the currently-running version, |
137 // decide whether any updates have been installed, and call | 139 // decide whether any updates have been installed, and call |
138 // -updateStatus:version:. | 140 // -updateStatus:version:error:. |
139 // | 141 // |
140 // In order to check the version on disk, the installed application's | 142 // In order to check the version on disk, the installed application's |
141 // Info.plist dictionary must be read; in order to see changes as updates are | 143 // Info.plist dictionary must be read; in order to see changes as updates are |
142 // applied, the dictionary must be read each time, bypassing any caches such | 144 // applied, the dictionary must be read each time, bypassing any caches such |
143 // as the one that NSBundle might be maintaining. Reading files can be a | 145 // as the one that NSBundle might be maintaining. Reading files can be a |
144 // blocking operation, and blocking operations are to be avoided on the main | 146 // blocking operation, and blocking operations are to be avoided on the main |
145 // thread. I'm not quite sure what jank means, but I bet that a blocked main | 147 // thread. I'm not quite sure what jank means, but I bet that a blocked main |
146 // thread would cause some of it. | 148 // thread would cause some of it. |
147 // | 149 // |
148 // -determineUpdateStatusAsync is called on the main thread to initiate the | 150 // -determineUpdateStatusAsync is called on the main thread to initiate the |
149 // operation. It performs initial set-up work that must be done on the main | 151 // operation. It performs initial set-up work that must be done on the main |
150 // thread and arranges for -determineUpdateStatus to be called on a work queue | 152 // thread and arranges for -determineUpdateStatus to be called on a work queue |
151 // thread managed by WorkerPool. | 153 // thread managed by WorkerPool. |
152 // -determineUpdateStatus then reads the Info.plist, gets the version from the | 154 // -determineUpdateStatus then reads the Info.plist, gets the version from the |
153 // CFBundleShortVersionString key, and performs | 155 // CFBundleShortVersionString key, and performs |
154 // -determineUpdateStatusForVersion: on the main thread. | 156 // -determineUpdateStatusForVersion: on the main thread. |
155 // -determineUpdateStatusForVersion: does the actual comparison of the version | 157 // -determineUpdateStatusForVersion: does the actual comparison of the version |
156 // on disk with the running version and calls -updateStatus:version: with the | 158 // on disk with the running version and calls -updateStatus:version:error: with |
157 // results of its analysis. | 159 // the results of its analysis. |
158 - (void)determineUpdateStatusAsync; | 160 - (void)determineUpdateStatusAsync; |
159 - (void)determineUpdateStatus; | 161 - (void)determineUpdateStatus; |
160 - (void)determineUpdateStatusForVersion:(NSString*)version; | 162 - (void)determineUpdateStatusForVersion:(NSString*)version; |
161 | 163 |
162 // Returns YES if registration_ is definitely on a user ticket. If definitely | 164 // Returns YES if registration_ is definitely on a user ticket. If definitely |
163 // on a system ticket, or uncertain of ticket type (due to an older version | 165 // on a system ticket, or uncertain of ticket type (due to an older version |
164 // of Keystone being used), returns NO. | 166 // of Keystone being used), returns NO. |
165 - (BOOL)isUserTicket; | 167 - (BOOL)isUserTicket; |
166 | 168 |
167 // Returns YES if Keystone is definitely installed at the system level, | 169 // Returns YES if Keystone is definitely installed at the system level, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 // tag key. If a full installer (as opposed to a binary diff/delta patch) is | 203 // tag key. If a full installer (as opposed to a binary diff/delta patch) is |
202 // required, the tag suffix will contain the string "-full". If no special | 204 // required, the tag suffix will contain the string "-full". If no special |
203 // treatment is required, the tag suffix will be an empty string. | 205 // treatment is required, the tag suffix will be an empty string. |
204 - (NSString*)tagSuffix; | 206 - (NSString*)tagSuffix; |
205 | 207 |
206 @end // @interface KeystoneGlue (Private) | 208 @end // @interface KeystoneGlue (Private) |
207 | 209 |
208 NSString* const kAutoupdateStatusNotification = @"AutoupdateStatusNotification"; | 210 NSString* const kAutoupdateStatusNotification = @"AutoupdateStatusNotification"; |
209 NSString* const kAutoupdateStatusStatus = @"status"; | 211 NSString* const kAutoupdateStatusStatus = @"status"; |
210 NSString* const kAutoupdateStatusVersion = @"version"; | 212 NSString* const kAutoupdateStatusVersion = @"version"; |
213 NSString* const kAutoupdateStatusErrorMessages = @"errormessages"; | |
211 | 214 |
212 namespace { | 215 namespace { |
213 | 216 |
214 NSString* const kChannelKey = @"KSChannelID"; | 217 NSString* const kChannelKey = @"KSChannelID"; |
215 NSString* const kBrandKey = @"KSBrandID"; | 218 NSString* const kBrandKey = @"KSBrandID"; |
216 NSString* const kVersionKey = @"KSVersion"; | 219 NSString* const kVersionKey = @"KSVersion"; |
217 | 220 |
218 } // namespace | 221 } // namespace |
219 | 222 |
220 @implementation KeystoneGlue | 223 @implementation KeystoneGlue |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
529 NSArray* profileCountsInformation = | 532 NSArray* profileCountsInformation = |
530 [NSArray arrayWithObjects:numAccountsAttr, numSignedInAccountsAttr, nil]; | 533 [NSArray arrayWithObjects:numAccountsAttr, numSignedInAccountsAttr, nil]; |
531 | 534 |
532 if (![registration_ setActiveWithReportingAttributes:profileCountsInformation | 535 if (![registration_ setActiveWithReportingAttributes:profileCountsInformation |
533 error:&reportingError]) { | 536 error:&reportingError]) { |
534 VLOG(1) << [reportingError localizedDescription]; | 537 VLOG(1) << [reportingError localizedDescription]; |
535 } | 538 } |
536 } | 539 } |
537 | 540 |
538 - (void)registerWithKeystone { | 541 - (void)registerWithKeystone { |
539 [self updateStatus:kAutoupdateRegistering version:nil]; | 542 [self updateStatus:kAutoupdateRegistering version:nil error:nil]; |
540 | 543 |
541 NSDictionary* parameters = [self keystoneParameters]; | 544 NSDictionary* parameters = [self keystoneParameters]; |
542 BOOL result = [registration_ registerWithParameters:parameters]; | 545 BOOL result = [registration_ registerWithParameters:parameters]; |
543 if (!result) { | 546 if (!result) { |
544 [self updateStatus:kAutoupdateRegisterFailed version:nil]; | 547 // TODO: If Keystone ever makes a variant of this API with a withError: |
548 // parameter, include the error message here in the call to updateStatus:. | |
549 [self updateStatus:kAutoupdateRegisterFailed version:nil error:nil]; | |
545 return; | 550 return; |
546 } | 551 } |
547 | 552 |
548 // Upon completion, ksr::KSRegistrationDidCompleteNotification will be | 553 // Upon completion, ksr::KSRegistrationDidCompleteNotification will be |
549 // posted, and -registrationComplete: will be called. | 554 // posted, and -registrationComplete: will be called. |
550 | 555 |
551 // Set up hourly activity pings. | 556 // Set up hourly activity pings. |
552 timer_ = [NSTimer scheduledTimerWithTimeInterval:60 * 60 // One hour | 557 timer_ = [NSTimer scheduledTimerWithTimeInterval:60 * 60 // One hour |
553 target:self | 558 target:self |
554 selector:@selector(markActive:) | 559 selector:@selector(markActive:) |
555 userInfo:nil | 560 userInfo:nil |
556 repeats:YES]; | 561 repeats:YES]; |
557 } | 562 } |
558 | 563 |
559 - (BOOL)isRegisteredAndActive { | 564 - (BOOL)isRegisteredAndActive { |
560 return registrationActive_; | 565 return registrationActive_; |
561 } | 566 } |
562 | 567 |
563 - (void)registrationComplete:(NSNotification*)notification { | 568 - (void)registrationComplete:(NSNotification*)notification { |
564 NSDictionary* userInfo = [notification userInfo]; | 569 NSDictionary* userInfo = [notification userInfo]; |
570 | |
571 // Error messages may be included, depending on the version of Keystone. | |
Boris Vidolov
2016/03/08 22:32:51
I don't believe that this is correct. It depends o
Ryan Myers (chromium)
2016/03/22 22:39:22
Done.
| |
572 NSString *errorMessages = | |
Boris Vidolov
2016/03/08 22:32:51
Fix the position of the '*': should be "NSString*
Ryan Myers (chromium)
2016/03/22 22:39:22
Done.
| |
573 [userInfo objectForKey:ksr::KSRegistrationUpdateCheckRawErrorMessagesKey]; | |
574 | |
565 if ([[userInfo objectForKey:ksr::KSRegistrationStatusKey] boolValue]) { | 575 if ([[userInfo objectForKey:ksr::KSRegistrationStatusKey] boolValue]) { |
566 if ([self isSystemTicketDoomed]) { | 576 if ([self isSystemTicketDoomed]) { |
Boris Vidolov
2016/03/08 22:32:51
Even in the happy case there could be warnings, re
Ryan Myers (chromium)
2016/03/22 22:39:22
Done. (Passed them on to updateStatus; version_upd
| |
567 [self updateStatus:kAutoupdateNeedsPromotion version:nil]; | 577 [self updateStatus:kAutoupdateNeedsPromotion version:nil error:nil]; |
568 } else { | 578 } else { |
569 [self updateStatus:kAutoupdateRegistered version:nil]; | 579 [self updateStatus:kAutoupdateRegistered version:nil error:nil]; |
570 } | 580 } |
571 } else { | 581 } else { |
572 // Dump registration_? | 582 // Dump registration_? |
573 [self updateStatus:kAutoupdateRegisterFailed version:nil]; | 583 [self updateStatus:kAutoupdateRegisterFailed |
584 version:nil | |
585 error:errorMessages]; | |
574 } | 586 } |
575 } | 587 } |
576 | 588 |
577 - (void)stopTimer { | 589 - (void)stopTimer { |
578 [timer_ invalidate]; | 590 [timer_ invalidate]; |
579 } | 591 } |
580 | 592 |
581 - (void)markActive:(NSTimer*)timer { | 593 - (void)markActive:(NSTimer*)timer { |
582 [self setRegistrationActive]; | 594 [self setRegistrationActive]; |
583 } | 595 } |
584 | 596 |
585 - (void)checkForUpdate { | 597 - (void)checkForUpdate { |
586 DCHECK(![self asyncOperationPending]); | 598 DCHECK(![self asyncOperationPending]); |
Boris Vidolov
2016/03/08 22:32:51
I believe that this should not be a debug check, b
Ryan Myers (chromium)
2016/03/22 22:39:22
Done.
| |
587 | 599 |
588 if (!registration_) { | 600 if (!registration_) { |
589 [self updateStatus:kAutoupdateCheckFailed version:nil]; | 601 [self updateStatus:kAutoupdateCheckFailed |
602 version:nil | |
603 error:@"keystone_glue: Keystone not available."]; | |
Boris Vidolov
2016/03/08 22:32:52
This should happen only on debug builds and Chrome
Ryan Myers (chromium)
2016/03/22 22:39:22
Done.
| |
590 return; | 604 return; |
591 } | 605 } |
592 | 606 |
593 [self updateStatus:kAutoupdateChecking version:nil]; | 607 [self updateStatus:kAutoupdateChecking version:nil error:nil]; |
594 | 608 |
595 // All checks from inside Chrome are considered user-initiated, because they | 609 // All checks from inside Chrome are considered user-initiated, because they |
596 // only happen following a user action, such as visiting the about page. | 610 // only happen following a user action, such as visiting the about page. |
597 // Non-user-initiated checks are the periodic checks automatically made by | 611 // Non-user-initiated checks are the periodic checks automatically made by |
598 // Keystone, which don't come through this code path (or even this process). | 612 // Keystone, which don't come through this code path (or even this process). |
599 [registration_ checkForUpdateWasUserInitiated:YES]; | 613 [registration_ checkForUpdateWasUserInitiated:YES]; |
600 | 614 |
601 // Upon completion, ksr::KSRegistrationCheckForUpdateNotification will be | 615 // Upon completion, ksr::KSRegistrationCheckForUpdateNotification will be |
602 // posted, and -checkForUpdateComplete: will be called. | 616 // posted, and -checkForUpdateComplete: will be called. |
603 } | 617 } |
604 | 618 |
605 - (void)checkForUpdateComplete:(NSNotification*)notification { | 619 - (void)checkForUpdateComplete:(NSNotification*)notification { |
606 NSDictionary* userInfo = [notification userInfo]; | 620 NSDictionary* userInfo = [notification userInfo]; |
607 | 621 |
622 // Error messages may be included, depending on the version of Keystone. | |
Boris Vidolov
2016/03/08 22:32:51
Ditto for the version of Keystone in the comment
Ryan Myers (chromium)
2016/03/22 22:39:22
Done.
| |
623 NSString *errorMessages = | |
624 [userInfo objectForKey:ksr::KSRegistrationUpdateCheckRawErrorMessagesKey]; | |
625 | |
608 if ([[userInfo objectForKey:ksr::KSRegistrationUpdateCheckErrorKey] | 626 if ([[userInfo objectForKey:ksr::KSRegistrationUpdateCheckErrorKey] |
609 boolValue]) { | 627 boolValue]) { |
610 [self updateStatus:kAutoupdateCheckFailed version:nil]; | 628 [self updateStatus:kAutoupdateCheckFailed version:nil error:errorMessages]; |
611 } else if ([[userInfo objectForKey:ksr::KSRegistrationStatusKey] boolValue]) { | 629 } else if ([[userInfo objectForKey:ksr::KSRegistrationStatusKey] boolValue]) { |
612 // If an update is known to be available, go straight to | 630 // If an update is known to be available, go straight to |
613 // -updateStatus:version:. It doesn't matter what's currently on disk. | 631 // -updateStatus:version:. It doesn't matter what's currently on disk. |
614 NSString* version = [userInfo objectForKey:ksr::KSRegistrationVersionKey]; | 632 NSString* version = [userInfo objectForKey:ksr::KSRegistrationVersionKey]; |
615 [self updateStatus:kAutoupdateAvailable version:version]; | 633 [self updateStatus:kAutoupdateAvailable version:version error:nil]; |
Boris Vidolov
2016/03/08 22:32:52
Again, maybe we should log the reported errors? It
Ryan Myers (chromium)
2016/03/22 22:39:22
Done.
| |
616 } else { | 634 } else { |
617 // If no updates are available, check what's on disk, because an update | 635 // If no updates are available, check what's on disk, because an update |
618 // may have already been installed. This check happens on another thread, | 636 // may have already been installed. This check happens on another thread, |
619 // and -updateStatus:version: will be called on the main thread when done. | 637 // and -updateStatus:version: will be called on the main thread when done. |
620 [self determineUpdateStatusAsync]; | 638 [self determineUpdateStatusAsync]; |
621 } | 639 } |
622 } | 640 } |
623 | 641 |
624 - (void)installUpdate { | 642 - (void)installUpdate { |
625 DCHECK(![self asyncOperationPending]); | 643 DCHECK(![self asyncOperationPending]); |
626 | 644 |
627 if (!registration_) { | 645 if (!registration_) { |
628 [self updateStatus:kAutoupdateInstallFailed version:nil]; | 646 [self updateStatus:kAutoupdateInstallFailed |
647 version:nil | |
648 error:@"keystone_glue: Keystone not available."]; | |
Boris Vidolov
2016/03/08 22:32:52
Ditto
Ryan Myers (chromium)
2016/03/22 22:39:22
Done.
| |
629 return; | 649 return; |
630 } | 650 } |
631 | 651 |
632 [self updateStatus:kAutoupdateInstalling version:nil]; | 652 [self updateStatus:kAutoupdateInstalling version:nil error:nil]; |
633 | 653 |
634 [registration_ startUpdate]; | 654 [registration_ startUpdate]; |
635 | 655 |
636 // Upon completion, ksr::KSRegistrationStartUpdateNotification will be | 656 // Upon completion, ksr::KSRegistrationStartUpdateNotification will be |
637 // posted, and -installUpdateComplete: will be called. | 657 // posted, and -installUpdateComplete: will be called. |
638 } | 658 } |
639 | 659 |
640 - (void)installUpdateComplete:(NSNotification*)notification { | 660 - (void)installUpdateComplete:(NSNotification*)notification { |
641 NSDictionary* userInfo = [notification userInfo]; | 661 NSDictionary* userInfo = [notification userInfo]; |
642 | 662 |
663 // Error messages may be included, depending on the version of Keystone. | |
Boris Vidolov
2016/03/08 22:32:51
Ditto
Ryan Myers (chromium)
2016/03/22 22:39:22
Done.
Boris Vidolov
2016/03/23 00:24:13
Still here...
Ryan Myers (chromium)
2016/03/23 00:48:23
Done.
| |
664 NSString *errorMsgs = | |
665 [userInfo objectForKey:ksr::KSRegistrationUpdateCheckRawErrorMessagesKey]; | |
666 | |
643 // http://crbug.com/160308 and b/7517358: when using system Keystone and on | 667 // http://crbug.com/160308 and b/7517358: when using system Keystone and on |
644 // a user ticket, KSUpdateCheckSuccessfulKey will be NO even when an update | 668 // a user ticket, KSUpdateCheckSuccessfulKey will be NO even when an update |
645 // was installed correctly, so don't check it. It should be redudnant when | 669 // was installed correctly, so don't check it. It should be redudnant when |
646 // KSUpdateCheckSuccessfullyInstalledKey is checked. | 670 // KSUpdateCheckSuccessfullyInstalledKey is checked. |
647 if (![[userInfo objectForKey:ksr::KSUpdateCheckSuccessfullyInstalledKey] | 671 if (![[userInfo objectForKey:ksr::KSUpdateCheckSuccessfullyInstalledKey] |
648 intValue]) { | 672 intValue]) { |
649 [self updateStatus:kAutoupdateInstallFailed version:nil]; | 673 [self updateStatus:kAutoupdateInstallFailed version:nil error:errorMsgs]; |
650 } else { | 674 } else { |
651 updateSuccessfullyInstalled_ = YES; | 675 updateSuccessfullyInstalled_ = YES; |
Boris Vidolov
2016/03/08 22:32:52
Ditto for logging
Ryan Myers (chromium)
2016/03/22 22:39:22
Done.
| |
652 | 676 |
653 // Nothing in the notification dictionary reports the version that was | 677 // Nothing in the notification dictionary reports the version that was |
654 // installed. Figure it out based on what's on disk. | 678 // installed. Figure it out based on what's on disk. |
655 [self determineUpdateStatusAsync]; | 679 [self determineUpdateStatusAsync]; |
656 } | 680 } |
657 } | 681 } |
658 | 682 |
659 - (NSString*)currentlyInstalledVersion { | 683 - (NSString*)currentlyInstalledVersion { |
660 NSString* appInfoPlistPath = [self appInfoPlistPath]; | 684 NSString* appInfoPlistPath = [self appInfoPlistPath]; |
661 NSDictionary* infoPlist = | 685 NSDictionary* infoPlist = |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
702 status = kAutoupdateCurrent; | 726 status = kAutoupdateCurrent; |
703 } else { | 727 } else { |
704 // If the version on disk doesn't match what's currently running, an | 728 // If the version on disk doesn't match what's currently running, an |
705 // update must have been applied in the background, without this app's | 729 // update must have been applied in the background, without this app's |
706 // direct participation. Leave updateSuccessfullyInstalled_ alone | 730 // direct participation. Leave updateSuccessfullyInstalled_ alone |
707 // because there's no direct knowledge of what actually happened. | 731 // because there's no direct knowledge of what actually happened. |
708 status = kAutoupdateInstalled; | 732 status = kAutoupdateInstalled; |
709 } | 733 } |
710 } | 734 } |
711 | 735 |
712 [self updateStatus:status version:version]; | 736 [self updateStatus:status version:version error:nil]; |
713 } | 737 } |
714 | 738 |
715 - (void)updateStatus:(AutoupdateStatus)status version:(NSString*)version { | 739 - (void)updateStatus:(AutoupdateStatus)status |
740 version:(NSString*)version | |
741 error:(NSString *)error { | |
716 NSNumber* statusNumber = [NSNumber numberWithInt:status]; | 742 NSNumber* statusNumber = [NSNumber numberWithInt:status]; |
717 NSMutableDictionary* dictionary = | 743 NSMutableDictionary* dictionary = |
718 [NSMutableDictionary dictionaryWithObject:statusNumber | 744 [NSMutableDictionary dictionaryWithObject:statusNumber |
719 forKey:kAutoupdateStatusStatus]; | 745 forKey:kAutoupdateStatusStatus]; |
720 if (version) { | 746 if (version) { |
721 [dictionary setObject:version forKey:kAutoupdateStatusVersion]; | 747 [dictionary setObject:version forKey:kAutoupdateStatusVersion]; |
722 } | 748 } |
749 if (error) { | |
750 [dictionary setObject:version forKey:kAutoupdateStatusErrorMessages]; | |
751 } | |
723 | 752 |
724 NSNotification* notification = | 753 NSNotification* notification = |
725 [NSNotification notificationWithName:kAutoupdateStatusNotification | 754 [NSNotification notificationWithName:kAutoupdateStatusNotification |
726 object:self | 755 object:self |
727 userInfo:dictionary]; | 756 userInfo:dictionary]; |
728 recentNotification_.reset([notification retain]); | 757 recentNotification_.reset([notification retain]); |
729 | 758 |
730 [[NSNotificationCenter defaultCenter] postNotification:notification]; | 759 [[NSNotificationCenter defaultCenter] postNotification:notification]; |
731 } | 760 } |
732 | 761 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
866 } | 895 } |
867 if (!synchronous && ![self wantsPromotion]) { | 896 if (!synchronous && ![self wantsPromotion]) { |
868 // If operating synchronously, the call came from the installer, which | 897 // If operating synchronously, the call came from the installer, which |
869 // means that a system ticket is required. Otherwise, only allow | 898 // means that a system ticket is required. Otherwise, only allow |
870 // promotion if it's wanted. | 899 // promotion if it's wanted. |
871 return; | 900 return; |
872 } | 901 } |
873 | 902 |
874 synchronousPromotion_ = synchronous; | 903 synchronousPromotion_ = synchronous; |
875 | 904 |
876 [self updateStatus:kAutoupdatePromoting version:nil]; | 905 [self updateStatus:kAutoupdatePromoting version:nil error:nil]; |
877 | 906 |
878 // TODO(mark): Remove when able! | 907 // TODO(mark): Remove when able! |
879 // | 908 // |
880 // keystone_promote_preflight will copy the current brand information out to | 909 // keystone_promote_preflight will copy the current brand information out to |
881 // the system level so all users can share the data as part of the ticket | 910 // the system level so all users can share the data as part of the ticket |
882 // promotion. | 911 // promotion. |
883 // | 912 // |
884 // It will also ensure that the Keystone system ticket store is in a usable | 913 // It will also ensure that the Keystone system ticket store is in a usable |
885 // state for all users on the system. Ideally, Keystone's installer or | 914 // state for all users on the system. Ideally, Keystone's installer or |
886 // another part of Keystone would handle this. The underlying problem is | 915 // another part of Keystone would handle this. The underlying problem is |
(...skipping 28 matching lines...) Expand all Loading... | |
915 OSStatus status = base::mac::ExecuteWithPrivilegesAndWait( | 944 OSStatus status = base::mac::ExecuteWithPrivilegesAndWait( |
916 authorization, | 945 authorization, |
917 preflightPathC, | 946 preflightPathC, |
918 kAuthorizationFlagDefaults, | 947 kAuthorizationFlagDefaults, |
919 arguments, | 948 arguments, |
920 NULL, // pipe | 949 NULL, // pipe |
921 &exit_status); | 950 &exit_status); |
922 if (status != errAuthorizationSuccess) { | 951 if (status != errAuthorizationSuccess) { |
923 OSSTATUS_LOG(ERROR, status) | 952 OSSTATUS_LOG(ERROR, status) |
924 << "AuthorizationExecuteWithPrivileges preflight"; | 953 << "AuthorizationExecuteWithPrivileges preflight"; |
925 [self updateStatus:kAutoupdatePromoteFailed version:nil]; | 954 |
955 NSString *errorMessage = | |
956 [NSString stringWithFormat:@"Pre-flight script failed to launch: %ld", | |
957 (long)status]; | |
958 [self updateStatus:kAutoupdatePromoteFailed | |
959 version:nil | |
960 error:errorMessage]; | |
926 return; | 961 return; |
927 } | 962 } |
928 if (exit_status != 0) { | 963 if (exit_status != 0) { |
929 LOG(ERROR) << "keystone_promote_preflight status " << exit_status; | 964 LOG(ERROR) << "keystone_promote_preflight status " << exit_status; |
930 [self updateStatus:kAutoupdatePromoteFailed version:nil]; | 965 |
966 NSString *errorMessage = | |
967 [NSString stringWithFormat:@"Promotion pre-flight script failed: %d", | |
968 exit_status]; | |
969 [self updateStatus:kAutoupdatePromoteFailed | |
970 version:nil | |
971 error:errorMessage]; | |
931 return; | 972 return; |
932 } | 973 } |
933 | 974 |
934 // Hang on to the AuthorizationRef so that it can be used once promotion is | 975 // Hang on to the AuthorizationRef so that it can be used once promotion is |
935 // complete. Do this before asking Keystone to promote the ticket, because | 976 // complete. Do this before asking Keystone to promote the ticket, because |
936 // -promotionComplete: may be called from inside the Keystone promotion | 977 // -promotionComplete: may be called from inside the Keystone promotion |
937 // call. | 978 // call. |
938 authorization_.swap(authorization); | 979 authorization_.swap(authorization); |
939 | 980 |
940 NSDictionary* parameters = [self keystoneParameters]; | 981 NSDictionary* parameters = [self keystoneParameters]; |
941 | 982 |
942 // If the brand file is user level, update parameters to point to the new | 983 // If the brand file is user level, update parameters to point to the new |
943 // system level file during promotion. | 984 // system level file during promotion. |
944 if (brandFileType_ == kBrandFileTypeUser) { | 985 if (brandFileType_ == kBrandFileTypeUser) { |
945 NSMutableDictionary* temp_parameters = | 986 NSMutableDictionary* temp_parameters = |
946 [[parameters mutableCopy] autorelease]; | 987 [[parameters mutableCopy] autorelease]; |
947 [temp_parameters setObject:SystemBrandFilePath() | 988 [temp_parameters setObject:SystemBrandFilePath() |
948 forKey:ksr::KSRegistrationBrandPathKey]; | 989 forKey:ksr::KSRegistrationBrandPathKey]; |
949 parameters = temp_parameters; | 990 parameters = temp_parameters; |
950 } | 991 } |
951 | 992 |
952 if (![registration_ promoteWithParameters:parameters | 993 if (![registration_ promoteWithParameters:parameters |
953 authorization:authorization_]) { | 994 authorization:authorization_]) { |
954 [self updateStatus:kAutoupdatePromoteFailed version:nil]; | 995 // TODO: If Keystone ever makes a variant of this API with a withError: |
996 // parameter, include the error message here in the call to updateStatus:. | |
997 [self updateStatus:kAutoupdatePromoteFailed version:nil error:nil]; | |
955 authorization_.reset(); | 998 authorization_.reset(); |
956 return; | 999 return; |
957 } | 1000 } |
958 | 1001 |
959 // Upon completion, ksr::KSRegistrationPromotionDidCompleteNotification will | 1002 // Upon completion, ksr::KSRegistrationPromotionDidCompleteNotification will |
960 // be posted, and -promotionComplete: will be called. | 1003 // be posted, and -promotionComplete: will be called. |
961 | 1004 |
962 // If synchronous, see to it that this happens immediately. Give it a | 1005 // If synchronous, see to it that this happens immediately. Give it a |
963 // 10-second deadline. | 1006 // 10-second deadline. |
964 if (synchronous) { | 1007 if (synchronous) { |
965 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, false); | 1008 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, false); |
966 } | 1009 } |
967 } | 1010 } |
968 | 1011 |
969 - (void)promotionComplete:(NSNotification*)notification { | 1012 - (void)promotionComplete:(NSNotification*)notification { |
970 NSDictionary* userInfo = [notification userInfo]; | 1013 NSDictionary* userInfo = [notification userInfo]; |
971 if ([[userInfo objectForKey:ksr::KSRegistrationStatusKey] boolValue]) { | 1014 if ([[userInfo objectForKey:ksr::KSRegistrationStatusKey] boolValue]) { |
972 if (synchronousPromotion_) { | 1015 if (synchronousPromotion_) { |
973 // Short-circuit: if performing a synchronous promotion, the promotion | 1016 // Short-circuit: if performing a synchronous promotion, the promotion |
974 // came from the installer, which already set the permissions properly. | 1017 // came from the installer, which already set the permissions properly. |
975 // Rather than run a duplicate permission-changing operation, jump | 1018 // Rather than run a duplicate permission-changing operation, jump |
976 // straight to "done." | 1019 // straight to "done." |
977 [self changePermissionsForPromotionComplete]; | 1020 [self changePermissionsForPromotionComplete]; |
978 } else { | 1021 } else { |
979 [self changePermissionsForPromotionAsync]; | 1022 [self changePermissionsForPromotionAsync]; |
980 } | 1023 } |
981 } else { | 1024 } else { |
982 authorization_.reset(); | 1025 authorization_.reset(); |
983 [self updateStatus:kAutoupdatePromoteFailed version:nil]; | 1026 [self updateStatus:kAutoupdatePromoteFailed version:nil error:nil]; |
984 } | 1027 } |
985 | 1028 |
986 if (synchronousPromotion_) { | 1029 if (synchronousPromotion_) { |
987 // The run loop doesn't need to wait for this any longer. | 1030 // The run loop doesn't need to wait for this any longer. |
988 CFRunLoopRef runLoop = CFRunLoopGetCurrent(); | 1031 CFRunLoopRef runLoop = CFRunLoopGetCurrent(); |
989 CFRunLoopStop(runLoop); | 1032 CFRunLoopStop(runLoop); |
990 CFRunLoopWakeUp(runLoop); | 1033 CFRunLoopWakeUp(runLoop); |
991 } | 1034 } |
992 } | 1035 } |
993 | 1036 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1029 | 1072 |
1030 SEL selector = @selector(changePermissionsForPromotionComplete); | 1073 SEL selector = @selector(changePermissionsForPromotionComplete); |
1031 [self performSelectorOnMainThread:selector | 1074 [self performSelectorOnMainThread:selector |
1032 withObject:nil | 1075 withObject:nil |
1033 waitUntilDone:NO]; | 1076 waitUntilDone:NO]; |
1034 } | 1077 } |
1035 | 1078 |
1036 - (void)changePermissionsForPromotionComplete { | 1079 - (void)changePermissionsForPromotionComplete { |
1037 authorization_.reset(); | 1080 authorization_.reset(); |
1038 | 1081 |
1039 [self updateStatus:kAutoupdatePromoted version:nil]; | 1082 [self updateStatus:kAutoupdatePromoted version:nil error:nil]; |
1040 } | 1083 } |
1041 | 1084 |
1042 - (void)setAppPath:(NSString*)appPath { | 1085 - (void)setAppPath:(NSString*)appPath { |
1043 if (appPath != appPath_) { | 1086 if (appPath != appPath_) { |
1044 [appPath_ release]; | 1087 [appPath_ release]; |
1045 appPath_ = [appPath copy]; | 1088 appPath_ = [appPath copy]; |
1046 } | 1089 } |
1047 } | 1090 } |
1048 | 1091 |
1049 - (BOOL)wantsFullInstaller { | 1092 - (BOOL)wantsFullInstaller { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1131 return [KeystoneGlue defaultKeystoneGlue] != nil; | 1174 return [KeystoneGlue defaultKeystoneGlue] != nil; |
1132 } | 1175 } |
1133 | 1176 |
1134 base::string16 CurrentlyInstalledVersion() { | 1177 base::string16 CurrentlyInstalledVersion() { |
1135 KeystoneGlue* keystoneGlue = [KeystoneGlue defaultKeystoneGlue]; | 1178 KeystoneGlue* keystoneGlue = [KeystoneGlue defaultKeystoneGlue]; |
1136 NSString* version = [keystoneGlue currentlyInstalledVersion]; | 1179 NSString* version = [keystoneGlue currentlyInstalledVersion]; |
1137 return base::SysNSStringToUTF16(version); | 1180 return base::SysNSStringToUTF16(version); |
1138 } | 1181 } |
1139 | 1182 |
1140 } // namespace keystone_glue | 1183 } // namespace keystone_glue |
OLD | NEW |