Snap for 4818534 from 651fcf9089db41046473320602883ffd4a3bba60 to pi-release

Change-Id: Ifd0daf84a846a4e7c48c43d5d82b444a01871920
diff --git a/src/com/google/doclava/Doclava.java b/src/com/google/doclava/Doclava.java
index 8231471..caa44a6 100644
--- a/src/com/google/doclava/Doclava.java
+++ b/src/com/google/doclava/Doclava.java
@@ -183,6 +183,7 @@
     // Create the dependency graph for the stubs  directory
     boolean offlineMode = false;
     String apiFile = null;
+    String dexApiFile = null;
     String removedApiFile = null;
     String removedDexApiFile = null;
     String exactApiFile = null;
@@ -304,6 +305,8 @@
         sdkValuePath = a[1];
       } else if (a[0].equals("-api")) {
         apiFile = a[1];
+      } else if (a[0].equals("-dexApi")) {
+        dexApiFile = a[1];
       } else if (a[0].equals("-removedApi")) {
         removedApiFile = a[1];
       } else if (a[0].equals("-removedDexApi")) {
@@ -558,12 +561,12 @@
     }
 
     // Stubs
-    if (stubsDir != null || apiFile != null || proguardFile != null || removedApiFile != null
-        || removedDexApiFile != null || exactApiFile != null || privateApiFile != null
-        || privateDexApiFile != null) {
-      Stubs.writeStubsAndApi(stubsDir, apiFile, proguardFile, removedApiFile, removedDexApiFile,
-          exactApiFile, privateApiFile, privateDexApiFile, stubPackages, stubImportPackages,
-          stubSourceOnly);
+    if (stubsDir != null || apiFile != null || dexApiFile != null || proguardFile != null
+        || removedApiFile != null || removedDexApiFile != null || exactApiFile != null
+        || privateApiFile != null || privateDexApiFile != null) {
+      Stubs.writeStubsAndApi(stubsDir, apiFile, dexApiFile, proguardFile, removedApiFile,
+          removedDexApiFile, exactApiFile, privateApiFile, privateDexApiFile, stubPackages,
+          stubImportPackages, stubSourceOnly);
     }
 
     Errors.printErrors();
@@ -858,6 +861,9 @@
     if (option.equals("-api")) {
       return 2;
     }
+    if (option.equals("-dexApi")) {
+      return 2;
+    }
     if (option.equals("-removedApi")) {
       return 2;
     }
diff --git a/src/com/google/doclava/Stubs.java b/src/com/google/doclava/Stubs.java
index f5eaf4b..dd2a5a7 100644
--- a/src/com/google/doclava/Stubs.java
+++ b/src/com/google/doclava/Stubs.java
@@ -46,15 +46,16 @@
 import java.util.stream.Collectors;
 
 public class Stubs {
-  public static void writeStubsAndApi(String stubsDir, String apiFile, String keepListFile,
-      String removedApiFile, String removedDexApiFile, String exactApiFile, String privateApiFile,
-      String privateDexApiFile, HashSet<String> stubPackages, HashSet<String> stubImportPackages,
-      boolean stubSourceOnly) {
+  public static void writeStubsAndApi(String stubsDir, String apiFile, String dexApiFile,
+      String keepListFile, String removedApiFile, String removedDexApiFile, String exactApiFile,
+      String privateApiFile, String privateDexApiFile, HashSet<String> stubPackages,
+      HashSet<String> stubImportPackages, boolean stubSourceOnly) {
     // figure out which classes we need
     final HashSet<ClassInfo> notStrippable = new HashSet<ClassInfo>();
     Collection<ClassInfo> all = Converter.allClasses();
     Map<PackageInfo, List<ClassInfo>> allClassesByPackage = null;
     PrintStream apiWriter = null;
+    PrintStream dexApiWriter = null;
     PrintStream keepListWriter = null;
     PrintStream removedApiWriter = null;
     PrintStream removedDexApiWriter = null;
@@ -72,6 +73,16 @@
             "Cannot open file for write.");
       }
     }
+    if (dexApiFile != null) {
+      try {
+        File dexApi = new File(dexApiFile);
+        dexApi.getParentFile().mkdirs();
+        dexApiWriter = new PrintStream(new BufferedOutputStream(new FileOutputStream(dexApi)));
+      } catch (FileNotFoundException e) {
+        Errors.error(Errors.IO_ERROR, new SourcePositionInfo(dexApiFile, 0, 0),
+            "Cannot open file for write.");
+      }
+    }
     if (keepListFile != null) {
       try {
         File keepList = new File(keepListFile);
@@ -239,7 +250,7 @@
             writeClassFile(stubsDir, notStrippable, cl);
           }
           // build class list for api file or keep list file
-          if (apiWriter != null || keepListWriter != null) {
+          if (apiWriter != null || dexApiWriter != null || keepListWriter != null) {
             if (packages.containsKey(cl.containingPackage())) {
               packages.get(cl.containingPackage()).add(cl);
             } else {
@@ -268,6 +279,7 @@
     FilterPredicate apiFilter = new FilterPredicate(new ApiPredicate().setIgnoreShown(ignoreShown));
     ApiPredicate apiReference = new ApiPredicate().setIgnoreShown(true);
     Predicate<MemberInfo> apiEmit = apiFilter.and(new ElidingPredicate(apiReference));
+    Predicate<MemberInfo> dexApiEmit = memberIsNotCloned.and(apiFilter);
 
     Predicate<MemberInfo> privateEmit = memberIsNotCloned.and(apiFilter.negate());
     Predicate<MemberInfo> privateReference = (x -> true);
@@ -284,6 +296,12 @@
       apiWriter.close();
     }
 
+    // Write out the current DEX API
+    if (dexApiWriter != null) {
+      writeDexApi(dexApiWriter, packages, dexApiEmit);
+      dexApiWriter.close();
+    }
+
     // Write out the keep list
     if (keepListWriter != null) {
       writeKeepList(keepListWriter, packages, notStrippable);