Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[jdk12 branch] fixed: missing iOS 13.3 simulators #435

Merged
merged 26 commits into from
Jan 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1190ffb
* jetbrains intellij plugin for gradle version updated
dkimitsa Nov 12, 2019
8f6ba99
* intellij maven pom reworked into stand-alone. as mvn:version is not…
dkimitsa Nov 12, 2019
960c7ed
* added sonatype repo for snapshot dependencies
dkimitsa Nov 12, 2019
939c3d4
* eclipse plugin's maven.pom switched into standalone (without) as ty…
dkimitsa Nov 12, 2019
e8e073d
* release script reworked to properly pick up new idea artifact and u…
dkimitsa Nov 12, 2019
533262e
* Idea: release script updated to use property to specify the depende…
dkimitsa Nov 15, 2019
ed1833a
Merge remote-tracking branch 'remotes/mobivm/jdk12' into jdk12
dkimitsa Nov 17, 2019
3fa7486
* version set to 2.3.10-SNAPSHOT
dkimitsa Nov 26, 2019
fd208a8
* java doc and source plugins are now always (was only for release) a…
dkimitsa Nov 26, 2019
6bfce56
* update commons-compress due to security vulnerability
dkimitsa Nov 28, 2019
14018bf
* upgraded deprecated code, as Idea 2019.3 removed old classes
dkimitsa Dec 11, 2019
d570e36
* ignore gradle files that are created once build with gradle
dkimitsa Dec 11, 2019
2a6605b
* reworked to @NotNull to minimize warnings
dkimitsa Dec 11, 2019
84b674c
* optimized imports
dkimitsa Dec 11, 2019
73e9163
* added RoboFileUtils to handle false result of file api into exceptions
dkimitsa Dec 11, 2019
7cf82c1
Merge remote-tracking branch 'mobivm/jdk12' into jdk12
dkimitsa Dec 11, 2019
15a883c
* readme updated with detailed instructions
dkimitsa Dec 12, 2019
ca22a91
* xcode setup dialog is not blocking now. as if something went wrong …
dkimitsa Dec 12, 2019
0df9f6b
* reworked to gracefully handle cases when there is no simulators in …
dkimitsa Dec 12, 2019
19e94aa
* updated to recent org.jetbrains.intellij
dkimitsa Dec 13, 2019
10ae92d
* added check for GraphicsEnvironment.isHeadless() as during plugin b…
dkimitsa Dec 13, 2019
ca3817a
* source code polish: fixes all lint warning, applied suggestions (li…
dkimitsa Dec 13, 2019
90457bd
Merge branch 'jdk12' into jdk12-wip/idea-maintenance
dkimitsa Dec 13, 2019
6cf1ce5
* reworked simulator device types. it doesn't depend today on SDK ver…
dkimitsa Dec 13, 2019
cf0758a
Merge remote-tracking branch 'remotes/mobivm/jdk12' into jdk12
dkimitsa Jan 3, 2020
e99dfe0
Merge branch 'jdk12' into jdk12-wip/sim-sdk-lookup-rework
dkimitsa Jan 3, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,60 +16,58 @@
*/
package org.robovm.compiler.target.ios;

import org.apache.commons.exec.util.StringUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.robovm.compiler.config.Arch;
import org.robovm.compiler.log.Logger;
import org.robovm.compiler.util.Executor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.robovm.compiler.config.Arch;
import org.robovm.compiler.log.Logger;
import org.robovm.compiler.util.Executor;

/**
* Simulator device types, consisting of the device type id and SDK version as
* listed by xcrun simctl devices -j list.
*/
public class DeviceType implements Comparable<DeviceType> {
public static final String PREFIX = "com.apple.CoreSimulator.SimDeviceType.";
public static final String IOS_VERSION_PREFIX = "com.apple.CoreSimulator.SimRuntime.iOS-";
public static final String PREFERRED_IPHONE_SIM_NAME = "iPhone 6";
public static final String PREFERRED_IPAD_SIM_NAME = "iPad Air";

public static final String[] ONLY_32BIT_DEVICES = {"iPhone 4", "iPhone 4s", "iPhone 5", "iPhone 5c", "iPad 2"};

public static enum DeviceFamily {
public enum DeviceFamily {
iPhone,
iPad
}

private final String deviceName;
private final String udid;
private final String state;
private final SDK sdk;
private final Version version;
private final Set<Arch> archs;

DeviceType(String deviceName, String udid, String state, SDK sdk, Set<Arch> archs) {
DeviceType(String deviceName, String udid, String state, Version version, Set<Arch> archs) {
this.deviceName = deviceName;
this.udid = udid;
this.state = state;
this.sdk = sdk;
this.version = version;
this.archs = archs;
}

public String getDeviceName() {
return deviceName;
}

public SDK getSdk() {
return sdk;
public Version getVersion() {
return version;
}

public Set<Arch> getArchs() {
Expand All @@ -80,7 +78,7 @@ public Set<Arch> getArchs() {
* @return id as understood by the AppCompiler -simdevicetype flag
*/
public String getSimpleDeviceTypeId() {
return getSimpleDeviceName() + ", " + sdk.getVersion();
return getSimpleDeviceName() + ", " + getVersion();
}

public String getSimpleDeviceName() {
Expand All @@ -94,10 +92,10 @@ public DeviceFamily getFamily() {
return DeviceFamily.iPad;
}
}

public String getUdid() {
return udid;
}
return udid;
}

public String getState() {
return getState(false);
Expand All @@ -112,62 +110,53 @@ public String getState(boolean fresh) {
}

}
return state;
return state;
}

public static List<DeviceType> listDeviceTypes() {
try {
List<SDK> sdks = SDK.listSimulatorSDKs();
Map<String, SDK> sdkMap = new HashMap<>();
for (SDK sdk : sdks) {
sdkMap.put(sdk.getVersion(), sdk);
}

String capture = new Executor(Logger.NULL_LOGGER, "xcrun").args(
"simctl", "list", "devices", "-j").execCapture();
List<DeviceType> types = new ArrayList<DeviceType>();
List<DeviceType> types = new ArrayList<>();

JSONParser parser = new JSONParser();
JSONObject deviceList = (JSONObject)((JSONObject) parser.parse(capture)).get("devices");
Iterator iter=deviceList.entrySet().iterator();
while(iter.hasNext()){
Map.Entry entry=(Map.Entry)iter.next();
String sdkMapKey = entry.getKey().toString();
if (sdkMapKey.startsWith(IOS_VERSION_PREFIX)) {
// com.apple.CoreSimulator.SimRuntime.iOS-
sdkMapKey = sdkMapKey.replace(IOS_VERSION_PREFIX, "").replace('-', '.');
} else if (sdkMapKey.startsWith("iOS ")) {
sdkMapKey = sdkMapKey.replace("iOS ","");
JSONObject deviceList = (JSONObject) ((JSONObject) parser.parse(capture)).get("devices");

for (Object value : deviceList.entrySet()) {
//noinspection rawtypes
Map.Entry entry = (Map.Entry) value;
String versionKey = entry.getKey().toString();
if (versionKey.startsWith(IOS_VERSION_PREFIX)) {
// com.apple.CoreSimulator.SimRuntime.iOS-
versionKey = versionKey.replace(IOS_VERSION_PREFIX, "").replace('-', '.');
} else if (versionKey.startsWith("iOS ")) {
versionKey = versionKey.replace("iOS ", "");
} else {
// not iOS
continue;
// not iOS
continue;
}
JSONArray devices = (JSONArray) entry.getValue();
for (Object obj : devices) {
JSONObject device = (JSONObject) obj;
SDK sdk = sdkMap.get(sdkMapKey);
boolean isAvailable = false;
if (sdk != null) {
if (device.containsKey("isAvailable")) {
Object o = device.get("isAvailable");
isAvailable = o instanceof Boolean ? (Boolean) o : "true".equals(o.toString());
} else if (device.containsKey("availability"))
isAvailable = !device.get("availability").toString().contains("unavailable");
}

if (isAvailable) {
JSONArray devices = (JSONArray) entry.getValue();
for (Object obj : devices) {
JSONObject device = (JSONObject) obj;
boolean isAvailable = false;
if (device.containsKey("isAvailable")) {
Object o = device.get("isAvailable");
isAvailable = o instanceof Boolean ? (Boolean) o : "true".equals(o.toString());
} else if (device.containsKey("availability"))
isAvailable = !device.get("availability").toString().contains("unavailable");

if (isAvailable) {
final String deviceName = device.get("name").toString();
Set<Arch> archs = new HashSet<>();
archs.add(Arch.x86);
if (!Arrays.asList(ONLY_32BIT_DEVICES).contains(deviceName)) {
archs.add(Arch.x86_64);
}

types.add(new DeviceType(deviceName, device.get("udid").toString(),
device.get("state").toString(), sdk, archs));
}
}
Set<Arch> archs = new HashSet<>();
archs.add(Arch.x86);
if (!Arrays.asList(ONLY_32BIT_DEVICES).contains(deviceName)) {
archs.add(Arch.x86_64);
}

types.add(new DeviceType(deviceName, device.get("udid").toString(),
device.get("state").toString(), Version.parse(versionKey), archs));
}
}
}

// Sort. Make sure that devices that have an id which is a prefix of
Expand All @@ -181,7 +170,7 @@ public static List<DeviceType> listDeviceTypes() {

@Override
public int compareTo(DeviceType that) {
int c = this.sdk.compareTo(that.sdk);
int c = this.version.compareTo(that.version);
if (c == 0) {
c = this.getFamily().compareTo(that.getFamily());
if (c == 0) {
Expand All @@ -192,7 +181,7 @@ public int compareTo(DeviceType that) {
}

private static List<DeviceType> filter(List<DeviceType> deviceTypes, Arch arch,
DeviceFamily family, String deviceName, String sdkVersion) {
DeviceFamily family, String deviceName, Version simVersion) {

deviceName = deviceName == null ? null : deviceName.toLowerCase();

Expand All @@ -201,7 +190,7 @@ private static List<DeviceType> filter(List<DeviceType> deviceTypes, Arch arch,
if (arch == null || type.getArchs().contains(arch)) {
if (family == null || family == type.getFamily()) {
if (deviceName == null || type.getDeviceName().toLowerCase().contains(deviceName)) {
if (sdkVersion == null || type.getSdk().getVersion().equals(sdkVersion)) {
if (simVersion == null || type.version.isSameOrBetter(simVersion)) {
result.add(type);
}
}
Expand Down Expand Up @@ -247,7 +236,7 @@ public static DeviceType getBestDeviceType(DeviceFamily family) {
* specified this method will default to {@link DeviceFamily#iPhone}.
*/
public static DeviceType getBestDeviceType(Arch arch, DeviceFamily family,
String deviceName, String sdkVersion) {
String deviceName, String deviceVersion) {

if (deviceName == null && family == null) {
family = DeviceFamily.iPhone;
Expand All @@ -262,19 +251,20 @@ public static DeviceType getBestDeviceType(Arch arch, DeviceFamily family,
DeviceType exact = null;
DeviceType bestDefault = null;
DeviceType bestAny = null;
List<DeviceType> devices = filter(listDeviceTypes(), arch, family, deviceName, sdkVersion);
Version version = deviceVersion != null ? Version.parse(deviceVersion) : null;
List<DeviceType> devices = filter(listDeviceTypes(), arch, family, deviceName, version);
for (DeviceType type : devices) {
if (deviceName != null && type.getDeviceName().equals(deviceName)) {
if (type.getDeviceName().equals(deviceName)) {
// match for specified device
if (exact == null || (sdkVersion == null && type.getSdk().getVersionCode() > exact.getSdk().getVersionCode()))
if (exact == null || (version == null && type.version.versionCode > exact.version.versionCode))
exact = type;
} else if (deviceName == null && type.getDeviceName().equals(preferredDeciveName)) {
// match for preferable device
if (bestDefault == null || (sdkVersion == null && type.getSdk().getVersionCode() > bestDefault.getSdk().getVersionCode()))
if (bestDefault == null || (version == null && type.version.versionCode > bestDefault.version.versionCode))
bestDefault = type;
} else {
// just pick one with best SDK version
if (bestAny == null || (sdkVersion == null && type.getSdk().getVersionCode() > bestAny.getSdk().getVersionCode()))
// just pick one with best version
if (bestAny == null || (version == null && type.version.versionCode > bestAny.version.versionCode))
bestAny = type;
}
}
Expand All @@ -286,15 +276,49 @@ public static DeviceType getBestDeviceType(Arch arch, DeviceFamily family,
if (best == null) {
throw new IllegalArgumentException("Unable to find a matching device "
+ "[arch=" + arch + ", family=" + family
+ ", name=" + deviceName + ", sdk=" + sdkVersion + "]");
+ ", name=" + deviceName + ", version=" + version + "]");
}
return best;
}

@Override
public String toString() {
return "DeviceType [deviceName=" + deviceName + ", sdk=" + sdk + ", archs=" + archs + "]";
return "DeviceType [deviceName=" + deviceName + ", version=" + version + ", archs=" + archs + "]";
}


/**
* simulator version
*/
public static class Version {
public final int major, minor, revision, versionCode;

public Version(int major, int minor, int revision, int versionCode) {
this.major = major;
this.minor = minor;
this.revision = revision;
this.versionCode = versionCode;
}

static Version parse(String v) {
String[] parts = StringUtils.split(v, ".");
int major = Integer.parseInt(parts[0]);
int minor = parts.length >= 2 ? Integer.parseInt(parts[1]) : 0;
int revision = parts.length >= 3 ? Integer.parseInt(parts[2]) : 0;
int versionCode = (major << 16) | (minor << 8) | revision;
return new Version(major, minor, revision, versionCode);
}

@Override
public String toString() {
return major + "." + minor + (revision != 0 ? ("." + revision) : "");
}

public int compareTo(Version other) {
return versionCode - other.versionCode;
}

public boolean isSameOrBetter(Version other) {
return versionCode >= other.versionCode;
}
}
}
Loading