Refactor HIDL HAL Dev GC invocation am: 8f0d45441c am: b586527450 am: c4f67a28f3

Original change: https://android-review.googlesource.com/c/platform/system/vold/+/1550387

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I70a8269151232c2faf07b5c06598bad5e7e79108
diff --git a/IdleMaint.cpp b/IdleMaint.cpp
index e4a1806..466cf19 100644
--- a/IdleMaint.cpp
+++ b/IdleMaint.cpp
@@ -22,6 +22,7 @@
 #include "model/PrivateVolume.h"
 
 #include <thread>
+#include <utility>
 
 #include <android-base/chrono_utils.h>
 #include <android-base/file.h>
@@ -48,9 +49,9 @@
 using android::base::WriteStringToFile;
 using android::hardware::Return;
 using android::hardware::Void;
-using android::hardware::health::storage::V1_0::IStorage;
-using android::hardware::health::storage::V1_0::IGarbageCollectCallback;
-using android::hardware::health::storage::V1_0::Result;
+using HStorage = android::hardware::health::storage::V1_0::IStorage;
+using HGarbageCollectCallback = android::hardware::health::storage::V1_0::IGarbageCollectCallback;
+using HResult = android::hardware::health::storage::V1_0::Result;
 
 namespace android {
 namespace vold {
@@ -300,26 +301,33 @@
     return;
 }
 
-class GcCallback : public IGarbageCollectCallback {
-  public:
-    Return<void> onFinish(Result result) override {
+enum class IDL { HIDL };
+std::ostream& operator<<(std::ostream& os, IDL idl) {
+    return os << "HIDL";
+}
+
+template <IDL idl, typename Result>
+class GcCallbackImpl {
+  protected:
+    void onFinishInternal(Result result) {
         std::unique_lock<std::mutex> lock(mMutex);
         mFinished = true;
         mResult = result;
         lock.unlock();
         mCv.notify_all();
-        return Void();
     }
+
+  public:
     void wait(uint64_t seconds) {
         std::unique_lock<std::mutex> lock(mMutex);
         mCv.wait_for(lock, std::chrono::seconds(seconds), [this] { return mFinished; });
 
         if (!mFinished) {
-            LOG(WARNING) << "Dev GC on HAL timeout";
+            LOG(WARNING) << "Dev GC on " << idl << " HAL timeout";
         } else if (mResult != Result::SUCCESS) {
-            LOG(WARNING) << "Dev GC on HAL failed with " << toString(mResult);
+            LOG(WARNING) << "Dev GC on " << idl << " HAL failed with " << toString(mResult);
         } else {
-            LOG(INFO) << "Dev GC on HAL successful";
+            LOG(INFO) << "Dev GC on " << idl << " HAL successful";
         }
     }
 
@@ -330,25 +338,34 @@
     Result mResult{Result::UNKNOWN_ERROR};
 };
 
-static void runDevGcOnHal(sp<IStorage> service) {
-    LOG(DEBUG) << "Start Dev GC on HAL";
-    sp<GcCallback> cb = new GcCallback();
+class HGcCallbackImpl : public HGarbageCollectCallback, public GcCallbackImpl<IDL::HIDL, HResult> {
+    Return<void> onFinish(HResult result) override {
+        onFinishInternal(result);
+        return Void();
+    }
+};
+
+template <IDL idl, typename Service, typename GcCallbackImpl, typename GetDescription>
+static void runDevGcOnHal(Service service, GcCallbackImpl cb, GetDescription get_description) {
+    LOG(DEBUG) << "Start Dev GC on " << idl << " HAL";
     auto ret = service->garbageCollect(DEVGC_TIMEOUT_SEC, cb);
     if (!ret.isOk()) {
-        LOG(WARNING) << "Cannot start Dev GC on HAL: " << ret.description();
+        LOG(WARNING) << "Cannot start Dev GC on " << idl
+                     << " HAL: " << std::invoke(get_description, ret);
         return;
     }
     cb->wait(DEVGC_TIMEOUT_SEC);
 }
 
 static void runDevGc(void) {
-    auto service = IStorage::getService();
-    if (service != nullptr) {
-        runDevGcOnHal(service);
-    } else {
-        // fallback to legacy code path
-        runDevGcFstab();
+    auto hidl_service = HStorage::getService();
+    if (hidl_service != nullptr) {
+        runDevGcOnHal<IDL::HIDL>(hidl_service, sp<HGcCallbackImpl>(new HGcCallbackImpl()),
+                                 &Return<void>::description);
+        return;
     }
+    // fallback to legacy code path
+    runDevGcFstab();
 }
 
 int RunIdleMaint(const android::sp<android::os::IVoldTaskListener>& listener) {