/* * Copyright (C) 2021 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 #include #include using HidlHealth = android::hardware::health::V2_0::IHealth; using HidlHealthInfoCallback = android::hardware::health::V2_0::IHealthInfoCallback; using HidlStorageInfo = android::hardware::health::V2_0::StorageInfo; using HidlDiskStats = android::hardware::health::V2_0::DiskStats; using HidlHealthInfo = android::hardware::health::V2_0::HealthInfo; using HidlBatteryStatus = android::hardware::health::V1_0::BatteryStatus; using android::sp; using android::hardware::Return; using android::hardware::Void; using android::hardware::health::V2_0::Result; using ndk::SharedRefBase; using testing::Invoke; using testing::NiceMock; namespace aidl::android::hardware::health { MATCHER(IsOk, "") { *result_listener << "status is " << arg.getDescription(); return arg.isOk(); } MATCHER_P(ExceptionIs, exception_code, "") { *result_listener << "status is " << arg.getDescription(); return arg.getExceptionCode() == exception_code; } class MockHidlHealth : public HidlHealth { public: MOCK_METHOD(Return, registerCallback, (const sp& callback), (override)); MOCK_METHOD(Return, unregisterCallback, (const sp& callback), (override)); MOCK_METHOD(Return, update, (), (override)); MOCK_METHOD(Return, getChargeCounter, (getChargeCounter_cb _hidl_cb), (override)); MOCK_METHOD(Return, getCurrentNow, (getCurrentNow_cb _hidl_cb), (override)); MOCK_METHOD(Return, getCurrentAverage, (getCurrentAverage_cb _hidl_cb), (override)); MOCK_METHOD(Return, getCapacity, (getCapacity_cb _hidl_cb), (override)); MOCK_METHOD(Return, getEnergyCounter, (getEnergyCounter_cb _hidl_cb), (override)); MOCK_METHOD(Return, getChargeStatus, (getChargeStatus_cb _hidl_cb), (override)); MOCK_METHOD(Return, getStorageInfo, (getStorageInfo_cb _hidl_cb), (override)); MOCK_METHOD(Return, getDiskStats, (getDiskStats_cb _hidl_cb), (override)); MOCK_METHOD(Return, getHealthInfo, (getHealthInfo_cb _hidl_cb), (override)); }; class HealthShimTest : public ::testing::Test { public: void SetUp() override { hidl = new NiceMock(); shim = SharedRefBase::make(hidl); } sp hidl; std::shared_ptr shim; }; #define ADD_TEST(name, aidl_name, AidlValueType, hidl_value, not_supported_hidl_value) \ TEST_F(HealthShimTest, name) { \ ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) { \ cb(Result::SUCCESS, hidl_value); \ return Void(); \ })); \ AidlValueType value; \ ASSERT_THAT(shim->aidl_name(&value), IsOk()); \ ASSERT_EQ(value, static_cast(hidl_value)); \ } \ \ TEST_F(HealthShimTest, name##Unsupported) { \ ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) { \ cb(Result::NOT_SUPPORTED, not_supported_hidl_value); \ return Void(); \ })); \ AidlValueType value; \ ASSERT_THAT(shim->aidl_name(&value), ExceptionIs(EX_UNSUPPORTED_OPERATION)); \ } ADD_TEST(getChargeCounter, getChargeCounterUah, int32_t, 0xFEEDBEEF, 0) ADD_TEST(getCurrentNow, getCurrentNowMicroamps, int32_t, 0xC0FFEE, 0) ADD_TEST(getCurrentAverage, getCurrentAverageMicroamps, int32_t, 0xA2D401D, 0) ADD_TEST(getCapacity, getCapacity, int32_t, 77, 0) ADD_TEST(getEnergyCounter, getEnergyCounterNwh, int64_t, 0x1234567887654321, 0) ADD_TEST(getChargeStatus, getChargeStatus, BatteryStatus, HidlBatteryStatus::CHARGING, HidlBatteryStatus::UNKNOWN) #undef ADD_TEST template bool Translate(const HidlValueType& hidl_value, AidlValueType* aidl_value) { return ::android::h2a::translate(hidl_value, aidl_value); } template bool Translate(const std::vector& hidl_vec, std::vector* aidl_vec) { aidl_vec->clear(); aidl_vec->reserve(hidl_vec.size()); for (const auto& hidl_value : hidl_vec) { auto& aidl_value = aidl_vec->emplace_back(); if (!Translate(hidl_value, &aidl_value)) return false; } return true; } #define ADD_INFO_TEST(name, AidlValueType, hidl_value) \ TEST_F(HealthShimTest, name) { \ AidlValueType expected_aidl_value; \ ASSERT_TRUE(Translate(hidl_value, &expected_aidl_value)); \ ON_CALL(*hidl, name).WillByDefault(Invoke([&](auto cb) { \ cb(Result::SUCCESS, hidl_value); \ return Void(); \ })); \ AidlValueType aidl_value; \ ASSERT_THAT(shim->name(&aidl_value), IsOk()); \ ASSERT_EQ(aidl_value, expected_aidl_value); \ } \ \ TEST_F(HealthShimTest, name##Unsupported) { \ ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) { \ cb(Result::NOT_SUPPORTED, {}); \ return Void(); \ })); \ AidlValueType aidl_value; \ ASSERT_THAT(shim->name(&aidl_value), ExceptionIs(EX_UNSUPPORTED_OPERATION)); \ } ADD_INFO_TEST(getStorageInfo, std::vector, (std::vector{{ .lifetimeA = 15, .lifetimeB = 18, }})) ADD_INFO_TEST(getDiskStats, std::vector, (std::vector{{ .reads = 100, .writes = 200, }})) ADD_INFO_TEST(getHealthInfo, HealthInfo, (HidlHealthInfo{ .batteryCurrentAverage = 999, })) #undef ADD_INFO_TEST } // namespace aidl::android::hardware::health