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 83 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 // Returns the a NSString containing the stdout from running |task|. | |
163 NSString* GetOutputFromTask(NSTask* task) { | |
TVL
2014/08/22 18:27:36
take
NSString *toolPath, NSArray *args
and you c
lliabraa
2014/08/25 13:14:04
Done.
| |
164 NSPipe* outputPipe = [NSPipe pipe]; | |
165 [task setStandardOutput:outputPipe]; | |
166 NSFileHandle* outputFile = [outputPipe fileHandleForReading]; | |
167 | |
168 [task launch]; | |
169 NSData* outputData = [outputFile readDataToEndOfFile]; | |
170 [task terminate]; | |
TVL
2014/08/22 18:27:35
optional - check exit code?
lliabraa
2014/08/25 13:14:04
Done.
| |
171 | |
172 return [[[NSString alloc] initWithData:outputData | |
173 encoding:NSUTF8StringEncoding] autorelease]; | |
174 } | |
175 | |
176 // Finds the Xcode version via xcodebuild -version. Output from xcodebuild is | |
177 // expected to look like: | |
178 // Xcode <version> | |
179 // Build version 5B130a | |
180 // where <version> is the string returned by this function (e.g. 6.0). | |
181 NSString* FindXcodeVersion() { | |
182 NSTask* task = [[[NSTask alloc] init] autorelease]; | |
183 [task setLaunchPath:@"/usr/bin/xcodebuild"]; | |
184 [task setArguments:[NSArray arrayWithObject:@"-version"]]; | |
185 NSString* output = GetOutputFromTask(task); | |
186 // Scan past the "Xcode ", then scan the rest of the line into |version|. | |
187 NSScanner* scanner = [NSScanner scannerWithString:output]; | |
188 BOOL valid = [scanner scanString:@"Xcode " intoString:NULL]; | |
189 NSString* version; | |
190 valid = | |
191 [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] | |
192 intoString:&version]; | |
193 if (!valid) { | |
194 LogError(@"Unable to find Xcode version. 'xcodebuild -version' " | |
195 @"returned \n%@", output); | |
196 return nil; | |
197 } | |
198 return version; | |
199 } | |
200 | |
201 // Returns true if iossim is running with Xcode 6 or later installed on the | |
202 // host. | |
203 BOOL IsRunningWithXcode6OrLater() { | |
204 static NSString* xcodeVersion = FindXcodeVersion(); | |
205 if (!xcodeVersion) { | |
206 return false; | |
207 } | |
208 NSArray* components = [xcodeVersion componentsSeparatedByString:@"."]; | |
209 if ([components count] < 1) { | |
210 return false; | |
211 } | |
212 NSInteger majorVersion = [components[0] integerValue]; | |
213 return majorVersion >= 6; | |
214 } | |
215 | |
175 // Prints supported devices and SDKs. | 216 // Prints supported devices and SDKs. |
176 void PrintSupportedDevices() { | 217 void PrintSupportedDevices() { |
177 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | 218 if (IsRunningWithXcode6OrLater()) { |
178 // (crbug.com/385030). | |
179 #if defined(IOSSIM_USE_XCODE_6) | 219 #if defined(IOSSIM_USE_XCODE_6) |
180 printf("Supported device/SDK combinations:\n"); | 220 printf("Supported device/SDK combinations:\n"); |
181 Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); | 221 Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); |
182 id deviceSet = | 222 id deviceSet = |
183 [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; | 223 [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; |
184 for (id simDevice in [deviceSet availableDevices]) { | 224 for (id simDevice in [deviceSet availableDevices]) { |
185 NSString* deviceInfo = | 225 NSString* deviceInfo = |
186 [NSString stringWithFormat:@" -d '%@' -s '%@'\n", | 226 [NSString stringWithFormat:@" -d '%@' -s '%@'\n", |
187 [simDevice name], [[simDevice runtime] versionString]]; | 227 [simDevice name], [[simDevice runtime] versionString]]; |
188 printf("%s", [deviceInfo UTF8String]); | 228 printf("%s", [deviceInfo UTF8String]); |
229 } | |
230 #endif // IOSSIM_USE_XCODE_6 | |
TVL
2014/08/22 18:27:36
#else
error out since support is missing?
#endif
lliabraa
2014/08/25 13:14:04
Acknowledged.
| |
231 } else { | |
232 printf("Supported SDK versions:\n"); | |
233 Class rootClass = FindClassByName(@"DTiPhoneSimulatorSystemRoot"); | |
234 for (id root in [rootClass knownRoots]) { | |
235 printf(" '%s'\n", [[root sdkVersion] UTF8String]); | |
236 } | |
237 // This is the list of devices supported on Xcode 5.1.x. | |
238 printf("Supported devices:\n"); | |
239 printf(" 'iPhone'\n"); | |
240 printf(" 'iPhone Retina (3.5-inch)'\n"); | |
241 printf(" 'iPhone Retina (4-inch)'\n"); | |
242 printf(" 'iPhone Retina (4-inch 64-bit)'\n"); | |
243 printf(" 'iPad'\n"); | |
244 printf(" 'iPad Retina'\n"); | |
245 printf(" 'iPad Retina (64-bit)'\n"); | |
189 } | 246 } |
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 } | 247 } |
206 } // namespace | 248 } // namespace |
207 | 249 |
208 // A delegate that is called when the simulated app is started or ended in the | 250 // A delegate that is called when the simulated app is started or ended in the |
209 // simulator. | 251 // simulator. |
210 @interface SimulatorDelegate : NSObject <DTiPhoneSimulatorSessionDelegate> { | 252 @interface SimulatorDelegate : NSObject <DTiPhoneSimulatorSessionDelegate> { |
211 @private | 253 @private |
212 NSString* stdioPath_; | 254 NSString* stdioPath_; |
213 NSString* developerDir_; | 255 NSString* developerDir_; |
214 NSString* simulatorHome_; | 256 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 | 295 // 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 | 296 // 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 | 297 // 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 | 298 // 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 | 299 // window). As a workaround, iossim creates a temp file to hold output, which |
258 // this method reads and copies to stdout. | 300 // this method reads and copies to stdout. |
259 - (void)tailOutputForSession:(DTiPhoneSimulatorSession*)session { | 301 - (void)tailOutputForSession:(DTiPhoneSimulatorSession*)session { |
260 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; | 302 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; |
261 | 303 |
262 NSFileHandle* simio = [NSFileHandle fileHandleForReadingAtPath:stdioPath_]; | 304 NSFileHandle* simio = [NSFileHandle fileHandleForReadingAtPath:stdioPath_]; |
263 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | 305 if (IsRunningWithXcode6OrLater()) { |
264 // (crbug.com/385030). | |
265 #if defined(IOSSIM_USE_XCODE_6) | 306 #if defined(IOSSIM_USE_XCODE_6) |
266 // With iOS 8 simulators on Xcode 6, the app output is relative to the | 307 // With iOS 8 simulators on Xcode 6, the app output is relative to the |
267 // simulator's data directory. | 308 // simulator's data directory. |
268 if ([session.sessionConfig.simulatedSystemRoot.sdkVersion isEqual:@"8.0"]) { | 309 if ([session.sessionConfig.simulatedSystemRoot.sdkVersion isEqual:@"8.0"]) { |
269 NSString* dataPath = session.sessionConfig.device.dataPath; | 310 NSString* dataPath = session.sessionConfig.device.dataPath; |
270 NSString* appOutput = [dataPath stringByAppendingPathComponent:stdioPath_]; | 311 NSString* appOutput = |
271 simio = [NSFileHandle fileHandleForReadingAtPath:appOutput]; | 312 [dataPath stringByAppendingPathComponent:stdioPath_]; |
313 simio = [NSFileHandle fileHandleForReadingAtPath:appOutput]; | |
314 } | |
315 #endif // IOSSIM_USE_XCODE_6 | |
TVL
2014/08/22 18:27:36
#else
error out since support is missing?
#endif
lliabraa
2014/08/25 13:14:04
Acknowledged.
| |
272 } | 316 } |
273 #endif | |
274 NSFileHandle* standardOutput = [NSFileHandle fileHandleWithStandardOutput]; | 317 NSFileHandle* standardOutput = [NSFileHandle fileHandleWithStandardOutput]; |
275 // Copy data to stdout/stderr while the app is running. | 318 // Copy data to stdout/stderr while the app is running. |
276 while (appRunning_) { | 319 while (appRunning_) { |
277 NSAutoreleasePool* innerPool = [[NSAutoreleasePool alloc] init]; | 320 NSAutoreleasePool* innerPool = [[NSAutoreleasePool alloc] init]; |
278 [standardOutput writeData:[simio readDataToEndOfFile]]; | 321 [standardOutput writeData:[simio readDataToEndOfFile]]; |
279 [NSThread sleepForTimeInterval:kOutputPollIntervalSeconds]; | 322 [NSThread sleepForTimeInterval:kOutputPollIntervalSeconds]; |
280 [innerPool drain]; | 323 [innerPool drain]; |
281 } | 324 } |
282 | 325 |
283 // Once the app is no longer running, copy any data that was written during | 326 // 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); | 455 const char* message = asl_get(entry, ASL_KEY_MSG); |
413 LogWarning(@"Console message: %s", message); | 456 LogWarning(@"Console message: %s", message); |
414 // Some messages are harmless, so don't trigger a failure for them. | 457 // Some messages are harmless, so don't trigger a failure for them. |
415 if (strstr(message, "The following job tried to hijack the service")) | 458 if (strstr(message, "The following job tried to hijack the service")) |
416 continue; | 459 continue; |
417 badEntryFound = YES; | 460 badEntryFound = YES; |
418 } | 461 } |
419 } else { | 462 } else { |
420 // Otherwise, the iOS Simulator's system logging is sandboxed, so parse the | 463 // Otherwise, the iOS Simulator's system logging is sandboxed, so parse the |
421 // sandboxed system.log file for known errors. | 464 // sandboxed system.log file for known errors. |
422 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | 465 NSString* path; |
423 // (crbug.com/385030). | 466 if (IsRunningWithXcode6OrLater()) { |
424 #if defined(IOSSIM_USE_XCODE_6) | 467 #if defined(IOSSIM_USE_XCODE_6) |
425 NSString* dataPath = session.sessionConfig.device.dataPath; | 468 NSString* dataPath = session.sessionConfig.device.dataPath; |
426 NSString* path = | 469 path = |
427 [dataPath stringByAppendingPathComponent:@"Library/Logs/system.log"]; | 470 [dataPath stringByAppendingPathComponent:@"Library/Logs/system.log"]; |
428 #else | 471 #endif // IOSSIM_USE_XCODE_6 |
TVL
2014/08/22 18:27:36
#else
error out since support is missing?
#endif
lliabraa
2014/08/25 13:14:04
Acknowledged.
| |
429 NSString* relativePathToSystemLog = | 472 } else { |
430 [NSString stringWithFormat: | 473 NSString* relativePathToSystemLog = |
431 @"Library/Logs/iOS Simulator/%@/system.log", versionString]; | 474 [NSString stringWithFormat: |
432 NSString* path = | 475 @"Library/Logs/iOS Simulator/%@/system.log", versionString]; |
433 [simulatorHome_ stringByAppendingPathComponent:relativePathToSystemLog]; | 476 path = [simulatorHome_ |
434 #endif // defined(IOSSIM_USE_XCODE_6) | 477 stringByAppendingPathComponent:relativePathToSystemLog]; |
478 } | |
435 NSFileManager* fileManager = [NSFileManager defaultManager]; | 479 NSFileManager* fileManager = [NSFileManager defaultManager]; |
436 if ([fileManager fileExistsAtPath:path]) { | 480 if ([fileManager fileExistsAtPath:path]) { |
437 NSString* content = | 481 NSString* content = |
438 [NSString stringWithContentsOfFile:path | 482 [NSString stringWithContentsOfFile:path |
439 encoding:NSUTF8StringEncoding | 483 encoding:NSUTF8StringEncoding |
440 error:NULL]; | 484 error:NULL]; |
441 NSArray* lines = [content componentsSeparatedByCharactersInSet: | 485 NSArray* lines = [content componentsSeparatedByCharactersInSet: |
442 [NSCharacterSet newlineCharacterSet]]; | 486 [NSCharacterSet newlineCharacterSet]]; |
443 NSString* simulatedAppPID = | 487 NSString* simulatedAppPID = |
444 [NSString stringWithFormat:@"%d", session.simulatedApplicationPID]; | 488 [NSString stringWithFormat:@"%d", session.simulatedApplicationPID]; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
477 // Check the env first. | 521 // Check the env first. |
478 NSDictionary* env = [[NSProcessInfo processInfo] environment]; | 522 NSDictionary* env = [[NSProcessInfo processInfo] environment]; |
479 NSString* developerDir = [env objectForKey:@"DEVELOPER_DIR"]; | 523 NSString* developerDir = [env objectForKey:@"DEVELOPER_DIR"]; |
480 if ([developerDir length] > 0) | 524 if ([developerDir length] > 0) |
481 return developerDir; | 525 return developerDir; |
482 | 526 |
483 // Go look for it via xcode-select. | 527 // Go look for it via xcode-select. |
484 NSTask* xcodeSelectTask = [[[NSTask alloc] init] autorelease]; | 528 NSTask* xcodeSelectTask = [[[NSTask alloc] init] autorelease]; |
485 [xcodeSelectTask setLaunchPath:@"/usr/bin/xcode-select"]; | 529 [xcodeSelectTask setLaunchPath:@"/usr/bin/xcode-select"]; |
486 [xcodeSelectTask setArguments:[NSArray arrayWithObject:@"-print-path"]]; | 530 [xcodeSelectTask setArguments:[NSArray arrayWithObject:@"-print-path"]]; |
487 | 531 NSString* output = GetOutputFromTask(xcodeSelectTask); |
488 NSPipe* outputPipe = [NSPipe pipe]; | |
489 [xcodeSelectTask setStandardOutput:outputPipe]; | |
490 NSFileHandle* outputFile = [outputPipe fileHandleForReading]; | |
491 | |
492 [xcodeSelectTask launch]; | |
493 NSData* outputData = [outputFile readDataToEndOfFile]; | |
494 [xcodeSelectTask terminate]; | |
495 | |
496 NSString* output = | |
497 [[[NSString alloc] initWithData:outputData | |
498 encoding:NSUTF8StringEncoding] autorelease]; | |
499 output = [output stringByTrimmingCharactersInSet: | 532 output = [output stringByTrimmingCharactersInSet: |
500 [NSCharacterSet whitespaceAndNewlineCharacterSet]]; | 533 [NSCharacterSet whitespaceAndNewlineCharacterSet]]; |
501 if ([output length] == 0) | 534 if ([output length] == 0) |
502 output = nil; | 535 output = nil; |
503 return output; | 536 return output; |
504 } | 537 } |
505 | 538 |
506 // Loads the Simulator framework from the given developer dir. | 539 // Loads the Simulator framework from the given developer dir. |
507 NSBundle* LoadSimulatorFramework(NSString* developerDir) { | 540 NSBundle* LoadSimulatorFramework(NSString* developerDir) { |
508 // The Simulator framework depends on some of the other Xcode private | 541 // The Simulator framework depends on some of the other Xcode private |
(...skipping 14 matching lines...) Expand all Loading... | |
523 | 556 |
524 // Prime DVTPlatform. | 557 // Prime DVTPlatform. |
525 NSError* error; | 558 NSError* error; |
526 Class DVTPlatformClass = FindClassByName(@"DVTPlatform"); | 559 Class DVTPlatformClass = FindClassByName(@"DVTPlatform"); |
527 if (![DVTPlatformClass loadAllPlatformsReturningError:&error]) { | 560 if (![DVTPlatformClass loadAllPlatformsReturningError:&error]) { |
528 LogError(@"Unable to loadAllPlatformsReturningError. Error: %@", | 561 LogError(@"Unable to loadAllPlatformsReturningError. Error: %@", |
529 [error localizedDescription]); | 562 [error localizedDescription]); |
530 return nil; | 563 return nil; |
531 } | 564 } |
532 | 565 |
533 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | 566 // The path within the developer dir of the private Simulator frameworks. |
534 // (crbug.com/385030). | 567 NSString* simulatorFrameworkRelativePath; |
535 #if defined(IOSSIM_USE_XCODE_6) | 568 if (IsRunningWithXcode6OrLater()) { |
536 NSString* coreSimulatorPath = [developerDir | 569 simulatorFrameworkRelativePath = |
537 stringByAppendingPathComponent:kCoreSimulatorRelativePath]; | 570 @"../SharedFrameworks/DVTiPhoneSimulatorRemoteClient.framework"; |
538 NSBundle* coreSimulatorBundle = | 571 NSString* const kCoreSimulatorRelativePath = |
539 [NSBundle bundleWithPath:coreSimulatorPath]; | 572 @"Library/PrivateFrameworks/CoreSimulator.framework"; |
540 if (![coreSimulatorBundle load]) | 573 NSString* coreSimulatorPath = [developerDir |
541 return nil; | 574 stringByAppendingPathComponent:kCoreSimulatorRelativePath]; |
542 #endif // defined(IOSSIM_USE_XCODE_6) | 575 NSBundle* coreSimulatorBundle = |
543 | 576 [NSBundle bundleWithPath:coreSimulatorPath]; |
577 if (![coreSimulatorBundle load]) | |
578 return nil; | |
579 } else { | |
580 simulatorFrameworkRelativePath = | |
581 @"Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/" | |
582 @"DVTiPhoneSimulatorRemoteClient.framework"; | |
583 } | |
544 NSString* simBundlePath = [developerDir | 584 NSString* simBundlePath = [developerDir |
545 stringByAppendingPathComponent:kSimulatorFrameworkRelativePath]; | 585 stringByAppendingPathComponent:simulatorFrameworkRelativePath]; |
546 NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath]; | 586 NSBundle* simBundle = [NSBundle bundleWithPath:simBundlePath]; |
547 if (![simBundle load]) | 587 if (![simBundle load]) |
548 return nil; | 588 return nil; |
549 return simBundle; | 589 return simBundle; |
550 } | 590 } |
551 | 591 |
552 // Converts the given app path to an application spec, which requires an | 592 // Converts the given app path to an application spec, which requires an |
553 // absolute path. | 593 // absolute path. |
554 DTiPhoneSimulatorApplicationSpecifier* BuildAppSpec(NSString* appPath) { | 594 DTiPhoneSimulatorApplicationSpecifier* BuildAppSpec(NSString* appPath) { |
555 Class applicationSpecifierClass = | 595 Class applicationSpecifierClass = |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
595 sessionConfig.applicationToSimulateOnStart = appSpec; | 635 sessionConfig.applicationToSimulateOnStart = appSpec; |
596 sessionConfig.simulatedSystemRoot = systemRoot; | 636 sessionConfig.simulatedSystemRoot = systemRoot; |
597 sessionConfig.localizedClientName = @"chromium"; | 637 sessionConfig.localizedClientName = @"chromium"; |
598 sessionConfig.simulatedApplicationStdErrPath = stderrPath; | 638 sessionConfig.simulatedApplicationStdErrPath = stderrPath; |
599 sessionConfig.simulatedApplicationStdOutPath = stdoutPath; | 639 sessionConfig.simulatedApplicationStdOutPath = stdoutPath; |
600 sessionConfig.simulatedApplicationLaunchArgs = appArgs; | 640 sessionConfig.simulatedApplicationLaunchArgs = appArgs; |
601 sessionConfig.simulatedApplicationLaunchEnvironment = appEnv; | 641 sessionConfig.simulatedApplicationLaunchEnvironment = appEnv; |
602 sessionConfig.simulatedDeviceInfoName = deviceName; | 642 sessionConfig.simulatedDeviceInfoName = deviceName; |
603 sessionConfig.simulatedDeviceFamily = deviceFamily; | 643 sessionConfig.simulatedDeviceFamily = deviceFamily; |
604 | 644 |
605 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | 645 if (IsRunningWithXcode6OrLater()) { |
606 // (crbug.com/385030). | |
607 #if defined(IOSSIM_USE_XCODE_6) | 646 #if defined(IOSSIM_USE_XCODE_6) |
608 Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); | 647 Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); |
609 id simDeviceType = | 648 id simDeviceType = |
610 [simDeviceTypeClass supportedDeviceTypesByName][deviceName]; | 649 [simDeviceTypeClass supportedDeviceTypesByName][deviceName]; |
611 Class simRuntimeClass = FindClassByName(@"SimRuntime"); | 650 Class simRuntimeClass = FindClassByName(@"SimRuntime"); |
612 NSString* identifier = systemRoot.runtime.identifier; | 651 NSString* identifier = systemRoot.runtime.identifier; |
613 id simRuntime = [simRuntimeClass supportedRuntimesByIdentifier][identifier]; | 652 id simRuntime = [simRuntimeClass supportedRuntimesByIdentifier][identifier]; |
614 | 653 |
615 // Attempt to use an existing device, but create one if a suitable match can't | 654 // 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 | 655 // 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 | 656 // non-default home directory (e.g. via iossim's -u command line arg) then |
618 // devices so one will have to be created. | 657 // there won't be any devices so one will have to be created. |
619 Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); | 658 Class simDeviceSetClass = FindClassByName(@"SimDeviceSet"); |
620 id deviceSet = | 659 id deviceSet = |
621 [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; | 660 [simDeviceSetClass setForSetPath:[simDeviceSetClass defaultSetPath]]; |
622 id simDevice = nil; | 661 id simDevice = nil; |
623 for (id device in [deviceSet availableDevices]) { | 662 for (id device in [deviceSet availableDevices]) { |
624 if ([device runtime] == simRuntime && | 663 if ([device runtime] == simRuntime && |
625 [device deviceType] == simDeviceType) { | 664 [device deviceType] == simDeviceType) { |
626 simDevice = device; | 665 simDevice = device; |
627 break; | 666 break; |
667 } | |
628 } | 668 } |
669 if (!simDevice) { | |
670 NSError* error = nil; | |
671 // n.b. only the device name is necessary because the iOS Simulator menu | |
672 // already splits devices by runtime version. | |
673 NSString* name = [NSString stringWithFormat:@"iossim - %@ ", deviceName]; | |
674 simDevice = [deviceSet createDeviceWithType:simDeviceType | |
675 runtime:simRuntime | |
676 name:name | |
677 error:&error]; | |
678 if (error) { | |
679 LogError(@"Failed to create device: %@", error); | |
680 exit(kExitInitializationFailure); | |
681 } | |
682 } | |
683 sessionConfig.device = simDevice; | |
684 #endif // IOSSIM_USE_XCODE_6 | |
TVL
2014/08/22 18:27:36
#else
error out since support is missing?
#endif
lliabraa
2014/08/25 13:14:04
Acknowledged.
| |
629 } | 685 } |
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; | 686 return sessionConfig; |
647 } | 687 } |
648 | 688 |
649 // Builds a simulator session that will use the given delegate. | 689 // Builds a simulator session that will use the given delegate. |
650 DTiPhoneSimulatorSession* BuildSession(SimulatorDelegate* delegate) { | 690 DTiPhoneSimulatorSession* BuildSession(SimulatorDelegate* delegate) { |
651 Class sessionClass = FindClassByName(@"DTiPhoneSimulatorSession"); | 691 Class sessionClass = FindClassByName(@"DTiPhoneSimulatorSession"); |
652 DTiPhoneSimulatorSession* session = | 692 DTiPhoneSimulatorSession* session = |
653 [[[sessionClass alloc] init] autorelease]; | 693 [[[sessionClass alloc] init] autorelease]; |
654 session.delegate = delegate; | 694 session.delegate = delegate; |
655 return session; | 695 return session; |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
767 toolName = strdup(toolName); | 807 toolName = strdup(toolName); |
768 if (toolName != NULL) | 808 if (toolName != NULL) |
769 gToolName = toolName; | 809 gToolName = toolName; |
770 } | 810 } |
771 if (worker != NULL) | 811 if (worker != NULL) |
772 free(worker); | 812 free(worker); |
773 | 813 |
774 NSString* appPath = nil; | 814 NSString* appPath = nil; |
775 NSString* appName = nil; | 815 NSString* appName = nil; |
776 NSString* sdkVersion = nil; | 816 NSString* sdkVersion = nil; |
777 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | 817 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; | 818 NSString* simHomePath = nil; |
785 NSMutableArray* appArgs = [NSMutableArray array]; | 819 NSMutableArray* appArgs = [NSMutableArray array]; |
786 NSMutableDictionary* appEnv = [NSMutableDictionary dictionary]; | 820 NSMutableDictionary* appEnv = [NSMutableDictionary dictionary]; |
787 NSTimeInterval sessionStartTimeout = kDefaultSessionStartTimeoutSeconds; | 821 NSTimeInterval sessionStartTimeout = kDefaultSessionStartTimeoutSeconds; |
788 | 822 |
789 NSString* developerDir = FindDeveloperDir(); | 823 NSString* developerDir = FindDeveloperDir(); |
790 if (!developerDir) { | 824 if (!developerDir) { |
791 LogError(@"Unable to find developer directory."); | 825 LogError(@"Unable to find developer directory."); |
792 exit(kExitInitializationFailure); | 826 exit(kExitInitializationFailure); |
793 } | 827 } |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
880 exit(kExitInitializationFailure); | 914 exit(kExitInitializationFailure); |
881 } | 915 } |
882 | 916 |
883 // Get the paths for stdout and stderr so the simulated app's output will show | 917 // Get the paths for stdout and stderr so the simulated app's output will show |
884 // up in the caller's stdout/stderr. | 918 // up in the caller's stdout/stderr. |
885 NSString* outputDir = CreateTempDirectory(@"iossim-XXXXXX"); | 919 NSString* outputDir = CreateTempDirectory(@"iossim-XXXXXX"); |
886 NSString* stdioPath = [outputDir stringByAppendingPathComponent:@"stdio.txt"]; | 920 NSString* stdioPath = [outputDir stringByAppendingPathComponent:@"stdio.txt"]; |
887 | 921 |
888 // Determine the deviceFamily based on the deviceName | 922 // Determine the deviceFamily based on the deviceName |
889 NSNumber* deviceFamily = nil; | 923 NSNumber* deviceFamily = nil; |
890 // TODO(lliabraa): Once all builders are on Xcode 6 this ifdef can be removed | 924 if (IsRunningWithXcode6OrLater()) { |
891 // (crbug.com/385030). | |
892 #if defined(IOSSIM_USE_XCODE_6) | 925 #if defined(IOSSIM_USE_XCODE_6) |
893 Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); | 926 Class simDeviceTypeClass = FindClassByName(@"SimDeviceType"); |
894 if ([simDeviceTypeClass supportedDeviceTypesByName][deviceName] == nil) { | 927 if ([simDeviceTypeClass supportedDeviceTypesByName][deviceName] == nil) { |
895 LogError(@"Invalid device name: %@.", deviceName); | 928 LogError(@"Invalid device name: %@.", deviceName); |
896 PrintSupportedDevices(); | 929 PrintSupportedDevices(); |
897 exit(kExitInvalidArguments); | 930 exit(kExitInvalidArguments); |
931 } | |
932 #endif // IOSSIM_USE_XCODE_6 | |
TVL
2014/08/22 18:27:35
#else
error out since support is missing?
#endif
lliabraa
2014/08/25 13:14:04
Acknowledged.
| |
933 } else { | |
934 if (!deviceName || CaseInsensitivePrefixSearch(deviceName, @"iPhone")) { | |
935 deviceFamily = [NSNumber numberWithInt:kIPhoneFamily]; | |
936 } else if (CaseInsensitivePrefixSearch(deviceName, @"iPad")) { | |
937 deviceFamily = [NSNumber numberWithInt:kIPadFamily]; | |
938 } | |
939 else { | |
940 LogError(@"Invalid device name: %@. Must begin with 'iPhone' or 'iPad'", | |
941 deviceName); | |
942 exit(kExitInvalidArguments); | |
943 } | |
898 } | 944 } |
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 | 945 |
912 // Set up the user home directory for the simulator only if a non-default | 946 // Set up the user home directory for the simulator only if a non-default |
913 // value was specified. | 947 // value was specified. |
914 if (simHomePath) { | 948 if (simHomePath) { |
915 if (!InitializeSimulatorUserHome(simHomePath)) { | 949 if (!InitializeSimulatorUserHome(simHomePath)) { |
916 LogError(@"Unable to initialize home directory for simulator: %@", | 950 LogError(@"Unable to initialize home directory for simulator: %@", |
917 simHomePath); | 951 simHomePath); |
918 exit(kExitInitializationFailure); | 952 exit(kExitInitializationFailure); |
919 } | 953 } |
920 } else { | 954 } else { |
(...skipping 30 matching lines...) Expand all Loading... | |
951 [error localizedDescription], | 985 [error localizedDescription], |
952 [error domain], static_cast<long int>([error code])); | 986 [error domain], static_cast<long int>([error code])); |
953 } | 987 } |
954 | 988 |
955 // Note that this code is only executed if the simulator fails to start | 989 // 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 | 990 // because once the main run loop is started, only the delegate calling |
957 // exit() will end the program. | 991 // exit() will end the program. |
958 [pool drain]; | 992 [pool drain]; |
959 return kExitFailure; | 993 return kExitFailure; |
960 } | 994 } |
OLD | NEW |