1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <health-shim/shim.h>
18
19 #include <android/hardware/health/translate-ndk.h>
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22
23 using HidlHealth = android::hardware::health::V2_0::IHealth;
24 using HidlHealthInfoCallback = android::hardware::health::V2_0::IHealthInfoCallback;
25 using HidlStorageInfo = android::hardware::health::V2_0::StorageInfo;
26 using HidlDiskStats = android::hardware::health::V2_0::DiskStats;
27 using HidlHealthInfo = android::hardware::health::V2_0::HealthInfo;
28 using HidlBatteryStatus = android::hardware::health::V1_0::BatteryStatus;
29 using android::sp;
30 using android::hardware::Return;
31 using android::hardware::Void;
32 using android::hardware::health::V2_0::Result;
33 using ndk::SharedRefBase;
34 using testing::Invoke;
35 using testing::NiceMock;
36
37 namespace aidl::android::hardware::health {
38 MATCHER(IsOk, "") {
39 *result_listener << "status is " << arg.getDescription();
40 return arg.isOk();
41 }
42
43 MATCHER_P(ExceptionIs, exception_code, "") {
44 *result_listener << "status is " << arg.getDescription();
45 return arg.getExceptionCode() == exception_code;
46 }
47
48 class MockHidlHealth : public HidlHealth {
49 public:
50 MOCK_METHOD(Return<Result>, registerCallback, (const sp<HidlHealthInfoCallback>& callback),
51 (override));
52 MOCK_METHOD(Return<Result>, unregisterCallback, (const sp<HidlHealthInfoCallback>& callback),
53 (override));
54 MOCK_METHOD(Return<Result>, update, (), (override));
55 MOCK_METHOD(Return<void>, getChargeCounter, (getChargeCounter_cb _hidl_cb), (override));
56 MOCK_METHOD(Return<void>, getCurrentNow, (getCurrentNow_cb _hidl_cb), (override));
57 MOCK_METHOD(Return<void>, getCurrentAverage, (getCurrentAverage_cb _hidl_cb), (override));
58 MOCK_METHOD(Return<void>, getCapacity, (getCapacity_cb _hidl_cb), (override));
59 MOCK_METHOD(Return<void>, getEnergyCounter, (getEnergyCounter_cb _hidl_cb), (override));
60 MOCK_METHOD(Return<void>, getChargeStatus, (getChargeStatus_cb _hidl_cb), (override));
61 MOCK_METHOD(Return<void>, getStorageInfo, (getStorageInfo_cb _hidl_cb), (override));
62 MOCK_METHOD(Return<void>, getDiskStats, (getDiskStats_cb _hidl_cb), (override));
63 MOCK_METHOD(Return<void>, getHealthInfo, (getHealthInfo_cb _hidl_cb), (override));
64 };
65
66 class HealthShimTest : public ::testing::Test {
67 public:
SetUp()68 void SetUp() override {
69 hidl = new NiceMock<MockHidlHealth>();
70 shim = SharedRefBase::make<HealthShim>(hidl);
71 }
72 sp<MockHidlHealth> hidl;
73 std::shared_ptr<IHealth> shim;
74 };
75
76 #define ADD_TEST(name, aidl_name, AidlValueType, hidl_value, not_supported_hidl_value) \
77 TEST_F(HealthShimTest, name) { \
78 ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) { \
79 cb(Result::SUCCESS, hidl_value); \
80 return Void(); \
81 })); \
82 AidlValueType value; \
83 ASSERT_THAT(shim->aidl_name(&value), IsOk()); \
84 ASSERT_EQ(value, static_cast<AidlValueType>(hidl_value)); \
85 } \
86 \
87 TEST_F(HealthShimTest, name##Unsupported) { \
88 ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) { \
89 cb(Result::NOT_SUPPORTED, not_supported_hidl_value); \
90 return Void(); \
91 })); \
92 AidlValueType value; \
93 ASSERT_THAT(shim->aidl_name(&value), ExceptionIs(EX_UNSUPPORTED_OPERATION)); \
94 }
95
96 ADD_TEST(getChargeCounter, getChargeCounterUah, int32_t, 0xFEEDBEEF, 0)
97 ADD_TEST(getCurrentNow, getCurrentNowMicroamps, int32_t, 0xC0FFEE, 0)
98 ADD_TEST(getCurrentAverage, getCurrentAverageMicroamps, int32_t, 0xA2D401D, 0)
99 ADD_TEST(getCapacity, getCapacity, int32_t, 77, 0)
100 ADD_TEST(getEnergyCounter, getEnergyCounterNwh, int64_t, 0x1234567887654321, 0)
ADD_TEST(getChargeStatus,getChargeStatus,BatteryStatus,HidlBatteryStatus::CHARGING,HidlBatteryStatus::UNKNOWN)101 ADD_TEST(getChargeStatus, getChargeStatus, BatteryStatus, HidlBatteryStatus::CHARGING,
102 HidlBatteryStatus::UNKNOWN)
103
104 #undef ADD_TEST
105
106 template <typename AidlValueType, typename HidlValueType>
107 bool Translate(const HidlValueType& hidl_value, AidlValueType* aidl_value) {
108 return ::android::h2a::translate(hidl_value, aidl_value);
109 }
110
111 template <typename AidlValueType, typename HidlValueType>
Translate(const std::vector<HidlValueType> & hidl_vec,std::vector<AidlValueType> * aidl_vec)112 bool Translate(const std::vector<HidlValueType>& hidl_vec, std::vector<AidlValueType>* aidl_vec) {
113 aidl_vec->clear();
114 aidl_vec->reserve(hidl_vec.size());
115 for (const auto& hidl_value : hidl_vec) {
116 auto& aidl_value = aidl_vec->emplace_back();
117 if (!Translate(hidl_value, &aidl_value)) return false;
118 }
119 return true;
120 }
121
122 #define ADD_INFO_TEST(name, AidlValueType, hidl_value) \
123 TEST_F(HealthShimTest, name) { \
124 AidlValueType expected_aidl_value; \
125 ASSERT_TRUE(Translate(hidl_value, &expected_aidl_value)); \
126 ON_CALL(*hidl, name).WillByDefault(Invoke([&](auto cb) { \
127 cb(Result::SUCCESS, hidl_value); \
128 return Void(); \
129 })); \
130 AidlValueType aidl_value; \
131 ASSERT_THAT(shim->name(&aidl_value), IsOk()); \
132 ASSERT_EQ(aidl_value, expected_aidl_value); \
133 } \
134 \
135 TEST_F(HealthShimTest, name##Unsupported) { \
136 ON_CALL(*hidl, name).WillByDefault(Invoke([](auto cb) { \
137 cb(Result::NOT_SUPPORTED, {}); \
138 return Void(); \
139 })); \
140 AidlValueType aidl_value; \
141 ASSERT_THAT(shim->name(&aidl_value), ExceptionIs(EX_UNSUPPORTED_OPERATION)); \
142 }
143
144 ADD_INFO_TEST(getStorageInfo, std::vector<StorageInfo>,
145 (std::vector<HidlStorageInfo>{{
146 .lifetimeA = 15,
147 .lifetimeB = 18,
148 }}))
149
150 ADD_INFO_TEST(getDiskStats, std::vector<DiskStats>,
151 (std::vector<HidlDiskStats>{{
152 .reads = 100,
153 .writes = 200,
154 }}))
155
156 ADD_INFO_TEST(getHealthInfo, HealthInfo,
157 (HidlHealthInfo{
158 .batteryCurrentAverage = 999,
159 }))
160
161 #undef ADD_INFO_TEST
162
163 } // namespace aidl::android::hardware::health
164