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

Commit 6dbd1f95 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Change to use support info for interval millis" into main

parents 896dbf9e 2a1c9e43
Loading
Loading
Loading
Loading
+2 −10
Original line number Diff line number Diff line
@@ -344,11 +344,7 @@ public class SystemHealthManager {
                || !mHintManagerClientData.supportInfo.headroom.isCpuSupported) {
            throw new UnsupportedOperationException();
        }
        try {
            return mHintManager.getCpuHeadroomMinIntervalMillis();
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
        return mHintManagerClientData.supportInfo.headroom.cpuMinIntervalMillis;
    }

    /**
@@ -366,11 +362,7 @@ public class SystemHealthManager {
                || !mHintManagerClientData.supportInfo.headroom.isGpuSupported) {
            throw new UnsupportedOperationException();
        }
        try {
            return mHintManager.getGpuHeadroomMinIntervalMillis();
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
        return mHintManagerClientData.supportInfo.headroom.gpuMinIntervalMillis;
    }

    /**
+153 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.os;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.hardware.power.CpuHeadroomResult;
import android.hardware.power.GpuHeadroomResult;
import android.hardware.power.SupportInfo;
import android.os.health.SystemHealthManager;

import androidx.test.ext.junit.runners.AndroidJUnit4;

import com.android.internal.app.IBatteryStats;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@RunWith(AndroidJUnit4.class)
public class SystemHealthManagerUnitTest {
    @Mock
    private IBatteryStats mBatteryStats;
    @Mock
    private IPowerStatsService mPowerStats;
    @Mock
    private IHintManager mHintManager;
    private SystemHealthManager mSystemHealthManager;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        IHintManager.HintManagerClientData clientData = new IHintManager.HintManagerClientData();
        clientData.supportInfo = new SupportInfo();
        clientData.maxCpuHeadroomThreads = 10;
        clientData.supportInfo.headroom = new SupportInfo.HeadroomSupportInfo();
        clientData.supportInfo.headroom.isCpuSupported = true;
        clientData.supportInfo.headroom.isGpuSupported = true;
        clientData.supportInfo.headroom.cpuMinCalculationWindowMillis = 45;
        clientData.supportInfo.headroom.cpuMaxCalculationWindowMillis = 9999;
        clientData.supportInfo.headroom.gpuMinCalculationWindowMillis = 46;
        clientData.supportInfo.headroom.gpuMaxCalculationWindowMillis = 9998;
        clientData.supportInfo.headroom.cpuMinIntervalMillis = 999;
        clientData.supportInfo.headroom.gpuMinIntervalMillis = 998;
        when(mHintManager.getClientData()).thenReturn(clientData);
        mSystemHealthManager = new SystemHealthManager(mBatteryStats, mPowerStats, mHintManager);
    }

    @Test
    public void testHeadroomParamsValueRange() {
        assertEquals(999, mSystemHealthManager.getCpuHeadroomMinIntervalMillis());
        assertEquals(998, mSystemHealthManager.getGpuHeadroomMinIntervalMillis());
        assertEquals(45, (int) mSystemHealthManager.getCpuHeadroomCalculationWindowRange().first);
        assertEquals(9999,
                (int) mSystemHealthManager.getCpuHeadroomCalculationWindowRange().second);
        assertEquals(46, (int) mSystemHealthManager.getGpuHeadroomCalculationWindowRange().first);
        assertEquals(9998,
                (int) mSystemHealthManager.getGpuHeadroomCalculationWindowRange().second);
        assertEquals(10, (int) mSystemHealthManager.getMaxCpuHeadroomTidsSize());
    }

    @Test
    public void testGetCpuHeadroom() throws RemoteException, InterruptedException {
        final CpuHeadroomParams params1 = null;
        final CpuHeadroomParamsInternal internalParams1 = new CpuHeadroomParamsInternal();

        final CpuHeadroomParams params2 = new CpuHeadroomParams.Builder()
                .setCalculationWindowMillis(100)
                .build();
        final CpuHeadroomParamsInternal internalParams2 = new CpuHeadroomParamsInternal();
        internalParams2.calculationWindowMillis = 100;

        final CpuHeadroomParams params3 = new CpuHeadroomParams.Builder()
                .setCalculationType(CpuHeadroomParams.CPU_HEADROOM_CALCULATION_TYPE_AVERAGE)
                .build();
        final CpuHeadroomParamsInternal internalParams3 = new CpuHeadroomParamsInternal();
        internalParams3.calculationType =
                (byte) CpuHeadroomParams.CPU_HEADROOM_CALCULATION_TYPE_AVERAGE;

        final CpuHeadroomParams params4 = new CpuHeadroomParams.Builder()
                .setTids(1000, 1001)
                .build();
        final CpuHeadroomParamsInternal internalParams4 = new CpuHeadroomParamsInternal();
        internalParams4.tids = new int[]{1000, 1001};

        when(mHintManager.getCpuHeadroom(internalParams1)).thenReturn(
                CpuHeadroomResult.globalHeadroom(99f));
        when(mHintManager.getCpuHeadroom(internalParams2)).thenReturn(
                CpuHeadroomResult.globalHeadroom(98f));
        when(mHintManager.getCpuHeadroom(internalParams3)).thenReturn(
                CpuHeadroomResult.globalHeadroom(97f));
        when(mHintManager.getCpuHeadroom(internalParams4)).thenReturn(null);

        assertEquals(99f, mSystemHealthManager.getCpuHeadroom(params1), 0.001f);
        assertEquals(98f, mSystemHealthManager.getCpuHeadroom(params2), 0.001f);
        assertEquals(97f, mSystemHealthManager.getCpuHeadroom(params3), 0.001f);
        assertTrue(Float.isNaN(mSystemHealthManager.getCpuHeadroom(params4)));
        verify(mHintManager, times(1)).getCpuHeadroom(internalParams1);
        verify(mHintManager, times(1)).getCpuHeadroom(internalParams2);
        verify(mHintManager, times(1)).getCpuHeadroom(internalParams3);
        verify(mHintManager, times(1)).getCpuHeadroom(internalParams4);
    }

    @Test
    public void testGetGpuHeadroom() throws RemoteException, InterruptedException {
        final GpuHeadroomParams params1 = null;
        final GpuHeadroomParamsInternal internalParams1 = new GpuHeadroomParamsInternal();
        final GpuHeadroomParams params2 = new GpuHeadroomParams.Builder()
                .setCalculationWindowMillis(100)
                .build();
        final GpuHeadroomParamsInternal internalParams2 = new GpuHeadroomParamsInternal();
        internalParams2.calculationWindowMillis = 100;
        final GpuHeadroomParams params3 = new GpuHeadroomParams.Builder()
                .setCalculationType(GpuHeadroomParams.GPU_HEADROOM_CALCULATION_TYPE_AVERAGE)
                .build();
        final GpuHeadroomParamsInternal internalParams3 = new GpuHeadroomParamsInternal();
        internalParams3.calculationType =
                (byte) GpuHeadroomParams.GPU_HEADROOM_CALCULATION_TYPE_AVERAGE;

        when(mHintManager.getGpuHeadroom(internalParams1)).thenReturn(
                GpuHeadroomResult.globalHeadroom(99f));
        when(mHintManager.getGpuHeadroom(internalParams2)).thenReturn(
                GpuHeadroomResult.globalHeadroom(98f));
        when(mHintManager.getGpuHeadroom(internalParams3)).thenReturn(null);

        assertEquals(99f, mSystemHealthManager.getGpuHeadroom(params1), 0.001f);
        assertEquals(98f, mSystemHealthManager.getGpuHeadroom(params2), 0.001f);
        assertTrue(Float.isNaN(mSystemHealthManager.getGpuHeadroom(params3)));
        verify(mHintManager, times(1)).getGpuHeadroom(internalParams1);
        verify(mHintManager, times(1)).getGpuHeadroom(internalParams2);
        verify(mHintManager, times(1)).getGpuHeadroom(internalParams3);
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -421,6 +421,7 @@ LIBANDROID {
LIBANDROID_PLATFORM {
  global:
    AThermal_setIThermalServiceForTesting;
    ASystemHealth_setIHintManagerForTesting;
    APerformanceHint_setIHintManagerForTesting;
    APerformanceHint_sendHint;
    APerformanceHint_getThreadIds;
+37 −23
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@
 * limitations under the License.
 */

#define LOG_TAG "system_health"

#include <aidl/android/hardware/power/CpuHeadroomParams.h>
#include <aidl/android/hardware/power/GpuHeadroomParams.h>
#include <aidl/android/os/CpuHeadroomParamsInternal.h>
@@ -23,6 +25,17 @@
#include <android/system_health.h>
#include <binder/IServiceManager.h>
#include <binder/Status.h>
#include <system_health_private.h>

#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <optional>
#include <utility>

#include "android-base/thread_annotations.h"
#include "utils/SystemClock.h"

using namespace android;
using namespace aidl::android::os;
@@ -55,9 +68,20 @@ private:
    IHintManager::HintManagerClientData mClientData;
};

static std::shared_ptr<IHintManager>* gIHintManagerForTesting = nullptr;
static std::shared_ptr<ASystemHealthManager> gSystemHealthManagerForTesting = nullptr;

ASystemHealthManager* ASystemHealthManager::getInstance() {
    static std::once_flag creationFlag;
    static ASystemHealthManager* instance = nullptr;
    if (gSystemHealthManagerForTesting) {
        return gSystemHealthManagerForTesting.get();
    }
    if (gIHintManagerForTesting) {
        gSystemHealthManagerForTesting =
                std::shared_ptr<ASystemHealthManager>(create(*gIHintManagerForTesting));
        return gSystemHealthManagerForTesting.get();
    }
    std::call_once(creationFlag, []() { instance = create(nullptr); });
    return instance;
}
@@ -121,7 +145,8 @@ int ASystemHealthManager::getCpuHeadroom(const ACpuHeadroomParams* params, float
        }
        return EPIPE;
    }
    *outHeadroom = res->get<hal::CpuHeadroomResult::Tag::globalHeadroom>();
    *outHeadroom = res ? res->get<hal::CpuHeadroomResult::Tag::globalHeadroom>()
                       : std::numeric_limits<float>::quiet_NaN();
    return OK;
}

@@ -155,37 +180,20 @@ int ASystemHealthManager::getGpuHeadroom(const AGpuHeadroomParams* params, float
        }
        return EPIPE;
    }
    *outHeadroom = res->get<hal::GpuHeadroomResult::Tag::globalHeadroom>();
    *outHeadroom = res ? res->get<hal::GpuHeadroomResult::Tag::globalHeadroom>()
                       : std::numeric_limits<float>::quiet_NaN();
    return OK;
}

int ASystemHealthManager::getCpuHeadroomMinIntervalMillis(int64_t* outMinIntervalMillis) {
    if (!mClientData.supportInfo.headroom.isCpuSupported) return ENOTSUP;
    int64_t minIntervalMillis = 0;
    ::ndk::ScopedAStatus ret = mHintManager->getCpuHeadroomMinIntervalMillis(&minIntervalMillis);
    if (!ret.isOk()) {
        ALOGE("ASystemHealth_getCpuHeadroomMinIntervalMillis fails: %s", ret.getMessage());
        if (ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
            return ENOTSUP;
        }
        return EPIPE;
    }
    *outMinIntervalMillis = minIntervalMillis;
    *outMinIntervalMillis = mClientData.supportInfo.headroom.cpuMinIntervalMillis;
    return OK;
}

int ASystemHealthManager::getGpuHeadroomMinIntervalMillis(int64_t* outMinIntervalMillis) {
    if (!mClientData.supportInfo.headroom.isGpuSupported) return ENOTSUP;
    int64_t minIntervalMillis = 0;
    ::ndk::ScopedAStatus ret = mHintManager->getGpuHeadroomMinIntervalMillis(&minIntervalMillis);
    if (!ret.isOk()) {
        ALOGE("ASystemHealth_getGpuHeadroomMinIntervalMillis fails: %s", ret.getMessage());
        if (ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
            return ENOTSUP;
        }
        return EPIPE;
    }
    *outMinIntervalMillis = minIntervalMillis;
    *outMinIntervalMillis = mClientData.supportInfo.headroom.gpuMinIntervalMillis;
    return OK;
}

@@ -298,7 +306,6 @@ void ACpuHeadroomParams_setTids(ACpuHeadroomParams* _Nonnull params, const int*
                                size_t tidsSize) {
    LOG_ALWAYS_FATAL_IF(tids == nullptr, "%s: tids should not be null", __FUNCTION__);
    params->tids.resize(tidsSize);
    params->tids.clear();
    for (int i = 0; i < (int)tidsSize; ++i) {
        LOG_ALWAYS_FATAL_IF(tids[i] <= 0, "ACpuHeadroomParams_setTids: Invalid non-positive tid %d",
                            tids[i]);
@@ -355,3 +362,10 @@ void ACpuHeadroomParams_destroy(ACpuHeadroomParams* _Nullable params) {
void AGpuHeadroomParams_destroy(AGpuHeadroomParams* _Nullable params) {
    delete params;
}

void ASystemHealth_setIHintManagerForTesting(void* iManager) {
    if (iManager == nullptr) {
        gSystemHealthManagerForTesting = nullptr;
    }
    gIHintManagerForTesting = static_cast<std::shared_ptr<IHintManager>*>(iManager);
}
+66 −0
Original line number Diff line number Diff line
// Copyright (C) 2024 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package {
    // See: http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
    // all of the 'license_kinds' from "frameworks_base_license"
    // to get the below license kinds:
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["frameworks_base_license"],
}

cc_test {
    name: "NativeSystemHealthUnitTestCases",

    multilib: {
        lib32: {
            suffix: "32",
        },
        lib64: {
            suffix: "64",
        },
    },

    srcs: ["NativeSystemHealthUnitTest.cpp"],

    shared_libs: [
        "libandroid",
        "libbinder",
        "libbinder_ndk",
        "liblog",
        "libpowermanager",
        "libutils",
    ],

    static_libs: [
        "libbase",
        "libgmock",
        "libgtest",
    ],
    stl: "c++_shared",

    test_suites: [
        "device-tests",
    ],

    cflags: [
        "-Wall",
        "-Werror",
    ],

    header_libs: [
        "libandroid_headers_private",
    ],
}
Loading