Merge "Tuner JNI: descrambler" into rvc-dev am: c1f78e8c20 am: 3937cf81cc

Change-Id: If8568eb1cecb49a976ca86215f7cc5b239ce4eed
This commit is contained in:
TreeHugger Robot
2020-04-20 00:07:50 +00:00
committed by Automerger Merge Worker
6 changed files with 239 additions and 90 deletions

View File

@@ -52,8 +52,12 @@ public class Descrambler implements AutoCloseable {
*/ */
public static final int PID_TYPE_MMTP = 2; public static final int PID_TYPE_MMTP = 2;
private static final String TAG = "Descrambler";
private long mNativeContext; 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 nativeAddPid(int pidType, int pid, Filter filter);
private native int nativeRemovePid(int pidType, int pid, Filter filter); private native int nativeRemovePid(int pidType, int pid, Filter filter);
@@ -80,8 +84,11 @@ public class Descrambler implements AutoCloseable {
*/ */
@Result @Result
public int addPid(@PidType int pidType, int pid, @Nullable Filter filter) { public int addPid(@PidType int pidType, int pid, @Nullable Filter filter) {
synchronized (mLock) {
TunerUtils.checkResourceState(TAG, mIsClosed);
return nativeAddPid(pidType, pid, filter); return nativeAddPid(pidType, pid, filter);
} }
}
/** /**
* Remove packets' PID from the descrambler * Remove packets' PID from the descrambler
@@ -95,8 +102,11 @@ public class Descrambler implements AutoCloseable {
*/ */
@Result @Result
public int removePid(@PidType int pidType, int pid, @Nullable Filter filter) { public int removePid(@PidType int pidType, int pid, @Nullable Filter filter) {
synchronized (mLock) {
TunerUtils.checkResourceState(TAG, mIsClosed);
return nativeRemovePid(pidType, pid, filter); return nativeRemovePid(pidType, pid, filter);
} }
}
/** /**
* Set a key token to link descrambler to a key slot * Set a key token to link descrambler to a key slot
@@ -109,16 +119,29 @@ public class Descrambler implements AutoCloseable {
*/ */
@Result @Result
public int setKeyToken(@NonNull byte[] keyToken) { public int setKeyToken(@NonNull byte[] keyToken) {
synchronized (mLock) {
TunerUtils.checkResourceState(TAG, mIsClosed);
Objects.requireNonNull(keyToken, "key token must not be null"); Objects.requireNonNull(keyToken, "key token must not be null");
return nativeSetKeyToken(keyToken); return nativeSetKeyToken(keyToken);
} }
}
/** /**
* Release the descrambler instance. * Release the descrambler instance.
*/ */
@Override @Override
public void close() { 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;
}
}
} }
} }

View File

@@ -143,9 +143,12 @@ public class Lnb implements AutoCloseable {
*/ */
public static final int EVENT_TYPE_LNB_OVERLOAD = Constants.LnbEventType.LNB_OVERLOAD; public static final int EVENT_TYPE_LNB_OVERLOAD = Constants.LnbEventType.LNB_OVERLOAD;
private static final String TAG = "Lnb";
int mId; int mId;
LnbCallback mCallback; LnbCallback mCallback;
Executor mExecutor; Executor mExecutor;
Tuner mTuner;
private native int nativeSetVoltage(int voltage); private native int nativeSetVoltage(int voltage);
@@ -156,13 +159,17 @@ public class Lnb implements AutoCloseable {
private long mNativeContext; private long mNativeContext;
private Boolean mIsClosed = false;
private final Object mLock = new Object();
private Lnb(int id) { private Lnb(int id) {
mId = id; mId = id;
} }
void setCallback(Executor executor, @Nullable LnbCallback callback) { void setCallback(Executor executor, @Nullable LnbCallback callback, Tuner tuner) {
mCallback = callback; mCallback = callback;
mExecutor = executor; mExecutor = executor;
mTuner = tuner;
} }
private void onEvent(int eventType) { 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. * Sets the LNB's power voltage.
* *
@@ -185,8 +198,11 @@ public class Lnb implements AutoCloseable {
*/ */
@Result @Result
public int setVoltage(@Voltage int voltage) { public int setVoltage(@Voltage int voltage) {
synchronized (mLock) {
TunerUtils.checkResourceState(TAG, mIsClosed);
return nativeSetVoltage(voltage); return nativeSetVoltage(voltage);
} }
}
/** /**
* Sets the LNB's tone mode. * Sets the LNB's tone mode.
@@ -196,8 +212,11 @@ public class Lnb implements AutoCloseable {
*/ */
@Result @Result
public int setTone(@Tone int tone) { public int setTone(@Tone int tone) {
synchronized (mLock) {
TunerUtils.checkResourceState(TAG, mIsClosed);
return nativeSetTone(tone); return nativeSetTone(tone);
} }
}
/** /**
* Selects the LNB's position. * Selects the LNB's position.
@@ -207,8 +226,11 @@ public class Lnb implements AutoCloseable {
*/ */
@Result @Result
public int setSatellitePosition(@Position int position) { public int setSatellitePosition(@Position int position) {
synchronized (mLock) {
TunerUtils.checkResourceState(TAG, mIsClosed);
return nativeSetSatellitePosition(position); return nativeSetSatellitePosition(position);
} }
}
/** /**
* Sends DiSEqC (Digital Satellite Equipment Control) message. * Sends DiSEqC (Digital Satellite Equipment Control) message.
@@ -222,16 +244,27 @@ public class Lnb implements AutoCloseable {
*/ */
@Result @Result
public int sendDiseqcMessage(@NonNull byte[] message) { public int sendDiseqcMessage(@NonNull byte[] message) {
synchronized (mLock) {
TunerUtils.checkResourceState(TAG, mIsClosed);
return nativeSendDiseqcMessage(message); return nativeSendDiseqcMessage(message);
} }
}
/** /**
* Releases the LNB instance. * Releases the LNB instance.
*/ */
public void close() { public void close() {
synchronized (mLock) {
if (mIsClosed) {
return;
}
int res = nativeClose(); int res = nativeClose();
if (res != Tuner.RESULT_SUCCESS) { if (res != Tuner.RESULT_SUCCESS) {
TunerUtils.throwExceptionForResult(res, "Failed to close LNB"); TunerUtils.throwExceptionForResult(res, "Failed to close LNB");
} else {
mIsClosed = true;
mTuner.releaseLnb();
}
} }
} }
} }

View File

@@ -57,7 +57,10 @@ import android.util.Log;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@@ -222,8 +225,8 @@ public class Tuner implements AutoCloseable {
private Executor mOnResourceLostListenerExecutor; private Executor mOnResourceLostListenerExecutor;
private Integer mDemuxHandle; private Integer mDemuxHandle;
private Integer mDescramblerHandle; private Map<Integer, Descrambler> mDescramblers = new HashMap<>();
private Descrambler mDescrambler; private List<Filter> mFilters = new ArrayList<>();
private final TunerResourceManager.ResourcesReclaimListener mResourceListener = private final TunerResourceManager.ResourcesReclaimListener mResourceListener =
new TunerResourceManager.ResourcesReclaimListener() { new TunerResourceManager.ResourcesReclaimListener() {
@@ -356,9 +359,20 @@ public class Tuner implements AutoCloseable {
mFrontend = null; mFrontend = null;
} }
if (mLnb != null) { if (mLnb != null) {
mTunerResourceManager.releaseLnb(mLnbHandle, mClientId); releaseLnb();
mLnb = null; }
mLnbHandle = null; 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"); TunerUtils.throwExceptionForResult(nativeClose(), "failed to close tuner");
} }
@@ -857,6 +871,7 @@ public class Tuner implements AutoCloseable {
if (mHandler == null) { if (mHandler == null) {
mHandler = createEventHandler(); mHandler = createEventHandler();
} }
mFilters.add(filter);
} }
return filter; return filter;
} }
@@ -875,9 +890,11 @@ public class Tuner implements AutoCloseable {
public Lnb openLnb(@CallbackExecutor @NonNull Executor executor, @NonNull LnbCallback cb) { public Lnb openLnb(@CallbackExecutor @NonNull Executor executor, @NonNull LnbCallback cb) {
Objects.requireNonNull(executor, "executor must not be null"); Objects.requireNonNull(executor, "executor must not be null");
Objects.requireNonNull(cb, "LnbCallback must not be null"); Objects.requireNonNull(cb, "LnbCallback must not be null");
checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_LNB);
if (mLnb != null) { 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; return mLnb;
} }
@@ -897,9 +914,14 @@ public class Tuner implements AutoCloseable {
Objects.requireNonNull(name, "LNB name must not be null"); Objects.requireNonNull(name, "LNB name must not be null");
Objects.requireNonNull(executor, "executor must not be null"); Objects.requireNonNull(executor, "executor must not be null");
Objects.requireNonNull(cb, "LnbCallback must not be null"); Objects.requireNonNull(cb, "LnbCallback must not be null");
mLnb = nativeOpenLnbByName(name); Lnb newLnb = nativeOpenLnbByName(name);
if (newLnb != null) {
if (mLnb != null) { if (mLnb != null) {
mLnb.setCallback(executor, cb); mLnb.close();
mLnbHandle = null;
}
mLnb = newLnb;
mLnb.setCallback(executor, cb, this);
} }
return mLnb; return mLnb;
} }
@@ -934,8 +956,7 @@ public class Tuner implements AutoCloseable {
@RequiresPermission(android.Manifest.permission.ACCESS_TV_DESCRAMBLER) @RequiresPermission(android.Manifest.permission.ACCESS_TV_DESCRAMBLER)
@Nullable @Nullable
public Descrambler openDescrambler() { public Descrambler openDescrambler() {
checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DESCRAMBLER); return requestDescrambler();
return mDescrambler;
} }
/** /**
@@ -995,15 +1016,21 @@ public class Tuner implements AutoCloseable {
return granted; return granted;
} }
private boolean requestDescrambler() { private Descrambler requestDescrambler() {
int[] descramblerHandle = new int[1]; int[] descramblerHandle = new int[1];
TunerDescramblerRequest request = new TunerDescramblerRequest(mClientId); TunerDescramblerRequest request = new TunerDescramblerRequest(mClientId);
boolean granted = mTunerResourceManager.requestDescrambler(request, descramblerHandle); boolean granted = mTunerResourceManager.requestDescrambler(request, descramblerHandle);
if (granted) { if (!granted) {
mDescramblerHandle = descramblerHandle[0]; return null;
mDescrambler = nativeOpenDescramblerByHandle(mDescramblerHandle);
} }
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) { private boolean checkResource(int resourceType) {
@@ -1015,7 +1042,7 @@ public class Tuner implements AutoCloseable {
break; break;
} }
case TunerResourceManager.TUNER_RESOURCE_TYPE_LNB: { case TunerResourceManager.TUNER_RESOURCE_TYPE_LNB: {
if (mLnbHandle == null && !requestLnb()) { if (mLnb == null && !requestLnb()) {
return false; return false;
} }
break; break;
@@ -1026,13 +1053,15 @@ public class Tuner implements AutoCloseable {
} }
break; break;
} }
case TunerResourceManager.TUNER_RESOURCE_TYPE_DESCRAMBLER: { default:
if (mDescramblerHandle == null && !requestDescrambler()) {
return false; return false;
} }
break;
}
}
return true; return true;
} }
/* package */ void releaseLnb() {
mTunerResourceManager.releaseLnb(mLnbHandle, mClientId);
mLnbHandle = null;
mLnb = null;
}
} }

View File

@@ -157,5 +157,16 @@ public final class TunerUtils {
throw new RuntimeException("Unexpected result " + r + ". " + msg); 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() {} private TunerUtils() {}
} }

View File

@@ -180,6 +180,8 @@ public class Filter implements AutoCloseable {
*/ */
public static final int STATUS_OVERFLOW = Constants.DemuxFilterStatus.OVERFLOW; public static final int STATUS_OVERFLOW = Constants.DemuxFilterStatus.OVERFLOW;
private static final String TAG = "Filter";
private long mNativeContext; private long mNativeContext;
private FilterCallback mCallback; private FilterCallback mCallback;
private Executor mExecutor; private Executor mExecutor;
@@ -188,6 +190,8 @@ public class Filter implements AutoCloseable {
private int mSubtype; private int mSubtype;
private Filter mSource; private Filter mSource;
private boolean mStarted; private boolean mStarted;
private boolean mIsClosed = false;
private final Object mLock = new Object();
private native int nativeConfigureFilter( private native int nativeConfigureFilter(
int type, int subType, FilterConfiguration settings); int type, int subType, FilterConfiguration settings);
@@ -244,6 +248,8 @@ public class Filter implements AutoCloseable {
*/ */
@Result @Result
public int configure(@NonNull FilterConfiguration config) { public int configure(@NonNull FilterConfiguration config) {
synchronized (mLock) {
TunerUtils.checkResourceState(TAG, mIsClosed);
Settings s = config.getSettings(); Settings s = config.getSettings();
int subType = (s == null) ? mSubtype : s.getType(); int subType = (s == null) ? mSubtype : s.getType();
if (mMainType != config.getType() || mSubtype != subType) { if (mMainType != config.getType() || mSubtype != subType) {
@@ -253,13 +259,17 @@ public class Filter implements AutoCloseable {
} }
return nativeConfigureFilter(config.getType(), subType, config); return nativeConfigureFilter(config.getType(), subType, config);
} }
}
/** /**
* Gets the filter Id. * Gets the filter Id.
*/ */
public int getId() { public int getId() {
synchronized (mLock) {
TunerUtils.checkResourceState(TAG, mIsClosed);
return nativeGetId(); return nativeGetId();
} }
}
/** /**
* Sets the filter's data source. * Sets the filter's data source.
@@ -276,6 +286,8 @@ public class Filter implements AutoCloseable {
*/ */
@Result @Result
public int setDataSource(@Nullable Filter source) { public int setDataSource(@Nullable Filter source) {
synchronized (mLock) {
TunerUtils.checkResourceState(TAG, mIsClosed);
if (mSource != null) { if (mSource != null) {
throw new IllegalStateException("Data source is existing"); throw new IllegalStateException("Data source is existing");
} }
@@ -285,6 +297,7 @@ public class Filter implements AutoCloseable {
} }
return res; return res;
} }
}
/** /**
* Starts filtering data. * Starts filtering data.
@@ -295,8 +308,11 @@ public class Filter implements AutoCloseable {
*/ */
@Result @Result
public int start() { public int start() {
synchronized (mLock) {
TunerUtils.checkResourceState(TAG, mIsClosed);
return nativeStartFilter(); return nativeStartFilter();
} }
}
/** /**
@@ -308,8 +324,11 @@ public class Filter implements AutoCloseable {
*/ */
@Result @Result
public int stop() { public int stop() {
synchronized (mLock) {
TunerUtils.checkResourceState(TAG, mIsClosed);
return nativeStopFilter(); return nativeStopFilter();
} }
}
/** /**
* Flushes the filter. * Flushes the filter.
@@ -321,8 +340,11 @@ public class Filter implements AutoCloseable {
*/ */
@Result @Result
public int flush() { public int flush() {
synchronized (mLock) {
TunerUtils.checkResourceState(TAG, mIsClosed);
return nativeFlushFilter(); return nativeFlushFilter();
} }
}
/** /**
* Copies filtered data from filter output to the given byte array. * Copies filtered data from filter output to the given byte array.
@@ -333,18 +355,28 @@ public class Filter implements AutoCloseable {
* @return the number of bytes read. * @return the number of bytes read.
*/ */
public int read(@NonNull byte[] buffer, @BytesLong long offset, @BytesLong long size) { public int read(@NonNull byte[] buffer, @BytesLong long offset, @BytesLong long size) {
synchronized (mLock) {
TunerUtils.checkResourceState(TAG, mIsClosed);
size = Math.min(size, buffer.length - offset); size = Math.min(size, buffer.length - offset);
return nativeRead(buffer, offset, size); return nativeRead(buffer, offset, size);
} }
}
/** /**
* Stops filtering data and releases the Filter instance. * Stops filtering data and releases the Filter instance.
*/ */
@Override @Override
public void close() { public void close() {
synchronized (mLock) {
if (mIsClosed) {
return;
}
int res = nativeClose(); int res = nativeClose();
if (res != Tuner.RESULT_SUCCESS) { if (res != Tuner.RESULT_SUCCESS) {
TunerUtils.throwExceptionForResult(res, "Failed to close filter."); TunerUtils.throwExceptionForResult(res, "Failed to close filter.");
} else {
mIsClosed = true;
}
} }
} }
} }

View File

@@ -1368,24 +1368,27 @@ int JTuner::disconnectCiCam() {
jobject JTuner::openDescrambler() { jobject JTuner::openDescrambler() {
ALOGD("JTuner::openDescrambler"); ALOGD("JTuner::openDescrambler");
if (mTuner == nullptr) { if (mTuner == nullptr || mDemux == nullptr) {
return NULL; return NULL;
} }
sp<IDescrambler> descramblerSp; sp<IDescrambler> descramblerSp;
mTuner->openDescrambler([&](Result, const sp<IDescrambler>& descrambler) { Result res;
mTuner->openDescrambler([&](Result r, const sp<IDescrambler>& descrambler) {
res = r;
descramblerSp = descrambler; descramblerSp = descrambler;
}); });
if (descramblerSp == NULL) { if (res != Result::SUCCESS || descramblerSp == NULL) {
return NULL; return NULL;
} }
descramblerSp->setDemuxSource(mDemuxId);
JNIEnv *env = AndroidRuntime::getJNIEnv(); JNIEnv *env = AndroidRuntime::getJNIEnv();
jobject descramblerObj = jobject descramblerObj =
env->NewObject( env->NewObject(
env->FindClass("android/media/tv/tuner/Descrambler"), env->FindClass("android/media/tv/tuner/Descrambler"),
gFields.descramblerInitID, gFields.descramblerInitID);
mObject);
descramblerSp->incStrong(descramblerObj); descramblerSp->incStrong(descramblerObj);
env->SetLongField(descramblerObj, gFields.descramblerContext, (jlong)descramblerSp.get()); env->SetLongField(descramblerObj, gFields.descramblerContext, (jlong)descramblerSp.get());
@@ -1402,11 +1405,13 @@ jobject JTuner::openFilter(DemuxFilterType type, int bufferSize) {
sp<IFilter> iFilterSp; sp<IFilter> iFilterSp;
sp<FilterCallback> callback = new FilterCallback(); sp<FilterCallback> callback = new FilterCallback();
Result res;
mDemux->openFilter(type, bufferSize, callback, mDemux->openFilter(type, bufferSize, callback,
[&](Result, const sp<IFilter>& filter) { [&](Result r, const sp<IFilter>& filter) {
iFilterSp = filter; iFilterSp = filter;
res = r;
}); });
if (iFilterSp == NULL) { if (res != Result::SUCCESS || iFilterSp == NULL) {
ALOGD("Failed to open filter, type = %d", type.mainType); ALOGD("Failed to open filter, type = %d", type.mainType);
return NULL; 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"); jclass descramblerClazz = env->FindClass("android/media/tv/tuner/Descrambler");
gFields.descramblerContext = env->GetFieldID(descramblerClazz, "mNativeContext", "J"); gFields.descramblerContext = env->GetFieldID(descramblerClazz, "mNativeContext", "J");
gFields.descramblerInitID = gFields.descramblerInitID = env->GetMethodID(descramblerClazz, "<init>", "()V");
env->GetMethodID(descramblerClazz, "<init>", "()V");
jclass dvrRecorderClazz = env->FindClass("android/media/tv/tuner/dvr/DvrRecorder"); jclass dvrRecorderClazz = env->FindClass("android/media/tv/tuner/dvr/DvrRecorder");
gFields.dvrRecorderContext = env->GetFieldID(dvrRecorderClazz, "mNativeContext", "J"); gFields.dvrRecorderContext = env->GetFieldID(dvrRecorderClazz, "mNativeContext", "J");
@@ -2905,7 +2909,7 @@ static jint android_media_tv_Tuner_configure_filter(
sp<IFilter> iFilterSp = filterSp->getIFilter(); sp<IFilter> iFilterSp = filterSp->getIFilter();
if (iFilterSp == NULL) { if (iFilterSp == NULL) {
ALOGD("Failed to configure filter: filter not found"); 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); DemuxFilterSettings filterSettings = getFilterConfiguration(env, type, subtype, settings);
Result res = iFilterSp->configure(filterSettings); 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(); sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
if (iFilterSp == NULL) { if (iFilterSp == NULL) {
ALOGD("Failed to get filter ID: filter not found"); ALOGD("Failed to get filter ID: filter not found");
return (int) Result::INVALID_STATE; return (int) Result::NOT_INITIALIZED;
} }
Result res; Result res;
uint32_t id; uint32_t id;
@@ -2956,7 +2960,7 @@ static jint android_media_tv_Tuner_set_filter_data_source(
sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter(); sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
if (iFilterSp == NULL) { if (iFilterSp == NULL) {
ALOGD("Failed to set filter data source: filter not found"); ALOGD("Failed to set filter data source: filter not found");
return (jint) Result::INVALID_STATE; return (jint) Result::NOT_INITIALIZED;
} }
Result r; Result r;
if (srcFilter == NULL) { if (srcFilter == NULL) {
@@ -2965,7 +2969,7 @@ static jint android_media_tv_Tuner_set_filter_data_source(
sp<IFilter> srcSp = getFilter(env, srcFilter)->getIFilter(); sp<IFilter> srcSp = getFilter(env, srcFilter)->getIFilter();
if (iFilterSp == NULL) { if (iFilterSp == NULL) {
ALOGD("Failed to set filter data source: src filter not found"); 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); 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(); sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
if (iFilterSp == NULL) { if (iFilterSp == NULL) {
ALOGD("Failed to start filter: filter not found"); ALOGD("Failed to start filter: filter not found");
return (jint) Result::INVALID_STATE; return (jint) Result::NOT_INITIALIZED;
} }
Result r = iFilterSp->start(); Result r = iFilterSp->start();
return (jint) r; 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(); sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
if (iFilterSp == NULL) { if (iFilterSp == NULL) {
ALOGD("Failed to stop filter: filter not found"); ALOGD("Failed to stop filter: filter not found");
return (jint) Result::INVALID_STATE; return (jint) Result::NOT_INITIALIZED;
} }
Result r = iFilterSp->stop(); Result r = iFilterSp->stop();
return (jint) r; 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(); sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
if (iFilterSp == NULL) { if (iFilterSp == NULL) {
ALOGD("Failed to flush filter: filter not found"); ALOGD("Failed to flush filter: filter not found");
return (jint) Result::INVALID_STATE; return (jint) Result::NOT_INITIALIZED;
} }
Result r = iFilterSp->flush(); Result r = iFilterSp->flush();
return (jint) r; 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(); sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
if (iFilterSp == NULL) { if (iFilterSp == NULL) {
ALOGD("Failed to close filter: filter not found"); ALOGD("Failed to close filter: filter not found");
return (jint) Result::INVALID_STATE; return (jint) Result::NOT_INITIALIZED;
} }
Result r = iFilterSp->close(); Result r = iFilterSp->close();
return (jint) r; return (jint) r;
@@ -3121,34 +3125,51 @@ static jobject android_media_tv_Tuner_open_descrambler(JNIEnv *env, jobject thiz
return tuner->openDescrambler(); 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) { JNIEnv *env, jobject descrambler, jint pidType, jint pid, jobject filter) {
sp<IDescrambler> descramblerSp = getDescrambler(env, descrambler); sp<IDescrambler> descramblerSp = getDescrambler(env, descrambler);
if (descramblerSp == NULL) { if (descramblerSp == NULL) {
return false; return (jint) Result::NOT_INITIALIZED;
} }
sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter(); sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
Result result = descramblerSp->addPid(getDemuxPid((int)pidType, (int)pid), iFilterSp); 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) { JNIEnv *env, jobject descrambler, jint pidType, jint pid, jobject filter) {
sp<IDescrambler> descramblerSp = getDescrambler(env, descrambler); sp<IDescrambler> descramblerSp = getDescrambler(env, descrambler);
if (descramblerSp == NULL) { if (descramblerSp == NULL) {
return false; return (jint) Result::NOT_INITIALIZED;
} }
sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter(); sp<IFilter> iFilterSp = getFilter(env, filter)->getIFilter();
Result result = descramblerSp->removePid(getDemuxPid((int)pidType, (int)pid), iFilterSp); 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) { static jint android_media_tv_Tuner_descrambler_set_key_token(
return 0; 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) { static jint android_media_tv_Tuner_close_descrambler(JNIEnv* env, jobject descrambler) {
return 0; 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( static jobject android_media_tv_Tuner_open_dvr_recorder(
@@ -3533,10 +3554,10 @@ static const JNINativeMethod gTimeFilterMethods[] = {
static const JNINativeMethod gDescramblerMethods[] = { static const JNINativeMethod gDescramblerMethods[] = {
{ "nativeAddPid", "(IILandroid/media/tv/tuner/filter/Filter;)I", { "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", { "nativeRemovePid", "(IILandroid/media/tv/tuner/filter/Filter;)I",
(void *)android_media_tv_Tuner_remove_pid }, (void *)android_media_tv_Tuner_descrambler_remove_pid },
{ "nativeSetKeyToken", "([B)I", (void *)android_media_tv_Tuner_set_key_token }, { "nativeSetKeyToken", "([B)I", (void *)android_media_tv_Tuner_descrambler_set_key_token },
{ "nativeClose", "()I", (void *)android_media_tv_Tuner_close_descrambler }, { "nativeClose", "()I", (void *)android_media_tv_Tuner_close_descrambler },
}; };