diff options
3 files changed, 55 insertions, 19 deletions
diff --git a/core/java/android/os/PerformanceHintManager.java b/core/java/android/os/PerformanceHintManager.java index f79d6e6da1f8..f6618d00dd01 100644 --- a/core/java/android/os/PerformanceHintManager.java +++ b/core/java/android/os/PerformanceHintManager.java @@ -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. */ @@ -54,15 +55,20 @@ public final class PerformanceHintManager { * duration. * * @param tids The list of threads to be associated with this session. They must be part of - * this process' thread group. + * this process' thread group * @param initialTargetWorkDurationNanos The desired duration in nanoseconds for the new - * session. + * session * @return the new session if it is supported on this device, null if hint session is not - * supported on this device. + * supported on this device or the tid doesn't belong to the application + * @throws IllegalArgumentException if the thread id list is empty, or + * initialTargetWorkDurationNanos is non-positive */ @Nullable public Session createHintSession(@NonNull int[] tids, long initialTargetWorkDurationNanos) { - Preconditions.checkNotNull(tids, "tids cannot be null"); + Objects.requireNonNull(tids, "tids cannot be null"); + if (tids.length == 0) { + throw new IllegalArgumentException("thread id list can't be empty."); + } Preconditions.checkArgumentPositive(initialTargetWorkDurationNanos, "the hint target duration should be positive."); long nativeSessionPtr = nativeCreateSession(mNativeManagerPtr, tids, @@ -74,7 +80,7 @@ public final class PerformanceHintManager { /** * Get preferred update rate information for this device. * - * @return the preferred update rate supported by device software. + * @return the preferred update rate supported by device software */ public long getPreferredUpdateRateNanos() { return nativeGetPreferredUpdateRateNanos(mNativeManagerPtr); @@ -208,7 +214,7 @@ public final class PerformanceHintManager { /** * Sends performance hints to inform the hint session of changes in the workload. * - * @param hint The hint to send to the session. + * @param hint The hint to send to the session * * @hide */ @@ -229,11 +235,11 @@ public final class PerformanceHintManager { * Note that this is not an oneway method. * * @param tids The list of threads to be associated with this session. They must be - * part of this app's thread group. + * part of this app's thread group * - * @throws IllegalStateException if the hint session is not in the foreground. - * @throws IllegalArgumentException if the thread id list is empty. - * @throws SecurityException if any thread id doesn't belong to the application. + * @throws IllegalStateException if the hint session is not in the foreground + * @throws IllegalArgumentException if the thread id list is empty + * @throws SecurityException if any thread id doesn't belong to the application */ public void setThreads(@NonNull int[] tids) { if (mNativeSessionPtr == 0) { diff --git a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java index 7eefbbca2d01..7c70449dafba 100644 --- a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java +++ b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java @@ -69,6 +69,24 @@ public class PerformanceHintManagerTest { } @Test + public void testCreateHintSession_noTids() { + assertThrows(NullPointerException.class, () -> { + mPerformanceHintManager.createHintSession( + null, DEFAULT_TARGET_NS); + }); + assertThrows(IllegalArgumentException.class, () -> { + mPerformanceHintManager.createHintSession( + new int[]{}, DEFAULT_TARGET_NS); + }); + } + + @Test + public void testCreateHintSession_invalidTids() { + assertNull(mPerformanceHintManager.createHintSession( + new int[]{-1}, DEFAULT_TARGET_NS)); + } + + @Test public void testGetPreferredUpdateRateNanos() { if (createSession() != null) { assertTrue(mPerformanceHintManager.getPreferredUpdateRateNanos() > 0); 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 1a91d252c431..8dcf3e06330f 100644 --- a/services/core/java/com/android/server/power/hint/HintManagerService.java +++ b/services/core/java/com/android/server/power/hint/HintManagerService.java @@ -304,7 +304,8 @@ public final class HintManagerService extends SystemService { return mService; } - private boolean checkTidValid(int uid, int tgid, int [] tids) { + // returns the first invalid tid or null if not found + private Integer checkTidValid(int uid, int tgid, int [] tids) { // Make sure all tids belongs to the same UID (including isolated UID), // tids can belong to different application processes. List<Integer> isolatedPids = null; @@ -326,19 +327,24 @@ public final class HintManagerService extends SystemService { if (isolatedPids == null) { // To avoid deadlock, do not call into AMS if the call is from system. if (uid == Process.SYSTEM_UID) { - return false; + return threadId; } isolatedPids = mAmInternal.getIsolatedProcesses(uid); if (isolatedPids == null) { - return false; + return threadId; } } if (isolatedPids.contains(pidOfThreadId)) { continue; } - return false; + return threadId; } - return true; + return null; + } + + private String formatTidCheckErrMsg(int callingUid, int[] tids, Integer invalidTid) { + return "Tid" + invalidTid + " from list " + Arrays.toString(tids) + + " doesn't belong to the calling application" + callingUid; } @VisibleForTesting @@ -356,8 +362,11 @@ public final class HintManagerService extends SystemService { final int callingTgid = Process.getThreadGroupLeader(Binder.getCallingPid()); final long identity = Binder.clearCallingIdentity(); try { - if (!checkTidValid(callingUid, callingTgid, tids)) { - throw new SecurityException("Some tid doesn't belong to the application"); + final Integer invalidTid = checkTidValid(callingUid, callingTgid, tids); + if (invalidTid != null) { + final String errMsg = formatTidCheckErrMsg(callingUid, tids, invalidTid); + Slogf.w(TAG, errMsg); + throw new SecurityException(errMsg); } long halSessionPtr = mNativeWrapper.halCreateHintSession(callingTgid, callingUid, @@ -561,8 +570,11 @@ public final class HintManagerService extends SystemService { final int callingTgid = Process.getThreadGroupLeader(Binder.getCallingPid()); final long identity = Binder.clearCallingIdentity(); try { - if (!checkTidValid(callingUid, callingTgid, tids)) { - throw new SecurityException("Some tid doesn't belong to the application."); + final Integer invalidTid = checkTidValid(callingUid, callingTgid, tids); + if (invalidTid != null) { + final String errMsg = formatTidCheckErrMsg(callingUid, tids, invalidTid); + Slogf.w(TAG, errMsg); + throw new SecurityException(errMsg); } } finally { Binder.restoreCallingIdentity(identity); |