network: fix binder object leakage in settings
Summary: When BT ON and enter into NetworkDashboardFragment, and turning BT OFF and exiting the fragment, the `BluetoothAdapter.closeProfileProxy(BluetoothProfile.PAN)` will not be called. This causes binder leakage on next time the NetworkDashboardFragment is entered, until killing Settings process. Reproduce Steps: 1. Turn BT ON 2. Open Settings process 3. Enter "Network & internet" (NetworkDashboardFragment) 4. Turn BT OFF 5. Back to previous page (do not kill Settings process) * Repeat Step 3-5 Solution: Do not set value of `mBluetoothPan` to null when `onServiceDisconnected` raised, to ensure the binder object (profile proxy) be closed in lifecycle `onDestroy()`. Bug: 243128377 Test: enter "Network & internet" page, turn off BT and leave the page Change-Id: Ieca3e5401c23d1b0ffece1bbb0db96988044262d
This commit is contained in:
@@ -33,7 +33,9 @@ import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
@@ -56,6 +58,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
public class TetherPreferenceController extends AbstractPreferenceController implements
|
||||
PreferenceControllerMixin, LifecycleObserver, OnCreate, OnResume, OnPause, OnDestroy {
|
||||
|
||||
private static final String TAG = "TetherPreferenceController";
|
||||
private static final String KEY_TETHER_SETTINGS = "tether_settings";
|
||||
|
||||
private final boolean mAdminDisallowedTetherConfig;
|
||||
@@ -66,12 +69,13 @@ public class TetherPreferenceController extends AbstractPreferenceController imp
|
||||
final BluetoothProfile.ServiceListener mBtProfileServiceListener =
|
||||
new android.bluetooth.BluetoothProfile.ServiceListener() {
|
||||
public void onServiceConnected(int profile, BluetoothProfile proxy) {
|
||||
mBluetoothPan.set((BluetoothPan) proxy);
|
||||
if (mBluetoothPan.get() == null) {
|
||||
mBluetoothPan.set((BluetoothPan) proxy);
|
||||
}
|
||||
updateSummary();
|
||||
}
|
||||
|
||||
public void onServiceDisconnected(int profile) {
|
||||
mBluetoothPan.set(null);
|
||||
updateSummary();
|
||||
}
|
||||
};
|
||||
@@ -79,6 +83,7 @@ public class TetherPreferenceController extends AbstractPreferenceController imp
|
||||
private SettingObserver mAirplaneModeObserver;
|
||||
private Preference mPreference;
|
||||
private TetherBroadcastReceiver mTetherReceiver;
|
||||
private BroadcastReceiver mBluetoothStateReceiver;
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||
TetherPreferenceController() {
|
||||
@@ -133,6 +138,12 @@ public class TetherPreferenceController extends AbstractPreferenceController imp
|
||||
mBluetoothAdapter.getProfileProxy(mContext, mBtProfileServiceListener,
|
||||
BluetoothProfile.PAN);
|
||||
}
|
||||
if (mBluetoothStateReceiver == null) {
|
||||
mBluetoothStateReceiver = new BluetoothStateReceiver();
|
||||
mContext.registerReceiver(
|
||||
mBluetoothStateReceiver,
|
||||
new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,6 +176,10 @@ public class TetherPreferenceController extends AbstractPreferenceController imp
|
||||
if (profile != null && mBluetoothAdapter != null) {
|
||||
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.PAN, profile);
|
||||
}
|
||||
if (mBluetoothStateReceiver != null) {
|
||||
mContext.unregisterReceiver(mBluetoothStateReceiver);
|
||||
mBluetoothStateReceiver = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isTetherConfigDisallowed(Context context) {
|
||||
@@ -270,4 +285,27 @@ public class TetherPreferenceController extends AbstractPreferenceController imp
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class BluetoothStateReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
Log.i(TAG, "onReceive: action: " + action);
|
||||
|
||||
if (TextUtils.equals(action, BluetoothAdapter.ACTION_STATE_CHANGED)) {
|
||||
final int state =
|
||||
intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
|
||||
Log.i(TAG, "onReceive: state: " + BluetoothAdapter.nameForState(state));
|
||||
final BluetoothProfile profile = mBluetoothPan.get();
|
||||
switch(state) {
|
||||
case BluetoothAdapter.STATE_ON:
|
||||
if (profile == null && mBluetoothAdapter != null) {
|
||||
mBluetoothAdapter.getProfileProxy(mContext, mBtProfileServiceListener,
|
||||
BluetoothProfile.PAN);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user