Crash in Settings observed while changing the device orientation after renamed tablet

There was a fundamental flow in the BT code. Basically BluetoothSettings is using
a singleton BluetoothDiscoverableEnabler.

BluetoothDiscoverableEnabler is keeping (thru its constructor) a reference on a Context
for registering/unregistering some broadcast receiver. BUMMER! When you change orientation
(or more generally the device Configuration), your Context is no more the same!

Hence the crash as we were  trying to unregister a Receiver on a Context that is no more valid.

Fix that issue by passing an updated Context to the BluetoothDiscoverableEnabler.resume() API.

Bug #12991455
Change-Id: I77db15d2b59b6dd973907e26f9e6bb022202a8b5
This commit is contained in:
Fabrice Di Meglio
2014-02-14 15:09:30 -08:00
parent b643627651
commit ce930c15ae
3 changed files with 12 additions and 9 deletions

View File

@@ -57,7 +57,7 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceClick
static final int DEFAULT_DISCOVERABLE_TIMEOUT = DISCOVERABLE_TIMEOUT_TWO_MINUTES; static final int DEFAULT_DISCOVERABLE_TIMEOUT = DISCOVERABLE_TIMEOUT_TWO_MINUTES;
private final Context mContext; private Context mContext;
private final Handler mUiHandler; private final Handler mUiHandler;
private final Preference mDiscoveryPreference; private final Preference mDiscoveryPreference;
// Preference for visibility time out. Not final as it needs to be set through setter. // Preference for visibility time out. Not final as it needs to be set through setter.
@@ -91,9 +91,8 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceClick
} }
}; };
BluetoothDiscoverableEnabler(Context context, LocalBluetoothAdapter adapter, BluetoothDiscoverableEnabler(LocalBluetoothAdapter adapter,
Preference discoveryPreference) { Preference discoveryPreference) {
mContext = context;
mUiHandler = new Handler(); mUiHandler = new Handler();
mLocalAdapter = adapter; mLocalAdapter = adapter;
mDiscoveryPreference = discoveryPreference; mDiscoveryPreference = discoveryPreference;
@@ -105,11 +104,15 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceClick
mVisibilityTimeoutPreference = visibilityPreference; mVisibilityTimeoutPreference = visibilityPreference;
} }
public void resume() { public void resume(Context context) {
if (mLocalAdapter == null) { if (mLocalAdapter == null) {
return; return;
} }
if (mContext != context) {
mContext = context;
}
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED); IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
mContext.registerReceiver(mReceiver, filter); mContext.registerReceiver(mReceiver, filter);
mDiscoveryPreference.setOnPreferenceClickListener(this); mDiscoveryPreference.setOnPreferenceClickListener(this);

View File

@@ -156,7 +156,7 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
super.onResume(); super.onResume();
if (mDiscoverableEnabler != null) { if (mDiscoverableEnabler != null) {
mDiscoverableEnabler.resume(); mDiscoverableEnabler.resume(getActivity());
} }
getActivity().registerReceiver(mReceiver, mIntentFilter); getActivity().registerReceiver(mReceiver, mIntentFilter);
if (mLocalAdapter != null) { if (mLocalAdapter != null) {
@@ -262,9 +262,9 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
if (!isRestrictedAndNotPinProtected()) { if (!isRestrictedAndNotPinProtected()) {
if (mDiscoverableEnabler == null) { if (mDiscoverableEnabler == null) {
mDiscoverableEnabler = new BluetoothDiscoverableEnabler(getActivity(), mDiscoverableEnabler = new BluetoothDiscoverableEnabler(mLocalAdapter,
mLocalAdapter, mMyDevicePreference); mMyDevicePreference);
mDiscoverableEnabler.resume(); mDiscoverableEnabler.resume(getActivity());
LocalBluetoothManager.getInstance(getActivity()).setDiscoverableEnabler( LocalBluetoothManager.getInstance(getActivity()).setDiscoverableEnabler(
mDiscoverableEnabler); mDiscoverableEnabler);
} }

View File

@@ -82,7 +82,7 @@ public final class LocalDeviceProfilesSettings extends SettingsPreferenceFragmen
super.onResume(); super.onResume();
mManager.setForegroundActivity(getActivity()); mManager.setForegroundActivity(getActivity());
mAdvertisingEnabler.resume(); mAdvertisingEnabler.resume();
mDiscoverableEnabler.resume(); mDiscoverableEnabler.resume(getActivity());
} }
@Override @Override