Update performance_hint to follow NDK API guidance
This patch updates the performance_hint NDK in response to API guidance,
and updates the tests accordingly.
Additionally, this patch updates the documentation and ergonomics of a
few related methods to better accomodate these changes, and to downgrade
going over the graphics pipeline limit from a breakage to a very severe
warning.
Flag: EXEMPT NDK
Test: atest
cts/tests/tests/os/src/android/os/cts/PerformanceHintManagerTest.java
Test: atest PerformanceHintNativeTestCases
Test: atest HintManagerServiceTest
Bug: 380299912
Bug: 381269529
Change-Id: I31f1c1db4ee4846a8aca63243f61ac1672aac309
diff --git a/core/java/android/os/IHintManager.aidl b/core/java/android/os/IHintManager.aidl
index 56a089a..5128e91 100644
--- a/core/java/android/os/IHintManager.aidl
+++ b/core/java/android/os/IHintManager.aidl
@@ -39,12 +39,18 @@
* Throws UnsupportedOperationException if ADPF is not supported, and IllegalStateException
* if creation is supported but fails.
*/
- IHintSession createHintSessionWithConfig(in IBinder token, in SessionTag tag,
+ SessionCreationReturn createHintSessionWithConfig(in IBinder token, in SessionTag tag,
in SessionCreationConfig creationConfig, out SessionConfig config);
void setHintSessionThreads(in IHintSession hintSession, in int[] tids);
int[] getHintSessionThreadIds(in IHintSession hintSession);
+ parcelable SessionCreationReturn {
+ IHintSession session;
+ // True if the graphics pipeline thread limit is being exceeded
+ boolean pipelineThreadLimitExceeded = false;
+ }
+
/**
* Returns FMQ channel information for the caller, which it associates to a binder token.
*
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 1ccadf9..f629c88 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -396,6 +396,7 @@
APerformanceHint_notifyWorkloadSpike; # introduced=36
APerformanceHint_borrowSessionFromJava; # introduced=36
APerformanceHint_setNativeSurfaces; # introduced=36
+ APerformanceHint_isFeatureSupported; # introduced=36
AWorkDuration_create; # introduced=VanillaIceCream
AWorkDuration_release; # introduced=VanillaIceCream
AWorkDuration_setWorkPeriodStartTimestampNanos; # introduced=VanillaIceCream
@@ -419,7 +420,6 @@
AThermal_setIThermalServiceForTesting;
APerformanceHint_setIHintManagerForTesting;
APerformanceHint_sendHint;
- APerformanceHint_setUseGraphicsPipelineForTesting;
APerformanceHint_getThreadIds;
APerformanceHint_createSessionInternal;
APerformanceHint_createSessionUsingConfigInternal;
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 9257901..7e65523 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -71,26 +71,31 @@
struct APerformanceHintSession;
-constexpr int64_t SEND_HINT_TIMEOUT = std::chrono::nanoseconds(100ms).count();
struct AWorkDuration : public hal::WorkDuration {};
struct ASessionCreationConfig : public SessionCreationConfig {
std::vector<wp<IBinder>> layers{};
- bool hasMode(hal::SessionMode&& mode) {
+ bool hasMode(hal::SessionMode mode) {
return std::find(modesToEnable.begin(), modesToEnable.end(), mode) != modesToEnable.end();
}
+ void setMode(hal::SessionMode mode, bool enabled) {
+ if (hasMode(mode)) {
+ if (!enabled) {
+ std::erase(modesToEnable, mode);
+ }
+ } else if (enabled) {
+ modesToEnable.push_back(mode);
+ }
+ }
};
-bool kForceGraphicsPipeline = false;
-
-bool useGraphicsPipeline() {
- return android::os::adpf_graphics_pipeline() || kForceGraphicsPipeline;
-}
-
// A pair of values that determine the behavior of the
// load hint rate limiter, to only allow "X hints every Y seconds"
-constexpr double kLoadHintInterval = std::chrono::nanoseconds(2s).count();
+constexpr int64_t kLoadHintInterval = std::chrono::nanoseconds(2s).count();
constexpr double kMaxLoadHintsPerInterval = 20;
-constexpr double kReplenishRate = kMaxLoadHintsPerInterval / kLoadHintInterval;
+// Replenish rate is used for new rate limiting behavior, it currently replenishes at a rate of
+// 20 / 2s = 1 per 100us, which is the same limit as before, just enforced differently
+constexpr double kReplenishRate = kMaxLoadHintsPerInterval / static_cast<double>(kLoadHintInterval);
+constexpr int64_t kSendHintTimeout = kLoadHintInterval / kMaxLoadHintsPerInterval;
bool kForceNewHintBehavior = false;
template <class T>
@@ -149,9 +154,7 @@
std::future<bool> mChannelCreationFinished;
};
-class SupportInfoWrapper {
-public:
- SupportInfoWrapper(hal::SupportInfo& info);
+struct SupportInfoWrapper : public hal::SupportInfo {
bool isSessionModeSupported(hal::SessionMode mode);
bool isSessionHintSupported(hal::SessionHint hint);
@@ -162,7 +165,6 @@
// over that much and cutting off any extra values
return (supportBitfield >> static_cast<int>(enumValue)) % 2;
}
- hal::SupportInfo mSupportInfo;
};
class HintManagerClient : public IHintManager::BnHintManagerClient {
@@ -188,9 +190,9 @@
bool isJava = false);
APerformanceHintSession* getSessionFromJava(JNIEnv* _Nonnull env, jobject _Nonnull sessionObj);
- APerformanceHintSession* createSessionUsingConfig(ASessionCreationConfig* sessionCreationConfig,
- hal::SessionTag tag = hal::SessionTag::APP,
- bool isJava = false);
+ int createSessionUsingConfig(ASessionCreationConfig* sessionCreationConfig,
+ APerformanceHintSession** sessionPtr,
+ hal::SessionTag tag = hal::SessionTag::APP, bool isJava = false);
int64_t getPreferredRateNanos() const;
int32_t getMaxGraphicsPipelineThreadsCount();
FMQWrapper& getFMQWrapper();
@@ -202,6 +204,7 @@
std::vector<T>& out);
ndk::SpAIBinder& getToken();
SupportInfoWrapper& getSupportInfo();
+ bool isFeatureSupported(APerformanceHintFeature feature);
private:
static APerformanceHintManager* create(std::shared_ptr<IHintManager> iHintManager);
@@ -239,8 +242,8 @@
int setPreferPowerEfficiency(bool enabled);
int reportActualWorkDuration(AWorkDuration* workDuration);
bool isJava();
- status_t setNativeSurfaces(ANativeWindow** windows, int numWindows, ASurfaceControl** controls,
- int numSurfaceControls);
+ status_t setNativeSurfaces(ANativeWindow** windows, size_t numWindows,
+ ASurfaceControl** controls, size_t numSurfaceControls);
private:
friend struct APerformanceHintManager;
@@ -294,14 +297,12 @@
// ===================================== SupportInfoWrapper implementation
-SupportInfoWrapper::SupportInfoWrapper(hal::SupportInfo& info) : mSupportInfo(info) {}
-
bool SupportInfoWrapper::isSessionHintSupported(hal::SessionHint hint) {
- return getEnumSupportFromBitfield(hint, mSupportInfo.sessionHints);
+ return getEnumSupportFromBitfield(hint, sessionHints);
}
bool SupportInfoWrapper::isSessionModeSupported(hal::SessionMode mode) {
- return getEnumSupportFromBitfield(mode, mSupportInfo.sessionModes);
+ return getEnumSupportFromBitfield(mode, sessionModes);
}
// ===================================== APerformanceHintManager implementation
@@ -386,12 +387,14 @@
.targetWorkDurationNanos = initialTargetWorkDurationNanos,
}};
- return APerformanceHintManager::createSessionUsingConfig(&creationConfig, tag, isJava);
+ APerformanceHintSession* sessionOut;
+ APerformanceHintManager::createSessionUsingConfig(&creationConfig, &sessionOut, tag, isJava);
+ return sessionOut;
}
-APerformanceHintSession* APerformanceHintManager::createSessionUsingConfig(
- ASessionCreationConfig* sessionCreationConfig, hal::SessionTag tag, bool isJava) {
- std::shared_ptr<IHintSession> session;
+int APerformanceHintManager::createSessionUsingConfig(ASessionCreationConfig* sessionCreationConfig,
+ APerformanceHintSession** sessionOut,
+ hal::SessionTag tag, bool isJava) {
hal::SessionConfig sessionConfig{.id = -1};
ndk::ScopedAStatus ret;
@@ -411,31 +414,65 @@
}
}
+ bool autoCpu = sessionCreationConfig->hasMode(hal::SessionMode::AUTO_CPU);
+ bool autoGpu = sessionCreationConfig->hasMode(hal::SessionMode::AUTO_GPU);
+
+ if (autoCpu || autoGpu) {
+ LOG_ALWAYS_FATAL_IF(!sessionCreationConfig->hasMode(hal::SessionMode::GRAPHICS_PIPELINE),
+ "Automatic session timing enabled without graphics pipeline mode");
+ }
+
+ if (autoCpu && !mSupportInfoWrapper.isSessionModeSupported(hal::SessionMode::AUTO_CPU)) {
+ ALOGE("Automatic CPU timing enabled but not supported");
+ return ENOTSUP;
+ }
+
+ if (autoGpu && !mSupportInfoWrapper.isSessionModeSupported(hal::SessionMode::AUTO_GPU)) {
+ ALOGE("Automatic GPU timing enabled but not supported");
+ return ENOTSUP;
+ }
+
+ IHintManager::SessionCreationReturn returnValue;
ret = mHintManager->createHintSessionWithConfig(mToken, tag,
*static_cast<SessionCreationConfig*>(
sessionCreationConfig),
- &sessionConfig, &session);
+ &sessionConfig, &returnValue);
sessionCreationConfig->layerTokens.clear();
- if (!ret.isOk() || !session) {
+ if (!ret.isOk() || !returnValue.session) {
ALOGE("%s: PerformanceHint cannot create session. %s", __FUNCTION__, ret.getMessage());
- return nullptr;
+ switch (ret.getExceptionCode()) {
+ case binder::Status::EX_UNSUPPORTED_OPERATION:
+ return ENOTSUP;
+ case binder::Status::EX_ILLEGAL_ARGUMENT:
+ return EINVAL;
+ default:
+ return EPIPE;
+ }
}
- auto out = new APerformanceHintSession(mHintManager, std::move(session),
+ auto out = new APerformanceHintSession(mHintManager, std::move(returnValue.session),
mClientData.preferredRateNanos,
sessionCreationConfig->targetWorkDurationNanos, isJava,
sessionConfig.id == -1
? std::nullopt
: std::make_optional<hal::SessionConfig>(
std::move(sessionConfig)));
+
+ *sessionOut = out;
+
std::scoped_lock lock(sHintMutex);
out->traceThreads(sessionCreationConfig->tids);
out->traceTargetDuration(sessionCreationConfig->targetWorkDurationNanos);
out->traceModes(sessionCreationConfig->modesToEnable);
- return out;
+ if (returnValue.pipelineThreadLimitExceeded) {
+ ALOGE("Graphics pipeline session thread limit exceeded!");
+ return EBUSY;
+ }
+
+ return 0;
}
APerformanceHintSession* APerformanceHintManager::getSessionFromJava(JNIEnv* env,
@@ -480,6 +517,25 @@
return mSupportInfoWrapper;
}
+bool APerformanceHintManager::isFeatureSupported(APerformanceHintFeature feature) {
+ switch (feature) {
+ case (APERF_HINT_SESSIONS):
+ return mSupportInfoWrapper.usesSessions;
+ case (APERF_HINT_POWER_EFFICIENCY):
+ return mSupportInfoWrapper.isSessionModeSupported(hal::SessionMode::POWER_EFFICIENCY);
+ case (APERF_HINT_SURFACE_BINDING):
+ return mSupportInfoWrapper.compositionData.isSupported;
+ case (APERF_HINT_GRAPHICS_PIPELINE):
+ return mSupportInfoWrapper.isSessionModeSupported(hal::SessionMode::GRAPHICS_PIPELINE);
+ case (APERF_HINT_AUTO_CPU):
+ return mSupportInfoWrapper.isSessionModeSupported(hal::SessionMode::AUTO_CPU);
+ case (APERF_HINT_AUTO_GPU):
+ return mSupportInfoWrapper.isSessionModeSupported(hal::SessionMode::AUTO_GPU);
+ default:
+ return false;
+ }
+}
+
// ===================================== APerformanceHintSession implementation
constexpr int kNumEnums = enum_size<hal::SessionHint>();
@@ -512,10 +568,6 @@
}
int APerformanceHintSession::updateTargetWorkDuration(int64_t targetDurationNanos) {
- if (targetDurationNanos <= 0) {
- ALOGE("%s: targetDurationNanos must be positive", __FUNCTION__);
- return EINVAL;
- }
std::scoped_lock lock(sHintMutex);
if (mTargetDurationNanos == targetDurationNanos) {
return 0;
@@ -546,7 +598,6 @@
.workPeriodStartTimestampNanos = 0,
.cpuDurationNanos = actualDurationNanos,
.gpuDurationNanos = 0};
-
return reportActualWorkDurationInternal(static_cast<AWorkDuration*>(&workDuration));
}
@@ -556,17 +607,24 @@
int APerformanceHintSession::sendHints(std::vector<hal::SessionHint>& hints, int64_t now,
const char*) {
- std::scoped_lock lock(sHintMutex);
+ auto& supportInfo = APerformanceHintManager::getInstance()->getSupportInfo();
+
+ // Drop all unsupported hints, there's not much point reporting errors or warnings for this
+ std::erase_if(hints,
+ [&](hal::SessionHint hint) { return !supportInfo.isSessionHintSupported(hint); });
+
if (hints.empty()) {
- return EINVAL;
- }
- for (auto&& hint : hints) {
- if (static_cast<int32_t>(hint) < 0 || static_cast<int32_t>(hint) >= kNumEnums) {
- ALOGE("%s: invalid session hint %d", __FUNCTION__, hint);
- return EINVAL;
- }
+ // We successfully sent all hints we were able to, technically
+ return 0;
}
+ for (auto&& hint : hints) {
+ LOG_ALWAYS_FATAL_IF(static_cast<int32_t>(hint) < 0 ||
+ static_cast<int32_t>(hint) >= kNumEnums,
+ "%s: invalid session hint %d", __FUNCTION__, hint);
+ }
+
+ std::scoped_lock lock(sHintMutex);
if (useNewLoadHintBehavior()) {
if (!APerformanceHintManager::getInstance()->canSendLoadHints(hints, now)) {
return EBUSY;
@@ -575,7 +633,7 @@
// keep old rate limiter behavior for legacy flag
else {
for (auto&& hint : hints) {
- if (now < (mLastHintSentTimestamp[static_cast<int32_t>(hint)] + SEND_HINT_TIMEOUT)) {
+ if (now < (mLastHintSentTimestamp[static_cast<int32_t>(hint)] + kSendHintTimeout)) {
return EBUSY;
}
}
@@ -651,7 +709,9 @@
}
std::vector<int32_t> tids(threadIds, threadIds + size);
ndk::ScopedAStatus ret = mHintManager->setHintSessionThreads(mHintSession, tids);
- if (!ret.isOk()) {
+
+ // Illegal state means there were too many graphics pipeline threads
+ if (!ret.isOk() && ret.getExceptionCode() != EX_SERVICE_SPECIFIC) {
ALOGE("%s: failed: %s", __FUNCTION__, ret.getMessage());
if (ret.getExceptionCode() == EX_ILLEGAL_ARGUMENT) {
return EINVAL;
@@ -663,8 +723,10 @@
std::scoped_lock lock(sHintMutex);
traceThreads(tids);
+ bool tooManyThreads =
+ ret.getExceptionCode() == EX_SERVICE_SPECIFIC && ret.getServiceSpecificError() == 5;
- return 0;
+ return tooManyThreads ? EBUSY : 0;
}
int APerformanceHintSession::getThreadIds(int32_t* const threadIds, size_t* size) {
@@ -711,10 +773,16 @@
int APerformanceHintSession::reportActualWorkDurationInternal(AWorkDuration* workDuration) {
int64_t actualTotalDurationNanos = workDuration->durationNanos;
- traceActualDuration(workDuration->durationNanos);
int64_t now = uptimeNanos();
workDuration->timeStampNanos = now;
std::scoped_lock lock(sHintMutex);
+
+ if (mTargetDurationNanos <= 0) {
+ ALOGE("Cannot report work durations if the target duration is not positive.");
+ return EINVAL;
+ }
+
+ traceActualDuration(actualTotalDurationNanos);
mActualWorkDurations.push_back(std::move(*workDuration));
if (actualTotalDurationNanos >= mTargetDurationNanos) {
@@ -757,9 +825,9 @@
return 0;
}
-status_t APerformanceHintSession::setNativeSurfaces(ANativeWindow** windows, int numWindows,
+status_t APerformanceHintSession::setNativeSurfaces(ANativeWindow** windows, size_t numWindows,
ASurfaceControl** controls,
- int numSurfaceControls) {
+ size_t numSurfaceControls) {
if (!mSessionConfig.has_value()) {
return ENOTSUP;
}
@@ -774,7 +842,10 @@
ndkLayerHandles.emplace_back(ndk::SpAIBinder(AIBinder_fromPlatformBinder(handle)));
}
- mHintSession->associateToLayers(ndkLayerHandles);
+ auto ret = mHintSession->associateToLayers(ndkLayerHandles);
+ if (!ret.isOk()) {
+ return EPIPE;
+ }
return 0;
}
@@ -857,6 +928,11 @@
}
return true;
});
+
+ // If we're unit testing the FMQ, we should block for it to finish completing
+ if (gForceFMQEnabled.has_value()) {
+ mChannelCreationFinished.wait();
+ }
}
return isActive();
}
@@ -1029,7 +1105,8 @@
ATrace_setCounter((mSessionName + " target duration").c_str(), targetDuration);
}
-// ===================================== C API
+// ===================================== Start of C API
+
APerformanceHintManager* APerformanceHint_getManager() {
return APerformanceHintManager::getInstance();
}
@@ -1037,10 +1114,16 @@
#define VALIDATE_PTR(ptr) \
LOG_ALWAYS_FATAL_IF(ptr == nullptr, "%s: " #ptr " is nullptr", __FUNCTION__);
+#define HARD_VALIDATE_INT(value, cmp) \
+ LOG_ALWAYS_FATAL_IF(!(value cmp), \
+ "%s: Invalid value. Check failed: (" #value " " #cmp \
+ ") with value: %" PRIi64, \
+ __FUNCTION__, static_cast<int64_t>(value));
+
#define VALIDATE_INT(value, cmp) \
if (!(value cmp)) { \
ALOGE("%s: Invalid value. Check failed: (" #value " " #cmp ") with value: %" PRIi64, \
- __FUNCTION__, value); \
+ __FUNCTION__, static_cast<int64_t>(value)); \
return EINVAL; \
}
@@ -1058,19 +1141,27 @@
return manager->createSession(threadIds, size, initialTargetWorkDurationNanos);
}
-APerformanceHintSession* APerformanceHint_createSessionUsingConfig(
- APerformanceHintManager* manager, ASessionCreationConfig* sessionCreationConfig) {
+int APerformanceHint_createSessionUsingConfig(APerformanceHintManager* manager,
+ ASessionCreationConfig* sessionCreationConfig,
+ APerformanceHintSession** sessionOut) {
VALIDATE_PTR(manager);
VALIDATE_PTR(sessionCreationConfig);
- return manager->createSessionUsingConfig(sessionCreationConfig);
+ VALIDATE_PTR(sessionOut);
+ *sessionOut = nullptr;
+
+ return manager->createSessionUsingConfig(sessionCreationConfig, sessionOut);
}
-APerformanceHintSession* APerformanceHint_createSessionUsingConfigInternal(
- APerformanceHintManager* manager, ASessionCreationConfig* sessionCreationConfig,
- SessionTag tag) {
+int APerformanceHint_createSessionUsingConfigInternal(APerformanceHintManager* manager,
+ ASessionCreationConfig* sessionCreationConfig,
+ APerformanceHintSession** sessionOut,
+ SessionTag tag) {
VALIDATE_PTR(manager);
VALIDATE_PTR(sessionCreationConfig);
- return manager->createSessionUsingConfig(sessionCreationConfig,
+ VALIDATE_PTR(sessionOut);
+ *sessionOut = nullptr;
+
+ return manager->createSessionUsingConfig(sessionCreationConfig, sessionOut,
static_cast<hal::SessionTag>(tag));
}
@@ -1111,6 +1202,7 @@
int APerformanceHint_updateTargetWorkDuration(APerformanceHintSession* session,
int64_t targetDurationNanos) {
VALIDATE_PTR(session)
+ VALIDATE_INT(targetDurationNanos, >= 0)
return session->updateTargetWorkDuration(targetDurationNanos);
}
@@ -1204,13 +1296,23 @@
}
int APerformanceHint_setNativeSurfaces(APerformanceHintSession* session,
- ANativeWindow** nativeWindows, int nativeWindowsSize,
- ASurfaceControl** surfaceControls, int surfaceControlsSize) {
+ ANativeWindow** nativeWindows, size_t nativeWindowsSize,
+ ASurfaceControl** surfaceControls,
+ size_t surfaceControlsSize) {
VALIDATE_PTR(session)
return session->setNativeSurfaces(nativeWindows, nativeWindowsSize, surfaceControls,
surfaceControlsSize);
}
+bool APerformanceHint_isFeatureSupported(APerformanceHintFeature feature) {
+ APerformanceHintManager* manager = APerformanceHintManager::getInstance();
+ if (manager == nullptr) {
+ // Clearly whatever it is isn't supported in this case
+ return false;
+ }
+ return manager->isFeatureSupported(feature);
+}
+
AWorkDuration* AWorkDuration_create() {
return new AWorkDuration();
}
@@ -1265,78 +1367,32 @@
void ASessionCreationConfig_release(ASessionCreationConfig* config) {
VALIDATE_PTR(config)
-
delete config;
}
-int ASessionCreationConfig_setTids(ASessionCreationConfig* config, const pid_t* tids, size_t size) {
+void ASessionCreationConfig_setTids(ASessionCreationConfig* config, const pid_t* tids,
+ size_t size) {
VALIDATE_PTR(config)
VALIDATE_PTR(tids)
+ HARD_VALIDATE_INT(size, > 0)
- if (!useGraphicsPipeline()) {
- return ENOTSUP;
- }
-
- if (size <= 0) {
- LOG_ALWAYS_FATAL_IF(size <= 0,
- "%s: Invalid value. Thread id list size should be greater than zero.",
- __FUNCTION__);
- return EINVAL;
- }
config->tids = std::vector<int32_t>(tids, tids + size);
- return 0;
}
-int ASessionCreationConfig_setTargetWorkDurationNanos(ASessionCreationConfig* config,
- int64_t targetWorkDurationNanos) {
+void ASessionCreationConfig_setTargetWorkDurationNanos(ASessionCreationConfig* config,
+ int64_t targetWorkDurationNanos) {
VALIDATE_PTR(config)
- VALIDATE_INT(targetWorkDurationNanos, >= 0)
-
- if (!useGraphicsPipeline()) {
- return ENOTSUP;
- }
-
config->targetWorkDurationNanos = targetWorkDurationNanos;
- return 0;
}
-int ASessionCreationConfig_setPreferPowerEfficiency(ASessionCreationConfig* config, bool enabled) {
+void ASessionCreationConfig_setPreferPowerEfficiency(ASessionCreationConfig* config, bool enabled) {
VALIDATE_PTR(config)
-
- if (!useGraphicsPipeline()) {
- return ENOTSUP;
- }
-
- if (enabled) {
- config->modesToEnable.push_back(hal::SessionMode::POWER_EFFICIENCY);
- } else {
- std::erase(config->modesToEnable, hal::SessionMode::POWER_EFFICIENCY);
- }
- return 0;
+ config->setMode(hal::SessionMode::POWER_EFFICIENCY, enabled);
}
-int ASessionCreationConfig_setGraphicsPipeline(ASessionCreationConfig* config, bool enabled) {
+void ASessionCreationConfig_setGraphicsPipeline(ASessionCreationConfig* config, bool enabled) {
VALIDATE_PTR(config)
-
- if (!useGraphicsPipeline()) {
- return ENOTSUP;
- }
-
- if (enabled) {
- config->modesToEnable.push_back(hal::SessionMode::GRAPHICS_PIPELINE);
- } else {
- std::erase(config->modesToEnable, hal::SessionMode::GRAPHICS_PIPELINE);
-
- // Remove automatic timing modes if we turn off GRAPHICS_PIPELINE,
- // as it is a strict pre-requisite for these to run
- std::erase(config->modesToEnable, hal::SessionMode::AUTO_CPU);
- std::erase(config->modesToEnable, hal::SessionMode::AUTO_GPU);
- }
- return 0;
-}
-
-void APerformanceHint_setUseGraphicsPipelineForTesting(bool enabled) {
- kForceGraphicsPipeline = enabled;
+ config->setMode(hal::SessionMode::GRAPHICS_PIPELINE, enabled);
}
void APerformanceHint_getRateLimiterPropertiesForTesting(int32_t* maxLoadHintsPerInterval,
@@ -1349,47 +1405,21 @@
kForceNewHintBehavior = newBehavior;
}
-int ASessionCreationConfig_setNativeSurfaces(ASessionCreationConfig* config,
- ANativeWindow** nativeWindows, int nativeWindowsSize,
- ASurfaceControl** surfaceControls,
- int surfaceControlsSize) {
+void ASessionCreationConfig_setNativeSurfaces(ASessionCreationConfig* config,
+ ANativeWindow** nativeWindows,
+ size_t nativeWindowsSize,
+ ASurfaceControl** surfaceControls,
+ size_t surfaceControlsSize) {
VALIDATE_PTR(config)
-
APerformanceHintManager::layersFromNativeSurfaces<wp<IBinder>>(nativeWindows, nativeWindowsSize,
surfaceControls,
surfaceControlsSize,
config->layers);
-
- if (config->layers.empty()) {
- return EINVAL;
- }
-
- return 0;
}
-int ASessionCreationConfig_setUseAutoTiming(ASessionCreationConfig* _Nonnull config, bool cpu,
- bool gpu) {
+void ASessionCreationConfig_setUseAutoTiming(ASessionCreationConfig* _Nonnull config, bool cpu,
+ bool gpu) {
VALIDATE_PTR(config)
- if ((cpu || gpu) && !config->hasMode(hal::SessionMode::GRAPHICS_PIPELINE)) {
- ALOGE("Automatic timing is not supported unless graphics pipeline mode is enabled first");
- return ENOTSUP;
- }
-
- if (config->hasMode(hal::SessionMode::AUTO_CPU)) {
- if (!cpu) {
- std::erase(config->modesToEnable, hal::SessionMode::AUTO_CPU);
- }
- } else if (cpu) {
- config->modesToEnable.push_back(static_cast<hal::SessionMode>(hal::SessionMode::AUTO_CPU));
- }
-
- if (config->hasMode(hal::SessionMode::AUTO_GPU)) {
- if (!gpu) {
- std::erase(config->modesToEnable, hal::SessionMode::AUTO_GPU);
- }
- } else if (gpu) {
- config->modesToEnable.push_back(static_cast<hal::SessionMode>(hal::SessionMode::AUTO_GPU));
- }
-
- return 0;
+ config->setMode(hal::SessionMode::AUTO_CPU, cpu);
+ config->setMode(hal::SessionMode::AUTO_GPU, gpu);
}
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index e3c10f6..f68fa1a 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -49,12 +49,87 @@
using namespace android;
using namespace testing;
+constexpr int64_t DEFAULT_TARGET_NS = 16666666L;
+
+template <class T, void (*D)(T*)>
+std::shared_ptr<T> wrapSP(T* incoming) {
+ return incoming == nullptr ? nullptr : std::shared_ptr<T>(incoming, [](T* ptr) { D(ptr); });
+}
+constexpr auto&& wrapSession = wrapSP<APerformanceHintSession, APerformanceHint_closeSession>;
+constexpr auto&& wrapConfig = wrapSP<ASessionCreationConfig, ASessionCreationConfig_release>;
+constexpr auto&& wrapWorkDuration = wrapSP<AWorkDuration, AWorkDuration_release>;
+
+std::shared_ptr<ASessionCreationConfig> createConfig() {
+ return wrapConfig(ASessionCreationConfig_create());
+}
+
+struct ConfigCreator {
+ std::vector<int32_t> tids{1, 2};
+ int64_t targetDuration = DEFAULT_TARGET_NS;
+ bool powerEfficient = false;
+ bool graphicsPipeline = false;
+ std::vector<ANativeWindow*> nativeWindows{};
+ std::vector<ASurfaceControl*> surfaceControls{};
+ bool autoCpu = false;
+ bool autoGpu = false;
+};
+
+struct SupportHelper {
+ bool hintSessions : 1;
+ bool powerEfficiency : 1;
+ bool bindToSurface : 1;
+ bool graphicsPipeline : 1;
+ bool autoCpu : 1;
+ bool autoGpu : 1;
+};
+
+SupportHelper getSupportHelper() {
+ return {
+ .hintSessions = APerformanceHint_isFeatureSupported(APERF_HINT_SESSIONS),
+ .powerEfficiency = APerformanceHint_isFeatureSupported(APERF_HINT_POWER_EFFICIENCY),
+ .bindToSurface = APerformanceHint_isFeatureSupported(APERF_HINT_SURFACE_BINDING),
+ .graphicsPipeline = APerformanceHint_isFeatureSupported(APERF_HINT_GRAPHICS_PIPELINE),
+ .autoCpu = APerformanceHint_isFeatureSupported(APERF_HINT_AUTO_CPU),
+ .autoGpu = APerformanceHint_isFeatureSupported(APERF_HINT_AUTO_GPU),
+ };
+}
+
+SupportHelper getFullySupportedSupportHelper() {
+ return {
+ .hintSessions = true,
+ .powerEfficiency = true,
+ .graphicsPipeline = true,
+ .autoCpu = true,
+ .autoGpu = true,
+ };
+}
+
+std::shared_ptr<ASessionCreationConfig> configFromCreator(ConfigCreator&& creator) {
+ auto config = createConfig();
+
+ ASessionCreationConfig_setTids(config.get(), creator.tids.data(), creator.tids.size());
+ ASessionCreationConfig_setTargetWorkDurationNanos(config.get(), creator.targetDuration);
+ ASessionCreationConfig_setPreferPowerEfficiency(config.get(), creator.powerEfficient);
+ ASessionCreationConfig_setGraphicsPipeline(config.get(), creator.graphicsPipeline);
+ ASessionCreationConfig_setNativeSurfaces(config.get(),
+ creator.nativeWindows.size() > 0
+ ? creator.nativeWindows.data()
+ : nullptr,
+ creator.nativeWindows.size(),
+ creator.surfaceControls.size() > 0
+ ? creator.surfaceControls.data()
+ : nullptr,
+ creator.surfaceControls.size());
+ ASessionCreationConfig_setUseAutoTiming(config.get(), creator.autoCpu, creator.autoGpu);
+ return config;
+}
+
class MockIHintManager : public IHintManager {
public:
MOCK_METHOD(ScopedAStatus, createHintSessionWithConfig,
(const SpAIBinder& token, hal::SessionTag tag,
const SessionCreationConfig& creationConfig, hal::SessionConfig* config,
- std::shared_ptr<IHintSession>* _aidl_return),
+ IHintManager::SessionCreationReturn* _aidl_return),
(override));
MOCK_METHOD(ScopedAStatus, setHintSessionThreads,
(const std::shared_ptr<IHintSession>& hintSession,
@@ -115,8 +190,9 @@
APerformanceHint_getRateLimiterPropertiesForTesting(&mMaxLoadHintsPerInterval,
&mLoadHintInterval);
APerformanceHint_setIHintManagerForTesting(&mMockIHintManager);
- APerformanceHint_setUseGraphicsPipelineForTesting(true);
APerformanceHint_setUseNewLoadHintBehaviorForTesting(true);
+ mTids.push_back(1);
+ mTids.push_back(2);
}
void TearDown() override {
@@ -130,20 +206,22 @@
ON_CALL(*mMockIHintManager, registerClient(_, _))
.WillByDefault(
DoAll(SetArgPointee<1>(mClientData), [] { return ScopedAStatus::ok(); }));
+ ON_CALL(*mMockIHintManager, isRemote()).WillByDefault(Return(true));
return APerformanceHint_getManager();
}
- APerformanceHintSession* createSession(APerformanceHintManager* manager,
- int64_t targetDuration = 56789L, bool isHwui = false) {
+ void prepareSessionMock() {
mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
const int64_t sessionId = 123;
- std::vector<int32_t> tids;
- tids.push_back(1);
- tids.push_back(2);
+
+ mSessionCreationReturn = IHintManager::SessionCreationReturn{
+ .session = mMockSession,
+ .pipelineThreadLimitExceeded = false,
+ };
ON_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _))
.WillByDefault(DoAll(SetArgPointee<3>(hal::SessionConfig({.id = sessionId})),
- SetArgPointee<4>(std::shared_ptr<IHintSession>(mMockSession)),
+ SetArgPointee<4>(mSessionCreationReturn),
[] { return ScopedAStatus::ok(); }));
ON_CALL(*mMockIHintManager, setHintSessionThreads(_, _)).WillByDefault([] {
@@ -161,48 +239,36 @@
ON_CALL(*mMockSession, reportActualWorkDuration2(_)).WillByDefault([] {
return ScopedAStatus::ok();
});
- if (isHwui) {
- return APerformanceHint_createSessionInternal(manager, tids.data(), tids.size(),
- targetDuration, SessionTag::HWUI);
- }
- return APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
}
- APerformanceHintSession* createSessionUsingConfig(APerformanceHintManager* manager,
- SessionCreationConfig config,
- bool isHwui = false) {
- mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
- const int64_t sessionId = 123;
-
- ON_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _))
- .WillByDefault(DoAll(SetArgPointee<3>(hal::SessionConfig({.id = sessionId})),
- SetArgPointee<4>(std::shared_ptr<IHintSession>(mMockSession)),
- [] { return ScopedAStatus::ok(); }));
-
- ON_CALL(*mMockIHintManager, setHintSessionThreads(_, _)).WillByDefault([] {
- return ScopedAStatus::ok();
- });
- ON_CALL(*mMockSession, sendHint(_)).WillByDefault([] { return ScopedAStatus::ok(); });
- ON_CALL(*mMockSession, setMode(_, true)).WillByDefault([] { return ScopedAStatus::ok(); });
- ON_CALL(*mMockSession, close()).WillByDefault([] { return ScopedAStatus::ok(); });
- ON_CALL(*mMockSession, updateTargetWorkDuration(_)).WillByDefault([] {
- return ScopedAStatus::ok();
- });
- ON_CALL(*mMockSession, reportActualWorkDuration(_, _)).WillByDefault([] {
- return ScopedAStatus::ok();
- });
- ON_CALL(*mMockSession, reportActualWorkDuration2(_)).WillByDefault([] {
- return ScopedAStatus::ok();
- });
-
+ std::shared_ptr<APerformanceHintSession> createSession(APerformanceHintManager* manager,
+ int64_t targetDuration = 56789L,
+ bool isHwui = false) {
+ prepareSessionMock();
if (isHwui) {
- return APerformanceHint_createSessionUsingConfigInternal(
- manager, reinterpret_cast<ASessionCreationConfig*>(&config), SessionTag::HWUI);
+ return wrapSession(APerformanceHint_createSessionInternal(manager, mTids.data(),
+ mTids.size(), targetDuration,
+ SessionTag::HWUI));
+ }
+ return wrapSession(APerformanceHint_createSession(manager, mTids.data(), mTids.size(),
+ targetDuration));
+ }
+
+ std::shared_ptr<APerformanceHintSession> createSessionUsingConfig(
+ APerformanceHintManager* manager, std::shared_ptr<ASessionCreationConfig>& config,
+ bool isHwui = false) {
+ prepareSessionMock();
+ APerformanceHintSession* session;
+ int out = 0;
+ if (isHwui) {
+ out = APerformanceHint_createSessionUsingConfigInternal(manager, config.get(), &session,
+ SessionTag::HWUI);
}
- return APerformanceHint_createSessionUsingConfig(manager,
- reinterpret_cast<ASessionCreationConfig*>(
- &config));
+ out = APerformanceHint_createSessionUsingConfig(manager, config.get(), &session);
+ EXPECT_EQ(out, 0);
+
+ return wrapSession(session);
}
void setFMQEnabled(bool enabled) {
@@ -233,11 +299,13 @@
uint32_t mWriteBits = 0x00000002;
std::shared_ptr<NiceMock<MockIHintManager>> mMockIHintManager = nullptr;
std::shared_ptr<NiceMock<MockIHintSession>> mMockSession = nullptr;
+ IHintManager::SessionCreationReturn mSessionCreationReturn;
std::shared_ptr<AidlMessageQueue<hal::ChannelMessage, SynchronizedReadWrite>> mMockFMQ;
std::shared_ptr<AidlMessageQueue<int8_t, SynchronizedReadWrite>> mMockFlagQueue;
hardware::EventFlag* mEventFlag;
int kMockQueueSize = 20;
bool mUsingFMQ = false;
+ std::vector<int> mTids;
IHintManager::HintManagerClientData mClientData{
.powerHalVersion = 6,
@@ -273,107 +341,109 @@
TEST_F(PerformanceHintTest, TestSession) {
APerformanceHintManager* manager = createManager();
- APerformanceHintSession* session = createSession(manager);
+ auto&& session = createSession(manager);
ASSERT_TRUE(session);
int64_t targetDurationNanos = 10;
EXPECT_CALL(*mMockSession, updateTargetWorkDuration(Eq(targetDurationNanos))).Times(Exactly(1));
- int result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
+ int result = APerformanceHint_updateTargetWorkDuration(session.get(), targetDurationNanos);
EXPECT_EQ(0, result);
// subsequent call with same target should be ignored but return no error
- result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
+ result = APerformanceHint_updateTargetWorkDuration(session.get(), targetDurationNanos);
EXPECT_EQ(0, result);
+ Mock::VerifyAndClearExpectations(mMockSession.get());
+
usleep(2); // Sleep for longer than preferredUpdateRateNanos.
int64_t actualDurationNanos = 20;
std::vector<int64_t> actualDurations;
actualDurations.push_back(20);
EXPECT_CALL(*mMockSession, reportActualWorkDuration2(_)).Times(Exactly(1));
- result = APerformanceHint_reportActualWorkDuration(session, actualDurationNanos);
+ EXPECT_CALL(*mMockSession, updateTargetWorkDuration(_)).Times(Exactly(1));
+ result = APerformanceHint_reportActualWorkDuration(session.get(), actualDurationNanos);
EXPECT_EQ(0, result);
- result = APerformanceHint_updateTargetWorkDuration(session, -1L);
+ result = APerformanceHint_reportActualWorkDuration(session.get(), -1L);
EXPECT_EQ(EINVAL, result);
- result = APerformanceHint_reportActualWorkDuration(session, -1L);
+ result = APerformanceHint_updateTargetWorkDuration(session.get(), 0);
+ EXPECT_EQ(0, result);
+ result = APerformanceHint_updateTargetWorkDuration(session.get(), -2);
+ EXPECT_EQ(EINVAL, result);
+ result = APerformanceHint_reportActualWorkDuration(session.get(), 12L);
EXPECT_EQ(EINVAL, result);
SessionHint hintId = SessionHint::CPU_LOAD_RESET;
EXPECT_CALL(*mMockSession, sendHint(Eq(hintId))).Times(Exactly(1));
- result = APerformanceHint_sendHint(session, hintId);
+ result = APerformanceHint_sendHint(session.get(), hintId);
EXPECT_EQ(0, result);
EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::CPU_LOAD_UP))).Times(Exactly(1));
- result = APerformanceHint_notifyWorkloadIncrease(session, true, false, "Test hint");
+ result = APerformanceHint_notifyWorkloadIncrease(session.get(), true, false, "Test hint");
EXPECT_EQ(0, result);
EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::CPU_LOAD_RESET))).Times(Exactly(1));
EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::GPU_LOAD_RESET))).Times(Exactly(1));
- result = APerformanceHint_notifyWorkloadReset(session, true, true, "Test hint");
+ result = APerformanceHint_notifyWorkloadReset(session.get(), true, true, "Test hint");
EXPECT_EQ(0, result);
EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::CPU_LOAD_SPIKE))).Times(Exactly(1));
EXPECT_CALL(*mMockSession, sendHint(Eq(SessionHint::GPU_LOAD_SPIKE))).Times(Exactly(1));
- result = APerformanceHint_notifyWorkloadSpike(session, true, true, "Test hint");
+ result = APerformanceHint_notifyWorkloadSpike(session.get(), true, true, "Test hint");
EXPECT_EQ(0, result);
- result = APerformanceHint_sendHint(session, static_cast<SessionHint>(-1));
- EXPECT_EQ(EINVAL, result);
+ EXPECT_DEATH(
+ { APerformanceHint_sendHint(session.get(), static_cast<SessionHint>(-1)); },
+ "invalid session hint");
Mock::VerifyAndClearExpectations(mMockSession.get());
for (int i = 0; i < mMaxLoadHintsPerInterval; ++i) {
- APerformanceHint_sendHint(session, hintId);
+ APerformanceHint_sendHint(session.get(), hintId);
}
// Expect to get rate limited if we try to send faster than the limiter allows
EXPECT_CALL(*mMockSession, sendHint(_)).Times(Exactly(0));
- result = APerformanceHint_notifyWorkloadIncrease(session, true, true, "Test hint");
+ result = APerformanceHint_notifyWorkloadIncrease(session.get(), true, true, "Test hint");
EXPECT_EQ(result, EBUSY);
EXPECT_CALL(*mMockSession, sendHint(_)).Times(Exactly(0));
- result = APerformanceHint_notifyWorkloadReset(session, true, true, "Test hint");
+ result = APerformanceHint_notifyWorkloadReset(session.get(), true, true, "Test hint");
EXPECT_CALL(*mMockSession, close()).Times(Exactly(1));
- APerformanceHint_closeSession(session);
}
TEST_F(PerformanceHintTest, TestUpdatedSessionCreation) {
EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _)).Times(1);
APerformanceHintManager* manager = createManager();
- APerformanceHintSession* session = createSession(manager);
+ auto&& session = createSession(manager);
ASSERT_TRUE(session);
- APerformanceHint_closeSession(session);
}
TEST_F(PerformanceHintTest, TestSessionCreationUsingConfig) {
EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _)).Times(1);
- SessionCreationConfig config{.tids = std::vector<int32_t>(1, 2),
- .targetWorkDurationNanos = 5678,
- .modesToEnable = std::vector<hal::SessionMode>(0)};
+ auto&& config = configFromCreator({.tids = mTids});
APerformanceHintManager* manager = createManager();
- APerformanceHintSession* session = createSessionUsingConfig(manager, config);
+ auto&& session = createSessionUsingConfig(manager, config);
ASSERT_TRUE(session);
- APerformanceHint_closeSession(session);
}
TEST_F(PerformanceHintTest, TestHwuiSessionCreation) {
EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, hal::SessionTag::HWUI, _, _, _))
.Times(1);
APerformanceHintManager* manager = createManager();
- APerformanceHintSession* session = createSession(manager, 56789L, true);
+ auto&& session = createSession(manager, 56789L, true);
ASSERT_TRUE(session);
- APerformanceHint_closeSession(session);
}
TEST_F(PerformanceHintTest, SetThreads) {
APerformanceHintManager* manager = createManager();
- APerformanceHintSession* session = createSession(manager);
+ auto&& session = createSession(manager);
ASSERT_TRUE(session);
int32_t emptyTids[2];
- int result = APerformanceHint_setThreads(session, emptyTids, 0);
+ int result = APerformanceHint_setThreads(session.get(), emptyTids, 0);
EXPECT_EQ(EINVAL, result);
std::vector<int32_t> newTids;
newTids.push_back(1);
newTids.push_back(3);
EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(newTids))).Times(Exactly(1));
- result = APerformanceHint_setThreads(session, newTids.data(), newTids.size());
+ result = APerformanceHint_setThreads(session.get(), newTids.data(), newTids.size());
EXPECT_EQ(0, result);
testing::Mock::VerifyAndClearExpectations(mMockIHintManager.get());
@@ -383,27 +453,27 @@
EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(invalidTids)))
.Times(Exactly(1))
.WillOnce(Return(ByMove(ScopedAStatus::fromExceptionCode(EX_SECURITY))));
- result = APerformanceHint_setThreads(session, invalidTids.data(), invalidTids.size());
+ result = APerformanceHint_setThreads(session.get(), invalidTids.data(), invalidTids.size());
EXPECT_EQ(EPERM, result);
}
TEST_F(PerformanceHintTest, SetPowerEfficient) {
APerformanceHintManager* manager = createManager();
- APerformanceHintSession* session = createSession(manager);
+ auto&& session = createSession(manager);
ASSERT_TRUE(session);
EXPECT_CALL(*mMockSession, setMode(_, Eq(true))).Times(Exactly(1));
- int result = APerformanceHint_setPreferPowerEfficiency(session, true);
+ int result = APerformanceHint_setPreferPowerEfficiency(session.get(), true);
EXPECT_EQ(0, result);
EXPECT_CALL(*mMockSession, setMode(_, Eq(false))).Times(Exactly(1));
- result = APerformanceHint_setPreferPowerEfficiency(session, false);
+ result = APerformanceHint_setPreferPowerEfficiency(session.get(), false);
EXPECT_EQ(0, result);
}
TEST_F(PerformanceHintTest, CreateZeroTargetDurationSession) {
APerformanceHintManager* manager = createManager();
- APerformanceHintSession* session = createSession(manager, 0);
+ auto&& session = createSession(manager, 0);
ASSERT_TRUE(session);
}
@@ -428,12 +498,12 @@
TEST_F(PerformanceHintTest, TestAPerformanceHint_reportActualWorkDuration2) {
APerformanceHintManager* manager = createManager();
- APerformanceHintSession* session = createSession(manager);
+ auto&& session = createSession(manager);
ASSERT_TRUE(session);
int64_t targetDurationNanos = 10;
EXPECT_CALL(*mMockSession, updateTargetWorkDuration(Eq(targetDurationNanos))).Times(Exactly(1));
- int result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
+ int result = APerformanceHint_updateTargetWorkDuration(session.get(), targetDurationNanos);
EXPECT_EQ(0, result);
usleep(2); // Sleep for longer than preferredUpdateRateNanos.
@@ -452,54 +522,53 @@
EXPECT_CALL(*mMockSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))
.Times(Exactly(pair.expectedResult == OK));
- result = APerformanceHint_reportActualWorkDuration2(session,
+ result = APerformanceHint_reportActualWorkDuration2(session.get(),
reinterpret_cast<AWorkDuration*>(
&pair.duration));
EXPECT_EQ(pair.expectedResult, result);
}
EXPECT_CALL(*mMockSession, close()).Times(Exactly(1));
- APerformanceHint_closeSession(session);
}
TEST_F(PerformanceHintTest, TestAWorkDuration) {
- AWorkDuration* aWorkDuration = AWorkDuration_create();
+ // AWorkDuration* aWorkDuration = AWorkDuration_create();
+ auto&& aWorkDuration = wrapWorkDuration(AWorkDuration_create());
ASSERT_NE(aWorkDuration, nullptr);
- AWorkDuration_setWorkPeriodStartTimestampNanos(aWorkDuration, 1);
- AWorkDuration_setActualTotalDurationNanos(aWorkDuration, 20);
- AWorkDuration_setActualCpuDurationNanos(aWorkDuration, 13);
- AWorkDuration_setActualGpuDurationNanos(aWorkDuration, 8);
- AWorkDuration_release(aWorkDuration);
+ AWorkDuration_setWorkPeriodStartTimestampNanos(aWorkDuration.get(), 1);
+ AWorkDuration_setActualTotalDurationNanos(aWorkDuration.get(), 20);
+ AWorkDuration_setActualCpuDurationNanos(aWorkDuration.get(), 13);
+ AWorkDuration_setActualGpuDurationNanos(aWorkDuration.get(), 8);
}
TEST_F(PerformanceHintTest, TestCreateUsingFMQ) {
setFMQEnabled(true);
APerformanceHintManager* manager = createManager();
- APerformanceHintSession* session = createSession(manager);
+ auto&& session = createSession(manager);
ASSERT_TRUE(session);
}
TEST_F(PerformanceHintTest, TestUpdateTargetWorkDurationUsingFMQ) {
setFMQEnabled(true);
APerformanceHintManager* manager = createManager();
- APerformanceHintSession* session = createSession(manager);
- APerformanceHint_updateTargetWorkDuration(session, 456);
+ auto&& session = createSession(manager);
+ APerformanceHint_updateTargetWorkDuration(session.get(), 456);
expectToReadFromFmq<HalChannelMessageContents::Tag::targetDuration>(456);
}
TEST_F(PerformanceHintTest, TestSendHintUsingFMQ) {
setFMQEnabled(true);
APerformanceHintManager* manager = createManager();
- APerformanceHintSession* session = createSession(manager);
- APerformanceHint_sendHint(session, SessionHint::CPU_LOAD_UP);
+ auto&& session = createSession(manager);
+ APerformanceHint_sendHint(session.get(), SessionHint::CPU_LOAD_UP);
expectToReadFromFmq<HalChannelMessageContents::Tag::hint>(hal::SessionHint::CPU_LOAD_UP);
}
TEST_F(PerformanceHintTest, TestReportActualUsingFMQ) {
setFMQEnabled(true);
APerformanceHintManager* manager = createManager();
- APerformanceHintSession* session = createSession(manager);
+ auto&& session = createSession(manager);
hal::WorkDuration duration{.timeStampNanos = 3,
.durationNanos = 999999,
.workPeriodStartTimestampNanos = 1,
@@ -513,20 +582,91 @@
.gpuDurationNanos = duration.gpuDurationNanos,
};
- APerformanceHint_reportActualWorkDuration2(session,
+ APerformanceHint_reportActualWorkDuration2(session.get(),
reinterpret_cast<AWorkDuration*>(&duration));
expectToReadFromFmq<HalChannelMessageContents::Tag::workDuration>(durationExpected);
}
TEST_F(PerformanceHintTest, TestASessionCreationConfig) {
- ASessionCreationConfig* config = ASessionCreationConfig_create();
- ASSERT_NE(config, nullptr);
+ auto&& config = configFromCreator({
+ .tids = mTids,
+ .targetDuration = 20,
+ .powerEfficient = true,
+ .graphicsPipeline = true,
+ });
- const int32_t testTids[2] = {1, 2};
- const size_t size = 2;
- EXPECT_EQ(ASessionCreationConfig_setTids(config, testTids, size), 0);
- EXPECT_EQ(ASessionCreationConfig_setTargetWorkDurationNanos(config, 20), 0);
- EXPECT_EQ(ASessionCreationConfig_setPreferPowerEfficiency(config, true), 0);
- EXPECT_EQ(ASessionCreationConfig_setGraphicsPipeline(config, true), 0);
- ASessionCreationConfig_release(config);
+ APerformanceHintManager* manager = createManager();
+ auto&& session = createSessionUsingConfig(manager, config);
+
+ ASSERT_NE(session, nullptr);
+ ASSERT_NE(config, nullptr);
+}
+
+TEST_F(PerformanceHintTest, TestSupportObject) {
+ // Disable GPU and Power Efficiency support to test partial enabling
+ mClientData.supportInfo.sessionModes &= ~(1 << (int)hal::SessionMode::AUTO_GPU);
+ mClientData.supportInfo.sessionHints &= ~(1 << (int)hal::SessionHint::GPU_LOAD_UP);
+ mClientData.supportInfo.sessionHints &= ~(1 << (int)hal::SessionHint::POWER_EFFICIENCY);
+
+ APerformanceHintManager* manager = createManager();
+
+ union {
+ int expectedSupportInt;
+ SupportHelper expectedSupport;
+ };
+
+ union {
+ int actualSupportInt;
+ SupportHelper actualSupport;
+ };
+
+ expectedSupport = getFullySupportedSupportHelper();
+ actualSupport = getSupportHelper();
+
+ expectedSupport.autoGpu = false;
+
+ EXPECT_EQ(expectedSupportInt, actualSupportInt);
+}
+
+TEST_F(PerformanceHintTest, TestCreatingAutoSession) {
+ // Disable GPU capability for testing
+ mClientData.supportInfo.sessionModes &= ~(1 << (int)hal::SessionMode::AUTO_GPU);
+ APerformanceHintManager* manager = createManager();
+
+ auto&& invalidConfig = configFromCreator({
+ .tids = mTids,
+ .targetDuration = 20,
+ .graphicsPipeline = false,
+ .autoCpu = true,
+ .autoGpu = true,
+ });
+
+ EXPECT_DEATH({ createSessionUsingConfig(manager, invalidConfig); }, "");
+
+ auto&& unsupportedConfig = configFromCreator({
+ .tids = mTids,
+ .targetDuration = 20,
+ .graphicsPipeline = true,
+ .autoCpu = true,
+ .autoGpu = true,
+ });
+
+ APerformanceHintSession* unsupportedSession = nullptr;
+
+ // Creating a session with auto timing but no graphics pipeline should fail
+ int out = APerformanceHint_createSessionUsingConfig(manager, unsupportedConfig.get(),
+ &unsupportedSession);
+ EXPECT_EQ(out, ENOTSUP);
+ EXPECT_EQ(wrapSession(unsupportedSession), nullptr);
+
+ auto&& validConfig = configFromCreator({
+ .tids = mTids,
+ .targetDuration = 20,
+ .graphicsPipeline = true,
+ .autoCpu = true,
+ .autoGpu = false,
+ });
+
+ auto&& validSession = createSessionUsingConfig(manager, validConfig);
+ EXPECT_NE(validSession, nullptr);
}
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index a0bc77e..c4e4c42 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -42,6 +42,7 @@
import android.hardware.power.GpuHeadroomResult;
import android.hardware.power.IPower;
import android.hardware.power.SessionConfig;
+import android.hardware.power.SessionMode;
import android.hardware.power.SessionTag;
import android.hardware.power.SupportInfo;
import android.hardware.power.WorkDuration;
@@ -58,6 +59,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
import android.os.SessionCreationConfig;
import android.os.SystemProperties;
import android.os.UserHandle;
@@ -80,7 +82,6 @@
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
-import com.android.server.power.hint.HintManagerService.AppHintSession.SessionModes;
import com.android.server.utils.Slogf;
import java.io.BufferedReader;
@@ -409,6 +410,29 @@
mEnforceCpuHeadroomUserModeCpuTimeCheck = true;
}
+ private boolean tooManyPipelineThreads(int uid) {
+ synchronized (mThreadsUsageObject) {
+ ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(uid);
+ int graphicsPipelineThreadCount = 0;
+ if (threadsSet != null) {
+ // We count the graphics pipeline threads that are
+ // *not* in this session, since those in this session
+ // will be replaced. Then if the count plus the new tids
+ // is over max available graphics pipeline threads we raise
+ // an exception.
+ for (ThreadUsageTracker t : threadsSet) {
+ if (t.isGraphicsPipeline()) {
+ graphicsPipelineThreadCount++;
+ }
+ }
+ if (graphicsPipelineThreadCount > MAX_GRAPHICS_PIPELINE_THREADS_COUNT) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
private ServiceThread createCleanUpThread() {
final ServiceThread handlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_LOWEST, true /*allowIo*/);
@@ -1307,9 +1331,9 @@
@VisibleForTesting
final class BinderService extends IHintManager.Stub {
@Override
- public IHintSession createHintSessionWithConfig(@NonNull IBinder token,
- @SessionTag int tag, SessionCreationConfig creationConfig,
- SessionConfig config) {
+ public IHintManager.SessionCreationReturn createHintSessionWithConfig(
+ @NonNull IBinder token, @SessionTag int tag,
+ SessionCreationConfig creationConfig, SessionConfig config) {
if (!isHintSessionSupported()) {
throw new UnsupportedOperationException("PowerHintSessions are not supported!");
}
@@ -1327,8 +1351,24 @@
final long identity = Binder.clearCallingIdentity();
final long durationNanos = creationConfig.targetWorkDurationNanos;
- Preconditions.checkArgument(checkGraphicsPipelineValid(creationConfig, callingUid),
- "not enough of available graphics pipeline thread.");
+ boolean isGraphicsPipeline = false;
+ boolean isAutoTimed = false;
+ if (creationConfig.modesToEnable != null) {
+ for (int mode : creationConfig.modesToEnable) {
+ if (mode == SessionMode.GRAPHICS_PIPELINE) {
+ isGraphicsPipeline = true;
+ }
+ if (mode == SessionMode.AUTO_CPU || mode == SessionMode.AUTO_GPU) {
+ isAutoTimed = true;
+ }
+ }
+ }
+
+ if (isAutoTimed) {
+ Preconditions.checkArgument(isGraphicsPipeline,
+ "graphics pipeline mode not enabled for an automatically timed session");
+ }
+
try {
final IntArray nonIsolated = powerhintThreadCleanup() ? new IntArray(tids.length)
: null;
@@ -1446,12 +1486,8 @@
}
if (hs != null) {
- boolean isGraphicsPipeline = false;
if (creationConfig.modesToEnable != null) {
for (int sessionMode : creationConfig.modesToEnable) {
- if (sessionMode == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
- isGraphicsPipeline = true;
- }
hs.setMode(sessionMode, true);
}
}
@@ -1470,7 +1506,10 @@
}
}
- return hs;
+ IHintManager.SessionCreationReturn out = new IHintManager.SessionCreationReturn();
+ out.pipelineThreadLimitExceeded = tooManyPipelineThreads(callingUid);
+ out.session = hs;
+ return out;
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -1852,45 +1891,6 @@
throw new IllegalStateException("Can't find cpu line in " + filePath);
}
- private boolean checkGraphicsPipelineValid(SessionCreationConfig creationConfig, int uid) {
- if (creationConfig.modesToEnable == null) {
- return true;
- }
- boolean setGraphicsPipeline = false;
- for (int modeToEnable : creationConfig.modesToEnable) {
- if (modeToEnable == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
- setGraphicsPipeline = true;
- }
- }
- if (!setGraphicsPipeline) {
- return true;
- }
-
- synchronized (mThreadsUsageObject) {
- // count used graphics pipeline threads for the calling UID
- // consider the case that new tids are overlapping with in session tids
- ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(uid);
- if (threadsSet == null) {
- return true;
- }
-
- final int newThreadCount = creationConfig.tids.length;
- int graphicsPipelineThreadCount = 0;
- for (ThreadUsageTracker t : threadsSet) {
- // count graphics pipeline threads in use
- // and exclude overlapping ones
- if (t.isGraphicsPipeline()) {
- graphicsPipelineThreadCount++;
- if (contains(creationConfig.tids, t.getTid())) {
- graphicsPipelineThreadCount--;
- }
- }
- }
- return graphicsPipelineThreadCount + newThreadCount
- <= MAX_GRAPHICS_PIPELINE_THREADS_COUNT;
- }
- }
-
private void logPerformanceHintSessionAtom(int uid, long sessionId,
long targetDuration, int[] tids, @SessionTag int sessionTag) {
FrameworkStatsLog.write(FrameworkStatsLog.PERFORMANCE_HINT_SESSION_REPORTED, uid,
@@ -1928,11 +1928,6 @@
protected Integer mSessionId;
protected boolean mTrackedBySF;
- enum SessionModes {
- POWER_EFFICIENCY,
- GRAPHICS_PIPELINE,
- };
-
protected AppHintSession(
int uid, int pid, int sessionTag, int[] threadIds, IBinder token,
long halSessionPtr, long durationNanos, Integer sessionId) {
@@ -1985,8 +1980,8 @@
if (!isHintAllowed()) {
return;
}
- Preconditions.checkArgument(targetDurationNanos > 0, "Expected"
- + " the target duration to be greater than 0.");
+ Preconditions.checkArgument(targetDurationNanos >= 0, "Expected"
+ + " the target duration to be greater than or equal to 0.");
mNativeWrapper.halUpdateTargetWorkDuration(mHalSessionPtr, targetDurationNanos);
mTargetDurationNanos = targetDurationNanos;
}
@@ -2149,6 +2144,11 @@
public void setThreads(@NonNull int[] tids) {
setThreadsInternal(tids, true);
+ if (tooManyPipelineThreads(Binder.getCallingUid())) {
+ // This is technically a success but we are going to throw a fit anyway
+ throw new ServiceSpecificException(5,
+ "Not enough available graphics pipeline threads.");
+ }
}
private void setThreadsInternal(int[] tids, boolean checkTid) {
@@ -2156,32 +2156,7 @@
throw new IllegalArgumentException("Thread id list can't be empty.");
}
-
final int callingUid = Binder.getCallingUid();
- if (mGraphicsPipeline) {
- synchronized (mThreadsUsageObject) {
- // replace original tids with new tids
- ArraySet<ThreadUsageTracker> threadsSet = mThreadsUsageMap.get(callingUid);
- int graphicsPipelineThreadCount = 0;
- if (threadsSet != null) {
- // We count the graphics pipeline threads that are
- // *not* in this session, since those in this session
- // will be replaced. Then if the count plus the new tids
- // is over max available graphics pipeline threads we raise
- // an exception.
- for (ThreadUsageTracker t : threadsSet) {
- if (t.isGraphicsPipeline() && !contains(mThreadIds, t.getTid())) {
- graphicsPipelineThreadCount++;
- }
- }
- if (graphicsPipelineThreadCount + tids.length
- > MAX_GRAPHICS_PIPELINE_THREADS_COUNT) {
- throw new IllegalArgumentException(
- "Not enough available graphics pipeline threads.");
- }
- }
- }
- }
synchronized (this) {
if (mHalSessionPtr == 0) {
@@ -2315,15 +2290,15 @@
}
Preconditions.checkArgument(mode >= 0, "the mode Id value should be"
+ " greater than zero.");
- if (mode == SessionModes.POWER_EFFICIENCY.ordinal()) {
+ if (mode == SessionMode.POWER_EFFICIENCY) {
mPowerEfficient = enabled;
- } else if (mode == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
+ } else if (mode == SessionMode.GRAPHICS_PIPELINE) {
mGraphicsPipeline = enabled;
}
mNativeWrapper.halSetMode(mHalSessionPtr, mode, enabled);
}
if (enabled) {
- if (mode == SessionModes.POWER_EFFICIENCY.ordinal()) {
+ if (mode == SessionMode.POWER_EFFICIENCY) {
if (!mHasBeenPowerEfficient) {
mHasBeenPowerEfficient = true;
synchronized (mSessionSnapshotMapLock) {
@@ -2342,7 +2317,7 @@
sessionSnapshot.logPowerEfficientSession();
}
}
- } else if (mode == SessionModes.GRAPHICS_PIPELINE.ordinal()) {
+ } else if (mode == SessionMode.GRAPHICS_PIPELINE) {
if (!mHasBeenGraphicsPipeline) {
mHasBeenGraphicsPipeline = true;
synchronized (mSessionSnapshotMapLock) {
diff --git a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
index de6f9bd..bd15bd0 100644
--- a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
+++ b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
@@ -391,19 +391,19 @@
makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SessionTag.OTHER, creationConfig, new SessionConfig());
+ SessionTag.OTHER, creationConfig, new SessionConfig()).session;
assertNotNull(a);
creationConfig.tids = SESSION_TIDS_B;
creationConfig.targetWorkDurationNanos = DOUBLED_TARGET_DURATION;
IHintSession b = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SessionTag.OTHER, creationConfig, new SessionConfig());
+ SessionTag.OTHER, creationConfig, new SessionConfig()).session;
assertNotEquals(a, b);
creationConfig.tids = SESSION_TIDS_C;
creationConfig.targetWorkDurationNanos = 0L;
IHintSession c = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SessionTag.OTHER, creationConfig, new SessionConfig());
+ SessionTag.OTHER, creationConfig, new SessionConfig()).session;
assertNotNull(c);
verify(mNativeWrapperMock, times(3)).halCreateHintSession(anyInt(), anyInt(),
any(int[].class), anyLong());
@@ -418,7 +418,7 @@
SessionConfig config = new SessionConfig();
IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SessionTag.OTHER, creationConfig, config);
+ SessionTag.OTHER, creationConfig, config).session;
assertNotNull(a);
assertEquals(SESSION_IDS[0], config.id);
@@ -426,7 +426,7 @@
creationConfig.tids = SESSION_TIDS_B;
creationConfig.targetWorkDurationNanos = DOUBLED_TARGET_DURATION;
IHintSession b = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SessionTag.APP, creationConfig, config2);
+ SessionTag.APP, creationConfig, config2).session;
assertNotEquals(a, b);
assertEquals(SESSION_IDS[1], config2.id);
@@ -434,7 +434,7 @@
creationConfig.tids = SESSION_TIDS_C;
creationConfig.targetWorkDurationNanos = 0L;
IHintSession c = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SessionTag.GAME, creationConfig, config3);
+ SessionTag.GAME, creationConfig, config3).session;
assertNotNull(c);
assertEquals(SESSION_IDS[2], config3.id);
verify(mNativeWrapperMock, times(3)).halCreateHintSessionWithConfig(anyInt(), anyInt(),
@@ -465,16 +465,14 @@
SessionConfig config = new SessionConfig();
IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SessionTag.OTHER, creationConfig, config);
+ SessionTag.OTHER, creationConfig, config).session;
assertNotNull(a);
assertEquals(sessionId1, config.id);
creationConfig.tids = createThreads(1, stopLatch1);
- assertThrows(IllegalArgumentException.class, () -> {
- service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SessionTag.OTHER, creationConfig, config);
- });
+ assertEquals(service.getBinderServiceInstance().createHintSessionWithConfig(token,
+ SessionTag.OTHER, creationConfig, config).pipelineThreadLimitExceeded, true);
}
@Test
@@ -486,7 +484,7 @@
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
.createHintSessionWithConfig(token, SessionTag.OTHER,
- creationConfig, new SessionConfig());
+ creationConfig, new SessionConfig()).session;
// Set session to background and calling updateHintAllowedByProcState() would invoke
// pause();
@@ -526,7 +524,7 @@
makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SessionTag.OTHER, creationConfig, new SessionConfig());
+ SessionTag.OTHER, creationConfig, new SessionConfig()).session;
a.close();
verify(mNativeWrapperMock, times(1)).halCloseHintSession(anyLong());
@@ -540,16 +538,12 @@
makeSessionCreationConfig(SESSION_TIDS_A, DEFAULT_TARGET_DURATION);
IHintSession a = service.getBinderServiceInstance().createHintSessionWithConfig(token,
- SessionTag.OTHER, creationConfig, new SessionConfig());
+ SessionTag.OTHER, creationConfig, new SessionConfig()).session;
assertThrows(IllegalArgumentException.class, () -> {
a.updateTargetWorkDuration(-1L);
});
- assertThrows(IllegalArgumentException.class, () -> {
- a.updateTargetWorkDuration(0L);
- });
-
a.updateTargetWorkDuration(100L);
verify(mNativeWrapperMock, times(1)).halUpdateTargetWorkDuration(anyLong(), eq(100L));
}
@@ -563,7 +557,7 @@
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
.createHintSessionWithConfig(token, SessionTag.OTHER,
- creationConfig, new SessionConfig());
+ creationConfig, new SessionConfig()).session;
a.updateTargetWorkDuration(100L);
a.reportActualWorkDuration(DURATIONS_THREE, TIMESTAMPS_THREE);
@@ -608,7 +602,7 @@
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
.createHintSessionWithConfig(token, SessionTag.OTHER,
- creationConfig, new SessionConfig());
+ creationConfig, new SessionConfig()).session;
a.sendHint(PerformanceHintManager.Session.CPU_LOAD_RESET);
verify(mNativeWrapperMock, times(1)).halSendHint(anyLong(),
@@ -637,7 +631,7 @@
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
.createHintSessionWithConfig(token, SessionTag.OTHER,
- creationConfig, new SessionConfig());
+ creationConfig, new SessionConfig()).session;
service.mUidObserver.onUidStateChanged(
a.mUid, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND, 0, 0);
@@ -661,7 +655,7 @@
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
.createHintSessionWithConfig(token, SessionTag.OTHER,
- creationConfig, new SessionConfig());
+ creationConfig, new SessionConfig()).session;
service.mUidObserver.onUidStateChanged(
a.mUid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0, 0);
@@ -677,7 +671,7 @@
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
.createHintSessionWithConfig(token, SessionTag.OTHER,
- creationConfig, new SessionConfig());
+ creationConfig, new SessionConfig()).session;
a.updateTargetWorkDuration(100L);
@@ -717,7 +711,7 @@
makeSessionCreationConfig(tids1, DEFAULT_TARGET_DURATION);
AppHintSession session1 = (AppHintSession) service.getBinderServiceInstance()
.createHintSessionWithConfig(token, SessionTag.OTHER,
- creationConfig, new SessionConfig());
+ creationConfig, new SessionConfig()).session;
assertNotNull(session1);
// trigger UID state change by making the process foreground->background, but because the
@@ -754,7 +748,7 @@
makeSessionCreationConfig(tids1, DEFAULT_TARGET_DURATION);
AppHintSession session1 = (AppHintSession) service.getBinderServiceInstance()
.createHintSessionWithConfig(token, SessionTag.OTHER,
- creationConfig, new SessionConfig());
+ creationConfig, new SessionConfig()).session;
assertNotNull(session1);
// let all session 1 threads to exit and the cleanup should force pause the session 1
@@ -865,7 +859,7 @@
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
.createHintSessionWithConfig(token, SessionTag.OTHER,
- creationConfig, new SessionConfig());
+ creationConfig, new SessionConfig()).session;
a.setMode(0, true);
verify(mNativeWrapperMock, times(1)).halSetMode(anyLong(),
@@ -885,7 +879,7 @@
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
.createHintSessionWithConfig(token, SessionTag.OTHER,
- creationConfig, new SessionConfig());
+ creationConfig, new SessionConfig()).session;
// Set session to background, then the duration would not be updated.
service.mUidObserver.onUidStateChanged(
@@ -906,7 +900,7 @@
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
.createHintSessionWithConfig(token, SessionTag.OTHER,
- creationConfig, new SessionConfig());
+ creationConfig, new SessionConfig()).session;
assertThrows(IllegalArgumentException.class, () -> {
a.setMode(-1, true);
@@ -923,7 +917,7 @@
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
.createHintSessionWithConfig(token, SessionTag.OTHER,
- creationConfig, new SessionConfig());
+ creationConfig, new SessionConfig()).session;
assertNotNull(a);
verify(mNativeWrapperMock, times(1)).halSetMode(anyLong(),
eq(0), eq(true));
@@ -1124,7 +1118,7 @@
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
.createHintSessionWithConfig(token, SessionTag.OTHER,
- creationConfig, new SessionConfig());
+ creationConfig, new SessionConfig()).session;
// we will start some threads and get their valid TIDs to update
int threadCount = 3;
// the list of TIDs
@@ -1194,7 +1188,7 @@
AppHintSession a = (AppHintSession) service.getBinderServiceInstance()
.createHintSessionWithConfig(token, SessionTag.OTHER,
- creationConfig, new SessionConfig());
+ creationConfig, new SessionConfig()).session;
a.updateTargetWorkDuration(100L);
a.reportActualWorkDuration2(WORK_DURATIONS_FIVE);