Tweaks for superseded blob processing

- Add an explicit type instead of a 3-tuple to improve clarity.
- Add additional watchpoints for processing stages.

Test: TreeHugger
Bug: 319563050
Change-Id: Ifd4130c4576c290bd0b78b50b6ce158e85bb2956
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index ffc80c9..a9a1c4b 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -46,7 +46,7 @@
 mod versioning;
 
 use crate::gc::Gc;
-use crate::impl_metadata; // This is in db_utils.rs
+use crate::impl_metadata; // This is in database/utils.rs
 use crate::key_parameter::{KeyParameter, KeyParameterValue, Tag};
 use crate::ks_err;
 use crate::permission::KeyPermSet;
@@ -856,6 +856,18 @@
     }
 }
 
+/// Information about a superseded blob (a blob that is no longer the
+/// most recent blob of that type for a given key, due to upgrade or
+/// replacement).
+pub struct SupersededBlob {
+    /// ID
+    pub blob_id: i64,
+    /// Contents.
+    pub blob: Vec<u8>,
+    /// Metadata.
+    pub metadata: BlobMetaData,
+}
+
 impl KeystoreDB {
     const UNASSIGNED_KEY_ID: i64 = -1i64;
     const CURRENT_DB_VERSION: u32 = 1;
@@ -1167,7 +1179,7 @@
         &mut self,
         blob_ids_to_delete: &[i64],
         max_blobs: usize,
-    ) -> Result<Vec<(i64, Vec<u8>, BlobMetaData)>> {
+    ) -> Result<Vec<SupersededBlob>> {
         let _wp = wd::watch("KeystoreDB::handle_next_superseded_blob");
         self.with_transaction(Immediate("TX_handle_next_superseded_blob"), |tx| {
             // Delete the given blobs.
@@ -1183,8 +1195,9 @@
 
             Self::cleanup_unreferenced(tx).context("Trying to cleanup unreferenced.")?;
 
-            // Find up to max_blobx more superseded key blobs, load their metadata and return it.
+            // Find up to `max_blobs` more superseded key blobs, load their metadata and return it.
             let result: Vec<(i64, Vec<u8>)> = {
+                let _wp = wd::watch("handle_next_superseded_blob find_next");
                 let mut stmt = tx
                     .prepare(
                         "SELECT id, blob FROM persistent.blobentry
@@ -1215,12 +1228,17 @@
                     .context("Trying to extract superseded blobs.")?
             };
 
+            let _wp = wd::watch("handle_next_superseded_blob load_metadata");
             let result = result
                 .into_iter()
                 .map(|(blob_id, blob)| {
-                    Ok((blob_id, blob, BlobMetaData::load_from_db(blob_id, tx)?))
+                    Ok(SupersededBlob {
+                        blob_id,
+                        blob,
+                        metadata: BlobMetaData::load_from_db(blob_id, tx)?,
+                    })
                 })
-                .collect::<Result<Vec<(i64, Vec<u8>, BlobMetaData)>>>()
+                .collect::<Result<Vec<_>>>()
                 .context("Trying to load blob metadata.")?;
             if !result.is_empty() {
                 return Ok(result).no_gc();
@@ -1228,6 +1246,7 @@
 
             // We did not find any superseded key blob, so let's remove other superseded blob in
             // one transaction.
+            let _wp = wd::watch("handle_next_superseded_blob delete");
             tx.execute(
                 "DELETE FROM persistent.blobentry
                  WHERE NOT subcomponent_type = ?
diff --git a/keystore2/src/gc.rs b/keystore2/src/gc.rs
index a033356..f2341e3 100644
--- a/keystore2/src/gc.rs
+++ b/keystore2/src/gc.rs
@@ -21,7 +21,7 @@
 use crate::ks_err;
 use crate::{
     async_task,
-    database::{BlobMetaData, KeystoreDB, Uuid},
+    database::{KeystoreDB, SupersededBlob, Uuid},
     super_key::SuperKeyManager,
 };
 use anyhow::{Context, Result};
@@ -84,7 +84,7 @@
 
 struct GcInternal {
     deleted_blob_ids: Vec<i64>,
-    superseded_blobs: Vec<(i64, Vec<u8>, BlobMetaData)>,
+    superseded_blobs: Vec<SupersededBlob>,
     invalidate_key: Box<dyn Fn(&Uuid, &[u8]) -> Result<()> + Send + 'static>,
     db: KeystoreDB,
     async_task: std::sync::Weak<AsyncTask>,
@@ -109,7 +109,7 @@
             self.superseded_blobs = blobs;
         }
 
-        if let Some((blob_id, blob, blob_metadata)) = self.superseded_blobs.pop() {
+        if let Some(SupersededBlob { blob_id, blob, metadata }) = self.superseded_blobs.pop() {
             // Add the next blob_id to the deleted blob ids list. So it will be
             // removed from the database regardless of whether the following
             // succeeds or not.
@@ -119,12 +119,12 @@
             // and delete the key, unwrapping if necessary and possible.
             // (At this time keys may get deleted without having the super encryption
             // key in this case we can only delete the key from the database.)
-            if let Some(uuid) = blob_metadata.km_uuid() {
+            if let Some(uuid) = metadata.km_uuid() {
                 let blob = self
                     .super_key
                     .read()
                     .unwrap()
-                    .unwrap_key_if_required(&blob_metadata, &blob)
+                    .unwrap_key_if_required(&metadata, &blob)
                     .context(ks_err!("Trying to unwrap to-be-deleted blob.",))?;
                 (self.invalidate_key)(uuid, &blob).context(ks_err!("Trying to invalidate key."))?;
             }