blob: d1dfb8bf63e5bdb85428f3d284b1e6eda0e4bd84 [file] [log] [blame]
/*
* 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 <health-shim/shim.h>
#include <android/hardware/health/translate-ndk.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
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<Result>, registerCallback, (const sp<HidlHealthInfoCallback>& callback),
(override));
MOCK_METHOD(Return<Result>, unregisterCallback, (const sp<HidlHealthInfoCallback>& callback),
(override));
MOCK_METHOD(Return<Result>, update, (), (override));
MOCK_METHOD(Return<void>, getChargeCounter, (getChargeCounter_cb _hidl_cb), (override));
MOCK_METHOD(Return<void>, getCurrentNow, (getCurrentNow_cb _hidl_cb), (override));
MOCK_METHOD(Return<void>, getCurrentAverage, (getCurrentAverage_cb _hidl_cb), (override));
MOCK_METHOD(Return<void>, getCapacity, (getCapacity_cb _hidl_cb), (override));
MOCK_METHOD(Return<void>, getEnergyCounter, (getEnergyCounter_cb _hidl_cb), (override));
MOCK_METHOD(Return<void>, getChargeStatus, (getChargeStatus_cb _hidl_cb), (override));
MOCK_METHOD(Return<void>, getStorageInfo, (getStorageInfo_cb _hidl_cb), (override));
MOCK_METHOD(Return<void>, getDiskStats, (getDiskStats_cb _hidl_cb), (override));
MOCK_METHOD(Return<void>, getHealthInfo, (getHealthInfo_cb _hidl_cb), (override));
};
class HealthShimTest : public ::testing::Test {
public:
void SetUp() override {
hidl = new NiceMock<MockHidlHealth>();
shim = SharedRefBase::make<HealthShim>(hidl);
}
sp<MockHidlHealth> hidl;
std::shared_ptr<IHealth> 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<AidlValueType>(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 <typename AidlValueType, typename HidlValueType>
bool Translate(const HidlValueType& hidl_value, AidlValueType* aidl_value) {
return ::android::h2a::translate(hidl_value, aidl_value);
}
template <typename AidlValueType, typename HidlValueType>
bool Translate(const std::vector<HidlValueType>& hidl_vec, std::vector<AidlValueType>* 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<StorageInfo>,
(std::vector<HidlStorageInfo>{{
.lifetimeA = 15,
.lifetimeB = 18,
}}))
ADD_INFO_TEST(getDiskStats, std::vector<DiskStats>,
(std::vector<HidlDiskStats>{{
.reads = 100,
.writes = 200,
}}))
ADD_INFO_TEST(getHealthInfo, HealthInfo,
(HidlHealthInfo{
.batteryCurrentAverage = 999,
}))
#undef ADD_INFO_TEST
} // namespace aidl::android::hardware::health