diff options
author | 2025-01-10 16:39:09 -0800 | |
---|---|---|
committer | 2025-01-10 16:39:09 -0800 | |
commit | 6dbd1f9575b2898b11583015d0baa66e440d3f40 (patch) | |
tree | bfd1d2c3eec9ecad5276d3c22e6c6f3410b09ce2 | |
parent | 896dbf9e13024e158f749d1ce8cdba4547004457 (diff) | |
parent | 2a1c9e4306a703162177ace37d38ecc30715b5d3 (diff) |
Merge "Change to use support info for interval millis" into main
-rw-r--r-- | core/java/android/os/health/SystemHealthManager.java | 12 | ||||
-rw-r--r-- | core/tests/coretests/src/android/os/SystemHealthManagerUnitTest.java | 153 | ||||
-rw-r--r-- | native/android/libandroid.map.txt | 1 | ||||
-rw-r--r-- | native/android/system_health.cpp | 60 | ||||
-rw-r--r-- | native/android/tests/system_health/Android.bp | 66 | ||||
-rw-r--r-- | native/android/tests/system_health/NativeSystemHealthUnitTest.cpp | 231 |
6 files changed, 490 insertions, 33 deletions
diff --git a/core/java/android/os/health/SystemHealthManager.java b/core/java/android/os/health/SystemHealthManager.java index febbfca56bfb..9d0e221bd9e7 100644 --- a/core/java/android/os/health/SystemHealthManager.java +++ b/core/java/android/os/health/SystemHealthManager.java @@ -344,11 +344,7 @@ public class SystemHealthManager { || !mHintManagerClientData.supportInfo.headroom.isCpuSupported) { throw new UnsupportedOperationException(); } - try { - return mHintManager.getCpuHeadroomMinIntervalMillis(); - } catch (RemoteException re) { - throw re.rethrowFromSystemServer(); - } + return mHintManagerClientData.supportInfo.headroom.cpuMinIntervalMillis; } /** @@ -366,11 +362,7 @@ public class SystemHealthManager { || !mHintManagerClientData.supportInfo.headroom.isGpuSupported) { throw new UnsupportedOperationException(); } - try { - return mHintManager.getGpuHeadroomMinIntervalMillis(); - } catch (RemoteException re) { - throw re.rethrowFromSystemServer(); - } + return mHintManagerClientData.supportInfo.headroom.gpuMinIntervalMillis; } /** diff --git a/core/tests/coretests/src/android/os/SystemHealthManagerUnitTest.java b/core/tests/coretests/src/android/os/SystemHealthManagerUnitTest.java new file mode 100644 index 000000000000..e093e1af2eb5 --- /dev/null +++ b/core/tests/coretests/src/android/os/SystemHealthManagerUnitTest.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2024 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. + */ + +package android.os; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.hardware.power.CpuHeadroomResult; +import android.hardware.power.GpuHeadroomResult; +import android.hardware.power.SupportInfo; +import android.os.health.SystemHealthManager; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.android.internal.app.IBatteryStats; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@RunWith(AndroidJUnit4.class) +public class SystemHealthManagerUnitTest { + @Mock + private IBatteryStats mBatteryStats; + @Mock + private IPowerStatsService mPowerStats; + @Mock + private IHintManager mHintManager; + private SystemHealthManager mSystemHealthManager; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + IHintManager.HintManagerClientData clientData = new IHintManager.HintManagerClientData(); + clientData.supportInfo = new SupportInfo(); + clientData.maxCpuHeadroomThreads = 10; + clientData.supportInfo.headroom = new SupportInfo.HeadroomSupportInfo(); + clientData.supportInfo.headroom.isCpuSupported = true; + clientData.supportInfo.headroom.isGpuSupported = true; + clientData.supportInfo.headroom.cpuMinCalculationWindowMillis = 45; + clientData.supportInfo.headroom.cpuMaxCalculationWindowMillis = 9999; + clientData.supportInfo.headroom.gpuMinCalculationWindowMillis = 46; + clientData.supportInfo.headroom.gpuMaxCalculationWindowMillis = 9998; + clientData.supportInfo.headroom.cpuMinIntervalMillis = 999; + clientData.supportInfo.headroom.gpuMinIntervalMillis = 998; + when(mHintManager.getClientData()).thenReturn(clientData); + mSystemHealthManager = new SystemHealthManager(mBatteryStats, mPowerStats, mHintManager); + } + + @Test + public void testHeadroomParamsValueRange() { + assertEquals(999, mSystemHealthManager.getCpuHeadroomMinIntervalMillis()); + assertEquals(998, mSystemHealthManager.getGpuHeadroomMinIntervalMillis()); + assertEquals(45, (int) mSystemHealthManager.getCpuHeadroomCalculationWindowRange().first); + assertEquals(9999, + (int) mSystemHealthManager.getCpuHeadroomCalculationWindowRange().second); + assertEquals(46, (int) mSystemHealthManager.getGpuHeadroomCalculationWindowRange().first); + assertEquals(9998, + (int) mSystemHealthManager.getGpuHeadroomCalculationWindowRange().second); + assertEquals(10, (int) mSystemHealthManager.getMaxCpuHeadroomTidsSize()); + } + + @Test + public void testGetCpuHeadroom() throws RemoteException, InterruptedException { + final CpuHeadroomParams params1 = null; + final CpuHeadroomParamsInternal internalParams1 = new CpuHeadroomParamsInternal(); + + final CpuHeadroomParams params2 = new CpuHeadroomParams.Builder() + .setCalculationWindowMillis(100) + .build(); + final CpuHeadroomParamsInternal internalParams2 = new CpuHeadroomParamsInternal(); + internalParams2.calculationWindowMillis = 100; + + final CpuHeadroomParams params3 = new CpuHeadroomParams.Builder() + .setCalculationType(CpuHeadroomParams.CPU_HEADROOM_CALCULATION_TYPE_AVERAGE) + .build(); + final CpuHeadroomParamsInternal internalParams3 = new CpuHeadroomParamsInternal(); + internalParams3.calculationType = + (byte) CpuHeadroomParams.CPU_HEADROOM_CALCULATION_TYPE_AVERAGE; + + final CpuHeadroomParams params4 = new CpuHeadroomParams.Builder() + .setTids(1000, 1001) + .build(); + final CpuHeadroomParamsInternal internalParams4 = new CpuHeadroomParamsInternal(); + internalParams4.tids = new int[]{1000, 1001}; + + when(mHintManager.getCpuHeadroom(internalParams1)).thenReturn( + CpuHeadroomResult.globalHeadroom(99f)); + when(mHintManager.getCpuHeadroom(internalParams2)).thenReturn( + CpuHeadroomResult.globalHeadroom(98f)); + when(mHintManager.getCpuHeadroom(internalParams3)).thenReturn( + CpuHeadroomResult.globalHeadroom(97f)); + when(mHintManager.getCpuHeadroom(internalParams4)).thenReturn(null); + + assertEquals(99f, mSystemHealthManager.getCpuHeadroom(params1), 0.001f); + assertEquals(98f, mSystemHealthManager.getCpuHeadroom(params2), 0.001f); + assertEquals(97f, mSystemHealthManager.getCpuHeadroom(params3), 0.001f); + assertTrue(Float.isNaN(mSystemHealthManager.getCpuHeadroom(params4))); + verify(mHintManager, times(1)).getCpuHeadroom(internalParams1); + verify(mHintManager, times(1)).getCpuHeadroom(internalParams2); + verify(mHintManager, times(1)).getCpuHeadroom(internalParams3); + verify(mHintManager, times(1)).getCpuHeadroom(internalParams4); + } + + @Test + public void testGetGpuHeadroom() throws RemoteException, InterruptedException { + final GpuHeadroomParams params1 = null; + final GpuHeadroomParamsInternal internalParams1 = new GpuHeadroomParamsInternal(); + final GpuHeadroomParams params2 = new GpuHeadroomParams.Builder() + .setCalculationWindowMillis(100) + .build(); + final GpuHeadroomParamsInternal internalParams2 = new GpuHeadroomParamsInternal(); + internalParams2.calculationWindowMillis = 100; + final GpuHeadroomParams params3 = new GpuHeadroomParams.Builder() + .setCalculationType(GpuHeadroomParams.GPU_HEADROOM_CALCULATION_TYPE_AVERAGE) + .build(); + final GpuHeadroomParamsInternal internalParams3 = new GpuHeadroomParamsInternal(); + internalParams3.calculationType = + (byte) GpuHeadroomParams.GPU_HEADROOM_CALCULATION_TYPE_AVERAGE; + + when(mHintManager.getGpuHeadroom(internalParams1)).thenReturn( + GpuHeadroomResult.globalHeadroom(99f)); + when(mHintManager.getGpuHeadroom(internalParams2)).thenReturn( + GpuHeadroomResult.globalHeadroom(98f)); + when(mHintManager.getGpuHeadroom(internalParams3)).thenReturn(null); + + assertEquals(99f, mSystemHealthManager.getGpuHeadroom(params1), 0.001f); + assertEquals(98f, mSystemHealthManager.getGpuHeadroom(params2), 0.001f); + assertTrue(Float.isNaN(mSystemHealthManager.getGpuHeadroom(params3))); + verify(mHintManager, times(1)).getGpuHeadroom(internalParams1); + verify(mHintManager, times(1)).getGpuHeadroom(internalParams2); + verify(mHintManager, times(1)).getGpuHeadroom(internalParams3); + } +} diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index b30b779b57b5..49cbd7181d77 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -421,6 +421,7 @@ LIBANDROID { LIBANDROID_PLATFORM { global: AThermal_setIThermalServiceForTesting; + ASystemHealth_setIHintManagerForTesting; APerformanceHint_setIHintManagerForTesting; APerformanceHint_sendHint; APerformanceHint_getThreadIds; diff --git a/native/android/system_health.cpp b/native/android/system_health.cpp index 5c07ac7bfccc..1b43e71c7bf0 100644 --- a/native/android/system_health.cpp +++ b/native/android/system_health.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "system_health" + #include <aidl/android/hardware/power/CpuHeadroomParams.h> #include <aidl/android/hardware/power/GpuHeadroomParams.h> #include <aidl/android/os/CpuHeadroomParamsInternal.h> @@ -23,6 +25,17 @@ #include <android/system_health.h> #include <binder/IServiceManager.h> #include <binder/Status.h> +#include <system_health_private.h> + +#include <list> +#include <map> +#include <memory> +#include <mutex> +#include <optional> +#include <utility> + +#include "android-base/thread_annotations.h" +#include "utils/SystemClock.h" using namespace android; using namespace aidl::android::os; @@ -55,9 +68,20 @@ private: IHintManager::HintManagerClientData mClientData; }; +static std::shared_ptr<IHintManager>* gIHintManagerForTesting = nullptr; +static std::shared_ptr<ASystemHealthManager> gSystemHealthManagerForTesting = nullptr; + ASystemHealthManager* ASystemHealthManager::getInstance() { static std::once_flag creationFlag; static ASystemHealthManager* instance = nullptr; + if (gSystemHealthManagerForTesting) { + return gSystemHealthManagerForTesting.get(); + } + if (gIHintManagerForTesting) { + gSystemHealthManagerForTesting = + std::shared_ptr<ASystemHealthManager>(create(*gIHintManagerForTesting)); + return gSystemHealthManagerForTesting.get(); + } std::call_once(creationFlag, []() { instance = create(nullptr); }); return instance; } @@ -121,7 +145,8 @@ int ASystemHealthManager::getCpuHeadroom(const ACpuHeadroomParams* params, float } return EPIPE; } - *outHeadroom = res->get<hal::CpuHeadroomResult::Tag::globalHeadroom>(); + *outHeadroom = res ? res->get<hal::CpuHeadroomResult::Tag::globalHeadroom>() + : std::numeric_limits<float>::quiet_NaN(); return OK; } @@ -155,37 +180,20 @@ int ASystemHealthManager::getGpuHeadroom(const AGpuHeadroomParams* params, float } return EPIPE; } - *outHeadroom = res->get<hal::GpuHeadroomResult::Tag::globalHeadroom>(); + *outHeadroom = res ? res->get<hal::GpuHeadroomResult::Tag::globalHeadroom>() + : std::numeric_limits<float>::quiet_NaN(); return OK; } int ASystemHealthManager::getCpuHeadroomMinIntervalMillis(int64_t* outMinIntervalMillis) { if (!mClientData.supportInfo.headroom.isCpuSupported) return ENOTSUP; - int64_t minIntervalMillis = 0; - ::ndk::ScopedAStatus ret = mHintManager->getCpuHeadroomMinIntervalMillis(&minIntervalMillis); - if (!ret.isOk()) { - ALOGE("ASystemHealth_getCpuHeadroomMinIntervalMillis fails: %s", ret.getMessage()); - if (ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION) { - return ENOTSUP; - } - return EPIPE; - } - *outMinIntervalMillis = minIntervalMillis; + *outMinIntervalMillis = mClientData.supportInfo.headroom.cpuMinIntervalMillis; return OK; } int ASystemHealthManager::getGpuHeadroomMinIntervalMillis(int64_t* outMinIntervalMillis) { if (!mClientData.supportInfo.headroom.isGpuSupported) return ENOTSUP; - int64_t minIntervalMillis = 0; - ::ndk::ScopedAStatus ret = mHintManager->getGpuHeadroomMinIntervalMillis(&minIntervalMillis); - if (!ret.isOk()) { - ALOGE("ASystemHealth_getGpuHeadroomMinIntervalMillis fails: %s", ret.getMessage()); - if (ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION) { - return ENOTSUP; - } - return EPIPE; - } - *outMinIntervalMillis = minIntervalMillis; + *outMinIntervalMillis = mClientData.supportInfo.headroom.gpuMinIntervalMillis; return OK; } @@ -298,7 +306,6 @@ void ACpuHeadroomParams_setTids(ACpuHeadroomParams* _Nonnull params, const int* size_t tidsSize) { LOG_ALWAYS_FATAL_IF(tids == nullptr, "%s: tids should not be null", __FUNCTION__); params->tids.resize(tidsSize); - params->tids.clear(); for (int i = 0; i < (int)tidsSize; ++i) { LOG_ALWAYS_FATAL_IF(tids[i] <= 0, "ACpuHeadroomParams_setTids: Invalid non-positive tid %d", tids[i]); @@ -355,3 +362,10 @@ void ACpuHeadroomParams_destroy(ACpuHeadroomParams* _Nullable params) { void AGpuHeadroomParams_destroy(AGpuHeadroomParams* _Nullable params) { delete params; } + +void ASystemHealth_setIHintManagerForTesting(void* iManager) { + if (iManager == nullptr) { + gSystemHealthManagerForTesting = nullptr; + } + gIHintManagerForTesting = static_cast<std::shared_ptr<IHintManager>*>(iManager); +} diff --git a/native/android/tests/system_health/Android.bp b/native/android/tests/system_health/Android.bp new file mode 100644 index 000000000000..30aeb77375ad --- /dev/null +++ b/native/android/tests/system_health/Android.bp @@ -0,0 +1,66 @@ +// Copyright (C) 2024 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. + +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "frameworks_base_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["frameworks_base_license"], +} + +cc_test { + name: "NativeSystemHealthUnitTestCases", + + multilib: { + lib32: { + suffix: "32", + }, + lib64: { + suffix: "64", + }, + }, + + srcs: ["NativeSystemHealthUnitTest.cpp"], + + shared_libs: [ + "libandroid", + "libbinder", + "libbinder_ndk", + "liblog", + "libpowermanager", + "libutils", + ], + + static_libs: [ + "libbase", + "libgmock", + "libgtest", + ], + stl: "c++_shared", + + test_suites: [ + "device-tests", + ], + + cflags: [ + "-Wall", + "-Werror", + ], + + header_libs: [ + "libandroid_headers_private", + ], +} diff --git a/native/android/tests/system_health/NativeSystemHealthUnitTest.cpp b/native/android/tests/system_health/NativeSystemHealthUnitTest.cpp new file mode 100644 index 000000000000..3f08fc66e392 --- /dev/null +++ b/native/android/tests/system_health/NativeSystemHealthUnitTest.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2024 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 "NativeSystemHealthUnitTest" + +#include <aidl/android/os/IHintManager.h> +#include <android/binder_manager.h> +#include <android/binder_status.h> +#include <android/system_health.h> +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <system_health_private.h> + +#include <memory> +#include <optional> +#include <vector> + +using namespace std::chrono_literals; +namespace hal = aidl::android::hardware::power; +using aidl::android::os::CpuHeadroomParamsInternal; +using aidl::android::os::GpuHeadroomParamsInternal; +using aidl::android::os::IHintManager; +using aidl::android::os::IHintSession; +using aidl::android::os::SessionCreationConfig; +using ndk::ScopedAStatus; +using ndk::SpAIBinder; + +using namespace android; +using namespace testing; + +class MockIHintManager : public IHintManager { +public: + MOCK_METHOD(ScopedAStatus, createHintSessionWithConfig, + (const SpAIBinder& token, hal::SessionTag tag, + const SessionCreationConfig& creationConfig, hal::SessionConfig* config, + IHintManager::SessionCreationReturn* _aidl_return), + (override)); + MOCK_METHOD(ScopedAStatus, setHintSessionThreads, + (const std::shared_ptr<IHintSession>& _, const ::std::vector<int32_t>& tids), + (override)); + MOCK_METHOD(ScopedAStatus, getHintSessionThreadIds, + (const std::shared_ptr<IHintSession>& _, ::std::vector<int32_t>* tids), (override)); + MOCK_METHOD(ScopedAStatus, getSessionChannel, + (const ::ndk::SpAIBinder& in_token, + std::optional<hal::ChannelConfig>* _aidl_return), + (override)); + MOCK_METHOD(ScopedAStatus, closeSessionChannel, (), (override)); + MOCK_METHOD(ScopedAStatus, getCpuHeadroom, + (const CpuHeadroomParamsInternal& _, + std::optional<hal::CpuHeadroomResult>* _aidl_return), + (override)); + MOCK_METHOD(ScopedAStatus, getCpuHeadroomMinIntervalMillis, (int64_t*), (override)); + MOCK_METHOD(ScopedAStatus, getGpuHeadroom, + (const GpuHeadroomParamsInternal& _, + std::optional<hal::GpuHeadroomResult>* _aidl_return), + (override)); + MOCK_METHOD(ScopedAStatus, getGpuHeadroomMinIntervalMillis, (int64_t* _aidl_return), + (override)); + MOCK_METHOD(ScopedAStatus, passSessionManagerBinder, (const SpAIBinder& sessionManager)); + MOCK_METHOD(ScopedAStatus, registerClient, + (const std::shared_ptr<aidl::android::os::IHintManager::IHintManagerClient>& _, + aidl::android::os::IHintManager::HintManagerClientData* _aidl_return), + (override)); + MOCK_METHOD(ScopedAStatus, getClientData, + (aidl::android::os::IHintManager::HintManagerClientData * _aidl_return), + (override)); + MOCK_METHOD(SpAIBinder, asBinder, (), (override)); + MOCK_METHOD(bool, isRemote, (), (override)); +}; + +class NativeSystemHealthUnitTest : public Test { +public: + void SetUp() override { + mMockIHintManager = ndk::SharedRefBase::make<NiceMock<MockIHintManager>>(); + ASystemHealth_setIHintManagerForTesting(&mMockIHintManager); + ON_CALL(*mMockIHintManager, getClientData(_)) + .WillByDefault( + DoAll(SetArgPointee<0>(mClientData), [] { return ScopedAStatus::ok(); })); + } + + void TearDown() override { + ASystemHealth_setIHintManagerForTesting(nullptr); + } + + IHintManager::HintManagerClientData mClientData{ + .powerHalVersion = 6, + .maxCpuHeadroomThreads = 10, + .supportInfo{.headroom{ + .isCpuSupported = true, + .isGpuSupported = true, + .cpuMinIntervalMillis = 999, + .gpuMinIntervalMillis = 998, + .cpuMinCalculationWindowMillis = 45, + .cpuMaxCalculationWindowMillis = 9999, + .gpuMinCalculationWindowMillis = 46, + .gpuMaxCalculationWindowMillis = 9998, + }}, + }; + + std::shared_ptr<NiceMock<MockIHintManager>> mMockIHintManager = nullptr; +}; + +TEST_F(NativeSystemHealthUnitTest, headroomParamsValueRange) { + int64_t minIntervalMillis = 0; + int minCalculationWindowMillis = 0; + int maxCalculationWindowMillis = 0; + ASSERT_EQ(OK, ASystemHealth_getCpuHeadroomMinIntervalMillis(&minIntervalMillis)); + ASSERT_EQ(OK, + ASystemHealth_getCpuHeadroomCalculationWindowRange(&minCalculationWindowMillis, + &maxCalculationWindowMillis)); + ASSERT_EQ(minIntervalMillis, mClientData.supportInfo.headroom.cpuMinIntervalMillis); + ASSERT_EQ(minCalculationWindowMillis, + mClientData.supportInfo.headroom.cpuMinCalculationWindowMillis); + ASSERT_EQ(maxCalculationWindowMillis, + mClientData.supportInfo.headroom.cpuMaxCalculationWindowMillis); + + ASSERT_EQ(OK, ASystemHealth_getGpuHeadroomMinIntervalMillis(&minIntervalMillis)); + ASSERT_EQ(OK, + ASystemHealth_getGpuHeadroomCalculationWindowRange(&minCalculationWindowMillis, + &maxCalculationWindowMillis)); + ASSERT_EQ(minIntervalMillis, mClientData.supportInfo.headroom.gpuMinIntervalMillis); + ASSERT_EQ(minCalculationWindowMillis, + mClientData.supportInfo.headroom.gpuMinCalculationWindowMillis); + ASSERT_EQ(maxCalculationWindowMillis, + mClientData.supportInfo.headroom.gpuMaxCalculationWindowMillis); +} + +TEST_F(NativeSystemHealthUnitTest, getCpuHeadroom) { + CpuHeadroomParamsInternal internalParams1; + ACpuHeadroomParams* params2 = ACpuHeadroomParams_create(); + ACpuHeadroomParams_setCalculationWindowMillis(params2, 200); + CpuHeadroomParamsInternal internalParams2; + internalParams2.calculationWindowMillis = 200; + ACpuHeadroomParams* params3 = ACpuHeadroomParams_create(); + ACpuHeadroomParams_setCalculationType(params3, ACPU_HEADROOM_CALCULATION_TYPE_AVERAGE); + CpuHeadroomParamsInternal internalParams3; + internalParams3.calculationType = hal::CpuHeadroomParams::CalculationType::AVERAGE; + ACpuHeadroomParams* params4 = ACpuHeadroomParams_create(); + int tids[3] = {1, 2, 3}; + ACpuHeadroomParams_setTids(params4, tids, 3); + CpuHeadroomParamsInternal internalParams4; + internalParams4.tids = {1, 2, 3}; + + EXPECT_CALL(*mMockIHintManager, getCpuHeadroom(internalParams1, _)) + .Times(Exactly(1)) + .WillOnce(DoAll(SetArgPointee<1>(hal::CpuHeadroomResult::make< + hal::CpuHeadroomResult::globalHeadroom>(1.0f)), + [] { return ScopedAStatus::ok(); })); + EXPECT_CALL(*mMockIHintManager, getCpuHeadroom(internalParams2, _)) + .Times(Exactly(1)) + .WillOnce(DoAll(SetArgPointee<1>(hal::CpuHeadroomResult::make< + hal::CpuHeadroomResult::globalHeadroom>(2.0f)), + [] { return ScopedAStatus::ok(); })); + EXPECT_CALL(*mMockIHintManager, getCpuHeadroom(internalParams3, _)) + .Times(Exactly(1)) + .WillOnce(DoAll(SetArgPointee<1>(std::nullopt), [] { return ScopedAStatus::ok(); })); + EXPECT_CALL(*mMockIHintManager, getCpuHeadroom(internalParams4, _)) + .Times(Exactly(1)) + .WillOnce(DoAll(SetArgPointee<1>(hal::CpuHeadroomResult::make< + hal::CpuHeadroomResult::globalHeadroom>(4.0f)), + [] { return ScopedAStatus::ok(); })); + + float headroom1 = 0.0f; + float headroom2 = 0.0f; + float headroom3 = 0.0f; + float headroom4 = 0.0f; + ASSERT_EQ(OK, ASystemHealth_getCpuHeadroom(nullptr, &headroom1)); + ASSERT_EQ(OK, ASystemHealth_getCpuHeadroom(params2, &headroom2)); + ASSERT_EQ(OK, ASystemHealth_getCpuHeadroom(params3, &headroom3)); + ASSERT_EQ(OK, ASystemHealth_getCpuHeadroom(params4, &headroom4)); + ASSERT_EQ(1.0f, headroom1); + ASSERT_EQ(2.0f, headroom2); + ASSERT_TRUE(isnan(headroom3)); + ASSERT_EQ(4.0f, headroom4); + + ACpuHeadroomParams_destroy(params2); + ACpuHeadroomParams_destroy(params3); + ACpuHeadroomParams_destroy(params4); +} + +TEST_F(NativeSystemHealthUnitTest, getGpuHeadroom) { + GpuHeadroomParamsInternal internalParams1; + AGpuHeadroomParams* params2 = AGpuHeadroomParams_create(); + AGpuHeadroomParams_setCalculationWindowMillis(params2, 200); + GpuHeadroomParamsInternal internalParams2; + internalParams2.calculationWindowMillis = 200; + AGpuHeadroomParams* params3 = AGpuHeadroomParams_create(); + AGpuHeadroomParams_setCalculationType(params3, AGPU_HEADROOM_CALCULATION_TYPE_AVERAGE); + GpuHeadroomParamsInternal internalParams3; + internalParams3.calculationType = hal::GpuHeadroomParams::CalculationType::AVERAGE; + + EXPECT_CALL(*mMockIHintManager, getGpuHeadroom(internalParams1, _)) + .Times(Exactly(1)) + .WillOnce(DoAll(SetArgPointee<1>(hal::GpuHeadroomResult::make< + hal::GpuHeadroomResult::globalHeadroom>(1.0f)), + [] { return ScopedAStatus::ok(); })); + EXPECT_CALL(*mMockIHintManager, getGpuHeadroom(internalParams2, _)) + .Times(Exactly(1)) + .WillOnce(DoAll(SetArgPointee<1>(hal::GpuHeadroomResult::make< + hal::GpuHeadroomResult::globalHeadroom>(2.0f)), + [] { return ScopedAStatus::ok(); })); + EXPECT_CALL(*mMockIHintManager, getGpuHeadroom(internalParams3, _)) + .Times(Exactly(1)) + .WillOnce(DoAll(SetArgPointee<1>(std::nullopt), [] { return ScopedAStatus::ok(); })); + + float headroom1 = 0.0f; + float headroom2 = 0.0f; + float headroom3 = 0.0f; + ASSERT_EQ(OK, ASystemHealth_getGpuHeadroom(nullptr, &headroom1)); + ASSERT_EQ(OK, ASystemHealth_getGpuHeadroom(params2, &headroom2)); + ASSERT_EQ(OK, ASystemHealth_getGpuHeadroom(params3, &headroom3)); + ASSERT_EQ(1.0f, headroom1); + ASSERT_EQ(2.0f, headroom2); + ASSERT_TRUE(isnan(headroom3)); + + AGpuHeadroomParams_destroy(params2); + AGpuHeadroomParams_destroy(params3); +} |