Address API review feedback
* Sync the headroom explanation between NDK and SDK
* Make the calculation window min max values public
* Change params to be immutable and add builder
* Add comment on how to use the APIs and the binder call warning
* Add new API getMaxCpuHeadroomTidsSize to query max TID count
Bug: 384056153
Bug: 346604998
Flag: android.os.cpu_gpu_headrooms
Test: atest HintManagerServiceTest
Change-Id: I8aff28a0b281e2948462924875017f9273440022
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 1ccadf9..c04f347 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -320,6 +320,9 @@
ASystemFontIterator_open; # introduced=29
ASystemFontIterator_close; # introduced=29
ASystemFontIterator_next; # introduced=29
+ ASystemHealth_getMaxCpuHeadroomTidsSize; # introduced=36
+ ASystemHealth_getCpuHeadroomCalculationWindowRange; # introduced=36
+ ASystemHealth_getGpuHeadroomCalculationWindowRange; # introduced=36
ASystemHealth_getCpuHeadroom; # introduced=36
ASystemHealth_getGpuHeadroom; # introduced=36
ASystemHealth_getCpuHeadroomMinIntervalMillis; # introduced=36
diff --git a/native/android/system_health.cpp b/native/android/system_health.cpp
index f3fa9f6..5c07ac7 100644
--- a/native/android/system_health.cpp
+++ b/native/android/system_health.cpp
@@ -31,26 +31,28 @@
struct ACpuHeadroomParams : public CpuHeadroomParamsInternal {};
struct AGpuHeadroomParams : public GpuHeadroomParamsInternal {};
-const int CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN = 50;
-const int CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX = 10000;
-const int GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN = 50;
-const int GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX = 10000;
-const int CPU_HEADROOM_MAX_TID_COUNT = 5;
-
struct ASystemHealthManager {
public:
static ASystemHealthManager* getInstance();
- ASystemHealthManager(std::shared_ptr<IHintManager>& hintManager);
+
+ ASystemHealthManager(std::shared_ptr<IHintManager>& hintManager,
+ IHintManager::HintManagerClientData&& clientData);
ASystemHealthManager() = delete;
~ASystemHealthManager();
int getCpuHeadroom(const ACpuHeadroomParams* params, float* outHeadroom);
int getGpuHeadroom(const AGpuHeadroomParams* params, float* outHeadroom);
int getCpuHeadroomMinIntervalMillis(int64_t* outMinIntervalMillis);
int getGpuHeadroomMinIntervalMillis(int64_t* outMinIntervalMillis);
+ int getMaxCpuHeadroomTidsSize(size_t* outSize);
+ int getCpuHeadroomCalculationWindowRange(int32_t* _Nonnull outMinMillis,
+ int32_t* _Nonnull outMaxMillis);
+ int getGpuHeadroomCalculationWindowRange(int32_t* _Nonnull outMinMillis,
+ int32_t* _Nonnull outMaxMillis);
private:
static ASystemHealthManager* create(std::shared_ptr<IHintManager> hintManager);
std::shared_ptr<IHintManager> mHintManager;
+ IHintManager::HintManagerClientData mClientData;
};
ASystemHealthManager* ASystemHealthManager::getInstance() {
@@ -60,10 +62,11 @@
return instance;
}
-ASystemHealthManager::ASystemHealthManager(std::shared_ptr<IHintManager>& hintManager)
- : mHintManager(std::move(hintManager)) {}
+ASystemHealthManager::ASystemHealthManager(std::shared_ptr<IHintManager>& hintManager,
+ IHintManager::HintManagerClientData&& clientData)
+ : mHintManager(std::move(hintManager)), mClientData(clientData) {}
-ASystemHealthManager::~ASystemHealthManager() {}
+ASystemHealthManager::~ASystemHealthManager() = default;
ASystemHealthManager* ASystemHealthManager::create(std::shared_ptr<IHintManager> hintManager) {
if (!hintManager) {
@@ -74,20 +77,37 @@
ALOGE("%s: PerformanceHint service is not ready ", __FUNCTION__);
return nullptr;
}
- return new ASystemHealthManager(hintManager);
-}
-
-ASystemHealthManager* ASystemHealth_acquireManager() {
- return ASystemHealthManager::getInstance();
+ IHintManager::HintManagerClientData clientData;
+ ndk::ScopedAStatus ret = hintManager->getClientData(&clientData);
+ if (!ret.isOk()) {
+ ALOGE("%s: PerformanceHint service is not initialized %s", __FUNCTION__, ret.getMessage());
+ return nullptr;
+ }
+ return new ASystemHealthManager(hintManager, std::move(clientData));
}
int ASystemHealthManager::getCpuHeadroom(const ACpuHeadroomParams* params, float* outHeadroom) {
+ if (!mClientData.supportInfo.headroom.isCpuSupported) return ENOTSUP;
std::optional<hal::CpuHeadroomResult> res;
::ndk::ScopedAStatus ret;
CpuHeadroomParamsInternal internalParams;
if (!params) {
ret = mHintManager->getCpuHeadroom(internalParams, &res);
} else {
+ LOG_ALWAYS_FATAL_IF((int)params->tids.size() > mClientData.maxCpuHeadroomThreads,
+ "%s: tids size should not exceed %d", __FUNCTION__,
+ mClientData.maxCpuHeadroomThreads);
+ LOG_ALWAYS_FATAL_IF(params->calculationWindowMillis <
+ mClientData.supportInfo.headroom
+ .cpuMinCalculationWindowMillis ||
+ params->calculationWindowMillis >
+ mClientData.supportInfo.headroom
+ .cpuMaxCalculationWindowMillis,
+ "%s: calculationWindowMillis should be in range [%d, %d] but got %d",
+ __FUNCTION__,
+ mClientData.supportInfo.headroom.cpuMinCalculationWindowMillis,
+ mClientData.supportInfo.headroom.cpuMaxCalculationWindowMillis,
+ params->calculationWindowMillis);
ret = mHintManager->getCpuHeadroom(*params, &res);
}
if (!ret.isOk()) {
@@ -106,12 +126,24 @@
}
int ASystemHealthManager::getGpuHeadroom(const AGpuHeadroomParams* params, float* outHeadroom) {
+ if (!mClientData.supportInfo.headroom.isGpuSupported) return ENOTSUP;
std::optional<hal::GpuHeadroomResult> res;
::ndk::ScopedAStatus ret;
GpuHeadroomParamsInternal internalParams;
if (!params) {
ret = mHintManager->getGpuHeadroom(internalParams, &res);
} else {
+ LOG_ALWAYS_FATAL_IF(params->calculationWindowMillis <
+ mClientData.supportInfo.headroom
+ .gpuMinCalculationWindowMillis ||
+ params->calculationWindowMillis >
+ mClientData.supportInfo.headroom
+ .gpuMaxCalculationWindowMillis,
+ "%s: calculationWindowMillis should be in range [%d, %d] but got %d",
+ __FUNCTION__,
+ mClientData.supportInfo.headroom.gpuMinCalculationWindowMillis,
+ mClientData.supportInfo.headroom.gpuMaxCalculationWindowMillis,
+ params->calculationWindowMillis);
ret = mHintManager->getGpuHeadroom(*params, &res);
}
if (!ret.isOk()) {
@@ -128,6 +160,7 @@
}
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()) {
@@ -142,6 +175,7 @@
}
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()) {
@@ -155,6 +189,57 @@
return OK;
}
+int ASystemHealthManager::getMaxCpuHeadroomTidsSize(size_t* outSize) {
+ if (!mClientData.supportInfo.headroom.isGpuSupported) return ENOTSUP;
+ *outSize = mClientData.maxCpuHeadroomThreads;
+ return OK;
+}
+
+int ASystemHealthManager::getCpuHeadroomCalculationWindowRange(int32_t* _Nonnull outMinMillis,
+ int32_t* _Nonnull outMaxMillis) {
+ if (!mClientData.supportInfo.headroom.isCpuSupported) return ENOTSUP;
+ *outMinMillis = mClientData.supportInfo.headroom.cpuMinCalculationWindowMillis;
+ *outMaxMillis = mClientData.supportInfo.headroom.cpuMaxCalculationWindowMillis;
+ return OK;
+}
+
+int ASystemHealthManager::getGpuHeadroomCalculationWindowRange(int32_t* _Nonnull outMinMillis,
+ int32_t* _Nonnull outMaxMillis) {
+ if (!mClientData.supportInfo.headroom.isGpuSupported) return ENOTSUP;
+ *outMinMillis = mClientData.supportInfo.headroom.gpuMinCalculationWindowMillis;
+ *outMaxMillis = mClientData.supportInfo.headroom.gpuMaxCalculationWindowMillis;
+ return OK;
+}
+
+int ASystemHealth_getMaxCpuHeadroomTidsSize(size_t* _Nonnull outSize) {
+ LOG_ALWAYS_FATAL_IF(outSize == nullptr, "%s: outSize should not be null", __FUNCTION__);
+ auto manager = ASystemHealthManager::getInstance();
+ if (manager == nullptr) return ENOTSUP;
+ return manager->getMaxCpuHeadroomTidsSize(outSize);
+}
+
+int ASystemHealth_getCpuHeadroomCalculationWindowRange(int32_t* _Nonnull outMinMillis,
+ int32_t* _Nonnull outMaxMillis) {
+ LOG_ALWAYS_FATAL_IF(outMinMillis == nullptr, "%s: outMinMillis should not be null",
+ __FUNCTION__);
+ LOG_ALWAYS_FATAL_IF(outMaxMillis == nullptr, "%s: outMaxMillis should not be null",
+ __FUNCTION__);
+ auto manager = ASystemHealthManager::getInstance();
+ if (manager == nullptr) return ENOTSUP;
+ return manager->getCpuHeadroomCalculationWindowRange(outMinMillis, outMaxMillis);
+}
+
+int ASystemHealth_getGpuHeadroomCalculationWindowRange(int32_t* _Nonnull outMinMillis,
+ int32_t* _Nonnull outMaxMillis) {
+ LOG_ALWAYS_FATAL_IF(outMinMillis == nullptr, "%s: outMinMillis should not be null",
+ __FUNCTION__);
+ LOG_ALWAYS_FATAL_IF(outMaxMillis == nullptr, "%s: outMaxMillis should not be null",
+ __FUNCTION__);
+ auto manager = ASystemHealthManager::getInstance();
+ if (manager == nullptr) return ENOTSUP;
+ return manager->getGpuHeadroomCalculationWindowRange(outMinMillis, outMaxMillis);
+}
+
int ASystemHealth_getCpuHeadroom(const ACpuHeadroomParams* _Nullable params,
float* _Nonnull outHeadroom) {
LOG_ALWAYS_FATAL_IF(outHeadroom == nullptr, "%s: outHeadroom should not be null", __FUNCTION__);
@@ -189,19 +274,15 @@
void ACpuHeadroomParams_setCalculationWindowMillis(ACpuHeadroomParams* _Nonnull params,
int windowMillis) {
- LOG_ALWAYS_FATAL_IF(windowMillis < CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN ||
- windowMillis > CPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX,
- "%s: windowMillis should be in range [50, 10000] but got %d", __FUNCTION__,
- windowMillis);
+ LOG_ALWAYS_FATAL_IF(windowMillis <= 0, "%s: windowMillis should be positive but got %d",
+ __FUNCTION__, windowMillis);
params->calculationWindowMillis = windowMillis;
}
void AGpuHeadroomParams_setCalculationWindowMillis(AGpuHeadroomParams* _Nonnull params,
int windowMillis) {
- LOG_ALWAYS_FATAL_IF(windowMillis < GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN ||
- windowMillis > GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX,
- "%s: windowMillis should be in range [50, 10000] but got %d", __FUNCTION__,
- windowMillis);
+ LOG_ALWAYS_FATAL_IF(windowMillis <= 0, "%s: windowMillis should be positive but got %d",
+ __FUNCTION__, windowMillis);
params->calculationWindowMillis = windowMillis;
}
@@ -214,13 +295,11 @@
}
void ACpuHeadroomParams_setTids(ACpuHeadroomParams* _Nonnull params, const int* _Nonnull tids,
- int tidsSize) {
+ size_t tidsSize) {
LOG_ALWAYS_FATAL_IF(tids == nullptr, "%s: tids should not be null", __FUNCTION__);
- LOG_ALWAYS_FATAL_IF(tidsSize > CPU_HEADROOM_MAX_TID_COUNT, "%s: tids size should not exceed 5",
- __FUNCTION__);
params->tids.resize(tidsSize);
params->tids.clear();
- for (int i = 0; i < tidsSize; ++i) {
+ for (int i = 0; i < (int)tidsSize; ++i) {
LOG_ALWAYS_FATAL_IF(tids[i] <= 0, "ACpuHeadroomParams_setTids: Invalid non-positive tid %d",
tids[i]);
params->tids[i] = tids[i];
@@ -269,10 +348,10 @@
return new AGpuHeadroomParams();
}
-void ACpuHeadroomParams_destroy(ACpuHeadroomParams* _Nonnull params) {
+void ACpuHeadroomParams_destroy(ACpuHeadroomParams* _Nullable params) {
delete params;
}
-void AGpuHeadroomParams_destroy(AGpuHeadroomParams* _Nonnull params) {
+void AGpuHeadroomParams_destroy(AGpuHeadroomParams* _Nullable params) {
delete params;
}
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index e3c10f6..7c18f2b 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -86,6 +86,9 @@
clientDataIn,
::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));
};