Index: chrome/browser/mac/keystone_glue.mm |
diff --git a/chrome/browser/mac/keystone_glue.mm b/chrome/browser/mac/keystone_glue.mm |
index 3a4d59e46c562ba2778bdecc8d7f3588f5f30cc9..dea4bb4845266aed424137134d01ae1a717b70ea 100644 |
--- a/chrome/browser/mac/keystone_glue.mm |
+++ b/chrome/browser/mac/keystone_glue.mm |
@@ -7,6 +7,8 @@ |
#include <sys/mount.h> |
#include <sys/param.h> |
#include <sys/stat.h> |
+#include <sys/sysctl.h> |
+#include <sys/types.h> |
#include <vector> |
@@ -22,6 +24,7 @@ |
#include "base/memory/ref_counted.h" |
#include "base/strings/sys_string_conversions.h" |
#include "base/threading/worker_pool.h" |
+#include "build/build_config.h" |
#import "chrome/browser/mac/keystone_registration.h" |
#include "chrome/common/chrome_constants.h" |
#include "chrome/common/chrome_version_info.h" |
@@ -188,6 +191,22 @@ class PerformBridge : public base::RefCountedThreadSafe<PerformBridge> { |
// Returns the brand file path to use for Keystone. |
- (NSString*)brandFilePath; |
+// YES if the system's CPU is 32-bit-only, NO if it's 64-bit-capable. |
+- (BOOL)has32BitOnlyCPU; |
+ |
+// YES if no update installation has succeeded since a binary diff patch |
+// installation failed. This signals the need to attempt a full installer |
+// which does not depend on applying a patch to existing files. |
+- (BOOL)wantsFullInstaller; |
+ |
+// Returns an NSString* suitable for appending to a Chrome Keystone tag value |
+// or tag key. If the system has a 32-bit-only CPU, the tag suffix will |
+// contain the string "-32bit". If a full installer (as opposed to a binary |
+// diff/delta patch) is required, the tag suffix will contain the string |
+// "-full". If no special treatment is required, the tag suffix will be an |
+// empty string. |
+- (NSString*)tagSuffix; |
+ |
@end // @interface KeystoneGlue (Private) |
NSString* const kAutoupdateStatusNotification = @"AutoupdateStatusNotification"; |
@@ -453,6 +472,13 @@ NSString* const kVersionKey = @"KSVersion"; |
brandKey = @""; |
} |
+ // Note that channel_ is permitted to be an empty string, but it must not be |
+ // nil. |
+ DCHECK(channel_); |
+ NSString* tagSuffix = [self tagSuffix]; |
+ NSString* tagValue = [channel_ stringByAppendingString:tagSuffix]; |
+ NSString* tagKey = [kChannelKey stringByAppendingString:tagSuffix]; |
+ |
return [NSDictionary dictionaryWithObjectsAndKeys: |
version_, ksr::KSRegistrationVersionKey, |
appInfoPlistPath, ksr::KSRegistrationVersionPathKey, |
@@ -461,9 +487,9 @@ NSString* const kVersionKey = @"KSVersion"; |
appPath_, ksr::KSRegistrationExistenceCheckerStringKey, |
url_, ksr::KSRegistrationServerURLStringKey, |
preserveTTToken, ksr::KSRegistrationPreserveTrustedTesterTokenKey, |
- channel_, ksr::KSRegistrationTagKey, |
+ tagValue, ksr::KSRegistrationTagKey, |
appInfoPlistPath, ksr::KSRegistrationTagPathKey, |
- kChannelKey, ksr::KSRegistrationTagKeyKey, |
+ tagKey, ksr::KSRegistrationTagKeyKey, |
brandPath, ksr::KSRegistrationBrandPathKey, |
brandKey, ksr::KSRegistrationBrandKeyKey, |
nil]; |
@@ -983,6 +1009,59 @@ NSString* const kVersionKey = @"KSVersion"; |
} |
} |
+- (BOOL)has32BitOnlyCPU { |
+#if defined(ARCH_CPU_64_BITS) |
+ return NO; |
+#else // ARCH_CPU_64_BITS |
+ int value; |
+ size_t valueSize = sizeof(value); |
+ if (sysctlbyname("hw.cpu64bit_capable", &value, &valueSize, NULL, 0) != 0) { |
+ return YES; |
+ } |
+ return value == 0; |
+#endif // ARCH_CPU_64_BITS |
+} |
+ |
+- (BOOL)wantsFullInstaller { |
+ // It's difficult to check the tag prior to Keystone registration, and |
+ // performing registration replaces the tag. keystone_install.sh |
+ // communicates a need for a full installer with Chrome in this file, |
+ // .want_full_installer. |
+ NSString* wantFullInstallerPath = |
+ [appPath_ stringByAppendingPathComponent:@".want_full_installer"]; |
+ NSString* wantFullInstallerContents = |
+ [NSString stringWithContentsOfFile:wantFullInstallerPath |
+ encoding:NSUTF8StringEncoding |
+ error:NULL]; |
+ if (!wantFullInstallerContents) { |
+ return NO; |
+ } |
+ |
+ NSString* wantFullInstallerVersion = |
+ [wantFullInstallerContents stringByTrimmingCharactersInSet: |
+ [NSCharacterSet newlineCharacterSet]]; |
+ return [wantFullInstallerVersion isEqualToString:version_]; |
+} |
+ |
+- (NSString*)tagSuffix { |
+ // Tag suffix components are not entirely arbitrary: all possible tag keys |
+ // must be present in the application's Info.plist, there must be |
+ // server-side agreement on the processing and meaning of tag suffix |
+ // components, and other code that manipulates tag values (such as the |
+ // Keystone update installation script) must be tag suffix-aware. To reduce |
+ // the number of tag suffix combinations that need to be listed in |
+ // Info.plist, tag suffix components should only be appended to the tag |
+ // suffix in ASCII sort order. |
+ NSString* tagSuffix = @""; |
+ if ([self has32BitOnlyCPU]) { |
+ tagSuffix = [tagSuffix stringByAppendingString:@"-32bit"]; |
+ } |
+ if ([self wantsFullInstaller]) { |
+ tagSuffix = [tagSuffix stringByAppendingString:@"-full"]; |
+ } |
+ return tagSuffix; |
+} |
+ |
@end // @implementation KeystoneGlue |
namespace { |