Implement health AIDL HAL.

Test: VTS
Test: manual charger mode
Test: recovery
Bug: 213273090

Change-Id: Ie02d7bc1e1c6e39bbab22f008b7767c5de620a73
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 12538be..8639586 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -83,3 +83,9 @@
 $(call add-clean-step, rm -f $(PRODUCT_OUT)/vendor/etc/init/android.hardware.keymaster@4.0-service.trusty.rc)
 $(call add-clean-step, rm -f $(PRODUCT_OUT)/vendor/etc/vintf/manifest/android.hardware.keymaster@4.0-service.trusty.xml)
 $(call add-clean-step, rm -f $(PRODUCT_OUT)/vendor/bin/hw/wait_for_strongbox)
+
+# Health HAL to AIDL
+$(call add-clean-step, find $(PRODUCT_OUT)/system -type f -name "*charger*" -print0 | xargs -0 rm -f)
+$(call add-clean-step, find $(PRODUCT_OUT)/vendor -type f -name "*health@*" -print0 | xargs -0 rm -f)
+$(call add-clean-step, find $(PRODUCT_OUT)/recovery/root -type f -name "*charger*" -print0 | xargs -0 rm -f)
+$(call add-clean-step, find $(PRODUCT_OUT)/recovery/root -type f -name "*health@*" -print0 | xargs -0 rm -f)
diff --git a/conf/init.gs101.rc b/conf/init.gs101.rc
index b90718d..8724044 100644
--- a/conf/init.gs101.rc
+++ b/conf/init.gs101.rc
@@ -3,17 +3,6 @@
 import init.exynos.sensorhub.rc
 import /vendor/etc/init/hw/init.aoc.rc
 
-service vendor.charger /system/bin/charger
-    class charger
-    seclabel u:r:charger: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 early-init
     mount_all /vendor/etc/fstab.persist --early
 
diff --git a/device.mk b/device.mk
index b71b960..ff5d0bd 100644
--- a/device.mk
+++ b/device.mk
@@ -925,8 +925,8 @@
 	$(NULL)
 
 PRODUCT_PACKAGES += \
-	android.hardware.health@2.1-impl-gs101 \
-	android.hardware.health@2.1-service
+	android.hardware.health-service.gs101 \
+	android.hardware.health-service.gs101_recovery \
 
 # Audio
 # Audio HAL Server & Default Implementations
diff --git a/health/Android.bp b/health/Android.bp
index 41a0e12..2bac61b 100644
--- a/health/Android.bp
+++ b/health/Android.bp
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package {
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
@@ -24,36 +23,39 @@
         "//device/google/gs101:device_google_gs101_license",
     ],
 }
-
-cc_library_shared {
-    name: "android.hardware.health@2.1-impl-gs101",
-    stem: "android.hardware.health@2.0-impl-2.1-gs101",
-
-    proprietary: true,
+cc_defaults {
+    name: "android.hardware.health-service.gs101-defaults",
+    defaults: [
+        "libhealth_aidl_impl_user",
+        "libhealth_aidl_charger_defaults",
+    ],
     relative_install_path: "hw",
+    vintf_fragments: ["android.hardware.health-service.gs101.xml"],
     srcs: [
         "Health.cpp",
     ],
-
     cflags: [
         "-Wall",
         "-Werror",
     ],
-
     static_libs: [
-        "android.hardware.health@1.0-convert",
-        "libbatterymonitor",
-        "libhealth2impl",
-        "libhealthloop",
+        "libhealth_aidl_impl",
     ],
-
+}
+cc_binary {
+    name: "android.hardware.health-service.gs101",
+    defaults: ["android.hardware.health-service.gs101-defaults"],
+    proprietary: true,
+    init_rc: ["android.hardware.health-service.gs101.rc"],
+    overrides: ["charger"],
     shared_libs: [
-        "libbase",
-        "libcutils",
-        "libhidlbase",
         "libpixelhealth",
-        "libutils",
-        "android.hardware.health@2.0",
-        "android.hardware.health@2.1",
     ],
 }
+cc_binary {
+    name: "android.hardware.health-service.gs101_recovery",
+    defaults: ["android.hardware.health-service.gs101-defaults"],
+    recovery: true,
+    init_rc: ["android.hardware.health-service.gs101_recovery.rc"],
+    overrides: ["charger.recovery"],
+}
diff --git a/health/Health.cpp b/health/Health.cpp
index fe8ad84..a50cc8b 100644
--- a/health/Health.cpp
+++ b/health/Health.cpp
@@ -19,17 +19,20 @@
 #include <android-base/file.h>
 #include <android-base/parseint.h>
 #include <android-base/strings.h>
-#include <android/hardware/health/2.0/types.h>
-#include <health2impl/Health.h>
+#include <android/hardware/health/translate-ndk.h>
+#include <health-impl/Health.h>
 #include <health/utils.h>
-#include <hal_conversion.h>
 
+// Recovery doesn't have libpixelhealth and charger mode
+#ifndef __ANDROID_RECOVERY__
+#include <health-impl/ChargerUtils.h>
 #include <pixelhealth/BatteryDefender.h>
 #include <pixelhealth/BatteryMetricsLogger.h>
 #include <pixelhealth/BatteryThermalControl.h>
 #include <pixelhealth/ChargerDetect.h>
 #include <pixelhealth/DeviceHealth.h>
 #include <pixelhealth/LowBatteryShutdownMetrics.h>
+#endif // !__ANDROID_RECOVERY__
 
 #include <chrono>
 #include <fstream>
@@ -41,15 +44,15 @@
 
 using namespace std::literals;
 
-using android::hardware::health::V1_0::hal_conversion::convertFromHealthInfo;
-using android::hardware::health::V1_0::hal_conversion::convertToHealthInfo;
-using android::hardware::health::V2_0::DiskStats;
-using android::hardware::health::V2_0::StorageAttribute;
-using android::hardware::health::V2_0::StorageInfo;
-using android::hardware::health::V2_0::Result;
-using ::android::hardware::health::V2_1::IHealth;
+using aidl::android::hardware::health::DiskStats;
+using aidl::android::hardware::health::HalHealthLoop;
+using aidl::android::hardware::health::HealthInfo;
+using aidl::android::hardware::health::StorageInfo;
 using android::hardware::health::InitHealthdConfig;
 
+#ifndef __ANDROID_RECOVERY__
+using aidl::android::hardware::health::charger::ChargerCallback;
+using aidl::android::hardware::health::charger::ChargerModeMain;
 using hardware::google::pixel::health::BatteryDefender;
 using hardware::google::pixel::health::BatteryMetricsLogger;
 using hardware::google::pixel::health::BatteryThermalControl;
@@ -72,6 +75,7 @@
 static BatteryMetricsLogger battMetricsLogger(kBatteryResistance, kBatteryOCV);
 static LowBatteryShutdownMetrics shutdownMetrics(kVoltageAvg);
 static DeviceHealth deviceHealth;
+#endif // !__ANDROID_RECOVERY__
 
 #define UFS_DIR "/dev/sys/block/bootdevice"
 constexpr char kUfsHealthEol[]{UFS_DIR "/health_descriptor/eol_info"};
@@ -79,7 +83,6 @@
 constexpr char kUfsHealthLifetimeB[]{UFS_DIR "/health_descriptor/life_time_estimation_b"};
 constexpr char kUfsVersion[]{UFS_DIR "/device_descriptor/specification_version"};
 constexpr char kDiskStatsFile[]{"/sys/block/sda/stat"};
-constexpr char kUFSName[]{"UFS0"};
 
 static std::string ufs_version;
 static uint16_t eol;
@@ -88,8 +91,10 @@
 static std::chrono::system_clock::time_point ufs_last_query_time;
 constexpr auto kUfsQueryIntervalHours = std::chrono::hours{24};
 
+#ifndef __ANDROID_RECOVERY__
 static bool needs_wlc_updates = false;
 constexpr char kWlcCapacity[]{WLC_DIR "/capacity"};
+#endif // !__ANDROID_RECOVERY__
 
 std::ifstream assert_open(const std::string &path) {
   std::ifstream stream(path);
@@ -118,12 +123,10 @@
   info->version = ufs_version;
 }
 
-void fill_ufs_storage_attribute(StorageAttribute *attr) {
-  attr->isInternal = true;
-  attr->isBootDevice = true;
-  attr->name = kUFSName;
-}
-
+#ifdef __ANDROID_RECOVERY__
+void private_healthd_board_init(struct healthd_config *) {}
+int private_healthd_board_battery_update(HealthInfo *) { return 0; }
+#else // !__ANDROID__RECOVERY__
 static bool FileExists(const std::string &filename) {
   struct stat buffer;
 
@@ -140,26 +143,26 @@
   }
 }
 
-int private_healthd_board_battery_update(struct android::BatteryProperties *props) {
-  deviceHealth.update(props);
-  battThermalControl.updateThermalState(props);
-  battMetricsLogger.logBatteryProperties(props);
-  shutdownMetrics.logShutdownVoltage(props);
+int private_healthd_board_battery_update(HealthInfo *health_info) {
+  deviceHealth.update(health_info);
+  battThermalControl.updateThermalState(*health_info);
+  battMetricsLogger.logBatteryProperties(*health_info);
+  shutdownMetrics.logShutdownVoltage(*health_info);
   // Allow BatteryDefender to override online properties
-  ChargerDetect::onlineUpdate(props);
-  battDefender.update(props);
+  ChargerDetect::onlineUpdate(health_info);
+  battDefender.update(health_info);
 
   if (needs_wlc_updates &&
-      !android::base::WriteStringToFile(std::to_string(props->batteryLevel), kWlcCapacity))
+      !android::base::WriteStringToFile(std::to_string(health_info->batteryLevel), kWlcCapacity))
       LOG(INFO) << "Unable to write battery level to wireless capacity";
 
   return 0;
 }
+#endif // __ANDROID_RECOVERY__
 
-void private_get_storage_info(std::vector<StorageInfo> &vec_storage_info) {
-  vec_storage_info.resize(1);
-  StorageInfo *storage_info = &vec_storage_info[0];
-  fill_ufs_storage_attribute(&storage_info->attr);
+void private_get_storage_info(std::vector<StorageInfo> *vec_storage_info) {
+  vec_storage_info->resize(1);
+  StorageInfo *storage_info = &vec_storage_info->at(0);
 
   read_ufs_version(storage_info);
 
@@ -180,10 +183,9 @@
   return;
 }
 
-void private_get_disk_stats(std::vector<DiskStats> &vec_stats) {
-  vec_stats.resize(1);
-  DiskStats *stats = &vec_stats[0];
-  fill_ufs_storage_attribute(&stats->attr);
+void private_get_disk_stats(std::vector<DiskStats> *vec_stats) {
+  vec_stats->resize(1);
+  DiskStats *stats = &vec_stats->at(0);
 
   auto stream = assert_open(kDiskStatsFile);
   // Regular diskstats entries
@@ -195,18 +197,14 @@
 }
 }  // anonymous namespace
 
-namespace android {
-namespace hardware {
-namespace health {
-namespace V2_1 {
-namespace implementation {
+namespace aidl::android::hardware::health::implementation {
 class HealthImpl : public Health {
  public:
-  HealthImpl(std::unique_ptr<healthd_config>&& config)
-    : Health(std::move(config)) {}
+  HealthImpl(std::string_view instance_name, std::unique_ptr<healthd_config>&& config)
+    : Health(std::move(instance_name), std::move(config)) {}
 
-  Return<void> getStorageInfo(getStorageInfo_cb _hidl_cb) override;
-  Return<void> getDiskStats(getDiskStats_cb _hidl_cb) override;
+    ndk::ScopedAStatus getDiskStats(std::vector<DiskStats>* out) override;
+    ndk::ScopedAStatus getStorageInfo(std::vector<StorageInfo>* out) override;
 
  protected:
   void UpdateHealthInfo(HealthInfo* health_info) override;
@@ -214,53 +212,57 @@
 };
 
 void HealthImpl::UpdateHealthInfo(HealthInfo* health_info) {
-  struct BatteryProperties props;
-  convertFromHealthInfo(health_info->legacy.legacy, &props);
-  private_healthd_board_battery_update(&props);
-  convertToHealthInfo(&props, health_info->legacy.legacy);
+  private_healthd_board_battery_update(health_info);
 }
 
-Return<void> HealthImpl::getStorageInfo(getStorageInfo_cb _hidl_cb)
+ndk::ScopedAStatus HealthImpl::getStorageInfo(std::vector<StorageInfo>* out)
 {
-  std::vector<struct StorageInfo> info;
-  private_get_storage_info(info);
-  hidl_vec<struct StorageInfo> info_vec(info);
-  if (!info.size()) {
-      _hidl_cb(Result::NOT_SUPPORTED, info_vec);
-  } else {
-      _hidl_cb(Result::SUCCESS, info_vec);
+  private_get_storage_info(out);
+  if (out->empty()) {
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
   }
-  return Void();
+  return ndk::ScopedAStatus::ok();
 }
 
-Return<void> HealthImpl::getDiskStats(getDiskStats_cb _hidl_cb)
+ndk::ScopedAStatus HealthImpl::getDiskStats(std::vector<DiskStats>* out)
 {
-  std::vector<struct DiskStats> stats;
-  private_get_disk_stats(stats);
-  hidl_vec<struct DiskStats> stats_vec(stats);
-  if (!stats.size()) {
-      _hidl_cb(Result::NOT_SUPPORTED, stats_vec);
-  } else {
-      _hidl_cb(Result::SUCCESS, stats_vec);
+  private_get_disk_stats(out);
+  if (out->empty()) {
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
   }
-  return Void();
+  return ndk::ScopedAStatus::ok();
 }
 
-}  // namespace implementation
-}  // namespace V2_1
-}  // namespace health
-}  // namespace hardware
-}  // namespace android
+}  // namespace aidl::android::hardware::health::implementation
 
-extern "C" IHealth* HIDL_FETCH_IHealth(const char* instance) {
-  using ::android::hardware::health::V2_1::implementation::HealthImpl;
-  if (instance != "default"sv) {
-      return nullptr;
-  }
+int main(int argc, char **argv) {
+  using ::aidl::android::hardware::health::implementation::HealthImpl;
+
+  // Use kernel logging in recovery
+#ifdef __ANDROID_RECOVERY__
+  android::base::InitLogging(argv, android::base::KernelLogger);
+#endif
+
   auto config = std::make_unique<healthd_config>();
   InitHealthdConfig(config.get());
 
   private_healthd_board_init(config.get());
 
-  return new HealthImpl(std::move(config));
+  auto binder =
+      ndk::SharedRefBase::make<HealthImpl>("default"sv, std::move(config));
+
+  if (argc >= 2 && argv[1] == "--charger"sv) {
+    // In regular mode, start charger UI.
+#ifndef __ANDROID_RECOVERY__
+    LOG(INFO) << "Starting charger mode with UI.";
+    return ChargerModeMain(binder, std::make_shared<ChargerCallback>(binder));
+#endif
+    // In recovery, ignore --charger arg.
+    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/health/android.hardware.health-service.gs101.rc b/health/android.hardware.health-service.gs101.rc
new file mode 100644
index 0000000..b738b5c
--- /dev/null
+++ b/health/android.hardware.health-service.gs101.rc
@@ -0,0 +1,16 @@
+service vendor.health-gs101 /vendor/bin/hw/android.hardware.health-service.gs101
+    class hal
+    user system
+    group system
+    capabilities WAKE_ALARM BLOCK_SUSPEND
+    file /dev/kmsg w
+service vendor.charger-gs101 /vendor/bin/hw/android.hardware.health-service.gs101 --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
diff --git a/health/android.hardware.health-service.gs101.xml b/health/android.hardware.health-service.gs101.xml
new file mode 100644
index 0000000..98026cb
--- /dev/null
+++ b/health/android.hardware.health-service.gs101.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>
diff --git a/health/android.hardware.health-service.gs101_recovery.rc b/health/android.hardware.health-service.gs101_recovery.rc
new file mode 100644
index 0000000..d1e3504
--- /dev/null
+++ b/health/android.hardware.health-service.gs101_recovery.rc
@@ -0,0 +1,7 @@
+service vendor.health-gs101 /system/bin/hw/android.hardware.health-service.gs101_recovery
+    class hal
+    seclabel u:r:hal_health_default:s0
+    user system
+    group system
+    capabilities WAKE_ALARM BLOCK_SUSPEND
+    file /dev/kmsg w