Merge changes from topic "storaged_health"

* changes:
  storaged: use health HAL to read StorageInfo.
  storaged: use health HAL to read DiskStats.
  storaged: storaged_t replace initHealthService with init.
  storaged: use get_health_service
diff --git a/storaged/Android.bp b/storaged/Android.bp
index 2c7dea1..b478f4a 100644
--- a/storaged/Android.bp
+++ b/storaged/Android.bp
@@ -65,6 +65,8 @@
         "binder/android/os/storaged/IStoragedPrivate.aidl",
     ],
 
+    static_libs: ["libhealthhalutils"],
+
     logtags: ["EventLogTags.logtags"],
 
     proto: {
@@ -84,7 +86,10 @@
 
     srcs: ["main.cpp"],
 
-    static_libs: ["libstoraged"],
+    static_libs: [
+        "libhealthhalutils",
+        "libstoraged",
+    ],
 }
 
 /*
@@ -98,7 +103,10 @@
 
     srcs: ["tests/storaged_test.cpp"],
 
-    static_libs: ["libstoraged"],
+    static_libs: [
+        "libhealthhalutils",
+        "libstoraged",
+    ],
 }
 
 // AIDL interface between storaged and framework.jar
diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h
index 6bf6c9c..c5cac27 100644
--- a/storaged/include/storaged.h
+++ b/storaged/include/storaged.h
@@ -81,7 +81,7 @@
   private:
     time_t mTimer;
     storaged_config mConfig;
-    disk_stats_monitor mDsm;
+    unique_ptr<disk_stats_monitor> mDsm;
     uid_monitor mUidm;
     time_t mStarttime;
     sp<android::hardware::health::V2_0::IHealth> health;
@@ -96,8 +96,11 @@
         return string("/data/misc_ce/") + to_string(user_id) +
                "/storaged/storaged.proto";
     }
-public:
+    void init_health_service();
+
+  public:
     storaged_t(void);
+    void init(void);
     void event(void);
     void event_checked(void);
     void pause(void) {
@@ -130,7 +133,6 @@
     void add_user_ce(userid_t user_id);
     void remove_user_ce(userid_t user_id);
 
-    void init_health_service();
     virtual ::android::hardware::Return<void> healthInfoChanged(
         const ::android::hardware::health::V1_0::HealthInfo& info);
     void serviceDied(uint64_t cookie, const wp<::android::hidl::base::V1_0::IBase>& who);
diff --git a/storaged/include/storaged_diskstats.h b/storaged/include/storaged_diskstats.h
index ff030f6..0b93ba6 100644
--- a/storaged/include/storaged_diskstats.h
+++ b/storaged/include/storaged_diskstats.h
@@ -19,6 +19,8 @@
 
 #include <stdint.h>
 
+#include <android/hardware/health/2.0/IHealth.h>
+
 // number of attributes diskstats has
 #define DISK_STATS_SIZE ( 11 )
 
@@ -160,6 +162,7 @@
     const double mSigma;
     struct disk_perf mMean;
     struct disk_perf mStd;
+    android::sp<android::hardware::health::V2_0::IHealth> mHealth;
 
     void update_mean();
     void update_std();
@@ -170,21 +173,27 @@
     void update(struct disk_stats* stats);
 
 public:
-    disk_stats_monitor(uint32_t window_size = 5, double sigma = 1.0) :
-        DISK_STATS_PATH(access(MMC_DISK_STATS_PATH, R_OK) ?
-                            (access(SDA_DISK_STATS_PATH, R_OK) ?
-                                nullptr :
-                                SDA_DISK_STATS_PATH) :
-                            MMC_DISK_STATS_PATH),
-        mPrevious(), mAccumulate(), mAccumulate_pub(),
-        mStall(false), mValid(false),
-        mWindow(window_size), mSigma(sigma),
-        mMean(), mStd() {}
-    bool enabled() {
-        return DISK_STATS_PATH != nullptr;
-    }
-    void update(void);
-    void publish(void);
+  disk_stats_monitor(const android::sp<android::hardware::health::V2_0::IHealth>& healthService,
+                     uint32_t window_size = 5, double sigma = 1.0)
+      : DISK_STATS_PATH(
+            healthService != nullptr
+                ? nullptr
+                : (access(MMC_DISK_STATS_PATH, R_OK) == 0
+                       ? MMC_DISK_STATS_PATH
+                       : (access(SDA_DISK_STATS_PATH, R_OK) == 0 ? SDA_DISK_STATS_PATH : nullptr))),
+        mPrevious(),
+        mAccumulate(),
+        mAccumulate_pub(),
+        mStall(false),
+        mValid(false),
+        mWindow(window_size),
+        mSigma(sigma),
+        mMean(),
+        mStd(),
+        mHealth(healthService) {}
+  bool enabled() { return mHealth != nullptr || DISK_STATS_PATH != nullptr; }
+  void update(void);
+  void publish(void);
 };
 
-#endif /* _STORAGED_DISKSTATS_H_ */
\ No newline at end of file
+#endif /* _STORAGED_DISKSTATS_H_ */
diff --git a/storaged/include/storaged_info.h b/storaged/include/storaged_info.h
index b1efac2..3a6a0d4 100644
--- a/storaged/include/storaged_info.h
+++ b/storaged/include/storaged_info.h
@@ -21,6 +21,7 @@
 
 #include <chrono>
 
+#include <android/hardware/health/2.0/IHealth.h>
 #include <utils/Mutex.h>
 
 #include "storaged.h"
@@ -35,7 +36,7 @@
 using namespace storaged_proto;
 
 class storage_info_t {
-protected:
+  protected:
     FRIEND_TEST(storaged_test, storage_info_t);
     // emmc lifetime
     uint16_t eol;                   // pre-eol (end of life) information
@@ -66,8 +67,10 @@
     }
     void publish();
     storage_info_t* s_info;
-public:
-    static storage_info_t* get_storage_info();
+
+  public:
+    static storage_info_t* get_storage_info(
+        const sp<android::hardware::health::V2_0::IHealth>& healthService);
     virtual ~storage_info_t() {};
     virtual void report() {};
     void load_perf_history_proto(const IOPerfHistory& perf_history);
@@ -98,4 +101,18 @@
     virtual void report();
 };
 
+class health_storage_info_t : public storage_info_t {
+  private:
+    using IHealth = hardware::health::V2_0::IHealth;
+    using StorageInfo = hardware::health::V2_0::StorageInfo;
+
+    sp<IHealth> mHealth;
+    void set_values_from_hal_storage_info(const StorageInfo& halInfo);
+
+  public:
+    health_storage_info_t(const sp<IHealth>& service) : mHealth(service){};
+    virtual ~health_storage_info_t() {}
+    virtual void report();
+};
+
 #endif /* _STORAGED_INFO_H_ */
diff --git a/storaged/main.cpp b/storaged/main.cpp
index c1b1329..b3f1281 100644
--- a/storaged/main.cpp
+++ b/storaged/main.cpp
@@ -51,7 +51,7 @@
 void* storaged_main(void* /* unused */) {
     storaged_sp = new storaged_t();
 
-    storaged_sp->init_health_service();
+    storaged_sp->init();
     storaged_sp->report_storage_info();
 
     LOG_TO(SYSTEM, INFO) << "storaged: Start";
diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp
index ff0de29..6807cd9 100644
--- a/storaged/storaged.cpp
+++ b/storaged/storaged.cpp
@@ -28,11 +28,12 @@
 #include <sstream>
 #include <string>
 
-#include <android/hidl/manager/1.0/IServiceManager.h>
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
 #include <batteryservice/BatteryServiceConstants.h>
 #include <cutils/properties.h>
+#include <healthhalutils/HealthHalUtils.h>
 #include <hidl/HidlTransportSupport.h>
 #include <hwbinder/IPCThreadState.h>
 #include <log/log.h>
@@ -62,25 +63,16 @@
 
 const uint32_t storaged_t::current_version = 4;
 
-using android::hardware::health::V1_0::BatteryStatus;
-using android::hardware::health::V1_0::toString;
-using android::hardware::health::V1_0::HealthInfo;
-using android::hardware::health::V2_0::IHealth;
-using android::hardware::health::V2_0::Result;
 using android::hardware::interfacesEqual;
 using android::hardware::Return;
+using android::hardware::health::V1_0::BatteryStatus;
+using android::hardware::health::V1_0::HealthInfo;
+using android::hardware::health::V1_0::toString;
+using android::hardware::health::V2_0::get_health_service;
+using android::hardware::health::V2_0::IHealth;
+using android::hardware::health::V2_0::Result;
 using android::hidl::manager::V1_0::IServiceManager;
 
-static sp<IHealth> get_health_service() {
-    for (auto&& instanceName : {"default", "backup"}) {
-        auto ret = IHealth::getService(instanceName);
-        if (ret != nullptr) {
-            return ret;
-        }
-        LOG_TO(SYSTEM, INFO) << "health: storaged: cannot get " << instanceName << " service";
-    }
-    return nullptr;
-}
 
 inline charger_stat_t is_charger_on(BatteryStatus prop) {
     return (prop == BatteryStatus::CHARGING || prop == BatteryStatus::FULL) ?
@@ -92,6 +84,12 @@
     return android::hardware::Void();
 }
 
+void storaged_t::init() {
+    init_health_service();
+    mDsm = std::make_unique<disk_stats_monitor>(health);
+    storage_info.reset(storage_info_t::get_storage_info(health));
+}
+
 void storaged_t::init_health_service() {
     if (!mUidm.enabled())
         return;
@@ -160,8 +158,6 @@
         property_get_int32("ro.storaged.flush_proto.interval",
                            DEFAULT_PERIODIC_CHORES_INTERVAL_FLUSH_PROTO);
 
-    storage_info.reset(storage_info_t::get_storage_info());
-
     mStarttime = time(NULL);
     mTimer = 0;
 }
@@ -315,10 +311,10 @@
 void storaged_t::event(void) {
     unordered_map<int, StoragedProto> protos;
 
-    if (mDsm.enabled()) {
-        mDsm.update();
+    if (mDsm->enabled()) {
+        mDsm->update();
         if (!(mTimer % mConfig.periodic_chores_interval_disk_stats_publish)) {
-            mDsm.publish();
+            mDsm->publish();
         }
     }
 
diff --git a/storaged/storaged_diskstats.cpp b/storaged/storaged_diskstats.cpp
index 0604e0a..1050033 100644
--- a/storaged/storaged_diskstats.cpp
+++ b/storaged/storaged_diskstats.cpp
@@ -30,6 +30,12 @@
 
 namespace {
 
+using android::sp;
+using android::hardware::health::V2_0::DiskStats;
+using android::hardware::health::V2_0::IHealth;
+using android::hardware::health::V2_0::Result;
+using android::hardware::health::V2_0::toString;
+
 #ifdef DEBUG
 void log_debug_disk_perf(struct disk_perf* perf, const char* type) {
     // skip if the input structure are all zeros
@@ -60,17 +66,30 @@
 
 } // namespace
 
-bool parse_disk_stats(const char* disk_stats_path, struct disk_stats* stats)
-{
-    // Get time
-    struct timespec ts;
+bool get_time(struct timespec* ts) {
     // Use monotonic to exclude suspend time so that we measure IO bytes/sec
     // when system is running.
-    int ret = clock_gettime(CLOCK_MONOTONIC, &ts);
+    int ret = clock_gettime(CLOCK_MONOTONIC, ts);
     if (ret < 0) {
         PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed";
         return false;
     }
+    return true;
+}
+
+void init_disk_stats_other(const struct timespec& ts, struct disk_stats* stats) {
+    stats->start_time = 0;
+    stats->end_time = (uint64_t)ts.tv_sec * SEC_TO_MSEC + ts.tv_nsec / (MSEC_TO_USEC * USEC_TO_NSEC);
+    stats->counter = 1;
+    stats->io_avg = (double)stats->io_in_flight;
+}
+
+bool parse_disk_stats(const char* disk_stats_path, struct disk_stats* stats) {
+    // Get time
+    struct timespec ts;
+    if (!get_time(&ts)) {
+        return false;
+    }
 
     std::string buffer;
     if (!android::base::ReadFileToString(disk_stats_path, &buffer)) {
@@ -84,11 +103,52 @@
         ss >> *((uint64_t*)stats + i);
     }
     // Other entries
-    stats->start_time = 0;
-    stats->end_time = (uint64_t)ts.tv_sec * SEC_TO_MSEC +
-        ts.tv_nsec / (MSEC_TO_USEC * USEC_TO_NSEC);
-    stats->counter = 1;
-    stats->io_avg = (double)stats->io_in_flight;
+    init_disk_stats_other(ts, stats);
+    return true;
+}
+
+void convert_hal_disk_stats(struct disk_stats* dst, const DiskStats& src) {
+    dst->read_ios = src.reads;
+    dst->read_merges = src.readMerges;
+    dst->read_sectors = src.readSectors;
+    dst->read_ticks = src.readTicks;
+    dst->write_ios = src.writes;
+    dst->write_merges = src.writeMerges;
+    dst->write_sectors = src.writeSectors;
+    dst->write_ticks = src.writeTicks;
+    dst->io_in_flight = src.ioInFlight;
+    dst->io_ticks = src.ioTicks;
+    dst->io_in_queue = src.ioInQueue;
+}
+
+bool get_disk_stats_from_health_hal(const sp<IHealth>& service, struct disk_stats* stats) {
+    struct timespec ts;
+    if (!get_time(&ts)) {
+        return false;
+    }
+
+    bool success = false;
+    auto ret = service->getDiskStats([&success, stats](auto result, const auto& halStats) {
+        if (result != Result::SUCCESS || halStats.size() == 0) {
+            LOG_TO(SYSTEM, ERROR) << "getDiskStats failed with result " << toString(result)
+                                  << " and size " << halStats.size();
+            return;
+        }
+
+        convert_hal_disk_stats(stats, halStats[0]);
+        success = true;
+    });
+
+    if (!ret.isOk()) {
+        LOG_TO(SYSTEM, ERROR) << "getDiskStats failed with " << ret.description();
+        return false;
+    }
+
+    if (!success) {
+        return false;
+    }
+
+    init_disk_stats_other(ts, stats);
     return true;
 }
 
@@ -243,8 +303,14 @@
 
 void disk_stats_monitor::update() {
     disk_stats curr;
-    if (!parse_disk_stats(DISK_STATS_PATH, &curr)) {
-        return;
+    if (mHealth != nullptr) {
+        if (!get_disk_stats_from_health_hal(mHealth, &curr)) {
+            return;
+        }
+    } else {
+        if (!parse_disk_stats(DISK_STATS_PATH, &curr)) {
+            return;
+        }
     }
 
     update(&curr);
diff --git a/storaged/storaged_info.cpp b/storaged/storaged_info.cpp
index 036d7e1..b6dd164 100644
--- a/storaged/storaged_info.cpp
+++ b/storaged/storaged_info.cpp
@@ -36,6 +36,10 @@
 using namespace android::base;
 using namespace storaged_proto;
 
+using android::hardware::health::V2_0::IHealth;
+using android::hardware::health::V2_0::Result;
+using android::hardware::health::V2_0::StorageInfo;
+
 const string emmc_info_t::emmc_sysfs = "/sys/bus/mmc/devices/mmc0:0001/";
 const string emmc_info_t::emmc_debugfs = "/d/mmc0/mmc0:0001/ext_csd";
 const char* emmc_info_t::emmc_ver_str[9] = {
@@ -54,8 +58,10 @@
 
 } // namespace
 
-storage_info_t* storage_info_t::get_storage_info()
-{
+storage_info_t* storage_info_t::get_storage_info(const sp<IHealth>& healthService) {
+    if (healthService != nullptr) {
+        return new health_storage_info_t(healthService);
+    }
     if (FileExists(emmc_info_t::emmc_sysfs) ||
         FileExists(emmc_info_t::emmc_debugfs)) {
         return new emmc_info_t;
@@ -351,3 +357,25 @@
     publish();
 }
 
+void health_storage_info_t::report() {
+    auto ret = mHealth->getStorageInfo([this](auto result, const auto& halInfos) {
+        if (result != Result::SUCCESS || halInfos.size() == 0) {
+            LOG_TO(SYSTEM, DEBUG) << "getStorageInfo failed with result " << toString(result)
+                                  << " and size " << halInfos.size();
+            return;
+        }
+        set_values_from_hal_storage_info(halInfos[0]);
+        publish();
+    });
+
+    if (!ret.isOk()) {
+        LOG_TO(SYSTEM, DEBUG) << "getStorageInfo failed with " << ret.description();
+    }
+}
+
+void health_storage_info_t::set_values_from_hal_storage_info(const StorageInfo& halInfo) {
+    eol = halInfo.eol;
+    lifetime_a = halInfo.lifetimeA;
+    lifetime_b = halInfo.lifetimeB;
+    version = halInfo.version;
+}
diff --git a/storaged/tests/storaged_test.cpp b/storaged/tests/storaged_test.cpp
index 6a5fc61..d1fa9ed 100644
--- a/storaged/tests/storaged_test.cpp
+++ b/storaged/tests/storaged_test.cpp
@@ -25,6 +25,7 @@
 
 #include <gtest/gtest.h>
 
+#include <healthhalutils/HealthHalUtils.h>
 #include <storaged.h>               // data structures
 #include <storaged_utils.h>         // functions to test
 
@@ -234,10 +235,17 @@
 }
 
 TEST(storaged_test, disk_stats_monitor) {
+    using android::hardware::health::V2_0::get_health_service;
+
+    auto healthService = get_health_service();
+
     // asserting that there is one file for diskstats
-    ASSERT_TRUE(access(MMC_DISK_STATS_PATH, R_OK) >= 0 || access(SDA_DISK_STATS_PATH, R_OK) >= 0);
+    ASSERT_TRUE(healthService != nullptr || access(MMC_DISK_STATS_PATH, R_OK) >= 0 ||
+                access(SDA_DISK_STATS_PATH, R_OK) >= 0);
+
     // testing if detect() will return the right value
-    disk_stats_monitor dsm_detect;
+    disk_stats_monitor dsm_detect{healthService};
+    ASSERT_TRUE(dsm_detect.enabled());
     // feed monitor with constant perf data for io perf baseline
     // using constant perf is reasonable since the functionality of stream_stats
     // has already been tested
@@ -280,7 +288,7 @@
     }
 
     // testing if stalled disk_stats can be correctly accumulated in the monitor
-    disk_stats_monitor dsm_acc;
+    disk_stats_monitor dsm_acc{healthService};
     struct disk_stats norm_inc = {
         .read_ios = 200,
         .read_merges = 0,