diff options
Diffstat (limited to 'Tethering/common/TetheringLib/src/android/net/TetheringManager.java')
| -rw-r--r-- | Tethering/common/TetheringLib/src/android/net/TetheringManager.java | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/Tethering/common/TetheringLib/src/android/net/TetheringManager.java index 73ab908af3..3086da2cee 100644 --- a/Tethering/common/TetheringLib/src/android/net/TetheringManager.java +++ b/Tethering/common/TetheringLib/src/android/net/TetheringManager.java @@ -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 |
