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

Commit e073c73f authored by Matt Buckley's avatar Matt Buckley
Browse files

Add support for createHintSessionWithConfig

This patch adds support for the new "createHintSessionWithConfig" call
which supports session tagging and session IDs, and updates the
performance_hint NDK implementation to use it.

Bug: 330553312
Bug: 315894228
Test: atest PerformanceHintNativeTestCases
Test: atest HintManagerServiceTest
Change-Id: Idc1c16be6bb53983cc3ec102596b9613935f7301
parent 66dd0d61
Loading
Loading
Loading
Loading
+7 −2
Original line number Original line Diff line number Diff line
@@ -18,16 +18,21 @@
package android.os;
package android.os;


import android.os.IHintSession;
import android.os.IHintSession;
import android.hardware.power.SessionConfig;
import android.hardware.power.SessionTag;


/** {@hide} */
/** {@hide} */
interface IHintManager {
interface IHintManager {
    /**
    /**
     * Creates a {@link Session} for the given set of threads and associates to a binder token.
     * Creates a {@link Session} for the given set of threads and associates to a binder token.
     * Returns a config if creation is not supported, and HMS had to use the
     * legacy creation method.
     */
     */
    IHintSession createHintSession(in IBinder token, in int[] tids, long durationNanos);
    IHintSession createHintSessionWithConfig(in IBinder token, in int[] threadIds,
            in long durationNanos, in SessionTag tag, out @nullable SessionConfig config);


    /**
    /**
     * Get preferred rate limit in nano second.
     * Get preferred rate limit in nanoseconds.
     */
     */
    long getHintSessionPreferredRate();
    long getHintSessionPreferredRate();


+28 −16
Original line number Original line Diff line number Diff line
@@ -59,7 +59,8 @@ public:
    ~APerformanceHintManager() = default;
    ~APerformanceHintManager() = default;


    APerformanceHintSession* createSession(const int32_t* threadIds, size_t size,
    APerformanceHintSession* createSession(const int32_t* threadIds, size_t size,
                                           int64_t initialTargetWorkDurationNanos);
                                           int64_t initialTargetWorkDurationNanos,
                                           hal::SessionTag tag = hal::SessionTag::OTHER);
    int64_t getPreferredRateNanos() const;
    int64_t getPreferredRateNanos() const;


private:
private:
@@ -84,7 +85,8 @@ struct APerformanceHintSession {
public:
public:
    APerformanceHintSession(std::shared_ptr<IHintManager> hintManager,
    APerformanceHintSession(std::shared_ptr<IHintManager> hintManager,
                            std::shared_ptr<IHintSession> session, int64_t preferredRateNanos,
                            std::shared_ptr<IHintSession> session, int64_t preferredRateNanos,
                            int64_t targetDurationNanos);
                            int64_t targetDurationNanos,
                            std::optional<hal::SessionConfig> sessionConfig);
    APerformanceHintSession() = delete;
    APerformanceHintSession() = delete;
    ~APerformanceHintSession();
    ~APerformanceHintSession();


@@ -116,9 +118,10 @@ private:
    // Cached samples
    // Cached samples
    std::vector<hal::WorkDuration> mActualWorkDurations;
    std::vector<hal::WorkDuration> mActualWorkDurations;
    std::string mSessionName;
    std::string mSessionName;
    static int32_t sIDCounter;
    static int64_t sIDCounter;
    // The most recent set of thread IDs
    // The most recent set of thread IDs
    std::vector<int32_t> mLastThreadIDs;
    std::vector<int32_t> mLastThreadIDs;
    std::optional<hal::SessionConfig> mSessionConfig;
    // Tracing helpers
    // Tracing helpers
    void traceThreads(std::vector<int32_t>& tids);
    void traceThreads(std::vector<int32_t>& tids);
    void tracePowerEfficient(bool powerEfficient);
    void tracePowerEfficient(bool powerEfficient);
@@ -129,7 +132,8 @@ private:


static std::shared_ptr<IHintManager>* gIHintManagerForTesting = nullptr;
static std::shared_ptr<IHintManager>* gIHintManagerForTesting = nullptr;
static APerformanceHintManager* gHintManagerForTesting = nullptr;
static APerformanceHintManager* gHintManagerForTesting = nullptr;
int32_t APerformanceHintSession::sIDCounter = 0;
// Start above the int32 range so we don't collide with config sessions
int64_t APerformanceHintSession::sIDCounter = INT32_MAX;


// ===================================== APerformanceHintManager implementation
// ===================================== APerformanceHintManager implementation
APerformanceHintManager::APerformanceHintManager(std::shared_ptr<IHintManager> manager,
APerformanceHintManager::APerformanceHintManager(std::shared_ptr<IHintManager> manager,
@@ -174,16 +178,20 @@ APerformanceHintManager* APerformanceHintManager::create(std::shared_ptr<IHintMa
}
}


APerformanceHintSession* APerformanceHintManager::createSession(
APerformanceHintSession* APerformanceHintManager::createSession(
        const int32_t* threadIds, size_t size, int64_t initialTargetWorkDurationNanos) {
        const int32_t* threadIds, size_t size, int64_t initialTargetWorkDurationNanos,
        hal::SessionTag tag) {
    std::vector<int32_t> tids(threadIds, threadIds + size);
    std::vector<int32_t> tids(threadIds, threadIds + size);
    std::shared_ptr<IHintSession> session;
    std::shared_ptr<IHintSession> session;
    ndk::ScopedAStatus ret =
    ndk::ScopedAStatus ret;
            mHintManager->createHintSession(mToken, tids, initialTargetWorkDurationNanos, &session);
    std::optional<hal::SessionConfig> sessionConfig;
    ret = mHintManager->createHintSessionWithConfig(mToken, tids, initialTargetWorkDurationNanos,
                                                    tag, &sessionConfig, &session);

    if (!ret.isOk() || !session) {
    if (!ret.isOk() || !session) {
        return nullptr;
        return nullptr;
    }
    }
    auto out = new APerformanceHintSession(mHintManager, std::move(session), mPreferredRateNanos,
    auto out = new APerformanceHintSession(mHintManager, std::move(session), mPreferredRateNanos,
                                           initialTargetWorkDurationNanos);
                                           initialTargetWorkDurationNanos, sessionConfig);
    out->traceThreads(tids);
    out->traceThreads(tids);
    out->traceTargetDuration(initialTargetWorkDurationNanos);
    out->traceTargetDuration(initialTargetWorkDurationNanos);
    out->tracePowerEfficient(false);
    out->tracePowerEfficient(false);
@@ -199,19 +207,23 @@ int64_t APerformanceHintManager::getPreferredRateNanos() const {
APerformanceHintSession::APerformanceHintSession(std::shared_ptr<IHintManager> hintManager,
APerformanceHintSession::APerformanceHintSession(std::shared_ptr<IHintManager> hintManager,
                                                 std::shared_ptr<IHintSession> session,
                                                 std::shared_ptr<IHintSession> session,
                                                 int64_t preferredRateNanos,
                                                 int64_t preferredRateNanos,
                                                 int64_t targetDurationNanos)
                                                 int64_t targetDurationNanos,
                                                 std::optional<hal::SessionConfig> sessionConfig)
      : mHintManager(hintManager),
      : mHintManager(hintManager),
        mHintSession(std::move(session)),
        mHintSession(std::move(session)),
        mPreferredRateNanos(preferredRateNanos),
        mPreferredRateNanos(preferredRateNanos),
        mTargetDurationNanos(targetDurationNanos),
        mTargetDurationNanos(targetDurationNanos),
        mFirstTargetMetTimestamp(0),
        mFirstTargetMetTimestamp(0),
        mLastTargetMetTimestamp(0) {
        mLastTargetMetTimestamp(0),
    const std::vector<hal::SessionHint> sessionHintRange{ndk::enum_range<hal::SessionHint>()
        mSessionConfig(sessionConfig) {
                                                                 .begin(),
    if (sessionConfig->id > INT32_MAX) {
                                                         ndk::enum_range<hal::SessionHint>().end()};
        ALOGE("Session ID too large, must fit 32-bit integer");

    }
    mLastHintSentTimestamp = std::vector<int64_t>(sessionHintRange.size(), 0);
    constexpr int numEnums =
    mSessionName = android::base::StringPrintf("ADPF Session %" PRId32, ++sIDCounter);
            ndk::enum_range<hal::SessionHint>().end() - ndk::enum_range<hal::SessionHint>().begin();
    mLastHintSentTimestamp = std::vector<int64_t>(numEnums, 0);
    int64_t traceId = sessionConfig.has_value() ? sessionConfig->id : ++sIDCounter;
    mSessionName = android::base::StringPrintf("ADPF Session %" PRId64, traceId);
}
}


APerformanceHintSession::~APerformanceHintSession() {
APerformanceHintSession::~APerformanceHintSession() {
+21 −5
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


#define LOG_TAG "PerformanceHintNativeTest"
#define LOG_TAG "PerformanceHintNativeTest"


#include <aidl/android/hardware/power/SessionConfig.h>
#include <aidl/android/hardware/power/SessionTag.h>
#include <aidl/android/hardware/power/WorkDuration.h>
#include <aidl/android/hardware/power/WorkDuration.h>
#include <aidl/android/os/IHintManager.h>
#include <aidl/android/os/IHintManager.h>
#include <android/binder_manager.h>
#include <android/binder_manager.h>
@@ -28,6 +30,8 @@
#include <memory>
#include <memory>
#include <vector>
#include <vector>


using aidl::android::hardware::power::SessionConfig;
using aidl::android::hardware::power::SessionTag;
using aidl::android::hardware::power::WorkDuration;
using aidl::android::hardware::power::WorkDuration;
using aidl::android::os::IHintManager;
using aidl::android::os::IHintManager;
using aidl::android::os::IHintSession;
using aidl::android::os::IHintSession;
@@ -39,8 +43,9 @@ using namespace testing;


class MockIHintManager : public IHintManager {
class MockIHintManager : public IHintManager {
public:
public:
    MOCK_METHOD(ScopedAStatus, createHintSession,
    MOCK_METHOD(ScopedAStatus, createHintSessionWithConfig,
                (const SpAIBinder& token, const ::std::vector<int32_t>& tids, int64_t durationNanos,
                (const SpAIBinder& token, const ::std::vector<int32_t>& tids, int64_t durationNanos,
                 SessionTag tag, std::optional<SessionConfig>* config,
                 std::shared_ptr<IHintSession>* _aidl_return),
                 std::shared_ptr<IHintSession>* _aidl_return),
                (override));
                (override));
    MOCK_METHOD(ScopedAStatus, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
    MOCK_METHOD(ScopedAStatus, getHintSessionPreferredRate, (int64_t * _aidl_return), (override));
@@ -92,14 +97,18 @@ public:
    APerformanceHintSession* createSession(APerformanceHintManager* manager,
    APerformanceHintSession* createSession(APerformanceHintManager* manager,
                                           int64_t targetDuration = 56789L) {
                                           int64_t targetDuration = 56789L) {
        mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();
        mMockSession = ndk::SharedRefBase::make<NiceMock<MockIHintSession>>();

        int64_t sessionId = 123;
        std::vector<int32_t> tids;
        std::vector<int32_t> tids;
        tids.push_back(1);
        tids.push_back(1);
        tids.push_back(2);
        tids.push_back(2);


        ON_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
        ON_CALL(*mMockIHintManager,
                .WillByDefault(DoAll(SetArgPointee<3>(std::shared_ptr<IHintSession>(mMockSession)),
                createHintSessionWithConfig(_, Eq(tids), Eq(targetDuration), _, _, _))
                .WillByDefault(DoAll(SetArgPointee<4>(
                                             std::make_optional<SessionConfig>({.id = sessionId})),
                                     SetArgPointee<5>(std::shared_ptr<IHintSession>(mMockSession)),
                                     [] { return ScopedAStatus::ok(); }));
                                     [] { return ScopedAStatus::ok(); }));

        ON_CALL(*mMockIHintManager, setHintSessionThreads(_, _)).WillByDefault([] {
        ON_CALL(*mMockIHintManager, setHintSessionThreads(_, _)).WillByDefault([] {
            return ScopedAStatus::ok();
            return ScopedAStatus::ok();
        });
        });
@@ -115,7 +124,6 @@ public:
        ON_CALL(*mMockSession, reportActualWorkDuration2(_)).WillByDefault([] {
        ON_CALL(*mMockSession, reportActualWorkDuration2(_)).WillByDefault([] {
            return ScopedAStatus::ok();
            return ScopedAStatus::ok();
        });
        });

        return APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
        return APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
    }
    }


@@ -178,6 +186,14 @@ TEST_F(PerformanceHintTest, TestSession) {
    APerformanceHint_closeSession(session);
    APerformanceHint_closeSession(session);
}
}


TEST_F(PerformanceHintTest, TestUpdatedSessionCreation) {
    EXPECT_CALL(*mMockIHintManager, createHintSessionWithConfig(_, _, _, _, _, _)).Times(1);
    APerformanceHintManager* manager = createManager();
    APerformanceHintSession* session = createSession(manager);
    ASSERT_TRUE(session);
    APerformanceHint_closeSession(session);
}

TEST_F(PerformanceHintTest, SetThreads) {
TEST_F(PerformanceHintTest, SetThreads) {
    APerformanceHintManager* manager = createManager();
    APerformanceHintManager* manager = createManager();


+51 −8
Original line number Original line Diff line number Diff line
@@ -20,11 +20,14 @@ import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
import static com.android.server.power.hint.Flags.powerhintThreadCleanup;
import static com.android.server.power.hint.Flags.powerhintThreadCleanup;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerInternal;
import android.app.StatsManager;
import android.app.StatsManager;
import android.app.UidObserver;
import android.app.UidObserver;
import android.content.Context;
import android.content.Context;
import android.hardware.power.SessionConfig;
import android.hardware.power.SessionTag;
import android.hardware.power.WorkDuration;
import android.hardware.power.WorkDuration;
import android.os.Binder;
import android.os.Binder;
import android.os.Handler;
import android.os.Handler;
@@ -67,6 +70,7 @@ import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Objects;
import java.util.Set;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;


/** An hint service implementation that runs in System Server process. */
/** An hint service implementation that runs in System Server process. */
public final class HintManagerService extends SystemService {
public final class HintManagerService extends SystemService {
@@ -87,7 +91,7 @@ public final class HintManagerService extends SystemService {
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private final ArrayMap<Integer, ArrayMap<IBinder, ArraySet<AppHintSession>>> mActiveSessions;
    private final ArrayMap<Integer, ArrayMap<IBinder, ArraySet<AppHintSession>>> mActiveSessions;


    /** Lock to protect HAL handles and listen list. */
    /** Lock to protect mActiveSessions. */
    private final Object mLock = new Object();
    private final Object mLock = new Object();


    @GuardedBy("mNonIsolatedTidsLock")
    @GuardedBy("mNonIsolatedTidsLock")
@@ -104,6 +108,8 @@ public final class HintManagerService extends SystemService {


    private final Context mContext;
    private final Context mContext;


    private AtomicBoolean mConfigCreationSupport = new AtomicBoolean(true);

    private static final String PROPERTY_SF_ENABLE_CPU_HINT = "debug.sf.enable_adpf_cpu_hint";
    private static final String PROPERTY_SF_ENABLE_CPU_HINT = "debug.sf.enable_adpf_cpu_hint";
    private static final String PROPERTY_HWUI_ENABLE_HINT_MANAGER = "debug.hwui.use_hint_manager";
    private static final String PROPERTY_HWUI_ENABLE_HINT_MANAGER = "debug.hwui.use_hint_manager";


@@ -217,6 +223,9 @@ public final class HintManagerService extends SystemService {
        private static native long nativeCreateHintSession(int tgid, int uid, int[] tids,
        private static native long nativeCreateHintSession(int tgid, int uid, int[] tids,
                long durationNanos);
                long durationNanos);


        private static native long nativeCreateHintSessionWithConfig(int tgid, int uid, int[] tids,
                long durationNanos, int tag, SessionConfig config);

        private static native void nativePauseHintSession(long halPtr);
        private static native void nativePauseHintSession(long halPtr);


        private static native void nativeResumeHintSession(long halPtr);
        private static native void nativeResumeHintSession(long halPtr);
@@ -253,6 +262,12 @@ public final class HintManagerService extends SystemService {
            return nativeCreateHintSession(tgid, uid, tids, durationNanos);
            return nativeCreateHintSession(tgid, uid, tids, durationNanos);
        }
        }


        /** Wrapper for HintManager.nativeCreateHintSessionWithConfig */
        public long halCreateHintSessionWithConfig(
                int tgid, int uid, int[] tids, long durationNanos, int tag, SessionConfig config) {
            return nativeCreateHintSessionWithConfig(tgid, uid, tids, durationNanos, tag, config);
        }

        /** Wrapper for HintManager.nativePauseHintSession */
        /** Wrapper for HintManager.nativePauseHintSession */
        public void halPauseHintSession(long halPtr) {
        public void halPauseHintSession(long halPtr) {
            nativePauseHintSession(halPtr);
            nativePauseHintSession(halPtr);
@@ -612,8 +627,12 @@ public final class HintManagerService extends SystemService {
    @VisibleForTesting
    @VisibleForTesting
    final class BinderService extends IHintManager.Stub {
    final class BinderService extends IHintManager.Stub {
        @Override
        @Override
        public IHintSession createHintSession(IBinder token, int[] tids, long durationNanos) {
        public IHintSession createHintSessionWithConfig(@NonNull IBinder token,
            if (!isHalSupported()) return null;
                @NonNull int[] tids, long durationNanos, @SessionTag int tag,
                @Nullable SessionConfig config) {
            if (!isHalSupported()) {
                throw new UnsupportedOperationException("PowerHAL is not supported!");
            }


            java.util.Objects.requireNonNull(token);
            java.util.Objects.requireNonNull(token);
            java.util.Objects.requireNonNull(tids);
            java.util.Objects.requireNonNull(tids);
@@ -634,8 +653,35 @@ public final class HintManagerService extends SystemService {
                    throw new SecurityException(errMsg);
                    throw new SecurityException(errMsg);
                }
                }


                long halSessionPtr = mNativeWrapper.halCreateHintSession(callingTgid, callingUid,
                Long halSessionPtr = null;
                        tids, durationNanos);
                if (mConfigCreationSupport.get()) {
                    try {
                        halSessionPtr = mNativeWrapper.halCreateHintSessionWithConfig(
                                callingTgid, callingUid, tids, durationNanos, tag, config);
                    } catch (UnsupportedOperationException e) {
                        mConfigCreationSupport.set(false);
                    } catch (IllegalStateException e) {
                        Slog.e("createHintSessionWithConfig failed: ", e.getMessage());
                        throw new IllegalStateException(
                            "createHintSessionWithConfig failed: " + e.getMessage());
                    }
                }

                if (halSessionPtr == null) {
                    try {
                        halSessionPtr = mNativeWrapper.halCreateHintSession(callingTgid,
                                callingUid, tids, durationNanos);
                    } catch (UnsupportedOperationException e) {
                        Slog.w("createHintSession unsupported: ", e.getMessage());
                        throw new UnsupportedOperationException(
                            "createHintSession unsupported: " + e.getMessage());
                    } catch (IllegalStateException e) {
                        Slog.e("createHintSession failed: ", e.getMessage());
                        throw new IllegalStateException(
                            "createHintSession failed: " + e.getMessage());
                    }
                }

                if (powerhintThreadCleanup()) {
                if (powerhintThreadCleanup()) {
                    synchronized (mNonIsolatedTidsLock) {
                    synchronized (mNonIsolatedTidsLock) {
                        for (int i = nonIsolated.size() - 1; i >= 0; i--) {
                        for (int i = nonIsolated.size() - 1; i >= 0; i--) {
@@ -644,9 +690,6 @@ public final class HintManagerService extends SystemService {
                        }
                        }
                    }
                    }
                }
                }
                if (halSessionPtr == 0) {
                    return null;
                }


                AppHintSession hs = new AppHintSession(callingUid, callingTgid, tids, token,
                AppHintSession hs = new AppHintSession(callingUid, callingTgid, tids, token,
                        halSessionPtr, durationNanos);
                        halSessionPtr, durationNanos);
+63 −3
Original line number Original line Diff line number Diff line
@@ -34,13 +34,13 @@


#include "jni.h"
#include "jni.h"


using aidl::android::hardware::power::SessionConfig;
using aidl::android::hardware::power::SessionHint;
using aidl::android::hardware::power::SessionHint;
using aidl::android::hardware::power::SessionMode;
using aidl::android::hardware::power::SessionMode;
using aidl::android::hardware::power::SessionTag;
using aidl::android::hardware::power::WorkDuration;
using aidl::android::hardware::power::WorkDuration;
using android::power::PowerHintSessionWrapper;
using android::power::PowerHintSessionWrapper;


using android::base::StringPrintf;

namespace android {
namespace android {


static struct {
static struct {
@@ -66,6 +66,15 @@ static int64_t getHintSessionPreferredRate() {
    return rate;
    return rate;
}
}


void throwUnsupported(JNIEnv* env, const char* msg) {
    env->ThrowNew(env->FindClass("java/lang/UnsupportedOperationException"), msg);
}

void throwFailed(JNIEnv* env, const char* msg) {
    // We throw IllegalStateException for all errors other than the "unsupported" ones
    env->ThrowNew(env->FindClass("java/lang/IllegalStateException"), msg);
}

static jlong createHintSession(JNIEnv* env, int32_t tgid, int32_t uid,
static jlong createHintSession(JNIEnv* env, int32_t tgid, int32_t uid,
                               std::vector<int32_t>& threadIds, int64_t durationNanos) {
                               std::vector<int32_t>& threadIds, int64_t durationNanos) {
    auto result = gPowerHalController.createHintSession(tgid, uid, threadIds, durationNanos);
    auto result = gPowerHalController.createHintSession(tgid, uid, threadIds, durationNanos);
@@ -76,10 +85,38 @@ static jlong createHintSession(JNIEnv* env, int32_t tgid, int32_t uid,
        return res.second ? session_ptr : 0;
        return res.second ? session_ptr : 0;
    } else if (result.isFailed()) {
    } else if (result.isFailed()) {
        ALOGW("createHintSession failed with message: %s", result.errorMessage());
        ALOGW("createHintSession failed with message: %s", result.errorMessage());
        throwFailed(env, result.errorMessage());
    } else if (result.isUnsupported()) {
        throwUnsupported(env, result.errorMessage());
        return -1;
    }
    }
    return 0;
    return 0;
}
}


static jlong createHintSessionWithConfig(JNIEnv* env, int32_t tgid, int32_t uid,
                                         std::vector<int32_t> threadIds, int64_t durationNanos,
                                         int32_t sessionTag, SessionConfig& config) {
    auto result =
            gPowerHalController.createHintSessionWithConfig(tgid, uid, threadIds, durationNanos,
                                                            static_cast<SessionTag>(sessionTag),
                                                            &config);
    if (result.isOk()) {
        jlong session_ptr = reinterpret_cast<jlong>(result.value().get());
        std::scoped_lock sessionLock(gSessionMapLock);
        auto res = gSessionMap.insert({session_ptr, result.value()});
        if (!res.second) {
            throwFailed(env, "PowerHAL provided an invalid session");
            return 0;
        }
        return session_ptr;
    } else if (result.isUnsupported()) {
        throwUnsupported(env, result.errorMessage());
        return -1;
    }
    throwFailed(env, result.errorMessage());
    return 0;
}

static void pauseHintSession(JNIEnv* env, int64_t session_ptr) {
static void pauseHintSession(JNIEnv* env, int64_t session_ptr) {
    auto appSession = reinterpret_cast<PowerHintSessionWrapper*>(session_ptr);
    auto appSession = reinterpret_cast<PowerHintSessionWrapper*>(session_ptr);
    appSession->pause();
    appSession->pause();
@@ -136,13 +173,34 @@ static jlong nativeCreateHintSession(JNIEnv* env, jclass /* clazz */, jint tgid,
                                     jintArray tids, jlong durationNanos) {
                                     jintArray tids, jlong durationNanos) {
    ScopedIntArrayRO tidArray(env, tids);
    ScopedIntArrayRO tidArray(env, tids);
    if (nullptr == tidArray.get() || tidArray.size() == 0) {
    if (nullptr == tidArray.get() || tidArray.size() == 0) {
        ALOGW("GetIntArrayElements returns nullptr.");
        ALOGW("nativeCreateHintSession: GetIntArrayElements returns nullptr.");
        return 0;
        return 0;
    }
    }
    std::vector<int32_t> threadIds(tidArray.get(), tidArray.get() + tidArray.size());
    std::vector<int32_t> threadIds(tidArray.get(), tidArray.get() + tidArray.size());
    return createHintSession(env, tgid, uid, threadIds, durationNanos);
    return createHintSession(env, tgid, uid, threadIds, durationNanos);
}
}


static jlong nativeCreateHintSessionWithConfig(JNIEnv* env, jclass /* clazz */, jint tgid, jint uid,
                                               jintArray tids, jlong durationNanos, jint sessionTag,
                                               jobject sessionConfig) {
    ScopedIntArrayRO tidArray(env, tids);
    if (nullptr == tidArray.get() || tidArray.size() == 0) {
        ALOGW("nativeCreateHintSessionWithConfig: GetIntArrayElements returns nullptr.");
        return 0;
    }
    std::vector<int32_t> threadIds(tidArray.get(), tidArray.get() + tidArray.size());
    SessionConfig config;
    jlong out = createHintSessionWithConfig(env, tgid, uid, std::move(threadIds), durationNanos,
                                            sessionTag, config);
    if (out <= 0) {
        return out;
    }
    static jclass configClass = env->FindClass("android/hardware/power/SessionConfig");
    static jfieldID fid = env->GetFieldID(configClass, "id", "J");
    env->SetLongField(sessionConfig, fid, config.id);
    return out;
}

static void nativePauseHintSession(JNIEnv* env, jclass /* clazz */, jlong session_ptr) {
static void nativePauseHintSession(JNIEnv* env, jclass /* clazz */, jlong session_ptr) {
    pauseHintSession(env, session_ptr);
    pauseHintSession(env, session_ptr);
}
}
@@ -215,6 +273,8 @@ static const JNINativeMethod sHintManagerServiceMethods[] = {
        {"nativeInit", "()V", (void*)nativeInit},
        {"nativeInit", "()V", (void*)nativeInit},
        {"nativeGetHintSessionPreferredRate", "()J", (void*)nativeGetHintSessionPreferredRate},
        {"nativeGetHintSessionPreferredRate", "()J", (void*)nativeGetHintSessionPreferredRate},
        {"nativeCreateHintSession", "(II[IJ)J", (void*)nativeCreateHintSession},
        {"nativeCreateHintSession", "(II[IJ)J", (void*)nativeCreateHintSession},
        {"nativeCreateHintSessionWithConfig", "(II[IJILandroid/hardware/power/SessionConfig;)J",
         (void*)nativeCreateHintSessionWithConfig},
        {"nativePauseHintSession", "(J)V", (void*)nativePauseHintSession},
        {"nativePauseHintSession", "(J)V", (void*)nativePauseHintSession},
        {"nativeResumeHintSession", "(J)V", (void*)nativeResumeHintSession},
        {"nativeResumeHintSession", "(J)V", (void*)nativeResumeHintSession},
        {"nativeCloseHintSession", "(J)V", (void*)nativeCloseHintSession},
        {"nativeCloseHintSession", "(J)V", (void*)nativeCloseHintSession},
Loading