Add thread protection for Filter/Descrambler table

Use weak reference in the tables to allow objects released by caller

bug: 174685399
bug: 174711353
Test: manual
Change-Id: I760d0a77ad9efe2709a14f0fb8a669f8f16652e1
This commit is contained in:
Henry Fang
2020-12-04 09:51:55 -08:00
parent b2c48f87ec
commit be8431c2ca

View File

@@ -60,6 +60,7 @@ import com.android.internal.util.FrameworkStatsLog;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@@ -296,8 +297,8 @@ public class Tuner implements AutoCloseable {
private Executor mOnResourceLostListenerExecutor; private Executor mOnResourceLostListenerExecutor;
private Integer mDemuxHandle; private Integer mDemuxHandle;
private Map<Integer, Descrambler> mDescramblers = new HashMap<>(); private Map<Integer, WeakReference<Descrambler>> mDescramblers = new HashMap<>();
private List<Filter> mFilters = new ArrayList<>(); private List<WeakReference<Filter>> mFilters = new ArrayList<WeakReference<Filter>>();
private final TunerResourceManager.ResourcesReclaimListener mResourceListener = private final TunerResourceManager.ResourcesReclaimListener mResourceListener =
new TunerResourceManager.ResourcesReclaimListener() { new TunerResourceManager.ResourcesReclaimListener() {
@@ -486,19 +487,29 @@ public class Tuner implements AutoCloseable {
if (mLnb != null) { if (mLnb != null) {
mLnb.close(); mLnb.close();
} }
synchronized (mDescramblers) {
if (!mDescramblers.isEmpty()) { if (!mDescramblers.isEmpty()) {
for (Map.Entry<Integer, Descrambler> d : mDescramblers.entrySet()) { for (Map.Entry<Integer, WeakReference<Descrambler>> d : mDescramblers.entrySet()) {
d.getValue().close(); Descrambler descrambler = d.getValue().get();
if (descrambler != null) {
descrambler.close();
}
mTunerResourceManager.releaseDescrambler(d.getKey(), mClientId); mTunerResourceManager.releaseDescrambler(d.getKey(), mClientId);
} }
mDescramblers.clear(); mDescramblers.clear();
} }
}
synchronized (mFilters) {
if (!mFilters.isEmpty()) { if (!mFilters.isEmpty()) {
for (Filter f : mFilters) { for (WeakReference<Filter> weakFilter : mFilters) {
f.close(); Filter filter = weakFilter.get();
if (filter != null) {
filter.close();
}
} }
mFilters.clear(); mFilters.clear();
} }
}
if (mDemuxHandle != null) { if (mDemuxHandle != null) {
int res = nativeCloseDemux(mDemuxHandle); int res = nativeCloseDemux(mDemuxHandle);
if (res != Tuner.RESULT_SUCCESS) { if (res != Tuner.RESULT_SUCCESS) {
@@ -1183,7 +1194,10 @@ public class Tuner implements AutoCloseable {
if (mHandler == null) { if (mHandler == null) {
mHandler = createEventHandler(); mHandler = createEventHandler();
} }
mFilters.add(filter); synchronized (mFilters) {
WeakReference<Filter> weakFilter = new WeakReference<Filter>(filter);
mFilters.add(weakFilter);
}
} }
return filter; return filter;
} }
@@ -1351,7 +1365,10 @@ public class Tuner implements AutoCloseable {
int handle = descramblerHandle[0]; int handle = descramblerHandle[0];
Descrambler descrambler = nativeOpenDescramblerByHandle(handle); Descrambler descrambler = nativeOpenDescramblerByHandle(handle);
if (descrambler != null) { if (descrambler != null) {
mDescramblers.put(handle, descrambler); synchronized (mDescramblers) {
WeakReference weakDescrambler = new WeakReference<Descrambler>(descrambler);
mDescramblers.put(handle, weakDescrambler);
}
} else { } else {
mTunerResourceManager.releaseDescrambler(handle, mClientId); mTunerResourceManager.releaseDescrambler(handle, mClientId);
} }