Loading media/java/android/media/tv/tuner/Descrambler.java +28 −5 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -80,8 +84,11 @@ public class Descrambler implements AutoCloseable { */ @Result public int addPid(@PidType int pidType, int pid, @Nullable Filter filter) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeAddPid(pidType, pid, filter); } } /** * Remove packets' PID from the descrambler Loading @@ -95,8 +102,11 @@ public class Descrambler implements AutoCloseable { */ @Result public int removePid(@PidType int pidType, int pid, @Nullable Filter filter) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeRemovePid(pidType, pid, filter); } } /** * Set a key token to link descrambler to a key slot Loading @@ -109,16 +119,29 @@ public class Descrambler implements AutoCloseable { */ @Result public int setKeyToken(@NonNull byte[] keyToken) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); Objects.requireNonNull(keyToken, "key token must not be null"); return nativeSetKeyToken(keyToken); } } /** * Release the descrambler instance. */ @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; } } } } media/java/android/media/tv/tuner/Lnb.java +41 −8 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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) { Loading @@ -177,6 +184,12 @@ public class Lnb implements AutoCloseable { } } /* package */ boolean isClosed() { synchronized (mLock) { return mIsClosed; } } /** * Sets the LNB's power voltage. * Loading @@ -185,8 +198,11 @@ public class Lnb implements AutoCloseable { */ @Result public int setVoltage(@Voltage int voltage) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeSetVoltage(voltage); } } /** * Sets the LNB's tone mode. Loading @@ -196,8 +212,11 @@ public class Lnb implements AutoCloseable { */ @Result public int setTone(@Tone int tone) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeSetTone(tone); } } /** * Selects the LNB's position. Loading @@ -207,8 +226,11 @@ public class Lnb implements AutoCloseable { */ @Result public int setSatellitePosition(@Position int position) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeSetSatellitePosition(position); } } /** * Sends DiSEqC (Digital Satellite Equipment Control) message. Loading @@ -222,16 +244,27 @@ public class Lnb implements AutoCloseable { */ @Result public int sendDiseqcMessage(@NonNull byte[] message) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeSendDiseqcMessage(message); } } /** * Releases the LNB instance. */ public void close() { 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(); } } } } media/java/android/media/tv/tuner/Tuner.java +53 −24 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -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"); } Loading Loading @@ -857,6 +871,7 @@ public class Tuner implements AutoCloseable { if (mHandler == null) { mHandler = createEventHandler(); } mFilters.add(filter); } return filter; } Loading @@ -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; } Loading @@ -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); Lnb newLnb = nativeOpenLnbByName(name); if (newLnb != null) { if (mLnb != null) { mLnb.setCallback(executor, cb); mLnb.close(); mLnbHandle = null; } mLnb = newLnb; mLnb.setCallback(executor, cb, this); } return mLnb; } Loading Loading @@ -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(); } /** Loading Loading @@ -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) { Loading @@ -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; Loading @@ -1026,13 +1053,15 @@ public class Tuner implements AutoCloseable { } break; } case TunerResourceManager.TUNER_RESOURCE_TYPE_DESCRAMBLER: { if (mDescramblerHandle == null && !requestDescrambler()) { default: return false; } break; } } return true; } /* package */ void releaseLnb() { mTunerResourceManager.releaseLnb(mLnbHandle, mClientId); mLnbHandle = null; mLnb = null; } } media/java/android/media/tv/tuner/TunerUtils.java +11 −0 Original line number Diff line number Diff line Loading @@ -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() {} } media/java/android/media/tv/tuner/filter/Filter.java +55 −23 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); Loading Loading @@ -244,6 +248,8 @@ public class Filter implements AutoCloseable { */ @Result public int configure(@NonNull FilterConfiguration config) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); Settings s = config.getSettings(); int subType = (s == null) ? mSubtype : s.getType(); if (mMainType != config.getType() || mSubtype != subType) { Loading @@ -253,13 +259,17 @@ public class Filter implements AutoCloseable { } return nativeConfigureFilter(config.getType(), subType, config); } } /** * Gets the filter Id. */ public int getId() { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeGetId(); } } /** * Sets the filter's data source. Loading @@ -276,6 +286,8 @@ public class Filter implements AutoCloseable { */ @Result public int setDataSource(@Nullable Filter source) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); if (mSource != null) { throw new IllegalStateException("Data source is existing"); } Loading @@ -285,6 +297,7 @@ public class Filter implements AutoCloseable { } return res; } } /** * Starts filtering data. Loading @@ -295,8 +308,11 @@ public class Filter implements AutoCloseable { */ @Result public int start() { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeStartFilter(); } } /** Loading @@ -308,8 +324,11 @@ public class Filter implements AutoCloseable { */ @Result public int stop() { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeStopFilter(); } } /** * Flushes the filter. Loading @@ -321,8 +340,11 @@ public class Filter implements AutoCloseable { */ @Result public int flush() { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeFlushFilter(); } } /** * Copies filtered data from filter output to the given byte array. Loading @@ -333,18 +355,28 @@ public class Filter implements AutoCloseable { * @return the number of bytes read. */ 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); return nativeRead(buffer, offset, size); } } /** * Stops filtering data and releases the Filter instance. */ @Override public void close() { synchronized (mLock) { if (mIsClosed) { return; } int res = nativeClose(); if (res != Tuner.RESULT_SUCCESS) { TunerUtils.throwExceptionForResult(res, "Failed to close filter."); } else { mIsClosed = true; } } } } Loading
media/java/android/media/tv/tuner/Descrambler.java +28 −5 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -80,8 +84,11 @@ public class Descrambler implements AutoCloseable { */ @Result public int addPid(@PidType int pidType, int pid, @Nullable Filter filter) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeAddPid(pidType, pid, filter); } } /** * Remove packets' PID from the descrambler Loading @@ -95,8 +102,11 @@ public class Descrambler implements AutoCloseable { */ @Result public int removePid(@PidType int pidType, int pid, @Nullable Filter filter) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeRemovePid(pidType, pid, filter); } } /** * Set a key token to link descrambler to a key slot Loading @@ -109,16 +119,29 @@ public class Descrambler implements AutoCloseable { */ @Result public int setKeyToken(@NonNull byte[] keyToken) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); Objects.requireNonNull(keyToken, "key token must not be null"); return nativeSetKeyToken(keyToken); } } /** * Release the descrambler instance. */ @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; } } } }
media/java/android/media/tv/tuner/Lnb.java +41 −8 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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) { Loading @@ -177,6 +184,12 @@ public class Lnb implements AutoCloseable { } } /* package */ boolean isClosed() { synchronized (mLock) { return mIsClosed; } } /** * Sets the LNB's power voltage. * Loading @@ -185,8 +198,11 @@ public class Lnb implements AutoCloseable { */ @Result public int setVoltage(@Voltage int voltage) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeSetVoltage(voltage); } } /** * Sets the LNB's tone mode. Loading @@ -196,8 +212,11 @@ public class Lnb implements AutoCloseable { */ @Result public int setTone(@Tone int tone) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeSetTone(tone); } } /** * Selects the LNB's position. Loading @@ -207,8 +226,11 @@ public class Lnb implements AutoCloseable { */ @Result public int setSatellitePosition(@Position int position) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeSetSatellitePosition(position); } } /** * Sends DiSEqC (Digital Satellite Equipment Control) message. Loading @@ -222,16 +244,27 @@ public class Lnb implements AutoCloseable { */ @Result public int sendDiseqcMessage(@NonNull byte[] message) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeSendDiseqcMessage(message); } } /** * Releases the LNB instance. */ public void close() { 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(); } } } }
media/java/android/media/tv/tuner/Tuner.java +53 −24 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -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"); } Loading Loading @@ -857,6 +871,7 @@ public class Tuner implements AutoCloseable { if (mHandler == null) { mHandler = createEventHandler(); } mFilters.add(filter); } return filter; } Loading @@ -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; } Loading @@ -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); Lnb newLnb = nativeOpenLnbByName(name); if (newLnb != null) { if (mLnb != null) { mLnb.setCallback(executor, cb); mLnb.close(); mLnbHandle = null; } mLnb = newLnb; mLnb.setCallback(executor, cb, this); } return mLnb; } Loading Loading @@ -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(); } /** Loading Loading @@ -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) { Loading @@ -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; Loading @@ -1026,13 +1053,15 @@ public class Tuner implements AutoCloseable { } break; } case TunerResourceManager.TUNER_RESOURCE_TYPE_DESCRAMBLER: { if (mDescramblerHandle == null && !requestDescrambler()) { default: return false; } break; } } return true; } /* package */ void releaseLnb() { mTunerResourceManager.releaseLnb(mLnbHandle, mClientId); mLnbHandle = null; mLnb = null; } }
media/java/android/media/tv/tuner/TunerUtils.java +11 −0 Original line number Diff line number Diff line Loading @@ -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() {} }
media/java/android/media/tv/tuner/filter/Filter.java +55 −23 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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); Loading Loading @@ -244,6 +248,8 @@ public class Filter implements AutoCloseable { */ @Result public int configure(@NonNull FilterConfiguration config) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); Settings s = config.getSettings(); int subType = (s == null) ? mSubtype : s.getType(); if (mMainType != config.getType() || mSubtype != subType) { Loading @@ -253,13 +259,17 @@ public class Filter implements AutoCloseable { } return nativeConfigureFilter(config.getType(), subType, config); } } /** * Gets the filter Id. */ public int getId() { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeGetId(); } } /** * Sets the filter's data source. Loading @@ -276,6 +286,8 @@ public class Filter implements AutoCloseable { */ @Result public int setDataSource(@Nullable Filter source) { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); if (mSource != null) { throw new IllegalStateException("Data source is existing"); } Loading @@ -285,6 +297,7 @@ public class Filter implements AutoCloseable { } return res; } } /** * Starts filtering data. Loading @@ -295,8 +308,11 @@ public class Filter implements AutoCloseable { */ @Result public int start() { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeStartFilter(); } } /** Loading @@ -308,8 +324,11 @@ public class Filter implements AutoCloseable { */ @Result public int stop() { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeStopFilter(); } } /** * Flushes the filter. Loading @@ -321,8 +340,11 @@ public class Filter implements AutoCloseable { */ @Result public int flush() { synchronized (mLock) { TunerUtils.checkResourceState(TAG, mIsClosed); return nativeFlushFilter(); } } /** * Copies filtered data from filter output to the given byte array. Loading @@ -333,18 +355,28 @@ public class Filter implements AutoCloseable { * @return the number of bytes read. */ 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); return nativeRead(buffer, offset, size); } } /** * Stops filtering data and releases the Filter instance. */ @Override public void close() { synchronized (mLock) { if (mIsClosed) { return; } int res = nativeClose(); if (res != Tuner.RESULT_SUCCESS) { TunerUtils.throwExceptionForResult(res, "Failed to close filter."); } else { mIsClosed = true; } } } }