Deflake service tests.

Wait on write finish before proceeding.

Test: Medium tests pass.

Bug: 35796537
Change-Id: I0c3542dd83fe3115f2e4065f8ccdf758e8399fe4
diff --git a/tests/common/com/android/documentsui/DocumentsProviderHelper.java b/tests/common/com/android/documentsui/DocumentsProviderHelper.java
index cfed56a..cac4f45 100644
--- a/tests/common/com/android/documentsui/DocumentsProviderHelper.java
+++ b/tests/common/com/android/documentsui/DocumentsProviderHelper.java
@@ -141,6 +141,7 @@
         try (AutoCloseOutputStream out = new AutoCloseOutputStream(file)) {
             out.write(contents, 0, contents.length);
         }
+        mClient.call("waitForWrite", null, null);
     }
 
     public byte[] readDocument(Uri documentUri) throws RemoteException, IOException {
diff --git a/tests/common/com/android/documentsui/StubProvider.java b/tests/common/com/android/documentsui/StubProvider.java
index 62e6659..9b6dbd4 100644
--- a/tests/common/com/android/documentsui/StubProvider.java
+++ b/tests/common/com/android/documentsui/StubProvider.java
@@ -51,6 +51,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.CountDownLatch;
 
 public class StubProvider extends DocumentsProvider {
 
@@ -428,49 +429,46 @@
         final ParcelFileDescriptor readPipe = pipe[0];
         final ParcelFileDescriptor writePipe = pipe[1];
 
-        new Thread() {
-            @Override
-            public void run() {
-                InputStream inputStream = null;
-                OutputStream outputStream = null;
-                try {
-                    Log.d(TAG, "Opening write stream on file " + document.documentId);
-                    inputStream = new ParcelFileDescriptor.AutoCloseInputStream(readPipe);
-                    outputStream = new FileOutputStream(document.file);
-                    byte[] buffer = new byte[32 * 1024];
-                    int bytesToRead;
-                    int bytesRead = 0;
-                    while (bytesRead != -1) {
-                        synchronized (mWriteLock) {
-                            // This cast is safe because the max possible value is buffer.length.
-                            bytesToRead = (int) Math.min(document.rootInfo.getRemainingCapacity(),
-                                    buffer.length);
-                            if (bytesToRead == 0) {
-                                closePipeWithErrorSilently(readPipe, "Not enough space.");
-                                break;
-                            }
-                            bytesRead = inputStream.read(buffer, 0, bytesToRead);
-                            if (bytesRead == -1) {
-                                break;
-                            }
-                            outputStream.write(buffer, 0, bytesRead);
-                            document.rootInfo.size += bytesRead;
+        postToMainThread(() -> {
+            InputStream inputStream = null;
+            OutputStream outputStream = null;
+            try {
+                Log.d(TAG, "Opening write stream on file " + document.documentId);
+                inputStream = new ParcelFileDescriptor.AutoCloseInputStream(readPipe);
+                outputStream = new FileOutputStream(document.file);
+                byte[] buffer = new byte[32 * 1024];
+                int bytesToRead;
+                int bytesRead = 0;
+                while (bytesRead != -1) {
+                    synchronized (mWriteLock) {
+                        // This cast is safe because the max possible value is buffer.length.
+                        bytesToRead = (int) Math.min(document.rootInfo.getRemainingCapacity(),
+                                buffer.length);
+                        if (bytesToRead == 0) {
+                            closePipeWithErrorSilently(readPipe, "Not enough space.");
+                            break;
                         }
+                        bytesRead = inputStream.read(buffer, 0, bytesToRead);
+                        if (bytesRead == -1) {
+                            break;
+                        }
+                        outputStream.write(buffer, 0, bytesRead);
+                        document.rootInfo.size += bytesRead;
                     }
-                } catch (IOException e) {
-                    Log.e(TAG, "Error on close", e);
-                    closePipeWithErrorSilently(readPipe, e.getMessage());
-                } finally {
-                    IoUtils.closeQuietly(inputStream);
-                    IoUtils.closeQuietly(outputStream);
-                    Log.d(TAG, "Closing write stream on file " + document.documentId);
-                    notifyParentChanged(document.parentId);
-                    getContext().getContentResolver().notifyChange(
-                            DocumentsContract.buildDocumentUri(mAuthority, document.documentId),
-                            null, false);
                 }
+            } catch (IOException e) {
+                Log.e(TAG, "Error on close", e);
+                closePipeWithErrorSilently(readPipe, e.getMessage());
+            } finally {
+                IoUtils.closeQuietly(inputStream);
+                IoUtils.closeQuietly(outputStream);
+                Log.d(TAG, "Closing write stream on file " + document.documentId);
+                notifyParentChanged(document.parentId);
+                getContext().getContentResolver().notifyChange(
+                        DocumentsContract.buildDocumentUri(mAuthority, document.documentId),
+                        null, false);
             }
-        }.start();
+        });
 
         return writePipe;
     }
@@ -509,6 +507,9 @@
             case "setLoadingDuration":
                 mLoadingDuration = extras.getLong(DocumentsContract.EXTRA_LOADING);
                 return null;
+            case "waitForWrite":
+                waitForWrite();
+                return null;
         }
 
         return null;
@@ -553,6 +554,22 @@
         return out;
     }
 
+    private void waitForWrite() {
+        try {
+            CountDownLatch latch = new CountDownLatch(1);
+            postToMainThread(latch::countDown);
+            latch.await();
+            Log.d(TAG, "All writing is done.");
+        } catch (InterruptedException e) {
+            // should never happen
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void postToMainThread(Runnable r) {
+        new Handler(Looper.getMainLooper()).post(r);
+    }
+
     public String createDocument(String parentId, String mimeType, String displayName, int flags,
             List<String> streamTypes) throws FileNotFoundException {