diff options
| author | 2020-04-18 06:16:30 +0000 | |
|---|---|---|
| committer | 2020-04-18 06:16:30 +0000 | |
| commit | c1f78e8c20cbe97fbaf71ccb6325cf5a5bcc9d0e (patch) | |
| tree | fb6a5aeb880ae64c1dcee053cc2dd6a8cdffc363 | |
| parent | 6b3c4ef8528a1616339551dc2a53e144fe81343e (diff) | |
| parent | 40454dbdcb4747e34ef6d9a9e99cb6d16ba29db1 (diff) | |
Merge "Tuner JNI: descrambler" into rvc-dev
| -rw-r--r-- | media/java/android/media/tv/tuner/Descrambler.java | 33 | ||||
| -rw-r--r-- | media/java/android/media/tv/tuner/Lnb.java | 49 | ||||
| -rw-r--r-- | media/java/android/media/tv/tuner/Tuner.java | 77 | ||||
| -rw-r--r-- | media/java/android/media/tv/tuner/TunerUtils.java | 11 | ||||
| -rw-r--r-- | media/java/android/media/tv/tuner/filter/Filter.java | 78 | ||||
| -rw-r--r-- | media/jni/android_media_tv_Tuner.cpp | 81 |
6 files changed, 239 insertions, 90 deletions
diff --git a/media/java/android/media/tv/tuner/Descrambler.java b/media/java/android/media/tv/tuner/Descrambler.java index 975604c1c2c7..7b58bfc30b24 100644 --- a/media/java/android/media/tv/tuner/Descrambler.java +++ b/media/java/android/media/tv/tuner/Descrambler.java @@ -52,8 +52,12 @@ public class Descrambler implements AutoCloseable { */ public static final int PID_TYPE_MMTP = 2; + private static final String TAG = "Descrambler"; + private long mNativeContext; + private boolean mIsClosed = false; + private final Object mLock = new Object(); private native int nativeAddPid(int pidType, int pid, Filter filter); private native int nativeRemovePid(int pidType, int pid, Filter filter); @@ -80,7 +84,10 @@ public class Descrambler implements AutoCloseable { */ @Result public int addPid(@PidType int pidType, int pid, @Nullable Filter filter) { - return nativeAddPid(pidType, pid, filter); + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + return nativeAddPid(pidType, pid, filter); + } } /** @@ -95,7 +102,10 @@ public class Descrambler implements AutoCloseable { */ @Result public int removePid(@PidType int pidType, int pid, @Nullable Filter filter) { - return nativeRemovePid(pidType, pid, filter); + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + return nativeRemovePid(pidType, pid, filter); + } } /** @@ -109,8 +119,11 @@ public class Descrambler implements AutoCloseable { */ @Result public int setKeyToken(@NonNull byte[] keyToken) { - Objects.requireNonNull(keyToken, "key token must not be null"); - return nativeSetKeyToken(keyToken); + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + Objects.requireNonNull(keyToken, "key token must not be null"); + return nativeSetKeyToken(keyToken); + } } /** @@ -118,7 +131,17 @@ public class Descrambler implements AutoCloseable { */ @Override public void close() { - nativeClose(); + synchronized (mLock) { + if (mIsClosed) { + return; + } + int res = nativeClose(); + if (res != Tuner.RESULT_SUCCESS) { + TunerUtils.throwExceptionForResult(res, "Failed to close descrambler"); + } else { + mIsClosed = true; + } + } } } diff --git a/media/java/android/media/tv/tuner/Lnb.java b/media/java/android/media/tv/tuner/Lnb.java index 9913d23b3301..5e9579430e11 100644 --- a/media/java/android/media/tv/tuner/Lnb.java +++ b/media/java/android/media/tv/tuner/Lnb.java @@ -143,9 +143,12 @@ public class Lnb implements AutoCloseable { */ public static final int EVENT_TYPE_LNB_OVERLOAD = Constants.LnbEventType.LNB_OVERLOAD; + private static final String TAG = "Lnb"; + int mId; LnbCallback mCallback; Executor mExecutor; + Tuner mTuner; private native int nativeSetVoltage(int voltage); @@ -156,13 +159,17 @@ public class Lnb implements AutoCloseable { private long mNativeContext; + private Boolean mIsClosed = false; + private final Object mLock = new Object(); + private Lnb(int id) { mId = id; } - void setCallback(Executor executor, @Nullable LnbCallback callback) { + void setCallback(Executor executor, @Nullable LnbCallback callback, Tuner tuner) { mCallback = callback; mExecutor = executor; + mTuner = tuner; } private void onEvent(int eventType) { @@ -177,6 +184,12 @@ public class Lnb implements AutoCloseable { } } + /* package */ boolean isClosed() { + synchronized (mLock) { + return mIsClosed; + } + } + /** * Sets the LNB's power voltage. * @@ -185,7 +198,10 @@ public class Lnb implements AutoCloseable { */ @Result public int setVoltage(@Voltage int voltage) { - return nativeSetVoltage(voltage); + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + return nativeSetVoltage(voltage); + } } /** @@ -196,7 +212,10 @@ public class Lnb implements AutoCloseable { */ @Result public int setTone(@Tone int tone) { - return nativeSetTone(tone); + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + return nativeSetTone(tone); + } } /** @@ -207,7 +226,10 @@ public class Lnb implements AutoCloseable { */ @Result public int setSatellitePosition(@Position int position) { - return nativeSetSatellitePosition(position); + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + return nativeSetSatellitePosition(position); + } } /** @@ -222,16 +244,27 @@ public class Lnb implements AutoCloseable { */ @Result public int sendDiseqcMessage(@NonNull byte[] message) { - return nativeSendDiseqcMessage(message); + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + return nativeSendDiseqcMessage(message); + } } /** * Releases the LNB instance. */ public void close() { - int res = nativeClose(); - if (res != Tuner.RESULT_SUCCESS) { - TunerUtils.throwExceptionForResult(res, "Failed to close LNB"); + synchronized (mLock) { + if (mIsClosed) { + return; + } + int res = nativeClose(); + if (res != Tuner.RESULT_SUCCESS) { + TunerUtils.throwExceptionForResult(res, "Failed to close LNB"); + } else { + mIsClosed = true; + mTuner.releaseLnb(); + } } } } diff --git a/media/java/android/media/tv/tuner/Tuner.java b/media/java/android/media/tv/tuner/Tuner.java index ee5ac467502a..d331126e4194 100644 --- a/media/java/android/media/tv/tuner/Tuner.java +++ b/media/java/android/media/tv/tuner/Tuner.java @@ -57,7 +57,10 @@ import android.util.Log; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.concurrent.Executor; @@ -222,8 +225,8 @@ public class Tuner implements AutoCloseable { private Executor mOnResourceLostListenerExecutor; private Integer mDemuxHandle; - private Integer mDescramblerHandle; - private Descrambler mDescrambler; + private Map<Integer, Descrambler> mDescramblers = new HashMap<>(); + private List<Filter> mFilters = new ArrayList<>(); private final TunerResourceManager.ResourcesReclaimListener mResourceListener = new TunerResourceManager.ResourcesReclaimListener() { @@ -356,9 +359,20 @@ public class Tuner implements AutoCloseable { mFrontend = null; } if (mLnb != null) { - mTunerResourceManager.releaseLnb(mLnbHandle, mClientId); - mLnb = null; - mLnbHandle = null; + releaseLnb(); + } + if (!mDescramblers.isEmpty()) { + for (Map.Entry<Integer, Descrambler> d : mDescramblers.entrySet()) { + d.getValue().close(); + mTunerResourceManager.releaseDescrambler(d.getKey(), mClientId); + } + mDescramblers.clear(); + } + if (!mFilters.isEmpty()) { + for (Filter f : mFilters) { + f.close(); + } + mFilters.clear(); } TunerUtils.throwExceptionForResult(nativeClose(), "failed to close tuner"); } @@ -857,6 +871,7 @@ public class Tuner implements AutoCloseable { if (mHandler == null) { mHandler = createEventHandler(); } + mFilters.add(filter); } return filter; } @@ -875,9 +890,11 @@ public class Tuner implements AutoCloseable { public Lnb openLnb(@CallbackExecutor @NonNull Executor executor, @NonNull LnbCallback cb) { Objects.requireNonNull(executor, "executor must not be null"); Objects.requireNonNull(cb, "LnbCallback must not be null"); - checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_LNB); if (mLnb != null) { - mLnb.setCallback(executor, cb); + return mLnb; + } + if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_LNB) && mLnb != null) { + mLnb.setCallback(executor, cb, this); } return mLnb; } @@ -897,9 +914,14 @@ public class Tuner implements AutoCloseable { Objects.requireNonNull(name, "LNB name must not be null"); Objects.requireNonNull(executor, "executor must not be null"); Objects.requireNonNull(cb, "LnbCallback must not be null"); - mLnb = nativeOpenLnbByName(name); - if (mLnb != null) { - mLnb.setCallback(executor, cb); + Lnb newLnb = nativeOpenLnbByName(name); + if (newLnb != null) { + if (mLnb != null) { + mLnb.close(); + mLnbHandle = null; + } + mLnb = newLnb; + mLnb.setCallback(executor, cb, this); } return mLnb; } @@ -934,8 +956,7 @@ public class Tuner implements AutoCloseable { @RequiresPermission(android.Manifest.permission.ACCESS_TV_DESCRAMBLER) @Nullable public Descrambler openDescrambler() { - checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DESCRAMBLER); - return mDescrambler; + return requestDescrambler(); } /** @@ -995,15 +1016,21 @@ public class Tuner implements AutoCloseable { return granted; } - private boolean requestDescrambler() { + private Descrambler requestDescrambler() { int[] descramblerHandle = new int[1]; TunerDescramblerRequest request = new TunerDescramblerRequest(mClientId); boolean granted = mTunerResourceManager.requestDescrambler(request, descramblerHandle); - if (granted) { - mDescramblerHandle = descramblerHandle[0]; - mDescrambler = nativeOpenDescramblerByHandle(mDescramblerHandle); + if (!granted) { + return null; } - return granted; + int handle = descramblerHandle[0]; + Descrambler descrambler = nativeOpenDescramblerByHandle(handle); + if (descrambler != null) { + mDescramblers.put(handle, descrambler); + } else { + mTunerResourceManager.releaseDescrambler(handle, mClientId); + } + return descrambler; } private boolean checkResource(int resourceType) { @@ -1015,7 +1042,7 @@ public class Tuner implements AutoCloseable { break; } case TunerResourceManager.TUNER_RESOURCE_TYPE_LNB: { - if (mLnbHandle == null && !requestLnb()) { + if (mLnb == null && !requestLnb()) { return false; } break; @@ -1026,13 +1053,15 @@ public class Tuner implements AutoCloseable { } break; } - case TunerResourceManager.TUNER_RESOURCE_TYPE_DESCRAMBLER: { - if (mDescramblerHandle == null && !requestDescrambler()) { - return false; - } - break; - } + default: + return false; } return true; } + + /* package */ void releaseLnb() { + mTunerResourceManager.releaseLnb(mLnbHandle, mClientId); + mLnbHandle = null; + mLnb = null; + } } diff --git a/media/java/android/media/tv/tuner/TunerUtils.java b/media/java/android/media/tv/tuner/TunerUtils.java index c1589cf3fb1d..a13077c77ced 100644 --- a/media/java/android/media/tv/tuner/TunerUtils.java +++ b/media/java/android/media/tv/tuner/TunerUtils.java @@ -157,5 +157,16 @@ public final class TunerUtils { throw new RuntimeException("Unexpected result " + r + ". " + msg); } + /** + * Checks the state of a resource instance. + * + * @throws IllegalStateException if the resource has already been closed. + */ + public static void checkResourceState(String name, boolean closed) { + if (closed) { + throw new IllegalStateException(name + " has been closed"); + } + } + private TunerUtils() {} } diff --git a/media/java/android/media/tv/tuner/filter/Filter.java b/media/java/android/media/tv/tuner/filter/Filter.java index d654b45da092..cc932da4a9f6 100644 --- a/media/java/android/media/tv/tuner/filter/Filter.java +++ b/media/java/android/media/tv/tuner/filter/Filter.java @@ -180,6 +180,8 @@ public class Filter implements AutoCloseable { */ public static final int STATUS_OVERFLOW = Constants.DemuxFilterStatus.OVERFLOW; + private static final String TAG = "Filter"; + private long mNativeContext; private FilterCallback mCallback; private Executor mExecutor; @@ -188,6 +190,8 @@ public class Filter implements AutoCloseable { private int mSubtype; private Filter mSource; private boolean mStarted; + private boolean mIsClosed = false; + private final Object mLock = new Object(); private native int nativeConfigureFilter( int type, int subType, FilterConfiguration settings); @@ -244,21 +248,27 @@ public class Filter implements AutoCloseable { */ @Result public int configure(@NonNull FilterConfiguration config) { - Settings s = config.getSettings(); - int subType = (s == null) ? mSubtype : s.getType(); - if (mMainType != config.getType() || mSubtype != subType) { - throw new IllegalArgumentException("Invalid filter config. filter main type=" - + mMainType + ", filter subtype=" + mSubtype + ". config main type=" - + config.getType() + ", config subtype=" + subType); + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + Settings s = config.getSettings(); + int subType = (s == null) ? mSubtype : s.getType(); + if (mMainType != config.getType() || mSubtype != subType) { + throw new IllegalArgumentException("Invalid filter config. filter main type=" + + mMainType + ", filter subtype=" + mSubtype + ". config main type=" + + config.getType() + ", config subtype=" + subType); + } + return nativeConfigureFilter(config.getType(), subType, config); } - return nativeConfigureFilter(config.getType(), subType, config); } /** * Gets the filter Id. */ public int getId() { - return nativeGetId(); + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + return nativeGetId(); + } } /** @@ -276,14 +286,17 @@ public class Filter implements AutoCloseable { */ @Result public int setDataSource(@Nullable Filter source) { - if (mSource != null) { - throw new IllegalStateException("Data source is existing"); + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + if (mSource != null) { + throw new IllegalStateException("Data source is existing"); + } + int res = nativeSetDataSource(source); + if (res == Tuner.RESULT_SUCCESS) { + mSource = source; + } + return res; } - int res = nativeSetDataSource(source); - if (res == Tuner.RESULT_SUCCESS) { - mSource = source; - } - return res; } /** @@ -295,7 +308,10 @@ public class Filter implements AutoCloseable { */ @Result public int start() { - return nativeStartFilter(); + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + return nativeStartFilter(); + } } @@ -308,7 +324,10 @@ public class Filter implements AutoCloseable { */ @Result public int stop() { - return nativeStopFilter(); + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + return nativeStopFilter(); + } } /** @@ -321,7 +340,10 @@ public class Filter implements AutoCloseable { */ @Result public int flush() { - return nativeFlushFilter(); + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + return nativeFlushFilter(); + } } /** @@ -333,8 +355,11 @@ public class Filter implements AutoCloseable { * @return the number of bytes read. */ public int read(@NonNull byte[] buffer, @BytesLong long offset, @BytesLong long size) { - size = Math.min(size, buffer.length - offset); - return nativeRead(buffer, offset, size); + synchronized (mLock) { + TunerUtils.checkResourceState(TAG, mIsClosed); + size = Math.min(size, buffer.length - offset); + return nativeRead(buffer, offset, size); + } } /** @@ -342,9 +367,16 @@ public class Filter implements AutoCloseable { */ @Override public void close() { - int res = nativeClose(); - if (res != Tuner.RESULT_SUCCESS) { - TunerUtils.throwExceptionForResult(res, "Failed to close filter."); + synchronized (mLock) { + if (mIsClosed) { + return; + } + int res = nativeClose(); + if (res != Tuner.RESULT_SUCCESS) { + TunerUtils.throwExceptionForResult(res, "Failed to close filter."); + } else { + mIsClosed = true; + } } } } diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp index 909394fbc495..614fe73a76de 100644 --- a/media/jni/android_media_tv_Tuner.cpp +++ b/media/jni/android_media_tv_Tuner.cpp @@ -1368,24 +1368,27 @@ int JTuner::disconnectCiCam() { jobject JTuner::openDescrambler() { ALOGD("JTuner::openDescrambler"); - if (mTuner == nullptr) { + if (mTuner == nullptr || mDemux == nullptr) { return NULL; } sp<IDescrambler> descramblerSp; - mTuner->openDescrambler([&](Result, const sp<IDescrambler>& descrambler) { + Result res; + mTuner->openDescrambler([&](Result r, const sp<IDescrambler>& descrambler) { + res = r; descramblerSp = descrambler; }); - if (descramblerSp == NULL) { + if (res != Result::SUCCESS || descramblerSp == NULL) { return NULL; } + descramblerSp->setDemuxSource(mDemuxId); + JNIEnv *env = AndroidRuntime::getJNIEnv(); jobject descramblerObj = env->NewObject( env->FindClass("android/media/tv/tuner/Descrambler"), - gFields.descramblerInitID, - mObject); + gFields.descramblerInitID); descramblerSp->incStrong(descramblerObj); env->SetLongField(descramblerObj, gFields.descramblerContext, (jlong)descramblerSp.get()); @@ -1402,11 +1405,13 @@ jobject JTuner::openFilter(DemuxFilterType type, int bufferSize) { sp<IFilter> iFilterSp; sp<FilterCallback> callback = new FilterCallback(); + Result res; mDemux->openFilter(type, bufferSize, callback, - [&](Result, const sp<IFilter>& filter) { + [&](Result r, const sp<IFilter>& filter) { iFilterSp = filter; + res = r; }); - if (iFilterSp == NULL) { + if (res != Result::SUCCESS || iFilterSp == NULL) { ALOGD("Failed to open filter, type = %d", type.mainType); return NULL; } @@ -2355,8 +2360,7 @@ static void android_media_tv_Tuner_native_init(JNIEnv *env) { jclass descramblerClazz = env->FindClass("android/media/tv/tuner/Descrambler"); gFields.descramblerContext = env->GetFieldID(descramblerClazz, "mNativeContext", "J"); - gFields.descramblerInitID = - env->GetMethodID(descramblerClazz, "<init>", "()V"); + gFields.descramblerInitID = env->GetMethodID(descramblerClazz, "<init>", "()V"); jclass dvrRecorderClazz = env->FindClass("android/media/tv/tuner/dvr/DvrRecorder"); gFields.dvrRecorderContext = env->GetFieldID(dvrRecorderClazz, "mNativeContext", "J"); @@ -2905,7 +2909,7 @@ static jint android_media_tv_Tuner_configure_filter( sp<IFilter> iFilterSp = filterSp->getIFilter(); if (iFilterSp == NULL) { ALOGD("Failed to configure filter: filter not found"); - return (int)Result::INVALID_STATE; + return (jint) Result::NOT_INITIALIZED; } DemuxFilterSettings filterSettings = getFilterConfiguration(env, type, subtype, settings); Result res = iFilterSp->configure(filterSettings); @@ -2936,7 +2940,7 @@ static jint android_media_tv_Tuner_get_filter_id(JNIEnv* env, jobject filter) { sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter(); if (iFilterSp == NULL) { ALOGD("Failed to get filter ID: filter not found"); - return (int) Result::INVALID_STATE; + return (int) Result::NOT_INITIALIZED; } Result res; uint32_t id; @@ -2956,7 +2960,7 @@ static jint android_media_tv_Tuner_set_filter_data_source( sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter(); if (iFilterSp == NULL) { ALOGD("Failed to set filter data source: filter not found"); - return (jint) Result::INVALID_STATE; + return (jint) Result::NOT_INITIALIZED; } Result r; if (srcFilter == NULL) { @@ -2965,7 +2969,7 @@ static jint android_media_tv_Tuner_set_filter_data_source( sp<IFilter> srcSp = getFilter(env, srcFilter)->getIFilter(); if (iFilterSp == NULL) { ALOGD("Failed to set filter data source: src filter not found"); - return (jint) Result::INVALID_STATE; + return (jint) Result::INVALID_ARGUMENT; } r = iFilterSp->setDataSource(srcSp); } @@ -2976,7 +2980,7 @@ static jint android_media_tv_Tuner_start_filter(JNIEnv *env, jobject filter) { sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter(); if (iFilterSp == NULL) { ALOGD("Failed to start filter: filter not found"); - return (jint) Result::INVALID_STATE; + return (jint) Result::NOT_INITIALIZED; } Result r = iFilterSp->start(); return (jint) r; @@ -2986,7 +2990,7 @@ static jint android_media_tv_Tuner_stop_filter(JNIEnv *env, jobject filter) { sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter(); if (iFilterSp == NULL) { ALOGD("Failed to stop filter: filter not found"); - return (jint) Result::INVALID_STATE; + return (jint) Result::NOT_INITIALIZED; } Result r = iFilterSp->stop(); return (jint) r; @@ -2996,7 +3000,7 @@ static jint android_media_tv_Tuner_flush_filter(JNIEnv *env, jobject filter) { sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter(); if (iFilterSp == NULL) { ALOGD("Failed to flush filter: filter not found"); - return (jint) Result::INVALID_STATE; + return (jint) Result::NOT_INITIALIZED; } Result r = iFilterSp->flush(); return (jint) r; @@ -3016,7 +3020,7 @@ static jint android_media_tv_Tuner_close_filter(JNIEnv *env, jobject filter) { sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter(); if (iFilterSp == NULL) { ALOGD("Failed to close filter: filter not found"); - return (jint) Result::INVALID_STATE; + return (jint) Result::NOT_INITIALIZED; } Result r = iFilterSp->close(); return (jint) r; @@ -3121,34 +3125,51 @@ static jobject android_media_tv_Tuner_open_descrambler(JNIEnv *env, jobject thiz return tuner->openDescrambler(); } -static int android_media_tv_Tuner_add_pid( +static jint android_media_tv_Tuner_descrambler_add_pid( JNIEnv *env, jobject descrambler, jint pidType, jint pid, jobject filter) { sp<IDescrambler> descramblerSp = getDescrambler(env, descrambler); if (descramblerSp == NULL) { - return false; + return (jint) Result::NOT_INITIALIZED; } sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter(); Result result = descramblerSp->addPid(getDemuxPid((int)pidType, (int)pid), iFilterSp); - return (int)result; + return (jint) result; } -static int android_media_tv_Tuner_remove_pid( +static jint android_media_tv_Tuner_descrambler_remove_pid( JNIEnv *env, jobject descrambler, jint pidType, jint pid, jobject filter) { sp<IDescrambler> descramblerSp = getDescrambler(env, descrambler); if (descramblerSp == NULL) { - return false; + return (jint) Result::NOT_INITIALIZED; } sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter(); Result result = descramblerSp->removePid(getDemuxPid((int)pidType, (int)pid), iFilterSp); - return (int)result; + return (jint) result; } -static int android_media_tv_Tuner_set_key_token(JNIEnv, jobject, jbyteArray) { - return 0; +static jint android_media_tv_Tuner_descrambler_set_key_token( + JNIEnv* env, jobject descrambler, jbyteArray keyToken) { + sp<IDescrambler> descramblerSp = getDescrambler(env, descrambler); + if (descramblerSp == NULL) { + return (jint) Result::NOT_INITIALIZED; + } + int size = env->GetArrayLength(keyToken); + std::vector<uint8_t> v(size); + env->GetByteArrayRegion(keyToken, 0, size, reinterpret_cast<jbyte*>(&v[0])); + Result result = descramblerSp->setKeyToken(v); + return (jint) result; } -static int android_media_tv_Tuner_close_descrambler(JNIEnv, jobject) { - return 0; +static jint android_media_tv_Tuner_close_descrambler(JNIEnv* env, jobject descrambler) { + sp<IDescrambler> descramblerSp = getDescrambler(env, descrambler); + if (descramblerSp == NULL) { + return (jint) Result::NOT_INITIALIZED; + } + Result r = descramblerSp->close(); + if (r == Result::SUCCESS) { + descramblerSp->decStrong(descrambler); + } + return (jint) r; } static jobject android_media_tv_Tuner_open_dvr_recorder( @@ -3533,10 +3554,10 @@ static const JNINativeMethod gTimeFilterMethods[] = { static const JNINativeMethod gDescramblerMethods[] = { { "nativeAddPid", "(IILandroid/media/tv/tuner/filter/Filter;)I", - (void *)android_media_tv_Tuner_add_pid }, + (void *)android_media_tv_Tuner_descrambler_add_pid }, { "nativeRemovePid", "(IILandroid/media/tv/tuner/filter/Filter;)I", - (void *)android_media_tv_Tuner_remove_pid }, - { "nativeSetKeyToken", "([B)I", (void *)android_media_tv_Tuner_set_key_token }, + (void *)android_media_tv_Tuner_descrambler_remove_pid }, + { "nativeSetKeyToken", "([B)I", (void *)android_media_tv_Tuner_descrambler_set_key_token }, { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_descrambler }, }; |