Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 40aba00f authored by Xiang Wang's avatar Xiang Wang
Browse files

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
parent badee29d
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -28,6 +28,5 @@ parcelable CpuHeadroomParamsInternal {
    int[] tids;
    int calculationWindowMillis = 1000;
    CpuHeadroomParams.CalculationType calculationType = CpuHeadroomParams.CalculationType.MIN;
    CpuHeadroomParams.SelectionType selectionType = CpuHeadroomParams.SelectionType.ALL;
}
+60 −78
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.hardware.power.GpuHeadroomResult;
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 @@ public final class HintManagerService extends SystemService {
    // 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 @@ public final class HintManagerService extends SystemService {

    private final IPower mPowerHal;
    private int mPowerHalVersion;
    private SupportInfo mSupportInfo = null;
    private final PackageManager mPackageManager;

    private boolean mUsesFmq;
@@ -246,13 +247,11 @@ public final class HintManagerService extends SystemService {

    @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 @@ public final class HintManagerService extends SystemService {
        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);
        }
        return HEADROOM_INTERVAL_UNSUPPORTED;
            throw new IllegalStateException("Could not contact PowerHAL!", e);
        }

    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());
                }
            }
        } 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);
        }
        return HEADROOM_INTERVAL_UNSUPPORTED;
        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
            }
            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;
            }
        }
        supportInfo.headroom = new SupportInfo.HeadroomSupportInfo();
        supportInfo.headroom.isCpuSupported = false;
        supportInfo.headroom.isGpuSupported = false;
        return supportInfo;
    }

    private ServiceThread createCleanUpThread() {
@@ -555,7 +545,7 @@ public final class HintManagerService extends SystemService {
            return targetDurations;
        }
    }
    private boolean isHalSupported() {
    private boolean isHintSessionSupported() {
        return mHintSessionPreferredRate != -1;
    }

@@ -1248,7 +1238,7 @@ public final class HintManagerService extends SystemService {
        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 @@ public final class HintManagerService extends SystemService {

        @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 @@ public final class HintManagerService extends SystemService {

        @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 @@ public final class HintManagerService extends SystemService {

        @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 @@ public final class HintManagerService extends SystemService {
            }
            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 @@ public final class HintManagerService extends SystemService {
                    }
                }
            }
            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");
+17 −14
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ import android.hardware.power.GpuHeadroomResult;
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 @@ public class HintManagerServiceTest {

    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 @@ public class HintManagerServiceTest {
        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 @@ public class HintManagerServiceTest {
                    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 @@ public class HintManagerServiceTest {

    @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 @@ public class HintManagerServiceTest {
        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 @@ public class HintManagerServiceTest {
        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 @@ public class HintManagerServiceTest {

    @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 @@ public class HintManagerServiceTest {
        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());