summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2020-04-18 06:16:30 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-04-18 06:16:30 +0000
commitc1f78e8c20cbe97fbaf71ccb6325cf5a5bcc9d0e (patch)
treefb6a5aeb880ae64c1dcee053cc2dd6a8cdffc363
parent6b3c4ef8528a1616339551dc2a53e144fe81343e (diff)
parent40454dbdcb4747e34ef6d9a9e99cb6d16ba29db1 (diff)
Merge "Tuner JNI: descrambler" into rvc-dev
-rw-r--r--media/java/android/media/tv/tuner/Descrambler.java33
-rw-r--r--media/java/android/media/tv/tuner/Lnb.java49
-rw-r--r--media/java/android/media/tv/tuner/Tuner.java77
-rw-r--r--media/java/android/media/tv/tuner/TunerUtils.java11
-rw-r--r--media/java/android/media/tv/tuner/filter/Filter.java78
-rw-r--r--media/jni/android_media_tv_Tuner.cpp81
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 },
};