Dumping view capture directly to file instead of loading it
all in memory

This avoid OOM when processing large data

Bug: 241600398
Test: Verified on device
Change-Id: I76072d52e47bea3a2f9802ce3b23ddae58fe8d23
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 38b46b0..5ee9aa8 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -3027,7 +3027,10 @@
         writer.println(prefix + "\tmAppWidgetHost.isListening: " + mAppWidgetHost.isListening());
 
         if (mViewCapture != null) {
-            writer.println(prefix + "\tmViewCapture: " + mViewCapture.dumpToString());
+            writer.print(prefix + "\tmViewCapture: ");
+            writer.flush();
+            mViewCapture.dump(fd);
+            writer.println();
         }
 
         // Extra logging for general debugging
diff --git a/src/com/android/launcher3/util/ViewCapture.java b/src/com/android/launcher3/util/ViewCapture.java
index 140971b..cf9ea69 100644
--- a/src/com/android/launcher3/util/ViewCapture.java
+++ b/src/com/android/launcher3/util/ViewCapture.java
@@ -21,6 +21,7 @@
 import android.os.SystemClock;
 import android.os.Trace;
 import android.util.Base64;
+import android.util.Base64OutputStream;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -32,6 +33,9 @@
 import com.android.launcher3.view.ViewCaptureData.FrameData;
 import com.android.launcher3.view.ViewCaptureData.ViewNode;
 
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
 import java.util.concurrent.FutureTask;
 
 /**
@@ -73,7 +77,7 @@
     /**
      * Creates a proto of all the data captured so far.
      */
-    public String dumpToString() {
+    public void dump(FileDescriptor out) {
         Handler handler = mRoot.getHandler();
         if (handler == null) {
             handler = Executors.MAIN_EXECUTOR.getHandler();
@@ -84,12 +88,15 @@
         } else {
             handler.post(task);
         }
-        try {
-            return Base64.encodeToString(task.get().toByteArray(),
+        try (OutputStream os = new FileOutputStream(out)) {
+            ExportedData data = task.get();
+            Base64OutputStream encodedOS = new Base64OutputStream(os,
                     Base64.NO_CLOSE | Base64.NO_PADDING | Base64.NO_WRAP);
+            data.writeTo(encodedOS);
+            encodedOS.close();
+            os.flush();
         } catch (Exception e) {
             Log.e(TAG, "Error capturing proto", e);
-            return "--error--";
         }
     }