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 10 matching lines...) Expand all Loading... | |
| 21 // However, there are some forward declarations required to get things to | 21 // However, there are some forward declarations required to get things to |
| 22 // compile. Also, the DTiPhoneSimulatorSessionDelegate protocol is referenced | 22 // compile. Also, the DTiPhoneSimulatorSessionDelegate protocol is referenced |
| 23 // by the iPhoneSimulatorRemoteClient framework, but not defined in the object | 23 // by the iPhoneSimulatorRemoteClient framework, but not defined in the object |
| 24 // file, so it must be defined here before importing the generated | 24 // file, so it must be defined here before importing the generated |
| 25 // iPhoneSimulatorRemoteClient.h file. | 25 // iPhoneSimulatorRemoteClient.h file. |
| 26 | 26 |
| 27 @class DTiPhoneSimulatorApplicationSpecifier; | 27 @class DTiPhoneSimulatorApplicationSpecifier; |
| 28 @class DTiPhoneSimulatorSession; | 28 @class DTiPhoneSimulatorSession; |
| 29 @class DTiPhoneSimulatorSessionConfig; | 29 @class DTiPhoneSimulatorSessionConfig; |
| 30 @class DTiPhoneSimulatorSystemRoot; | 30 @class DTiPhoneSimulatorSystemRoot; |
| 31 @class DVTiPhoneSimulatorMessenger; | |
| 32 | |
| 33 @interface DVTPlatform : NSObject | |
| 34 + (BOOL)loadAllPlatformsReturningError:(id *)arg1; | |
| 35 @end | |
| 36 | |
| 37 @protocol OS_dispatch_source | |
| 38 @end | |
| 39 @protocol OS_dispatch_queue | |
| 40 @end | |
| 41 @class DVTDispatchLock; | |
| 42 @class DVTConfinementServiceConnection; | |
| 43 @class DVTTask; | |
| 31 | 44 |
| 32 @protocol DTiPhoneSimulatorSessionDelegate | 45 @protocol DTiPhoneSimulatorSessionDelegate |
| 33 - (void)session:(DTiPhoneSimulatorSession*)session | 46 - (void)session:(DTiPhoneSimulatorSession*)session |
| 34 didEndWithError:(NSError*)error; | 47 didEndWithError:(NSError*)error; |
| 35 - (void)session:(DTiPhoneSimulatorSession*)session | 48 - (void)session:(DTiPhoneSimulatorSession*)session |
| 36 didStart:(BOOL)started | 49 didStart:(BOOL)started |
| 37 withError:(NSError*)error; | 50 withError:(NSError*)error; |
| 38 @end | 51 @end |
| 39 | 52 |
| 40 #import "iPhoneSimulatorRemoteClient.h" | 53 #import "DVTiPhoneSimulatorRemoteClient.h" |
| 41 | 54 |
| 42 // An undocumented system log key included in messages from launchd. The value | 55 // An undocumented system log key included in messages from launchd. The value |
| 43 // is the PID of the process the message is about (as opposed to launchd's PID). | 56 // is the PID of the process the message is about (as opposed to launchd's PID). |
| 44 #define ASL_KEY_REF_PID "RefPID" | 57 #define ASL_KEY_REF_PID "RefPID" |
| 45 | 58 |
| 46 namespace { | 59 namespace { |
| 47 | 60 |
| 48 // Name of environment variables that control the user's home directory in the | 61 // Name of environment variables that control the user's home directory in the |
| 49 // simulator. | 62 // simulator. |
| 50 const char* const kUserHomeEnvVariable = "CFFIXED_USER_HOME"; | 63 const char* const kUserHomeEnvVariable = "CFFIXED_USER_HOME"; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 66 const NSTimeInterval kDefaultSessionStartTimeoutSeconds = 30; | 79 const NSTimeInterval kDefaultSessionStartTimeoutSeconds = 30; |
| 67 | 80 |
| 68 // While the simulated app is running, its stdout is redirected to a file which | 81 // While the simulated app is running, its stdout is redirected to a file which |
| 69 // is polled by iossim and written to iossim's stdout using the following | 82 // is polled by iossim and written to iossim's stdout using the following |
| 70 // polling interval. | 83 // polling interval. |
| 71 const NSTimeInterval kOutputPollIntervalSeconds = 0.1; | 84 const NSTimeInterval kOutputPollIntervalSeconds = 0.1; |
| 72 | 85 |
| 73 // The path within the developer dir of the private Simulator frameworks. | 86 // The path within the developer dir of the private Simulator frameworks. |
| 74 NSString* const kSimulatorFrameworkRelativePath = | 87 NSString* const kSimulatorFrameworkRelativePath = |
| 75 @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/" | 88 @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/" |
| 76 @"iPhoneSimulatorRemoteClient.framework"; | 89 @"DVTiPhoneSimulatorRemoteClient.framework"; |
| 90 NSString* const kDVTFoundationRelativePath = | |
| 91 @"../SharedFrameworks/DVTFoundation.framework"; | |
| 77 NSString* const kDevToolsFoundationRelativePath = | 92 NSString* const kDevToolsFoundationRelativePath = |
| 78 @"../OtherFrameworks/DevToolsFoundation.framework"; | 93 @"../OtherFrameworks/DevToolsFoundation.framework"; |
| 79 NSString* const kSimulatorRelativePath = | 94 NSString* const kSimulatorRelativePath = |
| 80 @"Platforms/iPhoneSimulator.platform/Developer/Applications/" | 95 @"Platforms/iPhoneSimulator.platform/Developer/Applications/" |
| 81 @"iPhone Simulator.app"; | 96 @"iPhone Simulator.app"; |
| 82 | 97 |
| 83 // Simulator Error String Key. This can be found by looking in the Simulator's | 98 // Simulator Error String Key. This can be found by looking in the Simulator's |
| 84 // Localizable.strings files. | 99 // Localizable.strings files. |
| 85 NSString* const kSimulatorAppQuitErrorKey = @"The simulated application quit."; | 100 NSString* const kSimulatorAppQuitErrorKey = @"The simulated application quit."; |
| 86 | 101 |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 293 objectAtIndex:0] intValue]; | 308 objectAtIndex:0] intValue]; |
| 294 if (majorVersion <= 6) { | 309 if (majorVersion <= 6) { |
| 295 // In iOS 6 and before, logging from the simulated apps went to the main | 310 // In iOS 6 and before, logging from the simulated apps went to the main |
| 296 // system logs, so use ASL to check if the simulated app exited abnormally | 311 // system logs, so use ASL to check if the simulated app exited abnormally |
| 297 // by looking for system log messages from launchd that refer to the | 312 // by looking for system log messages from launchd that refer to the |
| 298 // simulated app's PID. Limit query to messages in the last minute since | 313 // simulated app's PID. Limit query to messages in the last minute since |
| 299 // PIDs are cyclical. | 314 // PIDs are cyclical. |
| 300 aslmsg query = asl_new(ASL_TYPE_QUERY); | 315 aslmsg query = asl_new(ASL_TYPE_QUERY); |
| 301 asl_set_query(query, ASL_KEY_SENDER, "launchd", | 316 asl_set_query(query, ASL_KEY_SENDER, "launchd", |
| 302 ASL_QUERY_OP_EQUAL | ASL_QUERY_OP_SUBSTRING); | 317 ASL_QUERY_OP_EQUAL | ASL_QUERY_OP_SUBSTRING); |
| 303 asl_set_query(query, ASL_KEY_REF_PID, | 318 asl_set_query( |
| 304 [[[session simulatedApplicationPID] stringValue] UTF8String], | 319 query, |
| 305 ASL_QUERY_OP_EQUAL); | 320 ASL_KEY_REF_PID, |
| 321 [[NSString stringWithFormat:@"%d", [session simulatedApplicationPID]] | |
|
lliabraa
2013/12/12 15:01:15
why change from stringValue to stringWithFormat?
justincohen
2013/12/12 15:02:03
Because it's not a NSNumber anymore, it's an int.
TVL
2013/12/12 16:08:27
This whole thing would be less scary with a char[2
justincohen
2013/12/16 18:44:37
Done, converted to snprintf.
On 2013/12/12 16:08:
| |
| 322 UTF8String], | |
| 323 ASL_QUERY_OP_EQUAL); | |
| 306 asl_set_query(query, ASL_KEY_TIME, "-1m", ASL_QUERY_OP_GREATER_EQUAL); | 324 asl_set_query(query, ASL_KEY_TIME, "-1m", ASL_QUERY_OP_GREATER_EQUAL); |
| 307 | 325 |
| 308 // Log any messages found, and take note of any messages that may indicate | 326 // Log any messages found, and take note of any messages that may indicate |
| 309 // the app crashed or did not exit cleanly. | 327 // the app crashed or did not exit cleanly. |
| 310 aslresponse response = asl_search(NULL, query); | 328 aslresponse response = asl_search(NULL, query); |
| 311 aslmsg entry; | 329 aslmsg entry; |
| 312 while ((entry = aslresponse_next(response)) != NULL) { | 330 while ((entry = aslresponse_next(response)) != NULL) { |
| 313 const char* message = asl_get(entry, ASL_KEY_MSG); | 331 const char* message = asl_get(entry, ASL_KEY_MSG); |
| 314 LogWarning(@"Console message: %s", message); | 332 LogWarning(@"Console message: %s", message); |
| 315 // Some messages are harmless, so don't trigger a failure for them. | 333 // Some messages are harmless, so don't trigger a failure for them. |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 386 NSString* output = | 404 NSString* output = |
| 387 [[[NSString alloc] initWithData:outputData | 405 [[[NSString alloc] initWithData:outputData |
| 388 encoding:NSUTF8StringEncoding] autorelease]; | 406 encoding:NSUTF8StringEncoding] autorelease]; |
| 389 output = [output stringByTrimmingCharactersInSet: | 407 output = [output stringByTrimmingCharactersInSet: |
| 390 [NSCharacterSet whitespaceAndNewlineCharacterSet]]; | 408 [NSCharacterSet whitespaceAndNewlineCharacterSet]]; |
| 391 if ([output length] == 0) | 409 if ([output length] == 0) |
| 392 output = nil; | 410 output = nil; |
| 393 return output; | 411 return output; |
| 394 } | 412 } |
| 395 | 413 |
| 414 // Helper to find a class by name and die if it isn't found. | |
|
TVL
2013/12/12 16:08:27
any reason this got moved?
justincohen
2013/12/16 18:44:37
Forward declaration.
On 2013/12/12 16:08:27, TVL
| |
| 415 Class FindClassByName(NSString* nameOfClass) { | |
| 416 Class theClass = NSClassFromString(nameOfClass); | |
| 417 if (!theClass) { | |
| 418 LogError(@"Failed to find class %@ at runtime.", nameOfClass); | |
| 419 exit(kExitInitializationFailure); | |
| 420 } | |
| 421 return theClass; | |
| 422 } | |
| 423 | |
| 396 // Loads the Simulator framework from the given developer dir. | 424 // Loads the Simulator framework from the given developer dir. |
| 397 NSBundle* LoadSimulatorFramework(NSString* developerDir) { | 425 NSBundle* LoadSimulatorFramework(NSString* developerDir) { |
| 398 // The Simulator framework depends on some of the other Xcode private | 426 // The Simulator framework depends on some of the other Xcode private |
| 399 // frameworks; manually load them first so everything can be linked up. | 427 // frameworks; manually load them first so everything can be linked up. |
| 428 NSString* dvtFoundationPath = [developerDir | |
| 429 stringByAppendingPathComponent:kDVTFoundationRelativePath]; | |
| 430 NSBundle* dvtFoundationBundle = | |
| 431 [NSBundle bundleWithPath:dvtFoundationPath]; | |
| 432 if (![dvtFoundationBundle load]) | |
| 433 return nil; | |
| 434 | |
| 400 NSString* devToolsFoundationPath = [developerDir | 435 NSString* devToolsFoundationPath = [developerDir |
| 401 stringByAppendingPathComponent:kDevToolsFoundationRelativePath]; | 436 stringByAppendingPathComponent:kDevToolsFoundationRelativePath]; |
| 402 NSBundle* devToolsFoundationBundle = | 437 NSBundle* devToolsFoundationBundle = |
| 403 [NSBundle bundleWithPath:devToolsFoundationPath]; | 438 [NSBundle bundleWithPath:devToolsFoundationPath]; |
| 404 if (![devToolsFoundationBundle load]) | 439 if (![devToolsFoundationBundle load]) |
| 405 return nil; | 440 return nil; |
| 441 | |
| 442 // Prime DVTPlatform. | |
| 443 Class DVTPlatformClass = FindClassByName(@"DVTPlatform"); | |
| 444 [DVTPlatformClass loadAllPlatformsReturningError:nil]; | |
|
TVL
2013/12/12 16:08:27
You should check the bool return result, and would
justincohen
2013/12/16 18:44:37
Done.
| |
| 445 | |
| 406 NSString* simBundlePath = [developerDir | 446 NSString* simBundlePath = [developerDir |
| 407 stringByAppendingPathComponent:kSimulatorFrameworkRelativePath]; | 447 stringByAppendingPathComponent:kSimulatorFrameworkRelativePath]; |
| 408 NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath]; | 448 NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath]; |
| 409 if (![simBundle load]) | 449 if (![simBundle load]) |
| 410 return nil; | 450 return nil; |
| 411 return simBundle; | 451 return simBundle; |
| 412 } | 452 } |
| 413 | 453 |
| 414 // Helper to find a class by name and die if it isn't found. | |
| 415 Class FindClassByName(NSString* nameOfClass) { | |
| 416 Class theClass = NSClassFromString(nameOfClass); | |
| 417 if (!theClass) { | |
| 418 LogError(@"Failed to find class %@ at runtime.", nameOfClass); | |
| 419 exit(kExitInitializationFailure); | |
| 420 } | |
| 421 return theClass; | |
| 422 } | |
| 423 | |
| 424 // Converts the given app path to an application spec, which requires an | 454 // Converts the given app path to an application spec, which requires an |
| 425 // absolute path. | 455 // absolute path. |
| 426 DTiPhoneSimulatorApplicationSpecifier* BuildAppSpec(NSString* appPath) { | 456 DTiPhoneSimulatorApplicationSpecifier* BuildAppSpec(NSString* appPath) { |
| 427 Class applicationSpecifierClass = | 457 Class applicationSpecifierClass = |
| 428 FindClassByName(@"DTiPhoneSimulatorApplicationSpecifier"); | 458 FindClassByName(@"DTiPhoneSimulatorApplicationSpecifier"); |
| 429 if (![appPath isAbsolutePath]) { | 459 if (![appPath isAbsolutePath]) { |
| 430 NSString* cwd = [[NSFileManager defaultManager] currentDirectoryPath]; | 460 NSString* cwd = [[NSFileManager defaultManager] currentDirectoryPath]; |
| 431 appPath = [cwd stringByAppendingPathComponent:appPath]; | 461 appPath = [cwd stringByAppendingPathComponent:appPath]; |
| 432 } | 462 } |
| 433 appPath = [appPath stringByStandardizingPath]; | 463 appPath = [appPath stringByStandardizingPath]; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 447 } | 477 } |
| 448 | 478 |
| 449 // Builds a config object for starting the specified app. | 479 // Builds a config object for starting the specified app. |
| 450 DTiPhoneSimulatorSessionConfig* BuildSessionConfig( | 480 DTiPhoneSimulatorSessionConfig* BuildSessionConfig( |
| 451 DTiPhoneSimulatorApplicationSpecifier* appSpec, | 481 DTiPhoneSimulatorApplicationSpecifier* appSpec, |
| 452 DTiPhoneSimulatorSystemRoot* systemRoot, | 482 DTiPhoneSimulatorSystemRoot* systemRoot, |
| 453 NSString* stdoutPath, | 483 NSString* stdoutPath, |
| 454 NSString* stderrPath, | 484 NSString* stderrPath, |
| 455 NSArray* appArgs, | 485 NSArray* appArgs, |
| 456 NSDictionary* appEnv, | 486 NSDictionary* appEnv, |
| 457 NSNumber* deviceFamily) { | 487 NSNumber* deviceFamily, |
| 488 NSString* deviceName) { | |
| 458 Class sessionConfigClass = FindClassByName(@"DTiPhoneSimulatorSessionConfig"); | 489 Class sessionConfigClass = FindClassByName(@"DTiPhoneSimulatorSessionConfig"); |
| 459 DTiPhoneSimulatorSessionConfig* sessionConfig = | 490 DTiPhoneSimulatorSessionConfig* sessionConfig = |
| 460 [[[sessionConfigClass alloc] init] autorelease]; | 491 [[[sessionConfigClass alloc] init] autorelease]; |
| 461 sessionConfig.applicationToSimulateOnStart = appSpec; | 492 sessionConfig.applicationToSimulateOnStart = appSpec; |
| 462 sessionConfig.simulatedSystemRoot = systemRoot; | 493 sessionConfig.simulatedSystemRoot = systemRoot; |
| 463 sessionConfig.localizedClientName = @"chromium"; | 494 sessionConfig.localizedClientName = @"chromium"; |
| 464 sessionConfig.simulatedApplicationStdErrPath = stderrPath; | 495 sessionConfig.simulatedApplicationStdErrPath = stderrPath; |
| 465 sessionConfig.simulatedApplicationStdOutPath = stdoutPath; | 496 sessionConfig.simulatedApplicationStdOutPath = stdoutPath; |
| 466 sessionConfig.simulatedApplicationLaunchArgs = appArgs; | 497 sessionConfig.simulatedApplicationLaunchArgs = appArgs; |
| 467 sessionConfig.simulatedApplicationLaunchEnvironment = appEnv; | 498 sessionConfig.simulatedApplicationLaunchEnvironment = appEnv; |
| 499 sessionConfig.simulatedDeviceInfoName = deviceName; | |
| 468 sessionConfig.simulatedDeviceFamily = deviceFamily; | 500 sessionConfig.simulatedDeviceFamily = deviceFamily; |
| 469 return sessionConfig; | 501 return sessionConfig; |
| 470 } | 502 } |
| 471 | 503 |
| 472 // Builds a simulator session that will use the given delegate. | 504 // Builds a simulator session that will use the given delegate. |
| 473 DTiPhoneSimulatorSession* BuildSession(SimulatorDelegate* delegate) { | 505 DTiPhoneSimulatorSession* BuildSession(SimulatorDelegate* delegate) { |
| 474 Class sessionClass = FindClassByName(@"DTiPhoneSimulatorSession"); | 506 Class sessionClass = FindClassByName(@"DTiPhoneSimulatorSession"); |
| 475 DTiPhoneSimulatorSession* session = | 507 DTiPhoneSimulatorSession* session = |
| 476 [[[sessionClass alloc] init] autorelease]; | 508 [[[sessionClass alloc] init] autorelease]; |
| 477 session.delegate = delegate; | 509 session.delegate = delegate; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 522 } | 554 } |
| 523 } | 555 } |
| 524 | 556 |
| 525 return YES; | 557 return YES; |
| 526 } | 558 } |
| 527 | 559 |
| 528 // Creates the necessary directory structure under the given user home directory | 560 // Creates the necessary directory structure under the given user home directory |
| 529 // path, then sets the path in the appropriate environment variable. | 561 // path, then sets the path in the appropriate environment variable. |
| 530 // Returns YES if successful, NO if unable to create or initialize the given | 562 // Returns YES if successful, NO if unable to create or initialize the given |
| 531 // directory. | 563 // directory. |
| 532 BOOL InitializeSimulatorUserHome(NSString* userHomePath, NSString* deviceName) { | 564 BOOL InitializeSimulatorUserHome(NSString* userHomePath) { |
| 533 if (!CreateHomeDirSubDirs(userHomePath)) | 565 if (!CreateHomeDirSubDirs(userHomePath)) |
| 534 return NO; | 566 return NO; |
| 535 | 567 |
| 536 // Set the device to simulate. Note that the iOS Simulator must not be running | |
| 537 // for this setting to take effect. | |
| 538 CFStringRef iPhoneSimulatorAppID = CFSTR("com.apple.iphonesimulator"); | |
| 539 CFPreferencesSetAppValue(CFSTR("SimulateDevice"), | |
| 540 deviceName, | |
| 541 iPhoneSimulatorAppID); | |
| 542 CFPreferencesAppSynchronize(iPhoneSimulatorAppID); | |
| 543 | |
| 544 // Update the environment to use the specified directory as the user home | 568 // Update the environment to use the specified directory as the user home |
| 545 // directory. | 569 // directory. |
| 546 // Note: the third param of setenv specifies whether or not to overwrite the | 570 // Note: the third param of setenv specifies whether or not to overwrite the |
| 547 // variable's value if it has already been set. | 571 // variable's value if it has already been set. |
| 548 if ((setenv(kUserHomeEnvVariable, [userHomePath UTF8String], YES) == -1) || | 572 if ((setenv(kUserHomeEnvVariable, [userHomePath UTF8String], YES) == -1) || |
| 549 (setenv(kHomeEnvVariable, [userHomePath UTF8String], YES) == -1)) { | 573 (setenv(kHomeEnvVariable, [userHomePath UTF8String], YES) == -1)) { |
| 550 LogError(@"Unable to set environment variables for home directory."); | 574 LogError(@"Unable to set environment variables for home directory."); |
| 551 return NO; | 575 return NO; |
| 552 } | 576 } |
| 553 | 577 |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 721 if (!simHomePath) { | 745 if (!simHomePath) { |
| 722 NSString* dirNameTemplate = | 746 NSString* dirNameTemplate = |
| 723 [NSString stringWithFormat:@"iossim-%@-%@-XXXXXX", appName, deviceName]; | 747 [NSString stringWithFormat:@"iossim-%@-%@-XXXXXX", appName, deviceName]; |
| 724 simHomePath = CreateTempDirectory(dirNameTemplate); | 748 simHomePath = CreateTempDirectory(dirNameTemplate); |
| 725 if (!simHomePath) { | 749 if (!simHomePath) { |
| 726 LogError(@"Unable to create unique directory for template %@", | 750 LogError(@"Unable to create unique directory for template %@", |
| 727 dirNameTemplate); | 751 dirNameTemplate); |
| 728 exit(kExitInitializationFailure); | 752 exit(kExitInitializationFailure); |
| 729 } | 753 } |
| 730 } | 754 } |
| 731 if (!InitializeSimulatorUserHome(simHomePath, deviceName)) { | 755 if (!InitializeSimulatorUserHome(simHomePath)) { |
| 732 LogError(@"Unable to initialize home directory for simulator: %@", | 756 LogError(@"Unable to initialize home directory for simulator: %@", |
| 733 simHomePath); | 757 simHomePath); |
| 734 exit(kExitInitializationFailure); | 758 exit(kExitInitializationFailure); |
| 735 } | 759 } |
| 736 | 760 |
| 737 // Create the config and simulator session. | 761 // Create the config and simulator session. |
| 738 DTiPhoneSimulatorSessionConfig* config = BuildSessionConfig(appSpec, | 762 DTiPhoneSimulatorSessionConfig* config = BuildSessionConfig(appSpec, |
| 739 systemRoot, | 763 systemRoot, |
| 740 stdioPath, | 764 stdioPath, |
| 741 stdioPath, | 765 stdioPath, |
| 742 appArgs, | 766 appArgs, |
| 743 appEnv, | 767 appEnv, |
| 744 deviceFamily); | 768 deviceFamily, |
| 769 deviceName); | |
| 745 SimulatorDelegate* delegate = | 770 SimulatorDelegate* delegate = |
| 746 [[[SimulatorDelegate alloc] initWithStdioPath:stdioPath | 771 [[[SimulatorDelegate alloc] initWithStdioPath:stdioPath |
| 747 developerDir:developerDir | 772 developerDir:developerDir |
| 748 simulatorHome:simHomePath] autorelease]; | 773 simulatorHome:simHomePath] autorelease]; |
| 749 DTiPhoneSimulatorSession* session = BuildSession(delegate); | 774 DTiPhoneSimulatorSession* session = BuildSession(delegate); |
| 750 | 775 |
| 751 // Start the simulator session. | 776 // Start the simulator session. |
| 752 NSError* error; | 777 NSError* error; |
| 753 BOOL started = [session requestStartWithConfig:config | 778 BOOL started = [session requestStartWithConfig:config |
| 754 timeout:sessionStartTimeout | 779 timeout:sessionStartTimeout |
| 755 error:&error]; | 780 error:&error]; |
| 756 | 781 |
| 757 // Spin the runtime indefinitely. When the delegate gets the message that the | 782 // Spin the runtime indefinitely. When the delegate gets the message that the |
| 758 // app has quit it will exit this program. | 783 // app has quit it will exit this program. |
| 759 if (started) { | 784 if (started) { |
| 760 [[NSRunLoop mainRunLoop] run]; | 785 [[NSRunLoop mainRunLoop] run]; |
| 761 } else { | 786 } else { |
| 762 LogError(@"Simulator failed request to start: \"%@\" (%@:%ld)", | 787 LogError(@"Simulator failed request to start: \"%@\" (%@:%ld)", |
| 763 [error localizedDescription], | 788 [error localizedDescription], |
| 764 [error domain], static_cast<long int>([error code])); | 789 [error domain], static_cast<long int>([error code])); |
| 765 } | 790 } |
| 766 | 791 |
| 767 // Note that this code is only executed if the simulator fails to start | 792 // Note that this code is only executed if the simulator fails to start |
| 768 // because once the main run loop is started, only the delegate calling | 793 // because once the main run loop is started, only the delegate calling |
| 769 // exit() will end the program. | 794 // exit() will end the program. |
| 770 [pool drain]; | 795 [pool drain]; |
| 771 return kExitFailure; | 796 return kExitFailure; |
| 772 } | 797 } |
| OLD | NEW |