Add AIDL Lights HAL to support multiple lights per type

This is a revision of the previous 2.0 HIDL-based light HAL.
It accomplishes 2 goals:
 1) Support more than 1 light for a given type. This allows Assistant to
    use the HAL on TV platforms that have usually 4 indicator lights.
 2) Use AIDL, which is the more modern way of writing HALs.
The previous HAL is in hardware/interfaces/light/2.0 and the new one is
in versioned as aidl, as that supports forward compatibility.

Test: atest VtsHalLightTargetTest
Bug: 142715294, 142230898
Change-Id: I08d831ca0380d8bb187e43f6d5c214810ff72f50
diff --git a/light/utils/Android.bp b/light/utils/Android.bp
index 4c287e4..e901129 100644
--- a/light/utils/Android.bp
+++ b/light/utils/Android.bp
@@ -23,7 +23,11 @@
     shared_libs: [
         "android.hardware.light@2.0",
         "libbase",
+        "libbinder",
         "libhidlbase",
         "libutils",
     ],
+    static_libs: [
+        "android.hardware.light-cpp",
+    ],
 }
diff --git a/light/utils/main.cpp b/light/utils/main.cpp
index b834132..b9b6489 100644
--- a/light/utils/main.cpp
+++ b/light/utils/main.cpp
@@ -19,34 +19,23 @@
 
 #include <android-base/logging.h>
 #include <android/hardware/light/2.0/ILight.h>
+#include <android/hardware/light/ILights.h>
+#include <binder/IServiceManager.h>
+
+using android::sp;
+using android::waitForVintfService;
+using android::binder::Status;
+using android::hardware::hidl_vec;
+
+namespace V2_0 = android::hardware::light::V2_0;
+namespace aidl = android::hardware::light;
 
 void error(const std::string& msg) {
     LOG(ERROR) << msg;
     std::cerr << msg << std::endl;
 }
 
-int main(int argc, char* argv[]) {
-    using ::android::hardware::hidl_vec;
-    using ::android::hardware::light::V2_0::Brightness;
-    using ::android::hardware::light::V2_0::Flash;
-    using ::android::hardware::light::V2_0::ILight;
-    using ::android::hardware::light::V2_0::LightState;
-    using ::android::hardware::light::V2_0::Status;
-    using ::android::hardware::light::V2_0::Type;
-    using ::android::sp;
-
-    sp<ILight> service = ILight::getService();
-    if (service == nullptr) {
-        error("Could not retrieve light service.");
-        return -1;
-    }
-
-    static LightState off = {
-            .color = 0u,
-            .flashMode = Flash::NONE,
-            .brightnessMode = Brightness::USER,
-    };
-
+int parseArgs(int argc, char* argv[], unsigned int* color) {
     if (argc > 2) {
         error("Usage: blank_screen [color]");
         return -1;
@@ -54,25 +43,78 @@
 
     if (argc > 1) {
         char* col_ptr;
-        unsigned int col_new;
 
-        col_new = strtoul(argv[1], &col_ptr, 0);
+        *color = strtoul(argv[1], &col_ptr, 0);
         if (*col_ptr != '\0') {
             error("Failed to convert " + std::string(argv[1]) + " to number");
             return -1;
         }
-        off.color = col_new;
+
+        return 0;
     }
 
-    service->getSupportedTypes([&](const hidl_vec<Type>& types) {
-        for (Type type : types) {
-            Status ret = service->setLight(type, off);
-            if (ret != Status::SUCCESS) {
-                error("Failed to shut off screen for type " +
+    *color = 0u;
+    return 0;
+}
+
+void setToColorAidl(sp<aidl::ILights> hal, unsigned int color) {
+    static aidl::HwLightState off;
+    off.color = color;
+    off.flashMode = aidl::FlashMode::NONE;
+    off.brightnessMode = aidl::BrightnessMode::USER;
+
+    std::vector<aidl::HwLight> lights;
+    Status status = hal->getLights(&lights);
+    if (!status.isOk()) {
+        error("Failed to list lights");
+        return;
+    }
+
+    for (auto light : lights) {
+        Status setStatus = hal->setLightState(light.id, off);
+        if (!setStatus.isOk()) {
+            error("Failed to shut off light id " + std::to_string(light.id));
+        }
+    }
+}
+
+void setToColorHidl(sp<V2_0::ILight> hal, unsigned int color) {
+    static V2_0::LightState off = {
+            .color = color,
+            .flashMode = V2_0::Flash::NONE,
+            .brightnessMode = V2_0::Brightness::USER,
+    };
+
+    hal->getSupportedTypes([&](const hidl_vec<V2_0::Type>& types) {
+        for (auto type : types) {
+            V2_0::Status ret = hal->setLight(type, off);
+            if (ret != V2_0::Status::SUCCESS) {
+                error("Failed to shut off light for type " +
                       std::to_string(static_cast<int>(type)));
             }
         }
     });
+}
 
-    return 0;
+int main(int argc, char* argv[]) {
+    unsigned int inputColor;
+    int result = parseArgs(argc, argv, &inputColor);
+    if (result != 0) {
+        return result;
+    }
+
+    auto aidlHal = waitForVintfService<aidl::ILights>();
+    if (aidlHal != nullptr) {
+        setToColorAidl(aidlHal, inputColor);
+        return 0;
+    }
+
+    sp<V2_0::ILight> hidlHal = V2_0::ILight::getService();
+    if (hidlHal != nullptr) {
+        setToColorHidl(hidlHal, inputColor);
+        return 0;
+    }
+
+    error("Could not retrieve light service.");
+    return -1;
 }