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