1 package org.robolectric.internal; 2 3 import android.os.Build; 4 import java.util.ArrayList; 5 import java.util.Collection; 6 import java.util.Collections; 7 import java.util.HashMap; 8 import java.util.Map; 9 import java.util.Objects; 10 import java.util.Set; 11 import javax.annotation.Nonnull; 12 import org.robolectric.internal.dependency.DependencyJar; 13 14 public class SdkConfig implements Comparable<SdkConfig> { 15 16 private static final Map<Integer, SdkVersion> SUPPORTED_APIS = 17 Collections.unmodifiableMap( 18 new HashMap<Integer, SdkVersion>() { 19 { 20 addSdk(Build.VERSION_CODES.JELLY_BEAN, "4.1.2_r1", "r1", "REL"); 21 addSdk(Build.VERSION_CODES.JELLY_BEAN_MR1, "4.2.2_r1.2", "r1", "REL"); 22 addSdk(Build.VERSION_CODES.JELLY_BEAN_MR2, "4.3_r2", "r1", "REL"); 23 addSdk(Build.VERSION_CODES.KITKAT, "4.4_r1", "r2", "REL"); 24 addSdk(Build.VERSION_CODES.LOLLIPOP, "5.0.2_r3", "r0", "REL"); 25 addSdk(Build.VERSION_CODES.LOLLIPOP_MR1, "5.1.1_r9", "r2", "REL"); 26 addSdk(Build.VERSION_CODES.M, "6.0.1_r3", "r1", "REL"); 27 addSdk(Build.VERSION_CODES.N, "7.0.0_r1", "r1", "REL"); 28 addSdk(Build.VERSION_CODES.N_MR1, "7.1.0_r7", "r1", "REL"); 29 addSdk(Build.VERSION_CODES.O, "8.0.0_r4", "r1", "REL"); 30 addSdk(Build.VERSION_CODES.O_MR1, "8.1.0", "4611349", "REL"); 31 addSdk(Build.VERSION_CODES.P, "9", "4913185-2", "REL"); 32 addSdk(Build.VERSION_CODES.Q, "10", "5803371", "REL"); 33 // BEGIN-INTERNAL 34 addSdk(Build.VERSION_CODES.R, "R", "r0", "R"); 35 // END-INTERNAL 36 } 37 38 private void addSdk( 39 int sdkVersion, 40 String androidVersion, 41 String frameworkSdkBuildVersion, 42 String codeName) { 43 put(sdkVersion, new SdkVersion(androidVersion, frameworkSdkBuildVersion, codeName)); 44 } 45 }); 46 47 public static final int FALLBACK_SDK_VERSION = Build.VERSION_CODES.JELLY_BEAN; 48 public static final int MAX_SDK_VERSION = Collections.max(getSupportedApis()); 49 50 private final int apiLevel; 51 getSupportedApis()52 public static Set<Integer> getSupportedApis() { 53 return SUPPORTED_APIS.keySet(); 54 } 55 getSupportedSdkConfigs()56 public static Collection<SdkConfig> getSupportedSdkConfigs() { 57 ArrayList<SdkConfig> sdkConfigs = new ArrayList<>(); 58 for (int sdkVersion : getSupportedApis()) { 59 sdkConfigs.add(new SdkConfig(sdkVersion)); 60 } 61 return sdkConfigs; 62 } 63 SdkConfig(int apiLevel)64 public SdkConfig(int apiLevel) { 65 this.apiLevel = apiLevel; 66 } 67 getApiLevel()68 public int getApiLevel() { 69 return apiLevel; 70 } 71 getAndroidVersion()72 public String getAndroidVersion() { 73 return getSdkVersion().androidVersion; 74 } 75 getAndroidCodeName()76 public String getAndroidCodeName() { 77 return getSdkVersion().codeName; 78 } 79 getAndroidSdkDependency()80 public DependencyJar getAndroidSdkDependency() { 81 return createDependency("org.robolectric", "android-all", getSdkVersion().getAndroidVersion() + "-robolectric-" + getSdkVersion().getRobolectricVersion(), null); 82 } 83 84 @Override equals(Object that)85 public boolean equals(Object that) { 86 return that == this || (that instanceof SdkConfig && ((SdkConfig) that).apiLevel == (apiLevel)); 87 } 88 89 @Override hashCode()90 public int hashCode() { 91 return apiLevel; 92 } 93 94 @Override toString()95 public String toString() { 96 return "API Level " + apiLevel; 97 } 98 99 @Override compareTo(@onnull SdkConfig o)100 public int compareTo(@Nonnull SdkConfig o) { 101 return apiLevel - o.apiLevel; 102 } 103 getSdkVersion()104 private SdkVersion getSdkVersion() { 105 final SdkVersion sdkVersion = SUPPORTED_APIS.get(apiLevel); 106 if (sdkVersion == null) { 107 throw new UnsupportedOperationException("Robolectric does not support API level " + apiLevel + "."); 108 } 109 return sdkVersion; 110 } 111 createDependency(String groupId, String artifactId, String version, String classifier)112 private DependencyJar createDependency(String groupId, String artifactId, String version, String classifier) { 113 return new DependencyJar(groupId, artifactId, version, classifier); 114 } 115 116 private static final class SdkVersion { 117 private final String androidVersion; 118 private final String robolectricVersion; 119 private final String codeName; 120 SdkVersion(String androidVersion, String robolectricVersion, String codeName)121 SdkVersion(String androidVersion, String robolectricVersion, String codeName) { 122 this.androidVersion = androidVersion; 123 this.robolectricVersion = robolectricVersion; 124 this.codeName = codeName; 125 } 126 127 @Override equals(Object that)128 public boolean equals(Object that) { 129 return that == this || (that instanceof SdkVersion && isEqualTo((SdkVersion) that)); 130 } 131 132 @SuppressWarnings("ReferenceEquality") isEqualTo(SdkVersion that)133 public boolean isEqualTo(SdkVersion that) { 134 return that == this || 135 (Objects.equals(that.androidVersion, androidVersion) && 136 Objects.equals(that.robolectricVersion, robolectricVersion)); 137 } 138 139 @Override hashCode()140 public int hashCode() { 141 return androidVersion.hashCode() * 31 + robolectricVersion.hashCode(); 142 } 143 getAndroidVersion()144 public String getAndroidVersion() { 145 return androidVersion; 146 } 147 getRobolectricVersion()148 public String getRobolectricVersion() { 149 return robolectricVersion; 150 } 151 } 152 } 153