Register callback again after service is connected

The exception is thrown when trying to unregister a not-registered callback. This may happen when after rebooting the device, the proxy is not attached to the service while registerCallback() is called in onResume(). The callback will not be correctly registered and hence causing this exception when unregisterCallback() is called in onPause().

Add listener to listen the onServiceConnected() callback and re-register
the callback if the service is not connected when user enters to the
page.

Bug: 330116041
Test: manually test the scenario and confirm no exception thrown
Change-Id: I1f99d067e28e285bcbfff1f34bd322cdbac8063a
This commit is contained in:
Angela Wang
2024-03-26 03:46:56 +00:00
parent 9ab22c28fb
commit eebd44074a

View File

@@ -41,9 +41,12 @@ import com.android.settings.R;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.HapClientProfile;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
import com.android.settingslib.utils.ThreadUtils;
import java.util.List;
@@ -53,13 +56,16 @@ import java.util.List;
*/
public class BluetoothDetailsHearingAidsPresetsController extends
BluetoothDetailsController implements Preference.OnPreferenceChangeListener,
BluetoothHapClient.Callback, OnResume, OnPause {
BluetoothHapClient.Callback, LocalBluetoothProfileManager.ServiceListener,
OnStart, OnResume, OnPause, OnStop {
private static final boolean DEBUG = true;
private static final String TAG = "BluetoothDetailsHearingAidsPresetsController";
static final String KEY_HEARING_AIDS_PRESETS = "hearing_aids_presets";
private final LocalBluetoothProfileManager mProfileManager;
private final HapClientProfile mHapClientProfile;
@Nullable
private ListPreference mPreference;
@@ -69,25 +75,34 @@ public class BluetoothDetailsHearingAidsPresetsController extends
@NonNull CachedBluetoothDevice device,
@NonNull Lifecycle lifecycle) {
super(context, fragment, device, lifecycle);
mHapClientProfile = manager.getProfileManager().getHapClientProfile();
mProfileManager = manager.getProfileManager();
mHapClientProfile = mProfileManager.getHapClientProfile();
}
@Override
public void onStart() {
if (mHapClientProfile != null && !mHapClientProfile.isProfileReady()) {
mProfileManager.addServiceListener(this);
}
}
@Override
public void onResume() {
registerHapCallback();
super.onResume();
if (mHapClientProfile != null) {
mHapClientProfile.registerCallback(ThreadUtils.getBackgroundExecutor(), this);
}
}
@Override
public void onPause() {
if (mHapClientProfile != null) {
mHapClientProfile.unregisterCallback(this);
}
unregisterHapCallback();
super.onPause();
}
@Override
public void onStop() {
mProfileManager.removeServiceListener(this);
}
@Override
public boolean onPreferenceChange(@NonNull Preference preference, @Nullable Object newValue) {
if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
@@ -203,9 +218,8 @@ public class BluetoothDetailsHearingAidsPresetsController extends
public void onPresetSelectionFailed(@NonNull BluetoothDevice device, int reason) {
if (device.equals(mCachedDevice.getDevice())) {
if (DEBUG) {
Log.d(TAG,
"onPresetSelectionFailed, device: " + device.getAddress()
+ ", reason: " + reason);
Log.d(TAG, "onPresetSelectionFailed, device: " + device.getAddress()
+ ", reason: " + reason);
}
mContext.getMainExecutor().execute(() -> {
refresh();
@@ -305,4 +319,41 @@ public class BluetoothDetailsHearingAidsPresetsController extends
Toast.makeText(mContext, R.string.bluetooth_hearing_aids_presets_error,
Toast.LENGTH_SHORT).show();
}
private void registerHapCallback() {
if (mHapClientProfile != null) {
try {
mHapClientProfile.registerCallback(ThreadUtils.getBackgroundExecutor(), this);
} catch (IllegalArgumentException e) {
// The callback was already registered
Log.w(TAG, "Cannot register callback: " + e.getMessage());
}
}
}
private void unregisterHapCallback() {
if (mHapClientProfile != null) {
try {
mHapClientProfile.unregisterCallback(this);
} catch (IllegalArgumentException e) {
// The callback was never registered or was already unregistered
Log.w(TAG, "Cannot unregister callback: " + e.getMessage());
}
}
}
@Override
public void onServiceConnected() {
if (mHapClientProfile != null && mHapClientProfile.isProfileReady()) {
mProfileManager.removeServiceListener(this);
registerHapCallback();
refresh();
}
}
@Override
public void onServiceDisconnected() {
// Do nothing
}
}