Chromium Code Reviews| 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 <Foundation/Foundation.h> | 5 #import <Foundation/Foundation.h> |
| 6 #include <asl.h> | 6 #include <asl.h> |
| 7 #include <libgen.h> | 7 #include <libgen.h> |
| 8 #include <stdarg.h> | 8 #include <stdarg.h> |
| 9 #include <stdio.h> | 9 #include <stdio.h> |
| 10 | 10 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 // (crbug.com/385030). | 36 // (crbug.com/385030). |
| 37 #if defined(IOSSIM_USE_XCODE_6) | 37 #if defined(IOSSIM_USE_XCODE_6) |
| 38 @protocol OS_xpc_object | 38 @protocol OS_xpc_object |
| 39 @end | 39 @end |
| 40 @protocol SimBridge; | 40 @protocol SimBridge; |
| 41 @class SimDeviceSet; | 41 @class SimDeviceSet; |
| 42 @class SimDeviceType; | 42 @class SimDeviceType; |
| 43 @class SimRuntime; | 43 @class SimRuntime; |
| 44 @class SimServiceConnectionManager; | 44 @class SimServiceConnectionManager; |
| 45 #import "CoreSimulator.h" | 45 #import "CoreSimulator.h" |
| 46 #endif // IOSSIM_USE_XCODE_6 | 46 #endif // IOSSIM_USE_XCODE_6 |
|
TVL
2014/08/21 19:41:50
I'm guessing these need to be cleaned up or this w
lliabraa
2014/08/22 17:50:56
I've added compile-time checks around all the xcod
| |
| 47 | 47 |
| 48 @interface DVTPlatform : NSObject | 48 @interface DVTPlatform : NSObject |
| 49 + (BOOL)loadAllPlatformsReturningError:(id*)arg1; | 49 + (BOOL)loadAllPlatformsReturningError:(id*)arg1; |
| 50 @end | 50 @end |
| 51 @class DTiPhoneSimulatorApplicationSpecifier; | 51 @class DTiPhoneSimulatorApplicationSpecifier; |
| 52 @class DTiPhoneSimulatorSession; | 52 @class DTiPhoneSimulatorSession; |
| 53 @class DTiPhoneSimulatorSessionConfig; | 53 @class DTiPhoneSimulatorSessionConfig; |
| 54 @class DTiPhoneSimulatorSystemRoot; | 54 @class DTiPhoneSimulatorSystemRoot; |
| 55 @class DVTConfinementServiceConnection; | 55 @class DVTConfinementServiceConnection; |
| 56 @class DVTDispatchLock; | 56 @class DVTDispatchLock; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 // If this timeout occurs iossim will likely exit with non-zero status; the | 94 // If this timeout occurs iossim will likely exit with non-zero status; the |
| 95 // exception being if the app is invoked and completes execution before the | 95 // exception being if the app is invoked and completes execution before the |
| 96 // session is started (this case is handled in session:didStart:withError). | 96 // session is started (this case is handled in session:didStart:withError). |
| 97 const NSTimeInterval kDefaultSessionStartTimeoutSeconds = 30; | 97 const NSTimeInterval kDefaultSessionStartTimeoutSeconds = 30; |
| 98 | 98 |
| 99 // While the simulated app is running, its stdout is redirected to a file which | 99 // While the simulated app is running, its stdout is redirected to a file which |
| 100 // is polled by iossim and written to iossim's stdout using the following | 100 // is polled by iossim and written to iossim's stdout using the following |
| 101 // polling interval. | 101 // polling interval. |
| 102 const NSTimeInterval kOutputPollIntervalSeconds = 0.1; | 102 const NSTimeInterval kOutputPollIntervalSeconds = 0.1; |
| 103 | 103 |
| 104 // The path within the developer dir of the private Simulator frameworks. | |
| 105 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | |
| 106 // (crbug.com/385030). | |
| 107 #if defined(IOSSIM_USE_XCODE_6) | |
| 108 NSString* const kSimulatorFrameworkRelativePath = | |
| 109 @"../SharedFrameworks/DVTiPhoneSimulatorRemoteClient.framework"; | |
| 110 NSString* const kCoreSimulatorRelativePath = | |
| 111 @"Library/PrivateFrameworks/CoreSimulator.framework"; | |
| 112 #else | |
| 113 NSString* const kSimulatorFrameworkRelativePath = | |
| 114 @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/" | |
| 115 @"DVTiPhoneSimulatorRemoteClient.framework"; | |
| 116 #endif // IOSSIM_USE_XCODE_6 | |
| 117 NSString* const kDVTFoundationRelativePath = | 104 NSString* const kDVTFoundationRelativePath = |
| 118 @"../SharedFrameworks/DVTFoundation.framework"; | 105 @"../SharedFrameworks/DVTFoundation.framework"; |
| 119 NSString* const kDevToolsFoundationRelativePath = | 106 NSString* const kDevToolsFoundationRelativePath = |
| 120 @"../OtherFrameworks/DevToolsFoundation.framework"; | 107 @"../OtherFrameworks/DevToolsFoundation.framework"; |
| 121 NSString* const kSimulatorRelativePath = | 108 NSString* const kSimulatorRelativePath = |
| 122 @"Platforms/iPhoneSimulator.platform/Developer/Applications/" | 109 @"Platforms/iPhoneSimulator.platform/Developer/Applications/" |
| 123 @"iPhone Simulator.app"; | 110 @"iPhone Simulator.app"; |
| 124 | 111 |
| 125 // Simulator Error String Key. This can be found by looking in the Simulator's | 112 // Simulator Error String Key. This can be found by looking in the Simulator's |
| 126 // Localizable.strings files. | 113 // Localizable.strings files. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 165 // Helper to find a class by name and die if it isn't found. | 152 // Helper to find a class by name and die if it isn't found. |
| 166 Class FindClassByName(NSString* nameOfClass) { | 153 Class FindClassByName(NSString* nameOfClass) { |
| 167 Class theClass = NSClassFromString(nameOfClass); | 154 Class theClass = NSClassFromString(nameOfClass); |
| 168 if (!theClass) { | 155 if (!theClass) { |
| 169 LogError(@"Failed to find class %@ at runtime.", nameOfClass); | 156 LogError(@"Failed to find class %@ at runtime.", nameOfClass); |
| 170 exit(kExitInitializationFailure); | 157 exit(kExitInitializationFailure); |
| 171 } | 158 } |
| 172 return theClass; | 159 return theClass; |
| 173 } | 160 } |
| 174 | 161 |
| 162 // Finds the Xcode version via xcodebuild -version. Output from xcodebuild is | |
| 163 // expected to look like: | |
| 164 // Xcode <version> | |
| 165 // Build version 5B130a | |
| 166 // where <version> is the string returned by this function (e.g. 6.0). | |
| 167 NSString* FindXcodeVersion() { | |
| 168 NSTask* xcodeSelectTask = [[[NSTask alloc] init] autorelease]; | |
|
TVL
2014/08/21 19:41:50
fyi - you could probably make a common method with
| |
| 169 [xcodeSelectTask setLaunchPath:@"/usr/bin/xcodebuild"]; | |
| 170 [xcodeSelectTask setArguments:[NSArray arrayWithObject:@"-version"]]; | |
| 171 | |
| 172 NSPipe* outputPipe = [NSPipe pipe]; | |
| 173 [xcodeSelectTask setStandardOutput:outputPipe]; | |
| 174 NSFileHandle* outputFile = [outputPipe fileHandleForReading]; | |
| 175 | |
| 176 [xcodeSelectTask launch]; | |
| 177 NSData* outputData = [outputFile readDataToEndOfFile]; | |
| 178 [xcodeSelectTask terminate]; | |
| 179 | |
| 180 NSString* output = | |
| 181 [[[NSString alloc] initWithData:outputData | |
| 182 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.
| |
| 183 NSArray* tokens = [output componentsSeparatedByCharactersInSet: | |
| 184 [NSCharacterSet whitespaceAndNewlineCharacterSet]]; | |
| 185 if ([tokens count] != 6) { | |
| 186 LogError(@"Unable to find Xcode version. 'xcodebuild -version' " | |
| 187 @"returned \n%@", output); | |
| 188 return nil; | |
| 189 } | |
| 190 return tokens[1]; | |
| 191 } | |
| 192 | |
| 193 // Returns true if iossim is running with Xcode 6 or later installed on the | |
| 194 // host. | |
| 195 BOOL IsRunningWithXcode6OrLater() { | |
| 196 static NSString* xcodeVersion = FindXcodeVersion(); | |
| 197 if (!xcodeVersion) { | |
| 198 return false; | |
| 199 } | |
| 200 NSArray* components = [xcodeVersion componentsSeparatedByString:@"."]; | |
| 201 if ([components count] < 1) { | |
| 202 return false; | |
| 203 } | |
| 204 NSInteger majorVersion = [components[0] integerValue]; | |
| 205 return majorVersion >= 6; | |
| 206 } | |
| 207 | |
| 175 // Prints supported devices and SDKs. | 208 // Prints supported devices and SDKs. |
| 176 void PrintSupportedDevices() { | 209 void PrintSupportedDevices() { |
| 177 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | 210 if (IsRunningWithXcode6OrLater()) { |
| 178 // (crbug.com/385030). | 211 printf("Supported device/SDK combinations:\n"); |
| 179 #if defined(IOSSIM_USE_XCODE_6) | 212 Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); |
| 180 printf("Supported device/SDK combinations:\n"); | 213 id deviceSet = |
| 181 Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); | 214 [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; |
| 182 id deviceSet = | 215 for (id simDevice in [deviceSet availableDevices]) { |
| 183 [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; | 216 NSString* deviceInfo = |
| 184 for (id simDevice in [deviceSet availableDevices]) { | 217 [NSString stringWithFormat:@" -d '%@' -s '%@'\n", |
| 185 NSString* deviceInfo = | 218 [simDevice name], [[simDevice runtime] versionString]]; |
| 186 [NSString stringWithFormat:@" -d '%@' -s '%@'\n", | 219 printf("%s", [deviceInfo UTF8String]); |
| 187 [simDevice name], [[simDevice runtime] versionString]]; | 220 } |
| 188 printf("%s", [deviceInfo UTF8String]); | 221 } else { |
| 222 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
| |
| 223 Class rootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot"); | |
| 224 for (id root in [rootClass knownRoots]) { | |
| 225 printf(" '%s'\n", [[root sdkVersion] UTF8String]); | |
| 226 } | |
| 227 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.
| |
| 228 printf(" 'iPhone'\n"); | |
| 229 printf(" 'iPhone Retina (3.5-inch)'\n"); | |
| 230 printf(" 'iPhone Retina (4-inch)'\n"); | |
| 231 printf(" 'iPhone Retina (4-inch 64-bit)'\n"); | |
| 232 printf(" 'iPad'\n"); | |
| 233 printf(" 'iPad Retina'\n"); | |
| 234 printf(" 'iPad Retina (64-bit)'\n"); | |
| 189 } | 235 } |
| 190 #else | |
| 191 printf("Supported SDK versions:\n"); | |
| 192 Class rootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot"); | |
| 193 for (id root in [rootClass knownRoots]) { | |
| 194 printf(" '%s'\n", [[root sdkVersion] UTF8String]); | |
| 195 } | |
| 196 printf("Supported devices:\n"); | |
| 197 printf(" 'iPhone'\n"); | |
| 198 printf(" 'iPhone Retina (3.5-inch)'\n"); | |
| 199 printf(" 'iPhone Retina (4-inch)'\n"); | |
| 200 printf(" 'iPhone Retina (4-inch 64-bit)'\n"); | |
| 201 printf(" 'iPad'\n"); | |
| 202 printf(" 'iPad Retina'\n"); | |
| 203 printf(" 'iPad Retina (64-bit)'\n"); | |
| 204 #endif // defined(IOSSIM_USE_XCODE_6) | |
| 205 } | 236 } |
| 206 } // namespace | 237 } // namespace |
| 207 | 238 |
| 208 // A delegate that is called when the simulated app is started or ended in the | 239 // A delegate that is called when the simulated app is started or ended in the |
| 209 // simulator. | 240 // simulator. |
| 210 @interface SimulatorDelegate : NSObject <DTiPhoneSimulatorSessionDelegate> { | 241 @interface SimulatorDelegate : NSObject <DTiPhoneSimulatorSessionDelegate> { |
| 211 @private | 242 @private |
| 212 NSString* stdioPath_; | 243 NSString* stdioPath_; |
| 213 NSString* developerDir_; | 244 NSString* developerDir_; |
| 214 NSString* simulatorHome_; | 245 NSString* simulatorHome_; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 253 // Reads data from the simulated app's output and writes it to stdout. This | 284 // Reads data from the simulated app's output and writes it to stdout. This |
| 254 // method blocks, so it should be called in a separate thread. The iOS | 285 // method blocks, so it should be called in a separate thread. The iOS |
| 255 // Simulator takes a file path for the simulated app's stdout and stderr, but | 286 // Simulator takes a file path for the simulated app's stdout and stderr, but |
| 256 // this path isn't always available (e.g. when the stdout is Xcode's build | 287 // this path isn't always available (e.g. when the stdout is Xcode's build |
| 257 // window). As a workaround, iossim creates a temp file to hold output, which | 288 // window). As a workaround, iossim creates a temp file to hold output, which |
| 258 // this method reads and copies to stdout. | 289 // this method reads and copies to stdout. |
| 259 - (void)tailOutputForSession:(DTiPhoneSimulatorSession*)session { | 290 - (void)tailOutputForSession:(DTiPhoneSimulatorSession*)session { |
| 260 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; | 291 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; |
| 261 | 292 |
| 262 NSFileHandle* simio = [NSFileHandle fileHandleForReadingAtPath:stdioPath_]; | 293 NSFileHandle* simio = [NSFileHandle fileHandleForReadingAtPath:stdioPath_]; |
| 263 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | 294 if (IsRunningWithXcode6OrLater()) { |
| 264 // (crbug.com/385030). | 295 // With iOS 8 simulators on Xcode 6, the app output is relative to the |
| 265 #if defined(IOSSIM_USE_XCODE_6) | 296 // simulator's data directory. |
| 266 // With iOS 8 simulators on Xcode 6, the app output is relative to the | 297 if ([session.sessionConfig.simulatedSystemRoot.sdkVersion isEqual:@"8.0"]) { |
| 267 // simulator's data directory. | 298 NSString* dataPath = session.sessionConfig.device.dataPath; |
| 268 if ([session.sessionConfig.simulatedSystemRoot.sdkVersion isEqual:@"8.0"]) { | 299 NSString* appOutput = |
| 269 NSString* dataPath = session.sessionConfig.device.dataPath; | 300 [dataPath stringByAppendingPathComponent:stdioPath_]; |
| 270 NSString* appOutput = [dataPath stringByAppendingPathComponent:stdioPath_]; | 301 simio = [NSFileHandle fileHandleForReadingAtPath:appOutput]; |
| 271 simio = [NSFileHandle fileHandleForReadingAtPath:appOutput]; | 302 } |
| 272 } | 303 } |
| 273 #endif | |
| 274 NSFileHandle* standardOutput = [NSFileHandle fileHandleWithStandardOutput]; | 304 NSFileHandle* standardOutput = [NSFileHandle fileHandleWithStandardOutput]; |
| 275 // Copy data to stdout/stderr while the app is running. | 305 // Copy data to stdout/stderr while the app is running. |
| 276 while (appRunning_) { | 306 while (appRunning_) { |
| 277 NSAutoreleasePool* innerPool = [[NSAutoreleasePool alloc] init]; | 307 NSAutoreleasePool* innerPool = [[NSAutoreleasePool alloc] init]; |
| 278 [standardOutput writeData:[simio readDataToEndOfFile]]; | 308 [standardOutput writeData:[simio readDataToEndOfFile]]; |
| 279 [NSThread sleepForTimeInterval:kOutputPollIntervalSeconds]; | 309 [NSThread sleepForTimeInterval:kOutputPollIntervalSeconds]; |
| 280 [innerPool drain]; | 310 [innerPool drain]; |
| 281 } | 311 } |
| 282 | 312 |
| 283 // Once the app is no longer running, copy any data that was written during | 313 // Once the app is no longer running, copy any data that was written during |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 const char* message = asl_get(entry, ASL_KEY_MSG); | 442 const char* message = asl_get(entry, ASL_KEY_MSG); |
| 413 LogWarning(@"Console message: %s", message); | 443 LogWarning(@"Console message: %s", message); |
| 414 // Some messages are harmless, so don't trigger a failure for them. | 444 // Some messages are harmless, so don't trigger a failure for them. |
| 415 if (strstr(message, "The following job tried to hijack the service")) | 445 if (strstr(message, "The following job tried to hijack the service")) |
| 416 continue; | 446 continue; |
| 417 badEntryFound = YES; | 447 badEntryFound = YES; |
| 418 } | 448 } |
| 419 } else { | 449 } else { |
| 420 // Otherwise, the iOS Simulator's system logging is sandboxed, so parse the | 450 // Otherwise, the iOS Simulator's system logging is sandboxed, so parse the |
| 421 // sandboxed system.log file for known errors. | 451 // sandboxed system.log file for known errors. |
| 422 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | 452 NSString* path; |
| 423 // (crbug.com/385030). | 453 if (IsRunningWithXcode6OrLater()) { |
| 424 #if defined(IOSSIM_USE_XCODE_6) | 454 NSString* dataPath = session.sessionConfig.device.dataPath; |
| 425 NSString* dataPath = session.sessionConfig.device.dataPath; | 455 path = |
| 426 NSString* path = | 456 [dataPath stringByAppendingPathComponent:@"Library/Logs/system.log"]; |
| 427 [dataPath stringByAppendingPathComponent:@"Library/Logs/system.log"]; | 457 } else { |
| 428 #else | 458 NSString* relativePathToSystemLog = |
| 429 NSString* relativePathToSystemLog = | 459 [NSString stringWithFormat: |
| 430 [NSString stringWithFormat: | 460 @"Library/Logs/iOS Simulator/%@/system.log", versionString]; |
| 431 @"Library/Logs/iOS Simulator/%@/system.log", versionString]; | 461 path = [simulatorHome_ |
| 432 NSString* path = | 462 stringByAppendingPathComponent:relativePathToSystemLog]; |
| 433 [simulatorHome_ stringByAppendingPathComponent:relativePathToSystemLog]; | 463 } |
| 434 #endif // defined(IOSSIM_USE_XCODE_6) | |
| 435 NSFileManager* fileManager = [NSFileManager defaultManager]; | 464 NSFileManager* fileManager = [NSFileManager defaultManager]; |
| 436 if ([fileManager fileExistsAtPath:path]) { | 465 if ([fileManager fileExistsAtPath:path]) { |
| 437 NSString* content = | 466 NSString* content = |
| 438 [NSString stringWithContentsOfFile:path | 467 [NSString stringWithContentsOfFile:path |
| 439 encoding:NSUTF8StringEncoding | 468 encoding:NSUTF8StringEncoding |
| 440 error:NULL]; | 469 error:NULL]; |
| 441 NSArray* lines = [content componentsSeparatedByCharactersInSet: | 470 NSArray* lines = [content componentsSeparatedByCharactersInSet: |
| 442 [NSCharacterSet newlineCharacterSet]]; | 471 [NSCharacterSet newlineCharacterSet]]; |
| 443 NSString* simulatedAppPID = | 472 NSString* simulatedAppPID = |
| 444 [NSString stringWithFormat:@"%d", session.simulatedApplicationPID]; | 473 [NSString stringWithFormat:@"%d", session.simulatedApplicationPID]; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 523 | 552 |
| 524 // Prime DVTPlatform. | 553 // Prime DVTPlatform. |
| 525 NSError* error; | 554 NSError* error; |
| 526 Class DVTPlatformClass = FindClassByName(@"DVTPlatform"); | 555 Class DVTPlatformClass = FindClassByName(@"DVTPlatform"); |
| 527 if (![DVTPlatformClass loadAllPlatformsReturningError:&error]) { | 556 if (![DVTPlatformClass loadAllPlatformsReturningError:&error]) { |
| 528 LogError(@"Unable to loadAllPlatformsReturningError. Error: %@", | 557 LogError(@"Unable to loadAllPlatformsReturningError. Error: %@", |
| 529 [error localizedDescription]); | 558 [error localizedDescription]); |
| 530 return nil; | 559 return nil; |
| 531 } | 560 } |
| 532 | 561 |
| 533 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | 562 // The path within the developer dir of the private Simulator frameworks. |
| 534 // (crbug.com/385030). | 563 NSString* simulatorFrameworkRelativePath; |
| 535 #if defined(IOSSIM_USE_XCODE_6) | 564 if (IsRunningWithXcode6OrLater()) { |
| 536 NSString* coreSimulatorPath = [developerDir | 565 simulatorFrameworkRelativePath = |
| 537 stringByAppendingPathComponent:kCoreSimulatorRelativePath]; | 566 @"../SharedFrameworks/DVTiPhoneSimulatorRemoteClient.framework"; |
| 538 NSBundle* coreSimulatorBundle = | 567 NSString* const kCoreSimulatorRelativePath = |
| 539 [NSBundle bundleWithPath:coreSimulatorPath]; | 568 @"Library/PrivateFrameworks/CoreSimulator.framework"; |
| 540 if (![coreSimulatorBundle load]) | 569 NSString* coreSimulatorPath = [developerDir |
| 541 return nil; | 570 stringByAppendingPathComponent:kCoreSimulatorRelativePath]; |
| 542 #endif // defined(IOSSIM_USE_XCODE_6) | 571 NSBundle* coreSimulatorBundle = |
| 543 | 572 [NSBundle bundleWithPath:coreSimulatorPath]; |
| 573 if (![coreSimulatorBundle load]) | |
| 574 return nil; | |
| 575 } else { | |
| 576 simulatorFrameworkRelativePath = | |
| 577 @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/" | |
| 578 @"DVTiPhoneSimulatorRemoteClient.framework"; | |
| 579 } | |
| 544 NSString* simBundlePath = [developerDir | 580 NSString* simBundlePath = [developerDir |
| 545 stringByAppendingPathComponent:kSimulatorFrameworkRelativePath]; | 581 stringByAppendingPathComponent:simulatorFrameworkRelativePath]; |
| 546 NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath]; | 582 NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath]; |
| 547 if (![simBundle load]) | 583 if (![simBundle load]) |
| 548 return nil; | 584 return nil; |
| 549 return simBundle; | 585 return simBundle; |
| 550 } | 586 } |
| 551 | 587 |
| 552 // Converts the given app path to an application spec, which requires an | 588 // Converts the given app path to an application spec, which requires an |
| 553 // absolute path. | 589 // absolute path. |
| 554 DTiPhoneSimulatorApplicationSpecifier* BuildAppSpec(NSString* appPath) { | 590 DTiPhoneSimulatorApplicationSpecifier* BuildAppSpec(NSString* appPath) { |
| 555 Class applicationSpecifierClass = | 591 Class applicationSpecifierClass = |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 595 sessionConfig.applicationToSimulateOnStart = appSpec; | 631 sessionConfig.applicationToSimulateOnStart = appSpec; |
| 596 sessionConfig.simulatedSystemRoot = systemRoot; | 632 sessionConfig.simulatedSystemRoot = systemRoot; |
| 597 sessionConfig.localizedClientName = @"chromium"; | 633 sessionConfig.localizedClientName = @"chromium"; |
| 598 sessionConfig.simulatedApplicationStdErrPath = stderrPath; | 634 sessionConfig.simulatedApplicationStdErrPath = stderrPath; |
| 599 sessionConfig.simulatedApplicationStdOutPath = stdoutPath; | 635 sessionConfig.simulatedApplicationStdOutPath = stdoutPath; |
| 600 sessionConfig.simulatedApplicationLaunchArgs = appArgs; | 636 sessionConfig.simulatedApplicationLaunchArgs = appArgs; |
| 601 sessionConfig.simulatedApplicationLaunchEnvironment = appEnv; | 637 sessionConfig.simulatedApplicationLaunchEnvironment = appEnv; |
| 602 sessionConfig.simulatedDeviceInfoName = deviceName; | 638 sessionConfig.simulatedDeviceInfoName = deviceName; |
| 603 sessionConfig.simulatedDeviceFamily = deviceFamily; | 639 sessionConfig.simulatedDeviceFamily = deviceFamily; |
| 604 | 640 |
| 605 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | 641 if (IsRunningWithXcode6OrLater()) { |
| 606 // (crbug.com/385030). | 642 Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); |
| 607 #if defined(IOSSIM_USE_XCODE_6) | 643 id simDeviceType = |
| 608 Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); | 644 [simDeviceTypeClass supportedDeviceTypesByName][deviceName]; |
| 609 id simDeviceType = | 645 Class simRuntimeClass = FindClassByName(@"SimRuntime"); |
| 610 [simDeviceTypeClass supportedDeviceTypesByName][deviceName]; | 646 NSString* identifier = systemRoot.runtime.identifier; |
| 611 Class simRuntimeClass = FindClassByName(@"SimRuntime"); | 647 id simRuntime = [simRuntimeClass supportedRuntimesByIdentifier][identifier]; |
| 612 NSString* identifier = systemRoot.runtime.identifier; | |
| 613 id simRuntime = [simRuntimeClass supportedRuntimesByIdentifier][identifier]; | |
| 614 | 648 |
| 615 // Attempt to use an existing device, but create one if a suitable match can't | 649 // Attempt to use an existing device, but create one if a suitable match |
| 616 // be found. For example, if the simulator is running with a non-default home | 650 // can't be found. For example, if the simulator is running with a |
| 617 // directory (e.g. via iossim's -u command line arg) then there won't be any | 651 // non-default home directory (e.g. via iossim's -u command line arg) then |
| 618 // devices so one will have to be created. | 652 // there won't be any devices so one will have to be created. |
| 619 Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); | 653 Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); |
| 620 id deviceSet = | 654 id deviceSet = |
| 621 [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; | 655 [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; |
| 622 id simDevice = nil; | 656 id simDevice = nil; |
| 623 for (id device in [deviceSet availableDevices]) { | 657 for (id device in [deviceSet availableDevices]) { |
| 624 if ([device runtime] == simRuntime && | 658 if ([device runtime] == simRuntime && |
| 625 [device deviceType] == simDeviceType) { | 659 [device deviceType] == simDeviceType) { |
| 626 simDevice = device; | 660 simDevice = device; |
| 627 break; | 661 break; |
| 662 } | |
| 628 } | 663 } |
| 664 if (!simDevice) { | |
| 665 NSError* error = nil; | |
| 666 // n.b. only the device name is necessary because the iOS Simulator menu | |
| 667 // already splits devices by runtime version. | |
| 668 NSString* name = [NSString stringWithFormat:@"iossim - %@ ", deviceName]; | |
| 669 simDevice = [deviceSet createDeviceWithType:simDeviceType | |
| 670 runtime:simRuntime | |
| 671 name:name | |
| 672 error:&error]; | |
| 673 if (error) { | |
| 674 LogError(@"Failed to create device: %@", error); | |
| 675 exit(kExitInitializationFailure); | |
| 676 } | |
| 677 } | |
| 678 sessionConfig.device = simDevice; | |
| 629 } | 679 } |
| 630 if (!simDevice) { | |
| 631 NSError* error = nil; | |
| 632 // n.b. only the device name is necessary because the iOS Simulator menu | |
| 633 // already splits devices by runtime version. | |
| 634 NSString* name = [NSString stringWithFormat:@"iossim - %@ ", deviceName]; | |
| 635 simDevice = [deviceSet createDeviceWithType:simDeviceType | |
| 636 runtime:simRuntime | |
| 637 name:name | |
| 638 error:&error]; | |
| 639 if (error) { | |
| 640 LogError(@"Failed to create device: %@", error); | |
| 641 exit(kExitInitializationFailure); | |
| 642 } | |
| 643 } | |
| 644 sessionConfig.device = simDevice; | |
| 645 #endif | |
| 646 return sessionConfig; | 680 return sessionConfig; |
| 647 } | 681 } |
| 648 | 682 |
| 649 // Builds a simulator session that will use the given delegate. | 683 // Builds a simulator session that will use the given delegate. |
| 650 DTiPhoneSimulatorSession* BuildSession(SimulatorDelegate* delegate) { | 684 DTiPhoneSimulatorSession* BuildSession(SimulatorDelegate* delegate) { |
| 651 Class sessionClass = FindClassByName(@"DTiPhoneSimulatorSession"); | 685 Class sessionClass = FindClassByName(@"DTiPhoneSimulatorSession"); |
| 652 DTiPhoneSimulatorSession* session = | 686 DTiPhoneSimulatorSession* session = |
| 653 [[[sessionClass alloc] init] autorelease]; | 687 [[[sessionClass alloc] init] autorelease]; |
| 654 session.delegate = delegate; | 688 session.delegate = delegate; |
| 655 return session; | 689 return session; |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 767 toolName = strdup(toolName); | 801 toolName = strdup(toolName); |
| 768 if (toolName != NULL) | 802 if (toolName != NULL) |
| 769 gToolName = toolName; | 803 gToolName = toolName; |
| 770 } | 804 } |
| 771 if (worker != NULL) | 805 if (worker != NULL) |
| 772 free(worker); | 806 free(worker); |
| 773 | 807 |
| 774 NSString* appPath = nil; | 808 NSString* appPath = nil; |
| 775 NSString* appName = nil; | 809 NSString* appName = nil; |
| 776 NSString* sdkVersion = nil; | 810 NSString* sdkVersion = nil; |
| 777 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | 811 NSString* deviceName = IsRunningWithXcode6OrLater() ? @"iPhone 5" : @"iPhone"; |
| 778 // (crbug.com/385030). | |
| 779 #if defined(IOSSIM_USE_XCODE_6) | |
| 780 NSString* deviceName = @"iPhone 5"; | |
| 781 #else | |
| 782 NSString* deviceName = @"iPhone"; | |
| 783 #endif | |
| 784 NSString* simHomePath = nil; | 812 NSString* simHomePath = nil; |
| 785 NSMutableArray* appArgs = [NSMutableArray array]; | 813 NSMutableArray* appArgs = [NSMutableArray array]; |
| 786 NSMutableDictionary* appEnv = [NSMutableDictionary dictionary]; | 814 NSMutableDictionary* appEnv = [NSMutableDictionary dictionary]; |
| 787 NSTimeInterval sessionStartTimeout = kDefaultSessionStartTimeoutSeconds; | 815 NSTimeInterval sessionStartTimeout = kDefaultSessionStartTimeoutSeconds; |
| 788 | 816 |
| 789 NSString* developerDir = FindDeveloperDir(); | 817 NSString* developerDir = FindDeveloperDir(); |
| 790 if (!developerDir) { | 818 if (!developerDir) { |
| 791 LogError(@"Unable to find developer directory."); | 819 LogError(@"Unable to find developer directory."); |
| 792 exit(kExitInitializationFailure); | 820 exit(kExitInitializationFailure); |
| 793 } | 821 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 880 exit(kExitInitializationFailure); | 908 exit(kExitInitializationFailure); |
| 881 } | 909 } |
| 882 | 910 |
| 883 // Get the paths for stdout and stderr so the simulated app's output will show | 911 // Get the paths for stdout and stderr so the simulated app's output will show |
| 884 // up in the caller's stdout/stderr. | 912 // up in the caller's stdout/stderr. |
| 885 NSString* outputDir = CreateTempDirectory(@"iossim-XXXXXX"); | 913 NSString* outputDir = CreateTempDirectory(@"iossim-XXXXXX"); |
| 886 NSString* stdioPath = [outputDir stringByAppendingPathComponent:@"stdio.txt"]; | 914 NSString* stdioPath = [outputDir stringByAppendingPathComponent:@"stdio.txt"]; |
| 887 | 915 |
| 888 // Determine the deviceFamily based on the deviceName | 916 // Determine the deviceFamily based on the deviceName |
| 889 NSNumber* deviceFamily = nil; | 917 NSNumber* deviceFamily = nil; |
| 890 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | 918 if (IsRunningWithXcode6OrLater()) { |
| 891 // (crbug.com/385030). | 919 Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); |
| 892 #if defined(IOSSIM_USE_XCODE_6) | 920 if ([simDeviceTypeClass supportedDeviceTypesByName][deviceName] == nil) { |
| 893 Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); | 921 LogError(@"Invalid device name: %@.", deviceName); |
| 894 if ([simDeviceTypeClass supportedDeviceTypesByName][deviceName] == nil) { | 922 PrintSupportedDevices(); |
| 895 LogError(@"Invalid device name: %@.", deviceName); | 923 exit(kExitInvalidArguments); |
| 896 PrintSupportedDevices(); | 924 } |
| 897 exit(kExitInvalidArguments); | 925 } else { |
| 926 if (!deviceName || CaseInsensitivePrefixSearch(deviceName, @"iPhone")) { | |
| 927 deviceFamily = [NSNumber numberWithInt:kIPhoneFamily]; | |
| 928 } else if (CaseInsensitivePrefixSearch(deviceName, @"iPad")) { | |
| 929 deviceFamily = [NSNumber numberWithInt:kIPadFamily]; | |
| 930 } | |
| 931 else { | |
| 932 LogError(@"Invalid device name: %@. Must begin with 'iPhone' or 'iPad'", | |
| 933 deviceName); | |
| 934 exit(kExitInvalidArguments); | |
| 935 } | |
| 898 } | 936 } |
| 899 #else | |
| 900 if (!deviceName || CaseInsensitivePrefixSearch(deviceName, @"iPhone")) { | |
| 901 deviceFamily = [NSNumber numberWithInt:kIPhoneFamily]; | |
| 902 } else if (CaseInsensitivePrefixSearch(deviceName, @"iPad")) { | |
| 903 deviceFamily = [NSNumber numberWithInt:kIPadFamily]; | |
| 904 } | |
| 905 else { | |
| 906 LogError(@"Invalid device name: %@. Must begin with 'iPhone' or 'iPad'", | |
| 907 deviceName); | |
| 908 exit(kExitInvalidArguments); | |
| 909 } | |
| 910 #endif // !defined(IOSSIM_USE_XCODE_6) | |
| 911 | 937 |
| 912 // Set up the user home directory for the simulator only if a non-default | 938 // Set up the user home directory for the simulator only if a non-default |
| 913 // value was specified. | 939 // value was specified. |
| 914 if (simHomePath) { | 940 if (simHomePath) { |
| 915 if (!InitializeSimulatorUserHome(simHomePath)) { | 941 if (!InitializeSimulatorUserHome(simHomePath)) { |
| 916 LogError(@"Unable to initialize home directory for simulator: %@", | 942 LogError(@"Unable to initialize home directory for simulator: %@", |
| 917 simHomePath); | 943 simHomePath); |
| 918 exit(kExitInitializationFailure); | 944 exit(kExitInitializationFailure); |
| 919 } | 945 } |
| 920 } else { | 946 } else { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 951 [error localizedDescription], | 977 [error localizedDescription], |
| 952 [error domain], static_cast<long int>([error code])); | 978 [error domain], static_cast<long int>([error code])); |
| 953 } | 979 } |
| 954 | 980 |
| 955 // Note that this code is only executed if the simulator fails to start | 981 // Note that this code is only executed if the simulator fails to start |
| 956 // because once the main run loop is started, only the delegate calling | 982 // because once the main run loop is started, only the delegate calling |
| 957 // exit() will end the program. | 983 // exit() will end the program. |
| 958 [pool drain]; | 984 [pool drain]; |
| 959 return kExitFailure; | 985 return kExitFailure; |
| 960 } | 986 } |
| OLD | NEW |