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

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

Merge "Implement program list and forced analog features of ITuner."

parents 085c1aac d3d53f66
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -58,4 +58,30 @@ interface ITuner {
    void cancel();

    RadioManager.ProgramInfo getProgramInformation();

    /**
     * @returns {@code true} if the scan was properly scheduled,
     *          {@code false} if the scan feature is unavailable
     */
    boolean startBackgroundScan();

    /**
     * @returns the list, or null if scan is in progress
     * @throws IllegalArgumentException if invalid arguments are passed
     * @throws IllegalStateException if the scan has not been started, client may
     *         call startBackgroundScan to fix this.
     */
    List<RadioManager.ProgramInfo> getProgramList(String filter);

    /**
     * @throws IllegalStateException if the switch is not supported at current
     *         configuration.
     */
    boolean isAnalogForced();

    /**
     * @throws IllegalStateException if the switch is not supported at current
     *         configuration.
     */
    void setAnalogForced(boolean isForced);
}
+20 −8
Original line number Diff line number Diff line
@@ -182,26 +182,38 @@ class TunerAdapter extends RadioTuner {

    @Override
    public boolean startBackgroundScan() {
        // TODO(b/36863239): forward to mTuner
        throw new RuntimeException("Not implemented");
        try {
            return mTuner.startBackgroundScan();
        } catch (RemoteException e) {
            throw new RuntimeException("service died", e);
        }
    }

    @Override
    public @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter) {
        // TODO(b/36863239): forward to mTuner
        throw new RuntimeException("Not implemented");
        try {
            return mTuner.getProgramList(filter);
        } catch (RemoteException e) {
            throw new RuntimeException("service died", e);
        }
    }

    @Override
    public boolean isAnalogForced() {
        // TODO(b/36863239): forward to mTuner
        throw new RuntimeException("Not implemented");
        try {
            return mTuner.isAnalogForced();
        } catch (RemoteException e) {
            throw new RuntimeException("service died", e);
        }
    }

    @Override
    public void setAnalogForced(boolean isForced) {
        // TODO(b/36863239): forward to mTuner
        throw new RuntimeException("Not implemented");
        try {
            mTuner.setAnalogForced(isForced);
        } catch (RemoteException e) {
            throw new RuntimeException("service died", e);
        }
    }

    @Override
+40 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;
import android.util.Slog;

import java.util.List;

class Tuner extends ITuner.Stub {
    // TODO(b/36863239): rename to RadioService.Tuner when native service goes away
    private static final String TAG = "RadioServiceJava.Tuner";
@@ -65,6 +67,12 @@ class Tuner extends ITuner.Stub {
    private native void nativeCancel(long nativeContext);

    private native RadioManager.ProgramInfo nativeGetProgramInformation(long nativeContext);
    private native boolean nativeStartBackgroundScan(long nativeContext);
    private native List<RadioManager.ProgramInfo> nativeGetProgramList(long nativeContext,
            String filter);

    private native boolean nativeIsAnalogForced(long nativeContext);
    private native void nativeSetAnalogForced(long nativeContext, boolean isForced);

    @Override
    public void close() {
@@ -168,4 +176,36 @@ class Tuner extends ITuner.Stub {
            return nativeGetProgramInformation(mNativeContext);
        }
    }

    public boolean startBackgroundScan() {
        synchronized (mLock) {
            checkNotClosedLocked();
            return nativeStartBackgroundScan(mNativeContext);
        }
    }

    public List<RadioManager.ProgramInfo> getProgramList(String filter) {
        synchronized (mLock) {
            checkNotClosedLocked();
            List<RadioManager.ProgramInfo> list = nativeGetProgramList(mNativeContext, filter);
            if (list == null) {
                throw new IllegalStateException("Program list is not ready");
            }
            return list;
        }
    }

    public boolean isAnalogForced() {
        synchronized (mLock) {
            checkNotClosedLocked();
            return nativeIsAnalogForced(mNativeContext);
        }
    }

    public void setAnalogForced(boolean isForced) {
        synchronized (mLock) {
            checkNotClosedLocked();
            nativeSetAnalogForced(mNativeContext, isForced);
        }
    }
}
+0 −7
Original line number Diff line number Diff line
@@ -54,10 +54,6 @@ static struct {
        jclass clazz;
        jmethodID cstor;
    } Tuner;

    struct {
        jclass clazz;
    } RadioService;
} gjni;

struct ServiceContext {
@@ -204,9 +200,6 @@ void register_android_server_radio_RadioService(JNIEnv *env) {
    gjni.Tuner.cstor = GetMethodIDOrDie(env, tunerClass, "<init>",
            "(Landroid/hardware/radio/ITunerCallback;IIZ)V");

    auto serviceClass = FindClassOrDie(env, "com/android/server/radio/RadioService");
    gjni.RadioService.clazz = MakeGlobalRefOrDie(env, serviceClass);

    auto res = jniRegisterNativeMethods(env, "com/android/server/radio/RadioService",
            gRadioServiceMethods, NELEM(gRadioServiceMethods));
    LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
+92 −0
Original line number Diff line number Diff line
@@ -47,6 +47,11 @@ using V1_1::ProgramListResult;
static Mutex gContextMutex;

static struct {
    struct {
        jclass clazz;
        jmethodID cstor;
        jmethodID add;
    } ArrayList;
    struct {
        jfieldID nativeContext;
        jfieldID region;
@@ -235,6 +240,83 @@ static jobject nativeGetProgramInformation(JNIEnv *env, jobject obj, jlong nativ
    return convert::ProgramInfoFromHal(env, halInfo).release();
}

static bool nativeStartBackgroundScan(JNIEnv *env, jobject obj, jlong nativeContext) {
    ALOGV("nativeStartBackgroundScan()");
    auto halTuner = getHalTuner11(nativeContext);
    if (halTuner == nullptr) {
        ALOGI("Background scan is not supported with HAL < 1.1");
        return false;
    }

    auto halResult = halTuner->startBackgroundScan();

    if (halResult.isOk() && halResult == ProgramListResult::UNAVAILABLE) return false;
    return !convert::ThrowIfFailed(env, halResult);
}

static jobject nativeGetProgramList(JNIEnv *env, jobject obj, jlong nativeContext, jstring jFilter) {
    ALOGV("nativeGetProgramList()");
    EnvWrapper wrap(env);
    auto halTuner = getHalTuner11(nativeContext);
    if (halTuner == nullptr) {
        ALOGI("Program list is not supported with HAL < 1.1");
        return nullptr;
    }

    JavaRef<jobject> jList;
    ProgramListResult halResult = ProgramListResult::NOT_INITIALIZED;
    auto filter = env->GetStringUTFChars(jFilter, nullptr);
    auto hidlResult = halTuner->getProgramList(filter,
            [&](ProgramListResult result, const hidl_vec<V1_1::ProgramInfo>& programList) {
        halResult = result;
        if (halResult != ProgramListResult::OK) return;

        jList = wrap(env->NewObject(gjni.ArrayList.clazz, gjni.ArrayList.cstor));
        for (auto& program : programList) {
            auto jProgram = convert::ProgramInfoFromHal(env, program);
            env->CallBooleanMethod(jList.get(), gjni.ArrayList.add, jProgram.get());
        }
    });

    if (convert::ThrowIfFailed(env, hidlResult, halResult)) return nullptr;

    return jList.release();
}

static bool nativeIsAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext) {
    ALOGV("nativeIsAnalogForced()");
    auto halTuner = getHalTuner11(nativeContext);
    if (halTuner == nullptr) {
        jniThrowException(env, "java/lang/IllegalStateException",
                "Forced analog switch is not supported with HAL < 1.1");
        return false;
    }

    bool isForced;
    Result halResult;
    auto hidlResult = halTuner->isAnalogForced([&](Result result, bool isForcedRet) {
        halResult = result;
        isForced = isForcedRet;
    });

    if (convert::ThrowIfFailed(env, hidlResult, halResult)) return false;

    return isForced;
}

static void nativeSetAnalogForced(JNIEnv *env, jobject obj, jlong nativeContext, bool isForced) {
    ALOGV("nativeSetAnalogForced()");
    auto halTuner = getHalTuner11(nativeContext);
    if (halTuner == nullptr) {
        jniThrowException(env, "java/lang/IllegalStateException",
                "Forced analog switch is not supported with HAL < 1.1");
        return;
    }

    auto halResult = halTuner->setAnalogForced(isForced);
    convert::ThrowIfFailed(env, halResult);
}

static const JNINativeMethod gTunerMethods[] = {
    { "nativeInit", "(I)J", (void*)nativeInit },
    { "nativeFinalize", "(J)V", (void*)nativeFinalize },
@@ -249,6 +331,11 @@ static const JNINativeMethod gTunerMethods[] = {
    { "nativeCancel", "(J)V", (void*)nativeCancel },
    { "nativeGetProgramInformation", "(J)Landroid/hardware/radio/RadioManager$ProgramInfo;",
            (void*)nativeGetProgramInformation },
    { "nativeStartBackgroundScan", "(J)Z", (void*)nativeStartBackgroundScan },
    { "nativeGetProgramList", "(JLjava/lang/String;)Ljava/util/List;",
            (void*)nativeGetProgramList },
    { "nativeIsAnalogForced", "(J)Z", (void*)nativeIsAnalogForced },
    { "nativeSetAnalogForced", "(JZ)V", (void*)nativeSetAnalogForced },
};

} // namespace Tuner
@@ -266,6 +353,11 @@ void register_android_server_radio_Tuner(JavaVM *vm, JNIEnv *env) {
    gjni.Tuner.tunerCallback = GetFieldIDOrDie(env, tunerClass, "mTunerCallback",
            "Lcom/android/server/radio/TunerCallback;");

    auto arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
    gjni.ArrayList.clazz = MakeGlobalRefOrDie(env, arrayListClass);
    gjni.ArrayList.cstor = GetMethodIDOrDie(env, arrayListClass, "<init>", "()V");
    gjni.ArrayList.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");

    auto res = jniRegisterNativeMethods(env, "com/android/server/radio/Tuner",
            gTunerMethods, NELEM(gTunerMethods));
    LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
Loading