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

Commit ed7fc385 authored by Amy Zhang's avatar Amy Zhang
Browse files

Manager CiCam resources in Tuner Resource Manager

Add a new resource type CiCamResource to be managed by the TRM

At one moment, there each client could only have one ciCam connected
to either demux or frontend.

Before reconnecting to different ciCam, the client needs to disconnect
first.

Higher priority client could get the ciCam from lower priority one
and cause all resources loss on the previous owner.

Test: atest com.android.server.tv.tunerresourcemanager
Bug: b/172310004
Bug: b/158818696
Change-Id: I2803d0edf1f7282b0a496d7eb79181be42b8eec1
parent 8af4d0bb
Loading
Loading
Loading
Loading
+41 −4
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.media.tv.tuner.frontend.FrontendStatus.FrontendStatusType;
import android.media.tv.tuner.frontend.OnTuneEventListener;
import android.media.tv.tuner.frontend.ScanCallback;
import android.media.tv.tunerresourcemanager.ResourceClientProfile;
import android.media.tv.tunerresourcemanager.TunerCiCamRequest;
import android.media.tv.tunerresourcemanager.TunerDemuxRequest;
import android.media.tv.tunerresourcemanager.TunerDescramblerRequest;
import android.media.tv.tunerresourcemanager.TunerFrontendRequest;
@@ -297,6 +298,8 @@ public class Tuner implements AutoCloseable {
    private Executor mOnResourceLostListenerExecutor;

    private Integer mDemuxHandle;
    private Integer mFrontendCiCamHandle;
    private Integer mFrontendCiCamId;
    private Map<Integer, WeakReference<Descrambler>> mDescramblers = new HashMap<>();
    private List<WeakReference<Filter>> mFilters = new ArrayList<WeakReference<Filter>>();

@@ -469,6 +472,14 @@ public class Tuner implements AutoCloseable {
        if (mLnb != null) {
            mLnb.close();
        }
        if (mFrontendCiCamHandle != null) {
            int result = nativeUnlinkCiCam(mFrontendCiCamId);
            if (result == RESULT_SUCCESS) {
                mTunerResourceManager.releaseCiCam(mFrontendCiCamHandle, mClientId);
                mFrontendCiCamId = null;
                mFrontendCiCamHandle = null;
            }
        }
        synchronized (mDescramblers) {
            if (!mDescramblers.isEmpty()) {
                for (Map.Entry<Integer, WeakReference<Descrambler>> d : mDescramblers.entrySet()) {
@@ -917,7 +928,8 @@ public class Tuner implements AutoCloseable {
    public int connectFrontendToCiCam(int ciCamId) {
        if (TunerVersionChecker.checkHigherOrEqualVersionTo(TunerVersionChecker.TUNER_VERSION_1_1,
                "linkFrontendToCiCam")) {
            if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
            if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)
                    && checkCiCamResource(ciCamId)) {
                return nativeLinkCiCam(ciCamId);
            }
        }
@@ -936,7 +948,7 @@ public class Tuner implements AutoCloseable {
     */
    @Result
    public int disconnectCiCam() {
        if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
        if (mDemuxHandle != null) {
            return nativeDisconnectCiCam();
        }
        return RESULT_UNAVAILABLE;
@@ -962,8 +974,14 @@ public class Tuner implements AutoCloseable {
    public int disconnectFrontendToCiCam(int ciCamId) {
        if (TunerVersionChecker.checkHigherOrEqualVersionTo(TunerVersionChecker.TUNER_VERSION_1_1,
                "unlinkFrontendToCiCam")) {
            if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
                return nativeUnlinkCiCam(ciCamId);
            if (mFrontendCiCamHandle != null && mFrontendCiCamId == ciCamId) {
                int result = nativeUnlinkCiCam(ciCamId);
                if (result == RESULT_SUCCESS) {
                    mTunerResourceManager.releaseCiCam(mFrontendCiCamHandle, mClientId);
                    mFrontendCiCamId = null;
                    mFrontendCiCamHandle = null;
                }
                return result;
            }
        }
        return RESULT_UNAVAILABLE;
@@ -1360,6 +1378,18 @@ public class Tuner implements AutoCloseable {
        return descrambler;
    }

    private boolean requestFrontendCiCam(int ciCamId) {
        int[] ciCamHandle = new int[1];
        TunerCiCamRequest request = new TunerCiCamRequest();
        request.clientId = mClientId;
        request.ciCamId = ciCamId;
        boolean granted = mTunerResourceManager.requestCiCam(request, ciCamHandle);
        if (granted) {
            mFrontendCiCamHandle = ciCamHandle[0];
        }
        return granted;
    }

    private boolean checkResource(int resourceType)  {
        switch (resourceType) {
            case TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND: {
@@ -1386,6 +1416,13 @@ public class Tuner implements AutoCloseable {
        return true;
    }

    private boolean checkCiCamResource(int ciCamId) {
        if (mFrontendCiCamHandle == null && !requestFrontendCiCam(ciCamId)) {
            return false;
        }
        return true;
    }

    /* package */ void releaseLnb() {
        if (mLnbHandle != null) {
            // LNB handle can be null if it's opened by name.
+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ filegroup {
        "aidl/android/media/tv/tunerresourcemanager/CasSessionRequest.aidl",
        "aidl/android/media/tv/tunerresourcemanager/IResourcesReclaimListener.aidl",
        "aidl/android/media/tv/tunerresourcemanager/ResourceClientProfile.aidl",
        "aidl/android/media/tv/tunerresourcemanager/TunerCiCamRequest.aidl",
        "aidl/android/media/tv/tunerresourcemanager/TunerDemuxRequest.aidl",
        "aidl/android/media/tv/tunerresourcemanager/TunerDescramblerRequest.aidl",
        "aidl/android/media/tv/tunerresourcemanager/TunerFrontendInfo.aidl",
+54 −1
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ public class TunerResourceManager {
        TUNER_RESOURCE_TYPE_DESCRAMBLER,
        TUNER_RESOURCE_TYPE_LNB,
        TUNER_RESOURCE_TYPE_CAS_SESSION,
        TUNER_RESOURCE_TYPE_FRONTEND_CICAM,
        TUNER_RESOURCE_TYPE_MAX,
     })
    @Retention(RetentionPolicy.SOURCE)
@@ -84,7 +85,8 @@ public class TunerResourceManager {
    public static final int TUNER_RESOURCE_TYPE_DESCRAMBLER = 2;
    public static final int TUNER_RESOURCE_TYPE_LNB = 3;
    public static final int TUNER_RESOURCE_TYPE_CAS_SESSION = 4;
    public static final int TUNER_RESOURCE_TYPE_MAX = 5;
    public static final int TUNER_RESOURCE_TYPE_FRONTEND_CICAM = 5;
    public static final int TUNER_RESOURCE_TYPE_MAX = 6;

    private final ITunerResourceManager mService;
    private final int mUserId;
@@ -378,6 +380,38 @@ public class TunerResourceManager {
        return result;
    }

    /**
     * Requests a CiCam resource.
     *
     * <p>There are three possible scenarios:
     * <ul>
     * <li>If there is CiCam available, the API would send the id back.
     *
     * <li>If no CiCam is available but the current request info can show higher priority than
     * other uses of the CiCam, the API will send
     * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
     * handle the resource reclaim on the holder of lower priority and notify the holder of its
     * resource loss.
     *
     * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
     * request.
     *
     * @param request {@link TunerCiCamRequest} information of the current request.
     * @param ciCamHandle a one-element array to return the granted ciCam handle.
     *                    If no ciCam granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
     *
     * @return true if there is ciCam granted.
     */
    public boolean requestCiCam(TunerCiCamRequest request, int[] ciCamHandle) {
        boolean result = false;
        try {
            result = mService.requestCiCam(request, ciCamHandle);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        return result;
    }

    /**
     * Requests a Tuner Lnb resource.
     *
@@ -481,6 +515,25 @@ public class TunerResourceManager {
        }
    }

    /**
     * Notifies the TRM that the given CiCam has been released.
     *
     * <p>Client must call this whenever it releases a CiCam.
     *
     * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
     * release.
     *
     * @param ciCamHandle the handle of the releasing CiCam.
     * @param clientId the id of the client that is releasing the CiCam.
     */
    public void releaseCiCam(int ciCamHandle, int clientId) {
        try {
            mService.releaseCiCam(ciCamHandle, clientId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Notifies the TRM that the Lnb with the given id has been released.
     *
+39 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.media.tv.tunerresourcemanager;
import android.media.tv.tunerresourcemanager.CasSessionRequest;
import android.media.tv.tunerresourcemanager.IResourcesReclaimListener;
import android.media.tv.tunerresourcemanager.ResourceClientProfile;
import android.media.tv.tunerresourcemanager.TunerCiCamRequest;
import android.media.tv.tunerresourcemanager.TunerDemuxRequest;
import android.media.tv.tunerresourcemanager.TunerDescramblerRequest;
import android.media.tv.tunerresourcemanager.TunerFrontendInfo;
@@ -224,6 +225,31 @@ interface ITunerResourceManager {
     */
    boolean requestCasSession(in CasSessionRequest request, out int[] casSessionHandle);

    /*
     * This API is used by the Tuner framework to request an available CuCam.
     *
     * <p>There are three possible scenarios:
     * <ul>
     * <li>If there is CiCam available, the API would send the handle back.
     *
     * <li>If no CiCma is available but the current request info can show higher priority than
     * other uses of the ciCam, the API will send
     * {@link ITunerResourceManagerCallback#onReclaimResources()} to the {@link Tuner}. Tuner would
     * handle the resource reclaim on the holder of lower priority and notify the holder of its
     * resource loss.
     *
     * <li>If no CiCam can be granted, the API would return false.
     * <ul>
     *
     * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this request.
     *
     * @param request {@link TunerCiCamRequest} information of the current request.
     * @param ciCamHandle a one-element array to return the granted ciCam handle.
     *
     * @return true if there is CiCam granted.
     */
    boolean requestCiCam(in TunerCiCamRequest request, out int[] ciCamHandle);

    /*
     * This API is used by the Tuner framework to request an available Lnb from the TunerHAL.
     *
@@ -293,6 +319,19 @@ interface ITunerResourceManager {
     */
    void releaseCasSession(in int casSessionHandle, int clientId);

    /**
     * Notifies the TRM that the given CiCam has been released.
     *
     * <p>Client must call this whenever it releases a CiCam.
     *
     * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
     * release.
     *
     * @param ciCamHandle the handle of the releasing CiCam.
     * @param clientId the id of the client that is releasing the CiCam.
     */
    void releaseCiCam(in int ciCamHandle, int clientId);

    /*
     * Notifies the TRM that the Lnb with the given handle was released.
     *
+28 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media.tv.tunerresourcemanager;

/**
 * A wrapper of a ciCam requests that contains all the request info of the client.
 *
 * @hide
 */
parcelable TunerCiCamRequest {
    int clientId;

    int ciCamId;
}
 No newline at end of file
Loading