Add daily reconciliation

Add a scheduled job, to run once a day while idle & charging, to make
sure we delete any secrets belonging to apps that are no longer
installed.

Bug: 294177871
Test: Manual: add a fake implementation in VS to invoke the callbacks
  Force run the job, see log output
Change-Id: I66e570899ed23f0ef612b552887a3016998bab40
diff --git a/virtualizationservice/aidl/android/system/virtualizationmaintenance/IVirtualizationMaintenance.aidl b/virtualizationservice/aidl/android/system/virtualizationmaintenance/IVirtualizationMaintenance.aidl
index 76d7309..08d61c1 100644
--- a/virtualizationservice/aidl/android/system/virtualizationmaintenance/IVirtualizationMaintenance.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationmaintenance/IVirtualizationMaintenance.aidl
@@ -16,6 +16,8 @@
 
 package android.system.virtualizationmaintenance;
 
+import android.system.virtualizationmaintenance.IVirtualizationReconciliationCallback;
+
 interface IVirtualizationMaintenance {
     /**
      * Notification that an app has been permanently removed, to allow related global state to
@@ -32,5 +34,13 @@
      */
     void userRemoved(int userId);
 
-    // TODO(b/294177871): Something for daily reconciliation
+    /*
+     * Requests virtualization service to perform reconciliation of Secretkeeper secrets.
+     * Secrets belonging to apps or users that no longer exist should be deleted.
+     * The supplied callback allows for querying of existence.
+     * This method should return on successful completion of the reconciliation process.
+     * It should throw an exception if there is any failure, or if any of the callback
+     * functions return {@code ERROR_STOP_REQUESTED}.
+     */
+    void performReconciliation(IVirtualizationReconciliationCallback callback);
 }
diff --git a/virtualizationservice/aidl/android/system/virtualizationmaintenance/IVirtualizationReconciliationCallback.aidl b/virtualizationservice/aidl/android/system/virtualizationmaintenance/IVirtualizationReconciliationCallback.aidl
new file mode 100644
index 0000000..6466aa2
--- /dev/null
+++ b/virtualizationservice/aidl/android/system/virtualizationmaintenance/IVirtualizationReconciliationCallback.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.virtualizationmaintenance;
+
+/*
+ * Callback interface provided when reconciliation is performed to allow verifying whether users
+ * and apps currently exist.
+ */
+interface IVirtualizationReconciliationCallback {
+    /*
+     * Service-specific error code indicating that the job scheduler has requested that we
+     * stop
+     */
+    const int ERROR_STOP_REQUESTED = 1;
+
+    /*
+     * Determine whether users with selected IDs currently exist. The result is an array of booleans
+     * which indicate whether the corresponding entry in the {@code userIds} array is a valid
+     * user ID.
+     */
+    boolean[] doUsersExist(in int[] userIds);
+
+    /*
+     * Determine whether apps with selected app IDs currently exist for a specific user.
+     * The result is an array of booleans which indicate whether the corresponding entry in the
+     * {@code appIds} array is a current app ID for the user.
+     */
+    boolean[] doAppsExist(int userId, in int[] appIds);
+}
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index c0024f1..bbfb220 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -51,7 +51,10 @@
 use std::sync::{Arc, Mutex, Weak};
 use tombstoned_client::{DebuggerdDumpType, TombstonedConnection};
 use virtualizationcommon::Certificate::Certificate;
-use virtualizationmaintenance::IVirtualizationMaintenance::IVirtualizationMaintenance;
+use virtualizationmaintenance::{
+    IVirtualizationMaintenance::IVirtualizationMaintenance,
+    IVirtualizationReconciliationCallback::IVirtualizationReconciliationCallback,
+};
 use virtualizationservice::{
     AssignableDevice::AssignableDevice, VirtualMachineDebugInfo::VirtualMachineDebugInfo,
 };
@@ -427,6 +430,14 @@
         }
         Ok(())
     }
+
+    fn performReconciliation(
+        &self,
+        _callback: &Strong<dyn IVirtualizationReconciliationCallback>,
+    ) -> binder::Result<()> {
+        Err(anyhow!("performReconciliation not supported"))
+            .or_binder_exception(ExceptionCode::UNSUPPORTED_OPERATION)
+    }
 }
 
 // KEEP IN SYNC WITH assignable_devices.xsd