Better error messages

Extract idsig creation to its own method. Give more specific error
messages on missing APK or idsig failure.

Bug: 266395810
Test: atest MicrodroidTests
Change-Id: I2408ec1d3475e9a8475d9b9b4942b0b98f0524e2
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachine.java b/javalib/src/android/system/virtualmachine/VirtualMachine.java
index 8cebc3c..e66cf29 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachine.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachine.java
@@ -769,7 +769,7 @@
                 }
             } catch (IOException e) {
                 // If the file already exists, exception is not thrown.
-                throw new VirtualMachineException("failed to create idsig file", e);
+                throw new VirtualMachineException("Failed to create APK signature file", e);
             }
 
             IVirtualizationService service = mVirtualizationService.connect();
@@ -782,30 +782,12 @@
                 VirtualMachineAppConfig appConfig = getConfig().toVsConfig();
                 appConfig.name = mName;
 
-                // Fill the idsig file by hashing the apk
-                service.createOrUpdateIdsigFile(
-                        appConfig.apk, ParcelFileDescriptor.open(mIdsigFilePath, MODE_READ_WRITE));
-
-                for (ExtraApkSpec extraApk : mExtraApks) {
-                    service.createOrUpdateIdsigFile(
-                            ParcelFileDescriptor.open(extraApk.apk, MODE_READ_ONLY),
-                            ParcelFileDescriptor.open(extraApk.idsig, MODE_READ_WRITE));
+                try {
+                    createIdSigs(service, appConfig);
+                } catch (FileNotFoundException e) {
+                    throw new VirtualMachineException("Failed to generate APK signature", e);
                 }
 
-                // Re-open idsig file in read-only mode
-                appConfig.idsig = ParcelFileDescriptor.open(mIdsigFilePath, MODE_READ_ONLY);
-                appConfig.instanceImage =
-                        ParcelFileDescriptor.open(mInstanceFilePath, MODE_READ_WRITE);
-                if (mEncryptedStoreFilePath != null) {
-                    appConfig.encryptedStorageImage =
-                            ParcelFileDescriptor.open(mEncryptedStoreFilePath, MODE_READ_WRITE);
-                }
-                List<ParcelFileDescriptor> extraIdsigs = new ArrayList<>();
-                for (ExtraApkSpec extraApk : mExtraApks) {
-                    extraIdsigs.add(ParcelFileDescriptor.open(extraApk.idsig, MODE_READ_ONLY));
-                }
-                appConfig.extraIdsigs = extraIdsigs;
-
                 android.system.virtualizationservice.VirtualMachineConfig vmConfigParcel =
                         android.system.virtualizationservice.VirtualMachineConfig.appConfig(
                                 appConfig);
@@ -814,7 +796,7 @@
                 mVirtualMachine.registerCallback(new CallbackTranslator(service));
                 mContext.registerComponentCallbacks(mMemoryManagementCallbacks);
                 mVirtualMachine.start();
-            } catch (IOException | IllegalStateException | ServiceSpecificException e) {
+            } catch (IllegalStateException | ServiceSpecificException e) {
                 throw new VirtualMachineException(e);
             } catch (RemoteException e) {
                 throw e.rethrowAsRuntimeException();
@@ -822,6 +804,32 @@
         }
     }
 
+    private void createIdSigs(IVirtualizationService service, VirtualMachineAppConfig appConfig)
+            throws RemoteException, FileNotFoundException {
+        // Fill the idsig file by hashing the apk
+        service.createOrUpdateIdsigFile(
+                appConfig.apk, ParcelFileDescriptor.open(mIdsigFilePath, MODE_READ_WRITE));
+
+        for (ExtraApkSpec extraApk : mExtraApks) {
+            service.createOrUpdateIdsigFile(
+                    ParcelFileDescriptor.open(extraApk.apk, MODE_READ_ONLY),
+                    ParcelFileDescriptor.open(extraApk.idsig, MODE_READ_WRITE));
+        }
+
+        // Re-open idsig files in read-only mode
+        appConfig.idsig = ParcelFileDescriptor.open(mIdsigFilePath, MODE_READ_ONLY);
+        appConfig.instanceImage = ParcelFileDescriptor.open(mInstanceFilePath, MODE_READ_WRITE);
+        if (mEncryptedStoreFilePath != null) {
+            appConfig.encryptedStorageImage =
+                    ParcelFileDescriptor.open(mEncryptedStoreFilePath, MODE_READ_WRITE);
+        }
+        List<ParcelFileDescriptor> extraIdsigs = new ArrayList<>();
+        for (ExtraApkSpec extraApk : mExtraApks) {
+            extraIdsigs.add(ParcelFileDescriptor.open(extraApk.idsig, MODE_READ_ONLY));
+        }
+        appConfig.extraIdsigs = extraIdsigs;
+    }
+
     @GuardedBy("mLock")
     private void createVmPipes() throws VirtualMachineException {
         try {
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
index f5c3cd2..1fd49c8 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -393,9 +393,14 @@
      * app-owned files and that could be abused to run a VM with software that the calling
      * application doesn't own.
      */
-    VirtualMachineAppConfig toVsConfig() throws FileNotFoundException {
+    VirtualMachineAppConfig toVsConfig() throws VirtualMachineException {
         VirtualMachineAppConfig vsConfig = new VirtualMachineAppConfig();
-        vsConfig.apk = ParcelFileDescriptor.open(new File(mApkPath), MODE_READ_ONLY);
+
+        try {
+            vsConfig.apk = ParcelFileDescriptor.open(new File(mApkPath), MODE_READ_ONLY);
+        } catch (FileNotFoundException e) {
+            throw new VirtualMachineException("Failed to open APK", e);
+        }
         if (mPayloadBinaryName != null) {
             VirtualMachinePayloadConfig payloadConfig = new VirtualMachinePayloadConfig();
             payloadConfig.payloadBinaryName = mPayloadBinaryName;