Control buffer size via server flags when writing to pipes in Full Backup flow.

Reasoning behind making buffer size configurable -
- In PerformFullTransportBackupTask (PFTBT) ->
    * PFTBT calls Transport#sendBackupData() everytime it writes buffer to the write end of the pipe (which is then read by the transport). That method is invoked through binder, which introduces some overhead. Current buffer size of 8KB means that for 25MB of backup data, PFTBT does a minimum of 3200 binder calls. Increasing the buffer size to 64KB, the number of binder call reduces to 400.
- In FullBackupUtils ->
    * FullBackupUtils#routeSocketDataToOutput() routes the data from BackupAgent to FullBackupEngine. Linux pipe2 implementation of Android has default size of 64KB. Increasing the buffer size in FullBackupUtils from 32KB to 64KB will result in optimal performance for piping the data, as buffer size will match input pipe's buffer.

Bug: b/265976737
Test: atest BackupAndRestoreFeatureFlagsTest
    - Manual testing for the performance impact
Change-Id: I729e0a5857e254eb9451eecf6fd9e58ac0511eb8
diff --git a/services/backup/java/com/android/server/backup/BackupAndRestoreFeatureFlags.java b/services/backup/java/com/android/server/backup/BackupAndRestoreFeatureFlags.java
index 042bcbd..1990fe2 100644
--- a/services/backup/java/com/android/server/backup/BackupAndRestoreFeatureFlags.java
+++ b/services/backup/java/com/android/server/backup/BackupAndRestoreFeatureFlags.java
@@ -52,4 +52,29 @@
                 /* name= */ "backup_transport_callback_timeout_millis",
                 /* defaultValue= */ 300000); // 5 minutes
     }
+
+    /**
+     * Retrieves the value of the flag "full_backup_write_to_transport_buffer_size_bytes".
+     * The returned value is max size of a chunk of backup data that is sent to the transport.
+     */
+    @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
+    public static int getFullBackupWriteToTransportBufferSizeBytes() {
+        return DeviceConfig.getInt(
+                NAMESPACE,
+                /* name= */ "full_backup_write_to_transport_buffer_size_bytes",
+                /* defaultValue= */ 8 * 1024); // 8 KB
+    }
+
+    /**
+     * Retrieves the value of the flag "full_backup_utils_route_buffer_size_bytes".
+     * The returned value is max size of a chunk of backup data that routed from write end of
+     * pipe from BackupAgent, to read end of pipe to Full Backup Task (PFTBT).
+     */
+    @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
+    public static int getFullBackupUtilsRouteBufferSizeBytes() {
+        return DeviceConfig.getInt(
+                NAMESPACE,
+                /* name= */ "full_backup_utils_route_buffer_size_bytes",
+                /* defaultValue= */ 32 * 1024); // 32 KB
+    }
 }
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
index 78df304..162046a 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -40,6 +40,7 @@
 
 import com.android.server.EventLogTags;
 import com.android.server.backup.BackupAgentTimeoutParameters;
+import com.android.server.backup.BackupAndRestoreFeatureFlags;
 import com.android.server.backup.BackupRestoreTask;
 import com.android.server.backup.FullBackupJob;
 import com.android.server.backup.OperationStorage;
@@ -142,7 +143,6 @@
     }
 
     private static final String TAG = "PFTBT";
-
     private UserBackupManagerService mUserBackupManagerService;
     private final Object mCancelLock = new Object();
 
@@ -388,7 +388,9 @@
 
             // Set up to send data to the transport
             final int N = mPackages.size();
-            final byte[] buffer = new byte[8192];
+            final int chunkSizeInBytes =
+                    BackupAndRestoreFeatureFlags.getFullBackupWriteToTransportBufferSizeBytes();
+            final byte[] buffer = new byte[chunkSizeInBytes];
             for (int i = 0; i < N; i++) {
                 mBackupRunner = null;
                 PackageInfo currentPackage = mPackages.get(i);
diff --git a/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java b/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
index dbe3cd9..1c0cd87 100644
--- a/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/FullBackupUtils.java
@@ -21,6 +21,8 @@
 import android.os.ParcelFileDescriptor;
 import android.util.Slog;
 
+import com.android.server.backup.BackupAndRestoreFeatureFlags;
+
 import java.io.DataInputStream;
 import java.io.EOFException;
 import java.io.FileInputStream;
@@ -31,8 +33,9 @@
  * Low-level utility methods for full backup.
  */
 public class FullBackupUtils {
+
     /**
-     * Reads data from pipe and writes it to the stream in chunks of up to 32KB.
+     * Reads data from pipe and writes it to the stream.
      *
      * @param inPipe - pipe to read the data from.
      * @param out - stream to write the data to.
@@ -43,8 +46,9 @@
         // We do not take close() responsibility for the pipe FD
         FileInputStream raw = new FileInputStream(inPipe.getFileDescriptor());
         DataInputStream in = new DataInputStream(raw);
-
-        byte[] buffer = new byte[32 * 1024];
+        final int chunkSizeInBytes =
+                BackupAndRestoreFeatureFlags.getFullBackupUtilsRouteBufferSizeBytes();
+        byte[] buffer = new byte[chunkSizeInBytes];
         int chunkTotal;
         while ((chunkTotal = in.readInt()) > 0) {
             while (chunkTotal > 0) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/BackupAndRestoreFeatureFlagsTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/BackupAndRestoreFeatureFlagsTest.java
index f535997..201da35 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/BackupAndRestoreFeatureFlagsTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/BackupAndRestoreFeatureFlagsTest.java
@@ -46,8 +46,9 @@
 
     @Test
     public void getBackupTransportFutureTimeoutMillis_set_returnsSetValue() {
-        DeviceConfig.setProperty("backup_and_restore", "backup_transport_future_timeout_millis",
-                "1234", false);
+        DeviceConfig.setProperty(/*namespace=*/ "backup_and_restore",
+                /*name=*/ "backup_transport_future_timeout_millis",
+                /*value=*/ "1234", /*makeDefault=*/ false);
 
         assertThat(
                 BackupAndRestoreFeatureFlags.getBackupTransportFutureTimeoutMillis()).isEqualTo(
@@ -63,11 +64,44 @@
 
     @Test
     public void getBackupTransportCallbackTimeoutMillis_set_returnsSetValue() {
-        DeviceConfig.setProperty("backup_and_restore", "backup_transport_callback_timeout_millis",
-                "5678", false);
+        DeviceConfig.setProperty(/*namespace=*/ "backup_and_restore",
+                /*name=*/ "backup_transport_callback_timeout_millis",
+                /*value=*/ "5678", /*makeDefault=*/ false);
 
         assertThat(
                 BackupAndRestoreFeatureFlags.getBackupTransportCallbackTimeoutMillis()).isEqualTo(
                 5678);
     }
+
+    @Test
+    public void getFullBackupWriteToTransportBufferSizeBytes_notSet_returnsDefault() {
+        assertThat(BackupAndRestoreFeatureFlags.getFullBackupWriteToTransportBufferSizeBytes())
+                .isEqualTo(8 * 1024);
+    }
+
+    @Test
+    public void getFullBackupWriteToTransportBufferSizeBytes_set_returnsSetValue() {
+        DeviceConfig.setProperty(/*namespace=*/ "backup_and_restore",
+                /*name=*/ "full_backup_write_to_transport_buffer_size_bytes",
+                /*value=*/ "5678", /*makeDefault=*/ false);
+
+        assertThat(BackupAndRestoreFeatureFlags.getFullBackupWriteToTransportBufferSizeBytes())
+                .isEqualTo(5678);
+    }
+
+    @Test
+    public void getFullBackupUtilsRouteBufferSizeBytes_notSet_returnsDefault() {
+        assertThat(BackupAndRestoreFeatureFlags.getFullBackupUtilsRouteBufferSizeBytes())
+                .isEqualTo(32 * 1024);
+    }
+
+    @Test
+    public void getFullBackupUtilsRouteBufferSizeBytes_set_returnsSetValue() {
+        DeviceConfig.setProperty(/*namespace=*/ "backup_and_restore",
+                /*name=*/ "full_backup_utils_route_buffer_size_bytes",
+                /*value=*/ "5678", /*makeDefault=*/ false);
+
+        assertThat(BackupAndRestoreFeatureFlags.getFullBackupUtilsRouteBufferSizeBytes())
+                .isEqualTo(5678);
+    }
 }