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

Commit fde24247 authored by Hemant Gupta's avatar Hemant Gupta Committed by Andre Eisenbach
Browse files

MAP: Serialize closeService to prevent ANR's

Usecase
1) Connect from carkit
2) Perform BT on/off
3) Repeat step(s) 1 and 2 repeatedly multiple times

Issue:
ANR observed on Bluetooth.

Rootcasue:
Issues in map code, explained below

Fix
- Mark MAPService state to stopped while closeService is ongoing.
  This will avoid extra shutdown message in stop() and fix a relevant
  NPE.
- Do not block for AcceptThread(s) cleanup during shutdown. Fix the
  handler thread blocking to handle BT TURN OFF timeout exception.

Test: ANR not obseved after performing above usecase.

Bug: 35013633
Change-Id: I065a13193200d3aa358abe5d82f1343244b05b97
parent 0d8c3245
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -410,8 +410,9 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler {
        removeSdpRecord();

        closeConnectionSocket();

        closeServerSockets(true);
        // Do not block for Accept thread cleanup.
        // Fix Handler Thread block during BT Turn OFF.
        closeServerSockets(false);
    }

    /**
+44 −12
Original line number Diff line number Diff line
@@ -148,7 +148,7 @@ public class BluetoothMapService extends ProfileService {
    private boolean mSdpSearchInitiated = false;
    SdpMnsRecord mMnsRecord = null;
    private MapServiceMessageHandler mSessionStatusHandler;
    private boolean mStartError = true;
    private boolean mServiceStarted = false;

    private boolean mSmsCapable = true;

@@ -165,7 +165,8 @@ public class BluetoothMapService extends ProfileService {
        if (DEBUG) {
            Log.d(TAG, "MAP Service closeService in");
        }

        // Mark MapService Started as false while shutdown ongoing.
        mServiceStarted = false;
        if (mBluetoothMnsObexClient != null) {
            mBluetoothMnsObexClient.shutdown();
            mBluetoothMnsObexClient = null;
@@ -505,7 +506,7 @@ public class BluetoothMapService extends ProfileService {
    }

    protected boolean isMapStarted() {
        return !mStartError;
        return mServiceStarted;
    }

    public static BluetoothDevice getRemoteDevice() {
@@ -672,8 +673,8 @@ public class BluetoothMapService extends ProfileService {

        // start RFCOMM listener
        sendStartListenerMessage(-1);
        mStartError = false;
        return !mStartError;
        mServiceStarted = true;
        return mServiceStarted;
    }

    /**
@@ -844,7 +845,8 @@ public class BluetoothMapService extends ProfileService {
        //TODO: Check if the profile state can be retreived from ProfileService or AdapterService.
        if (!isMapStarted()) {
            if (DEBUG) {
                Log.d(TAG, "Service Not Available to STOP, ignoring");
                Log.d(TAG, "Service Not Available to STOP or Shutdown already"
                                + " in progress - Ignoring");
            }
            return true;
        } else {
@@ -852,11 +854,13 @@ public class BluetoothMapService extends ProfileService {
                Log.d(TAG, "Service Stoping()");
            }
        }
        // setState Disconnect already handled from closeService.
        // Handle it otherwise - Redundant for backup?
        setState(BluetoothMap.STATE_DISCONNECTED, BluetoothMap.RESULT_CANCELED);
        if (mSessionStatusHandler != null) {
            sendShutdownMessage();
        }
        mStartError = true;
        setState(BluetoothMap.STATE_DISCONNECTED, BluetoothMap.RESULT_CANCELED);
        mServiceStarted = false;
        return true;
    }

@@ -865,10 +869,26 @@ public class BluetoothMapService extends ProfileService {
        if (DEBUG) {
            Log.d(TAG, "cleanup()");
        }
        // Stop MapProfile if already started.
        // TODO: Check if the profile state can be retreived from ProfileService or AdapterService.
        if (!isMapStarted()) {
            if (DEBUG) {
                Log.d(TAG, "Service Not Available to STOP or Shutdown already"
                                + " in progress - Ignoring");
            }
            return true;
        } else {
            if (VERBOSE) Log.d(TAG, "Service Stoping()");
        }
        // SetState Disconnect already handled from closeService.
        // Handle it otherwise. Redundant for backup ?
        setState(BluetoothMap.STATE_DISCONNECTED, BluetoothMap.RESULT_CANCELED);
        //Cleanup already handled in Stop().
        //Move this  extra check to Handler.
        if (mSessionStatusHandler != null) {
            sendShutdownMessage();
        }
        mServiceStarted = false;
        return true;
    }

@@ -1057,10 +1077,22 @@ public class BluetoothMapService extends ProfileService {
                int state =
                        intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
                if (state == BluetoothAdapter.STATE_TURNING_OFF) {
                    if (DEBUG) Log.d(TAG, "STATE_TURNING_OFF");
                    // Stop MapProfile if already started.
                    if (!isMapStarted()) {
                        if (DEBUG) {
                        Log.d(TAG, "STATE_TURNING_OFF");
                            Log.d(TAG, "Service Not Available to STOP or Shutdown already"
                                            + " in progress - Ignoring");
                        }
                    } else if (mSessionStatusHandler != null) {
                        if (VERBOSE) Log.d(TAG, "Service Stoping()");
                        sendShutdownMessage();
                    } else {
                        if (DEBUG) {
                            Log.d(TAG, "Unable to perform STOP or Shutdown already"
                                            + " in progress - Ignoring");
                        }
                    }
                } else if (state == BluetoothAdapter.STATE_ON) {
                    if (DEBUG) {
                        Log.d(TAG, "STATE_ON");