Merge changes from topic "storage_health_interface"

* changes:
  Add VTS tests for APIs that return storage info.
  Create libstoragehealthdefault
  Add methods to health HAL interface to report storage info
diff --git a/health/2.0/Android.bp b/health/2.0/Android.bp
index 1080df1..97704bf 100644
--- a/health/2.0/Android.bp
+++ b/health/2.0/Android.bp
@@ -17,6 +17,9 @@
     ],
     types: [
         "Result",
+        "DiskStats",
+        "StorageAttribute",
+        "StorageInfo",
     ],
     gen_java: true,
 }
diff --git a/health/2.0/IHealth.hal b/health/2.0/IHealth.hal
index 3e10701..a33bb15 100644
--- a/health/2.0/IHealth.hal
+++ b/health/2.0/IHealth.hal
@@ -137,4 +137,27 @@
      * @return value charge status, or UNKNOWN if not successful.
      */
     getChargeStatus() generates (Result result, BatteryStatus value);
+
+    /**
+     * Get storage info.
+     *
+     * @return result SUCCESS if successful,
+     *                NOT_SUPPORTED if this property is not supported,
+     *                UNKNOWN other errors.
+     * @return value vector of StorageInfo structs, to be ignored if result is not
+     *               SUCCESS.
+     */
+    getStorageInfo() generates (Result result, vec<StorageInfo> value);
+
+    /**
+     * Gets disk statistics (number of reads/writes processed, number of I/O
+     * operations in flight etc).
+     *
+     * @return result SUCCESS if successful,
+     *                NOT_SUPPORTED if this property is not supported,
+     *                UNKNOWN other errors.
+     * @return value vector of disk statistics, to be ignored if result is not SUCCESS.
+     *               The mapping is index 0->sda, 1->sdb and so on.
+     */
+    getDiskStats() generates (Result result, vec<DiskStats> value);
 };
diff --git a/health/2.0/default/Health.cpp b/health/2.0/default/Health.cpp
index 4710c90..96f6d70 100644
--- a/health/2.0/default/Health.cpp
+++ b/health/2.0/default/Health.cpp
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2018 The Android Open Source 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.
+ */
 #define LOG_TAG "android.hardware.health@2.0-impl"
 #include <android-base/logging.h>
 
@@ -160,6 +175,30 @@
     return Void();
 }
 
+Return<void> Health::getStorageInfo(getStorageInfo_cb _hidl_cb) {
+    std::vector<struct StorageInfo> info;
+    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);
+    }
+    return Void();
+}
+
+Return<void> Health::getDiskStats(getDiskStats_cb _hidl_cb) {
+    std::vector<struct DiskStats> stats;
+    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);
+    }
+    return Void();
+}
+
 void Health::serviceDied(uint64_t /* cookie */, const wp<IBase>& who) {
     (void)unregisterCallbackInternal(who.promote());
 }
diff --git a/health/2.0/default/include/health2/Health.h b/health/2.0/default/include/health2/Health.h
index ab42ae7..41ba9e9 100644
--- a/health/2.0/default/include/health2/Health.h
+++ b/health/2.0/default/include/health2/Health.h
@@ -9,6 +9,12 @@
 #include <healthd/BatteryMonitor.h>
 #include <hidl/Status.h>
 
+using android::hardware::health::V2_0::StorageInfo;
+using android::hardware::health::V2_0::DiskStats;
+
+void get_storage_info(std::vector<struct StorageInfo>& info);
+void get_disk_stats(std::vector<struct DiskStats>& stats);
+
 namespace android {
 namespace hardware {
 namespace health {
@@ -44,6 +50,8 @@
     Return<void> getCapacity(getCapacity_cb _hidl_cb) override;
     Return<void> getEnergyCounter(getEnergyCounter_cb _hidl_cb) override;
     Return<void> getChargeStatus(getChargeStatus_cb _hidl_cb) override;
+    Return<void> getStorageInfo(getStorageInfo_cb _hidl_cb) override;
+    Return<void> getDiskStats(getDiskStats_cb _hidl_cb) override;
 
     // Methods from ::android::hidl::base::V1_0::IBase follow.
     Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override;
diff --git a/health/2.0/libstoragehealthdefault/Android.bp b/health/2.0/libstoragehealthdefault/Android.bp
new file mode 100644
index 0000000..986e1ef
--- /dev/null
+++ b/health/2.0/libstoragehealthdefault/Android.bp
@@ -0,0 +1,11 @@
+// Copyright 2018 The Android Open Source Project
+
+cc_library_static {
+    srcs: ["StorageHealthDefault.cpp"],
+    name: "libhealthstoragedefault",
+    vendor_available: true,
+    cflags: ["-Werror"],
+    shared_libs: [
+        "android.hardware.health@2.0",
+    ],
+}
diff --git a/health/2.0/libstoragehealthdefault/StorageHealthDefault.cpp b/health/2.0/libstoragehealthdefault/StorageHealthDefault.cpp
new file mode 100644
index 0000000..aba6cc3
--- /dev/null
+++ b/health/2.0/libstoragehealthdefault/StorageHealthDefault.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2018 The Android Open Source 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 "include/StorageHealthDefault.h"
+
+void get_storage_info(std::vector<struct StorageInfo>&) {
+    // Use defaults.
+}
+
+void get_disk_stats(std::vector<struct DiskStats>&) {
+    // Use defaults
+}
diff --git a/health/2.0/libstoragehealthdefault/include/StorageHealthDefault.h b/health/2.0/libstoragehealthdefault/include/StorageHealthDefault.h
new file mode 100644
index 0000000..85eb210
--- /dev/null
+++ b/health/2.0/libstoragehealthdefault/include/StorageHealthDefault.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 The Android Open Source 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.
+ */
+#ifndef ANDROID_HARDWARE_HEALTH_V2_0_STORAGE_HEALTH_H
+#define ANDROID_HARDWARE_HEALTH_V2_0_STORAGE_HEALTH_H
+
+#include <android/hardware/health/2.0/types.h>
+
+using android::hardware::health::V2_0::StorageInfo;
+using android::hardware::health::V2_0::DiskStats;
+
+/*
+ * Get storage information.
+ */
+void get_storage_info(std::vector<struct StorageInfo>& info);
+
+/*
+ * Get disk statistics.
+ */
+void get_disk_stats(std::vector<struct DiskStats>& stats);
+
+#endif  // ANDROID_HARDWARE_HEALTH_V2_0_STORAGE_HEALTH_H
diff --git a/health/2.0/types.hal b/health/2.0/types.hal
index 8c6d88f..4e7a081 100644
--- a/health/2.0/types.hal
+++ b/health/2.0/types.hal
@@ -26,3 +26,101 @@
     NOT_FOUND,
     CALLBACK_DIED,
 };
+
+/*
+ * Identification attributes for a storage device.
+ */
+struct StorageAttribute {
+    /**
+     * Set to true if internal storage
+     */
+    bool isInternal;
+    /**
+     * Set to true if this is the boot device.
+     */
+    bool isBootDevice;
+    /**
+     * Name of the storage device.
+     */
+    string name;
+};
+
+/*
+ * Information on storage device including life time estimates, end of life
+ * information and other attributes.
+ */
+struct StorageInfo {
+    /**
+     * Attributes of the storage device whose info is contained by the struct.
+     */
+    StorageAttribute attr;
+    /**
+     * pre-eol (end of life) information. Follows JEDEC standard No.84-B50.
+     */
+    uint16_t eol;
+    /**
+     * device life time estimation (type A). Follows JEDEC standard No.84-B50.
+     */
+    uint16_t lifetimeA;
+    /**
+     * device life time estimation (type B). Follows JEDEC standard No.84-B50.
+     */
+    uint16_t lifetimeB;
+    /**
+     * version string
+     */
+    string version;
+};
+/*
+ * Disk statistics since boot.
+ */
+struct DiskStats {
+    /**
+     * Number of reads processed.
+     */
+    uint64_t reads;
+    /**
+     * number of read I/Os merged with in-queue I/Os.
+     */
+    uint64_t readMerges;
+    /**
+     * number of sectors read.
+     */
+    uint64_t readSectors;
+    /**
+     * total wait time for read requests.
+     */
+    uint64_t readTicks;
+    /**
+     * number of writes processed.
+     */
+    uint64_t writes;
+    /**
+     * number of writes merged with in-queue I/Os.
+     */
+    uint64_t writeMerges;
+    /**
+     * number of sectors written.
+     */
+    uint64_t writeSectors;
+    /**
+     * total wait time for write requests.
+     */
+    uint64_t writeTicks;
+    /**
+     * number of I/Os currently in flight.
+     */
+    uint64_t ioInFlight;
+    /**
+     * total time this block device has been active.
+     */
+    uint64_t ioTicks;
+    /**
+     * total wait time for all requests.
+     */
+    uint64_t ioInQueue;
+    /**
+     * Attributes of the memory device.
+     */
+    StorageAttribute attr;
+};
diff --git a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
index bf8548c..b2c6160 100644
--- a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
+++ b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
@@ -180,6 +180,29 @@
     return AssertionFailure() << "Result is not SUCCESS or NOT_SUPPORTED: " << toString(res);
 }
 
+bool verifyStorageInfo(const hidl_vec<struct StorageInfo>& info) {
+    for (size_t i = 0; i < info.size(); i++) {
+        if (!(0 <= info[i].eol && info[i].eol <= 3 && 0 <= info[i].lifetimeA &&
+              info[i].lifetimeA <= 0x0B && 0 <= info[i].lifetimeB && info[i].lifetimeB <= 0x0B)) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool verifyDiskStats(const hidl_vec<struct DiskStats>& stats) {
+    for (size_t i = 0; i < stats.size(); i++) {
+        if (!(stats[i].reads > 0 && stats[i].readMerges > 0 && stats[i].readSectors > 0 &&
+              stats[i].readTicks > 0 && stats[i].writes > 0 && stats[i].writeMerges > 0 &&
+              stats[i].writeSectors > 0 && stats[i].writeTicks > 0 && stats[i].ioTicks > 0)) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
 TEST_F(HealthHidlTest, Properties) {
     EXPECT_OK(mHealth->getChargeCounter([](auto result, auto value) {
         EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value > 0);
@@ -202,6 +225,12 @@
             value == BatteryStatus::CHARGING || value == BatteryStatus::DISCHARGING ||
                 value == BatteryStatus::NOT_CHARGING || value == BatteryStatus::FULL);
     }));
+    EXPECT_OK(mHealth->getStorageInfo([](auto result, auto& value) {
+        EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), (verifyStorageInfo(value)));
+    }));
+    EXPECT_OK(mHealth->getDiskStats([](auto result, auto& value) {
+        EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), verifyDiskStats(value));
+    }));
 }
 
 }  // namespace V2_0