diff options
3 files changed, 46 insertions, 0 deletions
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp index c25df6e08fd0..c571b742d2d1 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -144,6 +144,8 @@ APerformanceHintSession* APerformanceHintManager::createSession( binder::Status ret = mHintManager->createHintSession(mToken, tids, initialTargetWorkDurationNanos, &session); if (!ret.isOk() || !session) { + ALOGE("%s: PerformanceHint cannot create hint session. %s", __FUNCTION__, + ret.exceptionMessage().c_str()); return nullptr; } return new APerformanceHintSession(mHintManager, std::move(session), mPreferredRateNanos, 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 33bed3d42e50..577468b0c749 100644 --- a/services/core/java/com/android/server/power/hint/HintManagerService.java +++ b/services/core/java/com/android/server/power/hint/HintManagerService.java @@ -56,6 +56,7 @@ import java.util.Objects; public final class HintManagerService extends SystemService { private static final String TAG = "HintManagerService"; private static final boolean DEBUG = false; + private static final int MAX_HINT_SESSION_COUNT_PER_UID = 20; @VisibleForTesting final long mHintSessionPreferredRate; // Multi-level map storing all active AppHintSessions. @@ -367,6 +368,23 @@ public final class HintManagerService extends SystemService { + " not be empty."); final int callingUid = Binder.getCallingUid(); + if (callingUid != Process.SYSTEM_UID) { + int sessionCount = 0; + synchronized (mLock) { + ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap = + mActiveSessions.get(callingUid); + if (tokenMap != null) { + for (ArraySet<AppHintSession> arr : tokenMap.values()) { + sessionCount += arr.size(); + } + } + } + if (sessionCount >= MAX_HINT_SESSION_COUNT_PER_UID) { + throw new IllegalStateException( + "Max session count limit reached: " + sessionCount); + } + } + final int callingTgid = Process.getThreadGroupLeader(Binder.getCallingPid()); final long identity = Binder.clearCallingIdentity(); try { diff --git a/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java index 9fca513e50b9..ee3ab9744fdd 100644 --- a/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java @@ -149,6 +149,32 @@ public class HintManagerServiceTest { } @Test + public void testCreateHintSession_exceedsLimit() throws Exception { + HintManagerService service = createService(); + IBinder token1 = new Binder(); + IBinder token2 = new Binder(); + + for (int i = 0; i < 10; i++) { + IHintSession a = service.getBinderServiceInstance().createHintSession(token1, + SESSION_TIDS_A, DEFAULT_TARGET_DURATION); + assertNotNull(a); + } + + for (int i = 0; i < 10; i++) { + IHintSession b = service.getBinderServiceInstance().createHintSession(token2, + SESSION_TIDS_B, DEFAULT_TARGET_DURATION); + assertNotNull(b); + } + + assertThrows(IllegalStateException.class, + () -> service.getBinderServiceInstance().createHintSession(token1, SESSION_TIDS_A, + DEFAULT_TARGET_DURATION)); + assertThrows(IllegalStateException.class, + () -> service.getBinderServiceInstance().createHintSession(token2, SESSION_TIDS_B, + DEFAULT_TARGET_DURATION)); + } + + @Test public void testPauseResumeHintSession() throws Exception { HintManagerService service = createService(); IBinder token = new Binder(); |