Remove headroom selection type and move interval to support info

Bug: 346604998
API-Coverage-Bug: 378780498
Flag: android.os.cpu_gpu_headrooms
Test: atest HeadroomTest PerformanceHintNativeTestCases \
            HintManagerServiceTest PowerHalWrapperAidlTest
Change-Id: I04045bd177fef4dfeaf0dbbd41d3c3fa5631fdae
diff --git a/core/java/android/os/CpuHeadroomParamsInternal.aidl b/core/java/android/os/CpuHeadroomParamsInternal.aidl
index d572f965..12b2093 100644
--- a/core/java/android/os/CpuHeadroomParamsInternal.aidl
+++ b/core/java/android/os/CpuHeadroomParamsInternal.aidl
@@ -28,6 +28,5 @@
     int[] tids;
     int calculationWindowMillis = 1000;
     CpuHeadroomParams.CalculationType calculationType = CpuHeadroomParams.CalculationType.MIN;
-    CpuHeadroomParams.SelectionType selectionType = CpuHeadroomParams.SelectionType.ALL;
 }
 
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 aba15c8..46960a8 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -40,6 +40,7 @@
 import android.hardware.power.IPower;
 import android.hardware.power.SessionConfig;
 import android.hardware.power.SessionTag;
+import android.hardware.power.SupportInfo;
 import android.hardware.power.WorkDuration;
 import android.os.Binder;
 import android.os.CpuHeadroomParamsInternal;
@@ -102,7 +103,6 @@
     // The minimum interval between the headroom calls as rate limiting.
     private static final int DEFAULT_GPU_HEADROOM_INTERVAL_MILLIS = 1000;
     private static final int DEFAULT_CPU_HEADROOM_INTERVAL_MILLIS = 1000;
-    private static final int HEADROOM_INTERVAL_UNSUPPORTED = -1;
 
 
     @VisibleForTesting final long mHintSessionPreferredRate;
@@ -180,6 +180,7 @@
 
     private final IPower mPowerHal;
     private int mPowerHalVersion;
+    private SupportInfo mSupportInfo = null;
     private final PackageManager mPackageManager;
 
     private boolean mUsesFmq;
@@ -246,13 +247,11 @@
 
     @GuardedBy("mCpuHeadroomLock")
     private final HeadroomCache<CpuHeadroomParams, CpuHeadroomResult> mCpuHeadroomCache;
-    private final long mCpuHeadroomIntervalMillis;
 
     private final Object mGpuHeadroomLock = new Object();
 
     @GuardedBy("mGpuHeadroomLock")
     private final HeadroomCache<GpuHeadroomParams, GpuHeadroomResult> mGpuHeadroomCache;
-    private final long mGpuHeadroomIntervalMillis;
 
     // these are set to default values in CpuHeadroomParamsInternal and GpuHeadroomParamsInternal
     private final int mDefaultCpuHeadroomCalculationWindowMillis;
@@ -294,79 +293,70 @@
         mPowerHal = injector.createIPower();
         mPowerHalVersion = 0;
         mUsesFmq = false;
-        long cpuHeadroomIntervalMillis = HEADROOM_INTERVAL_UNSUPPORTED;
-        long gpuHeadroomIntervalMillis = HEADROOM_INTERVAL_UNSUPPORTED;
         if (mPowerHal != null) {
-            try {
-                mPowerHalVersion = mPowerHal.getInterfaceVersion();
-                if (mPowerHal.getInterfaceVersion() >= 6) {
-                    if (SystemProperties.getBoolean(PROPERTY_USE_HAL_HEADROOMS, true)) {
-                        cpuHeadroomIntervalMillis = checkCpuHeadroomSupport();
-                        gpuHeadroomIntervalMillis = checkGpuHeadroomSupport();
-                    }
-                }
-            } catch (RemoteException e) {
-                throw new IllegalStateException("Could not contact PowerHAL!", e);
-            }
+            mSupportInfo = getSupportInfo();
         }
-        mCpuHeadroomIntervalMillis = cpuHeadroomIntervalMillis;
         mDefaultCpuHeadroomCalculationWindowMillis =
                 new CpuHeadroomParamsInternal().calculationWindowMillis;
         mDefaultGpuHeadroomCalculationWindowMillis =
                 new GpuHeadroomParamsInternal().calculationWindowMillis;
-        mGpuHeadroomIntervalMillis = gpuHeadroomIntervalMillis;
-        if (mCpuHeadroomIntervalMillis > 0) {
-            mCpuHeadroomCache = new HeadroomCache<>(2, mCpuHeadroomIntervalMillis);
+        if (mSupportInfo.headroom.isCpuSupported) {
+            mCpuHeadroomCache = new HeadroomCache<>(2, mSupportInfo.headroom.cpuMinIntervalMillis);
         } else {
             mCpuHeadroomCache = null;
         }
-        if (mGpuHeadroomIntervalMillis > 0) {
-            mGpuHeadroomCache = new HeadroomCache<>(2, mGpuHeadroomIntervalMillis);
+        if (mSupportInfo.headroom.isGpuSupported) {
+            mGpuHeadroomCache = new HeadroomCache<>(2, mSupportInfo.headroom.gpuMinIntervalMillis);
         } else {
             mGpuHeadroomCache = null;
         }
     }
 
-    private long checkCpuHeadroomSupport() {
-        final CpuHeadroomParams params = new CpuHeadroomParams();
-        params.tids = new int[]{Process.myPid()};
+    SupportInfo getSupportInfo() {
         try {
-            synchronized (mCpuHeadroomLock) {
-                final CpuHeadroomResult ret = mPowerHal.getCpuHeadroom(params);
-                if (ret != null && ret.getTag() == CpuHeadroomResult.globalHeadroom
-                        && !Float.isNaN(ret.getGlobalHeadroom())) {
-                    return Math.max(
-                            DEFAULT_CPU_HEADROOM_INTERVAL_MILLIS,
-                            mPowerHal.getCpuHeadroomMinIntervalMillis());
-                }
+            mPowerHalVersion = mPowerHal.getInterfaceVersion();
+            if (mPowerHalVersion >= 6) {
+                return mPowerHal.getSupportInfo();
             }
-
-        } catch (UnsupportedOperationException e) {
-            Slog.w(TAG, "getCpuHeadroom HAL API is not supported, params: " + params, e);
         } catch (RemoteException e) {
-            Slog.e(TAG, "getCpuHeadroom HAL API fails, disabling the API, params: " + params, e);
+            throw new IllegalStateException("Could not contact PowerHAL!", e);
         }
-        return HEADROOM_INTERVAL_UNSUPPORTED;
-    }
 
-    private long checkGpuHeadroomSupport() {
-        final GpuHeadroomParams params = new GpuHeadroomParams();
-        try {
-            synchronized (mGpuHeadroomLock) {
-                final GpuHeadroomResult ret = mPowerHal.getGpuHeadroom(params);
-                if (ret != null && ret.getTag() == GpuHeadroomResult.globalHeadroom && !Float.isNaN(
-                        ret.getGlobalHeadroom())) {
-                    return Math.max(
-                            DEFAULT_GPU_HEADROOM_INTERVAL_MILLIS,
-                            mPowerHal.getGpuHeadroomMinIntervalMillis());
-                }
+        SupportInfo supportInfo = new SupportInfo();
+        supportInfo.usesSessions = isHintSessionSupported();
+        // Global boosts & modes aren't currently relevant for HMS clients
+        supportInfo.boosts = 0;
+        supportInfo.modes = 0;
+        supportInfo.sessionHints = 0;
+        supportInfo.sessionModes = 0;
+        supportInfo.sessionTags = 0;
+        if (isHintSessionSupported()) {
+            if (mPowerHalVersion == 4) {
+                // Assume we support the V4 hints & modes unless specified
+                // otherwise; this is to avoid breaking backwards compat
+                // since we historically just assumed they were.
+                supportInfo.sessionHints = 31; // first 5 bits are ones
             }
-        } catch (UnsupportedOperationException e) {
-            Slog.w(TAG, "getGpuHeadroom HAL API is not supported, params: " + params, e);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "getGpuHeadroom HAL API fails, disabling the API, params: " + params, e);
+            if (mPowerHalVersion == 5) {
+                // Assume we support the V5 hints & modes unless specified
+                // otherwise; this is to avoid breaking backwards compat
+                // since we historically just assumed they were.
+
+                // Hal V5 has 8 modes, all of which it assumes are supported,
+                // so we represent that by having the first 8 bits set
+                supportInfo.sessionHints = 255; // first 8 bits are ones
+                // Hal V5 has 1 mode which it assumes is supported, so we
+                // represent that by having the first bit set
+                supportInfo.sessionModes = 1;
+                // Hal V5 has 5 tags, all of which it assumes are supported,
+                // so we represent that by having the first 5 bits set
+                supportInfo.sessionTags = 31;
+            }
         }
-        return HEADROOM_INTERVAL_UNSUPPORTED;
+        supportInfo.headroom = new SupportInfo.HeadroomSupportInfo();
+        supportInfo.headroom.isCpuSupported = false;
+        supportInfo.headroom.isGpuSupported = false;
+        return supportInfo;
     }
 
     private ServiceThread createCleanUpThread() {
@@ -555,7 +545,7 @@
             return targetDurations;
         }
     }
-    private boolean isHalSupported() {
+    private boolean isHintSessionSupported() {
         return mHintSessionPreferredRate != -1;
     }
 
@@ -1248,7 +1238,7 @@
         public IHintSession createHintSessionWithConfig(@NonNull IBinder token,
                     @SessionTag int tag, SessionCreationConfig creationConfig,
                     SessionConfig config) {
-            if (!isHalSupported()) {
+            if (!isHintSessionSupported()) {
                 throw new UnsupportedOperationException("PowerHAL is not supported!");
             }
 
@@ -1460,14 +1450,13 @@
 
         @Override
         public CpuHeadroomResult getCpuHeadroom(@NonNull CpuHeadroomParamsInternal params) {
-            if (mCpuHeadroomIntervalMillis <= 0) {
+            if (!mSupportInfo.headroom.isCpuSupported) {
                 throw new UnsupportedOperationException();
             }
             final CpuHeadroomParams halParams = new CpuHeadroomParams();
             halParams.tids = new int[]{Binder.getCallingPid()};
             halParams.calculationType = params.calculationType;
             halParams.calculationWindowMillis = params.calculationWindowMillis;
-            halParams.selectionType = params.selectionType;
             if (params.usesDeviceHeadroom) {
                 halParams.tids = new int[]{};
             } else if (params.tids != null && params.tids.length > 0) {
@@ -1516,7 +1505,7 @@
 
         @Override
         public GpuHeadroomResult getGpuHeadroom(@NonNull GpuHeadroomParamsInternal params) {
-            if (mGpuHeadroomIntervalMillis <= 0) {
+            if (!mSupportInfo.headroom.isGpuSupported) {
                 throw new UnsupportedOperationException();
             }
             final GpuHeadroomParams halParams = new GpuHeadroomParams();
@@ -1551,18 +1540,18 @@
 
         @Override
         public long getCpuHeadroomMinIntervalMillis() {
-            if (mCpuHeadroomIntervalMillis <= 0) {
+            if (!mSupportInfo.headroom.isCpuSupported) {
                 throw new UnsupportedOperationException();
             }
-            return mCpuHeadroomIntervalMillis;
+            return mSupportInfo.headroom.cpuMinIntervalMillis;
         }
 
         @Override
         public long getGpuHeadroomMinIntervalMillis() {
-            if (mGpuHeadroomIntervalMillis <= 0) {
+            if (!mSupportInfo.headroom.isGpuSupported) {
                 throw new UnsupportedOperationException();
             }
-            return mGpuHeadroomIntervalMillis;
+            return mSupportInfo.headroom.gpuMinIntervalMillis;
         }
 
         @Override
@@ -1572,7 +1561,7 @@
             }
             pw.println("HintSessionPreferredRate: " + mHintSessionPreferredRate);
             pw.println("MaxGraphicsPipelineThreadsCount: " + MAX_GRAPHICS_PIPELINE_THREADS_COUNT);
-            pw.println("HAL Support: " + isHalSupported());
+            pw.println("HAL Support: " + isHintSessionSupported());
             pw.println("Active Sessions:");
             synchronized (mLock) {
                 for (int i = 0; i < mActiveSessions.size(); i++) {
@@ -1588,20 +1577,13 @@
                     }
                 }
             }
-            pw.println("CPU Headroom Interval: " + mCpuHeadroomIntervalMillis);
-            pw.println("GPU Headroom Interval: " + mGpuHeadroomIntervalMillis);
+            pw.println("CPU Headroom Interval: " + mSupportInfo.headroom.cpuMinIntervalMillis);
+            pw.println("GPU Headroom Interval: " + mSupportInfo.headroom.gpuMinIntervalMillis);
             try {
                 CpuHeadroomParamsInternal params = new CpuHeadroomParamsInternal();
-                params.selectionType = CpuHeadroomParams.SelectionType.ALL;
                 params.usesDeviceHeadroom = true;
                 CpuHeadroomResult ret = getCpuHeadroom(params);
                 pw.println("CPU headroom: " + (ret == null ? "N/A" : ret.getGlobalHeadroom()));
-                params = new CpuHeadroomParamsInternal();
-                params.selectionType = CpuHeadroomParams.SelectionType.PER_CORE;
-                params.usesDeviceHeadroom = true;
-                ret = getCpuHeadroom(params);
-                pw.println("CPU headroom per core: " + (ret == null ? "N/A"
-                        : Arrays.toString(ret.getPerCoreHeadroom())));
             } catch (Exception e) {
                 Slog.d(TAG, "Failed to dump CPU headroom", e);
                 pw.println("CPU headroom: N/A");
diff --git a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
index 313c01d..a9b4ca1 100644
--- a/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
+++ b/services/tests/performancehinttests/src/com/android/server/power/hint/HintManagerServiceTest.java
@@ -58,6 +58,7 @@
 import android.hardware.power.IPower;
 import android.hardware.power.SessionConfig;
 import android.hardware.power.SessionTag;
+import android.hardware.power.SupportInfo;
 import android.hardware.power.WorkDuration;
 import android.os.Binder;
 import android.os.CpuHeadroomParamsInternal;
@@ -159,6 +160,7 @@
 
     private HintManagerService mService;
     private ChannelConfig mConfig;
+    private SupportInfo mSupportInfo;
 
     private static Answer<Long> fakeCreateWithConfig(Long ptr, Long sessionId) {
         return new Answer<Long>() {
@@ -179,6 +181,18 @@
         mConfig.eventFlagDescriptor = new MQDescriptor<Byte, Byte>();
         ApplicationInfo applicationInfo = new ApplicationInfo();
         applicationInfo.category = ApplicationInfo.CATEGORY_GAME;
+        mSupportInfo = new SupportInfo();
+        mSupportInfo.usesSessions = true;
+        mSupportInfo.sessionHints = 5;
+        mSupportInfo.sessionModes = 1;
+        mSupportInfo.modes = 3;
+        mSupportInfo.boosts = 3;
+        mSupportInfo.sessionTags = 63;
+        mSupportInfo.headroom = new SupportInfo.HeadroomSupportInfo();
+        mSupportInfo.headroom.isCpuSupported = true;
+        mSupportInfo.headroom.cpuMinIntervalMillis = 2000;
+        mSupportInfo.headroom.isGpuSupported = true;
+        mSupportInfo.headroom.gpuMinIntervalMillis = 2000;
         when(mContext.getPackageManager()).thenReturn(mMockPackageManager);
         when(mMockPackageManager.getNameForUid(anyInt())).thenReturn(TEST_APP_NAME);
         when(mMockPackageManager.getApplicationInfo(eq(TEST_APP_NAME), anyInt()))
@@ -205,6 +219,7 @@
                     SESSION_IDS[2]));
 
         when(mIPowerMock.getInterfaceVersion()).thenReturn(6);
+        when(mIPowerMock.getSupportInfo()).thenReturn(mSupportInfo);
         when(mIPowerMock.getSessionChannel(anyInt(), anyInt())).thenReturn(mConfig);
         LocalServices.removeServiceForTest(ActivityManagerInternal.class);
         LocalServices.addService(ActivityManagerInternal.class, mAmInternalMock);
@@ -1247,28 +1262,22 @@
 
     @Test
     public void testCpuHeadroomCache() throws Exception {
-        when(mIPowerMock.getCpuHeadroomMinIntervalMillis()).thenReturn(2000L);
         CpuHeadroomParamsInternal params1 = new CpuHeadroomParamsInternal();
         CpuHeadroomParams halParams1 = new CpuHeadroomParams();
         halParams1.calculationType = CpuHeadroomParams.CalculationType.MIN;
-        halParams1.selectionType = CpuHeadroomParams.SelectionType.ALL;
         halParams1.tids = new int[]{Process.myPid()};
 
         CpuHeadroomParamsInternal params2 = new CpuHeadroomParamsInternal();
         params2.usesDeviceHeadroom = true;
         params2.calculationType = CpuHeadroomParams.CalculationType.MIN;
-        params2.selectionType = CpuHeadroomParams.SelectionType.PER_CORE;
         CpuHeadroomParams halParams2 = new CpuHeadroomParams();
         halParams2.calculationType = CpuHeadroomParams.CalculationType.MIN;
-        halParams2.selectionType = CpuHeadroomParams.SelectionType.PER_CORE;
         halParams2.tids = new int[]{};
 
         CpuHeadroomParamsInternal params3 = new CpuHeadroomParamsInternal();
         params3.calculationType = CpuHeadroomParams.CalculationType.AVERAGE;
-        params3.selectionType = CpuHeadroomParams.SelectionType.ALL;
         CpuHeadroomParams halParams3 = new CpuHeadroomParams();
         halParams3.calculationType = CpuHeadroomParams.CalculationType.AVERAGE;
-        halParams3.selectionType = CpuHeadroomParams.SelectionType.ALL;
         halParams3.tids = new int[]{Process.myPid()};
 
         // this params should not be cached as the window is not default
@@ -1276,15 +1285,14 @@
         params4.calculationWindowMillis = 123;
         CpuHeadroomParams halParams4 = new CpuHeadroomParams();
         halParams4.calculationType = CpuHeadroomParams.CalculationType.MIN;
-        halParams4.selectionType = CpuHeadroomParams.SelectionType.ALL;
         halParams4.calculationWindowMillis = 123;
         halParams4.tids = new int[]{Process.myPid()};
 
         float headroom1 = 0.1f;
         CpuHeadroomResult halRet1 = CpuHeadroomResult.globalHeadroom(headroom1);
         when(mIPowerMock.getCpuHeadroom(eq(halParams1))).thenReturn(halRet1);
-        float[] headroom2 = new float[] {0.2f, 0.2f};
-        CpuHeadroomResult halRet2 = CpuHeadroomResult.perCoreHeadroom(headroom2);
+        float headroom2 = 0.2f;
+        CpuHeadroomResult halRet2 = CpuHeadroomResult.globalHeadroom(headroom2);
         when(mIPowerMock.getCpuHeadroom(eq(halParams2))).thenReturn(halRet2);
         float headroom3 = 0.3f;
         CpuHeadroomResult halRet3 = CpuHeadroomResult.globalHeadroom(headroom3);
@@ -1296,8 +1304,6 @@
         HintManagerService service = createService();
         clearInvocations(mIPowerMock);
 
-        service.getBinderServiceInstance().getCpuHeadroomMinIntervalMillis();
-        verify(mIPowerMock, times(0)).getCpuHeadroomMinIntervalMillis();
         assertEquals(halRet1, service.getBinderServiceInstance().getCpuHeadroom(params1));
         verify(mIPowerMock, times(1)).getCpuHeadroom(eq(halParams1));
         assertEquals(halRet2, service.getBinderServiceInstance().getCpuHeadroom(params2));
@@ -1348,7 +1354,6 @@
 
     @Test
     public void testGpuHeadroomCache() throws Exception {
-        when(mIPowerMock.getGpuHeadroomMinIntervalMillis()).thenReturn(2000L);
         GpuHeadroomParamsInternal params1 = new GpuHeadroomParamsInternal();
         GpuHeadroomParams halParams1 = new GpuHeadroomParams();
         halParams1.calculationType = GpuHeadroomParams.CalculationType.MIN;
@@ -1369,8 +1374,6 @@
         HintManagerService service = createService();
         clearInvocations(mIPowerMock);
 
-        service.getBinderServiceInstance().getGpuHeadroomMinIntervalMillis();
-        verify(mIPowerMock, times(0)).getGpuHeadroomMinIntervalMillis();
         assertEquals(halRet1, service.getBinderServiceInstance().getGpuHeadroom(params1));
         assertEquals(halRet2, service.getBinderServiceInstance().getGpuHeadroom(params2));
         verify(mIPowerMock, times(2)).getGpuHeadroom(any());