| 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 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 // Creates the necessary directory structure under the given user home directory | 444 // Creates the necessary directory structure under the given user home directory |
| 445 // path. | 445 // path. |
| 446 // Returns YES if successful, NO if unable to create the directories. | 446 // Returns YES if successful, NO if unable to create the directories. |
| 447 BOOL CreateHomeDirSubDirs(NSString* userHomePath) { | 447 BOOL CreateHomeDirSubDirs(NSString* userHomePath) { |
| 448 NSFileManager* fileManager = [NSFileManager defaultManager]; | 448 NSFileManager* fileManager = [NSFileManager defaultManager]; |
| 449 | 449 |
| 450 // Create user home and subdirectories. | 450 // Create user home and subdirectories. |
| 451 NSArray* subDirsToCreate = [NSArray arrayWithObjects: | 451 NSArray* subDirsToCreate = [NSArray arrayWithObjects: |
| 452 @"Documents", | 452 @"Documents", |
| 453 @"Library/Caches", | 453 @"Library/Caches", |
| 454 @"Library/Preferences", |
| 454 nil]; | 455 nil]; |
| 455 for (NSString* subDir in subDirsToCreate) { | 456 for (NSString* subDir in subDirsToCreate) { |
| 456 NSString* path = [userHomePath stringByAppendingPathComponent:subDir]; | 457 NSString* path = [userHomePath stringByAppendingPathComponent:subDir]; |
| 457 NSError* error; | 458 NSError* error; |
| 458 if (![fileManager createDirectoryAtPath:path | 459 if (![fileManager createDirectoryAtPath:path |
| 459 withIntermediateDirectories:YES | 460 withIntermediateDirectories:YES |
| 460 attributes:nil | 461 attributes:nil |
| 461 error:&error]) { | 462 error:&error]) { |
| 462 LogError(@"Unable to create directory: %@. Error: %@", | 463 LogError(@"Unable to create directory: %@. Error: %@", |
| 463 path, [error localizedDescription]); | 464 path, [error localizedDescription]); |
| 464 return NO; | 465 return NO; |
| 465 } | 466 } |
| 466 } | 467 } |
| 467 | 468 |
| 468 return YES; | 469 return YES; |
| 469 } | 470 } |
| 470 | 471 |
| 471 // Creates the necessary directory structure under the given user home directory | 472 // Creates the necessary directory structure under the given user home directory |
| 472 // path, then sets the path in the appropriate environment variable. | 473 // path, then sets the path in the appropriate environment variable. |
| 473 // Returns YES if successful, NO if unable to create or initialize the given | 474 // Returns YES if successful, NO if unable to create or initialize the given |
| 474 // directory. | 475 // directory. |
| 475 BOOL InitializeSimulatorUserHome(NSString* userHomePath) { | 476 BOOL InitializeSimulatorUserHome(NSString* userHomePath, NSString* deviceName) { |
| 476 if (!CreateHomeDirSubDirs(userHomePath)) | 477 if (!CreateHomeDirSubDirs(userHomePath)) |
| 477 return NO; | 478 return NO; |
| 478 | 479 |
| 480 // Set the device to simulate. Note that the iOS Simulator must not be running |
| 481 // for this setting to take effect. |
| 482 NSMutableDictionary* plistDict = |
| 483 [NSMutableDictionary dictionaryWithObject:deviceName |
| 484 forKey:@"SimulateDevice"]; |
| 485 NSString* plistPath = @"Library/Preferences/com.apple.iphonesimulator.plist"; |
| 486 [plistDict writeToFile:[userHomePath stringByAppendingPathComponent:plistPath] |
| 487 atomically:YES]; |
| 488 |
| 479 // Update the environment to use the specified directory as the user home | 489 // Update the environment to use the specified directory as the user home |
| 480 // directory. | 490 // directory. |
| 481 // Note: the third param of setenv specifies whether or not to overwrite the | 491 // Note: the third param of setenv specifies whether or not to overwrite the |
| 482 // variable's value if it has already been set. | 492 // variable's value if it has already been set. |
| 483 if ((setenv(kUserHomeEnvVariable, [userHomePath UTF8String], YES) == -1) || | 493 if ((setenv(kUserHomeEnvVariable, [userHomePath UTF8String], YES) == -1) || |
| 484 (setenv(kHomeEnvVariable, [userHomePath UTF8String], YES) == -1)) { | 494 (setenv(kHomeEnvVariable, [userHomePath UTF8String], YES) == -1)) { |
| 485 LogError(@"Unable to set environment variables for home directory."); | 495 LogError(@"Unable to set environment variables for home directory."); |
| 486 return NO; | 496 return NO; |
| 487 } | 497 } |
| 488 | 498 |
| 489 return YES; | 499 return YES; |
| 490 } | 500 } |
| 491 | 501 |
| 502 // Performs a case-insensitive search to see if |stringToSearch| begins with |
| 503 // |prefixToFind|. Returns true if a match is found. |
| 504 BOOL CaseInsensitivePrefixSearch(NSString* stringToSearch, |
| 505 NSString* prefixToFind) { |
| 506 NSStringCompareOptions options = (NSAnchoredSearch | NSCaseInsensitiveSearch); |
| 507 NSRange range = [stringToSearch rangeOfString:prefixToFind |
| 508 options:options]; |
| 509 return range.location != 0; |
| 510 } |
| 511 |
| 492 // Prints the usage information to stderr. | 512 // Prints the usage information to stderr. |
| 493 void PrintUsage() { | 513 void PrintUsage() { |
| 494 fprintf(stderr, "Usage: iossim [-d device] [-s sdkVersion] [-u homeDir] " | 514 fprintf(stderr, "Usage: iossim [-d device] [-s sdkVersion] [-u homeDir] " |
| 495 "[-e envKey=value]* [-t startupTimeout] <appPath> [<appArgs>]\n" | 515 "[-e envKey=value]* [-t startupTimeout] <appPath> [<appArgs>]\n" |
| 496 " where <appPath> is the path to the .app directory and appArgs are any" | 516 " where <appPath> is the path to the .app directory and appArgs are any" |
| 497 " arguments to send the simulated app.\n" | 517 " arguments to send the simulated app.\n" |
| 498 "\n" | 518 "\n" |
| 499 "Options:\n" | 519 "Options:\n" |
| 500 " -d Specifies the device (either 'iPhone' or 'iPad')." | 520 " -d Specifies the device (must be one of the values from the iOS" |
| 501 " Defaults to 'iPhone'.\n" | 521 " Simulator's Hardware -> Device menu. Defaults to 'iPhone'.\n" |
| 502 " -s Specifies the SDK version to use (e.g '4.3')." | 522 " -s Specifies the SDK version to use (e.g '4.3')." |
| 503 " Will use system default if not specified.\n" | 523 " Will use system default if not specified.\n" |
| 504 " -u Specifies a user home directory for the simulator." | 524 " -u Specifies a user home directory for the simulator." |
| 505 " Will create a new directory if not specified.\n" | 525 " Will create a new directory if not specified.\n" |
| 506 " -e Specifies an environment key=value pair that will be" | 526 " -e Specifies an environment key=value pair that will be" |
| 507 " set in the simulated application's environment.\n" | 527 " set in the simulated application's environment.\n" |
| 508 " -t Specifies the session startup timeout (in seconds)." | 528 " -t Specifies the session startup timeout (in seconds)." |
| 509 " Defaults to %d.\n", | 529 " Defaults to %d.\n", |
| 510 static_cast<int>(kDefaultSessionStartTimeoutSeconds)); | 530 static_cast<int>(kDefaultSessionStartTimeoutSeconds)); |
| 511 } | 531 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 if (!systemRoot) { | 643 if (!systemRoot) { |
| 624 LogError(@"Invalid SDK version: %@", sdkVersion); | 644 LogError(@"Invalid SDK version: %@", sdkVersion); |
| 625 exit(EXIT_FAILURE); | 645 exit(EXIT_FAILURE); |
| 626 } | 646 } |
| 627 | 647 |
| 628 // Get the paths for stdout and stderr so the simulated app's output will show | 648 // Get the paths for stdout and stderr so the simulated app's output will show |
| 629 // up in the caller's stdout/stderr. | 649 // up in the caller's stdout/stderr. |
| 630 NSString* outputDir = CreateTempDirectory(@"iossim-XXXXXX"); | 650 NSString* outputDir = CreateTempDirectory(@"iossim-XXXXXX"); |
| 631 NSString* stdioPath = [outputDir stringByAppendingPathComponent:@"stdio.txt"]; | 651 NSString* stdioPath = [outputDir stringByAppendingPathComponent:@"stdio.txt"]; |
| 632 | 652 |
| 633 // Make sure the device name is legit. | 653 // Determine the deviceFamily based on the deviceName |
| 634 NSNumber* deviceFamily = nil; | 654 NSNumber* deviceFamily = nil; |
| 635 if (!deviceName || | 655 if (!deviceName || CaseInsensitivePrefixSearch(deviceName, @"iPhone")) { |
| 636 [@"iPhone" caseInsensitiveCompare:deviceName] == NSOrderedSame) { | |
| 637 deviceFamily = [NSNumber numberWithInt:kIPhoneFamily]; | 656 deviceFamily = [NSNumber numberWithInt:kIPhoneFamily]; |
| 638 } else if ([@"iPad" caseInsensitiveCompare:deviceName] == NSOrderedSame) { | 657 } else if (CaseInsensitivePrefixSearch(deviceName, @"iPad")) { |
| 639 deviceFamily = [NSNumber numberWithInt:kIPadFamily]; | 658 deviceFamily = [NSNumber numberWithInt:kIPadFamily]; |
| 640 } else { | 659 } else { |
| 641 LogError(@"Invalid device name: %@", deviceName); | 660 LogError(@"Invalid device name: %@. Must begin with 'iPhone' or 'iPad'", |
| 661 deviceName); |
| 642 exit(EXIT_FAILURE); | 662 exit(EXIT_FAILURE); |
| 643 } | 663 } |
| 644 | 664 |
| 645 // Set up the user home directory for the simulator | 665 // Set up the user home directory for the simulator |
| 646 if (!simHomePath) { | 666 if (!simHomePath) { |
| 647 NSString* dirNameTemplate = | 667 NSString* dirNameTemplate = |
| 648 [NSString stringWithFormat:@"iossim-%@-%@-XXXXXX", appName, deviceName]; | 668 [NSString stringWithFormat:@"iossim-%@-%@-XXXXXX", appName, deviceName]; |
| 649 simHomePath = CreateTempDirectory(dirNameTemplate); | 669 simHomePath = CreateTempDirectory(dirNameTemplate); |
| 650 if (!simHomePath) { | 670 if (!simHomePath) { |
| 651 LogError(@"Unable to create unique directory for template %@", | 671 LogError(@"Unable to create unique directory for template %@", |
| 652 dirNameTemplate); | 672 dirNameTemplate); |
| 653 exit(EXIT_FAILURE); | 673 exit(EXIT_FAILURE); |
| 654 } | 674 } |
| 655 } | 675 } |
| 656 if (!InitializeSimulatorUserHome(simHomePath)) { | 676 if (!InitializeSimulatorUserHome(simHomePath, deviceName)) { |
| 657 LogError(@"Unable to initialize home directory for simulator: %@", | 677 LogError(@"Unable to initialize home directory for simulator: %@", |
| 658 simHomePath); | 678 simHomePath); |
| 659 exit(EXIT_FAILURE); | 679 exit(EXIT_FAILURE); |
| 660 } | 680 } |
| 661 | 681 |
| 662 // Create the config and simulator session. | 682 // Create the config and simulator session. |
| 663 DTiPhoneSimulatorSessionConfig* config = BuildSessionConfig(appSpec, | 683 DTiPhoneSimulatorSessionConfig* config = BuildSessionConfig(appSpec, |
| 664 systemRoot, | 684 systemRoot, |
| 665 stdioPath, | 685 stdioPath, |
| 666 stdioPath, | 686 stdioPath, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 687 [error localizedDescription], | 707 [error localizedDescription], |
| 688 [error domain], static_cast<long int>([error code])); | 708 [error domain], static_cast<long int>([error code])); |
| 689 } | 709 } |
| 690 | 710 |
| 691 // Note that this code is only executed if the simulator fails to start | 711 // Note that this code is only executed if the simulator fails to start |
| 692 // because once the main run loop is started, only the delegate calling | 712 // because once the main run loop is started, only the delegate calling |
| 693 // exit() will end the program. | 713 // exit() will end the program. |
| 694 [pool drain]; | 714 [pool drain]; |
| 695 return EXIT_FAILURE; | 715 return EXIT_FAILURE; |
| 696 } | 716 } |
| OLD | NEW |