Refine WifiTetherSoftApManager and DataSaverBackend to avoid activity leaks

- Declare the service callback as static class and use WeakReference to avoid the callback link being occupied

- Use application context instead of fragment context to avoid context being occupied by external modules

Bug: 237273138
Test: manual test
make RunSettingsRoboTests ROBOTEST_FILTER=TetherSettingsTest
make RunSettingsRoboTests ROBOTEST_FILTER=WifiTetherPreferenceControllerTest

Change-Id: Icca145b8ef08b9949feafbbd4e761f8d50c99181
This commit is contained in:
Weng Su
2022-09-13 21:47:50 +08:00
parent aea2e7cd2e
commit 2f55ae15f1
3 changed files with 47 additions and 16 deletions

View File

@@ -27,6 +27,8 @@ import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.utils.ThreadUtils;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
public class DataSaverBackend {
@@ -43,10 +45,11 @@ public class DataSaverBackend {
private boolean mDenylistInitialized;
// TODO: Staticize into only one.
public DataSaverBackend(Context context) {
mContext = context;
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
mPolicyManager = NetworkPolicyManager.from(context);
public DataSaverBackend(@NotNull Context context) {
// TODO(b/246537614):Use fragment context to DataSaverBackend class will caused memory leak
mContext = context.getApplicationContext();
mMetricsFeatureProvider = FeatureFactory.getFactory(mContext).getMetricsFeatureProvider();
mPolicyManager = NetworkPolicyManager.from(mContext);
}
public void addListener(Listener listener) {

View File

@@ -56,8 +56,9 @@ public class WifiTetherPreferenceController extends AbstractPreferenceController
WifiTetherSoftApManager mWifiTetherSoftApManager;
public WifiTetherPreferenceController(Context context, Lifecycle lifecycle) {
// TODO(b/246537032):Use fragment context to WifiManager service will caused memory leak
this(context, lifecycle,
context.getSystemService(WifiManager.class),
context.getApplicationContext().getSystemService(WifiManager.class),
context.getSystemService(TetheringManager.class),
true /* initSoftApManager */,
WifiEnterpriseRestrictionUtils.isWifiTetheringAllowed(context));

View File

@@ -5,6 +5,7 @@ import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.HandlerExecutor;
import java.lang.ref.WeakReference;
import java.util.List;
/**
@@ -15,23 +16,14 @@ public class WifiTetherSoftApManager {
private WifiManager mWifiManager;
private WifiTetherSoftApCallback mWifiTetherSoftApCallback;
private WifiManager.SoftApCallback mSoftApCallback = new WifiManager.SoftApCallback() {
@Override
public void onStateChanged(int state, int failureReason) {
mWifiTetherSoftApCallback.onStateChanged(state, failureReason);
}
@Override
public void onConnectedClientsChanged(List<WifiClient> clients) {
mWifiTetherSoftApCallback.onConnectedClientsChanged(clients);
}
};
private WifiManager.SoftApCallback mSoftApCallback;
private Handler mHandler;
WifiTetherSoftApManager(WifiManager wifiManager,
WifiTetherSoftApCallback wifiTetherSoftApCallback) {
mWifiManager = wifiManager;
mWifiTetherSoftApCallback = wifiTetherSoftApCallback;
mSoftApCallback = new WifiManagerSoftApCallback(this);
mHandler = new Handler();
}
@@ -43,6 +35,14 @@ public class WifiTetherSoftApManager {
mWifiManager.unregisterSoftApCallback(mSoftApCallback);
}
void onStateChanged(int state, int failureReason) {
mWifiTetherSoftApCallback.onStateChanged(state, failureReason);
}
void onConnectedClientsChanged(List<WifiClient> clients) {
mWifiTetherSoftApCallback.onConnectedClientsChanged(clients);
}
public interface WifiTetherSoftApCallback {
void onStateChanged(int state, int failureReason);
@@ -53,4 +53,31 @@ public class WifiTetherSoftApManager {
*/
void onConnectedClientsChanged(List<WifiClient> clients);
}
// TODO(b/246537032):Need to declare the service callback as static class and use
// WeakReference to avoid the callback link being occupied by WifiManager
private static final class WifiManagerSoftApCallback implements
WifiManager.SoftApCallback {
WeakReference<WifiTetherSoftApManager> mMyClass;
WifiManagerSoftApCallback(WifiTetherSoftApManager controller) {
mMyClass = new WeakReference<>(controller);
}
@Override
public void onStateChanged(int state, int failureReason) {
WifiTetherSoftApManager controller = mMyClass.get();
if (controller == null) return;
controller.onStateChanged(state, failureReason);
}
@Override
public void onConnectedClientsChanged(List<WifiClient> clients) {
WifiTetherSoftApManager controller = mMyClass.get();
if (controller == null) return;
controller.onConnectedClientsChanged(clients);
}
}
}