Merge "Fix TetheringManager memory leak"

This commit is contained in:
Treehugger Robot
2021-10-20 03:59:59 +00:00
committed by Gerrit Code Review
3 changed files with 79 additions and 14 deletions

View File

@@ -37,6 +37,7 @@ import com.android.internal.annotations.GuardedBy;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -265,7 +266,7 @@ public class TetheringManager {
public TetheringManager(@NonNull final Context context,
@NonNull Supplier<IBinder> connectorSupplier) {
mContext = context;
mCallback = new TetheringCallbackInternal();
mCallback = new TetheringCallbackInternal(this);
mConnectorSupplier = connectorSupplier;
final String pkgName = mContext.getOpPackageName();
@@ -415,7 +416,7 @@ public class TetheringManager {
}
}
private void throwIfPermissionFailure(final int errorCode) {
private static void throwIfPermissionFailure(final int errorCode) {
switch (errorCode) {
case TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION:
throw new SecurityException("No android.permission.TETHER_PRIVILEGED"
@@ -426,21 +427,40 @@ public class TetheringManager {
}
}
private class TetheringCallbackInternal extends ITetheringEventCallback.Stub {
private static class TetheringCallbackInternal extends ITetheringEventCallback.Stub {
private volatile int mError = TETHER_ERROR_NO_ERROR;
private final ConditionVariable mWaitForCallback = new ConditionVariable();
// This object is never garbage collected because the Tethering code running in
// the system server always maintains a reference to it for as long as
// mCallback is registered.
//
// Don't keep a strong reference to TetheringManager because otherwise
// TetheringManager cannot be garbage collected, and because TetheringManager
// stores the Context that it was created from, this will prevent the calling
// Activity from being garbage collected as well.
private final WeakReference<TetheringManager> mTetheringMgrRef;
TetheringCallbackInternal(final TetheringManager tm) {
mTetheringMgrRef = new WeakReference<>(tm);
}
@Override
public void onCallbackStarted(TetheringCallbackStartedParcel parcel) {
mTetheringConfiguration = parcel.config;
mTetherStatesParcel = parcel.states;
mWaitForCallback.open();
TetheringManager tetheringMgr = mTetheringMgrRef.get();
if (tetheringMgr != null) {
tetheringMgr.mTetheringConfiguration = parcel.config;
tetheringMgr.mTetherStatesParcel = parcel.states;
mWaitForCallback.open();
}
}
@Override
public void onCallbackStopped(int errorCode) {
mError = errorCode;
mWaitForCallback.open();
TetheringManager tetheringMgr = mTetheringMgrRef.get();
if (tetheringMgr != null) {
mError = errorCode;
mWaitForCallback.open();
}
}
@Override
@@ -448,12 +468,14 @@ public class TetheringManager {
@Override
public void onConfigurationChanged(TetheringConfigurationParcel config) {
mTetheringConfiguration = config;
TetheringManager tetheringMgr = mTetheringMgrRef.get();
if (tetheringMgr != null) tetheringMgr.mTetheringConfiguration = config;
}
@Override
public void onTetherStatesChanged(TetherStatesParcel states) {
mTetherStatesParcel = states;
TetheringManager tetheringMgr = mTetheringMgrRef.get();
if (tetheringMgr != null) tetheringMgr.mTetherStatesParcel = states;
}
@Override