Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(422)

Side by Side Diff: testing/iossim/iossim.mm

Issue 1796093003: Remove support for old version of Xcode from iossim. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase on origin/master and remove unused const variables Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « testing/iossim/iossim.gyp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <asl.h> 5 #include <asl.h>
6 #import <Foundation/Foundation.h> 6 #import <Foundation/Foundation.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
11 // An executable (iossim) that runs an app in the iOS Simulator. 11 // An executable (iossim) that runs an app in the iOS Simulator.
12 // Run 'iossim -h' for usage information. 12 // Run 'iossim -h' for usage information.
13 // 13 //
14 // For best results, the iOS Simulator application should not be running when 14 // For best results, the iOS Simulator application should not be running when
15 // iossim is invoked. 15 // iossim is invoked.
16 // 16 //
17 // Headers for iPhoneSimulatorRemoteClient and other frameworks used in this 17 // Headers for iPhoneSimulatorRemoteClient and other frameworks used in this
18 // tool are generated by class-dump, via GYP. 18 // tool are generated by class-dump, via GYP.
19 // (class-dump is available at http://www.codethecode.com/projects/class-dump/) 19 // (class-dump is available at http://www.codethecode.com/projects/class-dump/)
20 // 20 //
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. 22 // compile.
23 23
24 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed
25 // (crbug.com/385030).
26 #if defined(IOSSIM_USE_XCODE_6)
27 @class DVTStackBacktrace; 24 @class DVTStackBacktrace;
28 #import "DVTFoundation.h" 25 #import "DVTFoundation.h"
29 #endif // IOSSIM_USE_XCODE_6
30 26
31 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed
32 // (crbug.com/385030).
33 #if defined(IOSSIM_USE_XCODE_6)
34 @protocol SimBridge; 27 @protocol SimBridge;
35 @class DVTSimulatorApplication; 28 @class DVTSimulatorApplication;
36 @class SimDeviceSet; 29 @class SimDeviceSet;
37 @class SimDeviceType; 30 @class SimDeviceType;
38 @class SimProfilesPathMonitor; 31 @class SimProfilesPathMonitor;
39 @class SimRuntime; 32 @class SimRuntime;
40 @class SimServiceConnectionManager; 33 @class SimServiceConnectionManager;
41 #import "CoreSimulator.h" 34 #import "CoreSimulator.h"
42 #endif // IOSSIM_USE_XCODE_6
43 35
44 @interface DVTPlatform : NSObject 36 @interface DVTPlatform : NSObject
45 + (BOOL)loadAllPlatformsReturningError:(id*)arg1; 37 + (BOOL)loadAllPlatformsReturningError:(id*)arg1;
46 @end 38 @end
47 @class DTiPhoneSimulatorApplicationSpecifier; 39 @class DTiPhoneSimulatorApplicationSpecifier;
48 @class DTiPhoneSimulatorSession; 40 @class DTiPhoneSimulatorSession;
49 @class DTiPhoneSimulatorSessionConfig; 41 @class DTiPhoneSimulatorSessionConfig;
50 @class DTiPhoneSimulatorSystemRoot; 42 @class DTiPhoneSimulatorSystemRoot;
51 @class DVTConfinementServiceConnection; 43 @class DVTConfinementServiceConnection;
52 @class DVTDispatchLock; 44 @class DVTDispatchLock;
(...skipping 17 matching lines...) Expand all
70 // is the PID of the process the message is about (as opposed to launchd's PID). 62 // is the PID of the process the message is about (as opposed to launchd's PID).
71 #define ASL_KEY_REF_PID "RefPID" 63 #define ASL_KEY_REF_PID "RefPID"
72 64
73 namespace { 65 namespace {
74 66
75 // Name of environment variables that control the user's home directory in the 67 // Name of environment variables that control the user's home directory in the
76 // simulator. 68 // simulator.
77 const char* const kUserHomeEnvVariable = "CFFIXED_USER_HOME"; 69 const char* const kUserHomeEnvVariable = "CFFIXED_USER_HOME";
78 const char* const kHomeEnvVariable = "HOME"; 70 const char* const kHomeEnvVariable = "HOME";
79 71
80 // Device family codes for iPhone and iPad.
81 const int kIPhoneFamily = 1;
82 const int kIPadFamily = 2;
83
84 // Max number of seconds to wait for the simulator session to start. 72 // Max number of seconds to wait for the simulator session to start.
85 // This timeout must allow time to start up iOS Simulator, install the app 73 // This timeout must allow time to start up iOS Simulator, install the app
86 // and perform any other black magic that is encoded in the 74 // and perform any other black magic that is encoded in the
87 // iPhoneSimulatorRemoteClient framework to kick things off. Normal start up 75 // iPhoneSimulatorRemoteClient framework to kick things off. Normal start up
88 // time is only a couple seconds but machine load, disk caches, etc., can all 76 // time is only a couple seconds but machine load, disk caches, etc., can all
89 // affect startup time in the wild so the timeout needs to be fairly generous. 77 // affect startup time in the wild so the timeout needs to be fairly generous.
90 // If this timeout occurs iossim will likely exit with non-zero status; the 78 // If this timeout occurs iossim will likely exit with non-zero status; the
91 // exception being if the app is invoked and completes execution before the 79 // exception being if the app is invoked and completes execution before the
92 // session is started (this case is handled in session:didStart:withError). 80 // session is started (this case is handled in session:didStart:withError).
93 const NSTimeInterval kDefaultSessionStartTimeoutSeconds = 30; 81 const NSTimeInterval kDefaultSessionStartTimeoutSeconds = 30;
(...skipping 17 matching lines...) Expand all
111 99
112 const char* gToolName = "iossim"; 100 const char* gToolName = "iossim";
113 101
114 // Exit status codes. 102 // Exit status codes.
115 const int kExitSuccess = EXIT_SUCCESS; 103 const int kExitSuccess = EXIT_SUCCESS;
116 const int kExitFailure = EXIT_FAILURE; 104 const int kExitFailure = EXIT_FAILURE;
117 const int kExitInvalidArguments = 2; 105 const int kExitInvalidArguments = 2;
118 const int kExitInitializationFailure = 3; 106 const int kExitInitializationFailure = 3;
119 const int kExitAppFailedToStart = 4; 107 const int kExitAppFailedToStart = 4;
120 const int kExitAppCrashed = 5; 108 const int kExitAppCrashed = 5;
121 const int kExitUnsupportedXcodeVersion = 6;
122 109
123 void LogError(NSString* format, ...) { 110 void LogError(NSString* format, ...) {
124 va_list list; 111 va_list list;
125 va_start(list, format); 112 va_start(list, format);
126 113
127 NSString* message = 114 NSString* message =
128 [[[NSString alloc] initWithFormat:format arguments:list] autorelease]; 115 [[[NSString alloc] initWithFormat:format arguments:list] autorelease];
129 116
130 fprintf(stderr, "%s: ERROR: %s\n", gToolName, [message UTF8String]); 117 fprintf(stderr, "%s: ERROR: %s\n", gToolName, [message UTF8String]);
131 fflush(stderr); 118 fflush(stderr);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 LogError(@"Task '%@ %@' exited with return code %d.", 165 LogError(@"Task '%@ %@' exited with return code %d.",
179 toolPath, 166 toolPath,
180 [args componentsJoinedByString:@" "], 167 [args componentsJoinedByString:@" "],
181 [task terminationStatus]); 168 [task terminationStatus]);
182 return nil; 169 return nil;
183 } 170 }
184 return [[[NSString alloc] initWithData:outputData 171 return [[[NSString alloc] initWithData:outputData
185 encoding:NSUTF8StringEncoding] autorelease]; 172 encoding:NSUTF8StringEncoding] autorelease];
186 } 173 }
187 174
188 // Finds the Xcode version via xcodebuild -version. Output from xcodebuild is
189 // expected to look like:
190 // Xcode <version>
191 // Build version 5B130a
192 // where <version> is the string returned by this function (e.g. 6.0).
193 NSString* FindXcodeVersion() {
194 NSString* output = GetOutputFromTask(@"/usr/bin/xcodebuild",
195 @[ @"-version" ]);
196 // Scan past the "Xcode ", then scan the rest of the line into |version|.
197 NSScanner* scanner = [NSScanner scannerWithString:output];
198 BOOL valid = [scanner scanString:@"Xcode " intoString:NULL];
199 NSString* version;
200 valid =
201 [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet]
202 intoString:&version];
203 if (!valid) {
204 LogError(@"Unable to find Xcode version. 'xcodebuild -version' "
205 @"returned \n%@", output);
206 return nil;
207 }
208 return version;
209 }
210
211 // Returns true if iossim is running with Xcode 6 or later installed on the
212 // host.
213 BOOL IsRunningWithXcode6OrLater() {
214 static NSString* xcodeVersion = FindXcodeVersion();
215 if (!xcodeVersion) {
216 return false;
217 }
218 NSArray* components = [xcodeVersion componentsSeparatedByString:@"."];
219 if ([components count] < 1) {
220 return false;
221 }
222 NSInteger majorVersion = [[components objectAtIndex:0] integerValue];
223 return majorVersion >= 6;
224 }
225
226 // Prints supported devices and SDKs. 175 // Prints supported devices and SDKs.
227 void PrintSupportedDevices() { 176 void PrintSupportedDevices() {
228 if (IsRunningWithXcode6OrLater()) { 177 printf("Supported device/SDK combinations:\n");
229 #if defined(IOSSIM_USE_XCODE_6) 178 Class simDeviceSetClass = FindClassByName(@"SimDeviceSet");
230 printf("Supported device/SDK combinations:\n"); 179 id deviceSet =
231 Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); 180 [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]];
232 id deviceSet = 181 for (id simDevice in [deviceSet availableDevices]) {
233 [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; 182 NSString* deviceInfo =
234 for (id simDevice in [deviceSet availableDevices]) { 183 [NSString stringWithFormat:@" -d '%@' -s '%@'\n",
235 NSString* deviceInfo = 184 [simDevice name], [[simDevice runtime] versionString]];
236 [NSString stringWithFormat:@" -d '%@' -s '%@'\n", 185 printf("%s", [deviceInfo UTF8String]);
237 [simDevice name], [[simDevice runtime] versionString]];
238 printf("%s", [deviceInfo UTF8String]);
239 }
240 #endif // IOSSIM_USE_XCODE_6
241 } else {
242 printf("Supported SDK versions:\n");
243 Class rootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot");
244 for (id root in [rootClass knownRoots]) {
245 printf(" '%s'\n", [[root sdkVersion] UTF8String]);
246 }
247 // This is the list of devices supported on Xcode 5.1.x.
248 printf("Supported devices:\n");
249 printf(" 'iPhone'\n");
250 printf(" 'iPhone Retina (3.5-inch)'\n");
251 printf(" 'iPhone Retina (4-inch)'\n");
252 printf(" 'iPhone Retina (4-inch 64-bit)'\n");
253 printf(" 'iPad'\n");
254 printf(" 'iPad Retina'\n");
255 printf(" 'iPad Retina (64-bit)'\n");
256 } 186 }
257 } 187 }
258 } // namespace 188 } // namespace
259 189
260 // A delegate that is called when the simulated app is started or ended in the 190 // A delegate that is called when the simulated app is started or ended in the
261 // simulator. 191 // simulator.
262 @interface SimulatorDelegate : NSObject <DTiPhoneSimulatorSessionDelegate> { 192 @interface SimulatorDelegate : NSObject <DTiPhoneSimulatorSessionDelegate> {
263 @private 193 @private
264 NSString* stdioPath_; 194 NSString* stdioPath_;
265 NSString* developerDir_; 195 NSString* developerDir_;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 // Reads data from the simulated app's output and writes it to stdout. This 235 // Reads data from the simulated app's output and writes it to stdout. This
306 // method blocks, so it should be called in a separate thread. The iOS 236 // method blocks, so it should be called in a separate thread. The iOS
307 // Simulator takes a file path for the simulated app's stdout and stderr, but 237 // Simulator takes a file path for the simulated app's stdout and stderr, but
308 // this path isn't always available (e.g. when the stdout is Xcode's build 238 // this path isn't always available (e.g. when the stdout is Xcode's build
309 // window). As a workaround, iossim creates a temp file to hold output, which 239 // window). As a workaround, iossim creates a temp file to hold output, which
310 // this method reads and copies to stdout. 240 // this method reads and copies to stdout.
311 - (void)tailOutputForSession:(DTiPhoneSimulatorSession*)session { 241 - (void)tailOutputForSession:(DTiPhoneSimulatorSession*)session {
312 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 242 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
313 243
314 NSFileHandle* simio = [NSFileHandle fileHandleForReadingAtPath:stdioPath_]; 244 NSFileHandle* simio = [NSFileHandle fileHandleForReadingAtPath:stdioPath_];
315 if (IsRunningWithXcode6OrLater()) { 245 NSString* versionString =
316 #if defined(IOSSIM_USE_XCODE_6) 246 [[[session sessionConfig] simulatedSystemRoot] sdkVersion];
317 // With iOS 8 simulators on Xcode 6, the app output is relative to the 247 NSInteger majorVersion = [[[versionString componentsSeparatedByString:@"."]
318 // simulator's data directory. 248 objectAtIndex:0] intValue];
319 NSString* versionString = 249 if (majorVersion >= 8) {
320 [[[session sessionConfig] simulatedSystemRoot] sdkVersion]; 250 NSString* dataPath = session.sessionConfig.device.dataPath;
321 NSInteger majorVersion = [[[versionString componentsSeparatedByString:@"."] 251 NSString* appOutput =
322 objectAtIndex:0] intValue]; 252 [dataPath stringByAppendingPathComponent:stdioPath_];
323 if (majorVersion >= 8) { 253 simio = [NSFileHandle fileHandleForReadingAtPath:appOutput];
324 NSString* dataPath = session.sessionConfig.device.dataPath;
325 NSString* appOutput =
326 [dataPath stringByAppendingPathComponent:stdioPath_];
327 simio = [NSFileHandle fileHandleForReadingAtPath:appOutput];
328 }
329 #endif // IOSSIM_USE_XCODE_6
330 } 254 }
331 NSFileHandle* standardOutput = [NSFileHandle fileHandleWithStandardOutput]; 255 NSFileHandle* standardOutput = [NSFileHandle fileHandleWithStandardOutput];
332 // Copy data to stdout/stderr while the app is running. 256 // Copy data to stdout/stderr while the app is running.
333 while (appRunning_) { 257 while (appRunning_) {
334 NSAutoreleasePool* innerPool = [[NSAutoreleasePool alloc] init]; 258 NSAutoreleasePool* innerPool = [[NSAutoreleasePool alloc] init];
335 [standardOutput writeData:[simio readDataToEndOfFile]]; 259 [standardOutput writeData:[simio readDataToEndOfFile]];
336 [NSThread sleepForTimeInterval:kOutputPollIntervalSeconds]; 260 [NSThread sleepForTimeInterval:kOutputPollIntervalSeconds];
337 [innerPool drain]; 261 [innerPool drain];
338 } 262 }
339 263
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 LogWarning(@"Console message: %s", message); 394 LogWarning(@"Console message: %s", message);
471 // Some messages are harmless, so don't trigger a failure for them. 395 // Some messages are harmless, so don't trigger a failure for them.
472 if (strstr(message, "The following job tried to hijack the service")) 396 if (strstr(message, "The following job tried to hijack the service"))
473 continue; 397 continue;
474 badEntryFound = YES; 398 badEntryFound = YES;
475 } 399 }
476 } else { 400 } else {
477 // Otherwise, the iOS Simulator's system logging is sandboxed, so parse the 401 // Otherwise, the iOS Simulator's system logging is sandboxed, so parse the
478 // sandboxed system.log file for known errors. 402 // sandboxed system.log file for known errors.
479 NSString* path; 403 NSString* path;
480 if (IsRunningWithXcode6OrLater()) { 404 NSString* dataPath = session.sessionConfig.device.dataPath;
481 #if defined(IOSSIM_USE_XCODE_6) 405 path =
482 NSString* dataPath = session.sessionConfig.device.dataPath; 406 [dataPath stringByAppendingPathComponent:@"Library/Logs/system.log"];
483 path =
484 [dataPath stringByAppendingPathComponent:@"Library/Logs/system.log"];
485 #endif // IOSSIM_USE_XCODE_6
486 } else {
487 NSString* relativePathToSystemLog =
488 [NSString stringWithFormat:
489 @"Library/Logs/iOS Simulator/%@/system.log", versionString];
490 path = [simulatorHome_
491 stringByAppendingPathComponent:relativePathToSystemLog];
492 }
493 NSFileManager* fileManager = [NSFileManager defaultManager]; 407 NSFileManager* fileManager = [NSFileManager defaultManager];
494 if ([fileManager fileExistsAtPath:path]) { 408 if ([fileManager fileExistsAtPath:path]) {
495 NSString* content = 409 NSString* content =
496 [NSString stringWithContentsOfFile:path 410 [NSString stringWithContentsOfFile:path
497 encoding:NSUTF8StringEncoding 411 encoding:NSUTF8StringEncoding
498 error:NULL]; 412 error:NULL];
499 NSArray* lines = [content componentsSeparatedByCharactersInSet: 413 NSArray* lines = [content componentsSeparatedByCharactersInSet:
500 [NSCharacterSet newlineCharacterSet]]; 414 [NSCharacterSet newlineCharacterSet]];
501 NSString* simulatedAppPID = 415 NSString* simulatedAppPID =
502 [NSString stringWithFormat:@"%d", session.simulatedApplicationPID]; 416 [NSString stringWithFormat:@"%d", session.simulatedApplicationPID];
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 NSError* error; 493 NSError* error;
580 Class DVTPlatformClass = FindClassByName(@"DVTPlatform"); 494 Class DVTPlatformClass = FindClassByName(@"DVTPlatform");
581 if (![DVTPlatformClass loadAllPlatformsReturningError:&error]) { 495 if (![DVTPlatformClass loadAllPlatformsReturningError:&error]) {
582 LogError(@"Unable to loadAllPlatformsReturningError. Error: %@", 496 LogError(@"Unable to loadAllPlatformsReturningError. Error: %@",
583 [error localizedDescription]); 497 [error localizedDescription]);
584 return nil; 498 return nil;
585 } 499 }
586 500
587 // The path within the developer dir of the private Simulator frameworks. 501 // The path within the developer dir of the private Simulator frameworks.
588 NSString* simulatorFrameworkRelativePath; 502 NSString* simulatorFrameworkRelativePath;
589 if (IsRunningWithXcode6OrLater()) { 503 simulatorFrameworkRelativePath =
590 simulatorFrameworkRelativePath = 504 @"../SharedFrameworks/DVTiPhoneSimulatorRemoteClient.framework";
591 @"../SharedFrameworks/DVTiPhoneSimulatorRemoteClient.framework"; 505 NSString* const kCoreSimulatorRelativePath =
592 NSString* const kCoreSimulatorRelativePath = 506 @"Library/PrivateFrameworks/CoreSimulator.framework";
593 @"Library/PrivateFrameworks/CoreSimulator.framework"; 507 NSString* coreSimulatorPath = [developerDir
594 NSString* coreSimulatorPath = [developerDir 508 stringByAppendingPathComponent:kCoreSimulatorRelativePath];
595 stringByAppendingPathComponent:kCoreSimulatorRelativePath]; 509 NSBundle* coreSimulatorBundle =
596 NSBundle* coreSimulatorBundle = 510 [NSBundle bundleWithPath:coreSimulatorPath];
597 [NSBundle bundleWithPath:coreSimulatorPath]; 511 if (![coreSimulatorBundle load])
598 if (![coreSimulatorBundle load]) 512 return nil;
599 return nil;
600 } else {
601 simulatorFrameworkRelativePath =
602 @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/"
603 @"DVTiPhoneSimulatorRemoteClient.framework";
604 }
605 NSString* simBundlePath = [developerDir 513 NSString* simBundlePath = [developerDir
606 stringByAppendingPathComponent:simulatorFrameworkRelativePath]; 514 stringByAppendingPathComponent:simulatorFrameworkRelativePath];
607 NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath]; 515 NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath];
608 if (![simBundle load]) 516 if (![simBundle load])
609 return nil; 517 return nil;
610 return simBundle; 518 return simBundle;
611 } 519 }
612 520
613 // Converts the given app path to an application spec, which requires an 521 // Converts the given app path to an application spec, which requires an
614 // absolute path. 522 // absolute path.
(...skipping 11 matching lines...) Expand all
626 exit(kExitInvalidArguments); 534 exit(kExitInvalidArguments);
627 } 535 }
628 return [applicationSpecifierClass specifierWithApplicationPath:appPath]; 536 return [applicationSpecifierClass specifierWithApplicationPath:appPath];
629 } 537 }
630 538
631 // Returns the system root for the given SDK version. If sdkVersion is nil, the 539 // Returns the system root for the given SDK version. If sdkVersion is nil, the
632 // default system root is returned. Will return nil if the sdkVersion is not 540 // default system root is returned. Will return nil if the sdkVersion is not
633 // valid. 541 // valid.
634 DTiPhoneSimulatorSystemRoot* BuildSystemRoot(NSString* sdkVersion) { 542 DTiPhoneSimulatorSystemRoot* BuildSystemRoot(NSString* sdkVersion) {
635 Class systemRootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot"); 543 Class systemRootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot");
636 #if defined(IOSSIM_USE_XCODE_6)
637 Class simRuntimeClass = FindClassByName(@"SimRuntime"); 544 Class simRuntimeClass = FindClassByName(@"SimRuntime");
638 NSArray* sorted = 545 NSArray* sorted =
639 [[simRuntimeClass supportedRuntimes] sortedArrayUsingDescriptors:@[ 546 [[simRuntimeClass supportedRuntimes] sortedArrayUsingDescriptors:@[
640 [NSSortDescriptor sortDescriptorWithKey:@"version" ascending:YES] 547 [NSSortDescriptor sortDescriptorWithKey:@"version" ascending:YES]
641 ]]; 548 ]];
642 NSString* versionString = [[sorted lastObject] versionString]; 549 NSString* versionString = [[sorted lastObject] versionString];
643 DTiPhoneSimulatorSystemRoot* systemRoot = 550 DTiPhoneSimulatorSystemRoot* systemRoot =
644 [systemRootClass rootWithSDKVersion:versionString]; 551 [systemRootClass rootWithSDKVersion:versionString];
645 #else
646 DTiPhoneSimulatorSystemRoot* systemRoot = [systemRootClass defaultRoot];
647 #endif
648 if (sdkVersion) 552 if (sdkVersion)
649 systemRoot = [systemRootClass rootWithSDKVersion:sdkVersion]; 553 systemRoot = [systemRootClass rootWithSDKVersion:sdkVersion];
650 554
651 return systemRoot; 555 return systemRoot;
652 } 556 }
653 557
654 // Builds a config object for starting the specified app. 558 // Builds a config object for starting the specified app.
655 DTiPhoneSimulatorSessionConfig* BuildSessionConfig( 559 DTiPhoneSimulatorSessionConfig* BuildSessionConfig(
656 DTiPhoneSimulatorApplicationSpecifier* appSpec, 560 DTiPhoneSimulatorApplicationSpecifier* appSpec,
657 DTiPhoneSimulatorSystemRoot* systemRoot, 561 DTiPhoneSimulatorSystemRoot* systemRoot,
658 NSString* stdoutPath, 562 NSString* stdoutPath,
659 NSString* stderrPath, 563 NSString* stderrPath,
660 NSArray* appArgs, 564 NSArray* appArgs,
661 NSDictionary* appEnv, 565 NSDictionary* appEnv,
662 NSNumber* deviceFamily, 566 NSNumber* deviceFamily,
663 NSString* deviceName) { 567 NSString* deviceName) {
664 Class sessionConfigClass = FindClassByName(@"DTiPhoneSimulatorSessionConfig"); 568 Class sessionConfigClass = FindClassByName(@"DTiPhoneSimulatorSessionConfig");
665 DTiPhoneSimulatorSessionConfig* sessionConfig = 569 DTiPhoneSimulatorSessionConfig* sessionConfig =
666 [[[sessionConfigClass alloc] init] autorelease]; 570 [[[sessionConfigClass alloc] init] autorelease];
667 sessionConfig.applicationToSimulateOnStart = appSpec; 571 sessionConfig.applicationToSimulateOnStart = appSpec;
668 sessionConfig.simulatedSystemRoot = systemRoot; 572 sessionConfig.simulatedSystemRoot = systemRoot;
669 sessionConfig.localizedClientName = @"chromium"; 573 sessionConfig.localizedClientName = @"chromium";
670 sessionConfig.simulatedApplicationStdErrPath = stderrPath; 574 sessionConfig.simulatedApplicationStdErrPath = stderrPath;
671 sessionConfig.simulatedApplicationStdOutPath = stdoutPath; 575 sessionConfig.simulatedApplicationStdOutPath = stdoutPath;
672 sessionConfig.simulatedApplicationLaunchArgs = appArgs; 576 sessionConfig.simulatedApplicationLaunchArgs = appArgs;
673 sessionConfig.simulatedApplicationLaunchEnvironment = appEnv; 577 sessionConfig.simulatedApplicationLaunchEnvironment = appEnv;
674 sessionConfig.simulatedDeviceInfoName = deviceName; 578 sessionConfig.simulatedDeviceInfoName = deviceName;
675 sessionConfig.simulatedDeviceFamily = deviceFamily; 579 sessionConfig.simulatedDeviceFamily = deviceFamily;
676 580
677 if (IsRunningWithXcode6OrLater()) { 581 Class simDeviceTypeClass = FindClassByName(@"SimDeviceType");
678 #if defined(IOSSIM_USE_XCODE_6) 582 id simDeviceType =
679 Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); 583 [simDeviceTypeClass supportedDeviceTypesByAlias][deviceName];
680 id simDeviceType = 584 Class simRuntimeClass = FindClassByName(@"SimRuntime");
681 [simDeviceTypeClass supportedDeviceTypesByAlias][deviceName]; 585 NSString* identifier = systemRoot.runtime.identifier;
682 Class simRuntimeClass = FindClassByName(@"SimRuntime"); 586 id simRuntime = [simRuntimeClass supportedRuntimesByIdentifier][identifier];
683 NSString* identifier = systemRoot.runtime.identifier;
684 id simRuntime = [simRuntimeClass supportedRuntimesByIdentifier][identifier];
685 587
686 // Attempt to use an existing device, but create one if a suitable match 588 // Attempt to use an existing device, but create one if a suitable match
687 // can't be found. For example, if the simulator is running with a 589 // can't be found. For example, if the simulator is running with a
688 // non-default home directory (e.g. via iossim's -u command line arg) then 590 // non-default home directory (e.g. via iossim's -u command line arg) then
689 // there won't be any devices so one will have to be created. 591 // there won't be any devices so one will have to be created.
690 Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); 592 Class simDeviceSetClass = FindClassByName(@"SimDeviceSet");
691 id deviceSet = 593 id deviceSet =
692 [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; 594 [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]];
693 id simDevice = nil; 595 id simDevice = nil;
694 for (id device in [deviceSet availableDevices]) { 596 for (id device in [deviceSet availableDevices]) {
695 if ([device runtime] == simRuntime && 597 if ([device runtime] == simRuntime &&
696 [device deviceType] == simDeviceType) { 598 [device deviceType] == simDeviceType) {
697 simDevice = device; 599 simDevice = device;
698 break; 600 break;
699 }
700 } 601 }
701 if (!simDevice) { 602 }
702 NSError* error = nil; 603 if (!simDevice) {
703 // n.b. only the device name is necessary because the iOS Simulator menu 604 NSError* error = nil;
704 // already splits devices by runtime version. 605 // n.b. only the device name is necessary because the iOS Simulator menu
705 NSString* name = [NSString stringWithFormat:@"iossim - %@ ", deviceName]; 606 // already splits devices by runtime version.
706 simDevice = [deviceSet createDeviceWithType:simDeviceType 607 NSString* name = [NSString stringWithFormat:@"iossim - %@ ", deviceName];
707 runtime:simRuntime 608 simDevice = [deviceSet createDeviceWithType:simDeviceType
708 name:name 609 runtime:simRuntime
709 error:&error]; 610 name:name
710 if (error) { 611 error:&error];
711 LogError(@"Failed to create device: %@", error); 612 if (error) {
712 exit(kExitInitializationFailure); 613 LogError(@"Failed to create device: %@", error);
713 } 614 exit(kExitInitializationFailure);
714 } 615 }
715 sessionConfig.device = simDevice;
716 #endif // IOSSIM_USE_XCODE_6
717 } 616 }
617 sessionConfig.device = simDevice;
718 return sessionConfig; 618 return sessionConfig;
719 } 619 }
720 620
721 // Builds a simulator session that will use the given delegate. 621 // Builds a simulator session that will use the given delegate.
722 DTiPhoneSimulatorSession* BuildSession(SimulatorDelegate* delegate) { 622 DTiPhoneSimulatorSession* BuildSession(SimulatorDelegate* delegate) {
723 Class sessionClass = FindClassByName(@"DTiPhoneSimulatorSession"); 623 Class sessionClass = FindClassByName(@"DTiPhoneSimulatorSession");
724 DTiPhoneSimulatorSession* session = 624 DTiPhoneSimulatorSession* session =
725 [[[sessionClass alloc] init] autorelease]; 625 [[[sessionClass alloc] init] autorelease];
726 session.delegate = delegate; 626 session.delegate = delegate;
727 return session; 627 return session;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 // variable's value if it has already been set. 688 // variable's value if it has already been set.
789 if ((setenv(kUserHomeEnvVariable, [userHomePath UTF8String], YES) == -1) || 689 if ((setenv(kUserHomeEnvVariable, [userHomePath UTF8String], YES) == -1) ||
790 (setenv(kHomeEnvVariable, [userHomePath UTF8String], YES) == -1)) { 690 (setenv(kHomeEnvVariable, [userHomePath UTF8String], YES) == -1)) {
791 LogError(@"Unable to set environment variables for home directory."); 691 LogError(@"Unable to set environment variables for home directory.");
792 return NO; 692 return NO;
793 } 693 }
794 694
795 return YES; 695 return YES;
796 } 696 }
797 697
798 // Performs a case-insensitive search to see if |stringToSearch| begins with
799 // |prefixToFind|. Returns true if a match is found.
800 BOOL CaseInsensitivePrefixSearch(NSString* stringToSearch,
801 NSString* prefixToFind) {
802 NSStringCompareOptions options = (NSAnchoredSearch | NSCaseInsensitiveSearch);
803 NSRange range = [stringToSearch rangeOfString:prefixToFind
804 options:options];
805 return range.location != NSNotFound;
806 }
807
808 // Prints the usage information to stderr. 698 // Prints the usage information to stderr.
809 void PrintUsage() { 699 void PrintUsage() {
810 fprintf(stderr, "Usage: iossim [-d device] [-s sdkVersion] [-u homeDir] " 700 fprintf(stderr, "Usage: iossim [-d device] [-s sdkVersion] [-u homeDir] "
811 "[-e envKey=value]* [-t startupTimeout] <appPath> [<appArgs>]\n" 701 "[-e envKey=value]* [-t startupTimeout] <appPath> [<appArgs>]\n"
812 " where <appPath> is the path to the .app directory and appArgs are any" 702 " where <appPath> is the path to the .app directory and appArgs are any"
813 " arguments to send the simulated app.\n" 703 " arguments to send the simulated app.\n"
814 "\n" 704 "\n"
815 "Options:\n" 705 "Options:\n"
816 " -d Specifies the device (must be one of the values from the iOS" 706 " -d Specifies the device (must be one of the values from the iOS"
817 " Simulator's Hardware -> Device menu. Defaults to 'iPhone'.\n" 707 " Simulator's Hardware -> Device menu. Defaults to 'iPhone'.\n"
818 " -s Specifies the SDK version to use (e.g '4.3')." 708 " -s Specifies the SDK version to use (e.g '4.3')."
819 " Will use system default if not specified.\n" 709 " Will use system default if not specified.\n"
820 " -u Specifies a user home directory for the simulator." 710 " -u Specifies a user home directory for the simulator."
821 " Will create a new directory if not specified.\n" 711 " Will create a new directory if not specified.\n"
822 " -e Specifies an environment key=value pair that will be" 712 " -e Specifies an environment key=value pair that will be"
823 " set in the simulated application's environment.\n" 713 " set in the simulated application's environment.\n"
824 " -t Specifies the session startup timeout (in seconds)." 714 " -t Specifies the session startup timeout (in seconds)."
825 " Defaults to %d.\n" 715 " Defaults to %d.\n"
826 " -l List supported devices and iOS versions.\n", 716 " -l List supported devices and iOS versions.\n",
827 static_cast<int>(kDefaultSessionStartTimeoutSeconds)); 717 static_cast<int>(kDefaultSessionStartTimeoutSeconds));
828 } 718 }
829 } // namespace 719 } // namespace
830 720
831 void EnsureSupportForCurrentXcodeVersion() {
832 if (IsRunningWithXcode6OrLater()) {
833 #if !IOSSIM_USE_XCODE_6
834 LogError(@"Running on Xcode 6, but Xcode 6 support was not compiled in.");
835 exit(kExitUnsupportedXcodeVersion);
836 #endif // IOSSIM_USE_XCODE_6
837 }
838 }
839
840 int main(int argc, char* const argv[]) { 721 int main(int argc, char* const argv[]) {
841 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 722 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
842 723
843 EnsureSupportForCurrentXcodeVersion();
844
845 // basename() may modify the passed in string and it returns a pointer to an 724 // basename() may modify the passed in string and it returns a pointer to an
846 // internal buffer. Give it a copy to modify, and copy what it returns. 725 // internal buffer. Give it a copy to modify, and copy what it returns.
847 char* worker = strdup(argv[0]); 726 char* worker = strdup(argv[0]);
848 char* toolName = basename(worker); 727 char* toolName = basename(worker);
849 if (toolName != NULL) { 728 if (toolName != NULL) {
850 toolName = strdup(toolName); 729 toolName = strdup(toolName);
851 if (toolName != NULL) 730 if (toolName != NULL)
852 gToolName = toolName; 731 gToolName = toolName;
853 } 732 }
854 if (worker != NULL) 733 if (worker != NULL)
855 free(worker); 734 free(worker);
856 735
857 NSString* appPath = nil; 736 NSString* appPath = nil;
858 NSString* appName = nil; 737 NSString* appName = nil;
859 NSString* sdkVersion = nil; 738 NSString* sdkVersion = nil;
860 NSString* deviceName = 739 NSString* deviceName = @"iPhone 5s";
861 IsRunningWithXcode6OrLater() ? @"iPhone 5s" : @"iPhone";
862 NSString* simHomePath = nil; 740 NSString* simHomePath = nil;
863 NSMutableArray* appArgs = [NSMutableArray array]; 741 NSMutableArray* appArgs = [NSMutableArray array];
864 NSMutableDictionary* appEnv = [NSMutableDictionary dictionary]; 742 NSMutableDictionary* appEnv = [NSMutableDictionary dictionary];
865 NSTimeInterval sessionStartTimeout = kDefaultSessionStartTimeoutSeconds; 743 NSTimeInterval sessionStartTimeout = kDefaultSessionStartTimeoutSeconds;
866 744
867 NSString* developerDir = FindDeveloperDir(); 745 NSString* developerDir = FindDeveloperDir();
868 if (!developerDir) { 746 if (!developerDir) {
869 LogError(@"Unable to find developer directory."); 747 LogError(@"Unable to find developer directory.");
870 exit(kExitInitializationFailure); 748 exit(kExitInitializationFailure);
871 } 749 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 exit(kExitInitializationFailure); 836 exit(kExitInitializationFailure);
959 } 837 }
960 838
961 // Get the paths for stdout and stderr so the simulated app's output will show 839 // Get the paths for stdout and stderr so the simulated app's output will show
962 // up in the caller's stdout/stderr. 840 // up in the caller's stdout/stderr.
963 NSString* outputDir = CreateTempDirectory(@"iossim-XXXXXX"); 841 NSString* outputDir = CreateTempDirectory(@"iossim-XXXXXX");
964 NSString* stdioPath = [outputDir stringByAppendingPathComponent:@"stdio.txt"]; 842 NSString* stdioPath = [outputDir stringByAppendingPathComponent:@"stdio.txt"];
965 843
966 // Determine the deviceFamily based on the deviceName 844 // Determine the deviceFamily based on the deviceName
967 NSNumber* deviceFamily = nil; 845 NSNumber* deviceFamily = nil;
968 if (IsRunningWithXcode6OrLater()) { 846 Class simDeviceTypeClass = FindClassByName(@"SimDeviceType");
969 #if defined(IOSSIM_USE_XCODE_6) 847 if ([simDeviceTypeClass supportedDeviceTypesByAlias][deviceName] == nil) {
970 Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); 848 LogError(@"Invalid device name: %@.", deviceName);
971 if ([simDeviceTypeClass supportedDeviceTypesByAlias][deviceName] == nil) { 849 PrintSupportedDevices();
972 LogError(@"Invalid device name: %@.", deviceName); 850 exit(kExitInvalidArguments);
973 PrintSupportedDevices();
974 exit(kExitInvalidArguments);
975 }
976 #endif // IOSSIM_USE_XCODE_6
977 } else {
978 if (!deviceName || CaseInsensitivePrefixSearch(deviceName, @"iPhone")) {
979 deviceFamily = [NSNumber numberWithInt:kIPhoneFamily];
980 } else if (CaseInsensitivePrefixSearch(deviceName, @"iPad")) {
981 deviceFamily = [NSNumber numberWithInt:kIPadFamily];
982 }
983 else {
984 LogError(@"Invalid device name: %@. Must begin with 'iPhone' or 'iPad'",
985 deviceName);
986 exit(kExitInvalidArguments);
987 }
988 } 851 }
989 852
990 // Set up the user home directory for the simulator only if a non-default 853 // Set up the user home directory for the simulator only if a non-default
991 // value was specified. 854 // value was specified.
992 if (simHomePath) { 855 if (simHomePath) {
993 if (!InitializeSimulatorUserHome(simHomePath)) { 856 if (!InitializeSimulatorUserHome(simHomePath)) {
994 LogError(@"Unable to initialize home directory for simulator: %@", 857 LogError(@"Unable to initialize home directory for simulator: %@",
995 simHomePath); 858 simHomePath);
996 exit(kExitInitializationFailure); 859 exit(kExitInitializationFailure);
997 } 860 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 [error localizedDescription], 892 [error localizedDescription],
1030 [error domain], static_cast<long int>([error code])); 893 [error domain], static_cast<long int>([error code]));
1031 } 894 }
1032 895
1033 // Note that this code is only executed if the simulator fails to start 896 // Note that this code is only executed if the simulator fails to start
1034 // because once the main run loop is started, only the delegate calling 897 // because once the main run loop is started, only the delegate calling
1035 // exit() will end the program. 898 // exit() will end the program.
1036 [pool drain]; 899 [pool drain];
1037 return kExitFailure; 900 return kExitFailure;
1038 } 901 }
OLDNEW
« no previous file with comments | « testing/iossim/iossim.gyp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698