AAPT2: Move all file output to FileOutputStream

FileOutputStream is safe to use on Windows, as it opens
files using our compatibility API.

Bug: 68262818
Test: make aapt2_tests
Change-Id: Ib0b27e93edd609b49b1327db7d9867a002198ebb
diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp
index b214d21..132b234 100644
--- a/tools/aapt2/java/ProguardRules.cpp
+++ b/tools/aapt2/java/ProguardRules.cpp
@@ -20,14 +20,18 @@
 #include <string>
 
 #include "android-base/macros.h"
+#include "androidfw/StringPiece.h"
 
 #include "JavaClassGenerator.h"
 #include "ResourceUtils.h"
 #include "ValueVisitor.h"
-#include "androidfw/StringPiece.h"
+#include "text/Printer.h"
 #include "util/Util.h"
 #include "xml/XmlDom.h"
 
+using ::aapt::io::OutputStream;
+using ::aapt::text::Printer;
+
 namespace aapt {
 namespace proguard {
 
@@ -326,12 +330,13 @@
   return true;
 }
 
-bool WriteKeepSet(std::ostream* out, const KeepSet& keep_set) {
+void WriteKeepSet(const KeepSet& keep_set, OutputStream* out) {
+  Printer printer(out);
   for (const auto& entry : keep_set.manifest_class_set_) {
     for (const UsageLocation& location : entry.second) {
-      *out << "# Referenced at " << location.source << "\n";
+      printer.Print("# Referenced at ").Println(location.source.to_string());
     }
-    *out << "-keep class " << entry.first << " { <init>(...); }\n" << std::endl;
+    printer.Print("-keep class ").Print(entry.first).Println(" { <init>(...); }");
   }
 
   for (const auto& entry : keep_set.conditional_class_set_) {
@@ -342,26 +347,31 @@
     }
 
     for (const UsageLocation& location : entry.second) {
-      *out << "# Referenced at " << location.source << "\n";
+      printer.Print("# Referenced at ").Println(location.source.to_string());
     }
     if (keep_set.conditional_keep_rules_ && can_be_conditional) {
-      *out << "-if class **.R$layout {\n";
+      printer.Println("-if class **.R$layout {");
+      printer.Indent();
       for (const UsageLocation& location : locations) {
-        auto transformed_name = JavaClassGenerator::TransformToFieldName(location.name.entry);
-        *out << "  int " << transformed_name << ";\n";
+        printer.Print("int ")
+            .Print(JavaClassGenerator::TransformToFieldName(location.name.entry))
+            .Println(";");
       }
-      *out << "}\n";
+      printer.Undent();
+      printer.Println("}");
+      printer.Println();
     }
-    *out << "-keep class " << entry.first << " { <init>(...); }\n" << std::endl;
+    printer.Print("-keep class ").Print(entry.first).Println(" { <init>(...); }");
+    printer.Println();
   }
 
   for (const auto& entry : keep_set.method_set_) {
     for (const UsageLocation& location : entry.second) {
-      *out << "# Referenced at " << location.source << "\n";
+      printer.Print("# Referenced at ").Println(location.source.to_string());
     }
-    *out << "-keepclassmembers class * { *** " << entry.first << "(...); }\n" << std::endl;
+    printer.Print("-keepclassmembers class * { *** ").Print(entry.first).Println("(...); }");
+    printer.Println();
   }
-  return true;
 }
 
 bool CollectLocations(const UsageLocation& location, const KeepSet& keep_set,