• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 #define LOG_TAG "NativeSystemHealthUnitTest"
18 
19 #include <aidl/android/os/IHintManager.h>
20 #include <android/binder_manager.h>
21 #include <android/binder_status.h>
22 #include <android/system_health.h>
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25 #include <system_health_private.h>
26 
27 #include <memory>
28 #include <optional>
29 #include <vector>
30 
31 using namespace std::chrono_literals;
32 namespace hal = aidl::android::hardware::power;
33 using aidl::android::os::CpuHeadroomParamsInternal;
34 using aidl::android::os::GpuHeadroomParamsInternal;
35 using aidl::android::os::IHintManager;
36 using aidl::android::os::IHintSession;
37 using aidl::android::os::SessionCreationConfig;
38 using ndk::ScopedAStatus;
39 using ndk::SpAIBinder;
40 
41 using namespace android;
42 using namespace testing;
43 
44 class MockIHintManager : public IHintManager {
45 public:
46     MOCK_METHOD(ScopedAStatus, createHintSessionWithConfig,
47                 (const SpAIBinder& token, hal::SessionTag tag,
48                  const SessionCreationConfig& creationConfig, hal::SessionConfig* config,
49                  IHintManager::SessionCreationReturn* _aidl_return),
50                 (override));
51     MOCK_METHOD(ScopedAStatus, setHintSessionThreads,
52                 (const std::shared_ptr<IHintSession>& _, const ::std::vector<int32_t>& tids),
53                 (override));
54     MOCK_METHOD(ScopedAStatus, getHintSessionThreadIds,
55                 (const std::shared_ptr<IHintSession>& _, ::std::vector<int32_t>* tids), (override));
56     MOCK_METHOD(ScopedAStatus, getSessionChannel,
57                 (const ::ndk::SpAIBinder& in_token,
58                  std::optional<hal::ChannelConfig>* _aidl_return),
59                 (override));
60     MOCK_METHOD(ScopedAStatus, closeSessionChannel, (), (override));
61     MOCK_METHOD(ScopedAStatus, getCpuHeadroom,
62                 (const CpuHeadroomParamsInternal& _,
63                  std::optional<hal::CpuHeadroomResult>* _aidl_return),
64                 (override));
65     MOCK_METHOD(ScopedAStatus, getCpuHeadroomMinIntervalMillis, (int64_t*), (override));
66     MOCK_METHOD(ScopedAStatus, getGpuHeadroom,
67                 (const GpuHeadroomParamsInternal& _,
68                  std::optional<hal::GpuHeadroomResult>* _aidl_return),
69                 (override));
70     MOCK_METHOD(ScopedAStatus, getGpuHeadroomMinIntervalMillis, (int64_t* _aidl_return),
71                 (override));
72     MOCK_METHOD(ScopedAStatus, passSessionManagerBinder, (const SpAIBinder& sessionManager));
73     MOCK_METHOD(ScopedAStatus, registerClient,
74                 (const std::shared_ptr<aidl::android::os::IHintManager::IHintManagerClient>& _,
75                  aidl::android::os::IHintManager::HintManagerClientData* _aidl_return),
76                 (override));
77     MOCK_METHOD(ScopedAStatus, getClientData,
78                 (aidl::android::os::IHintManager::HintManagerClientData * _aidl_return),
79                 (override));
80     MOCK_METHOD(SpAIBinder, asBinder, (), (override));
81     MOCK_METHOD(bool, isRemote, (), (override));
82 };
83 
84 class NativeSystemHealthUnitTest : public Test {
85 public:
SetUp()86     void SetUp() override {
87         mMockIHintManager = ndk::SharedRefBase::make<NiceMock<MockIHintManager>>();
88         ASystemHealth_setIHintManagerForTesting(&mMockIHintManager);
89         ON_CALL(*mMockIHintManager, getClientData(_))
90                 .WillByDefault(
91                         DoAll(SetArgPointee<0>(mClientData), [] { return ScopedAStatus::ok(); }));
92     }
93 
TearDown()94     void TearDown() override {
95         ASystemHealth_setIHintManagerForTesting(nullptr);
96     }
97 
98     IHintManager::HintManagerClientData mClientData{
99             .powerHalVersion = 6,
100             .maxCpuHeadroomThreads = 10,
101             .supportInfo{.headroom{
102                     .isCpuSupported = true,
103                     .isGpuSupported = true,
104                     .cpuMinIntervalMillis = 999,
105                     .gpuMinIntervalMillis = 998,
106                     .cpuMinCalculationWindowMillis = 45,
107                     .cpuMaxCalculationWindowMillis = 9999,
108                     .gpuMinCalculationWindowMillis = 46,
109                     .gpuMaxCalculationWindowMillis = 9998,
110             }},
111     };
112 
113     std::shared_ptr<NiceMock<MockIHintManager>> mMockIHintManager = nullptr;
114 };
115 
TEST_F(NativeSystemHealthUnitTest,headroomParamsValueRange)116 TEST_F(NativeSystemHealthUnitTest, headroomParamsValueRange) {
117     int64_t minIntervalMillis = 0;
118     int minCalculationWindowMillis = 0;
119     int maxCalculationWindowMillis = 0;
120     ASSERT_EQ(OK, ASystemHealth_getCpuHeadroomMinIntervalMillis(&minIntervalMillis));
121     ASSERT_EQ(OK,
122               ASystemHealth_getCpuHeadroomCalculationWindowRange(&minCalculationWindowMillis,
123                                                                  &maxCalculationWindowMillis));
124     ASSERT_EQ(minIntervalMillis, mClientData.supportInfo.headroom.cpuMinIntervalMillis);
125     ASSERT_EQ(minCalculationWindowMillis,
126               mClientData.supportInfo.headroom.cpuMinCalculationWindowMillis);
127     ASSERT_EQ(maxCalculationWindowMillis,
128               mClientData.supportInfo.headroom.cpuMaxCalculationWindowMillis);
129 
130     ASSERT_EQ(OK, ASystemHealth_getGpuHeadroomMinIntervalMillis(&minIntervalMillis));
131     ASSERT_EQ(OK,
132               ASystemHealth_getGpuHeadroomCalculationWindowRange(&minCalculationWindowMillis,
133                                                                  &maxCalculationWindowMillis));
134     ASSERT_EQ(minIntervalMillis, mClientData.supportInfo.headroom.gpuMinIntervalMillis);
135     ASSERT_EQ(minCalculationWindowMillis,
136               mClientData.supportInfo.headroom.gpuMinCalculationWindowMillis);
137     ASSERT_EQ(maxCalculationWindowMillis,
138               mClientData.supportInfo.headroom.gpuMaxCalculationWindowMillis);
139 }
140 
TEST_F(NativeSystemHealthUnitTest,getCpuHeadroom)141 TEST_F(NativeSystemHealthUnitTest, getCpuHeadroom) {
142     CpuHeadroomParamsInternal internalParams1;
143     ACpuHeadroomParams* params2 = ACpuHeadroomParams_create();
144     ACpuHeadroomParams_setCalculationWindowMillis(params2, 200);
145     CpuHeadroomParamsInternal internalParams2;
146     internalParams2.calculationWindowMillis = 200;
147     ACpuHeadroomParams* params3 = ACpuHeadroomParams_create();
148     ACpuHeadroomParams_setCalculationType(params3, ACPU_HEADROOM_CALCULATION_TYPE_AVERAGE);
149     CpuHeadroomParamsInternal internalParams3;
150     internalParams3.calculationType = hal::CpuHeadroomParams::CalculationType::AVERAGE;
151     ACpuHeadroomParams* params4 = ACpuHeadroomParams_create();
152     int tids[3] = {1, 2, 3};
153     ACpuHeadroomParams_setTids(params4, tids, 3);
154     CpuHeadroomParamsInternal internalParams4;
155     internalParams4.tids = {1, 2, 3};
156 
157     EXPECT_CALL(*mMockIHintManager, getCpuHeadroom(internalParams1, _))
158             .Times(Exactly(1))
159             .WillOnce(DoAll(SetArgPointee<1>(hal::CpuHeadroomResult::make<
160                                              hal::CpuHeadroomResult::globalHeadroom>(1.0f)),
161                             [] { return ScopedAStatus::ok(); }));
162     EXPECT_CALL(*mMockIHintManager, getCpuHeadroom(internalParams2, _))
163             .Times(Exactly(1))
164             .WillOnce(DoAll(SetArgPointee<1>(hal::CpuHeadroomResult::make<
165                                              hal::CpuHeadroomResult::globalHeadroom>(2.0f)),
166                             [] { return ScopedAStatus::ok(); }));
167     EXPECT_CALL(*mMockIHintManager, getCpuHeadroom(internalParams3, _))
168             .Times(Exactly(1))
169             .WillOnce(DoAll(SetArgPointee<1>(std::nullopt), [] { return ScopedAStatus::ok(); }));
170     EXPECT_CALL(*mMockIHintManager, getCpuHeadroom(internalParams4, _))
171             .Times(Exactly(1))
172             .WillOnce(DoAll(SetArgPointee<1>(hal::CpuHeadroomResult::make<
173                                              hal::CpuHeadroomResult::globalHeadroom>(4.0f)),
174                             [] { return ScopedAStatus::ok(); }));
175 
176     float headroom1 = 0.0f;
177     float headroom2 = 0.0f;
178     float headroom3 = 0.0f;
179     float headroom4 = 0.0f;
180     ASSERT_EQ(OK, ASystemHealth_getCpuHeadroom(nullptr, &headroom1));
181     ASSERT_EQ(OK, ASystemHealth_getCpuHeadroom(params2, &headroom2));
182     ASSERT_EQ(OK, ASystemHealth_getCpuHeadroom(params3, &headroom3));
183     ASSERT_EQ(OK, ASystemHealth_getCpuHeadroom(params4, &headroom4));
184     ASSERT_EQ(1.0f, headroom1);
185     ASSERT_EQ(2.0f, headroom2);
186     ASSERT_TRUE(isnan(headroom3));
187     ASSERT_EQ(4.0f, headroom4);
188 
189     ACpuHeadroomParams_destroy(params2);
190     ACpuHeadroomParams_destroy(params3);
191     ACpuHeadroomParams_destroy(params4);
192 }
193 
TEST_F(NativeSystemHealthUnitTest,getGpuHeadroom)194 TEST_F(NativeSystemHealthUnitTest, getGpuHeadroom) {
195     GpuHeadroomParamsInternal internalParams1;
196     AGpuHeadroomParams* params2 = AGpuHeadroomParams_create();
197     AGpuHeadroomParams_setCalculationWindowMillis(params2, 200);
198     GpuHeadroomParamsInternal internalParams2;
199     internalParams2.calculationWindowMillis = 200;
200     AGpuHeadroomParams* params3 = AGpuHeadroomParams_create();
201     AGpuHeadroomParams_setCalculationType(params3, AGPU_HEADROOM_CALCULATION_TYPE_AVERAGE);
202     GpuHeadroomParamsInternal internalParams3;
203     internalParams3.calculationType = hal::GpuHeadroomParams::CalculationType::AVERAGE;
204 
205     EXPECT_CALL(*mMockIHintManager, getGpuHeadroom(internalParams1, _))
206             .Times(Exactly(1))
207             .WillOnce(DoAll(SetArgPointee<1>(hal::GpuHeadroomResult::make<
208                                              hal::GpuHeadroomResult::globalHeadroom>(1.0f)),
209                             [] { return ScopedAStatus::ok(); }));
210     EXPECT_CALL(*mMockIHintManager, getGpuHeadroom(internalParams2, _))
211             .Times(Exactly(1))
212             .WillOnce(DoAll(SetArgPointee<1>(hal::GpuHeadroomResult::make<
213                                              hal::GpuHeadroomResult::globalHeadroom>(2.0f)),
214                             [] { return ScopedAStatus::ok(); }));
215     EXPECT_CALL(*mMockIHintManager, getGpuHeadroom(internalParams3, _))
216             .Times(Exactly(1))
217             .WillOnce(DoAll(SetArgPointee<1>(std::nullopt), [] { return ScopedAStatus::ok(); }));
218 
219     float headroom1 = 0.0f;
220     float headroom2 = 0.0f;
221     float headroom3 = 0.0f;
222     ASSERT_EQ(OK, ASystemHealth_getGpuHeadroom(nullptr, &headroom1));
223     ASSERT_EQ(OK, ASystemHealth_getGpuHeadroom(params2, &headroom2));
224     ASSERT_EQ(OK, ASystemHealth_getGpuHeadroom(params3, &headroom3));
225     ASSERT_EQ(1.0f, headroom1);
226     ASSERT_EQ(2.0f, headroom2);
227     ASSERT_TRUE(isnan(headroom3));
228 
229     AGpuHeadroomParams_destroy(params2);
230     AGpuHeadroomParams_destroy(params3);
231 }
232