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

Commit 8a71933f authored by Tomasz Wasilczyk's avatar Tomasz Wasilczyk Committed by Android (Google) Code Review
Browse files

Merge "Broadcast Radio service cleanup." into oc-mr1-dev

parents 7ceb8eff e3e8f90c
Loading
Loading
Loading
Loading
+13 −10
Original line number Diff line number Diff line
@@ -27,14 +27,17 @@
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <core_jni_helpers.h>
#include <hidl/ServiceManagement.h>
#include <nativehelper/JNIHelp.h>
#include <utils/Log.h>
#include <JNIHelp.h>

namespace android {
namespace server {
namespace BroadcastRadio {
namespace BroadcastRadioService {

using std::lock_guard;
using std::mutex;

using hardware::Return;
using hardware::hidl_string;
using hardware::hidl_vec;
@@ -50,7 +53,7 @@ using V1_0::ProgramInfo;
using V1_0::MetaData;
using V1_0::ITuner;

static Mutex gContextMutex;
static mutex gContextMutex;

static struct {
    struct {
@@ -90,8 +93,8 @@ static ServiceContext& getNativeContext(jlong nativeContextHandle) {
}

static jlong nativeInit(JNIEnv *env, jobject obj) {
    ALOGV("nativeInit()");
    AutoMutex _l(gContextMutex);
    ALOGV("%s", __func__);
    lock_guard<mutex> lk(gContextMutex);

    auto nativeContext = new ServiceContext();
    static_assert(sizeof(jlong) >= sizeof(nativeContext), "jlong is smaller than a pointer");
@@ -99,16 +102,16 @@ static jlong nativeInit(JNIEnv *env, jobject obj) {
}

static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
    ALOGV("nativeFinalize()");
    AutoMutex _l(gContextMutex);
    ALOGV("%s", __func__);
    lock_guard<mutex> lk(gContextMutex);

    auto ctx = reinterpret_cast<ServiceContext*>(nativeContext);
    delete ctx;
}

static jobject nativeLoadModules(JNIEnv *env, jobject obj, jlong nativeContext) {
    ALOGV("nativeLoadModules()");
    AutoMutex _l(gContextMutex);
    ALOGV("%s", __func__);
    lock_guard<mutex> lk(gContextMutex);
    auto& ctx = getNativeContext(nativeContext);

    // Get list of registered HIDL HAL implementations.
@@ -182,8 +185,8 @@ static jobject nativeLoadModules(JNIEnv *env, jobject obj, jlong nativeContext)

static jobject nativeOpenTuner(JNIEnv *env, jobject obj, long nativeContext, jint moduleId,
        jobject bandConfig, bool withAudio, jobject callback) {
    ALOGV("nativeOpenTuner()");
    AutoMutex _l(gContextMutex);
    ALOGV("%s", __func__);
    lock_guard<mutex> lk(gContextMutex);
    auto& ctx = getNativeContext(nativeContext);

    if (callback == nullptr) {
+25 −33
Original line number Diff line number Diff line
@@ -23,45 +23,38 @@

namespace android {

NativeCallbackThread::NativeCallbackThread(JavaVM *vm) : mExitting(false), mvm(vm) {
    auto res = pthread_create(&mThread, nullptr, main, this);
    if (res != 0) {
        ALOGE("Couldn't start NativeCallbackThread");
        mThread = 0;
        return;
    }
using std::lock_guard;
using std::mutex;
using std::unique_lock;

NativeCallbackThread::NativeCallbackThread(JavaVM *vm) : mvm(vm), mExiting(false),
        mThread(&NativeCallbackThread::threadLoop, this) {
    ALOGD("Started native callback thread %p", this);
}

NativeCallbackThread::~NativeCallbackThread() {
    ALOGV("~NativeCallbackThread %p", this);
    ALOGV("%s %p", __func__, this);
    stop();
}

void* NativeCallbackThread::main(void *args) {
    auto self = reinterpret_cast<NativeCallbackThread*>(args);
    self->main();
    return nullptr;
}

void NativeCallbackThread::main() {
    ALOGV("NativeCallbackThread::main()");
void NativeCallbackThread::threadLoop() {
    ALOGV("%s", __func__);

    JNIEnv *env = nullptr;
    JavaVMAttachArgs aargs = {JNI_VERSION_1_4, "NativeCallbackThread", nullptr};
    if (mvm->AttachCurrentThread(&env, &aargs) != JNI_OK || env == nullptr) {
        ALOGE("Couldn't attach thread");
        mExiting = true;
        return;
    }

    while (!mExitting) {
    while (!mExiting) {
        ALOGV("Waiting for task...");
        Task task;
        {
            AutoMutex _l(mQueueMutex);
            auto res = mQueueCond.wait(mQueueMutex);
            ALOGE_IF(res != 0, "Wait failed: %d", res);
            if (mExitting || res != 0) break;
            unique_lock<mutex> lk(mQueueMutex);
            mQueueCond.wait(lk);
            if (mExiting) break;

            if (mQueue.empty()) continue;
            task = mQueue.front();
@@ -84,36 +77,35 @@ void NativeCallbackThread::main() {
}

void NativeCallbackThread::enqueue(const Task &task) {
    AutoMutex _l(mQueueMutex);
    lock_guard<mutex> lk(mQueueMutex);

    if (mThread == 0 || mExitting) {
    if (mExiting) {
        ALOGW("Callback thread %p is not serving calls", this);
        return;
    }

    mQueue.push(task);
    mQueueCond.signal();
    mQueueCond.notify_one();
}

void NativeCallbackThread::stop() {
    ALOGV("stop() %p", this);
    ALOGV("%s %p", __func__, this);

    {
        AutoMutex _l(mQueueMutex);
        lock_guard<mutex> lk(mQueueMutex);

        if (mThread == 0 || mExitting) return;
        if (mExiting) return;

        mExitting = true;
        mQueueCond.signal();
        mExiting = true;
        mQueueCond.notify_one();
    }

    if (pthread_self() == mThread) {
    if (mThread.get_id() == std::thread::id()) {
        // you can't self-join a thread, but it's ok when calling from our sub-task
        ALOGD("About to stop native callback thread %p", this);
        mThread.detach();
    } else {
        auto ret = pthread_join(mThread, nullptr);
        ALOGE_IF(ret != 0, "Couldn't join thread: %d", ret);

        mThread.join();
        ALOGD("Stopped native callback thread %p", this);
    }
}
+7 −10
Original line number Diff line number Diff line
@@ -20,26 +20,23 @@
#include <android-base/macros.h>
#include <functional>
#include <jni.h>
#include <pthread.h>
#include <queue>
#include <utils/Condition.h>
#include <utils/Mutex.h>
#include <thread>

namespace android {

class NativeCallbackThread {
    typedef std::function<void(JNIEnv*)> Task;

    pthread_t mThread;
    Mutex mQueueMutex;
    Condition mQueueCond;
    std::atomic<bool> mExitting;

    JavaVM *mvm;
    std::queue<Task> mQueue;

    static void* main(void *args);
    void main();
    std::mutex mQueueMutex;
    std::condition_variable mQueueCond;
    std::atomic<bool> mExiting;
    std::thread mThread;

    void threadLoop();

    DISALLOW_COPY_AND_ASSIGN(NativeCallbackThread);

+35 −29
Original line number Diff line number Diff line
@@ -22,12 +22,12 @@
#include "convert.h"
#include "TunerCallback.h"

#include <JNIHelp.h>
#include <Utils.h>
#include <android/hardware/broadcastradio/1.1/IBroadcastRadioFactory.h>
#include <binder/IPCThreadState.h>
#include <broadcastradio-utils/Utils.h>
#include <core_jni_helpers.h>
#include <media/AudioSystem.h>
#include <nativehelper/JNIHelp.h>
#include <utils/Log.h>

namespace android {
@@ -35,6 +35,9 @@ namespace server {
namespace BroadcastRadio {
namespace Tuner {

using std::lock_guard;
using std::mutex;

using hardware::Return;
using hardware::hidl_death_recipient;
using hardware::hidl_vec;
@@ -49,7 +52,7 @@ using V1_0::Result;
using V1_1::ITunerCallback;
using V1_1::ProgramListResult;

static Mutex gContextMutex;
static mutex gContextMutex;

static struct {
    struct {
@@ -106,8 +109,8 @@ static TunerContext& getNativeContext(JNIEnv *env, JavaRef<jobject> const &jTune
}

static jlong nativeInit(JNIEnv *env, jobject obj, jint halRev, bool withAudio, jint band) {
    ALOGV("nativeInit()");
    AutoMutex _l(gContextMutex);
    ALOGV("%s", __func__);
    lock_guard<mutex> lk(gContextMutex);

    auto ctx = new TunerContext();
    ctx->mHalRev = static_cast<HalRevision>(halRev);
@@ -119,8 +122,8 @@ static jlong nativeInit(JNIEnv *env, jobject obj, jint halRev, bool withAudio, j
}

static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
    ALOGV("nativeFinalize()");
    AutoMutex _l(gContextMutex);
    ALOGV("%s", __func__);
    lock_guard<mutex> lk(gContextMutex);

    auto ctx = reinterpret_cast<TunerContext*>(nativeContext);
    delete ctx;
@@ -150,10 +153,9 @@ static void notifyAudioService(TunerContext& ctx, bool connected) {

void assignHalInterfaces(JNIEnv *env, JavaRef<jobject> const &jTuner,
        sp<V1_0::IBroadcastRadio> halModule, sp<V1_0::ITuner> halTuner) {
    ALOGV("setHalTuner(%p)", halTuner.get());
    ALOGV("%s(%p)", __func__, halTuner.get());
    ALOGE_IF(halTuner == nullptr, "HAL tuner is a nullptr");

    AutoMutex _l(gContextMutex);
    lock_guard<mutex> lk(gContextMutex);
    auto& ctx = getNativeContext(env, jTuner);

    if (ctx.mIsClosed) {
@@ -187,12 +189,12 @@ static sp<V1_0::ITuner> getHalTuner(const TunerContext& ctx) {
}

sp<V1_0::ITuner> getHalTuner(jlong nativeContext) {
    AutoMutex _l(gContextMutex);
    lock_guard<mutex> lk(gContextMutex);
    return getHalTuner(getNativeContext(nativeContext));
}

sp<V1_1::ITuner> getHalTuner11(jlong nativeContext) {
    AutoMutex _l(gContextMutex);
    lock_guard<mutex> lk(gContextMutex);
    return getNativeContext(nativeContext).mHalTuner11;
}

@@ -206,8 +208,9 @@ Region getRegion(JNIEnv *env, jobject obj) {
}

static void nativeClose(JNIEnv *env, jobject obj, jlong nativeContext) {
    AutoMutex _l(gContextMutex);
    lock_guard<mutex> lk(gContextMutex);
    auto& ctx = getNativeContext(nativeContext);

    if (ctx.mIsClosed) return;
    ctx.mIsClosed = true;

@@ -228,9 +231,10 @@ static void nativeClose(JNIEnv *env, jobject obj, jlong nativeContext) {
}

static void nativeSetConfiguration(JNIEnv *env, jobject obj, jlong nativeContext, jobject config) {
    ALOGV("nativeSetConfiguration()");
    AutoMutex _l(gContextMutex);
    ALOGV("%s", __func__);
    lock_guard<mutex> lk(gContextMutex);
    auto& ctx = getNativeContext(nativeContext);

    auto halTuner = getHalTuner(ctx);
    if (halTuner == nullptr) return;

@@ -244,7 +248,7 @@ static void nativeSetConfiguration(JNIEnv *env, jobject obj, jlong nativeContext

static jobject nativeGetConfiguration(JNIEnv *env, jobject obj, jlong nativeContext,
        Region region) {
    ALOGV("nativeSetConfiguration()");
    ALOGV("%s", __func__);
    auto halTuner = getHalTuner(nativeContext);
    if (halTuner == nullptr) return nullptr;

@@ -263,7 +267,7 @@ static jobject nativeGetConfiguration(JNIEnv *env, jobject obj, jlong nativeCont

static void nativeStep(JNIEnv *env, jobject obj, jlong nativeContext,
        bool directionDown, bool skipSubChannel) {
    ALOGV("nativeStep()");
    ALOGV("%s", __func__);
    auto halTuner = getHalTuner(nativeContext);
    if (halTuner == nullptr) return;

@@ -273,7 +277,7 @@ static void nativeStep(JNIEnv *env, jobject obj, jlong nativeContext,

static void nativeScan(JNIEnv *env, jobject obj, jlong nativeContext,
        bool directionDown, bool skipSubChannel) {
    ALOGV("nativeScan()");
    ALOGV("%s", __func__);
    auto halTuner = getHalTuner(nativeContext);
    if (halTuner == nullptr) return;

@@ -282,9 +286,10 @@ static void nativeScan(JNIEnv *env, jobject obj, jlong nativeContext,
}

static void nativeTune(JNIEnv *env, jobject obj, jlong nativeContext, jobject jSelector) {
    ALOGV("nativeTune()");
    AutoMutex _l(gContextMutex);
    ALOGV("%s", __func__);
    lock_guard<mutex> lk(gContextMutex);
    auto& ctx = getNativeContext(nativeContext);

    auto halTuner10 = getHalTuner(ctx);
    auto halTuner11 = ctx.mHalTuner11;
    if (halTuner10 == nullptr) return;
@@ -304,7 +309,7 @@ static void nativeTune(JNIEnv *env, jobject obj, jlong nativeContext, jobject jS
}

static void nativeCancel(JNIEnv *env, jobject obj, jlong nativeContext) {
    ALOGV("nativeCancel()");
    ALOGV("%s", __func__);
    auto halTuner = getHalTuner(nativeContext);
    if (halTuner == nullptr) return;

@@ -323,9 +328,10 @@ static void nativeCancelAnnouncement(JNIEnv *env, jobject obj, jlong nativeConte
}

static jobject nativeGetProgramInformation(JNIEnv *env, jobject obj, jlong nativeContext) {
    ALOGV("nativeGetProgramInformation()");
    AutoMutex _l(gContextMutex);
    ALOGV("%s", __func__);
    lock_guard<mutex> lk(gContextMutex);
    auto& ctx = getNativeContext(nativeContext);

    auto halTuner10 = getHalTuner(ctx);
    auto halTuner11 = ctx.mHalTuner11;
    if (halTuner10 == nullptr) return nullptr;
@@ -355,7 +361,7 @@ static jobject nativeGetProgramInformation(JNIEnv *env, jobject obj, jlong nativ
}

static bool nativeStartBackgroundScan(JNIEnv *env, jobject obj, jlong nativeContext) {
    ALOGV("nativeStartBackgroundScan()");
    ALOGV("%s", __func__);
    auto halTuner = getHalTuner11(nativeContext);
    if (halTuner == nullptr) {
        ALOGI("Background scan is not supported with HAL < 1.1");
@@ -369,7 +375,7 @@ static bool nativeStartBackgroundScan(JNIEnv *env, jobject obj, jlong nativeCont
}

static jobject nativeGetProgramList(JNIEnv *env, jobject obj, jlong nativeContext, jstring jFilter) {
    ALOGV("nativeGetProgramList()");
    ALOGV("%s", __func__);
    auto halTuner = getHalTuner11(nativeContext);
    if (halTuner == nullptr) {
        ALOGI("Program list is not supported with HAL < 1.1");
@@ -398,7 +404,7 @@ static jobject nativeGetProgramList(JNIEnv *env, jobject obj, jlong nativeContex

static jbyteArray nativeGetImage(JNIEnv *env, jobject obj, jlong nativeContext, jint id) {
    ALOGV("%s(%x)", __func__, id);
    AutoMutex _l(gContextMutex);
    lock_guard<mutex> lk(gContextMutex);
    auto& ctx = getNativeContext(nativeContext);

    if (ctx.mHalModule11 == nullptr) {
@@ -435,7 +441,7 @@ static jbyteArray nativeGetImage(JNIEnv *env, jobject obj, jlong nativeContext,
}

static bool nativeIsAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext) {
    ALOGV("nativeIsAnalogForced()");
    ALOGV("%s", __func__);
    auto halTuner = getHalTuner11(nativeContext);
    if (halTuner == nullptr) {
        jniThrowException(env, "java/lang/IllegalStateException",
@@ -456,7 +462,7 @@ static bool nativeIsAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext)
}

static void nativeSetAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext, bool isForced) {
    ALOGV("nativeSetAnalogForced()");
    ALOGV("%s(%d)", __func__, isForced);
    auto halTuner = getHalTuner11(nativeContext);
    if (halTuner == nullptr) {
        jniThrowException(env, "java/lang/IllegalStateException",
@@ -469,7 +475,7 @@ static void nativeSetAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext,
}

static bool nativeIsAntennaConnected(JNIEnv *env, jobject obj, jlong nativeContext) {
    ALOGV("nativeIsAntennaConnected()");
    ALOGV("%s", __func__);
    auto halTuner = getHalTuner(nativeContext);
    if (halTuner == nullptr) return false;

+28 −25
Original line number Diff line number Diff line
@@ -22,9 +22,9 @@
#include "Tuner.h"
#include "convert.h"

#include <JNIHelp.h>
#include <Utils.h>
#include <broadcastradio-utils/Utils.h>
#include <core_jni_helpers.h>
#include <nativehelper/JNIHelp.h>
#include <utils/Log.h>

namespace android {
@@ -32,6 +32,9 @@ namespace server {
namespace BroadcastRadio {
namespace TunerCallback {

using std::lock_guard;
using std::mutex;

using hardware::Return;
using hardware::hidl_vec;

@@ -76,7 +79,7 @@ enum class TunerError : jint {
    BACKGROUND_SCAN_FAILED = 6,
};

static Mutex gContextMutex;
static mutex gContextMutex;

class NativeCallback : public ITunerCallback {
    jobject mJTuner;
@@ -122,13 +125,13 @@ private:

NativeCallback::NativeCallback(JNIEnv *env, jobject jTuner, jobject jCallback, HalRevision halRev)
        : mCallbackThread(gvm), mHalRev(halRev) {
    ALOGV("NativeCallback()");
    ALOGV("%s", __func__);
    mJTuner = env->NewGlobalRef(jTuner);
    mJCallback = env->NewGlobalRef(jCallback);
}

NativeCallback::~NativeCallback() {
    ALOGV("~NativeCallback()");
    ALOGV("%s", __func__);

    // stop callback thread before dereferencing client callback
    mCallbackThread.stop();
@@ -155,7 +158,7 @@ Return<void> NativeCallback::hardwareFailure() {
}

Return<void> NativeCallback::configChange(Result result, const BandConfig& config) {
    ALOGV("configChange(%d)", result);
    ALOGV("%s(%d)", __func__, result);

    mCallbackThread.enqueue([result, config, this](JNIEnv *env) {
        if (result == Result::OK) {
@@ -173,7 +176,7 @@ Return<void> NativeCallback::configChange(Result result, const BandConfig& confi
}

Return<void> NativeCallback::tuneComplete(Result result, const V1_0::ProgramInfo& info) {
    ALOGV("tuneComplete(%d)", result);
    ALOGV("%s(%d)", __func__, result);

    if (mHalRev > HalRevision::V1_0) {
        ALOGW("1.0 callback was ignored");
@@ -185,7 +188,7 @@ Return<void> NativeCallback::tuneComplete(Result result, const V1_0::ProgramInfo
}

Return<void> NativeCallback::tuneComplete_1_1(Result result, const ProgramSelector& selector) {
    ALOGV("tuneComplete_1_1(%d)", result);
    ALOGV("%s(%d)", __func__, result);

    mCallbackThread.enqueue([result, this](JNIEnv *env) {
        if (result == Result::OK) {
@@ -201,17 +204,17 @@ Return<void> NativeCallback::tuneComplete_1_1(Result result, const ProgramSelect
}

Return<void> NativeCallback::afSwitch(const V1_0::ProgramInfo& info) {
    ALOGV("afSwitch()");
    ALOGV("%s", __func__);
    return tuneComplete(Result::OK, info);
}

Return<void> NativeCallback::afSwitch_1_1(const ProgramSelector& selector) {
    ALOGV("afSwitch_1_1()");
    ALOGV("%s", __func__);
    return tuneComplete_1_1(Result::OK, selector);
}

Return<void> NativeCallback::antennaStateChange(bool connected) {
    ALOGV("antennaStateChange(%d)", connected);
    ALOGV("%s(%d)", __func__, connected);

    mCallbackThread.enqueue([this, connected](JNIEnv *env) {
        env->CallVoidMethod(mJCallback, gjni.TunerCallback.onAntennaState, connected);
@@ -221,7 +224,7 @@ Return<void> NativeCallback::antennaStateChange(bool connected) {
}

Return<void> NativeCallback::trafficAnnouncement(bool active) {
    ALOGV("trafficAnnouncement(%d)", active);
    ALOGV("%s(%d)", __func__, active);

    mCallbackThread.enqueue([this, active](JNIEnv *env) {
        env->CallVoidMethod(mJCallback, gjni.TunerCallback.onTrafficAnnouncement, active);
@@ -231,7 +234,7 @@ Return<void> NativeCallback::trafficAnnouncement(bool active) {
}

Return<void> NativeCallback::emergencyAnnouncement(bool active) {
    ALOGV("emergencyAnnouncement(%d)", active);
    ALOGV("%s(%d)", __func__, active);

    mCallbackThread.enqueue([this, active](JNIEnv *env) {
        env->CallVoidMethod(mJCallback, gjni.TunerCallback.onEmergencyAnnouncement, active);
@@ -243,7 +246,7 @@ Return<void> NativeCallback::emergencyAnnouncement(bool active) {
Return<void> NativeCallback::newMetadata(uint32_t channel, uint32_t subChannel,
        const hidl_vec<MetaData>& metadata) {
    // channel and subChannel are not used
    ALOGV("newMetadata(%d, %d)", channel, subChannel);
    ALOGV("%s(%d, %d)", __func__, channel, subChannel);

    if (mHalRev > HalRevision::V1_0) {
        ALOGW("1.0 callback was ignored");
@@ -258,7 +261,7 @@ Return<void> NativeCallback::newMetadata(uint32_t channel, uint32_t subChannel,
}

Return<void> NativeCallback::backgroundScanAvailable(bool isAvailable) {
    ALOGV("backgroundScanAvailable(%d)", isAvailable);
    ALOGV("%s(%d)", __func__, isAvailable);

    mCallbackThread.enqueue([this, isAvailable](JNIEnv *env) {
        env->CallVoidMethod(mJCallback,
@@ -269,7 +272,7 @@ Return<void> NativeCallback::backgroundScanAvailable(bool isAvailable) {
}

Return<void> NativeCallback::backgroundScanComplete(ProgramListResult result) {
    ALOGV("backgroundScanComplete(%d)", result);
    ALOGV("%s(%d)", __func__, result);

    mCallbackThread.enqueue([this, result](JNIEnv *env) {
        if (result == ProgramListResult::OK) {
@@ -285,7 +288,7 @@ Return<void> NativeCallback::backgroundScanComplete(ProgramListResult result) {
}

Return<void> NativeCallback::programListChanged() {
    ALOGV("programListChanged()");
    ALOGV("%s", __func__);

    mCallbackThread.enqueue([this](JNIEnv *env) {
        env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramListChanged);
@@ -295,7 +298,7 @@ Return<void> NativeCallback::programListChanged() {
}

Return<void> NativeCallback::programInfoChanged() {
    ALOGV("programInfoChanged()");
    ALOGV("%s", __func__);

    mCallbackThread.enqueue([this](JNIEnv *env) {
        env->CallVoidMethod(mJCallback, gjni.TunerCallback.onProgramInfoChanged);
@@ -318,8 +321,8 @@ static TunerCallbackContext& getNativeContext(JNIEnv *env, jobject jTunerCb) {
}

static jlong nativeInit(JNIEnv *env, jobject obj, jobject jTuner, jint jHalRev) {
    ALOGV("nativeInit()");
    AutoMutex _l(gContextMutex);
    ALOGV("%s", __func__);
    lock_guard<mutex> lk(gContextMutex);

    auto halRev = static_cast<HalRevision>(jHalRev);

@@ -331,16 +334,16 @@ static jlong nativeInit(JNIEnv *env, jobject obj, jobject jTuner, jint jHalRev)
}

static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
    ALOGV("nativeFinalize()");
    AutoMutex _l(gContextMutex);
    ALOGV("%s", __func__);
    lock_guard<mutex> lk(gContextMutex);

    auto ctx = reinterpret_cast<TunerCallbackContext*>(nativeContext);
    delete ctx;
}

static void nativeDetach(JNIEnv *env, jobject obj, jlong nativeContext) {
    ALOGV("nativeDetach()");
    AutoMutex _l(gContextMutex);
    ALOGV("%s", __func__);
    lock_guard<mutex> lk(gContextMutex);
    auto& ctx = getNativeContext(nativeContext);

    if (ctx.mNativeCallback == nullptr) return;
@@ -349,7 +352,7 @@ static void nativeDetach(JNIEnv *env, jobject obj, jlong nativeContext) {
}

sp<ITunerCallback> getNativeCallback(JNIEnv *env, jobject jTunerCallback) {
    AutoMutex _l(gContextMutex);
    lock_guard<mutex> lk(gContextMutex);
    auto& ctx = getNativeContext(env, jTunerCallback);
    return ctx.mNativeCallback;
}
Loading