aidl: health: Initial AIDL implementation

* Granted correct permissions on fb0 by default
* Enabled suspend according to
  https://android.googlesource.com/platform/hardware/interfaces/+/refs/tags/android-13.0.0_r3/health/aidl#charger-enable-suspend

Change-Id: I41b84840a03a57d46beb1a7520182de2bb29d2f5
diff --git a/aidl/health/Android.bp b/aidl/health/Android.bp
new file mode 100644
index 0000000..19265d3
--- /dev/null
+++ b/aidl/health/Android.bp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The LineageOS 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.
+ */
+
+cc_defaults {
+    name: "android.hardware.health-service.samsung-defaults",
+    defaults: [
+        "libhealth_aidl_impl_user",
+        "libhealth_aidl_charger_defaults",
+    ],
+    relative_install_path: "hw",
+    vintf_fragments: ["android.hardware.health-service.samsung.xml"],
+    srcs: [
+        "Health.cpp",
+    ],
+    static_libs: [
+        "libhealth_aidl_impl",
+    ],
+}
+
+cc_binary {
+    name: "android.hardware.health-service.samsung",
+    defaults: ["android.hardware.health-service.samsung-defaults"],
+    vendor: true,
+    init_rc: ["android.hardware.health-service.samsung.rc"],
+    overrides: ["charger"],
+}
+
+cc_binary {
+    name: "android.hardware.health-service.samsung-recovery",
+    defaults: ["android.hardware.health-service.samsung-defaults"],
+    recovery: true,
+    init_rc: ["android.hardware.health-service.samsung-recovery.rc"],
+    overrides: ["charger.recovery"],
+}
diff --git a/aidl/health/Health.cpp b/aidl/health/Health.cpp
new file mode 100644
index 0000000..39d03bf
--- /dev/null
+++ b/aidl/health/Health.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2022 The LineageOS 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.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <health-impl/Health.h>
+#include <health/utils.h>
+
+#ifndef CHARGER_FORCE_NO_UI
+#define CHARGER_FORCE_NO_UI 0
+#endif
+
+#if !CHARGER_FORCE_NO_UI
+#include <health-impl/ChargerUtils.h>
+#endif
+
+using aidl::android::hardware::health::HalHealthLoop;
+using aidl::android::hardware::health::Health;
+
+#if !CHARGER_FORCE_NO_UI
+using aidl::android::hardware::health::charger::ChargerCallback;
+using aidl::android::hardware::health::charger::ChargerModeMain;
+#endif
+
+static constexpr const char* gInstanceName = "default";
+static constexpr std::string_view gChargerArg{"--charger"};
+
+#if !CHARGER_FORCE_NO_UI
+namespace aidl::android::hardware::health {
+class ChargerCallbackImpl : public ChargerCallback {
+public:
+    using ChargerCallback::ChargerCallback;
+    bool ChargerEnableSuspend() override { return true; }
+};
+} // namespace aidl::android::hardware::health
+#endif
+
+int main(int argc, char** argv) {
+#ifdef __ANDROID_RECOVERY__
+    android::base::InitLogging(argv, android::base::KernelLogger);
+#endif
+
+    // make a default health service
+    auto config = std::make_unique<healthd_config>();
+    ::android::hardware::health::InitHealthdConfig(config.get());
+    auto binder = ndk::SharedRefBase::make<Health>(gInstanceName, std::move(config));
+
+    if (argc >= 2 && argv[1] == gChargerArg) {
+#if !CHARGER_FORCE_NO_UI
+        // If charger shouldn't have UI for your device, simply drop the line below
+        // for your service implementation. This corresponds to
+        // ro.charger.no_ui=true
+        return ChargerModeMain(binder, std::make_shared<aidl::android::hardware::health::ChargerCallbackImpl>(binder));
+#endif
+
+        LOG(INFO) << "Starting charger mode without UI.";
+    } else {
+        LOG(INFO) << "Starting health HAL.";
+    }
+
+    auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, binder);
+    return hal_health_loop->StartLoop();
+}
diff --git a/aidl/health/android.hardware.health-service.samsung-recovery.rc b/aidl/health/android.hardware.health-service.samsung-recovery.rc
new file mode 100644
index 0000000..59aa97c
--- /dev/null
+++ b/aidl/health/android.hardware.health-service.samsung-recovery.rc
@@ -0,0 +1,7 @@
+service vendor.health-samsung /system/bin/hw/android.hardware.health-service.samsung-recovery
+    class hal
+    seclabel u:r:hal_health_default:s0
+    user system
+    group system
+    capabilities WAKE_ALARM BLOCK_SUSPEND
+    file /dev/kmsg w
diff --git a/aidl/health/android.hardware.health-service.samsung.rc b/aidl/health/android.hardware.health-service.samsung.rc
new file mode 100644
index 0000000..5d08aae
--- /dev/null
+++ b/aidl/health/android.hardware.health-service.samsung.rc
@@ -0,0 +1,20 @@
+service vendor.health-samsung /vendor/bin/hw/android.hardware.health-service.samsung
+    class hal
+    user system
+    group system
+    capabilities WAKE_ALARM BLOCK_SUSPEND
+    file /dev/kmsg w
+
+service vendor.charger /vendor/bin/hw/android.hardware.health-service.samsung --charger
+    class charger
+    seclabel u:r:charger_vendor:s0
+    user system
+    group system wakelock input
+    capabilities SYS_BOOT
+    file /dev/kmsg w
+    file /sys/fs/pstore/console-ramoops-0 r
+    file /sys/fs/pstore/console-ramoops r
+    file /proc/last_kmsg r
+
+on charger
+    chown system system /dev/graphics/fb0
diff --git a/aidl/health/android.hardware.health-service.samsung.xml b/aidl/health/android.hardware.health-service.samsung.xml
new file mode 100644
index 0000000..98026cb
--- /dev/null
+++ b/aidl/health/android.hardware.health-service.samsung.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.health</name>
+        <version>1</version>
+        <fqname>IHealth/default</fqname>
+    </hal>
+</manifest>