Title: [178601] trunk/Tools
Revision
178601
Author
[email protected]
Date
2015-01-16 13:58:28 -0800 (Fri, 16 Jan 2015)

Log Message

REGRESSION (r171968): run-safari --simulator fails to launch Safari on iOS
https://bugs.webkit.org/show_bug.cgi?id=135589

Reviewed by David Kilzer.

Derived from a patch by David Farler.

Following the removal IPhoneSimulatorNotification.pm in <http://trac.webkit.org/changeset/171968>
run-safari --simulator fails to launch Safari on iOS. We need to implement run-safari
in terms of the simctl command line utility.

* Scripts/webkitdirs.pm: Added constant SIMULATOR_DEVICE_STATE_BOOTED.
(eraseIOSSimulatorDevice): Added.
(bootedIOSSimulatorDevice): Added.
(iosSimulatorApplicationsPath): Added.
(installedMobileSafariBundle): Implemented in terms of iosSimulatorApplicationsPath().
(openIOSSimulator): Modified to launch iOS Simulator using OPEN(1).
(quitIOSSimulator): Added.
(iosSimulatorDeviceByName): Modified to find the first simulator device that matches
the specified name and currently selected iOS runtime.
(isIOSSimulatorSystemInstalledApp): Added.
(runIOSWebKitAppInSimulator): Modified to use simctl launch to launch an app in the simulator.
(deleteiOSSimulatorDevice): Deleted.
(loadIPhoneSimulatorNotificationIfNeeded): Deleted.
(installAndLaunchIOSWebKitAppInSimulator): Deleted.

Modified Paths

Diff

Modified: trunk/Tools/ChangeLog (178600 => 178601)


--- trunk/Tools/ChangeLog	2015-01-16 21:42:50 UTC (rev 178600)
+++ trunk/Tools/ChangeLog	2015-01-16 21:58:28 UTC (rev 178601)
@@ -1,3 +1,31 @@
+2015-01-16  Daniel Bates  <[email protected]>
+
+        REGRESSION (r171968): run-safari --simulator fails to launch Safari on iOS
+        https://bugs.webkit.org/show_bug.cgi?id=135589
+
+        Reviewed by David Kilzer.
+
+        Derived from a patch by David Farler.
+
+        Following the removal IPhoneSimulatorNotification.pm in <http://trac.webkit.org/changeset/171968>
+        run-safari --simulator fails to launch Safari on iOS. We need to implement run-safari
+        in terms of the simctl command line utility.
+
+        * Scripts/webkitdirs.pm: Added constant SIMULATOR_DEVICE_STATE_BOOTED.
+        (eraseIOSSimulatorDevice): Added.
+        (bootedIOSSimulatorDevice): Added.
+        (iosSimulatorApplicationsPath): Added.
+        (installedMobileSafariBundle): Implemented in terms of iosSimulatorApplicationsPath().
+        (openIOSSimulator): Modified to launch iOS Simulator using OPEN(1).
+        (quitIOSSimulator): Added.
+        (iosSimulatorDeviceByName): Modified to find the first simulator device that matches
+        the specified name and currently selected iOS runtime.
+        (isIOSSimulatorSystemInstalledApp): Added.
+        (runIOSWebKitAppInSimulator): Modified to use simctl launch to launch an app in the simulator.
+        (deleteiOSSimulatorDevice): Deleted.
+        (loadIPhoneSimulatorNotificationIfNeeded): Deleted.
+        (installAndLaunchIOSWebKitAppInSimulator): Deleted.
+
 2015-01-16  Alex Christensen  <[email protected]>
 
         Resurrect the WinCairo bot.

Modified: trunk/Tools/Scripts/webkitdirs.pm (178600 => 178601)


--- trunk/Tools/Scripts/webkitdirs.pm	2015-01-16 21:42:50 UTC (rev 178600)
+++ trunk/Tools/Scripts/webkitdirs.pm	2015-01-16 21:58:28 UTC (rev 178601)
@@ -33,6 +33,7 @@
 use version;
 use warnings;
 use Config;
+use Cwd qw(realpath);
 use Digest::MD5 qw(md5_hex);
 use FindBin;
 use File::Basename;
@@ -63,7 +64,6 @@
        &currentSVNRevision
        &debugSafari
        &findOrCreateSimulatorForIOSDevice
-       &installAndLaunchIOSWebKitAppInSimulator
        &iosSimulatorDeviceByName
        &nmPath
        &openIOSSimulator
@@ -86,6 +86,7 @@
 
 use constant USE_OPEN_COMMAND => 1; # Used in runMacWebKitApp().
 use constant INCLUDE_OPTIONS_FOR_DEBUGGING => 1;
+use constant SIMULATOR_DEVICE_STATE_BOOTED => "3";
 
 our @EXPORT_OK;
 
@@ -1178,12 +1179,23 @@
     die "Device $name $deviceTypeId $runtimeId wasn't found in " . iOSSimulatorDevicesPath();
 }
 
-sub deleteiOSSimulatorDevice
+sub eraseIOSSimulatorDevice($)
 {
     my $udid = shift;
-    return system("xcrun", "--sdk", "iphonesimulator", "simctl", "delete", $udid);
+    return exitStatus(system("xcrun", "--sdk", "iphonesimulator", "simctl", "erase", $udid)) == 0;
 }
 
+sub bootedIOSSimulatorDevice()
+{
+    my @devices = iOSSimulatorDevices();
+    for my $device (@devices) {
+        if ($device->{state} eq SIMULATOR_DEVICE_STATE_BOOTED) {
+            return $device;
+        }
+    }
+    return undef;
+}
+
 sub willUseIOSDeviceSDKWhenBuilding()
 {
     return xcodeSDKPlatformName() eq "iphoneos";
@@ -2026,9 +2038,14 @@
     setUpGuardMallocIfNeeded();
 }
 
+sub iosSimulatorApplicationsPath()
+{
+    return File::Spec->catdir(XcodeSDKPath(), "Applications");
+}
+
 sub installedMobileSafariBundle()
 {
-    return File::Spec->catfile(XcodeSDKPath(), "Applications", "MobileSafari.app");
+    return File::Spec->catfile(iosSimulatorApplicationsPath(), "MobileSafari.app");
 }
 
 sub mobileSafariBundle()
@@ -2066,44 +2083,36 @@
     return $bundleDisplayName;
 }
 
-sub loadIPhoneSimulatorNotificationIfNeeded()
+sub openIOSSimulator($)
 {
-    return if $didLoadIPhoneSimulatorNotification;
-    push(@INC, productDir() . "/lib/perl5/darwin-thread-multi-2level");
-    require IPhoneSimulatorNotification;
-    $didLoadIPhoneSimulatorNotification = 1;
-}
-
-sub openIOSSimulator()
-{
+    my ($simulatedDevice) = @_;
     chomp(my $developerDirectory = $ENV{DEVELOPER_DIR} || `xcode-select --print-path`);
     my $iosSimulatorPath = File::Spec->catfile($developerDirectory, "Applications", "iOS Simulator.app");
 
-    loadIPhoneSimulatorNotificationIfNeeded();
+    system("open", "-a", $iosSimulatorPath, "--args", "-CurrentDeviceUDID", $simulatedDevice->{UDID}) == 0 or die "Failed to open $iosSimulatorPath: $!";
+    my $device;
+    do {
+        $device = iosSimulatorDeviceByName($simulatedDevice->{name});
+        sleep(2);
+    } while ($device->{state} ne SIMULATOR_DEVICE_STATE_BOOTED);
+}
 
-    my $iPhoneSimulatorNotification = new IPhoneSimulatorNotification;
-    $iPhoneSimulatorNotification->startObservingReadyNotification();
-    system("open", "-a", $iosSimulatorPath, "--args", "-SessionOnLaunch", "NO") == 0 or die "Failed to open $iosSimulatorPath: $!";
-    while (!$iPhoneSimulatorNotification->hasReceivedReadyNotification()) {
-        my $date = NSDate->alloc()->initWithTimeIntervalSinceNow_(0.1);
-        NSRunLoop->currentRunLoop->runUntilDate_($date);
-        $date->release();
-    }
-    $iPhoneSimulatorNotification->stopObservingReadyNotification();
+sub quitIOSSimulator()
+{
+    return system {"osascript"} "osascript", "-e", 'tell application "iOS Simulator" to quit';
 }
 
 sub iosSimulatorDeviceByName($)
 {
     my ($simulatorName) = @_;
-    my @devices = grep {$_->{name} eq $simulatorName} iOSSimulatorDevices();
-    my $deviceToUse = $devices[0];
-    if (@devices > 1) {
-        print "Warning: Found more than one simulator device named '$simulatorName'.\n";
-        print "         Using simulator device with UDID: $deviceToUse->{UDID}.\n";
-        print "         To see the list of simulator devices, run:\n";
-        print "         xcrun --sdk iphonesimulator simctl list\n";
+    my $simulatorRuntime = iosSimulatorRuntime();
+    my @devices = iOSSimulatorDevices();
+    for my $device (@devices) {
+        if ($device->{name} eq $simulatorName && $device->{runtime} eq $simulatorRuntime) {
+            return $device;
+        }
     }
-    return $deviceToUse;
+    return undef;
 }
 
 sub iosSimulatorRuntime()
@@ -2130,13 +2139,26 @@
     return createiOSSimulatorDevice($simulatorName, $simulatorDeviceType, iosSimulatorRuntime());
 }
 
+sub isIOSSimulatorSystemInstalledApp($)
+{
+    my ($appBundle) = @_;
+    my $simulatorApplicationsPath = iosSimulatorApplicationsPath();
+    return substr(realpath($appBundle), 0, length($simulatorApplicationsPath)) eq $simulatorApplicationsPath;
+}
+
 sub runIOSWebKitAppInSimulator($;$)
 {
     my ($appBundle, $simulatorOptions) = @_;
     my $productDir = productDir();
-    my $appDisplayName = appDisplayNameFromBundle($appBundle);
-    print "Starting $appDisplayName with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
+    my $appDisplayName = appDisplayNameFromBundle($appBundle);;
+    my $simulatedDevice = findOrCreateSimulatorForIOSDevice("For WebKit Development");
 
+    my $bootedSimulatorDevice = bootedIOSSimulatorDevice();
+    if (!$bootedSimulatorDevice || $bootedSimulatorDevice->{UDID} ne $simulatedDevice->{UDID}) {
+        quitIOSSimulator();
+        openIOSSimulator($simulatedDevice);
+    }
+
     $simulatorOptions = {} unless $simulatorOptions;
 
     my %simulatorENV;
@@ -2146,79 +2168,23 @@
         setupIOSWebKitEnvironment($productDir);
         %simulatorENV = %ENV;
     }
-    $simulatorOptions->{applicationEnvironment} = \%simulatorENV;
-    return installAndLaunchIOSWebKitAppInSimulator($appBundle, findOrCreateSimulatorForIOSDevice("For WebKit Development"), $simulatorOptions) <= 0;
-}
-
-# Launches the iOS WebKit-based application in the specified simulator device and dynamically
-# linked against the built WebKit. The application will be installed if applicable.
-#
-# Args:
-#   $appBundle: the path to the app bundle to launch.
-#   $simulatedDevice: the simulator device to use to run the app.
-#   $simulatorOptions: a hash reference representing optional simulator options.
-#     sessionUUID: a unique identifier to use for the iOS Simulator session. Defaults to an identifier
-#                  of the form "theAwesomeUniqueSessionIdentifierForX" where X is the display name of
-#                  the specified app.
-#     applicationArguments: an array reference representing the arguments to pass to the app (defaults to \@ARGV).
-#     applicationEnvironment: a hash reference representing the environment variables to use when launching the app (defaults to {}).
-#
-# Returns the process identifier of the launched app.
-sub installAndLaunchIOSWebKitAppInSimulator($$;$)
-{
-    my ($appBundle, $simulatedDevice, $simulatorOptions) = @_;
-
-    loadIPhoneSimulatorNotificationIfNeeded();
-
-    my $makeNSDictionaryFromHash = sub {
-        my ($dict) = @_;
-        my $result = NSMutableDictionary->alloc()->initWithCapacity_(scalar(keys %{$dict}));
-        for my $key (keys %{$dict}) {
-            $result->setObject_forKey_(NSString->stringWithCString_($dict->{$key}), NSString->stringWithCString_($key));
-        }
-        return $result->autorelease();
-    };
-    my $makeNSArrayFromArray = sub {
-        my ($array) = @_;
-        my $result = NSMutableArray->alloc()->initWithCapacity_(scalar(@{$array}));
-        for my $item (@{$array}) {
-            $result->addObject_(NSString->stringWithCString_($item));
-        }
-        return $result->autorelease();
-    };
-
-    my $simulatorENVHashRef = {};
-    $simulatorENVHashRef = $simulatorOptions->{applicationEnvironment} if $simulatorOptions && $simulatorOptions->{applicationEnvironment};
     my $applicationArguments = \@ARGV;
     $applicationArguments = $simulatorOptions->{applicationArguments} if $simulatorOptions && $simulatorOptions->{applicationArguments};
-    my $sessionUUID;
-    if ($simulatorOptions && $simulatorOptions->{sessionUUID}) {
-        $sessionUUID = $simulatorOptions->{sessionUUID};
-    } else {
-        $sessionUUID = "theAwesomeUniqueSessionIdentifierFor" . appDisplayNameFromBundle($appBundle);
+
+    # Prefix the environment variables with SIMCTL_CHILD_ per `xcrun simctl help launch`.
+    foreach my $key (keys %simulatorENV) {
+        $ENV{"SIMCTL_CHILD_$key"} = $simulatorENV{$key};
     }
-    # FIXME: We should have the iOS application adopt the files descriptors for our standard output and error streams.
-    my $sessionInfo = {
-        applicationArguments => &$makeNSArrayFromArray($applicationArguments),
-        applicationEnvironment => &$makeNSDictionaryFromHash($simulatorENVHashRef),
-        applicationIdentifier => NSString->stringWithCString_(appIdentifierFromBundle($appBundle)),
-        applicationPath => NSString->stringWithCString_($appBundle),
-        deviceUDID => NSString->stringWithCString_($simulatedDevice->{UDID}),
-        sessionUUID => NSString->stringWithCString_($sessionUUID),
-    };
 
-    openIOSSimulator();
-
-    my $iPhoneSimulatorNotification = new IPhoneSimulatorNotification;
-    $iPhoneSimulatorNotification->startObservingApplicationLaunchedNotification();
-    $iPhoneSimulatorNotification->postStartSessionNotification($sessionInfo);
-    while (!$iPhoneSimulatorNotification->hasReceivedApplicationLaunchedNotification()) {
-        my $date = NSDate->alloc()->initWithTimeIntervalSinceNow_(0.1);
-        NSRunLoop->currentRunLoop->runUntilDate_($date);
-        $date->release();
+    # FIXME: We should also erase the iOS Simulator device when alternating between running a
+    # custom-built MobileSafari and the system-installed MobileSafari.
+    if (!isIOSSimulatorSystemInstalledApp($appBundle)) {
+        eraseIOSSimulatorDevice($simulatedDevice->{UDID}) or die;
     }
-    $iPhoneSimulatorNotification->stopObservingApplicationLaunchedNotification();
-    return $iPhoneSimulatorNotification->applicationLaunchedApplicationPID();
+
+    my $appIdentifier = appIdentifierFromBundle($appBundle);
+    print "Starting $appDisplayName with DYLD_FRAMEWORK_PATH set to point to built WebKit in $productDir.\n";
+    return exitStatus(system("xcrun", "--sdk", "iphonesimulator", "simctl", "launch", $simulatedDevice->{UDID}, $appIdentifier, @$applicationArguments));
 }
 
 sub runIOSWebKitApp($)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to