summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--native/android/performance_hint.cpp2
-rw-r--r--services/core/java/com/android/server/power/hint/HintManagerService.java18
-rw-r--r--services/tests/servicestests/src/com/android/server/power/hint/HintManagerServiceTest.java26
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();