Add HWUI session tagging
Adds a hidden method for the creation of special "internal" hint
sessions with extra metadata, and plumbs hwui to use it
Bug: 330553312
Test: atest PerformanceHintNativeTestCases
Test: hwui unit tests
Change-Id: I35e7f81623b8f81a9a12e485f221952a13035b02
diff --git a/libs/hwui/renderthread/HintSessionWrapper.cpp b/libs/hwui/renderthread/HintSessionWrapper.cpp
index 6993d52..7a155c5 100644
--- a/libs/hwui/renderthread/HintSessionWrapper.cpp
+++ b/libs/hwui/renderthread/HintSessionWrapper.cpp
@@ -45,7 +45,7 @@
LOG_ALWAYS_FATAL_IF(handle_ == nullptr, "Failed to dlopen libandroid.so!");
BIND_APH_METHOD(getManager);
- BIND_APH_METHOD(createSession);
+ BIND_APH_METHOD(createSessionInternal);
BIND_APH_METHOD(closeSession);
BIND_APH_METHOD(updateTargetWorkDuration);
BIND_APH_METHOD(reportActualWorkDuration);
@@ -122,7 +122,8 @@
int64_t targetDurationNanos =
mLastTargetWorkDuration == 0 ? kDefaultTargetDuration : mLastTargetWorkDuration;
mHintSessionFuture = CommonPool::async([=, this, tids = mPermanentSessionTids] {
- return mBinding->createSession(manager, tids.data(), tids.size(), targetDurationNanos);
+ return mBinding->createSessionInternal(manager, tids.data(), tids.size(),
+ targetDurationNanos, SessionTag::HWUI);
});
return false;
}
diff --git a/libs/hwui/renderthread/HintSessionWrapper.h b/libs/hwui/renderthread/HintSessionWrapper.h
index 14e7a53..859cc57 100644
--- a/libs/hwui/renderthread/HintSessionWrapper.h
+++ b/libs/hwui/renderthread/HintSessionWrapper.h
@@ -17,6 +17,7 @@
#pragma once
#include <android/performance_hint.h>
+#include <private/performance_hint_private.h>
#include <future>
#include <optional>
@@ -80,9 +81,10 @@
virtual ~HintSessionBinding() = default;
virtual void init();
APerformanceHintManager* (*getManager)();
- APerformanceHintSession* (*createSession)(APerformanceHintManager* manager,
- const int32_t* tids, size_t tidCount,
- int64_t defaultTarget) = nullptr;
+ APerformanceHintSession* (*createSessionInternal)(APerformanceHintManager* manager,
+ const int32_t* tids, size_t tidCount,
+ int64_t defaultTarget,
+ SessionTag tag) = nullptr;
void (*closeSession)(APerformanceHintSession* session) = nullptr;
void (*updateTargetWorkDuration)(APerformanceHintSession* session,
int64_t targetDuration) = nullptr;
diff --git a/libs/hwui/tests/unit/HintSessionWrapperTests.cpp b/libs/hwui/tests/unit/HintSessionWrapperTests.cpp
index c16602c..a8db0f4a 100644
--- a/libs/hwui/tests/unit/HintSessionWrapperTests.cpp
+++ b/libs/hwui/tests/unit/HintSessionWrapperTests.cpp
@@ -52,8 +52,8 @@
void init() override;
MOCK_METHOD(APerformanceHintManager*, fakeGetManager, ());
- MOCK_METHOD(APerformanceHintSession*, fakeCreateSession,
- (APerformanceHintManager*, const int32_t*, size_t, int64_t));
+ MOCK_METHOD(APerformanceHintSession*, fakeCreateSessionInternal,
+ (APerformanceHintManager*, const int32_t*, size_t, int64_t, SessionTag));
MOCK_METHOD(void, fakeCloseSession, (APerformanceHintSession*));
MOCK_METHOD(void, fakeUpdateTargetWorkDuration, (APerformanceHintSession*, int64_t));
MOCK_METHOD(void, fakeReportActualWorkDuration, (APerformanceHintSession*, int64_t));
@@ -72,22 +72,28 @@
// Must be static so we can point to them as normal fn pointers with HintSessionBinding
static APerformanceHintManager* stubGetManager() { return sMockBinding->fakeGetManager(); };
- static APerformanceHintSession* stubCreateSession(APerformanceHintManager* manager,
- const int32_t* ids, size_t idsSize,
- int64_t initialTarget) {
- return sMockBinding->fakeCreateSession(manager, ids, idsSize, initialTarget);
+ static APerformanceHintSession* stubCreateSessionInternal(APerformanceHintManager* manager,
+ const int32_t* ids, size_t idsSize,
+ int64_t initialTarget,
+ SessionTag tag) {
+ return sMockBinding->fakeCreateSessionInternal(manager, ids, idsSize, initialTarget,
+ SessionTag::HWUI);
}
- static APerformanceHintSession* stubManagedCreateSession(APerformanceHintManager* manager,
- const int32_t* ids, size_t idsSize,
- int64_t initialTarget) {
+ static APerformanceHintSession* stubManagedCreateSessionInternal(
+ APerformanceHintManager* manager, const int32_t* ids, size_t idsSize,
+ int64_t initialTarget, SessionTag tag) {
sMockBinding->allowCreationToFinish.get_future().wait();
- return sMockBinding->fakeCreateSession(manager, ids, idsSize, initialTarget);
+ return sMockBinding->fakeCreateSessionInternal(manager, ids, idsSize, initialTarget,
+ SessionTag::HWUI);
}
- static APerformanceHintSession* stubSlowCreateSession(APerformanceHintManager* manager,
- const int32_t* ids, size_t idsSize,
- int64_t initialTarget) {
+ static APerformanceHintSession* stubSlowCreateSessionInternal(APerformanceHintManager* manager,
+ const int32_t* ids,
+ size_t idsSize,
+ int64_t initialTarget,
+ SessionTag tag) {
std::this_thread::sleep_for(50ms);
- return sMockBinding->fakeCreateSession(manager, ids, idsSize, initialTarget);
+ return sMockBinding->fakeCreateSessionInternal(manager, ids, idsSize, initialTarget,
+ SessionTag::HWUI);
}
static void stubCloseSession(APerformanceHintSession* session) {
sMockBinding->fakeCloseSession(session);
@@ -139,14 +145,14 @@
mWrapper = std::make_shared<HintSessionWrapper>(uiThreadId, renderThreadId);
mWrapper->mBinding = sMockBinding;
EXPECT_CALL(*sMockBinding, fakeGetManager).WillOnce(Return(managerPtr));
- ON_CALL(*sMockBinding, fakeCreateSession).WillByDefault(Return(sessionPtr));
+ ON_CALL(*sMockBinding, fakeCreateSessionInternal).WillByDefault(Return(sessionPtr));
ON_CALL(*sMockBinding, fakeSetThreads).WillByDefault(Return(0));
}
void HintSessionWrapperTests::MockHintSessionBinding::init() {
sMockBinding->getManager = &stubGetManager;
- if (sMockBinding->createSession == nullptr) {
- sMockBinding->createSession = &stubCreateSession;
+ if (sMockBinding->createSessionInternal == nullptr) {
+ sMockBinding->createSessionInternal = &stubCreateSessionInternal;
}
sMockBinding->closeSession = &stubCloseSession;
sMockBinding->updateTargetWorkDuration = &stubUpdateTargetWorkDuration;
@@ -163,14 +169,14 @@
TEST_F(HintSessionWrapperTests, destructorClosesBackgroundSession) {
EXPECT_CALL(*sMockBinding, fakeCloseSession(sessionPtr)).Times(1);
- sMockBinding->createSession = stubSlowCreateSession;
+ sMockBinding->createSessionInternal = stubSlowCreateSessionInternal;
mWrapper->init();
mWrapper = nullptr;
Mock::VerifyAndClearExpectations(sMockBinding.get());
}
TEST_F(HintSessionWrapperTests, sessionInitializesCorrectly) {
- EXPECT_CALL(*sMockBinding, fakeCreateSession(managerPtr, _, Gt(1), _)).Times(1);
+ EXPECT_CALL(*sMockBinding, fakeCreateSessionInternal(managerPtr, _, Gt(1), _, _)).Times(1);
mWrapper->init();
waitForWrapperReady();
}
@@ -219,7 +225,7 @@
// Here we test whether queueing delayedDestroy works while creation is still happening, if
// creation happens after
EXPECT_CALL(*sMockBinding, fakeCloseSession(sessionPtr)).Times(1);
- sMockBinding->createSession = &stubManagedCreateSession;
+ sMockBinding->createSessionInternal = &stubManagedCreateSessionInternal;
// Start creating the session and destroying it at the same time
mWrapper->init();
@@ -246,7 +252,7 @@
// Here we test whether queueing delayedDestroy works while creation is still happening, if
// creation happens before
EXPECT_CALL(*sMockBinding, fakeCloseSession(sessionPtr)).Times(1);
- sMockBinding->createSession = &stubManagedCreateSession;
+ sMockBinding->createSessionInternal = &stubManagedCreateSessionInternal;
// Start creating the session and destroying it at the same time
mWrapper->init();
@@ -352,7 +358,7 @@
}
TEST_F(HintSessionWrapperTests, setThreadsUpdatesSessionThreads) {
- EXPECT_CALL(*sMockBinding, fakeCreateSession(managerPtr, _, Gt(1), _)).Times(1);
+ EXPECT_CALL(*sMockBinding, fakeCreateSessionInternal(managerPtr, _, Gt(1), _, _)).Times(1);
EXPECT_CALL(*sMockBinding, fakeSetThreads(sessionPtr, testing::IsSupersetOf({11, 22})))
.Times(1);
mWrapper->init();
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index 1c203e3..346c87d 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -366,6 +366,7 @@
APerformanceHint_setIHintManagerForTesting;
APerformanceHint_sendHint;
APerformanceHint_getThreadIds;
+ APerformanceHint_createSessionInternal;
extern "C++" {
ASurfaceControl_registerSurfaceStatsListener*;
ASurfaceControl_unregisterSurfaceStatsListener*;
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index fbb35e2..83056b2 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -463,6 +463,15 @@
return manager->createSession(threadIds, size, initialTargetWorkDurationNanos);
}
+APerformanceHintSession* APerformanceHint_createSessionInternal(
+ APerformanceHintManager* manager, const int32_t* threadIds, size_t size,
+ int64_t initialTargetWorkDurationNanos, SessionTag tag) {
+ VALIDATE_PTR(manager)
+ VALIDATE_PTR(threadIds)
+ return manager->createSession(threadIds, size, initialTargetWorkDurationNanos,
+ static_cast<hal::SessionTag>(tag));
+}
+
int64_t APerformanceHint_getPreferredUpdateRateNanos(APerformanceHintManager* manager) {
VALIDATE_PTR(manager)
return manager->getPreferredRateNanos();
@@ -486,9 +495,9 @@
delete session;
}
-int APerformanceHint_sendHint(void* session, SessionHint hint) {
+int APerformanceHint_sendHint(APerformanceHintSession* session, SessionHint hint) {
VALIDATE_PTR(session)
- return reinterpret_cast<APerformanceHintSession*>(session)->sendHint(hint);
+ return session->sendHint(hint);
}
int APerformanceHint_setThreads(APerformanceHintSession* session, const pid_t* threadIds,
@@ -498,11 +507,10 @@
return session->setThreads(threadIds, size);
}
-int APerformanceHint_getThreadIds(void* aPerformanceHintSession, int32_t* const threadIds,
+int APerformanceHint_getThreadIds(APerformanceHintSession* session, int32_t* const threadIds,
size_t* const size) {
- VALIDATE_PTR(aPerformanceHintSession)
- return static_cast<APerformanceHintSession*>(aPerformanceHintSession)
- ->getThreadIds(threadIds, size);
+ VALIDATE_PTR(session)
+ return session->getThreadIds(threadIds, size);
}
int APerformanceHint_setPreferPowerEfficiency(APerformanceHintSession* session, bool enabled) {
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index 974e6e6..58f56b8 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -30,9 +30,7 @@
#include <memory>
#include <vector>
-using aidl::android::hardware::power::SessionConfig;
-using aidl::android::hardware::power::SessionTag;
-using aidl::android::hardware::power::WorkDuration;
+namespace hal = aidl::android::hardware::power;
using aidl::android::os::IHintManager;
using aidl::android::os::IHintSession;
using ndk::ScopedAStatus;
@@ -45,7 +43,7 @@
public:
MOCK_METHOD(ScopedAStatus, createHintSessionWithConfig,
(const SpAIBinder& token, const ::std::vector<int32_t>& tids, int64_t durationNanos,
- SessionTag tag, std::optional<SessionConfig>* config,
+ hal::SessionTag tag, std::optional<hal::SessionConfig>* config,
std::shared_ptr<IHintSession>* _aidl_return),
(override));
MOCK_METHOD(ScopedAStatus, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
@@ -71,7 +69,7 @@
MOCK_METHOD(ScopedAStatus, setMode, (int32_t mode, bool enabled), (override));
MOCK_METHOD(ScopedAStatus, close, (), (override));
MOCK_METHOD(ScopedAStatus, reportActualWorkDuration2,
- (const ::std::vector<WorkDuration>& workDurations), (override));
+ (const ::std::vector<hal::WorkDuration>& workDurations), (override));
MOCK_METHOD(SpAIBinder, asBinder, (), (override));
MOCK_METHOD(bool, isRemote, (), (override));
};
@@ -95,7 +93,7 @@
return APerformanceHint_getManager();
}
APerformanceHintSession* createSession(APerformanceHintManager* manager,
- int64_t targetDuration = 56789L) {
+ int64_t targetDuration = 56789L, bool isHwui = false) {
mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
int64_t sessionId = 123;
std::vector<int32_t> tids;
@@ -104,8 +102,8 @@
ON_CALL(*mMockIHintManager,
createHintSessionWithConfig(_, Eq(tids), Eq(targetDuration), _, _, _))
- .WillByDefault(DoAll(SetArgPointee<4>(
- std::make_optional<SessionConfig>({.id = sessionId})),
+ .WillByDefault(DoAll(SetArgPointee<4>(std::make_optional<hal::SessionConfig>(
+ {.id = sessionId})),
SetArgPointee<5>(std::shared_ptr<IHintSession>(mMockSession)),
[] { return ScopedAStatus::ok(); }));
@@ -124,6 +122,10 @@
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);
}
@@ -131,7 +133,7 @@
std::shared_ptr<NiceMock<MockIHintSession>> mMockSession = nullptr;
};
-bool equalsWithoutTimestamp(WorkDuration lhs, WorkDuration rhs) {
+bool equalsWithoutTimestamp(hal::WorkDuration lhs, hal::WorkDuration rhs) {
return lhs.workPeriodStartTimestampNanos == rhs.workPeriodStartTimestampNanos &&
lhs.cpuDurationNanos == rhs.cpuDurationNanos &&
lhs.gpuDurationNanos == rhs.gpuDurationNanos && lhs.durationNanos == rhs.durationNanos;
@@ -194,6 +196,16 @@
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);
+ ASSERT_TRUE(session);
+ APerformanceHint_closeSession(session);
+}
+
TEST_F(PerformanceHintTest, SetThreads) {
APerformanceHintManager* manager = createManager();
@@ -249,8 +261,8 @@
return false;
}
for (int i = 0; i < expected.size(); ++i) {
- WorkDuration expectedWorkDuration = expected[i];
- WorkDuration actualWorkDuration = arg[i];
+ hal::WorkDuration expectedWorkDuration = expected[i];
+ hal::WorkDuration actualWorkDuration = arg[i];
if (!equalsWithoutTimestamp(expectedWorkDuration, actualWorkDuration)) {
*result_listener << "WorkDuration at [" << i << "] is different: "
<< "Expected: " << expectedWorkDuration.toString()
@@ -273,7 +285,7 @@
usleep(2); // Sleep for longer than preferredUpdateRateNanos.
struct TestPair {
- WorkDuration duration;
+ hal::WorkDuration duration;
int expectedResult;
};
std::vector<TestPair> testPairs{
@@ -282,7 +294,7 @@
{{1, -20, 1, 13, -8}, EINVAL},
};
for (auto&& pair : testPairs) {
- std::vector<WorkDuration> actualWorkDurations;
+ std::vector<hal::WorkDuration> actualWorkDurations;
actualWorkDurations.push_back(pair.duration);
EXPECT_CALL(*mMockSession, reportActualWorkDuration2(WorkDurationEq(actualWorkDurations)))