Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eebd4407 authored by Angela Wang's avatar Angela Wang
Browse files

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
parent 9ab22c28
Loading
Loading
Loading
Loading
+62 −11
Original line number Diff line number Diff line
@@ -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,8 +218,7 @@ 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()
                Log.d(TAG, "onPresetSelectionFailed, device: " + device.getAddress()
                        + ", reason: " + reason);
            }
            mContext.getMainExecutor().execute(() -> {
@@ -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
    }
}