Merge "Check error status after installing each DSU partition"
diff --git a/core/java/android/os/image/DynamicSystemManager.java b/core/java/android/os/image/DynamicSystemManager.java
index 17851ad..7f01cad 100644
--- a/core/java/android/os/image/DynamicSystemManager.java
+++ b/core/java/android/os/image/DynamicSystemManager.java
@@ -155,6 +155,19 @@
         }
     }
     /**
+     * Complete the current partition installation.
+     *
+     * @return true if the partition installation completes without error.
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
+    public boolean closePartition() {
+        try {
+            return mService.closePartition();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e.toString());
+        }
+    }
+    /**
      * Finish a previously started installation. Installations without a cooresponding
      * finishInstallation() will be cleaned up during device boot.
      */
diff --git a/core/java/android/os/image/IDynamicSystemService.aidl b/core/java/android/os/image/IDynamicSystemService.aidl
index a1f9272..df0a69b 100644
--- a/core/java/android/os/image/IDynamicSystemService.aidl
+++ b/core/java/android/os/image/IDynamicSystemService.aidl
@@ -39,6 +39,13 @@
     boolean createPartition(@utf8InCpp String name, long size, boolean readOnly);
 
     /**
+     * Complete the current partition installation.
+     *
+     * @return true if the partition installation completes without error.
+     */
+    boolean closePartition();
+
+    /**
      * Finish a previously started installation. Installations without
      * a cooresponding finishInstallation() will be cleaned up during device boot.
      */
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
index f8952ac..4d31ce9 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java
@@ -334,6 +334,11 @@
             throw new IOException(
                     "Failed to start installation with requested size: " + mUserdataSize);
         }
+        // Reset installation session and verify that installation completes successfully.
+        mInstallationSession = null;
+        if (!mDynSystem.closePartition()) {
+            throw new IOException("Failed to complete partition installation: userdata");
+        }
     }
 
     private void installImages()
@@ -503,6 +508,12 @@
                 imageValidationThrowOrWarning(new KeyRevokedException(publicKey));
             }
         }
+
+        // Reset installation session and verify that installation completes successfully.
+        mInstallationSession = null;
+        if (!mDynSystem.closePartition()) {
+            throw new IOException("Failed to complete partition installation: " + partitionName);
+        }
     }
 
     private static String toHexString(byte[] bytes) {
diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java
index 191a9bc..776f25f 100644
--- a/services/core/java/com/android/server/DynamicSystemService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -126,6 +126,16 @@
     }
 
     @Override
+    public boolean closePartition() throws RemoteException {
+        IGsiService service = getGsiService();
+        if (service.closePartition() != 0) {
+            Slog.i(TAG, "Partition installation completes with error");
+            return false;
+        }
+        return true;
+    }
+
+    @Override
     public boolean finishInstallation() throws RemoteException {
         IGsiService service = getGsiService();
         if (service.closeInstall() != 0) {