Chromium Code Reviews| Index: testing/iossim/iossim.mm |
| diff --git a/testing/iossim/iossim.mm b/testing/iossim/iossim.mm |
| index 48482e81ef2b69b68dd7a0b5de2dde36b7d1d502..7a3ffebbdc32598ec5a520c576b8ea7045ea18c2 100644 |
| --- a/testing/iossim/iossim.mm |
| +++ b/testing/iossim/iossim.mm |
| @@ -101,19 +101,6 @@ const NSTimeInterval kDefaultSessionStartTimeoutSeconds = 30; |
| // polling interval. |
| const NSTimeInterval kOutputPollIntervalSeconds = 0.1; |
| -// The path within the developer dir of the private Simulator frameworks. |
| -// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
| -// (crbug.com/385030). |
| -#if defined(IOSSIM_USE_XCODE_6) |
| -NSString* const kSimulatorFrameworkRelativePath = |
| - @"../SharedFrameworks/DVTiPhoneSimulatorRemoteClient.framework"; |
| -NSString* const kCoreSimulatorRelativePath = |
| - @"Library/PrivateFrameworks/CoreSimulator.framework"; |
| -#else |
| -NSString* const kSimulatorFrameworkRelativePath = |
| - @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/" |
| - @"DVTiPhoneSimulatorRemoteClient.framework"; |
| -#endif // IOSSIM_USE_XCODE_6 |
| NSString* const kDVTFoundationRelativePath = |
| @"../SharedFrameworks/DVTFoundation.framework"; |
| NSString* const kDevToolsFoundationRelativePath = |
| @@ -172,36 +159,80 @@ Class FindClassByName(NSString* nameOfClass) { |
| return theClass; |
| } |
| +// Finds the Xcode version via xcodebuild -version. Output from xcodebuild is |
| +// expected to look like: |
| +// Xcode <version> |
| +// Build version 5B130a |
| +// where <version> is the string returned by this function (e.g. 6.0). |
| +NSString* FindXcodeVersion() { |
| + NSTask* xcodeSelectTask = [[[NSTask alloc] init] autorelease]; |
|
TVL
2014/08/21 19:41:50
fyi - you could probably make a common method with
|
| + [xcodeSelectTask setLaunchPath:@"/usr/bin/xcodebuild"]; |
| + [xcodeSelectTask setArguments:[NSArray arrayWithObject:@"-version"]]; |
| + |
| + NSPipe* outputPipe = [NSPipe pipe]; |
| + [xcodeSelectTask setStandardOutput:outputPipe]; |
| + NSFileHandle* outputFile = [outputPipe fileHandleForReading]; |
| + |
| + [xcodeSelectTask launch]; |
| + NSData* outputData = [outputFile readDataToEndOfFile]; |
| + [xcodeSelectTask terminate]; |
| + |
| + NSString* output = |
| + [[[NSString alloc] initWithData:outputData |
| + encoding:NSUTF8StringEncoding] autorelease]; |
|
TVL
2014/08/21 19:41:50
fyi - another options is NSScanner, can the "Xcode
lliabraa
2014/08/22 17:50:56
Done.
|
| + NSArray* tokens = [output componentsSeparatedByCharactersInSet: |
| + [NSCharacterSet whitespaceAndNewlineCharacterSet]]; |
| + if ([tokens count] != 6) { |
| + LogError(@"Unable to find Xcode version. 'xcodebuild -version' " |
| + @"returned \n%@", output); |
| + return nil; |
| + } |
| + return tokens[1]; |
| +} |
| + |
| +// Returns true if iossim is running with Xcode 6 or later installed on the |
| +// host. |
| +BOOL IsRunningWithXcode6OrLater() { |
| + static NSString* xcodeVersion = FindXcodeVersion(); |
| + if (!xcodeVersion) { |
| + return false; |
| + } |
| + NSArray* components = [xcodeVersion componentsSeparatedByString:@"."]; |
| + if ([components count] < 1) { |
| + return false; |
| + } |
| + NSInteger majorVersion = [components[0] integerValue]; |
| + return majorVersion >= 6; |
| +} |
| + |
| // Prints supported devices and SDKs. |
| void PrintSupportedDevices() { |
| -// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
| -// (crbug.com/385030). |
| -#if defined(IOSSIM_USE_XCODE_6) |
| - printf("Supported device/SDK combinations:\n"); |
| - Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); |
| - id deviceSet = |
| - [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; |
| - for (id simDevice in [deviceSet availableDevices]) { |
| - NSString* deviceInfo = |
| - [NSString stringWithFormat:@" -d '%@' -s '%@'\n", |
| - [simDevice name], [[simDevice runtime] versionString]]; |
| - printf("%s", [deviceInfo UTF8String]); |
| - } |
| -#else |
| - printf("Supported SDK versions:\n"); |
| - Class rootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot"); |
| - for (id root in [rootClass knownRoots]) { |
| - printf(" '%s'\n", [[root sdkVersion] UTF8String]); |
| + if (IsRunningWithXcode6OrLater()) { |
| + printf("Supported device/SDK combinations:\n"); |
| + Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); |
| + id deviceSet = |
| + [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; |
| + for (id simDevice in [deviceSet availableDevices]) { |
| + NSString* deviceInfo = |
| + [NSString stringWithFormat:@" -d '%@' -s '%@'\n", |
| + [simDevice name], [[simDevice runtime] versionString]]; |
| + printf("%s", [deviceInfo UTF8String]); |
| + } |
| + } else { |
| + printf("Supported SDK versions:\n"); |
|
TVL
2014/08/21 19:41:50
maybe a comment that this the the list from Xcode
lliabraa
2014/08/22 17:50:56
Makes sense for the hard-coded list of devices, bu
|
| + Class rootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot"); |
| + for (id root in [rootClass knownRoots]) { |
| + printf(" '%s'\n", [[root sdkVersion] UTF8String]); |
| + } |
| + printf("Supported devices:\n"); |
|
TVL
2014/08/21 19:41:50
maybe a comment that this the the list from Xcode
lliabraa
2014/08/22 17:50:56
Done.
|
| + printf(" 'iPhone'\n"); |
| + printf(" 'iPhone Retina (3.5-inch)'\n"); |
| + printf(" 'iPhone Retina (4-inch)'\n"); |
| + printf(" 'iPhone Retina (4-inch 64-bit)'\n"); |
| + printf(" 'iPad'\n"); |
| + printf(" 'iPad Retina'\n"); |
| + printf(" 'iPad Retina (64-bit)'\n"); |
| } |
| - printf("Supported devices:\n"); |
| - printf(" 'iPhone'\n"); |
| - printf(" 'iPhone Retina (3.5-inch)'\n"); |
| - printf(" 'iPhone Retina (4-inch)'\n"); |
| - printf(" 'iPhone Retina (4-inch 64-bit)'\n"); |
| - printf(" 'iPad'\n"); |
| - printf(" 'iPad Retina'\n"); |
| - printf(" 'iPad Retina (64-bit)'\n"); |
| -#endif // defined(IOSSIM_USE_XCODE_6) |
| } |
| } // namespace |
| @@ -260,17 +291,16 @@ void PrintSupportedDevices() { |
| NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; |
| NSFileHandle* simio = [NSFileHandle fileHandleForReadingAtPath:stdioPath_]; |
| -// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
| -// (crbug.com/385030). |
| -#if defined(IOSSIM_USE_XCODE_6) |
| - // With iOS 8 simulators on Xcode 6, the app output is relative to the |
| - // simulator's data directory. |
| - if ([session.sessionConfig.simulatedSystemRoot.sdkVersion isEqual:@"8.0"]) { |
| - NSString* dataPath = session.sessionConfig.device.dataPath; |
| - NSString* appOutput = [dataPath stringByAppendingPathComponent:stdioPath_]; |
| - simio = [NSFileHandle fileHandleForReadingAtPath:appOutput]; |
| + if (IsRunningWithXcode6OrLater()) { |
| + // With iOS 8 simulators on Xcode 6, the app output is relative to the |
| + // simulator's data directory. |
| + if ([session.sessionConfig.simulatedSystemRoot.sdkVersion isEqual:@"8.0"]) { |
| + NSString* dataPath = session.sessionConfig.device.dataPath; |
| + NSString* appOutput = |
| + [dataPath stringByAppendingPathComponent:stdioPath_]; |
| + simio = [NSFileHandle fileHandleForReadingAtPath:appOutput]; |
| + } |
| } |
| -#endif |
| NSFileHandle* standardOutput = [NSFileHandle fileHandleWithStandardOutput]; |
| // Copy data to stdout/stderr while the app is running. |
| while (appRunning_) { |
| @@ -419,19 +449,18 @@ void PrintSupportedDevices() { |
| } else { |
| // Otherwise, the iOS Simulator's system logging is sandboxed, so parse the |
| // sandboxed system.log file for known errors. |
| -// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
| -// (crbug.com/385030). |
| -#if defined(IOSSIM_USE_XCODE_6) |
| - NSString* dataPath = session.sessionConfig.device.dataPath; |
| - NSString* path = |
| - [dataPath stringByAppendingPathComponent:@"Library/Logs/system.log"]; |
| -#else |
| - NSString* relativePathToSystemLog = |
| - [NSString stringWithFormat: |
| - @"Library/Logs/iOS Simulator/%@/system.log", versionString]; |
| - NSString* path = |
| - [simulatorHome_ stringByAppendingPathComponent:relativePathToSystemLog]; |
| -#endif // defined(IOSSIM_USE_XCODE_6) |
| + NSString* path; |
| + if (IsRunningWithXcode6OrLater()) { |
| + NSString* dataPath = session.sessionConfig.device.dataPath; |
| + path = |
| + [dataPath stringByAppendingPathComponent:@"Library/Logs/system.log"]; |
| + } else { |
| + NSString* relativePathToSystemLog = |
| + [NSString stringWithFormat: |
| + @"Library/Logs/iOS Simulator/%@/system.log", versionString]; |
| + path = [simulatorHome_ |
| + stringByAppendingPathComponent:relativePathToSystemLog]; |
| + } |
| NSFileManager* fileManager = [NSFileManager defaultManager]; |
| if ([fileManager fileExistsAtPath:path]) { |
| NSString* content = |
| @@ -530,19 +559,26 @@ NSBundle* LoadSimulatorFramework(NSString* developerDir) { |
| return nil; |
| } |
| -// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
| -// (crbug.com/385030). |
| -#if defined(IOSSIM_USE_XCODE_6) |
| - NSString* coreSimulatorPath = [developerDir |
| - stringByAppendingPathComponent:kCoreSimulatorRelativePath]; |
| - NSBundle* coreSimulatorBundle = |
| - [NSBundle bundleWithPath:coreSimulatorPath]; |
| - if (![coreSimulatorBundle load]) |
| - return nil; |
| -#endif // defined(IOSSIM_USE_XCODE_6) |
| - |
| + // The path within the developer dir of the private Simulator frameworks. |
| + NSString* simulatorFrameworkRelativePath; |
| + if (IsRunningWithXcode6OrLater()) { |
| + simulatorFrameworkRelativePath = |
| + @"../SharedFrameworks/DVTiPhoneSimulatorRemoteClient.framework"; |
| + NSString* const kCoreSimulatorRelativePath = |
| + @"Library/PrivateFrameworks/CoreSimulator.framework"; |
| + NSString* coreSimulatorPath = [developerDir |
| + stringByAppendingPathComponent:kCoreSimulatorRelativePath]; |
| + NSBundle* coreSimulatorBundle = |
| + [NSBundle bundleWithPath:coreSimulatorPath]; |
| + if (![coreSimulatorBundle load]) |
| + return nil; |
| + } else { |
| + simulatorFrameworkRelativePath = |
| + @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/" |
| + @"DVTiPhoneSimulatorRemoteClient.framework"; |
| + } |
| NSString* simBundlePath = [developerDir |
| - stringByAppendingPathComponent:kSimulatorFrameworkRelativePath]; |
| + stringByAppendingPathComponent:simulatorFrameworkRelativePath]; |
| NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath]; |
| if (![simBundle load]) |
| return nil; |
| @@ -602,47 +638,45 @@ DTiPhoneSimulatorSessionConfig* BuildSessionConfig( |
| sessionConfig.simulatedDeviceInfoName = deviceName; |
| sessionConfig.simulatedDeviceFamily = deviceFamily; |
| -// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
| -// (crbug.com/385030). |
| -#if defined(IOSSIM_USE_XCODE_6) |
| - Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); |
| - id simDeviceType = |
| - [simDeviceTypeClass supportedDeviceTypesByName][deviceName]; |
| - Class simRuntimeClass = FindClassByName(@"SimRuntime"); |
| - NSString* identifier = systemRoot.runtime.identifier; |
| - id simRuntime = [simRuntimeClass supportedRuntimesByIdentifier][identifier]; |
| - |
| - // Attempt to use an existing device, but create one if a suitable match can't |
| - // be found. For example, if the simulator is running with a non-default home |
| - // directory (e.g. via iossim's -u command line arg) then there won't be any |
| - // devices so one will have to be created. |
| - Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); |
| - id deviceSet = |
| - [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; |
| - id simDevice = nil; |
| - for (id device in [deviceSet availableDevices]) { |
| - if ([device runtime] == simRuntime && |
| - [device deviceType] == simDeviceType) { |
| - simDevice = device; |
| - break; |
| + if (IsRunningWithXcode6OrLater()) { |
| + Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); |
| + id simDeviceType = |
| + [simDeviceTypeClass supportedDeviceTypesByName][deviceName]; |
| + Class simRuntimeClass = FindClassByName(@"SimRuntime"); |
| + NSString* identifier = systemRoot.runtime.identifier; |
| + id simRuntime = [simRuntimeClass supportedRuntimesByIdentifier][identifier]; |
| + |
| + // Attempt to use an existing device, but create one if a suitable match |
| + // can't be found. For example, if the simulator is running with a |
| + // non-default home directory (e.g. via iossim's -u command line arg) then |
| + // there won't be any devices so one will have to be created. |
| + Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); |
| + id deviceSet = |
| + [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; |
| + id simDevice = nil; |
| + for (id device in [deviceSet availableDevices]) { |
| + if ([device runtime] == simRuntime && |
| + [device deviceType] == simDeviceType) { |
| + simDevice = device; |
| + break; |
| + } |
| } |
| - } |
| - if (!simDevice) { |
| - NSError* error = nil; |
| - // n.b. only the device name is necessary because the iOS Simulator menu |
| - // already splits devices by runtime version. |
| - NSString* name = [NSString stringWithFormat:@"iossim - %@ ", deviceName]; |
| - simDevice = [deviceSet createDeviceWithType:simDeviceType |
| - runtime:simRuntime |
| - name:name |
| - error:&error]; |
| - if (error) { |
| - LogError(@"Failed to create device: %@", error); |
| - exit(kExitInitializationFailure); |
| + if (!simDevice) { |
| + NSError* error = nil; |
| + // n.b. only the device name is necessary because the iOS Simulator menu |
| + // already splits devices by runtime version. |
| + NSString* name = [NSString stringWithFormat:@"iossim - %@ ", deviceName]; |
| + simDevice = [deviceSet createDeviceWithType:simDeviceType |
| + runtime:simRuntime |
| + name:name |
| + error:&error]; |
| + if (error) { |
| + LogError(@"Failed to create device: %@", error); |
| + exit(kExitInitializationFailure); |
| + } |
| } |
| + sessionConfig.device = simDevice; |
| } |
| - sessionConfig.device = simDevice; |
| -#endif |
| return sessionConfig; |
| } |
| @@ -774,13 +808,7 @@ int main(int argc, char* const argv[]) { |
| NSString* appPath = nil; |
| NSString* appName = nil; |
| NSString* sdkVersion = nil; |
| -// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
| -// (crbug.com/385030). |
| -#if defined(IOSSIM_USE_XCODE_6) |
| - NSString* deviceName = @"iPhone 5"; |
| -#else |
| - NSString* deviceName = @"iPhone"; |
| -#endif |
| + NSString* deviceName = IsRunningWithXcode6OrLater() ? @"iPhone 5" : @"iPhone"; |
| NSString* simHomePath = nil; |
| NSMutableArray* appArgs = [NSMutableArray array]; |
| NSMutableDictionary* appEnv = [NSMutableDictionary dictionary]; |
| @@ -887,27 +915,25 @@ int main(int argc, char* const argv[]) { |
| // Determine the deviceFamily based on the deviceName |
| NSNumber* deviceFamily = nil; |
| -// TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed |
| -// (crbug.com/385030). |
| -#if defined(IOSSIM_USE_XCODE_6) |
| - Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); |
| - if ([simDeviceTypeClass supportedDeviceTypesByName][deviceName] == nil) { |
| - LogError(@"Invalid device name: %@.", deviceName); |
| - PrintSupportedDevices(); |
| - exit(kExitInvalidArguments); |
| - } |
| -#else |
| - if (!deviceName || CaseInsensitivePrefixSearch(deviceName, @"iPhone")) { |
| - deviceFamily = [NSNumber numberWithInt:kIPhoneFamily]; |
| - } else if (CaseInsensitivePrefixSearch(deviceName, @"iPad")) { |
| - deviceFamily = [NSNumber numberWithInt:kIPadFamily]; |
| - } |
| - else { |
| - LogError(@"Invalid device name: %@. Must begin with 'iPhone' or 'iPad'", |
| - deviceName); |
| - exit(kExitInvalidArguments); |
| + if (IsRunningWithXcode6OrLater()) { |
| + Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); |
| + if ([simDeviceTypeClass supportedDeviceTypesByName][deviceName] == nil) { |
| + LogError(@"Invalid device name: %@.", deviceName); |
| + PrintSupportedDevices(); |
| + exit(kExitInvalidArguments); |
| + } |
| + } else { |
| + if (!deviceName || CaseInsensitivePrefixSearch(deviceName, @"iPhone")) { |
| + deviceFamily = [NSNumber numberWithInt:kIPhoneFamily]; |
| + } else if (CaseInsensitivePrefixSearch(deviceName, @"iPad")) { |
| + deviceFamily = [NSNumber numberWithInt:kIPadFamily]; |
| + } |
| + else { |
| + LogError(@"Invalid device name: %@. Must begin with 'iPhone' or 'iPad'", |
| + deviceName); |
| + exit(kExitInvalidArguments); |
| + } |
| } |
| -#endif // !defined(IOSSIM_USE_XCODE_6) |
| // Set up the user home directory for the simulator only if a non-default |
| // value was specified. |