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

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

Merge "Implement get/setConfiguration calls of ITuner."

parents 4afd39e7 8b6db4f2
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -22,5 +22,12 @@ import android.hardware.radio.RadioManager;
interface ITuner {
    void close();

    /**
     * @throws IllegalArgumentException if config is not valid or null
     */
    void setConfiguration(in RadioManager.BandConfig config);

    RadioManager.BandConfig getConfiguration();

    int getProgramInformation(out RadioManager.ProgramInfo[] infoOut);
}
+18 −4
Original line number Diff line number Diff line
@@ -58,14 +58,28 @@ class TunerAdapter extends RadioTuner {

    @Override
    public int setConfiguration(RadioManager.BandConfig config) {
        // TODO(b/36863239): forward to mTuner
        throw new RuntimeException("Not implemented");
        try {
            mTuner.setConfiguration(config);
            return RadioManager.STATUS_OK;
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "Can't set configuration", e);
            return RadioManager.STATUS_BAD_VALUE;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @Override
    public int getConfiguration(RadioManager.BandConfig[] config) {
        // TODO(b/36863239): forward to mTuner
        throw new RuntimeException("Not implemented");
        if (config == null || config.length != 1) {
            throw new IllegalArgumentException("The argument must be an array of length 1");
        }
        try {
            config[0] = mTuner.getConfiguration();
            return RadioManager.STATUS_OK;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @Override
+31 −3
Original line number Diff line number Diff line
@@ -31,7 +31,8 @@ class Tuner extends ITuner.Stub {
     */
    private final long mNativeContext;

    private int mRegion;
    private final Object mLock = new Object();
    private int mRegion;  // TODO(b/36863239): find better solution to manage regions

    Tuner(@NonNull ITunerCallback clientCallback, int region) {
        mRegion = region;
@@ -44,17 +45,44 @@ class Tuner extends ITuner.Stub {
        super.finalize();
    }

    private native long nativeInit(ITunerCallback clientCallback);
    private native long nativeInit(@NonNull ITunerCallback clientCallback);
    private native void nativeFinalize(long nativeContext);
    private native void nativeClose(long nativeContext);

    private native void nativeSetConfiguration(long nativeContext,
            @NonNull RadioManager.BandConfig config);
    private native RadioManager.BandConfig nativeGetConfiguration(long nativeContext, int region);

    @Override
    public void close() {
        synchronized (mLock) {
            nativeClose(mNativeContext);
        }
    }

    @Override
    public void setConfiguration(RadioManager.BandConfig config) {
        if (config == null) {
            throw new IllegalArgumentException("The argument must not be a null pointer");
        }
        synchronized (mLock) {
            nativeSetConfiguration(mNativeContext, config);
            mRegion = config.getRegion();
        }
    }

    @Override
    public RadioManager.BandConfig getConfiguration() {
        synchronized (mLock) {
            return nativeGetConfiguration(mNativeContext, mRegion);
        }
    }

    @Override
    public int getProgramInformation(RadioManager.ProgramInfo[] infoOut) {
        if (infoOut == null || infoOut.length != 1) {
            throw new IllegalArgumentException("The argument must be an array of length 1");
        }
        Slog.d(TAG, "getProgramInformation()");
        return RadioManager.STATUS_INVALID_OPERATION;
    }
+42 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include "com_android_server_radio_Tuner.h"

#include "com_android_server_radio_convert.h"
#include "com_android_server_radio_Tuner_TunerCallback.h"

#include <android/hardware/broadcastradio/1.1/IBroadcastRadioFactory.h>
@@ -104,6 +105,13 @@ void setHalTuner(JNIEnv *env, jobject obj, sp<ITuner> halTuner) {
    ctx.mHalTuner = halTuner;
}

sp<ITuner> getHalTuner(jlong nativeContext) {
    AutoMutex _l(gContextMutex);
    auto tuner = getNativeContext(nativeContext).mHalTuner;
    LOG_ALWAYS_FATAL_IF(tuner == nullptr, "HAL tuner not set");
    return tuner;
}

sp<ITunerCallback> getNativeCallback(JNIEnv *env, jobject obj) {
    AutoMutex _l(gContextMutex);
    auto& ctx = getNativeContext(env, obj);
@@ -114,7 +122,7 @@ Region getRegion(JNIEnv *env, jobject obj) {
    return static_cast<Region>(env->GetIntField(obj, gjni.Tuner.region));
}

static void close(JNIEnv *env, jobject obj, jlong nativeContext) {
static void nativeClose(JNIEnv *env, jobject obj, jlong nativeContext) {
    AutoMutex _l(gContextMutex);
    auto& ctx = getNativeContext(nativeContext);
    ALOGI("Closing tuner %p", ctx.mHalTuner.get());
@@ -123,10 +131,42 @@ static void close(JNIEnv *env, jobject obj, jlong nativeContext) {
    ctx.mNativeCallback = nullptr;
}

static void nativeSetConfiguration(JNIEnv *env, jobject obj, jlong nativeContext, jobject config) {
    ALOGV("nativeSetConfiguration()");
    auto halTuner = getHalTuner(nativeContext);

    Region region_unused;
    BandConfig bandConfigHal = convert::BandConfigToHal(env, config, region_unused);

    convert::ThrowIfFailed(env, halTuner->setConfiguration(bandConfigHal));
}

static jobject nativeGetConfiguration(JNIEnv *env, jobject obj, jlong nativeContext,
        Region region) {
    ALOGV("nativeSetConfiguration()");
    auto halTuner = getHalTuner(nativeContext);

    BandConfig halConfig;
    Result halResult;
    auto hidlResult = halTuner->getConfiguration([&](Result result, const BandConfig& config) {
        halResult = result;
        halConfig = config;
    });
    if (convert::ThrowIfFailed(env, hidlResult)) {
        return nullptr;
    }

    return convert::BandConfigFromHal(env, halConfig, region).release();
}

static const JNINativeMethod gTunerMethods[] = {
    { "nativeInit", "(Landroid/hardware/radio/ITunerCallback;)J", (void*)nativeInit },
    { "nativeFinalize", "(J)V", (void*)nativeFinalize },
    { "nativeClose", "(J)V", (void*)close },
    { "nativeClose", "(J)V", (void*)nativeClose },
    { "nativeSetConfiguration", "(JLandroid/hardware/radio/RadioManager$BandConfig;)V",
            (void*)nativeSetConfiguration },
    { "nativeGetConfiguration", "(JI)Landroid/hardware/radio/RadioManager$BandConfig;",
            (void*)nativeGetConfiguration },
};

} // namespace Tuner
+45 −0
Original line number Diff line number Diff line
@@ -28,10 +28,12 @@ namespace server {
namespace radio {
namespace convert {

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

using V1_0::Band;
using V1_0::Deemphasis;
using V1_0::Result;
using V1_0::Rds;

static struct {
@@ -62,6 +64,47 @@ static struct {
    } BandDescriptor;
} gjni;

template <typename T>
bool ThrowIfFailedCommon(JNIEnv *env, const hardware::Return<T> &hidlResult) {
    if (hidlResult.isOk()) return false;

    jniThrowExceptionFmt(env, "java/lang/RuntimeException",
            "HIDL call failed: %s", hidlResult.description().c_str());
    return true;
}

bool ThrowIfFailed(JNIEnv *env, const hardware::Return<void> &hidlResult) {
    return ThrowIfFailedCommon(env, hidlResult);
}

bool ThrowIfFailed(JNIEnv *env, const hardware::Return<V1_0::Result> &hidlResult) {
    if (ThrowIfFailedCommon(env, hidlResult)) return true;

    Result result = hidlResult;
    switch (result) {
        case Result::OK:
            return false;
        case Result::NOT_INITIALIZED:
            jniThrowException(env, "java/lang/RuntimeException", "Result::NOT_INITIALIZED");
            return true;
        case Result::INVALID_ARGUMENTS:
            jniThrowException(env, "java/lang/IllegalArgumentException",
                    "Result::INVALID_ARGUMENTS");
            return true;
        case Result::INVALID_STATE:
            jniThrowException(env, "java/lang/IllegalStateException", "Result::INVALID_STATE");
            return true;
        case Result::TIMEOUT:
            jniThrowException(env, "java/lang/RuntimeException",
                    "Result::TIMEOUT (unexpected here)");
            return true;
        default:
            jniThrowExceptionFmt(env, "java/lang/RuntimeException",
                    "Unknown failure, result: %d", result);
            return true;
    }
}

static Rds RdsForRegion(bool rds, Region region) {
    if (!rds) return Rds::NONE;

@@ -95,6 +138,7 @@ static Deemphasis DeemphasisForRegion(Region region) {
}

JavaRef BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region region) {
    ALOGV("BandConfigFromHal()");
    EnvWrapper wrap(env);

    jint spacing = config.spacings.size() > 0 ? config.spacings[0] : 0;
@@ -122,6 +166,7 @@ JavaRef BandConfigFromHal(JNIEnv *env, const V1_0::BandConfig &config, Region re
}

V1_0::BandConfig BandConfigToHal(JNIEnv *env, jobject jConfig, Region &region) {
    ALOGV("BandConfigToHal()");
    auto jDescriptor = env->GetObjectField(jConfig, gjni.BandConfig.descriptor);
    if (jDescriptor == nullptr) {
        ALOGE("Descriptor is missing");
Loading