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

Commit 2e1e9cd8 authored by Matt Buckley's avatar Matt Buckley Committed by Android (Google) Code Review
Browse files

Merge "Add support for converting java hint sessions to native hint sessions" into main

parents 75741bd3 8739382f
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;

import com.android.internal.util.Preconditions;
@@ -106,7 +107,9 @@ public final class PerformanceHintManager {
     * All timings should be in {@link SystemClock#uptimeNanos()}.
     */
    public static class Session implements Closeable {
        private long mNativeSessionPtr;
        /** @hide */
        @UnsupportedAppUsage
        public long mNativeSessionPtr;

        /** @hide */
        public Session(long nativeSessionPtr) {
+5 −4
Original line number Diff line number Diff line
@@ -88,9 +88,10 @@ void ensureAPerformanceHintBindingInitialized() {
                        "Failed to find required symbol "
                        "APerformanceHint_getPreferredUpdateRateNanos!");

    gAPH_createSessionFn = (APH_createSession)dlsym(handle_, "APerformanceHint_createSession");
    gAPH_createSessionFn =
            (APH_createSession)dlsym(handle_, "APerformanceHint_createSessionFromJava");
    LOG_ALWAYS_FATAL_IF(gAPH_createSessionFn == nullptr,
                        "Failed to find required symbol APerformanceHint_createSession!");
                        "Failed to find required symbol APerformanceHint_createSessionFromJava!");

    gAPH_updateTargetWorkDurationFn =
            (APH_updateTargetWorkDuration)dlsym(handle_,
@@ -106,9 +107,9 @@ void ensureAPerformanceHintBindingInitialized() {
                        "Failed to find required symbol "
                        "APerformanceHint_reportActualWorkDuration!");

    gAPH_closeSessionFn = (APH_closeSession)dlsym(handle_, "APerformanceHint_closeSession");
    gAPH_closeSessionFn = (APH_closeSession)dlsym(handle_, "APerformanceHint_closeSessionFromJava");
    LOG_ALWAYS_FATAL_IF(gAPH_closeSessionFn == nullptr,
                        "Failed to find required symbol APerformanceHint_closeSession!");
                        "Failed to find required symbol APerformanceHint_closeSessionFromJava!");

    gAPH_sendHintFn = (APH_sendHint)dlsym(handle_, "APerformanceHint_sendHint");
    LOG_ALWAYS_FATAL_IF(gAPH_sendHintFn == nullptr,
+3 −0
Original line number Diff line number Diff line
@@ -363,6 +363,7 @@ LIBANDROID {
    APerformanceHint_reportActualWorkDuration2; # introduced=VanillaIceCream
    APerformanceHint_notifyWorkloadIncrease; # introduced=36
    APerformanceHint_notifyWorkloadReset; # introduced=36
    APerformanceHint_borrowSessionFromJava; # introduced=36
    AWorkDuration_create; # introduced=VanillaIceCream
    AWorkDuration_release; # introduced=VanillaIceCream
    AWorkDuration_setWorkPeriodStartTimestampNanos; # introduced=VanillaIceCream
@@ -383,6 +384,8 @@ LIBANDROID_PLATFORM {
    APerformanceHint_setUseFMQForTesting;
    APerformanceHint_getRateLimiterPropertiesForTesting;
    APerformanceHint_setUseNewLoadHintBehaviorForTesting;
    APerformanceHint_closeSessionFromJava;
    APerformanceHint_createSessionFromJava;
    extern "C++" {
        ASurfaceControl_registerSurfaceStatsListener*;
        ASurfaceControl_unregisterSurfaceStatsListener*;
+69 −5
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <cutils/trace.h>
#include <fmq/AidlMessageQueue.h>
#include <inttypes.h>
#include <jni_wrappers.h>
#include <performance_hint_private.h>
#include <utils/SystemClock.h>

@@ -137,10 +138,14 @@ public:

    APerformanceHintSession* createSession(const int32_t* threadIds, size_t size,
                                           int64_t initialTargetWorkDurationNanos,
                                           hal::SessionTag tag = hal::SessionTag::APP);
                                           hal::SessionTag tag = hal::SessionTag::APP,
                                           bool isJava = false);
    APerformanceHintSession* getSessionFromJava(JNIEnv* _Nonnull env, jobject _Nonnull sessionObj);

    int64_t getPreferredRateNanos() const;
    FMQWrapper& getFMQWrapper();
    bool canSendLoadHints(std::vector<hal::SessionHint>& hints, int64_t now) REQUIRES(sHintMutex);
    void initJava(JNIEnv* _Nonnull env);

private:
    // Necessary to create an empty binder object
@@ -161,13 +166,16 @@ private:
    FMQWrapper mFMQWrapper;
    double mHintBudget = kMaxLoadHintsPerInterval;
    int64_t mLastBudgetReplenish = 0;
    bool mJavaInitialized = false;
    jclass mJavaSessionClazz;
    jfieldID mJavaSessionNativePtr;
};

struct APerformanceHintSession {
public:
    APerformanceHintSession(std::shared_ptr<IHintManager> hintManager,
                            std::shared_ptr<IHintSession> session, int64_t preferredRateNanos,
                            int64_t targetDurationNanos,
                            int64_t targetDurationNanos, bool isJava,
                            std::optional<hal::SessionConfig> sessionConfig);
    APerformanceHintSession() = delete;
    ~APerformanceHintSession();
@@ -181,6 +189,7 @@ public:
    int getThreadIds(int32_t* const threadIds, size_t* size);
    int setPreferPowerEfficiency(bool enabled);
    int reportActualWorkDuration(AWorkDuration* workDuration);
    bool isJava();

private:
    friend struct APerformanceHintManager;
@@ -203,6 +212,8 @@ private:
    std::vector<int64_t> mLastHintSentTimestamp GUARDED_BY(sHintMutex);
    // Cached samples
    std::vector<hal::WorkDuration> mActualWorkDurations GUARDED_BY(sHintMutex);
    // Is this session backing an SDK wrapper object
    const bool mIsJava;
    std::string mSessionName;
    static int64_t sIDCounter GUARDED_BY(sHintMutex);
    // The most recent set of thread IDs
@@ -299,7 +310,7 @@ bool APerformanceHintManager::canSendLoadHints(std::vector<hal::SessionHint>& hi

APerformanceHintSession* APerformanceHintManager::createSession(
        const int32_t* threadIds, size_t size, int64_t initialTargetWorkDurationNanos,
        hal::SessionTag tag) {
        hal::SessionTag tag, bool isJava) {
    std::vector<int32_t> tids(threadIds, threadIds + size);
    std::shared_ptr<IHintSession> session;
    ndk::ScopedAStatus ret;
@@ -312,7 +323,7 @@ APerformanceHintSession* APerformanceHintManager::createSession(
        return nullptr;
    }
    auto out = new APerformanceHintSession(mHintManager, std::move(session), mPreferredRateNanos,
                                           initialTargetWorkDurationNanos,
                                           initialTargetWorkDurationNanos, isJava,
                                           sessionConfig.id == -1
                                                   ? std::nullopt
                                                   : std::make_optional<hal::SessionConfig>(
@@ -324,6 +335,18 @@ APerformanceHintSession* APerformanceHintManager::createSession(
    return out;
}

APerformanceHintSession* APerformanceHintManager::getSessionFromJava(JNIEnv* env,
                                                                     jobject sessionObj) {
    initJava(env);
    LOG_ALWAYS_FATAL_IF(!env->IsInstanceOf(sessionObj, mJavaSessionClazz),
                        "Wrong java type passed to APerformanceHint_getSessionFromJava");
    APerformanceHintSession* out = reinterpret_cast<APerformanceHintSession*>(
            env->GetLongField(sessionObj, mJavaSessionNativePtr));
    LOG_ALWAYS_FATAL_IF(out == nullptr, "Java-wrapped native hint session is nullptr");
    LOG_ALWAYS_FATAL_IF(!out->isJava(), "Unmanaged native hint session returned from Java SDK");
    return out;
}

int64_t APerformanceHintManager::getPreferredRateNanos() const {
    return mPreferredRateNanos;
}
@@ -332,13 +355,23 @@ FMQWrapper& APerformanceHintManager::getFMQWrapper() {
    return mFMQWrapper;
}

void APerformanceHintManager::initJava(JNIEnv* _Nonnull env) {
    if (mJavaInitialized) {
        return;
    }
    jclass sessionClazz = FindClassOrDie(env, "android/os/PerformanceHintManager$Session");
    mJavaSessionClazz = MakeGlobalRefOrDie(env, sessionClazz);
    mJavaSessionNativePtr = GetFieldIDOrDie(env, mJavaSessionClazz, "mNativeSessionPtr", "J");
    mJavaInitialized = true;
}

// ===================================== APerformanceHintSession implementation

constexpr int kNumEnums = enum_size<hal::SessionHint>();
APerformanceHintSession::APerformanceHintSession(std::shared_ptr<IHintManager> hintManager,
                                                 std::shared_ptr<IHintSession> session,
                                                 int64_t preferredRateNanos,
                                                 int64_t targetDurationNanos,
                                                 int64_t targetDurationNanos, bool isJava,
                                                 std::optional<hal::SessionConfig> sessionConfig)
      : mHintManager(hintManager),
        mHintSession(std::move(session)),
@@ -347,6 +380,7 @@ APerformanceHintSession::APerformanceHintSession(std::shared_ptr<IHintManager> h
        mFirstTargetMetTimestamp(0),
        mLastTargetMetTimestamp(0),
        mLastHintSentTimestamp(std::vector<int64_t>(kNumEnums, 0)),
        mIsJava(isJava),
        mSessionConfig(sessionConfig) {
    if (sessionConfig->id > INT32_MAX) {
        ALOGE("Session ID too large, must fit 32-bit integer");
@@ -401,6 +435,10 @@ int APerformanceHintSession::reportActualWorkDuration(int64_t actualDurationNano
    return reportActualWorkDurationInternal(static_cast<AWorkDuration*>(&workDuration));
}

bool APerformanceHintSession::isJava() {
    return mIsJava;
}

int APerformanceHintSession::sendHints(std::vector<hal::SessionHint>& hints, int64_t now,
                                       const char*) {
    std::scoped_lock lock(sHintMutex);
@@ -826,6 +864,22 @@ APerformanceHintSession* APerformanceHint_createSessionInternal(
                                  static_cast<hal::SessionTag>(tag));
}

APerformanceHintSession* APerformanceHint_createSessionFromJava(
        APerformanceHintManager* manager, const int32_t* threadIds, size_t size,
        int64_t initialTargetWorkDurationNanos) {
    VALIDATE_PTR(manager)
    VALIDATE_PTR(threadIds)
    return manager->createSession(threadIds, size, initialTargetWorkDurationNanos,
                                  hal::SessionTag::APP, true);
}

APerformanceHintSession* APerformanceHint_borrowSessionFromJava(JNIEnv* env,
                                                                    jobject sessionObj) {
    VALIDATE_PTR(env)
    VALIDATE_PTR(sessionObj)
    return APerformanceHintManager::getInstance()->getSessionFromJava(env, sessionObj);
}

int64_t APerformanceHint_getPreferredUpdateRateNanos(APerformanceHintManager* manager) {
    VALIDATE_PTR(manager)
    return manager->getPreferredRateNanos();
@@ -845,6 +899,16 @@ int APerformanceHint_reportActualWorkDuration(APerformanceHintSession* session,
}

void APerformanceHint_closeSession(APerformanceHintSession* session) {
    VALIDATE_PTR(session)
    if (session->isJava()) {
        LOG_ALWAYS_FATAL("%s: Java-owned PerformanceHintSession cannot be closed in native",
                         __FUNCTION__);
        return;
    }
    delete session;
}

void APerformanceHint_closeSessionFromJava(APerformanceHintSession* session) {
    VALIDATE_PTR(session)
    delete session;
}