summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-17 23:48:56 +0000
committerthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-17 23:48:56 +0000
commit0db4cb1262c482ffa303eba8f38532602b755099 (patch)
treef26182b151c2a280ba27d956533a7e36bf6600b9
parent795a597b1171b9f91d2cdc3bb1455e428592013a (diff)
downloadchromium_src-0db4cb1262c482ffa303eba8f38532602b755099.zip
chromium_src-0db4cb1262c482ffa303eba8f38532602b755099.tar.gz
chromium_src-0db4cb1262c482ffa303eba8f38532602b755099.tar.bz2
mac: Start implementing gcapi.
For now, this includes checks if chrome is installed and if the OS X version is recent enough for chrome. BUG=128462 TEST=none Review URL: https://chromiumcodereview.appspot.com/10388132 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137774 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/chrome_installer.gypi127
-rw-r--r--chrome/installer/gcapi/gcapi.h33
-rw-r--r--chrome/installer/gcapi_mac/gcapi.h38
-rw-r--r--chrome/installer/gcapi_mac/gcapi.mm124
-rw-r--r--chrome/installer/gcapi_mac/gcapi_example_client.mm13
5 files changed, 275 insertions, 60 deletions
diff --git a/chrome/chrome_installer.gypi b/chrome/chrome_installer.gypi
index b178e67..54aa94a 100644
--- a/chrome/chrome_installer.gypi
+++ b/chrome/chrome_installer.gypi
@@ -4,7 +4,7 @@
{
'variables': {
- 'lastchange_path': '<(DEPTH)/build/util/LASTCHANGE',
+ 'lastchange_path': '../build/util/LASTCHANGE',
# 'branding_dir' is set in the 'conditions' section at the bottom.
},
'conditions': [
@@ -15,11 +15,11 @@
'type': 'loadable_module',
'dependencies': [
'installer_util',
- '<(DEPTH)/base/base.gyp:base',
- '<(DEPTH)/google_update/google_update.gyp:google_update',
+ '../base/base.gyp:base',
+ '../google_update/google_update.gyp:google_update',
],
'include_dirs': [
- '<(DEPTH)',
+ '..',
],
'sources': [
'installer/gcapi/gcapi.cc',
@@ -36,11 +36,11 @@
'type': 'static_library',
'dependencies': [
'installer_util',
- '<(DEPTH)/base/base.gyp:base',
- '<(DEPTH)/google_update/google_update.gyp:google_update',
+ '../base/base.gyp:base',
+ '../google_update/google_update.gyp:google_update',
],
'include_dirs': [
- '<(DEPTH)',
+ '..',
],
'sources': [
'installer/gcapi/gcapi.cc',
@@ -59,12 +59,12 @@
'gcapi_dll',
'gcapi_lib',
'installer_util',
- '<(DEPTH)/base/base.gyp:base',
- '<(DEPTH)/base/base.gyp:test_support_base',
- '<(DEPTH)/testing/gtest.gyp:gtest',
+ '../base/base.gyp:base',
+ '../base/base.gyp:test_support_base',
+ '../testing/gtest.gyp:gtest',
],
'include_dirs': [
- '<(DEPTH)',
+ '..',
],
'sources': [
'installer/gcapi/gcapi_last_run_test.cc',
@@ -80,16 +80,16 @@
'dependencies': [
'installer_util',
'installer_util_strings',
- '<(DEPTH)/base/base.gyp:base',
- '<(DEPTH)/base/base.gyp:base_i18n',
- '<(DEPTH)/base/base.gyp:test_support_base',
- '<(DEPTH)/build/temp_gyp/googleurl.gyp:googleurl',
- '<(DEPTH)/content/content.gyp:content_common',
- '<(DEPTH)/testing/gmock.gyp:gmock',
- '<(DEPTH)/testing/gtest.gyp:gtest',
+ '../base/base.gyp:base',
+ '../base/base.gyp:base_i18n',
+ '../base/base.gyp:test_support_base',
+ '../build/temp_gyp/googleurl.gyp:googleurl',
+ '../content/content.gyp:content_common',
+ '../testing/gmock.gyp:gmock',
+ '../testing/gtest.gyp:gtest',
],
'include_dirs': [
- '<(DEPTH)',
+ '..',
],
'sources': [
'installer/setup/compat_checks_unittest.cc',
@@ -183,14 +183,14 @@
'dependencies': [
'installer_util',
'installer_util_strings',
- '<(DEPTH)/base/base.gyp:base',
- '<(DEPTH)/base/base.gyp:base_i18n',
- '<(DEPTH)/base/base.gyp:test_support_base',
- '<(DEPTH)/chrome/chrome.gyp:test_support_common',
- '<(DEPTH)/testing/gtest.gyp:gtest',
+ '../base/base.gyp:base',
+ '../base/base.gyp:base_i18n',
+ '../base/base.gyp:test_support_base',
+ '../chrome/chrome.gyp:test_support_common',
+ '../testing/gtest.gyp:gtest',
],
'include_dirs': [
- '<(DEPTH)',
+ '..',
],
'sources': [
'<(SHARED_INTERMEDIATE_DIR)/installer_util_strings/installer_util_strings.rc',
@@ -219,18 +219,18 @@
'dependencies': [
'installer_util',
'installer_util_strings',
- '<(DEPTH)/base/base.gyp:base',
- '<(DEPTH)/build/temp_gyp/googleurl.gyp:googleurl',
- '<(DEPTH)/build/util/build_util.gyp:lastchange#target',
- '<(DEPTH)/build/util/support/support.gyp:*',
- '<(DEPTH)/chrome_frame/chrome_frame.gyp:chrome_tab_idl',
- '<(DEPTH)/chrome_frame/chrome_frame.gyp:npchrome_frame',
- '<(DEPTH)/breakpad/breakpad.gyp:breakpad_handler',
- '<(DEPTH)/rlz/rlz.gyp:rlz_lib',
- '<(DEPTH)/third_party/zlib/zlib.gyp:zlib',
+ '../base/base.gyp:base',
+ '../build/temp_gyp/googleurl.gyp:googleurl',
+ '../build/util/build_util.gyp:lastchange#target',
+ '../build/util/support/support.gyp:*',
+ '../chrome_frame/chrome_frame.gyp:chrome_tab_idl',
+ '../chrome_frame/chrome_frame.gyp:npchrome_frame',
+ '../breakpad/breakpad.gyp:breakpad_handler',
+ '../rlz/rlz.gyp:rlz_lib',
+ '../third_party/zlib/zlib.gyp:zlib',
],
'include_dirs': [
- '<(DEPTH)',
+ '..',
'<(INTERMEDIATE_DIR)',
'<(SHARED_INTERMEDIATE_DIR)/setup',
],
@@ -274,7 +274,7 @@
'rule_name': 'setup_version',
'extension': 'version',
'variables': {
- 'version_py_path': '<(DEPTH)/chrome/tools/build/version.py',
+ 'version_py_path': '../chrome/tools/build/version.py',
'template_input_path': 'installer/setup/setup_exe_version.rc.version',
},
'inputs': [
@@ -355,16 +355,16 @@
'dependencies': [
'installer_util',
'installer_util_strings',
- '<(DEPTH)/base/base.gyp:base',
- '<(DEPTH)/base/base.gyp:base_i18n',
- '<(DEPTH)/base/base.gyp:test_support_base',
- '<(DEPTH)/build/temp_gyp/googleurl.gyp:googleurl',
- '<(DEPTH)/chrome_frame/chrome_frame.gyp:chrome_tab_idl',
- '<(DEPTH)/testing/gmock.gyp:gmock',
- '<(DEPTH)/testing/gtest.gyp:gtest',
+ '../base/base.gyp:base',
+ '../base/base.gyp:base_i18n',
+ '../base/base.gyp:test_support_base',
+ '../build/temp_gyp/googleurl.gyp:googleurl',
+ '../chrome_frame/chrome_frame.gyp:chrome_tab_idl',
+ '../testing/gmock.gyp:gmock',
+ '../testing/gtest.gyp:gtest',
],
'include_dirs': [
- '<(DEPTH)',
+ '..',
'<(INTERMEDIATE_DIR)',
],
# TODO(robertshield): Move the items marked with "Move to lib"
@@ -431,8 +431,8 @@
'variables': {
# Always google_chrome since this only applies to branding==Chrome.
'branding_dir': 'app/theme/google_chrome',
- 'version' : '<!(python <(version_py_path) -f <(DEPTH)/chrome/VERSION -t "@MAJOR@.@MINOR@.@BUILD@.@PATCH@")',
- 'revision' : '<!(python <(DEPTH)/build/util/lastchange.py --revision-only)',
+ 'version' : '<!(python <(version_py_path) -f ../chrome/VERSION -t "@MAJOR@.@MINOR@.@BUILD@.@PATCH@")',
+ 'revision' : '<!(python ../build/util/lastchange.py --revision-only)',
'packaging_files_common': [
'installer/linux/internal/common/apt.include',
'installer/linux/internal/common/default-app.template',
@@ -984,6 +984,41 @@
'installer/mac/keychain_reauthorize_main.cc',
],
}, # target: keychain_reauthorize
+ {
+ 'target_name': 'gcapi_lib',
+ 'type': 'static_library',
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'installer/gcapi_mac/gcapi.h',
+ 'installer/gcapi_mac/gcapi.mm',
+ ],
+ 'link_settings': {
+ 'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/Cocoa.framework',
+ ],
+ },
+ 'xcode_settings': {
+ # TODO(thakis): Enable once http://crbug.com/90185 is done.
+ # 'ARCHS': [ 'i386', 'x86_64' ],
+ 'MACOSX_DEPLOYMENT_TARGET': '10.4',
+ 'GCC_ENABLE_OBJC_GC': 'supported',
+ },
+ },
+ {
+ 'target_name': 'gcapi_example',
+ 'type': 'executable',
+ 'dependencies': [
+ 'gcapi_lib',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ 'installer/gcapi_mac/gcapi_example_client.mm',
+ ],
+ },
], # targets
}], # OS=="mac"
[ 'branding == "Chrome"', {
diff --git a/chrome/installer/gcapi/gcapi.h b/chrome/installer/gcapi/gcapi.h
index 5d950fa..bca1c66 100644
--- a/chrome/installer/gcapi/gcapi.h
+++ b/chrome/installer/gcapi/gcapi.h
@@ -8,25 +8,28 @@
#include <windows.h>
-extern "C" {
// Error conditions for GoogleChromeCompatibilityCheck().
-#define GCCC_ERROR_USERLEVELALREADYPRESENT 0x01
-#define GCCC_ERROR_SYSTEMLEVELALREADYPRESENT 0x02
-#define GCCC_ERROR_ACCESSDENIED 0x04
-#define GCCC_ERROR_OSNOTSUPPORTED 0x08
-#define GCCC_ERROR_ALREADYOFFERED 0x10
-#define GCCC_ERROR_INTEGRITYLEVEL 0x20
+#define GCCC_ERROR_USERLEVELALREADYPRESENT (1 << 0)
+#define GCCC_ERROR_SYSTEMLEVELALREADYPRESENT (1 << 1)
+#define GCCC_ERROR_ACCESSDENIED (1 << 2)
+#define GCCC_ERROR_OSNOTSUPPORTED (1 << 3)
+#define GCCC_ERROR_ALREADYOFFERED (1 << 4)
+#define GCCC_ERROR_INTEGRITYLEVEL (1 << 5)
// Error conditions for CanReactivateChrome().
-#define REACTIVATE_ERROR_NOTINSTALLED 0x01
-#define REACTIVATE_ERROR_NOTDORMANT 0x02
-#define REACTIVATE_ERROR_ALREADY_REACTIVATED 0x04
-#define REACTIVATE_ERROR_INVALID_INPUT 0x08
-#define REACTIVATE_ERROR_REACTIVATION_FAILED 0x10
+#define REACTIVATE_ERROR_NOTINSTALLED (1 << 0)
+#define REACTIVATE_ERROR_NOTDORMANT (1 << 1)
+#define REACTIVATE_ERROR_ALREADY_REACTIVATED (1 << 2)
+#define REACTIVATE_ERROR_INVALID_INPUT (1 << 3)
+#define REACTIVATE_ERROR_REACTIVATION_FAILED (1 << 4)
// Flags to indicate how GCAPI is invoked
-#define GCAPI_INVOKED_STANDARD_SHELL 0x01
-#define GCAPI_INVOKED_UAC_ELEVATION 0x02
+#define GCAPI_INVOKED_STANDARD_SHELL (1 << 0)
+#define GCAPI_INVOKED_UAC_ELEVATION (1 << 1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
// The minimum number of days an installation can be dormant before reactivation
// may be offered.
@@ -107,6 +110,8 @@ typedef BOOL (__stdcall *GCCC_ReactivateChrome)(const wchar_t*,
int,
DWORD*);
+#ifdef __cplusplus
} // extern "C"
+#endif
#endif // CHROME_INSTALLER_GCAPI_GCAPI_H_
diff --git a/chrome/installer/gcapi_mac/gcapi.h b/chrome/installer/gcapi_mac/gcapi.h
new file mode 100644
index 0000000..3a84a1f
--- /dev/null
+++ b/chrome/installer/gcapi_mac/gcapi.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_INSTALLER_GCAPI_MAC_GCAPI_H_
+#define CHROME_INSTALLER_GCAPI_MAC_GCAPI_H_
+#pragma once
+
+// Error conditions for GoogleChromeCompatibilityCheck().
+#define GCCC_ERROR_USERLEVELALREADYPRESENT (1 << 0)
+#define GCCC_ERROR_SYSTEMLEVELALREADYPRESENT (1 << 1)
+#define GCCC_ERROR_ACCESSDENIED (1 << 2)
+#define GCCC_ERROR_OSNOTSUPPORTED (1 << 3)
+#define GCCC_ERROR_ALREADYOFFERED (1 << 4)
+#define GCCC_ERROR_INTEGRITYLEVEL (1 << 5)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// This function returns YES if Google Chrome should be offered.
+// If the return is NO, |reasons| explains why. If you don't care for the
+// reason, you can pass NULL for |reasons|.
+// |set_flag| indicates whether a flag should be set indicating that Chrome was
+// offered within the last six months; if passed NO, this method will not
+// set the flag even if Chrome can be offered. If passed TRUE, this method
+// will set the flag only if Chrome can be offered.
+// |shell_mode| should be set to one of GCAPI_INVOKED_STANDARD_SHELL or
+// GCAPI_INVOKED_UAC_ELEVATION depending on whether this method is invoked
+// from an elevated or non-elevated process. TODO(thakis): This doesn't make
+// sense on mac, change comment.
+int GoogleChromeCompatibilityCheck(unsigned* reasons);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // CHROME_INSTALLER_GCAPI_MAC_GCAPI_H_
diff --git a/chrome/installer/gcapi_mac/gcapi.mm b/chrome/installer/gcapi_mac/gcapi.mm
new file mode 100644
index 0000000..2530e8d
--- /dev/null
+++ b/chrome/installer/gcapi_mac/gcapi.mm
@@ -0,0 +1,124 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/installer/gcapi_mac/gcapi.h"
+
+#import <Cocoa/Cocoa.h>
+#include <sys/utsname.h>
+
+namespace {
+
+// Condensed from chromium's base/mac/mac_util.mm.
+bool IsOSXLeopardOrLater() {
+ // On 10.6, Gestalt() was observed to be able to spawn threads (see
+ // http://crbug.com/53200). Don't call Gestalt().
+ struct utsname uname_info;
+ if (uname(&uname_info) != 0)
+ return false;
+ if (strcmp(uname_info.sysname, "Darwin") != 0)
+ return false;
+
+ char* dot = strchr(uname_info.release, '.');
+ if (!dot)
+ return false;
+
+ int darwin_major_version = atoi(uname_info.release);
+ if (darwin_major_version < 6)
+ return false;
+
+ // The Darwin major version is always 4 greater than the Mac OS X minor
+ // version for Darwin versions beginning with 6, corresponding to Mac OS X
+ // 10.2.
+ int mac_os_x_minor_version = darwin_major_version - 4;
+
+ return mac_os_x_minor_version >= 5;
+}
+
+NSString* const kSystemKsadminPath =
+ @"/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/"
+ "Contents/MacOS/ksadmin";
+
+NSString* const kUserKsadminPath =
+ @"~/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/"
+ "Contents/MacOS/ksadmin";
+
+enum TicketKind {
+ kSystemTicket, kUserTicket
+};
+
+BOOL HasChromeTicket(TicketKind kind) {
+ // Don't use Objective-C 2 loop syntax, in case an installer runs on 10.4.
+ NSMutableArray* keystonePaths =
+ [NSMutableArray arrayWithObject:kUserKsadminPath];
+ if (kind == kSystemTicket)
+ [keystonePaths insertObject:kSystemKsadminPath atIndex:0];
+ NSEnumerator* e = [keystonePaths objectEnumerator];
+ id ksPath;
+ while ((ksPath = [e nextObject])) {
+ NSTask* task = nil;
+ NSString* string = nil;
+ bool ksadminRanSuccessfully = false;
+
+ @try {
+ task = [[NSTask alloc] init];
+ [task setLaunchPath:ksPath];
+
+ NSArray* arguments = @[
+ kind == kUserTicket ? @"--user-store" : @"--system-store",
+ @"--print-tickets",
+ @"--productid",
+ @"com.google.Chrome",
+ ];
+ [task setArguments:arguments];
+
+ NSPipe* pipe = [NSPipe pipe];
+ [task setStandardOutput:pipe];
+
+ NSFileHandle* file = [pipe fileHandleForReading];
+
+ [task launch];
+
+ NSData* data = [file readDataToEndOfFile];
+ [task waitUntilExit];
+
+ ksadminRanSuccessfully = [task terminationStatus] == 0;
+ string = [[[NSString alloc] initWithData:data
+ encoding:NSUTF8StringEncoding] autorelease];
+ }
+ @catch (id exception) {
+ // Most likely, ksPath didn't exist.
+ }
+ [task release];
+
+ if (ksadminRanSuccessfully && [string length] > 0)
+ return YES;
+ }
+
+ return NO;
+}
+
+} // namespace
+
+int GoogleChromeCompatibilityCheck(unsigned* reasons) {
+ unsigned local_reasons = 0;
+
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ if (!IsOSXLeopardOrLater())
+ local_reasons |= GCCC_ERROR_OSNOTSUPPORTED;
+
+ if (HasChromeTicket(kSystemTicket))
+ local_reasons |= GCCC_ERROR_SYSTEMLEVELALREADYPRESENT;
+
+ if (HasChromeTicket(kUserTicket))
+ local_reasons |= GCCC_ERROR_USERLEVELALREADYPRESENT;
+
+ [pool drain];
+
+ // Done. Copy/return results.
+ if (reasons != NULL)
+ *reasons = local_reasons;
+
+ return local_reasons == 0;
+}
diff --git a/chrome/installer/gcapi_mac/gcapi_example_client.mm b/chrome/installer/gcapi_mac/gcapi_example_client.mm
new file mode 100644
index 0000000..902fff3
--- /dev/null
+++ b/chrome/installer/gcapi_mac/gcapi_example_client.mm
@@ -0,0 +1,13 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/installer/gcapi_mac/gcapi.h"
+
+#import <Foundation/Foundation.h>
+
+int main() {
+ unsigned reasons;
+ int b = GoogleChromeCompatibilityCheck(&reasons);
+ NSLog(@"%d: %x", b, reasons);
+}