Merge "GUID of a partion can be specified if needed" into main
diff --git a/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java b/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java
index 0efaa18..a2d8ee6 100644
--- a/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/java/framework/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -705,6 +705,7 @@
                                 new File(p.imagePath),
                                 p.writable ? MODE_READ_WRITE : MODE_READ_ONLY);
                 part.writable = p.writable;
+                part.guid = TextUtils.isEmpty(p.guid) ? null : p.guid;
                 partitions.add(part);
             }
             config.disks[i].partitions = partitions.toArray(new Partition[0]);
diff --git a/java/framework/src/android/system/virtualmachine/VirtualMachineCustomImageConfig.java b/java/framework/src/android/system/virtualmachine/VirtualMachineCustomImageConfig.java
index aa22fc2..3f074b5 100644
--- a/java/framework/src/android/system/virtualmachine/VirtualMachineCustomImageConfig.java
+++ b/java/framework/src/android/system/virtualmachine/VirtualMachineCustomImageConfig.java
@@ -35,6 +35,7 @@
     private static final String KEY_PARTITION_LABELS = "partition_labels_";
     private static final String KEY_PARTITION_IMAGES = "partition_images_";
     private static final String KEY_PARTITION_WRITABLES = "partition_writables_";
+    private static final String KEY_PARTITION_GUIDS = "partition_guids_";
     private static final String KEY_DISPLAY_CONFIG = "display_config";
     private static final String KEY_TOUCH = "touch";
     private static final String KEY_KEYBOARD = "keyboard";
@@ -167,9 +168,12 @@
                             customImageConfigBundle.getStringArray(KEY_PARTITION_IMAGES + i);
                     boolean[] partitionWritables =
                             customImageConfigBundle.getBooleanArray(KEY_PARTITION_WRITABLES + i);
+                    String[] guids =
+                            customImageConfigBundle.getStringArray(KEY_PARTITION_GUIDS + i);
                     for (int j = 0; j < labels.length; j++) {
                         disk.addPartition(
-                                new Partition(labels[j], images[j], partitionWritables[j]));
+                                new Partition(
+                                        labels[j], images[j], partitionWritables[j], guids[j]));
                     }
                     builder.addDisk(disk);
                 }
@@ -210,10 +214,12 @@
                 List<String> partitionLabels = new ArrayList<>();
                 List<String> partitionImages = new ArrayList<>();
                 List<Boolean> partitionWritables = new ArrayList<>();
+                List<String> partitionGuids = new ArrayList<>();
                 for (Partition p : disks[i].getPartitions()) {
                     partitionLabels.add(p.name);
                     partitionImages.add(p.imagePath);
                     partitionWritables.add(p.writable);
+                    partitionGuids.add(p.guid == null ? "" : p.guid);
                 }
                 pb.putStringArray(KEY_PARTITION_LABELS + i, partitionLabels.toArray(new String[0]));
                 pb.putStringArray(KEY_PARTITION_IMAGES + i, partitionImages.toArray(new String[0]));
@@ -223,6 +229,7 @@
                     arr[index++] = b;
                 }
                 pb.putBooleanArray(KEY_PARTITION_WRITABLES + i, arr);
+                pb.putStringArray(KEY_PARTITION_GUIDS + i, partitionGuids.toArray(new String[0]));
             }
             pb.putBooleanArray(KEY_DISK_WRITABLES, writables);
             pb.putStringArray(KEY_DISK_IMAGES, images);
@@ -310,11 +317,13 @@
         public final String name;
         public final String imagePath;
         public final boolean writable;
+        public final String guid;
 
-        public Partition(String name, String imagePath, boolean writable) {
+        public Partition(String name, String imagePath, boolean writable, String guid) {
             this.name = name;
             this.imagePath = imagePath;
             this.writable = writable;
+            this.guid = guid;
         }
     }
 
diff --git a/libs/vmconfig/Android.bp b/libs/vmconfig/Android.bp
index 728033c..657e604 100644
--- a/libs/vmconfig/Android.bp
+++ b/libs/vmconfig/Android.bp
@@ -14,6 +14,7 @@
         "libsemver",
         "libserde",
         "libserde_json",
+        "libuuid",
     ],
     apex_available: [
         "com.android.virt",
diff --git a/libs/vmconfig/src/lib.rs b/libs/vmconfig/src/lib.rs
index 1413b51..ff115f3 100644
--- a/libs/vmconfig/src/lib.rs
+++ b/libs/vmconfig/src/lib.rs
@@ -32,6 +32,7 @@
 use std::io::BufReader;
 use std::num::NonZeroU32;
 use std::path::{Path, PathBuf};
+use uuid::Uuid;
 
 /// Configuration for a particular VM to be started.
 #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
@@ -176,6 +177,9 @@
     /// Whether the partition should be writable.
     #[serde(default)]
     pub writable: bool,
+    /// GUID of this partition.
+    #[serde(default)]
+    pub guid: Option<Uuid>,
 }
 
 impl Partition {
@@ -184,6 +188,7 @@
             image: Some(open_parcel_file(&self.path, self.writable)?),
             writable: self.writable,
             label: self.label.to_owned(),
+            guid: None,
         })
     }
 }
diff --git a/service_vm/manager/src/lib.rs b/service_vm/manager/src/lib.rs
index 987325d..78ed85b 100644
--- a/service_vm/manager/src/lib.rs
+++ b/service_vm/manager/src/lib.rs
@@ -220,6 +220,7 @@
         label: "vm-instance".to_owned(),
         image: Some(instance_img),
         writable: true,
+        guid: None,
     }];
     let rialto = File::open(RIALTO_PATH).context("Failed to open Rialto kernel binary")?;
     let instance_id_file = Path::new(VIRT_DATA_DIR).join(INSTANCE_ID_FILENAME);
diff --git a/virtualizationmanager/Android.bp b/virtualizationmanager/Android.bp
index ada66dd..ae85934 100644
--- a/virtualizationmanager/Android.bp
+++ b/virtualizationmanager/Android.bp
@@ -71,6 +71,7 @@
         "liblibfdt",
         "libfsfdt",
         "libhypervisor_props",
+        "libuuid",
         // TODO(b/202115393) stabilize the interface
         "packagemanager_aidl-rust",
     ],
diff --git a/virtualizationmanager/src/composite.rs b/virtualizationmanager/src/composite.rs
index a4b7eae..681ec59 100644
--- a/virtualizationmanager/src/composite.rs
+++ b/virtualizationmanager/src/composite.rs
@@ -23,6 +23,8 @@
 use std::os::unix::io::AsRawFd;
 use std::path::{Path, PathBuf};
 
+use uuid::Uuid;
+
 /// Constructs a composite disk image for the given list of partitions, and opens it ready to use.
 ///
 /// Returns the composite disk image file, and a list of files whose file descriptors must be passed
@@ -105,6 +107,7 @@
                 partition_type: ImagePartitionType::LinuxFilesystem,
                 writable: partition.writable,
                 size,
+                part_guid: partition.guid.as_deref().map(Uuid::parse_str).transpose()?,
             })
         })
         .collect::<Result<_, Error>>()?;
diff --git a/virtualizationmanager/src/payload.rs b/virtualizationmanager/src/payload.rs
index 9d0c7d6..82d9ba0 100644
--- a/virtualizationmanager/src/payload.rs
+++ b/virtualizationmanager/src/payload.rs
@@ -289,6 +289,7 @@
         label: "payload-metadata".to_owned(),
         image: Some(metadata_file),
         writable: false,
+        guid: None,
     }];
 
     for (i, apex_info) in apex_infos.iter().enumerate() {
@@ -297,17 +298,20 @@
             label: format!("microdroid-apex-{}", i),
             image: Some(apex_file),
             writable: false,
+            guid: None,
         });
     }
     partitions.push(Partition {
         label: "microdroid-apk".to_owned(),
         image: Some(ParcelFileDescriptor::new(apk_file)),
         writable: false,
+        guid: None,
     });
     partitions.push(Partition {
         label: "microdroid-apk-idsig".to_owned(),
         image: Some(ParcelFileDescriptor::new(idsig_file)),
         writable: false,
+        guid: None,
     });
 
     // we've already checked that extra_apks and extraIdsigs are in the same size.
@@ -319,6 +323,7 @@
             label: format!("extra-apk-{i}"),
             image: Some(ParcelFileDescriptor::new(extra_apk_file)),
             writable: false,
+            guid: None,
         });
 
         partitions.push(Partition {
@@ -330,6 +335,7 @@
                     .with_context(|| format!("Failed to clone the extra idsig #{i}"))?,
             )),
             writable: false,
+            guid: None,
         });
     }
 
@@ -416,6 +422,7 @@
             label: "microdroid-vendor".to_owned(),
             image: Some(ParcelFileDescriptor::new(vendor_image)),
             writable: false,
+            guid: None,
         }],
     })
 }
@@ -439,6 +446,7 @@
         label: "vm-instance".to_owned(),
         image: Some(ParcelFileDescriptor::new(instance_file)),
         writable: true,
+        guid: None,
     }];
 
     if let Some(file) = storage_image {
@@ -446,6 +454,7 @@
             label: "encryptedstore".to_owned(),
             image: Some(ParcelFileDescriptor::new(file)),
             writable: true,
+            guid: None,
         });
     }
 
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/Partition.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/Partition.aidl
index 825c3da..11a2115 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/Partition.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/Partition.aidl
@@ -25,4 +25,7 @@
 
     /** Whether the partition should be writable by the VM. */
     boolean writable;
+
+    /** GUID of the partition. If not set, automatically created */
+    @nullable String guid;
 }
diff --git a/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java b/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java
index 31591bf..1ab220c 100644
--- a/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java
+++ b/vmlauncher_app/java/com/android/virtualization/vmlauncher/MainActivity.java
@@ -143,9 +143,10 @@
                             String label = partition.getString("label");
                             String path = partition.getString("path");
                             boolean partitionWritable = partition.optBoolean("writable", false);
+                            String guid = partition.optString("guid");
                             VirtualMachineCustomImageConfig.Partition p =
                                     new VirtualMachineCustomImageConfig.Partition(
-                                            label, path, partitionWritable);
+                                            label, path, partitionWritable, guid);
                             disk.addPartition(p);
                         }
                         customImageConfigBuilder.addDisk(disk);