From ae83ac248f092bf899e675aaa4e04d2ac375e498 Mon Sep 17 00:00:00 2001 From: Matt Gilbride Date: Tue, 24 Sep 2024 22:48:38 +0000 Subject: Add `DynamicInstrumentationManagerService` Adds a new service with a single operation `getExecutableMethodFileOffsets`. The operation allows the caller to fetch information about the native executable of a given method. The operation's access control is limited to the UprobeStats module. Given a method in the form of fully qualified class name, method name, and fully qualified parameter list, the operation returns information from the ODEX file associated with that method. If the method isn't precompiled, the operation returns null. However, ART can be enhanced to support returning information about JIT compiled methods in the future. Bug: 372925025 Test: DynamicInstrumentationManagerServiceTests, ExecutableMethodFileOffsetsTest Flag: com.android.art.flags.executable_method_file_offsets Change-Id: I1f2dc3780d1bd2a682c1fd3ec41e5c8d73e96fc2 --- native/android/Android.bp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'native/android/Android.bp') diff --git a/native/android/Android.bp b/native/android/Android.bp index 3eb99c3387f7..da29c49f9d7b 100644 --- a/native/android/Android.bp +++ b/native/android/Android.bp @@ -55,6 +55,7 @@ cc_library_shared { "surface_control_input_receiver.cpp", "choreographer.cpp", "configuration.cpp", + "dynamic_instrumentation_manager.cpp", "hardware_buffer_jni.cpp", "input.cpp", "input_transfer_token.cpp", @@ -100,6 +101,7 @@ cc_library_shared { "android.hardware.configstore@1.0", "android.hardware.configstore-utils", "android.os.flags-aconfig-cc", + "dynamic_instrumentation_manager_aidl-cpp", "libnativedisplay", "libfmq", ], -- cgit v1.2.3-59-g8ed1b From 176e379d58764acd0d543ac880c9fa8bc3419aee Mon Sep 17 00:00:00 2001 From: Sally Qi Date: Mon, 4 Nov 2024 11:45:23 -0800 Subject: [Lut NDK] Define ASurfaceTransaction_setLuts API - And also ADisplayLuts, ADisplayLutsEntry struct and correspsonding NDK APIs. Bug: 377329333 Test: android.view.surfacecontrol.cts.ASurfaceControlTest#testSurfaceTransaction_setLuts_* Flag: EXEMPT NDK Change-Id: I23eaef36725a0d63ceba557811812b82b157f83e --- native/android/Android.bp | 1 + native/android/display_luts.cpp | 135 +++++++++++++++++++++++++++++++++++++ native/android/libandroid.map.txt | 10 +++ native/android/surface_control.cpp | 63 +++++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 native/android/display_luts.cpp (limited to 'native/android/Android.bp') diff --git a/native/android/Android.bp b/native/android/Android.bp index da29c49f9d7b..cd6de5a5c8f0 100644 --- a/native/android/Android.bp +++ b/native/android/Android.bp @@ -55,6 +55,7 @@ cc_library_shared { "surface_control_input_receiver.cpp", "choreographer.cpp", "configuration.cpp", + "display_luts.cpp", "dynamic_instrumentation_manager.cpp", "hardware_buffer_jni.cpp", "input.cpp", diff --git a/native/android/display_luts.cpp b/native/android/display_luts.cpp new file mode 100644 index 000000000000..179a32bd1c03 --- /dev/null +++ b/native/android/display_luts.cpp @@ -0,0 +1,135 @@ +/* + * 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 "DisplayLuts" + +#include +#include +#include + +#include + +#define ADISPLAYLUTS_BUFFER_LENGTH_LIMIT (100000) + +#define CHECK_NOT_NULL(name) \ + LOG_ALWAYS_FATAL_IF(name == nullptr, "nullptr passed as " #name " argument"); + +ADisplayLutsEntry* ADisplayLutsEntry_createEntry(float* buffer, int32_t length, int32_t dimension, + int32_t key) { + CHECK_NOT_NULL(buffer); + LOG_ALWAYS_FATAL_IF(length >= ADISPLAYLUTS_BUFFER_LENGTH_LIMIT, + "the lut raw buffer length is too big to handle"); + if (dimension != ADISPLAYLUTS_ONE_DIMENSION && dimension != ADISPLAYLUTS_THREE_DIMENSION) { + LOG_ALWAYS_FATAL("the lut dimension is be either 1 or 3"); + } + int32_t size = 0; + if (dimension == ADISPLAYLUTS_THREE_DIMENSION) { + LOG_ALWAYS_FATAL_IF(length % 3 != 0, "the 3d lut raw buffer is not divisible by 3"); + int32_t lengthPerChannel = length / 3; + float sizeForDim = std::cbrt(static_cast(lengthPerChannel)); + LOG_ALWAYS_FATAL_IF(sizeForDim != (int)(sizeForDim), + "the 3d lut buffer length is incorrect"); + size = (int)sizeForDim; + } else { + size = length; + } + LOG_ALWAYS_FATAL_IF(size < 2, "the lut size for each dimension is too small"); + + ADisplayLutsEntry* entry = new ADisplayLutsEntry(); + entry->buffer.data.resize(length); + std::copy(buffer, buffer + length, entry->buffer.data.begin()); + entry->properties = {dimension, size, key}; + + entry->incStrong((void*)ADisplayLutsEntry_createEntry); + return static_cast(entry); +} + +void ADisplayLutsEntry_destroy(ADisplayLutsEntry* entry) { + if (entry != NULL) { + entry->decStrong((void*)ADisplayLutsEntry_createEntry); + } +} + +ADisplayLuts_Dimension ADisplayLutsEntry_getDimension(const ADisplayLutsEntry* entry) { + CHECK_NOT_NULL(entry); + return static_cast(entry->properties.dimension); +} + +int32_t ADisplayLutsEntry_getSize(const ADisplayLutsEntry* entry) { + CHECK_NOT_NULL(entry); + return entry->properties.size; +} + +ADisplayLuts_SamplingKey ADisplayLutsEntry_getSamplingKey(const ADisplayLutsEntry* entry) { + CHECK_NOT_NULL(entry); + return static_cast(entry->properties.samplingKey); +} + +const float* ADisplayLutsEntry_getBuffer(const ADisplayLutsEntry* _Nonnull entry) { + CHECK_NOT_NULL(entry); + return entry->buffer.data.data(); +} + +ADisplayLuts* ADisplayLuts_create() { + ADisplayLuts* luts = new ADisplayLuts(); + if (luts == NULL) { + delete luts; + return NULL; + } + luts->incStrong((void*)ADisplayLuts_create); + return static_cast(luts); +} + +void ADisplayLuts_clearLuts(ADisplayLuts* luts) { + for (auto& entry : luts->entries) { + entry->decStrong((void*)ADisplayLuts_setEntries); // Decrement ref count + } + luts->entries.clear(); + luts->offsets.clear(); + luts->totalBufferSize = 0; +} + +void ADisplayLuts_destroy(ADisplayLuts* luts) { + if (luts != NULL) { + ADisplayLuts_clearLuts(luts); + luts->decStrong((void*)ADisplayLuts_create); + } +} + +void ADisplayLuts_setEntries(ADisplayLuts* luts, ADisplayLutsEntry** entries, int32_t numEntries) { + CHECK_NOT_NULL(luts); + // always clear the previously set lut(s) + ADisplayLuts_clearLuts(luts); + + // do nothing + if (!entries || numEntries == 0) { + return; + } + + LOG_ALWAYS_FATAL_IF(numEntries > 2, "The number of entries should be not over 2!"); + if (numEntries == 2 && entries[0]->properties.dimension != ADISPLAYLUTS_ONE_DIMENSION && + entries[1]->properties.dimension != ADISPLAYLUTS_THREE_DIMENSION) { + LOG_ALWAYS_FATAL("The entries should be 1D and 3D in order!"); + } + + luts->offsets.reserve(numEntries); + luts->entries.reserve(numEntries); + for (int32_t i = 0; i < numEntries; i++) { + luts->offsets.emplace_back(luts->totalBufferSize); + luts->totalBufferSize += entries[i]->buffer.data.size(); + luts->entries.emplace_back(entries[i]); + luts->entries.back()->incStrong((void*)ADisplayLuts_setEntries); + } +} \ No newline at end of file diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index 2d1fbf9e7f66..5dd4542c020f 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -95,6 +95,15 @@ LIBANDROID { AConfiguration_setTouchscreen; AConfiguration_setUiModeNight; AConfiguration_setUiModeType; + ADisplayLuts_create; # introduced=36 + ADisplayLuts_setEntries; # introduced=36 + ADisplayLuts_destroy; # introduced=36 + ADisplayLutsEntry_createEntry; # introduced=36 + ADisplayLutsEntry_getDimension; # introduced=36 + ADisplayLutsEntry_getSize; # introduced=36 + ADisplayLutsEntry_getSamplingKey; # introduced=36 + ADisplayLutsEntry_getBuffer; # introduced=36 + ADisplayLutsEntry_destroy; # introduced=36 AInputEvent_getDeviceId; AInputEvent_getSource; AInputEvent_getType; @@ -300,6 +309,7 @@ LIBANDROID { ASurfaceTransaction_setHdrMetadata_smpte2086; # introduced=29 ASurfaceTransaction_setExtendedRangeBrightness; # introduced=UpsideDownCake ASurfaceTransaction_setDesiredHdrHeadroom; # introduced=VanillaIceCream + ASurfaceTransaction_setLuts; # introduced=36 ASurfaceTransaction_setOnComplete; # introduced=29 ASurfaceTransaction_setOnCommit; # introduced=31 ASurfaceTransaction_setPosition; # introduced=31 diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index 698bc84a78b9..fc64e9b48f6d 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -14,12 +14,15 @@ * limitations under the License. */ +#include #include #include #include #include #include #include +#include +#include #include #include #include @@ -53,6 +56,14 @@ static_assert(static_cast(ADATASPACE_SCRGB) == static_cast(HAL_DATASPA static_assert(static_cast(ADATASPACE_DISPLAY_P3) == static_cast(HAL_DATASPACE_DISPLAY_P3)); static_assert(static_cast(ADATASPACE_BT2020_PQ) == static_cast(HAL_DATASPACE_BT2020_PQ)); +static_assert(static_cast(ADISPLAYLUTS_ONE_DIMENSION) == + static_cast(android::gui::LutProperties::Dimension::ONE_D)); +static_assert(static_cast(ADISPLAYLUTS_THREE_DIMENSION) == + static_cast(android::gui::LutProperties::Dimension::THREE_D)); +static_assert(static_cast(ADISPLAYLUTS_SAMPLINGKEY_RGB) == + static_cast(android::gui::LutProperties::SamplingKey::RGB)); +static_assert(static_cast(ADISPLAYLUTS_SAMPLINGKEY_MAX_RGB) == + static_cast(android::gui::LutProperties::SamplingKey::MAX_RGB)); Transaction* ASurfaceTransaction_to_Transaction(ASurfaceTransaction* aSurfaceTransaction) { return reinterpret_cast(aSurfaceTransaction); @@ -693,6 +704,58 @@ void ASurfaceTransaction_setDesiredHdrHeadroom(ASurfaceTransaction* aSurfaceTran transaction->setDesiredHdrHeadroom(surfaceControl, desiredRatio); } +void ASurfaceTransaction_setLuts(ASurfaceTransaction* aSurfaceTransaction, + ASurfaceControl* aSurfaceControl, + const struct ADisplayLuts* luts) { + CHECK_NOT_NULL(aSurfaceTransaction); + CHECK_NOT_NULL(aSurfaceControl); + + sp surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl); + Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction); + + int fd = -1; + std::vector offsets; + std::vector dimensions; + std::vector sizes; + std::vector samplingKeys; + + if (luts) { + std::vector buffer(luts->totalBufferSize); + int32_t count = luts->offsets.size(); + offsets = luts->offsets; + + dimensions.reserve(count); + sizes.reserve(count); + samplingKeys.reserve(count); + for (int32_t i = 0; i < count; i++) { + dimensions.emplace_back(luts->entries[i]->properties.dimension); + sizes.emplace_back(luts->entries[i]->properties.size); + samplingKeys.emplace_back(luts->entries[i]->properties.samplingKey); + std::copy(luts->entries[i]->buffer.data.begin(), luts->entries[i]->buffer.data.end(), + buffer.begin() + offsets[i]); + } + + // mmap + fd = ashmem_create_region("lut_shared_mem", luts->totalBufferSize * sizeof(float)); + if (fd < 0) { + LOG_ALWAYS_FATAL("setLuts, ashmem_create_region() failed"); + return; + } + void* ptr = mmap(nullptr, luts->totalBufferSize * sizeof(float), PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + if (ptr == MAP_FAILED) { + LOG_ALWAYS_FATAL("setLuts, Failed to map the shared memory"); + return; + } + + memcpy(ptr, buffer.data(), luts->totalBufferSize * sizeof(float)); + munmap(ptr, luts->totalBufferSize * sizeof(float)); + } + + transaction->setLuts(surfaceControl, base::unique_fd(fd), offsets, dimensions, sizes, + samplingKeys); +} + void ASurfaceTransaction_setColor(ASurfaceTransaction* aSurfaceTransaction, ASurfaceControl* aSurfaceControl, float r, float g, float b, float alpha, -- cgit v1.2.3-59-g8ed1b From 0ab9e0aa664ce5a74b4020f454af1b6e7f462ebe Mon Sep 17 00:00:00 2001 From: Xiang Wang Date: Wed, 6 Nov 2024 15:25:06 -0800 Subject: Add NDK support for CPU/GPU headroom APIs Bug: 346604998 Flag: EXEMPT ndk Test: atest NativeSystemHealthTest Change-Id: I5fd4bee8711f60f948010d96019cc0e200713e06 --- native/android/Android.bp | 1 + native/android/libandroid.map.txt | 17 +++ native/android/system_health.cpp | 278 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 296 insertions(+) create mode 100644 native/android/system_health.cpp (limited to 'native/android/Android.bp') diff --git a/native/android/Android.bp b/native/android/Android.bp index cd6de5a5c8f0..129d6163010e 100644 --- a/native/android/Android.bp +++ b/native/android/Android.bp @@ -73,6 +73,7 @@ cc_library_shared { "surface_control.cpp", "surface_texture.cpp", "system_fonts.cpp", + "system_health.cpp", "trace.cpp", "thermal.cpp", ], diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index e8644ee1a73c..4924a68ede0a 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -320,6 +320,23 @@ LIBANDROID { ASystemFontIterator_open; # introduced=29 ASystemFontIterator_close; # introduced=29 ASystemFontIterator_next; # introduced=29 + ASystemHealth_getCpuHeadroom; # introduced=36 + ASystemHealth_getGpuHeadroom; # introduced=36 + ASystemHealth_getCpuHeadroomMinIntervalMillis; # introduced=36 + ASystemHealth_getGpuHeadroomMinIntervalMillis; # introduced=36 + ACpuHeadroomParams_create; # introduced=36 + ACpuHeadroomParams_destroy; # introduced=36 + ACpuHeadroomParams_setCalculationType; # introduced=36 + ACpuHeadroomParams_getCalculationType; # introduced=36 + ACpuHeadroomParams_setCalculationWindowMillis; # introduced=36 + ACpuHeadroomParams_getCalculationWindowMillis; # introduced=36 + ACpuHeadroomParams_setTids; # introduced=36 + AGpuHeadroomParams_create; # introduced=36 + AGpuHeadroomParams_destroy; # introduced=36 + AGpuHeadroomParams_setCalculationType; # introduced=36 + AGpuHeadroomParams_getCalculationType; # introduced=36 + AGpuHeadroomParams_setCalculationWindowMillis; # introduced=36 + AGpuHeadroomParams_getCalculationWindowMillis; # introduced=36 AFont_close; # introduced=29 AFont_getFontFilePath; # introduced=29 AFont_getWeight; # introduced=29 diff --git a/native/android/system_health.cpp b/native/android/system_health.cpp new file mode 100644 index 000000000000..f3fa9f6836d5 --- /dev/null +++ b/native/android/system_health.cpp @@ -0,0 +1,278 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace android; +using namespace aidl::android::os; +namespace hal = aidl::android::hardware::power; + +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& hintManager); + 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); + +private: + static ASystemHealthManager* create(std::shared_ptr hintManager); + std::shared_ptr mHintManager; +}; + +ASystemHealthManager* ASystemHealthManager::getInstance() { + static std::once_flag creationFlag; + static ASystemHealthManager* instance = nullptr; + std::call_once(creationFlag, []() { instance = create(nullptr); }); + return instance; +} + +ASystemHealthManager::ASystemHealthManager(std::shared_ptr& hintManager) + : mHintManager(std::move(hintManager)) {} + +ASystemHealthManager::~ASystemHealthManager() {} + +ASystemHealthManager* ASystemHealthManager::create(std::shared_ptr hintManager) { + if (!hintManager) { + hintManager = IHintManager::fromBinder( + ndk::SpAIBinder(AServiceManager_waitForService("performance_hint"))); + } + if (hintManager == nullptr) { + ALOGE("%s: PerformanceHint service is not ready ", __FUNCTION__); + return nullptr; + } + return new ASystemHealthManager(hintManager); +} + +ASystemHealthManager* ASystemHealth_acquireManager() { + return ASystemHealthManager::getInstance(); +} + +int ASystemHealthManager::getCpuHeadroom(const ACpuHeadroomParams* params, float* outHeadroom) { + std::optional res; + ::ndk::ScopedAStatus ret; + CpuHeadroomParamsInternal internalParams; + if (!params) { + ret = mHintManager->getCpuHeadroom(internalParams, &res); + } else { + ret = mHintManager->getCpuHeadroom(*params, &res); + } + if (!ret.isOk()) { + LOG_ALWAYS_FATAL_IF(ret.getExceptionCode() == EX_ILLEGAL_ARGUMENT, + "Invalid ACpuHeadroomParams: %s", ret.getMessage()); + ALOGE("ASystemHealth_getCpuHeadroom fails: %s", ret.getMessage()); + if (ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION) { + return ENOTSUP; + } else if (ret.getExceptionCode() == EX_SECURITY) { + return EPERM; + } + return EPIPE; + } + *outHeadroom = res->get(); + return OK; +} + +int ASystemHealthManager::getGpuHeadroom(const AGpuHeadroomParams* params, float* outHeadroom) { + std::optional res; + ::ndk::ScopedAStatus ret; + GpuHeadroomParamsInternal internalParams; + if (!params) { + ret = mHintManager->getGpuHeadroom(internalParams, &res); + } else { + ret = mHintManager->getGpuHeadroom(*params, &res); + } + if (!ret.isOk()) { + LOG_ALWAYS_FATAL_IF(ret.getExceptionCode() == EX_ILLEGAL_ARGUMENT, + "Invalid AGpuHeadroomParams: %s", ret.getMessage()); + ALOGE("ASystemHealth_getGpuHeadroom fails: %s", ret.getMessage()); + if (ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION) { + return ENOTSUP; + } + return EPIPE; + } + *outHeadroom = res->get(); + return OK; +} + +int ASystemHealthManager::getCpuHeadroomMinIntervalMillis(int64_t* outMinIntervalMillis) { + 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; + return OK; +} + +int ASystemHealthManager::getGpuHeadroomMinIntervalMillis(int64_t* outMinIntervalMillis) { + 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; + return OK; +} + +int ASystemHealth_getCpuHeadroom(const ACpuHeadroomParams* _Nullable params, + float* _Nonnull outHeadroom) { + LOG_ALWAYS_FATAL_IF(outHeadroom == nullptr, "%s: outHeadroom should not be null", __FUNCTION__); + auto manager = ASystemHealthManager::getInstance(); + if (manager == nullptr) return ENOTSUP; + return manager->getCpuHeadroom(params, outHeadroom); +} + +int ASystemHealth_getGpuHeadroom(const AGpuHeadroomParams* _Nullable params, + float* _Nonnull outHeadroom) { + LOG_ALWAYS_FATAL_IF(outHeadroom == nullptr, "%s: outHeadroom should not be null", __FUNCTION__); + auto manager = ASystemHealthManager::getInstance(); + if (manager == nullptr) return ENOTSUP; + return manager->getGpuHeadroom(params, outHeadroom); +} + +int ASystemHealth_getCpuHeadroomMinIntervalMillis(int64_t* _Nonnull outMinIntervalMillis) { + LOG_ALWAYS_FATAL_IF(outMinIntervalMillis == nullptr, + "%s: outMinIntervalMillis should not be null", __FUNCTION__); + auto manager = ASystemHealthManager::getInstance(); + if (manager == nullptr) return ENOTSUP; + return manager->getCpuHeadroomMinIntervalMillis(outMinIntervalMillis); +} + +int ASystemHealth_getGpuHeadroomMinIntervalMillis(int64_t* _Nonnull outMinIntervalMillis) { + LOG_ALWAYS_FATAL_IF(outMinIntervalMillis == nullptr, + "%s: outMinIntervalMillis should not be null", __FUNCTION__); + auto manager = ASystemHealthManager::getInstance(); + if (manager == nullptr) return ENOTSUP; + return manager->getGpuHeadroomMinIntervalMillis(outMinIntervalMillis); +} + +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); + 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); + params->calculationWindowMillis = windowMillis; +} + +int ACpuHeadroomParams_getCalculationWindowMillis(ACpuHeadroomParams* _Nonnull params) { + return params->calculationWindowMillis; +} + +int AGpuHeadroomParams_getCalculationWindowMillis(AGpuHeadroomParams* _Nonnull params) { + return params->calculationWindowMillis; +} + +void ACpuHeadroomParams_setTids(ACpuHeadroomParams* _Nonnull params, const int* _Nonnull tids, + int 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) { + LOG_ALWAYS_FATAL_IF(tids[i] <= 0, "ACpuHeadroomParams_setTids: Invalid non-positive tid %d", + tids[i]); + params->tids[i] = tids[i]; + } +} + +void ACpuHeadroomParams_setCalculationType(ACpuHeadroomParams* _Nonnull params, + ACpuHeadroomCalculationType calculationType) { + LOG_ALWAYS_FATAL_IF(calculationType < ACpuHeadroomCalculationType:: + ACPU_HEADROOM_CALCULATION_TYPE_MIN || + calculationType > ACpuHeadroomCalculationType:: + ACPU_HEADROOM_CALCULATION_TYPE_AVERAGE, + "%s: calculationType should be one of ACpuHeadroomCalculationType values " + "but got %d", + __FUNCTION__, calculationType); + params->calculationType = static_cast(calculationType); +} + +ACpuHeadroomCalculationType ACpuHeadroomParams_getCalculationType( + ACpuHeadroomParams* _Nonnull params) { + return static_cast(params->calculationType); +} + +void AGpuHeadroomParams_setCalculationType(AGpuHeadroomParams* _Nonnull params, + AGpuHeadroomCalculationType calculationType) { + LOG_ALWAYS_FATAL_IF(calculationType < AGpuHeadroomCalculationType:: + AGPU_HEADROOM_CALCULATION_TYPE_MIN || + calculationType > AGpuHeadroomCalculationType:: + AGPU_HEADROOM_CALCULATION_TYPE_AVERAGE, + "%s: calculationType should be one of AGpuHeadroomCalculationType values " + "but got %d", + __FUNCTION__, calculationType); + params->calculationType = static_cast(calculationType); +} + +AGpuHeadroomCalculationType AGpuHeadroomParams_getCalculationType( + AGpuHeadroomParams* _Nonnull params) { + return static_cast(params->calculationType); +} + +ACpuHeadroomParams* _Nonnull ACpuHeadroomParams_create() { + return new ACpuHeadroomParams(); +} + +AGpuHeadroomParams* _Nonnull AGpuHeadroomParams_create() { + return new AGpuHeadroomParams(); +} + +void ACpuHeadroomParams_destroy(ACpuHeadroomParams* _Nonnull params) { + delete params; +} + +void AGpuHeadroomParams_destroy(AGpuHeadroomParams* _Nonnull params) { + delete params; +} -- cgit v1.2.3-59-g8ed1b