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

Commit 2f9cab38 authored by shubang's avatar shubang Committed by Amy Zhang
Browse files

Tuner FW: handle release frontend

This can unblock tune/scan CTS test cases.
If a frontend resource is acquired in a test case and not released,
it cannot be used by another test case.

Bug: 150952758
Test: atest android.media.tv.tuner.cts.TunerTest
Change-Id: Ib9bab003fc81fe008091a9d1aaefc43e454c3230
parent 2b40d3c4
Loading
Loading
Loading
Loading
+20 −4
Original line number Diff line number Diff line
@@ -263,14 +263,14 @@ public class Tuner implements AutoCloseable {
    }

    private void setFrontendInfoList() {
        List<Integer> ids = nativeGetFrontendIds();
        List<Integer> ids = getFrontendIds();
        if (ids == null) {
            return;
        }
        TunerFrontendInfo[] infos = new TunerFrontendInfo[ids.size()];
        for (int i = 0; i < ids.size(); i++) {
            int id = ids.get(i);
            FrontendInfo frontendInfo = nativeGetFrontendInfo(id);
            FrontendInfo frontendInfo = getFrontendInfoById(id);
            if (frontendInfo == null) {
                continue;
            }
@@ -281,6 +281,11 @@ public class Tuner implements AutoCloseable {
        mTunerResourceManager.setFrontendInfoList(infos);
    }

    /** @hide */
    public List<Integer> getFrontendIds() {
        return nativeGetFrontendIds();
    }

    private void setLnbIds() {
        int[] ids = nativeGetLnbIds();
        if (ids == null) {
@@ -345,14 +350,17 @@ public class Tuner implements AutoCloseable {
    @Override
    public void close() {
        if (mFrontendHandle != null) {
            nativeCloseFrontendByHandle(mFrontendHandle);
            mTunerResourceManager.releaseFrontend(mFrontendHandle);
            mFrontendHandle = null;
            mFrontend = null;
        }
        if (mLnb != null) {
            mTunerResourceManager.releaseLnb(mLnbHandle);
            mLnb = null;
            mLnbHandle = null;
        }
        nativeClose();
        TunerUtils.throwExceptionForResult(nativeClose(), "failed to close tuner");
    }

    /**
@@ -374,6 +382,8 @@ public class Tuner implements AutoCloseable {
     * Native method to open frontend of the given ID.
     */
    private native Frontend nativeOpenFrontendByHandle(int handle);
    @Result
    private native int nativeCloseFrontendByHandle(int handle);
    private native int nativeTune(int type, FrontendSettings settings);
    private native int nativeStopTune();
    private native int nativeScan(int settingsType, FrontendSettings settings, int scanType);
@@ -522,6 +532,7 @@ public class Tuner implements AutoCloseable {
    public int tune(@NonNull FrontendSettings settings) {
        mFrontendType = settings.getType();
        checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND);

        mFrontendInfo = null;
        return nativeTune(settings.getType(), settings);
    }
@@ -706,11 +717,16 @@ public class Tuner implements AutoCloseable {
            throw new IllegalStateException("frontend is not initialized");
        }
        if (mFrontendInfo == null) {
            mFrontendInfo = nativeGetFrontendInfo(mFrontend.mId);
            mFrontendInfo = getFrontendInfoById(mFrontend.mId);
        }
        return mFrontendInfo;
    }

    /** @hide */
    public FrontendInfo getFrontendInfoById(int id) {
        return nativeGetFrontendInfo(id);
    }

    /**
     * Gets Demux capabilities.
     *
+3 −3
Original line number Diff line number Diff line
@@ -416,11 +416,11 @@ public class TunerResourceManager {
     * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
     * before this release.
     *
     * @param frontendId the id of the released frontend.
     * @param frontendHandle the handle of the released frontend.
     */
    public void releaseFrontend(int frontendId) {
    public void releaseFrontend(int frontendHandle) {
        try {
            mService.releaseFrontend(frontendId);
            mService.releaseFrontend(frontendHandle);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+46 −0
Original line number Diff line number Diff line
@@ -833,6 +833,12 @@ JTuner::JTuner(JNIEnv *env, jobject thiz)
}

JTuner::~JTuner() {
    if (mFe != NULL) {
        mFe->close();
    }
    if (mDemux != NULL) {
        mDemux->close();
    }
    JNIEnv *env = AndroidRuntime::getJNIEnv();

    env->DeleteWeakGlobalRef(mObject);
@@ -908,6 +914,14 @@ jobject JTuner::openFrontendById(int id) {
            (jint) jId);
}

jint JTuner::closeFrontendById(int id) {
    if (mFe != NULL && mFeId == id) {
        Result r = mFe->close();
        return (jint) r;
    }
    return (jint) Result::SUCCESS;
}

jobject JTuner::getAnalogFrontendCaps(JNIEnv *env, FrontendInfo::FrontendCapabilities& caps) {
    jclass clazz = env->FindClass("android/media/tv/tuner/frontend/AnalogFrontendCapabilities");
    jmethodID capsInit = env->GetMethodID(clazz, "<init>", "(II)V");
@@ -1271,6 +1285,23 @@ Result JTuner::openDemux() {
    return res;
}

jint JTuner::close() {
    Result res = Result::SUCCESS;
    if (mFe != NULL) {
        res = mFe->close();
        if (res != Result::SUCCESS) {
            return (jint) res;
        }
    }
    if (mDemux != NULL) {
        res = mDemux->close();
        if (res != Result::SUCCESS) {
            return (jint) res;
        }
    }
    return (jint) res;
}

jobject JTuner::getAvSyncHwId(sp<Filter> filter) {
    if (mDemux == NULL) {
        return NULL;
@@ -2362,6 +2393,13 @@ static jobject android_media_tv_Tuner_open_frontend_by_handle(
    return tuner->openFrontendById(id);
}

static jint android_media_tv_Tuner_close_frontend_by_handle(
        JNIEnv *env, jobject thiz, jint handle) {
    sp<JTuner> tuner = getTuner(env, thiz);
    uint32_t id = getResourceIdFromHandle(handle);
    return tuner->closeFrontendById(id);
}

static int android_media_tv_Tuner_tune(JNIEnv *env, jobject thiz, jint type, jobject settings) {
    sp<JTuner> tuner = getTuner(env, thiz);
    return tuner->tune(getFrontendSettings(env, type, settings));
@@ -3135,6 +3173,11 @@ static jint android_media_tv_Tuner_open_demux(JNIEnv* env, jobject thiz, jint /*
    return (jint) tuner->openDemux();
}

static jint android_media_tv_Tuner_close_tuner(JNIEnv* env, jobject thiz) {
    sp<JTuner> tuner = getTuner(env, thiz);
    return (jint) tuner->close();
}

static jint android_media_tv_Tuner_attach_filter(JNIEnv *env, jobject dvr, jobject filter) {
    sp<Dvr> dvrSp = getDvr(env, dvr);
    if (dvrSp == NULL) {
@@ -3424,6 +3467,8 @@ static const JNINativeMethod gTunerMethods[] = {
            (void *)android_media_tv_Tuner_get_frontend_ids },
    { "nativeOpenFrontendByHandle", "(I)Landroid/media/tv/tuner/Tuner$Frontend;",
            (void *)android_media_tv_Tuner_open_frontend_by_handle },
    { "nativeCloseFrontendByHandle", "(I)I",
            (void *)android_media_tv_Tuner_close_frontend_by_handle },
    { "nativeTune", "(ILandroid/media/tv/tuner/frontend/FrontendSettings;)I",
            (void *)android_media_tv_Tuner_tune },
    { "nativeStopTune", "()I", (void *)android_media_tv_Tuner_stop_tune },
@@ -3460,6 +3505,7 @@ static const JNINativeMethod gTunerMethods[] = {
    { "nativeGetDemuxCapabilities", "()Landroid/media/tv/tuner/DemuxCapabilities;",
            (void *)android_media_tv_Tuner_get_demux_caps },
    { "nativeOpenDemuxByhandle", "(I)I", (void *)android_media_tv_Tuner_open_demux },
    {"nativeClose", "()I", (void *)android_media_tv_Tuner_close_tuner },
};

static const JNINativeMethod gFilterMethods[] = {
+2 −0
Original line number Diff line number Diff line
@@ -172,6 +172,7 @@ struct JTuner : public RefBase {
    int disconnectCiCam();
    jobject getFrontendIds();
    jobject openFrontendById(int id);
    jint closeFrontendById(int id);
    jobject getFrontendInfo(int id);
    int tune(const FrontendSettings& settings);
    int stopTune();
@@ -189,6 +190,7 @@ struct JTuner : public RefBase {
    jobject getDemuxCaps();
    jobject getFrontendStatus(jintArray types);
    Result openDemux();
    jint close();

protected:
    virtual ~JTuner();
+20 −1
Original line number Diff line number Diff line
@@ -247,12 +247,15 @@ public class TunerResourceManagerService extends SystemService {
        }

        @Override
        public void releaseFrontend(int frontendId) {
        public void releaseFrontend(int frontendHandle) {
            enforceTunerAccessPermission("releaseFrontend");
            enforceTrmAccessPermission("releaseFrontend");
            int frontendId = getResourceId(
                    TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND, frontendHandle);
            if (DEBUG) {
                Slog.d(TAG, "releaseFrontend(id=" + frontendId + ")");
            }
            updateFrontendClientMappingOnRelease(frontendId);
        }

        @Override
@@ -568,6 +571,17 @@ public class TunerResourceManagerService extends SystemService {
        }
    }

    private void updateFrontendClientMappingOnRelease(int frontendId) {
        FrontendResource releasingFrontend = getFrontendResource(frontendId);
        ClientProfile ownerProfile = getClientProfile(releasingFrontend.getOwnerClientId());
        releasingFrontend.removeOwner();
        ownerProfile.releaseFrontend(frontendId);
        for (int exclusiveGroupMember : releasingFrontend.getExclusiveGroupMemberFeIds()) {
            getFrontendResource(exclusiveGroupMember).removeOwner();
            ownerProfile.releaseFrontend(frontendId);
        }
    }

    /**
     * Get the owner client's priority from the frontend id.
     *
@@ -651,6 +665,11 @@ public class TunerResourceManagerService extends SystemService {
                | (mResourceRequestCount++ & 0xffff);
    }

    private int getResourceId(
            @TunerResourceManager.TunerResourceType int resourceType, int resourceHandle) {
        return (resourceHandle & 0x00ff0000) >> 16;
    }

    private void enforceTrmAccessPermission(String apiName) {
        getContext().enforceCallingPermission("android.permission.TUNER_RESOURCE_ACCESS",
                TAG + ": " + apiName);