Merge "Don't use Executors.newSingleThreadExecutor()"
diff --git a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
index 7645242..e659231 100644
--- a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
+++ b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
@@ -4,6 +4,7 @@
 package com.android.tools.r8;
 
 import com.android.tools.r8.dex.Constants;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.FileUtils;
 import com.android.tools.r8.utils.OutputMode;
@@ -67,7 +68,7 @@
     private Path outputPath = null;
     private OutputMode outputMode = OutputMode.Indexed;
     private CompilationMode mode;
-    private int minApiLevel = Constants.DEFAULT_ANDROID_API;
+    private int minApiLevel = AndroidApiLevel.getDefault().getLevel();
 
     protected Builder(CompilationMode mode) {
       this(AndroidApp.builder(), mode, false);
diff --git a/src/main/java/com/android/tools/r8/compatdx/CompatDx.java b/src/main/java/com/android/tools/r8/compatdx/CompatDx.java
index fdd5964..c0d4bbb 100644
--- a/src/main/java/com/android/tools/r8/compatdx/CompatDx.java
+++ b/src/main/java/com/android/tools/r8/compatdx/CompatDx.java
@@ -22,6 +22,7 @@
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.logging.Log;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.FileUtils;
 import com.android.tools.r8.utils.ThreadUtils;
 import com.google.common.collect.ImmutableList;
@@ -298,7 +299,7 @@
         List<Integer> allMinApiLevels = options.valuesOf(spec.minApiLevel);
         minApiLevel = allMinApiLevels.get(allMinApiLevels.size() - 1);
       } else {
-        minApiLevel = Constants.DEFAULT_ANDROID_API;
+        minApiLevel = AndroidApiLevel.getDefault().getLevel();
       }
       inputList = options.valueOf(spec.inputList);
       inputs = ImmutableList.copyOf(options.valuesOf(spec.inputs));
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
index 9aa712a..6169178 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
@@ -3,11 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.dex;
 
-import static com.android.tools.r8.dex.Constants.ANDROID_N_API;
 import static com.android.tools.r8.dex.Constants.ANDROID_N_DEX_VERSION;
-import static com.android.tools.r8.dex.Constants.ANDROID_O_API;
 import static com.android.tools.r8.dex.Constants.ANDROID_O_DEX_VERSION;
-import static com.android.tools.r8.dex.Constants.DEFAULT_ANDROID_API;
 import static com.android.tools.r8.graph.ClassKind.CLASSPATH;
 import static com.android.tools.r8.graph.ClassKind.LIBRARY;
 import static com.android.tools.r8.graph.ClassKind.PROGRAM;
@@ -27,6 +24,7 @@
 import com.android.tools.r8.graph.JarClassFileReader;
 import com.android.tools.r8.graph.LazyLoadedDexApplication;
 import com.android.tools.r8.naming.ProguardMapReader;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.ClassProvider;
 import com.android.tools.r8.utils.ClasspathClassCollection;
@@ -98,7 +96,7 @@
 
   private int verifyOrComputeMinApiLevel(int computedMinApiLevel, DexFile file) {
     int version = file.getDexVersion();
-    if (options.minApiLevel == DEFAULT_ANDROID_API) {
+    if (options.minApiLevel == AndroidApiLevel.getDefault().getLevel()) {
       computedMinApiLevel = Math.max(computedMinApiLevel, dexVersionToMinSdk(version));
     } else if (!minApiMatchesDexVersion(version)) {
       throw new CompilationError("Dex file with version '" + version +
@@ -110,9 +108,9 @@
   private boolean minApiMatchesDexVersion(int version) {
     switch (version) {
       case ANDROID_O_DEX_VERSION:
-        return options.minApiLevel >= ANDROID_O_API;
+        return options.minApiLevel >= AndroidApiLevel.O.getLevel();
       case ANDROID_N_DEX_VERSION:
-        return options.minApiLevel >= ANDROID_N_API;
+        return options.minApiLevel >= AndroidApiLevel.N.getLevel();
       default:
         return true;
     }
@@ -121,11 +119,11 @@
   private int dexVersionToMinSdk(int version) {
     switch (version) {
       case ANDROID_O_DEX_VERSION:
-        return ANDROID_O_API;
+        return AndroidApiLevel.O.getLevel();
       case ANDROID_N_DEX_VERSION:
-        return ANDROID_N_API;
+        return AndroidApiLevel.N.getLevel();
       default:
-        return DEFAULT_ANDROID_API;
+        return AndroidApiLevel.getDefault().getLevel();
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/dex/Constants.java b/src/main/java/com/android/tools/r8/dex/Constants.java
index d2e457b..58ff5d7 100644
--- a/src/main/java/com/android/tools/r8/dex/Constants.java
+++ b/src/main/java/com/android/tools/r8/dex/Constants.java
@@ -11,13 +11,6 @@
   public static final byte[] VDEX_FILE_MAGIC_PREFIX = {'v', 'd', 'e', 'x'};
   public static final byte[] VDEX_FILE_VERSION = {'0', '1', '0', '\0'};
 
-  public static final int ANDROID_O_API = 26;
-  public static final int ANDROID_N_API = 24;
-  public static final int ANDROID_L_API = 21;
-  public static final int ANDROID_K_API = 19;
-  public static final int ANDROID_I_API = 14;
-  public static final int DEFAULT_ANDROID_API = 1;
-
   /** dex file version number for Android O (API level 26) */
   public static final int ANDROID_O_DEX_VERSION = 38;
   public static final byte[] ANDROID_O_DEX_VERSION_BYTES = {'0', '3', '8'};
diff --git a/src/main/java/com/android/tools/r8/dex/FileWriter.java b/src/main/java/com/android/tools/r8/dex/FileWriter.java
index 826aaba..afa7105 100644
--- a/src/main/java/com/android/tools/r8/dex/FileWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/FileWriter.java
@@ -734,10 +734,10 @@
   }
 
   private static byte[] convertApiLevelToDexVersion(int apiLevel) {
-    if (apiLevel >= Constants.ANDROID_O_API) {
+    if (apiLevel >= AndroidApiLevel.O.getLevel()) {
       return Constants.ANDROID_O_DEX_VERSION_BYTES;
     }
-    if (apiLevel >= Constants.ANDROID_N_API) {
+    if (apiLevel >= AndroidApiLevel.N.getLevel()) {
       return Constants.ANDROID_N_DEX_VERSION_BYTES;
     }
     return Constants.ANDROID_PRE_N_DEX_VERSION_BYTES;
diff --git a/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionIterator.java b/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionIterator.java
index aebb9ed..131e0d0 100644
--- a/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionIterator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/BasicBlockInstructionIterator.java
@@ -346,7 +346,7 @@
     assert invoke.inValues().size() == arguments.size();
     for (int i = 0; i < invoke.inValues().size(); i++) {
       // TODO(zerny): Support inlining in --debug mode.
-      assert arguments.get(i).getLocalInfo() == null;
+      assert !arguments.get(i).hasLocalInfo();
       if ((i == 0) && (downcast != null)) {
         Value invokeValue = invoke.inValues().get(0);
         Value receiverValue = arguments.get(0);
diff --git a/src/main/java/com/android/tools/r8/ir/code/DebugLocalWrite.java b/src/main/java/com/android/tools/r8/ir/code/DebugLocalWrite.java
index a96b673..d3d5553 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DebugLocalWrite.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DebugLocalWrite.java
@@ -18,7 +18,7 @@
 
   public DebugLocalWrite(Value dest, Value src) {
     super(dest, src);
-    assert dest.getLocalInfo() != null;
+    assert dest.hasLocalInfo();
     assert dest.getLocalInfo() != src.getLocalInfo() || src.isPhi();
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCode.java b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
index 20bba3f..2e8b683 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCode.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
@@ -246,7 +246,7 @@
       assert phiUser.getOperands().contains(value);
       assert phiUser.getBlock().getPhis().contains(phiUser);
     }
-    if (value.getLocalInfo() != null) {
+    if (value.hasLocalInfo()) {
       for (Instruction debugUser : value.debugUsers()) {
         assert debugUser.getDebugValues().contains(value);
       }
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index 15291a5..21c2abf 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -59,7 +59,7 @@
 
   public boolean hasInValueWithLocalInfo() {
     for (Value inValue : inValues()) {
-      if (inValue.getLocalInfo() != null) {
+      if (inValue.hasLocalInfo()) {
         return true;
       }
     }
@@ -79,7 +79,7 @@
   }
 
   public void addDebugValue(Value value) {
-    assert value.getLocalInfo() != null;
+    assert value.hasLocalInfo();
     if (debugValues == null) {
       debugValues = new HashSet<>();
     }
@@ -116,7 +116,7 @@
 
   public void replaceDebugValue(Value oldValue, Value newValue) {
     if (debugValues.remove(oldValue)) {
-      if (newValue.getLocalInfo() != null) {
+      if (newValue.hasLocalInfo()) {
         // TODO(zerny): Insert a write if replacing a phi with different debug-local info.
         addDebugValue(newValue);
       }
@@ -141,7 +141,7 @@
   }
 
   public void removeDebugValue(Value value) {
-    assert value.getLocalInfo() != null;
+    assert value.hasLocalInfo();
     if (debugValues != null) {
       assert debugValues.contains(value);
       if (debugValues.remove(value)) {
diff --git a/src/main/java/com/android/tools/r8/ir/code/Phi.java b/src/main/java/com/android/tools/r8/ir/code/Phi.java
index a644470..22c8380 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Phi.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Phi.java
@@ -100,7 +100,7 @@
   }
 
   public void addDebugValue(Value value) {
-    assert value.getLocalInfo() != null;
+    assert value.hasLocalInfo();
     if (debugValues == null) {
       debugValues = new HashSet<>();
     }
@@ -165,7 +165,7 @@
   }
 
   void replaceDebugValue(Value current, Value newValue) {
-    assert current.getLocalInfo() != null;
+    assert current.hasLocalInfo();
     assert current.getLocalInfo() == newValue.getLocalInfo();
     if (debugValues.remove(current)) {
       addDebugValue(newValue);
@@ -240,7 +240,7 @@
     StringBuilder builder = new StringBuilder();
     builder.append("v");
     builder.append(number);
-    if (getLocalInfo() != null) {
+    if (hasLocalInfo()) {
       builder.append("(").append(getLocalInfo()).append(")");
     }
     builder.append(" <- phi");
diff --git a/src/main/java/com/android/tools/r8/ir/code/Value.java b/src/main/java/com/android/tools/r8/ir/code/Value.java
index 61bd315..1915155 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Value.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Value.java
@@ -114,6 +114,10 @@
     return debugData == null ? null : debugData.local;
   }
 
+  public boolean hasLocalInfo() {
+    return getLocalInfo() != null;
+  }
+
   public void setLocalInfo(DebugLocalInfo local) {
     assert local != null;
     assert debugData == null;
@@ -316,12 +320,12 @@
   }
 
   public void addDebugUser(Instruction user) {
-    assert getLocalInfo() != null;
+    assert hasLocalInfo();
     debugData.users.putIfAbsent(user, DebugUse.LIVE);
   }
 
   public void addDebugPhiUser(Phi user) {
-    assert getLocalInfo() != null;
+    assert hasLocalInfo();
     debugData.phiUsers.add(user);
   }
 
@@ -453,8 +457,7 @@
     builder.append("v");
     builder.append(number);
     boolean isConstant = definition != null && definition.isConstNumber();
-    boolean hasLocalInfo = getLocalInfo() != null;
-    if (isConstant || hasLocalInfo) {
+    if (isConstant || hasLocalInfo()) {
       builder.append("(");
       if (isConstant) {
         ConstNumber constNumber = definition.asConstNumber();
@@ -464,10 +467,10 @@
           builder.append(constNumber.getRawValue());
         }
       }
-      if (isConstant && hasLocalInfo) {
+      if (isConstant && hasLocalInfo()) {
         builder.append(", ");
       }
-      if (hasLocalInfo) {
+      if (hasLocalInfo()) {
         builder.append(getLocalInfo());
       }
       builder.append(")");
@@ -496,7 +499,7 @@
   }
 
   public boolean isConstant() {
-    return definition.isOutConstant() && getLocalInfo() == null;
+    return definition.isOutConstant() && !hasLocalInfo();
   }
 
   public boolean isPhi() {
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index fc516e4..91b51f4 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -546,7 +546,7 @@
     }
     Value value = writeRegister(register, MoveType.fromConstType(type), ThrowingInfo.NO_THROW,
         null);
-    assert value.getLocalInfo() == null;
+    assert !value.hasLocalInfo();
     addInstruction(new DebugLocalUninitialized(type, value));
   }
 
@@ -1183,7 +1183,7 @@
 
   public void addMoveException(int dest) {
     Value out = writeRegister(dest, MoveType.OBJECT, ThrowingInfo.NO_THROW);
-    assert out.getLocalInfo() == null;
+    assert !out.hasLocalInfo();
     MoveException instruction = new MoveException(out);
     assert !instruction.instructionTypeCanThrow();
     if (!currentBlock.getInstructions().isEmpty()
@@ -1549,7 +1549,7 @@
     // If this assert triggers, the probable cause is that we end up reading an SSA value
     // after it should have been ended on a fallthrough from a conditional jump or a trivial-phi
     // removal resurrected the local.
-    assert value.getLocalInfo() == null
+    assert !value.hasLocalInfo()
         || value.getDebugLocalEnds() != null
         || source.verifyLocalInScope(value.getLocalInfo());
     return value;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index ca307f4..810039f 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -803,7 +803,7 @@
       Instruction current = iterator.next();
       if (current.isInvokeMethod()) {
         InvokeMethod invoke = current.asInvokeMethod();
-        if (invoke.outValue() != null && invoke.outValue().getLocalInfo() == null) {
+        if (invoke.outValue() != null && !invoke.outValue().hasLocalInfo()) {
           boolean isLibraryMethodReturningReceiver =
               libraryMethodsReturningReceiver.contains(invoke.getInvokedMethod());
           if (isLibraryMethodReturningReceiver) {
@@ -1165,7 +1165,7 @@
       Instruction instruction = it.next();
       if (instruction.isConstNumber() &&
           instruction.outValue().numberOfAllUsers() != 0 &&
-          instruction.outValue().getLocalInfo() == null) {
+          !instruction.outValue().hasLocalInfo()) {
         // Collect the blocks for all users of the constant.
         List<BasicBlock> userBlocks = new LinkedList<>();
         for (Instruction user : instruction.outValue().uniqueUsers()) {
@@ -1464,7 +1464,7 @@
   public void simplifyDebugLocals(IRCode code) {
     for (BasicBlock block : code.blocks) {
       for (Phi phi : block.getPhis()) {
-        if (phi.getLocalInfo() == null && phi.numberOfUsers() == 1 && phi.numberOfAllUsers() == 1) {
+        if (!phi.hasLocalInfo() && phi.numberOfUsers() == 1 && phi.numberOfAllUsers() == 1) {
           Instruction instruction = phi.uniqueUsers().iterator().next();
           if (instruction.isDebugLocalWrite()) {
             removeDebugWriteOfPhi(phi, instruction.asDebugLocalWrite());
@@ -1480,7 +1480,7 @@
           Value inValue = instruction.inValues().get(0);
           if (inValue.definition != null &&
               !hasLineChangeBetween(inValue.definition, instruction) &&
-              inValue.getLocalInfo() == null &&
+              !inValue.hasLocalInfo() &&
               inValue.numberOfAllUsers() == 1) {
             inValue.setLocalInfo(instruction.outValue().getLocalInfo());
             instruction.moveDebugValues(inValue.definition);
@@ -1551,7 +1551,7 @@
         }
         // Copy over each debug value replacing phi values of this block by their operands.
         for (Value value : origInstruction.getDebugValues()) {
-          assert value.getLocalInfo() != null;
+          assert value.hasLocalInfo();
           if (value.isPhi() && block.getPhis().contains(value)) {
             Phi phi = value.asPhi();
             Value operand = phi.getOperand(predIndex);
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
index 7facea6..7a2dc4a 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
@@ -83,7 +83,7 @@
     final int end;
 
     LocalRange(Value value, int register, int start, int end) {
-      assert value.getLocalInfo() != null;
+      assert value.hasLocalInfo();
       this.value = value;
       this.local = value.getLocalInfo();
       this.register = register;
@@ -228,7 +228,7 @@
     List<LocalRange> ranges = new ArrayList<>();
     for (LiveIntervals interval : liveIntervals) {
       Value value = interval.getValue();
-      if (value.getLocalInfo() == null) {
+      if (!value.hasLocalInfo()) {
         continue;
       }
       List<Integer> starts = ListUtils.map(value.getDebugLocalStarts(), Instruction::getNumber);
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApiLevel.java b/src/main/java/com/android/tools/r8/utils/AndroidApiLevel.java
index d72fb2b..04ab202 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApiLevel.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApiLevel.java
@@ -47,4 +47,8 @@
   public String getName() {
     return "Android " + name();
   }
+
+  public static AndroidApiLevel getDefault() {
+    return AndroidApiLevel.B;
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 90597ca..f497ce5 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -81,7 +81,7 @@
   }
 
   public List<String> methodsFilter = ImmutableList.of();
-  public int minApiLevel = Constants.DEFAULT_ANDROID_API;
+  public int minApiLevel = AndroidApiLevel.getDefault().getLevel();
   // Skipping min_api check and compiling an intermediate result intended for later merging.
   public boolean intermediate = false;
   public List<String> logArgumentsFilter = ImmutableList.of();
diff --git a/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
index c39dc31..94fadf1 100644
--- a/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8LazyRunExamplesAndroidOTest.java
@@ -4,12 +4,12 @@
 
 package com.android.tools.r8;
 
-import static com.android.tools.r8.dex.Constants.ANDROID_K_API;
 import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
 import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.D8Command.Builder;
 import com.android.tools.r8.shaking.FilteredClassPath;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.DirectoryClassFileProvider;
 import com.android.tools.r8.utils.FileUtils;
@@ -70,7 +70,7 @@
 
   @Test
   public void dexPerClassFileWithDesugaringAndFolderClasspath() throws Throwable {
-    int minAPILevel = ANDROID_K_API;
+    int minAPILevel = AndroidApiLevel.K.getLevel();
     Path inputFile =
         Paths.get(ToolHelper.EXAMPLES_ANDROID_N_BUILD_DIR, "interfacemethods" + JAR_EXTENSION);
     Path tmpClassesDir = temp.newFolder().toPath();
diff --git a/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
index a2e64e1..fa8fd25 100644
--- a/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/D8RunExamplesAndroidOTest.java
@@ -4,14 +4,13 @@
 
 package com.android.tools.r8;
 
-import static com.android.tools.r8.dex.Constants.ANDROID_K_API;
-import static com.android.tools.r8.dex.Constants.ANDROID_O_API;
 import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
 import static com.android.tools.r8.utils.FileUtils.ZIP_EXTENSION;
 
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.errors.InternalCompilerError;
 import com.android.tools.r8.errors.Unimplemented;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.DexInspector;
 import com.android.tools.r8.utils.OffOrAuto;
 import com.android.tools.r8.utils.OutputMode;
@@ -88,7 +87,7 @@
     D8TestRunner lib1 =
         test("testDefaultInInterfaceWithoutDesugaring", "desugaringwithmissingclasslib1", "N/A")
             .withInterfaceMethodDesugaring(OffOrAuto.Off)
-            .withMinApiLevel(ANDROID_K_API);
+            .withMinApiLevel(AndroidApiLevel.K.getLevel());
     try  {
       lib1.build();
 
@@ -105,7 +104,7 @@
     D8TestRunner lib1 =
         test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
             .withInterfaceMethodDesugaring(OffOrAuto.Auto)
-            .withMinApiLevel(ANDROID_K_API);
+            .withMinApiLevel(AndroidApiLevel.K.getLevel());
     lib1.build();
 
     // lib2: interface B extends A { default String foo() { return "B"; } }
@@ -114,7 +113,7 @@
         test("desugaringwithmissingclasslib2", "desugaringwithmissingclasslib2", "N/A")
             .withInterfaceMethodDesugaring(OffOrAuto.Auto)
             .withClasspath(lib1.getInputJar())
-            .withMinApiLevel(ANDROID_K_API);
+            .withMinApiLevel(AndroidApiLevel.K.getLevel());
     lib2.build();
 
     // test: class ImplementMethodsWithDefault implements A, B {} should get its foo implementation
@@ -125,7 +124,7 @@
         test("desugaringwithmissingclasstest1", "desugaringwithmissingclasstest1", "N/A")
             .withInterfaceMethodDesugaring(OffOrAuto.Auto)
             .withClasspath(lib1.getInputJar())
-            .withMinApiLevel(ANDROID_K_API);
+            .withMinApiLevel(AndroidApiLevel.K.getLevel());
     test.build();
 
     // TODO check compilation warnings are correctly reported
@@ -134,7 +133,7 @@
 
   @Test
   public void testMissingInterfaceDesugared2AndroidK() throws Throwable {
-    int minApi = ANDROID_K_API;
+    int minApi = AndroidApiLevel.K.getLevel();
 
     // lib1: interface A { default String foo() { return "A"; } }
     D8TestRunner lib1 =
@@ -188,7 +187,7 @@
 
   @Test
   public void testMissingInterfaceDesugared2AndroidO() throws Throwable {
-    int minApi = ANDROID_O_API;
+    int minApi = AndroidApiLevel.O.getLevel();
     // lib1: interface A { default String foo() { return "A"; } }
     D8TestRunner lib1 =
         test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
@@ -236,7 +235,7 @@
   @Test
   public void testCallToMissingSuperInterfaceDesugaredAndroidK() throws Throwable {
 
-    int minApi = ANDROID_K_API;
+    int minApi = AndroidApiLevel.K.getLevel();
     // lib1: interface A { default String foo() { return "A"; } }
     D8TestRunner lib1 =
         test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
@@ -289,7 +288,7 @@
 
   @Test
   public void testCallToMissingSuperInterfaceDesugaredAndroidO() throws Throwable {
-    int minApi = ANDROID_O_API;
+    int minApi = AndroidApiLevel.O.getLevel();
     // lib1: interface A { default String foo() { return "A"; } }
     D8TestRunner lib1 =
         test("desugaringwithmissingclasslib1", "desugaringwithmissingclasslib1", "N/A")
@@ -336,7 +335,7 @@
 
   @Test
   public void testMissingSuperDesugaredAndroidK() throws Throwable {
-    int minApi = ANDROID_K_API;
+    int minApi = AndroidApiLevel.K.getLevel();
 
     // lib1: interface A { default String foo() { return "A"; } }
     D8TestRunner lib1 =
@@ -384,7 +383,7 @@
 
   @Test
   public void testMissingSuperDesugaredAndroidO() throws Throwable {
-    int minApi = ANDROID_O_API;
+    int minApi = AndroidApiLevel.O.getLevel();
 
     // lib1: interface A { default String foo() { return "A"; } }
     D8TestRunner lib1 =
@@ -434,7 +433,7 @@
 
   @Test
   public void testMissingSuperDesugaredWithProgramCrossImplementationAndroidK() throws Throwable {
-    int minApi = ANDROID_K_API;
+    int minApi = AndroidApiLevel.K.getLevel();
 
     // lib1: interface A { default String foo() { return "A"; } }
     //       interface A2 { default String foo2() { return "A2"; } }
@@ -479,7 +478,7 @@
 
   @Test
   public void testMissingSuperDesugaredWithClasspathCrossImplementationAndroidK() throws Throwable {
-    int minApi = ANDROID_K_API;
+    int minApi = AndroidApiLevel.K.getLevel();
 
     // lib1: interface A { default String foo() { return "A"; } }
     //       interface A2 { default String foo2() { return "A2"; } }
@@ -586,7 +585,7 @@
         int expectedMainDexListSize,
         String... mainDexClasses)
         throws Throwable {
-    int minApi = ANDROID_K_API;
+    int minApi = AndroidApiLevel.K.getLevel();
 
     // Full build, will be used as reference.
     TestRunner<?> full =
diff --git a/src/test/java/com/android/tools/r8/JctfTestSpecifications.java b/src/test/java/com/android/tools/r8/JctfTestSpecifications.java
index c629a99..c58fc2b 100644
--- a/src/test/java/com/android/tools/r8/JctfTestSpecifications.java
+++ b/src/test/java/com/android/tools/r8/JctfTestSpecifications.java
@@ -1893,7 +1893,8 @@
           // 1) t04
           // java.lang.AssertionError: reference is not enqueued after 2 sec
 
-          .put("lang.ref.SoftReference.isEnqueued.SoftReference_isEnqueued_A01", any())
+          .put("lang.ref.SoftReference.isEnqueued.SoftReference_isEnqueued_A01",
+              match(runtimes(DexVm.ART_DEFAULT, DexVm.ART_7_0_0, DexVm.ART_6_0_1, DexVm.ART_5_1_1)))
           // 1) t03
           // java.lang.AssertionError: reference is not enqueued after 2 sec
 
@@ -1901,7 +1902,8 @@
           // 1) t03
           // java.lang.AssertionError: expected null, but was:<[I@e2603b4>
 
-          .put("lang.ref.ReferenceQueue.poll.ReferenceQueue_poll_A01", any())
+          .put("lang.ref.ReferenceQueue.poll.ReferenceQueue_poll_A01",
+              match(runtimes(DexVm.ART_DEFAULT, DexVm.ART_7_0_0, DexVm.ART_6_0_1, DexVm.ART_5_1_1)))
           // 1) t03
           // java.lang.AssertionError: reference is not enqueued after 2 sec
 
@@ -4805,8 +4807,14 @@
               match(runtimes(DexVm.ART_4_4_4)))
           .put("lang.ref.WeakReference.isEnqueued.WeakReference_isEnqueued_A01",
               match(runtimes(DexVm.ART_4_4_4)))
+          .put("lang.ref.SoftReference.isEnqueued.SoftReference_isEnqueued_A01",
+              match(runtimes(DexVm.ART_4_4_4)))
           // Passes or fails randomly. Check that something is enqueued after 2 seconds.
 
+          .put("lang.ref.ReferenceQueue.poll.ReferenceQueue_poll_A01",
+              match(runtimes(DexVm.ART_4_4_4)))
+          // Passes or fails randomly.
+
           .build(); // end of flakyWithArt
 
   public static final Multimap<String, TestCondition> timeoutsWithArt =
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
index 4155dd2..c379193 100644
--- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -14,6 +14,7 @@
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.shaking.ProguardRuleParserException;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.ArtErrorParser;
 import com.android.tools.r8.utils.ArtErrorParser.ArtErrorInfo;
 import com.android.tools.r8.utils.DexInspector;
@@ -103,42 +104,42 @@
   private static Map<String, Integer> needMinSdkVersion =
       new ImmutableMap.Builder<String, Integer>()
           // Android O
-          .put("952-invoke-custom", Constants.ANDROID_O_API)
-          .put("952-invoke-custom-kinds", Constants.ANDROID_O_API)
-          .put("953-invoke-polymorphic-compiler", Constants.ANDROID_O_API)
-          .put("957-methodhandle-transforms", Constants.ANDROID_O_API)
-          .put("958-methodhandle-stackframe", Constants.ANDROID_O_API)
-          .put("959-invoke-polymorphic-accessors", Constants.ANDROID_O_API)
-          .put("990-method-handle-and-mr", Constants.ANDROID_O_API)
+          .put("952-invoke-custom", AndroidApiLevel.O.getLevel())
+          .put("952-invoke-custom-kinds", AndroidApiLevel.O.getLevel())
+          .put("953-invoke-polymorphic-compiler", AndroidApiLevel.O.getLevel())
+          .put("957-methodhandle-transforms", AndroidApiLevel.O.getLevel())
+          .put("958-methodhandle-stackframe", AndroidApiLevel.O.getLevel())
+          .put("959-invoke-polymorphic-accessors", AndroidApiLevel.O.getLevel())
+          .put("990-method-handle-and-mr", AndroidApiLevel.O.getLevel())
           // Test intentionally asserts presence of bridge default methods desugar removes.
-          .put("044-proxy", Constants.ANDROID_N_API)
+          .put("044-proxy", AndroidApiLevel.N.getLevel())
           // Test intentionally asserts absence of default interface method in a class.
-          .put("048-reflect-v8", Constants.ANDROID_N_API)
+          .put("048-reflect-v8", AndroidApiLevel.N.getLevel())
           // Uses default interface methods.
-          .put("162-method-resolution", Constants.ANDROID_N_API)
-          .put("616-cha-interface-default", Constants.ANDROID_N_API)
-          .put("1910-transform-with-default", Constants.ANDROID_N_API)
+          .put("162-method-resolution", AndroidApiLevel.N.getLevel())
+          .put("616-cha-interface-default", AndroidApiLevel.N.getLevel())
+          .put("1910-transform-with-default", AndroidApiLevel.N.getLevel())
           // Interface initializer is not triggered after desugaring.
-          .put("962-iface-static", Constants.ANDROID_N_API)
+          .put("962-iface-static", AndroidApiLevel.N.getLevel())
           // Interface initializer is not triggered after desugaring.
-          .put("964-default-iface-init-gen", Constants.ANDROID_N_API)
+          .put("964-default-iface-init-gen",AndroidApiLevel.N.getLevel())
           // AbstractMethodError (for method not implemented in class) instead of
           // IncompatibleClassChangeError (for conflict of default interface methods).
-          .put("968-default-partial-compile-gen", Constants.ANDROID_N_API)
+          .put("968-default-partial-compile-gen",AndroidApiLevel.N.getLevel())
           // NoClassDefFoundError (for companion class) instead of NoSuchMethodError.
-          .put("970-iface-super-resolution-gen", Constants.ANDROID_N_API)
+          .put("970-iface-super-resolution-gen", AndroidApiLevel.N.getLevel())
           // NoClassDefFoundError (for companion class) instead of AbstractMethodError.
-          .put("971-iface-super", Constants.ANDROID_N_API)
+          .put("971-iface-super", AndroidApiLevel.N.getLevel())
           // Test for miranda methods is not relevant for desugaring scenario.
-          .put("972-default-imt-collision", Constants.ANDROID_N_API)
+          .put("972-default-imt-collision", AndroidApiLevel.N.getLevel())
           // Uses default interface methods.
-          .put("972-iface-super-multidex", Constants.ANDROID_N_API)
+          .put("972-iface-super-multidex", AndroidApiLevel.N.getLevel())
           // java.util.Objects is missing and test has default methods.
-          .put("973-default-multidex", Constants.ANDROID_N_API)
+          .put("973-default-multidex", AndroidApiLevel.N.getLevel())
           // a.klass.that.does.not.Exist is missing and test has default methods.
-          .put("974-verify-interface-super", Constants.ANDROID_N_API)
+          .put("974-verify-interface-super", AndroidApiLevel.N.getLevel())
           // Desugaring of interface private methods is not yet supported.
-          .put("975-iface-private", Constants.ANDROID_N_API)
+          .put("975-iface-private", AndroidApiLevel.N.getLevel())
           .build();
 
   // Tests that timeout when run with Art.
@@ -183,6 +184,9 @@
           // of '__gnu_cxx::recursive_init_error'
           .put("096-array-copy-concurrent-gc",
               TestCondition.match(TestCondition.runtimes(DexVm.ART_4_4_4)))
+          // Sometimes fails with out of memory on Dalvik.
+          .put("114-ParallelGC",
+              TestCondition.match(TestCondition.runtimes(DexVm.ART_4_4_4)))
           // Seen crash: currently no more information
           .put("144-static-field-sigquit", TestCondition.any())
           // Opens a lot of file descriptors and depending on the state of the machine this
@@ -1224,7 +1228,7 @@
           builder.addLibraryFiles(Paths.get(ToolHelper.getAndroidJar(minSdkVersion)));
         } else {
           builder.addLibraryFiles(Paths.get(
-              ToolHelper.getAndroidJar(Constants.DEFAULT_ANDROID_API)));
+              ToolHelper.getAndroidJar(AndroidApiLevel.getDefault().getLevel())));
         }
 
         D8Output output = D8.run(builder.build());
diff --git a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
index e63b155..b43b041 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.ToolHelper.DexVm;
 import com.android.tools.r8.dex.Constants;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import java.nio.file.Path;
@@ -39,7 +40,7 @@
   @Test
   public void invokeCustomWithShrinking() throws Throwable {
     test("invokecustom-with-shrinking", "invokecustom", "InvokeCustom")
-        .withMinApiLevel(Constants.ANDROID_O_API)
+        .withMinApiLevel(AndroidApiLevel.O.getLevel())
         .withBuilderTransformation(builder ->
             builder.addProguardConfigurationFiles(
                 Paths.get(ToolHelper.EXAMPLES_ANDROID_O_DIR, "invokecustom/keep-rules.txt")))
diff --git a/src/test/java/com/android/tools/r8/RunExamplesAndroidNTest.java b/src/test/java/com/android/tools/r8/RunExamplesAndroidNTest.java
index 9d745f6..03093df 100644
--- a/src/test/java/com/android/tools/r8/RunExamplesAndroidNTest.java
+++ b/src/test/java/com/android/tools/r8/RunExamplesAndroidNTest.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.ToolHelper.ProcessResult;
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.OffOrAuto;
 import com.google.common.collect.ImmutableList;
@@ -123,7 +124,7 @@
   @Test
   public void staticInterfaceMethods() throws Throwable {
     test("staticinterfacemethods", "interfacemethods", "StaticInterfaceMethods")
-        .withMinApiLevel(Constants.ANDROID_K_API)
+        .withMinApiLevel(AndroidApiLevel.K.getLevel())
         .withInterfaceMethodDesugaring(OffOrAuto.Auto)
         .run();
   }
@@ -140,7 +141,7 @@
   @Test
   public void defaultMethods() throws Throwable {
     test("defaultmethods", "interfacemethods", "DefaultMethods")
-        .withMinApiLevel(Constants.ANDROID_K_API)
+        .withMinApiLevel(AndroidApiLevel.K.getLevel())
         .withInterfaceMethodDesugaring(OffOrAuto.Auto)
         .run();
   }
diff --git a/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
index 0e0fd9d..84f2768 100644
--- a/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
@@ -4,14 +4,13 @@
 
 package com.android.tools.r8;
 
-import static com.android.tools.r8.dex.Constants.ANDROID_K_API;
-import static com.android.tools.r8.dex.Constants.ANDROID_O_API;
 import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
 import static com.android.tools.r8.utils.FileUtils.ZIP_EXTENSION;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.ToolHelper.DexVm;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.DexInspector;
 import com.android.tools.r8.utils.DexInspector.FoundClassSubject;
@@ -256,14 +255,14 @@
   @Test
   public void invokeCustom() throws Throwable {
     test("invokecustom", "invokecustom", "InvokeCustom")
-        .withMinApiLevel(ANDROID_O_API)
+        .withMinApiLevel(AndroidApiLevel.O.getLevel())
         .run();
   }
 
   @Test
   public void invokeCustom2() throws Throwable {
     test("invokecustom2", "invokecustom2", "InvokeCustom")
-        .withMinApiLevel(ANDROID_O_API)
+        .withMinApiLevel(AndroidApiLevel.O.getLevel())
         .run();
   }
 
@@ -277,7 +276,7 @@
   @Test
   public void invokePolymorphic() throws Throwable {
     test("invokepolymorphic", "invokepolymorphic", "InvokePolymorphic")
-        .withMinApiLevel(ANDROID_O_API)
+        .withMinApiLevel(AndroidApiLevel.O.getLevel())
         .run();
   }
 
@@ -291,14 +290,14 @@
   @Test
   public void lambdaDesugaring() throws Throwable {
     test("lambdadesugaring", "lambdadesugaring", "LambdaDesugaring")
-        .withMinApiLevel(ANDROID_K_API)
+        .withMinApiLevel(AndroidApiLevel.K.getLevel())
         .run();
   }
 
   @Test
   public void lambdaDesugaringNPlus() throws Throwable {
     test("lambdadesugaringnplus", "lambdadesugaringnplus", "LambdasWithStaticAndDefaultMethods")
-        .withMinApiLevel(ANDROID_K_API)
+        .withMinApiLevel(AndroidApiLevel.K.getLevel())
         .withInterfaceMethodDesugaring(OffOrAuto.Auto)
         .run();
   }
@@ -306,8 +305,8 @@
   @Test
   public void desugarDefaultMethodInAndroidJar25() throws Throwable {
     test("DefaultMethodInAndroidJar25", "desugaringwithandroidjar25", "DefaultMethodInAndroidJar25")
-        .withMinApiLevel(ANDROID_K_API)
-        .withAndroidJar(ANDROID_O_API)
+        .withMinApiLevel(AndroidApiLevel.K.getLevel())
+        .withAndroidJar(AndroidApiLevel.O.getLevel())
         .withInterfaceMethodDesugaring(OffOrAuto.Auto)
         .run();
   }
@@ -315,8 +314,8 @@
   @Test
   public void desugarStaticMethodInAndroidJar25() throws Throwable {
     test("StaticMethodInAndroidJar25", "desugaringwithandroidjar25", "StaticMethodInAndroidJar25")
-        .withMinApiLevel(ANDROID_K_API)
-        .withAndroidJar(ANDROID_O_API)
+        .withMinApiLevel(AndroidApiLevel.K.getLevel())
+        .withAndroidJar(AndroidApiLevel.O.getLevel())
         .withInterfaceMethodDesugaring(OffOrAuto.Auto)
         .run();
   }
@@ -324,14 +323,14 @@
   @Test
   public void lambdaDesugaringValueAdjustments() throws Throwable {
     test("lambdadesugaring-value-adjustments", "lambdadesugaring", "ValueAdjustments")
-        .withMinApiLevel(ANDROID_K_API)
+        .withMinApiLevel(AndroidApiLevel.K.getLevel())
         .run();
   }
 
   @Test
   public void paramNames() throws Throwable {
     test("paramnames", "paramnames", "ParameterNames")
-        .withMinApiLevel(ANDROID_O_API)
+        .withMinApiLevel(AndroidApiLevel.O.getLevel())
         .withOptionConsumer((internalOptions) -> internalOptions.allowParameterName = true)
         .run();
   }
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 64941da..377d2aa 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -16,6 +16,7 @@
 import com.android.tools.r8.shaking.ProguardConfiguration;
 import com.android.tools.r8.shaking.ProguardConfigurationParser;
 import com.android.tools.r8.shaking.ProguardRuleParserException;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.ListUtils;
@@ -65,7 +66,7 @@
   public final static String PATH_SEPARATOR = File.pathSeparator;
 
   private static final String ANDROID_JAR_PATTERN = "third_party/android_jar/lib-v%d/android.jar";
-  private static final int DEFAULT_MIN_SDK = Constants.ANDROID_I_API;
+  private static final int DEFAULT_MIN_SDK = AndroidApiLevel.I.getLevel();
 
   public enum DexVm {
     ART_4_4_4("4.4.4"),
@@ -330,17 +331,17 @@
   }
 
   public static String getDefaultAndroidJar() {
-    return getAndroidJar(Constants.DEFAULT_ANDROID_API);
+    return getAndroidJar(AndroidApiLevel.getDefault().getLevel());
   }
 
   public static String getAndroidJar(int minSdkVersion) {
     return String.format(
         ANDROID_JAR_PATTERN,
-        minSdkVersion == Constants.DEFAULT_ANDROID_API ? DEFAULT_MIN_SDK : minSdkVersion);
+        minSdkVersion == AndroidApiLevel.getDefault().getLevel() ? DEFAULT_MIN_SDK : minSdkVersion);
   }
 
   public static Path getJdwpTestsJarPath(int minSdk) {
-    if (minSdk >= Constants.ANDROID_N_API) {
+    if (minSdk >= AndroidApiLevel.N.getLevel()) {
       return Paths.get("third_party", "jdwp-tests", "apache-harmony-jdwp-tests-host.jar");
     } else {
       return Paths.get(ToolHelper.BUILD_DIR, "libs", "jdwp-tests-preN.jar");
@@ -418,11 +419,11 @@
   public static int getMinApiLevelForDexVm(DexVm dexVm) {
     switch (dexVm) {
       case ART_DEFAULT:
-        return Constants.ANDROID_O_API;
+        return AndroidApiLevel.O.getLevel();
       case ART_7_0_0:
-        return Constants.ANDROID_N_API;
+        return AndroidApiLevel.N.getLevel();
       default:
-        return Constants.DEFAULT_ANDROID_API;
+        return AndroidApiLevel.getDefault().getLevel();
     }
   }
 
diff --git a/src/test/java/com/android/tools/r8/d8/D8FrameworkDexPassthroughMarkerTest.java b/src/test/java/com/android/tools/r8/d8/D8FrameworkDexPassthroughMarkerTest.java
index 3aadc15..9b538b0 100644
--- a/src/test/java/com/android/tools/r8/d8/D8FrameworkDexPassthroughMarkerTest.java
+++ b/src/test/java/com/android/tools/r8/d8/D8FrameworkDexPassthroughMarkerTest.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.dex.Marker;
 import com.android.tools.r8.dex.Marker.Tool;
 import com.android.tools.r8.graph.DexApplication;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.Timing;
@@ -56,7 +57,7 @@
   @Test
   public void compile() throws CompilationException, IOException, ExecutionException {
     D8Command command = D8Command.builder()
-        .setMinApiLevel(Constants.ANDROID_N_API)
+        .setMinApiLevel(AndroidApiLevel.N.getLevel())
         .addProgramFiles(FRAMEWORK_JAR)
         .build();
     Marker marker = new Marker(Tool.D8)
diff --git a/src/test/java/com/android/tools/r8/d8/DexVersionTests.java b/src/test/java/com/android/tools/r8/d8/DexVersionTests.java
index 0d72a52..ebf75f2 100644
--- a/src/test/java/com/android/tools/r8/d8/DexVersionTests.java
+++ b/src/test/java/com/android/tools/r8/d8/DexVersionTests.java
@@ -10,6 +10,7 @@
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -39,15 +40,15 @@
     D8Command.Builder arrayAccessBuilder = D8Command.builder().addProgramFiles(ARRAYACCESS_JAR);
     D8Output output = D8.run(arrayAccessBuilder.build());
     output.write(defaultApiFolder1.getRoot().toPath());
-    output = D8.run(arrayAccessBuilder.setMinApiLevel(Constants.ANDROID_O_API).build());
+    output = D8.run(arrayAccessBuilder.setMinApiLevel(AndroidApiLevel.O.getLevel()).build());
     output.write(androidOApiFolder1.getRoot().toPath());
-    output = D8.run(arrayAccessBuilder.setMinApiLevel(Constants.ANDROID_N_API).build());
+    output = D8.run(arrayAccessBuilder.setMinApiLevel(AndroidApiLevel.N.getLevel()).build());
     output.write(androidNApiFolder1.getRoot().toPath());
     output = D8.run(arithmeticBuilder.build());
     output.write(defaultApiFolder2.getRoot().toPath());
-    output = D8.run(arithmeticBuilder.setMinApiLevel(Constants.ANDROID_O_API).build());
+    output = D8.run(arithmeticBuilder.setMinApiLevel(AndroidApiLevel.O.getLevel()).build());
     output.write(androidOApiFolder2.getRoot().toPath());
-    output = D8.run(arithmeticBuilder.setMinApiLevel(Constants.ANDROID_N_API).build());
+    output = D8.run(arithmeticBuilder.setMinApiLevel(AndroidApiLevel.N.getLevel()).build());
     output.write(androidNApiFolder2.getRoot().toPath());
   }
 
@@ -88,37 +89,37 @@
     // set to Android O.
     D8.run(
         D8Command.builder()
-            .setMinApiLevel(Constants.ANDROID_O_API)
+            .setMinApiLevel(AndroidApiLevel.O.getLevel())
             .addProgramFiles(default1())
             .addProgramFiles(default2())
             .build());
     D8.run(
         D8Command.builder()
-            .setMinApiLevel(Constants.ANDROID_O_API)
+            .setMinApiLevel(AndroidApiLevel.O.getLevel())
             .addProgramFiles(default1())
             .addProgramFiles(androidO2())
             .build());
     D8.run(
         D8Command.builder()
-            .setMinApiLevel(Constants.ANDROID_O_API)
+            .setMinApiLevel(AndroidApiLevel.O.getLevel())
             .addProgramFiles(default1())
             .addProgramFiles(androidN2())
             .build());
     D8.run(
         D8Command.builder()
-            .setMinApiLevel(Constants.ANDROID_O_API)
+            .setMinApiLevel(AndroidApiLevel.O.getLevel())
             .addProgramFiles(androidO1())
             .addProgramFiles(androidN2())
             .build());
     D8.run(
         D8Command.builder()
-            .setMinApiLevel(Constants.ANDROID_O_API)
+            .setMinApiLevel(AndroidApiLevel.O.getLevel())
             .addProgramFiles(androidO1())
             .addProgramFiles(androidO2())
             .build());
     D8.run(
         D8Command.builder()
-            .setMinApiLevel(Constants.ANDROID_O_API)
+            .setMinApiLevel(AndroidApiLevel.O.getLevel())
             .addProgramFiles(androidN1())
             .addProgramFiles(androidN2())
             .build());
@@ -126,19 +127,19 @@
     // Android N.
     D8.run(
         D8Command.builder()
-            .setMinApiLevel(Constants.ANDROID_N_API)
+            .setMinApiLevel(AndroidApiLevel.N.getLevel())
             .addProgramFiles(default1())
             .addProgramFiles(default2())
             .build());
     D8.run(
         D8Command.builder()
-            .setMinApiLevel(Constants.ANDROID_N_API)
+            .setMinApiLevel(AndroidApiLevel.N.getLevel())
             .addProgramFiles(default1())
             .addProgramFiles(androidN2())
             .build());
     D8.run(
         D8Command.builder()
-            .setMinApiLevel(Constants.ANDROID_N_API)
+            .setMinApiLevel(AndroidApiLevel.N.getLevel())
             .addProgramFiles(androidN1())
             .addProgramFiles(androidN2())
             .build());
@@ -146,7 +147,7 @@
     // Android K.
     D8.run(
         D8Command.builder()
-            .setMinApiLevel(Constants.ANDROID_K_API)
+            .setMinApiLevel(AndroidApiLevel.K.getLevel())
             .addProgramFiles(default1())
             .addProgramFiles(default2())
             .build());
@@ -156,7 +157,7 @@
   public void mergeErrorVersionNWithVersionOInput() throws CompilationException, IOException {
     D8.run(
         D8Command.builder()
-            .setMinApiLevel(Constants.ANDROID_N_API)
+            .setMinApiLevel(AndroidApiLevel.N.getLevel())
             .addProgramFiles(default1())
             .addProgramFiles(androidO2())
             .build());
@@ -166,7 +167,7 @@
   public void mergeErrorVersionKWithVersionOInput() throws CompilationException, IOException {
     D8.run(
         D8Command.builder()
-            .setMinApiLevel(Constants.ANDROID_K_API)
+            .setMinApiLevel(AndroidApiLevel.K.getLevel())
             .addProgramFiles(default1())
             .addProgramFiles(androidO2())
             .build());
@@ -176,7 +177,7 @@
   public void mergeErrorVersionKWithVersionNInput() throws CompilationException, IOException {
     D8.run(
         D8Command.builder()
-            .setMinApiLevel(Constants.ANDROID_K_API)
+            .setMinApiLevel(AndroidApiLevel.K.getLevel())
             .addProgramFiles(default1())
             .addProgramFiles(androidN2())
             .build());
diff --git a/src/test/java/com/android/tools/r8/debug/DebugTestBase.java b/src/test/java/com/android/tools/r8/debug/DebugTestBase.java
index cc01eab..34c1181 100644
--- a/src/test/java/com/android/tools/r8/debug/DebugTestBase.java
+++ b/src/test/java/com/android/tools/r8/debug/DebugTestBase.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.shaking.ProguardConfiguration;
 import com.android.tools.r8.shaking.ProguardRuleParserException;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.OffOrAuto;
@@ -182,7 +183,7 @@
 
   protected final boolean supportsDefaultMethod() {
     return RUNTIME_KIND == RuntimeKind.JAVA ||
-        ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm()) >= Constants.ANDROID_N_API;
+        ToolHelper.getMinApiLevelForDexVm(ToolHelper.getDexVm()) >= AndroidApiLevel.N.getLevel();
   }
 
   protected static boolean isRunningJava() {
diff --git a/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java b/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java
index 39d90d6..59da13f 100644
--- a/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java
@@ -8,6 +8,7 @@
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.errors.CompilationError;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.OffOrAuto;
 import com.google.common.collect.Sets;
 import java.io.File;
@@ -85,8 +86,8 @@
     ToolHelper.runD8(
         D8Command.builder().addClasspathFiles(classpath)
         .addProgramFiles(toCompile)
-        .addLibraryFiles(Paths.get(ToolHelper.getAndroidJar(Constants.ANDROID_K_API)))
-        .setMinApiLevel(Constants.ANDROID_K_API)
+        .addLibraryFiles(Paths.get(ToolHelper.getAndroidJar(AndroidApiLevel.K.getLevel())))
+        .setMinApiLevel(AndroidApiLevel.K.getLevel())
         .build(),
         options -> options.interfaceMethodDesugaring = OffOrAuto.Auto);
   }
@@ -99,8 +100,8 @@
     ToolHelper.runD8(
         D8Command.builder().addClasspathFiles(classpath)
         .addProgramFiles(toCompile)
-        .addLibraryFiles(Paths.get(ToolHelper.getAndroidJar(Constants.ANDROID_K_API)))
-        .setMinApiLevel(Constants.ANDROID_K_API)
+        .addLibraryFiles(Paths.get(ToolHelper.getAndroidJar(AndroidApiLevel.K.getLevel())))
+        .setMinApiLevel(AndroidApiLevel.K.getLevel())
         .build(),
         options -> options.interfaceMethodDesugaring = OffOrAuto.Off);
   }
diff --git a/src/test/java/com/android/tools/r8/internal/CompilationTestBase.java b/src/test/java/com/android/tools/r8/internal/CompilationTestBase.java
index 91ecb4f..3e4d129 100644
--- a/src/test/java/com/android/tools/r8/internal/CompilationTestBase.java
+++ b/src/test/java/com/android/tools/r8/internal/CompilationTestBase.java
@@ -16,6 +16,7 @@
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.shaking.ProguardRuleParserException;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.ArtErrorParser;
 import com.android.tools.r8.utils.ArtErrorParser.ArtErrorInfo;
@@ -82,7 +83,7 @@
         builder.addProguardConfigurationFiles(Paths.get(pgConf));
       }
       builder.setMode(mode);
-      builder.setMinApiLevel(Constants.ANDROID_L_API);
+      builder.setMinApiLevel(AndroidApiLevel.L.getLevel());
       builder.addProguardConfigurationConsumer(b -> {
         b.setPrintSeeds(false);
       });
@@ -94,7 +95,7 @@
               D8Command.builder()
                   .addProgramFiles(ListUtils.map(inputs, Paths::get))
                   .setMode(mode)
-                  .setMinApiLevel(Constants.ANDROID_L_API)
+                  .setMinApiLevel(AndroidApiLevel.L.getLevel())
                   .build());
     }
     return checkVerification(outputApp, referenceApk);
diff --git a/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java b/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java
index 75a0275..02e301e 100644
--- a/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java
+++ b/src/test/java/com/android/tools/r8/internal/R8GMSCoreDeterministicTest.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.shaking.ProguardRuleParserException;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.OutputMode;
 import com.beust.jcommander.internal.Lists;
@@ -40,7 +41,7 @@
           options.testing.irOrdering = this::shuffle;
           // Only use one thread to process to process in the order decided by the callback.
           options.numberOfThreads = 1;
-          options.minApiLevel = Constants.ANDROID_L_API;
+          options.minApiLevel = AndroidApiLevel.L.getLevel();
         });
   }
 
diff --git a/src/test/java/com/android/tools/r8/internal/R8GMSCoreFixedPointTest.java b/src/test/java/com/android/tools/r8/internal/R8GMSCoreFixedPointTest.java
index 376ccf3..0b0151c 100644
--- a/src/test/java/com/android/tools/r8/internal/R8GMSCoreFixedPointTest.java
+++ b/src/test/java/com/android/tools/r8/internal/R8GMSCoreFixedPointTest.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.shaking.ProguardRuleParserException;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import java.io.IOException;
 import java.nio.file.Paths;
@@ -23,7 +24,7 @@
     // First compilation.
     AndroidApp app = AndroidApp.fromProgramDirectory(Paths.get(GMSCORE_V7_DIR));
     AndroidApp app1 =
-        ToolHelper.runR8(app, options -> options.minApiLevel = Constants.ANDROID_L_API);
+        ToolHelper.runR8(app, options -> options.minApiLevel = AndroidApiLevel.L.getLevel());
 
     // Second compilation.
     // Add option --skip-outline-opt for second compilation. The second compilation can find
@@ -32,7 +33,7 @@
     // See b/33410508 and b/33475705.
     AndroidApp app2 = ToolHelper.runR8(app1, options -> {
       options.outline.enabled = false;
-      options.minApiLevel = Constants.ANDROID_L_API;
+      options.minApiLevel = AndroidApiLevel.L.getLevel();
     });
 
     // TODO: Require that the results of the two compilations are the same.
diff --git a/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java b/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java
index ab88a99..b260304 100644
--- a/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java
+++ b/src/test/java/com/android/tools/r8/jsr45/JSR45Tests.java
@@ -13,6 +13,7 @@
 import com.android.tools.r8.graph.DexAnnotationElement;
 import com.android.tools.r8.graph.DexValue.DexValueString;
 import com.android.tools.r8.shaking.ProguardRuleParserException;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.DexInspector;
 import com.android.tools.r8.utils.DexInspector.AnnotationSubject;
@@ -52,7 +53,7 @@
   void compileWithD8(Path intputPath, Path outputPath) throws IOException, CompilationException {
     D8.run(
         D8Command.builder()
-            .setMinApiLevel(Constants.ANDROID_O_API)
+            .setMinApiLevel(AndroidApiLevel.O.getLevel())
             .addProgramFiles(intputPath)
             .setOutputPath(outputPath)
             .build());
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index ed19b8e..15cd3b6 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -47,6 +47,7 @@
 import com.android.tools.r8.jasmin.JasminBuilder;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.shaking.ProguardRuleParserException;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.DexInspector;
@@ -105,17 +106,19 @@
     // Generates an application with many classes, every even in one package and every odd in
     // another. Keep the number of methods low enough for single dex application.
     AndroidApp generated = generateApplication(
-        MANY_CLASSES, Constants.DEFAULT_ANDROID_API, MANY_CLASSES_SINGLE_DEX_METHODS_PER_CLASS);
+        MANY_CLASSES, AndroidApiLevel.getDefault().getLevel(),
+        MANY_CLASSES_SINGLE_DEX_METHODS_PER_CLASS);
     generated.write(getManyClassesSingleDexAppPath(), OutputMode.Indexed);
 
     // Generates an application with many classes, every even in one package and every odd in
     // another. Add enough methods so the application cannot fit into one dex file.
     generated = generateApplication(
-        MANY_CLASSES, Constants.ANDROID_L_API, MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS);
+        MANY_CLASSES, AndroidApiLevel.L.getLevel(), MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS);
     generated.write(getManyClassesMultiDexAppPath(), OutputMode.Indexed);
 
     // Generates an application with two classes, each with the maximum possible number of methods.
-    generated = generateApplication(TWO_LARGE_CLASSES, Constants.ANDROID_N_API, MAX_METHOD_COUNT);
+    generated = generateApplication(TWO_LARGE_CLASSES, AndroidApiLevel.N.getLevel(),
+        MAX_METHOD_COUNT);
     generated.write(getTwoLargeClassesAppPath(), OutputMode.Indexed);
   }
 
@@ -403,7 +406,7 @@
     // another. Add enough methods so the application cannot fit into one dex file.
     // Notice that this one allows multidex while using lower API.
     AndroidApp generated = generateApplication(
-        MANY_CLASSES, Constants.ANDROID_K_API, true, MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS);
+        MANY_CLASSES, AndroidApiLevel.K.getLevel(), true, MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS);
     generated.write(getManyClassesForceMultiDexAppPath(), OutputMode.Indexed);
     // Make sure the generated app indeed has multiple dex files.
     assertTrue(generated.getDexProgramResources().size() > 1);
@@ -416,7 +419,8 @@
     // Notice that this one fails due to the min API.
     try {
       generateApplication(
-          MANY_CLASSES, Constants.ANDROID_K_API, false, MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS);
+          MANY_CLASSES, AndroidApiLevel.K.getLevel(), false,
+          MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS);
       fail("Expect to fail, for there are many classes while multidex is not enabled.");
     } catch (DexOverflowException e) {
       // Make sure {@link MonoDexDistributor} was used.
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
index cc56417..e8d8ee7 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
@@ -4,7 +4,6 @@
 
 package com.android.tools.r8.maindexlist;
 
-import static com.android.tools.r8.dex.Constants.ANDROID_I_API;
 import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
 import static com.android.tools.r8.utils.FileUtils.ZIP_EXTENSION;
 
@@ -16,6 +15,7 @@
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.desugar.LambdaRewriter;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.InternalOptions;
 import java.nio.charset.StandardCharsets;
@@ -48,7 +48,7 @@
         EXAMPLE_BUILD_DIR,
         Paths.get(EXAMPLE_SRC_DIR, "multidex", "main-dex-rules.txt"),
         Paths.get(EXAMPLE_SRC_DIR, "multidex001", "ref-list-1.txt"),
-        ANDROID_I_API);
+        AndroidApiLevel.I.getLevel());
   }
 
   @Test
@@ -59,7 +59,7 @@
         EXAMPLE_BUILD_DIR,
         Paths.get(EXAMPLE_SRC_DIR, "multidex001", "main-dex-rules-2.txt"),
         Paths.get(EXAMPLE_SRC_DIR, "multidex001", "ref-list-2.txt"),
-        ANDROID_I_API);
+        AndroidApiLevel.I.getLevel());
   }
 
   @Test
@@ -70,7 +70,7 @@
         EXAMPLE_BUILD_DIR,
         Paths.get(EXAMPLE_SRC_DIR, "multidex", "main-dex-rules.txt"),
         Paths.get(EXAMPLE_SRC_DIR, "multidex002", "ref-list-1.txt"),
-        ANDROID_I_API);
+        AndroidApiLevel.I.getLevel());
   }
 
   @Test
@@ -81,7 +81,7 @@
         EXAMPLE_BUILD_DIR,
         Paths.get(EXAMPLE_SRC_DIR, "multidex", "main-dex-rules.txt"),
         Paths.get(EXAMPLE_SRC_DIR, "multidex003", "ref-list-1.txt"),
-        ANDROID_I_API);
+        AndroidApiLevel.I.getLevel());
   }
 
   @Test
@@ -92,7 +92,7 @@
         EXAMPLE_O_BUILD_DIR,
         Paths.get(EXAMPLE_SRC_DIR, "multidex", "main-dex-rules.txt"),
         Paths.get(EXAMPLE_O_SRC_DIR, "multidex004", "ref-list-1.txt"),
-        ANDROID_I_API);
+        AndroidApiLevel.I.getLevel());
   }
 
   private void doTest(
diff --git a/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingTest.java b/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingTest.java
index a80f46d..22876ff 100644
--- a/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingTest.java
+++ b/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingTest.java
@@ -12,6 +12,7 @@
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.naming.MemberNaming.MethodSignature;
 import com.android.tools.r8.shaking.ProguardRuleParserException;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.DexInspector;
 import com.android.tools.r8.utils.DexInspector.FieldAccessInstructionSubject;
 import com.android.tools.r8.utils.DexInspector.InstructionSubject;
@@ -294,9 +295,9 @@
     public int getMinApiLevel() {
       switch (version) {
         case PRE_N:
-          return Constants.DEFAULT_ANDROID_API;
+          return AndroidApiLevel.getDefault().getLevel();
         case N:
-          return Constants.ANDROID_N_API;
+          return AndroidApiLevel.N.getLevel();
         default:
           Assert.fail();
           return -1;
diff --git a/src/test/java/com/android/tools/r8/regress/b63935662/Regress63935662.java b/src/test/java/com/android/tools/r8/regress/b63935662/Regress63935662.java
index 8d0e667..01b0a17 100644
--- a/src/test/java/com/android/tools/r8/regress/b63935662/Regress63935662.java
+++ b/src/test/java/com/android/tools/r8/regress/b63935662/Regress63935662.java
@@ -8,6 +8,7 @@
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.dex.Constants;
+import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.OffOrAuto;
 import java.nio.file.Path;
@@ -22,7 +23,7 @@
     R8Command command =
         ToolHelper.prepareR8CommandBuilder(app)
             .addProguardConfigurationFiles(proguardConfig)
-            .setMinApiLevel(Constants.ANDROID_L_API)
+            .setMinApiLevel(AndroidApiLevel.L.getLevel())
             .build();
     String resultFromJava = runOnJava(mainClass);
     app = ToolHelper.runR8(command, options -> options.interfaceMethodDesugaring = OffOrAuto.Auto);