Add YouTube 16.12 to run_on_app.py

Fixes: 183734568
Change-Id: I8b58be9bb1e162a938d0886c03a290f130bbf776
diff --git a/src/test/java/com/android/tools/r8/D8TestBuilder.java b/src/test/java/com/android/tools/r8/D8TestBuilder.java
index d299224..822a5bd 100644
--- a/src/test/java/com/android/tools/r8/D8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/D8TestBuilder.java
@@ -82,9 +82,12 @@
 
   @Override
   public D8TestBuilder enableCoreLibraryDesugaring(
-      AndroidApiLevel minApiLevel, KeepRuleConsumer keepRuleConsumer) {
+      AndroidApiLevel minApiLevel,
+      KeepRuleConsumer keepRuleConsumer,
+      StringResource desugaredLibraryConfiguration) {
     if (minApiLevel.getLevel() < AndroidApiLevel.O.getLevel()) {
-      super.enableCoreLibraryDesugaring(minApiLevel, keepRuleConsumer);
+      super.enableCoreLibraryDesugaring(
+          minApiLevel, keepRuleConsumer, desugaredLibraryConfiguration);
       builder.setDesugaredLibraryKeepRuleConsumer(keepRuleConsumer);
     }
     return self();
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index 0d90a34..19b414a 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -618,9 +618,12 @@
 
   @Override
   public T enableCoreLibraryDesugaring(
-      AndroidApiLevel minApiLevel, KeepRuleConsumer keepRuleConsumer) {
+      AndroidApiLevel minApiLevel,
+      KeepRuleConsumer keepRuleConsumer,
+      StringResource desugaredLibraryConfiguration) {
     if (minApiLevel.getLevel() < AndroidApiLevel.O.getLevel()) {
-      super.enableCoreLibraryDesugaring(minApiLevel, keepRuleConsumer);
+      super.enableCoreLibraryDesugaring(
+          minApiLevel, keepRuleConsumer, desugaredLibraryConfiguration);
       builder.setDesugaredLibraryKeepRuleConsumer(keepRuleConsumer);
     }
     return self();
diff --git a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
index 766fb0f..cd584e0 100644
--- a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -432,9 +432,18 @@
 
   public T enableCoreLibraryDesugaring(
       AndroidApiLevel minApiLevel, KeepRuleConsumer keepRuleConsumer) {
-    assert minApiLevel.getLevel() < AndroidApiLevel.O.getLevel();
-    builder.addDesugaredLibraryConfiguration(
+    return enableCoreLibraryDesugaring(
+        minApiLevel,
+        keepRuleConsumer,
         StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()));
+  }
+
+  public T enableCoreLibraryDesugaring(
+      AndroidApiLevel minApiLevel,
+      KeepRuleConsumer keepRuleConsumer,
+      StringResource desugaredLibraryConfiguration) {
+    assert minApiLevel.getLevel() < AndroidApiLevel.O.getLevel();
+    builder.addDesugaredLibraryConfiguration(desugaredLibraryConfiguration);
     // TODO(b/158543446): This should not be setting an implicit library file. Doing so causes
     //  inconsistent library setup depending on the api level and makes tests hard to read and
     //  reason about.
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryTestBase.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryTestBase.java
index 8f1d451..3b9a63d 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryTestBase.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredLibraryTestBase.java
@@ -19,6 +19,7 @@
 import com.android.tools.r8.TestDiagnosticMessagesImpl;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.ToolHelper.DexVm.Version;
 import com.android.tools.r8.errors.Unreachable;
@@ -27,21 +28,25 @@
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.tracereferences.TraceReferences;
 import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.ConsumerUtils;
 import com.android.tools.r8.utils.FileUtils;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableList;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Consumer;
 import org.junit.BeforeClass;
+import org.junit.rules.TemporaryFolder;
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.MethodVisitor;
@@ -94,6 +99,158 @@
     return parameters.getApiLevel().getLevel() < AndroidApiLevel.O.getLevel();
   }
 
+  public static class L8TestBuilder {
+
+    private final AndroidApiLevel apiLevel;
+    private final TemporaryFolder temp;
+
+    private CompilationMode mode = CompilationMode.RELEASE;
+    private List<String> keepRules = new ArrayList<>();
+    private List<Path> additionalProgramFiles = new ArrayList<>();
+    private Consumer<InternalOptions> optionsModifier = ConsumerUtils.emptyConsumer();
+    private Path desugarJDKLibs = ToolHelper.getDesugarJDKLibs();
+    private Path desugarJDKLibsConfiguration = ToolHelper.DESUGAR_LIB_CONVERSIONS;
+    private StringResource desugaredLibraryConfiguration =
+        StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting());
+
+    public static L8TestBuilder builder(AndroidApiLevel apiLevel, TemporaryFolder temp) {
+      return new L8TestBuilder(apiLevel, temp);
+    }
+
+    private L8TestBuilder(AndroidApiLevel apiLevel, TemporaryFolder temp) {
+      this.apiLevel = apiLevel;
+      this.temp = temp;
+    }
+
+    public L8TestBuilder addProgramFiles(Collection<Path> programFiles) {
+      this.additionalProgramFiles.addAll(programFiles);
+      return this;
+    }
+
+    public L8TestBuilder addKeepRules(String keepRules) {
+      if (!keepRules.trim().isEmpty()) {
+        this.keepRules.add(keepRules);
+      }
+      return this;
+    }
+
+    public L8TestBuilder addKeepRuleFiles(Collection<Path> keepRuleFiles) throws IOException {
+      for (Path keepRuleFile : keepRuleFiles) {
+        addKeepRules(FileUtils.readTextFile(keepRuleFile, StandardCharsets.UTF_8));
+      }
+      return this;
+    }
+
+    public L8TestBuilder addOptionsModifier(Consumer<InternalOptions> optionsModifier) {
+      this.optionsModifier = this.optionsModifier.andThen(optionsModifier);
+      return this;
+    }
+
+    public L8TestBuilder applyIf(boolean condition, ThrowableConsumer<L8TestBuilder> thenConsumer) {
+      return applyIf(condition, thenConsumer, ThrowableConsumer.empty());
+    }
+
+    public L8TestBuilder applyIf(
+        boolean condition,
+        ThrowableConsumer<L8TestBuilder> thenConsumer,
+        ThrowableConsumer<L8TestBuilder> elseConsumer) {
+      if (condition) {
+        thenConsumer.acceptWithRuntimeException(this);
+      } else {
+        elseConsumer.acceptWithRuntimeException(this);
+      }
+      return this;
+    }
+
+    public L8TestBuilder setDebug() {
+      this.mode = CompilationMode.DEBUG;
+      return this;
+    }
+
+    public L8TestBuilder setDesugarJDKLibs(Path desugarJDKLibs) {
+      this.desugarJDKLibs = desugarJDKLibs;
+      return this;
+    }
+
+    public L8TestBuilder setDesugarJDKLibsConfiguration(Path desugarJDKLibsConfiguration) {
+      this.desugarJDKLibsConfiguration = desugarJDKLibsConfiguration;
+      return this;
+    }
+
+    public L8TestBuilder setDesugaredLibraryConfiguration(Path path) {
+      this.desugaredLibraryConfiguration = StringResource.fromFile(path);
+      return this;
+    }
+
+    public Path compile() {
+      // We wrap exceptions in a RuntimeException to call this from a lambda.
+      try {
+        // If we compile extended library here, it means we use TestNG.
+        // TestNG requires annotations, hence we disable AnnotationRemoval.
+        // This implies that extra warning are generated if this is set.
+        TestDiagnosticMessagesImpl diagnosticsHandler = new TestDiagnosticMessagesImpl();
+        Path desugaredLib = temp.newFolder().toPath().resolve("desugar_jdk_libs_dex.zip");
+        L8Command.Builder l8Builder =
+            L8Command.builder(diagnosticsHandler)
+                .addProgramFiles(getProgramFiles())
+                .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
+                .setMode(mode)
+                .addDesugaredLibraryConfiguration(desugaredLibraryConfiguration)
+                .setMinApiLevel(apiLevel.getLevel())
+                .setOutput(desugaredLib, OutputMode.DexIndexed);
+        Path mapping = null;
+        if (!keepRules.isEmpty()) {
+          mapping = temp.newFolder().toPath().resolve("mapping.txt");
+          l8Builder.addProguardConfiguration(
+              ImmutableList.<String>builder()
+                  .addAll(keepRules)
+                  .add("-printmapping " + mapping)
+                  .build(),
+              Origin.unknown());
+        }
+        ToolHelper.runL8(
+            l8Builder.build(),
+            options -> {
+              if (!additionalProgramFiles.isEmpty()) {
+                options.testing.disableL8AnnotationRemoval = true;
+              }
+              optionsModifier.accept(options);
+            });
+        if (additionalProgramFiles.isEmpty()) {
+          assertTrue(
+              diagnosticsHandler.getInfos().stream()
+                  .noneMatch(
+                      string ->
+                          string
+                              .getDiagnosticMessage()
+                              .startsWith(
+                                  "Invalid parameter counts in MethodParameter attributes.")));
+        }
+        new CodeInspector(desugaredLib, mapping)
+            .forAllClasses(clazz -> assertTrue(clazz.getFinalName().startsWith("j$.")));
+        return desugaredLib;
+      } catch (Exception e) {
+        // Don't wrap assumption violation so junit can catch it.
+        if (e instanceof RuntimeException) {
+          throw ((RuntimeException) e);
+        }
+        throw new RuntimeException(e);
+      }
+    }
+
+    private Collection<Path> getProgramFiles() {
+      return ImmutableList.<Path>builder()
+          .add(desugarJDKLibs)
+          .add(desugarJDKLibsConfiguration)
+          .addAll(additionalProgramFiles)
+          .build();
+    }
+  }
+
+  protected L8TestBuilder testForL8(AndroidApiLevel apiLevel) {
+    return new L8TestBuilder(apiLevel, temp);
+  }
+
   protected Path buildDesugaredLibrary(AndroidApiLevel apiLevel) {
     return buildDesugaredLibrary(apiLevel, "", false);
   }
@@ -126,62 +283,11 @@
       boolean shrink,
       List<Path> additionalProgramFiles,
       Consumer<InternalOptions> optionsModifier) {
-    // We wrap exceptions in a RuntimeException to call this from a lambda.
-    try {
-      // If we compile extended library here, it means we use TestNG.
-      // TestNG requires annotations, hence we disable AnnotationRemoval.
-      // This implies that extra warning are generated if this is set.
-      boolean extraFiles = !additionalProgramFiles.isEmpty();
-      ArrayList<Path> extraPaths = new ArrayList<>(additionalProgramFiles);
-      TestDiagnosticMessagesImpl diagnosticsHandler = new TestDiagnosticMessagesImpl();
-      Path desugaredLib = temp.newFolder().toPath().resolve("desugar_jdk_libs_dex.zip");
-      L8Command.Builder l8Builder =
-          L8Command.builder(diagnosticsHandler)
-              .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
-              .addProgramFiles(ToolHelper.getDesugarJDKLibs())
-              .addProgramFiles(ToolHelper.DESUGAR_LIB_CONVERSIONS)
-              .setMode(shrink ? CompilationMode.RELEASE : CompilationMode.DEBUG)
-              .addProgramFiles(extraPaths)
-              .addDesugaredLibraryConfiguration(
-                  StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()))
-              .setMinApiLevel(apiLevel.getLevel())
-              .setOutput(desugaredLib, OutputMode.DexIndexed);
-      Path mapping = null;
-      if (shrink) {
-        mapping = temp.newFolder().toPath().resolve("mapping.txt");
-        List<String> lines =
-            new ArrayList<>(Arrays.asList(keepRules.split(System.lineSeparator())));
-        lines.add("-printmapping " + mapping);
-        l8Builder.addProguardConfiguration(lines, Origin.unknown());
-      }
-      ToolHelper.runL8(
-          l8Builder.build(),
-          options -> {
-            if (extraFiles) {
-              options.testing.disableL8AnnotationRemoval = true;
-            }
-            optionsModifier.accept(options);
-          });
-      if (!extraFiles) {
-        assertTrue(
-            diagnosticsHandler.getInfos().stream()
-                .noneMatch(
-                    string ->
-                        string
-                            .getDiagnosticMessage()
-                            .startsWith(
-                                "Invalid parameter counts in MethodParameter attributes.")));
-      }
-      new CodeInspector(desugaredLib, mapping)
-          .forAllClasses(clazz -> assertTrue(clazz.getFinalName().startsWith("j$.")));
-      return desugaredLib;
-    } catch (Exception e) {
-      // Don't wrap assumption violation so junit can catch it.
-      if (e instanceof RuntimeException) {
-        throw ((RuntimeException) e);
-      }
-      throw new RuntimeException(e);
-    }
+    return testForL8(apiLevel)
+        .addProgramFiles(additionalProgramFiles)
+        .applyIf(shrink, builder -> builder.addKeepRules(keepRules), L8TestBuilder::setDebug)
+        .addOptionsModifier(optionsModifier)
+        .compile();
   }
 
   protected void assertLines2By2Correct(String stdOut) {
diff --git a/src/test/java/com/android/tools/r8/internal/YouTubeCompilationTestBase.java b/src/test/java/com/android/tools/r8/internal/YouTubeCompilationTestBase.java
index 1e87434..b9c868c 100644
--- a/src/test/java/com/android/tools/r8/internal/YouTubeCompilationTestBase.java
+++ b/src/test/java/com/android/tools/r8/internal/YouTubeCompilationTestBase.java
@@ -37,6 +37,33 @@
             + "/";
   }
 
+  protected Path getDesugaredLibraryConfiguration() {
+    Path path = Paths.get(base, "desugar_jdk_libs/full_desugar_jdk_libs.json");
+    assertTrue(path.toFile().exists());
+    return path;
+  }
+
+  protected Path getDesugaredLibraryJDKLibs() {
+    Path path = Paths.get(base, "desugar_jdk_libs/jdk_libs_to_desugar.jar");
+    assertTrue(path.toFile().exists());
+    return path;
+  }
+
+  protected Path getDesugaredLibraryJDKLibsConfiguration() {
+    Path path = Paths.get(base, "desugar_jdk_libs/desugar_jdk_libs_configuration.jar");
+    assertTrue(path.toFile().exists());
+    return path;
+  }
+
+  protected List<Path> getDesugaredLibraryKeepRuleFiles() {
+    ImmutableList<Path> keepRuleFiles =
+        ImmutableList.of(
+            Paths.get(base, "desugar_jdk_libs/base.pgcfg"),
+            Paths.get(base, "desugar_jdk_libs/minify_desugar_jdk_libs.pgcfg"));
+    assertTrue(keepRuleFiles.stream().allMatch(keepRuleFile -> keepRuleFile.toFile().exists()));
+    return keepRuleFiles;
+  }
+
   protected List<Path> getKeepRuleFiles() {
     ImmutableList.Builder<Path> builder = ImmutableList.builder();
     builder.add(Paths.get(base).resolve(PG_CONF));
diff --git a/src/test/java/com/android/tools/r8/internal/YouTubeV1612TreeShakeJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/YouTubeV1612TreeShakeJarVerificationTest.java
index 81be8fe..0f07300 100644
--- a/src/test/java/com/android/tools/r8/internal/YouTubeV1612TreeShakeJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/YouTubeV1612TreeShakeJarVerificationTest.java
@@ -8,11 +8,13 @@
 import static org.junit.Assume.assumeTrue;
 
 import com.android.tools.r8.R8TestCompileResult;
+import com.android.tools.r8.StringResource;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.ZipUtils;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.analysis.ProtoApplicationStats;
 import java.nio.file.Files;
@@ -29,6 +31,8 @@
   private static final boolean DUMP = false;
   private static final int MAX_SIZE = 30000000;
 
+  private final Path dumpDirectory = Paths.get("YouTubeV1612-" + System.currentTimeMillis());
+
   @Parameters(name = "{0}")
   public static TestParametersCollection data() {
     return getTestParameters().withNoneRuntime().build();
@@ -54,14 +58,17 @@
             .allowUnusedDontWarnPatterns()
             .allowUnusedProguardConfigurationRules()
             .setMinApi(AndroidApiLevel.L)
-            .enableCoreLibraryDesugaring(AndroidApiLevel.L, keepRuleConsumer)
+            .enableCoreLibraryDesugaring(
+                AndroidApiLevel.L,
+                keepRuleConsumer,
+                StringResource.fromFile(getDesugaredLibraryConfiguration()))
             .compile();
 
     if (ToolHelper.isLocalDevelopment()) {
       if (DUMP) {
-        long time = System.currentTimeMillis();
-        compileResult.writeToZip(Paths.get("YouTubeV1612-" + time + ".zip"));
-        compileResult.writeProguardMap(Paths.get("YouTubeV1612-" + time + ".map"));
+        dumpDirectory.toFile().mkdirs();
+        compileResult.writeToZip(dumpDirectory.resolve("app.zip"));
+        compileResult.writeProguardMap(dumpDirectory.resolve("mapping.txt"));
       }
 
       DexItemFactory dexItemFactory = new DexItemFactory();
@@ -75,14 +82,28 @@
       System.out.println(actual.getStats(baseline));
     }
 
-    long applicationSize = compileResult.getApp().applicationSize();
+    int applicationSize = compileResult.getApp().applicationSize();
     System.out.println("Dex size (app, excluding desugared library): " + applicationSize);
 
-    Path desugaredLibrary = buildDesugaredLibrary(AndroidApiLevel.L, keepRuleConsumer.get());
-    long desugaredLibrarySize = Files.size(desugaredLibrary);
+    Path desugaredLibrary =
+        testForL8(AndroidApiLevel.L)
+            .setDesugaredLibraryConfiguration(getDesugaredLibraryConfiguration())
+            .setDesugarJDKLibs(getDesugaredLibraryJDKLibs())
+            .setDesugarJDKLibsConfiguration(getDesugaredLibraryJDKLibsConfiguration())
+            .addKeepRules(keepRuleConsumer.get())
+            .addKeepRuleFiles(getDesugaredLibraryKeepRuleFiles())
+            .compile();
+
+    byte[] desugaredLibraryDex = ZipUtils.readSingleEntry(desugaredLibrary, "classes.dex");
+
+    if (DUMP) {
+      Files.write(dumpDirectory.resolve("desugared_jdk_libs.dex"), desugaredLibraryDex);
+    }
+
+    int desugaredLibrarySize = desugaredLibraryDex.length;
     System.out.println("Dex size (desugared library): " + desugaredLibrarySize);
 
-    long totalApplicationSize = applicationSize + desugaredLibrarySize;
+    int totalApplicationSize = applicationSize + desugaredLibrarySize;
     System.out.println("Dex size (total): " + totalApplicationSize);
 
     assertTrue(
diff --git a/third_party/youtube/youtube.android_16.12.tar.gz.sha1 b/third_party/youtube/youtube.android_16.12.tar.gz.sha1
index b4ba7e4..580b87e 100644
--- a/third_party/youtube/youtube.android_16.12.tar.gz.sha1
+++ b/third_party/youtube/youtube.android_16.12.tar.gz.sha1
@@ -1 +1 @@
-8e572873935b39dc65790631ffcdcd0a8f749c0f
\ No newline at end of file
+1e50d558d85ebd9741cf4bd62e01cf415d4d480f
\ No newline at end of file
diff --git a/tools/run_on_app.py b/tools/run_on_app.py
index b58eafb..60cd4f1 100755
--- a/tools/run_on_app.py
+++ b/tools/run_on_app.py
@@ -454,72 +454,62 @@
 def should_build(options):
   return not options.no_build and not options.golem
 
-def build_desugared_library_dex(options, quiet, temp, android_java8_libs, inputs, outdir):
-  if not input:
-    raise Exception("If 'android_java8_libs' is specified the inputs must be explicit"
-       + "(not defined using '-injars' in Proguard configuration files)")
+def build_desugared_library_dex(
+    options,
+    quiet,
+    temp,
+    android_java8_libs,
+    desugared_lib_pg_conf,
+    inputs,
+    outdir):
+  if not inputs:
+    raise Exception(
+        "If 'android_java8_libs' is specified the inputs must be explicit"
+            + "(not defined using '-injars' in Proguard configuration files)")
   if outdir.endswith('.zip') or outdir.endswith('.jar'):
-    raise Exception("If 'android_java8_libs' is specified the output must be a directory")
+    raise Exception(
+        "If 'android_java8_libs' is specified the output must be a directory")
 
   jar = None
   main = None
   if options.hash:
     jar = os.path.join(utils.LIBS, 'r8-' + options.hash + '.jar')
+    main = 'com.android.tools.r8.R8'
 
+  # Determine the l8 tool.
   assert(options.compiler_build in ['full', 'lib'])
   lib_prefix = 'r8lib-' if options.compiler_build == 'lib' else ''
+  tool = lib_prefix + 'l8'
 
-  # Determine the tracereferences tool.
-  tool = lib_prefix + 'tracereferences'
-  if options.hash:
-    main = 'com.android.tools.r8.TraceReferences'
-  tracereferences_output = os.path.join(outdir, 'tracereferences.pgcfg')
-  args = [
-    '--map-diagnostics:MissingDefinitionsDiagnostic', 'error', 'warning',
-    '--keep-rules',
-    '--lib', 'third_party/android_jar/lib-v30/android.jar',
-    '--target', android_java8_libs['library'],
-    '--output', tracereferences_output,
-  ]
-  for source in inputs:
-    args.extend(['--source', source])
-  exit_code = toolhelper.run(tool, args,
-      build=should_build(options),
-      debug=not options.no_debug,
-      quiet=quiet,
-      jar=jar,
-      main=main)
-  if exit_code != 0:
-    raise Exception("tracereferences failed")
-
-  # Determine the r8 tool.
-  tool = lib_prefix + 'r8'
-  if options.compiler_build == 'full':
-    tool = ''
-  else:
-    assert(options.compiler_build == 'lib')
-    tool = 'r8lib-r8'
-  if options.hash:
-    main = 'com.android.tools.r8.R8'
+  # Prepare out directory.
   android_java8_libs_output = os.path.join(temp, 'android_java8_libs')
   os.makedirs(android_java8_libs_output)
+
+  # Prepare arguments for L8.
   args = [
-    '--no-desugaring',
-    '--lib', '%s/android_jar/lib-v30/android.jar' % utils.THIRD_PARTY,
+    '--desugared-lib', android_java8_libs['config'],
+    '--lib', android_java8_libs['library'],
     '--output', android_java8_libs_output,
-    '--pg-conf', tracereferences_output,
-    android_java8_libs['library']
+    '--pg-conf', desugared_lib_pg_conf,
+    '--release',
   ]
-  for pgconf in android_java8_libs['pgconf']:
-    args.extend(['--pg-conf', pgconf])
-  exit_code = toolhelper.run(tool, args,
+  if 'pgconf' in android_java8_libs:
+    for pgconf in android_java8_libs['pgconf']:
+      args.extend(['--pg-conf', pgconf])
+  args.extend(android_java8_libs['program'])
+
+  # Run L8.
+  exit_code = toolhelper.run(
+      tool, args,
       build=should_build(options),
       debug=not options.no_debug,
       quiet=quiet,
       jar=jar,
       main=main)
+
   # Copy the desugared library DEX to the output.
-  dex_file_name = 'classes' + str(len(glob(os.path.join(outdir, '*.dex'))) + 1) + '.dex'
+  dex_file_name = (
+      'classes' + str(len(glob(os.path.join(outdir, '*.dex'))) + 1) + '.dex')
   shutil.copyfile(
       os.path.join(android_java8_libs_output, 'classes.dex'),
       os.path.join(outdir, dex_file_name))
@@ -680,6 +670,15 @@
           additional_pg_conf = GenerateAdditionalProguardConfiguration(
               temp, os.path.abspath(pg_outdir))
           args.extend(['--pg-conf', additional_pg_conf])
+
+      android_java8_libs = values.get('android_java8_libs')
+      if android_java8_libs:
+        desugared_lib_pg_conf = os.path.join(
+            temp, 'desugared-lib-pg-conf.txt')
+        args.extend(['--desugared-lib', android_java8_libs['config']])
+        args.extend(
+            ['--desugared-lib-pg-conf-output', desugared_lib_pg_conf])
+
       stderr_path = os.path.join(temp, 'stderr')
       with open(stderr_path, 'w') as stderr:
         jar = None
@@ -722,9 +721,10 @@
             .format(options.print_memoryuse,
                 utils.grep_memoryuse(options.track_memory_to_file)))
 
-      if 'android_java8_libs' in values:
-        android_java8_libs = values['android_java8_libs']
-        build_desugared_library_dex(options, quiet, temp, android_java8_libs, inputs, outdir)
+      if android_java8_libs:
+        build_desugared_library_dex(
+            options, quiet, temp, android_java8_libs,
+            desugared_lib_pg_conf, inputs, outdir)
 
 
   if options.print_runtimeraw:
diff --git a/tools/toolhelper.py b/tools/toolhelper.py
index b66b70f..02cb549 100644
--- a/tools/toolhelper.py
+++ b/tools/toolhelper.py
@@ -39,6 +39,8 @@
     cmd.extend(['-cp', jar, main])
   elif tool == 'r8lib-d8':
     cmd.extend(['-cp', utils.R8LIB_JAR, 'com.android.tools.r8.D8'])
+  elif tool == 'r8lib-l8':
+    cmd.extend(['-cp', utils.R8LIB_JAR, 'com.android.tools.r8.L8'])
   elif tool == 'r8lib-r8':
     cmd.extend(['-cp', utils.R8LIB_JAR, 'com.android.tools.r8.R8'])
   elif tool == 'r8lib-tracereferences':
diff --git a/tools/youtube_data.py b/tools/youtube_data.py
index eafe5bb..04d9e1f 100644
--- a/tools/youtube_data.py
+++ b/tools/youtube_data.py
@@ -37,6 +37,9 @@
 V15_33_BASE = os.path.join(BASE, 'youtube.android_15.33')
 V15_33_PREFIX = os.path.join(V15_33_BASE, 'YouTubeRelease')
 
+V16_12_BASE = os.path.join(BASE, 'youtube.android_16.12')
+V16_12_PREFIX = os.path.join(V16_12_BASE, 'YouTubeRelease')
+
 # NOTE: we always use android.jar for SDK v25, later we might want to revise it
 #       to use proper android.jar version for each of youtube version separately.
 ANDROID_JAR = utils.get_android_jar(25)
@@ -283,4 +286,35 @@
       'min-api' : ANDROID_L_API,
     }
   },
+  '16.12': {
+    'deploy' : {
+      'sanitize_libraries': False,
+      'inputs': ['%s_deploy.jar' % V16_12_PREFIX],
+      'libraries' : [
+          os.path.join(
+              V16_12_BASE,
+              'legacy_YouTubeRelease_combined_library_jars_filtered.jar')],
+      'pgconf': [
+          '%s_proguard.config' % V16_12_PREFIX,
+          '%s/proguardsettings/YouTubeRelease_proguard.config' % utils.THIRD_PARTY,
+          utils.IGNORE_WARNINGS_RULES],
+      'min-api' : ANDROID_L_API,
+      'android_java8_libs': {
+        'config': '%s/desugar_jdk_libs/full_desugar_jdk_libs.json' % V16_12_BASE,
+        'program': [
+            '%s/desugar_jdk_libs/jdk_libs_to_desugar.jar' % V16_12_BASE,
+            '%s/desugar_jdk_libs/desugar_jdk_libs_configuration.jar' % V16_12_BASE],
+        'library': '%s/android_jar/lib-v30/android.jar' % utils.THIRD_PARTY,
+        'pgconf': [
+          '%s/desugar_jdk_libs/base.pgcfg' % V16_12_BASE,
+          '%s/desugar_jdk_libs/minify_desugar_jdk_libs.pgcfg' % V16_12_BASE
+        ]
+      }
+    },
+    'proguarded' : {
+      'inputs': ['%s_proguard.jar' % V16_12_PREFIX],
+      'pgmap': '%s_proguard.map' % V16_12_PREFIX,
+      'min-api' : ANDROID_L_API,
+    }
+  },
 }