Loading core/java/android/os/PerformanceHintManager.java +2 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import java.io.Closeable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.Reference; import java.util.Objects; /** The PerformanceHintManager allows apps to send performance hint to system. */ Loading Loading @@ -239,6 +240,7 @@ public final class PerformanceHintManager { if (mNativeSessionPtr == 0) { return; } Objects.requireNonNull(tids, "tids cannot be null"); if (tids.length == 0) { throw new IllegalArgumentException("Thread id list can't be empty."); } Loading core/jni/android_os_PerformanceHintManager.cpp +20 −3 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ typedef void (*APH_updateTargetWorkDuration)(APerformanceHintSession*, int64_t); typedef void (*APH_reportActualWorkDuration)(APerformanceHintSession*, int64_t); typedef void (*APH_closeSession)(APerformanceHintSession* session); typedef void (*APH_sendHint)(APerformanceHintSession*, int32_t); typedef void (*APH_setThreads)(APerformanceHintSession*, const pid_t*, size_t); typedef int (*APH_setThreads)(APerformanceHintSession*, const pid_t*, size_t); typedef void (*APH_getThreadIds)(APerformanceHintSession*, int32_t* const, size_t* const); bool gAPerformanceHintBindingInitialized = false; Loading Loading @@ -112,6 +112,20 @@ void ensureAPerformanceHintBindingInitialized() { } // namespace static void throwExceptionForErrno(JNIEnv* env, int err, const std::string& msg) { switch (err) { case EINVAL: jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", msg.c_str()); break; case EPERM: jniThrowExceptionFmt(env, "java/lang/SecurityException", msg.c_str()); break; default: jniThrowException(env, "java/lang/RuntimeException", msg.c_str()); break; } } static jlong nativeAcquireManager(JNIEnv* env, jclass clazz) { ensureAPerformanceHintBindingInitialized(); return reinterpret_cast<jlong>(gAPH_getManagerFn()); Loading Loading @@ -174,8 +188,11 @@ static void nativeSetThreads(JNIEnv* env, jclass clazz, jlong nativeSessionPtr, for (size_t i = 0; i < tidsArray.size(); ++i) { tidsVector.push_back(static_cast<int32_t>(tidsArray[i])); } gAPH_setThreadsFn(reinterpret_cast<APerformanceHintSession*>(nativeSessionPtr), int err = gAPH_setThreadsFn(reinterpret_cast<APerformanceHintSession*>(nativeSessionPtr), tidsVector.data(), tidsVector.size()); if (err != 0) { throwExceptionForErrno(env, err, "Failed to set threads for hint session"); } } // This call should only be used for validation in tests only. This call will initiate two IPC Loading core/tests/coretests/src/android/os/PerformanceHintManagerTest.java +11 −2 Original line number Diff line number Diff line Loading @@ -139,11 +139,20 @@ public class PerformanceHintManagerTest { } @Test public void testSetThreadsWithIllegalArgument() { public void testSetThreads_emptyTids() { Session session = createSession(); assumeNotNull(session); assertThrows(IllegalArgumentException.class, () -> { session.setThreads(new int[]{}); }); } @Test public void testSetThreads_invalidTids() { Session session = createSession(); assumeNotNull(session); assertThrows(SecurityException.class, () -> { session.setThreads(new int[]{-1}); }); } } native/android/performance_hint.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -274,9 +274,10 @@ int APerformanceHintSession::setThreads(const int32_t* threadIds, size_t size) { binder::Status ret = mHintManager->setHintSessionThreads(mHintSession, tids); if (!ret.isOk()) { ALOGE("%s: failed: %s", __FUNCTION__, ret.exceptionMessage().c_str()); if (ret.exceptionCode() == binder::Status::Exception::EX_SECURITY || ret.exceptionCode() == binder::Status::Exception::EX_ILLEGAL_ARGUMENT) { if (ret.exceptionCode() == binder::Status::Exception::EX_ILLEGAL_ARGUMENT) { return EINVAL; } else if (ret.exceptionCode() == binder::Status::Exception::EX_SECURITY) { return EPERM; } return EPIPE; } Loading native/android/tests/performance_hint/PerformanceHintNativeTest.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -178,4 +178,15 @@ TEST_F(PerformanceHintTest, SetThreads) { .WillOnce(Return(Status())); result = APerformanceHint_setThreads(session, newTids.data(), newTids.size()); EXPECT_EQ(0, result); testing::Mock::VerifyAndClearExpectations(mMockIHintManager); std::vector<int32_t> invalidTids; auto status = Status::fromExceptionCode(binder::Status::Exception::EX_SECURITY); invalidTids.push_back(4); invalidTids.push_back(6); EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(invalidTids))) .Times(Exactly(1)) .WillOnce(Return(status)); result = APerformanceHint_setThreads(session, invalidTids.data(), invalidTids.size()); EXPECT_EQ(EPERM, result); } Loading
core/java/android/os/PerformanceHintManager.java +2 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import java.io.Closeable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.Reference; import java.util.Objects; /** The PerformanceHintManager allows apps to send performance hint to system. */ Loading Loading @@ -239,6 +240,7 @@ public final class PerformanceHintManager { if (mNativeSessionPtr == 0) { return; } Objects.requireNonNull(tids, "tids cannot be null"); if (tids.length == 0) { throw new IllegalArgumentException("Thread id list can't be empty."); } Loading
core/jni/android_os_PerformanceHintManager.cpp +20 −3 Original line number Diff line number Diff line Loading @@ -41,7 +41,7 @@ typedef void (*APH_updateTargetWorkDuration)(APerformanceHintSession*, int64_t); typedef void (*APH_reportActualWorkDuration)(APerformanceHintSession*, int64_t); typedef void (*APH_closeSession)(APerformanceHintSession* session); typedef void (*APH_sendHint)(APerformanceHintSession*, int32_t); typedef void (*APH_setThreads)(APerformanceHintSession*, const pid_t*, size_t); typedef int (*APH_setThreads)(APerformanceHintSession*, const pid_t*, size_t); typedef void (*APH_getThreadIds)(APerformanceHintSession*, int32_t* const, size_t* const); bool gAPerformanceHintBindingInitialized = false; Loading Loading @@ -112,6 +112,20 @@ void ensureAPerformanceHintBindingInitialized() { } // namespace static void throwExceptionForErrno(JNIEnv* env, int err, const std::string& msg) { switch (err) { case EINVAL: jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", msg.c_str()); break; case EPERM: jniThrowExceptionFmt(env, "java/lang/SecurityException", msg.c_str()); break; default: jniThrowException(env, "java/lang/RuntimeException", msg.c_str()); break; } } static jlong nativeAcquireManager(JNIEnv* env, jclass clazz) { ensureAPerformanceHintBindingInitialized(); return reinterpret_cast<jlong>(gAPH_getManagerFn()); Loading Loading @@ -174,8 +188,11 @@ static void nativeSetThreads(JNIEnv* env, jclass clazz, jlong nativeSessionPtr, for (size_t i = 0; i < tidsArray.size(); ++i) { tidsVector.push_back(static_cast<int32_t>(tidsArray[i])); } gAPH_setThreadsFn(reinterpret_cast<APerformanceHintSession*>(nativeSessionPtr), int err = gAPH_setThreadsFn(reinterpret_cast<APerformanceHintSession*>(nativeSessionPtr), tidsVector.data(), tidsVector.size()); if (err != 0) { throwExceptionForErrno(env, err, "Failed to set threads for hint session"); } } // This call should only be used for validation in tests only. This call will initiate two IPC Loading
core/tests/coretests/src/android/os/PerformanceHintManagerTest.java +11 −2 Original line number Diff line number Diff line Loading @@ -139,11 +139,20 @@ public class PerformanceHintManagerTest { } @Test public void testSetThreadsWithIllegalArgument() { public void testSetThreads_emptyTids() { Session session = createSession(); assumeNotNull(session); assertThrows(IllegalArgumentException.class, () -> { session.setThreads(new int[]{}); }); } @Test public void testSetThreads_invalidTids() { Session session = createSession(); assumeNotNull(session); assertThrows(SecurityException.class, () -> { session.setThreads(new int[]{-1}); }); } }
native/android/performance_hint.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -274,9 +274,10 @@ int APerformanceHintSession::setThreads(const int32_t* threadIds, size_t size) { binder::Status ret = mHintManager->setHintSessionThreads(mHintSession, tids); if (!ret.isOk()) { ALOGE("%s: failed: %s", __FUNCTION__, ret.exceptionMessage().c_str()); if (ret.exceptionCode() == binder::Status::Exception::EX_SECURITY || ret.exceptionCode() == binder::Status::Exception::EX_ILLEGAL_ARGUMENT) { if (ret.exceptionCode() == binder::Status::Exception::EX_ILLEGAL_ARGUMENT) { return EINVAL; } else if (ret.exceptionCode() == binder::Status::Exception::EX_SECURITY) { return EPERM; } return EPIPE; } Loading
native/android/tests/performance_hint/PerformanceHintNativeTest.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -178,4 +178,15 @@ TEST_F(PerformanceHintTest, SetThreads) { .WillOnce(Return(Status())); result = APerformanceHint_setThreads(session, newTids.data(), newTids.size()); EXPECT_EQ(0, result); testing::Mock::VerifyAndClearExpectations(mMockIHintManager); std::vector<int32_t> invalidTids; auto status = Status::fromExceptionCode(binder::Status::Exception::EX_SECURITY); invalidTids.push_back(4); invalidTids.push_back(6); EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(invalidTids))) .Times(Exactly(1)) .WillOnce(Return(status)); result = APerformanceHint_setThreads(session, invalidTids.data(), invalidTids.size()); EXPECT_EQ(EPERM, result); }