Invoke FileDescriptor#sync after copying each file.
Bug: 32919847
Test: DocumentsUITest
Change-Id: Id16211522e4b9dd7129797c7e43a0ba064ce5591
diff --git a/src/com/android/documentsui/services/CopyJob.java b/src/com/android/documentsui/services/CopyJob.java
index 30bbbf1..1a3d94c 100644
--- a/src/com/android/documentsui/services/CopyJob.java
+++ b/src/com/android/documentsui/services/CopyJob.java
@@ -46,6 +46,9 @@
import android.os.RemoteException;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
import android.text.format.DateUtils;
import android.util.Log;
import android.webkit.MimeTypeMap;
@@ -65,6 +68,7 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.io.SyncFailedException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
@@ -583,6 +587,17 @@
makeCopyProgress(len);
}
+ // Need to invoke Os#fsync to ensure the file is written to the storage device.
+ try {
+ Os.fsync(dstFile.getFileDescriptor());
+ } catch (ErrnoException error) {
+ // fsync will fail with fd of pipes and return EROFS or EINVAL.
+ if (error.errno != OsConstants.EROFS && error.errno != OsConstants.EINVAL) {
+ throw new SyncFailedException(
+ "Failed to sync bytes after copying a file.");
+ }
+ }
+
// Need to invoke IoUtils.close explicitly to avoid from ignoring errors at flush.
IoUtils.close(dstFile.getFileDescriptor());
srcFile.checkError();