Title: [260758] trunk/Tools
Revision
260758
Author
[email protected]
Date
2020-04-27 09:04:30 -0700 (Mon, 27 Apr 2020)

Log Message

Make run-safari --ios-simulator work again
https://bugs.webkit.org/show_bug.cgi?id=211008

Reviewed by Darin Adler.

While at it, removed all direct uses of device.plist, and all use of Foundation.

* Scripts/webkitdirs.pm: Stopped exporting unused simulator related functions. New
code should be using webkitpy.
(simulatorDeviceFromJSON): Helper function for parsing simctl output.
(iOSSimulatorDevices): Use simctl instead of reading device.plist.
(createiOSSimulatorDevice): Device creation appears to be synchronous, I couldn't
find any reason for waiting and retrying.
(iosSimulatorApplicationsPath): This is part of the actual fix - runtime path built
here was incorrect; switched to one provided by simctl.
(shutDownIOSSimulatorDevice): Added an early return to avoid stderr spew.
(relaunchIOSSimulator): Another part of the actual fix: open Simulator.app before booting the
simulator to have it visible; CurrentDeviceUDID doesn't work.
(iosSimulatorDeviceByUDID): Stop using device.plist.
(runIOSWebKitAppInSimulator): Stop quitting Simulator.app, we only needed to shut down
the device.
(iOSSimulatorDevicesPath): Deleted.
(quitIOSSimulator): Deleted.

Modified Paths

Diff

Modified: trunk/Tools/ChangeLog (260757 => 260758)


--- trunk/Tools/ChangeLog	2020-04-27 15:54:00 UTC (rev 260757)
+++ trunk/Tools/ChangeLog	2020-04-27 16:04:30 UTC (rev 260758)
@@ -1,3 +1,29 @@
+2020-04-27  Alexey Proskuryakov  <[email protected]>
+
+        Make run-safari --ios-simulator work again
+        https://bugs.webkit.org/show_bug.cgi?id=211008
+
+        Reviewed by Darin Adler.
+
+        While at it, removed all direct uses of device.plist, and all use of Foundation.
+
+        * Scripts/webkitdirs.pm: Stopped exporting unused simulator related functions. New
+        code should be using webkitpy.
+        (simulatorDeviceFromJSON): Helper function for parsing simctl output.
+        (iOSSimulatorDevices): Use simctl instead of reading device.plist.
+        (createiOSSimulatorDevice): Device creation appears to be synchronous, I couldn't
+        find any reason for waiting and retrying.
+        (iosSimulatorApplicationsPath): This is part of the actual fix - runtime path built
+        here was incorrect; switched to one provided by simctl.
+        (shutDownIOSSimulatorDevice): Added an early return to avoid stderr spew.
+        (relaunchIOSSimulator): Another part of the actual fix: open Simulator.app before booting the
+        simulator to have it visible; CurrentDeviceUDID doesn't work.
+        (iosSimulatorDeviceByUDID): Stop using device.plist.
+        (runIOSWebKitAppInSimulator): Stop quitting Simulator.app, we only needed to shut down
+        the device.
+        (iOSSimulatorDevicesPath): Deleted.
+        (quitIOSSimulator): Deleted.
+
 2020-04-27  Daniel Bates  <[email protected]>
 
         Text interaction tests should ensure view is not scroll instead of looking for a zoom change

Modified: trunk/Tools/Scripts/webkitdirs.pm (260757 => 260758)


--- trunk/Tools/Scripts/webkitdirs.pm	2020-04-27 15:54:00 UTC (rev 260757)
+++ trunk/Tools/Scripts/webkitdirs.pm	2020-04-27 16:04:30 UTC (rev 260758)
@@ -42,6 +42,7 @@
 use File::Spec;
 use File::Temp qw(tempdir);
 use File::stat;
+use JSON::PP;
 use List::Util;
 use POSIX;
 use Time::HiRes qw(usleep);
@@ -70,8 +71,6 @@
        &debugSafari
        &executableProductDir
        &extractNonHostConfiguration
-       &findOrCreateSimulatorForIOSDevice
-       &iosSimulatorDeviceByName
        &iosVersion
        &nmPath
        &passedConfiguration
@@ -78,9 +77,6 @@
        &prependToEnvironmentVariableList
        &printHelpAndExitForRunAndDebugWebKitAppIfNeeded
        &productDir
-       &quitIOSSimulator
-       &relaunchIOSSimulator
-       &restartIOSSimulatorDevice
        &runIOSWebKitApp
        &runMacWebKitApp
        &safariPath
@@ -93,12 +89,10 @@
        &sharedCommandLineOptionsUsage
        &shouldUseFlatpak
        &runInFlatpak
-       &shutDownIOSSimulatorDevice
        &sourceDir
        &willUseIOSDeviceSDK
        &willUseIOSSimulatorSDK
        DO_NOT_USE_OPEN_COMMAND
-       SIMULATOR_DEVICE_SUFFIX_FOR_WEBKIT_DEVELOPMENT
        USE_OPEN_COMMAND
    );
    %EXPORT_TAGS = ( );
@@ -124,8 +118,8 @@
 
 use constant USE_OPEN_COMMAND => 1; # Used in runMacWebKitApp().
 use constant DO_NOT_USE_OPEN_COMMAND => 2;
-use constant SIMULATOR_DEVICE_STATE_SHUTDOWN => "1";
-use constant SIMULATOR_DEVICE_STATE_BOOTED => "3";
+use constant SIMULATOR_DEVICE_STATE_SHUTDOWN => "Shutdown";
+use constant SIMULATOR_DEVICE_STATE_BOOTED => "Booted";
 use constant SIMULATOR_DEVICE_SUFFIX_FOR_WEBKIT_DEVELOPMENT  => "For WebKit Development";
 
 # See table "Certificate types and names" on <https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingCertificates/MaintainingCertificates.html#//apple_ref/doc/uid/TP40012582-CH31-SW41>.
@@ -1511,27 +1505,35 @@
     return portName() eq AppleWin;
 }
 
-sub iOSSimulatorDevicesPath
+sub simulatorDeviceFromJSON
 {
-    return "$ENV{HOME}/Library/Developer/CoreSimulator/Devices";
+    my $runtime = shift;
+    my $jsonDevice = shift;
+
+    return {
+        "UDID" => $jsonDevice->{udid},
+        "name" => $jsonDevice->{name},
+        "runtime" => $runtime,
+        "state" => $jsonDevice->{state},
+        "deviceType" => $jsonDevice->{deviceTypeIdentifier}
+    };
 }
 
 sub iOSSimulatorDevices
 {
-    eval "require Foundation";
-    my $devicesPath = iOSSimulatorDevicesPath();
-    opendir(DEVICES, $devicesPath);
-    my @udids = grep {
-        $_ =~ m/^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$/;
-    } readdir(DEVICES);
-    close(DEVICES);
+    my $output = `xcrun simctl list devices --json`;
+    my $runtimes = decode_json($output)->{devices};
+    if (!$runtimes) {
+        die "No simulator devices found";
+    }
 
-    # FIXME: We should parse the device.plist file ourself and map the dictionary keys in it to known
-    #        dictionary keys so as to decouple our representation of the plist from the actual structure
-    #        of the plist, which may change.
-    my @devices = map {
-        Foundation::perlRefFromObjectRef(NSDictionary->dictionaryWithContentsOfFile_("$devicesPath/$_/device.plist"));
-    } @udids;
+    my @devices = ();
+    while ((my $runtime, my $devicesForRuntime) = each %$runtimes) {
+        foreach my $jsonDevice (@$devicesForRuntime) {
+            next if $jsonDevice->{availabilityError};
+            push @devices, simulatorDeviceFromJSON($runtime, $jsonDevice);
+        }
+    }
 
     return @devices;
 }
@@ -1545,18 +1547,12 @@
     my $created = system("xcrun", "--sdk", "iphonesimulator", "simctl", "create", $name, $deviceTypeId, $runtimeId) == 0;
     die "Couldn't create simulator device: $name $deviceTypeId $runtimeId" if not $created;
 
-    system("xcrun", "--sdk", "iphonesimulator", "simctl", "list");
+    my @devices = iOSSimulatorDevices();
+    foreach my $device (@devices) {
+        return $device if $device->{name} eq $name and $device->{deviceType} eq $deviceTypeId and $device->{runtime} eq $runtimeId;
+    }
 
-    print "Waiting for device to be created ...\n";
-    sleep 5;
-    for (my $tries = 0; $tries < 5; $tries++){
-        my @devices = iOSSimulatorDevices();
-        foreach my $device (@devices) {
-            return $device if $device->{name} eq $name and $device->{deviceType} eq $deviceTypeId and $device->{runtime} eq $runtimeId;
-        }
-        sleep 5;
-    }
-    die "Device $name $deviceTypeId $runtimeId wasn't found in " . iOSSimulatorDevicesPath();
+    die "Device $name $deviceTypeId $runtimeId wasn't found";
 }
 
 sub willUseIOSDeviceSDK()
@@ -2642,13 +2638,13 @@
 
 sub iosSimulatorApplicationsPath()
 {
-    # FIXME: We should ask simctl for this information, instead of guessing from available runtimes.
-    my $runtimePath = File::Spec->catdir(sdkPlatformDirectory("iphoneos"), "Library", "Developer", "CoreSimulator", "Profiles", "Runtimes");
-    opendir(RUNTIMES, $runtimePath);
-    my @runtimes = grep {/.*\.simruntime/} readdir(RUNTIMES);
-    close(RUNTIMES);
-    my $sult = File::Spec->catdir($runtimePath, @runtimes ? $runtimes[0] : "iOS.simruntime", "Contents", "Resources", "RuntimeRoot", "Applications");
-    return $sult;
+    my $output = `xcrun simctl list runtimes iOS --json`;
+    my $runtimes = decode_json($output)->{runtimes};
+    if (!$runtimes) {
+        die "No iOS simulator runtimes found";
+    }
+    my $runtimePath = @$runtimes[0]->{runtimeRoot};
+    return File::Spec->catdir($runtimePath, "Applications");
 }
 
 sub installedMobileSafariBundle()
@@ -2713,6 +2709,8 @@
 sub shutDownIOSSimulatorDevice($)
 {
     my ($simulatorDevice) = @_;
+
+    return if $simulatorDevice->{state} eq SIMULATOR_DEVICE_STATE_SHUTDOWN;
     system("xcrun --sdk iphonesimulator simctl shutdown $simulatorDevice->{UDID} > /dev/null 2>&1");
 }
 
@@ -2727,36 +2725,18 @@
 sub relaunchIOSSimulator($)
 {
     my ($simulatedDevice) = @_;
-    quitIOSSimulator($simulatedDevice->{UDID});
+    shutDownIOSSimulatorDevice($simulatedDevice);
 
-    # FIXME: <rdar://problem/20916140> Switch to using CoreSimulator.framework for launching and quitting iOS Simulator
     chomp(my $developerDirectory = $ENV{DEVELOPER_DIR} || `xcode-select --print-path`); 
-    my $iosSimulatorPath = File::Spec->catfile($developerDirectory, "Applications", "Simulator.app"); 
+    my $iosSimulatorPath = File::Spec->catfile($developerDirectory, "Applications", "Simulator.app");
+    # Simulator.app needs to be running before the simulator is booted to have it visible.
     system("open", "-a", $iosSimulatorPath, "--args", "-CurrentDeviceUDID", $simulatedDevice->{UDID}) == 0 or die "Failed to open $iosSimulatorPath: $!"; 
+    system("xcrun", "simctl", "boot", $simulatedDevice->{UDID}) == 0 or die "Failed to boot simulator $simulatedDevice->{UDID}: $!"; 
 
     waitUntilIOSSimulatorDeviceIsInState($simulatedDevice->{UDID}, SIMULATOR_DEVICE_STATE_BOOTED);
     waitUntilProcessNotRunning("com.apple.datamigrator");
 }
 
-sub quitIOSSimulator(;$)
-{
-    my ($waitForShutdownOfSimulatedDeviceUDID) = @_;
-    # FIXME: <rdar://problem/20916140> Switch to using CoreSimulator.framework for launching and quitting iOS Simulator
-    if (exitStatus(system {"osascript"} "osascript", "-e", 'tell application id "com.apple.iphonesimulator" to quit')) {
-        # osascript returns a non-zero exit status if Simulator.app is not registered in LaunchServices.
-        return;
-    }
-
-    if (!defined($waitForShutdownOfSimulatedDeviceUDID)) {
-        return;
-    }
-    # FIXME: We assume that $waitForShutdownOfSimulatedDeviceUDID was not booted using the simctl command line tool.
-    #        Otherwise we will spin indefinitely since quiting the iOS Simulator will not shutdown this device. We
-    #        should add a maximum time limit to wait for a device to shutdown and either return an error or die()
-    #        on expiration of the time limit.
-    waitUntilIOSSimulatorDeviceIsInState($waitForShutdownOfSimulatedDeviceUDID, SIMULATOR_DEVICE_STATE_SHUTDOWN);
-}
-
 sub iosSimulatorDeviceByName($)
 {
     my ($simulatorName) = @_;
@@ -2773,15 +2753,16 @@
 sub iosSimulatorDeviceByUDID($)
 {
     my ($simulatedDeviceUDID) = @_;
-    my $devicePlistPath = File::Spec->catfile(iOSSimulatorDevicesPath(), $simulatedDeviceUDID, "device.plist");
-    if (!-f $devicePlistPath) {
-        return;
+
+    my $output = `xcrun simctl list devices $simulatedDeviceUDID --json`;
+    my $runtimes = decode_json($output)->{devices};
+
+    while ((my $runtime, my $devicesForRuntime) = each %$runtimes) {
+        next if not @$devicesForRuntime;
+        die "Multiple devices found for UDID $simulatedDeviceUDID: $output" if scalar(@$devicesForRuntime) > 1;
+        return simulatorDeviceFromJSON($runtime, @$devicesForRuntime[0]);        
     }
-    # FIXME: We should parse the device.plist file ourself and map the dictionary keys in it to known
-    #        dictionary keys so as to decouple our representation of the plist from the actual structure
-    #        of the plist, which may change.
-    eval "require Foundation";
-    return Foundation::perlRefFromObjectRef(NSDictionary->dictionaryWithContentsOfFile_($devicePlistPath));
+    return undef;
 }
 
 sub iosSimulatorRuntime()
@@ -2871,7 +2852,7 @@
             # was previously overwritten with a custom built version of the app.
             # FIXME: Only restore the system-installed version of the app instead of erasing all contents and settings.
             print "Quitting iOS Simulator...\n";
-            quitIOSSimulator($simulatedDeviceUDID);
+            shutDownIOSSimulatorDevice($simulatedDevice);
             print "Erasing contents and settings for simulator device \"$simulatedDevice->{name}\".\n";
             exitStatus(system("xcrun", "--sdk", "iphonesimulator", "simctl", "erase", $simulatedDeviceUDID)) == 0 or die;
         }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to