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