SdkConfig.java revision 104b292a58958d310fcb27472fd7e450b3d99946
1package org.robolectric.internal; 2 3import android.os.Build; 4import org.jetbrains.annotations.NotNull; 5import org.robolectric.internal.dependency.DependencyJar; 6import org.robolectric.util.Logger; 7 8import java.io.IOException; 9import java.io.InputStream; 10import java.util.Collections; 11import java.util.HashMap; 12import java.util.Map; 13import java.util.Objects; 14import java.util.Properties; 15import java.util.Set; 16 17public class SdkConfig implements Comparable<SdkConfig> { 18 private static final String ROBOLECTRIC_VERSION = getRobolectricVersion(); 19 20 private static final Map<Integer, SdkVersion> SUPPORTED_APIS = Collections.unmodifiableMap(new HashMap<Integer, SdkVersion>() { 21 private final double jdkVersion = Double.parseDouble(System.getProperty("java.specification.version")); 22 23 { 24 addSdk(Build.VERSION_CODES.JELLY_BEAN, "4.1.2_r1", "0", "1.6"); 25 addSdk(Build.VERSION_CODES.JELLY_BEAN_MR1, "4.2.2_r1.2", "0", "1.6"); 26 addSdk(Build.VERSION_CODES.JELLY_BEAN_MR2, "4.3_r2", "0", "1.6"); 27 addSdk(Build.VERSION_CODES.KITKAT, "4.4_r1", "1", "1.7"); 28 addSdk(Build.VERSION_CODES.LOLLIPOP, "5.0.0_r2", "1", "1.7"); 29 addSdk(Build.VERSION_CODES.LOLLIPOP_MR1, "5.1.1_r9", "1", "1.7"); 30 addSdk(Build.VERSION_CODES.M, "6.0.1_r3", "0", "1.7"); 31 addSdk(Build.VERSION_CODES.N, "7.0.0_r1", "0", "1.8"); 32 addSdk(Build.VERSION_CODES.N_MR1, "7.1.0_r7", "0", "1.8"); 33 } 34 35 private void addSdk(int sdkVersion, String androidVersion, String frameworkSdkBuildVersion, String minJdkVersion) { 36 if (jdkVersion >= Double.parseDouble(minJdkVersion)) { 37 put(sdkVersion, new SdkVersion(androidVersion, frameworkSdkBuildVersion)); 38 } else { 39 Logger.info("Android SDK %s not supported on JDK %s (it requires %s)", sdkVersion, jdkVersion, minJdkVersion); 40 } 41 } 42 }); 43 44 public static final int FALLBACK_SDK_VERSION = Build.VERSION_CODES.JELLY_BEAN; 45 public static final int MAX_SDK_VERSION = Collections.max(getSupportedApis()); 46 47 private final int apiLevel; 48 private final SdkVersion sdkVersion; 49 50 public static Set<Integer> getSupportedApis() { 51 return SUPPORTED_APIS.keySet(); 52 } 53 54 public SdkConfig(int apiLevel) { 55 this.apiLevel = apiLevel; 56 sdkVersion = SUPPORTED_APIS.get(apiLevel); 57 if (sdkVersion == null) { 58 throw new UnsupportedOperationException("Robolectric does not support API level " + apiLevel + "."); 59 } 60 } 61 62 public int getApiLevel() { 63 return apiLevel; 64 } 65 66 public String getAndroidVersion() { 67 return sdkVersion.androidVersion; 68 } 69 70 public DependencyJar getAndroidSdkDependency() { 71 return createDependency("org.robolectric", "android-all", sdkVersion.toString(), null); 72 } 73 74 public DependencyJar getCoreShadowsDependency() { 75 return createDependency("org.robolectric", "shadows-core", ROBOLECTRIC_VERSION, null); 76 } 77 78 @Override 79 public boolean equals(Object that) { 80 return that == this || that instanceof SdkConfig && ((SdkConfig) that).sdkVersion.equals(sdkVersion); 81 } 82 83 @Override 84 public String toString() { 85 return "API Level " + apiLevel; 86 } 87 88 @Override 89 public int hashCode() { 90 return sdkVersion.hashCode(); 91 } 92 93 @Override 94 public int compareTo(@NotNull SdkConfig o) { 95 return getApiLevel() - o.getApiLevel(); 96 } 97 98 private DependencyJar createDependency(String groupId, String artifactId, String version, String classifier) { 99 return new DependencyJar(groupId, artifactId, version, classifier); 100 } 101 102 private static String getRobolectricVersion() { 103 ClassLoader classLoader = SdkVersion.class.getClassLoader(); 104 try (InputStream is = classLoader.getResourceAsStream("robolectric-version.properties")) { 105 final Properties properties = new Properties(); 106 properties.load(is); 107 return properties.getProperty("robolectric.version"); 108 } catch (IOException e) { 109 throw new RuntimeException("Error determining Robolectric version: " + e.getMessage()); 110 } 111 } 112 113 private static final class SdkVersion { 114 private final String androidVersion; 115 private final String robolectricVersion; 116 117 SdkVersion(String androidVersion, String robolectricVersion) { 118 this.androidVersion = androidVersion; 119 this.robolectricVersion = robolectricVersion; 120 } 121 122 @Override 123 public boolean equals(Object that) { 124 return that == this || that instanceof SdkVersion && equals((SdkVersion) that); 125 } 126 127 public boolean equals(SdkVersion that) { 128 return that == this || 129 Objects.equals(that.androidVersion, androidVersion) && 130 Objects.equals(that.robolectricVersion, robolectricVersion); 131 } 132 133 @Override 134 public int hashCode() { 135 return androidVersion.hashCode() * 31 + robolectricVersion.hashCode(); 136 } 137 138 @Override 139 public String toString() { 140 return androidVersion + "-robolectric-" + robolectricVersion; 141 } 142 } 143} 144