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

Commit 50b40cec authored by Jaikumar Ganesh's avatar Jaikumar Ganesh
Browse files

Wait till SDP records are registered before sending intent.

Wait till all SDP records are registered, before sending STATE_ON intent.
This would fix crashes in Settings app when the profile manager
is not registered.
Problem:
  We were sending Bluetooth State on intent before we got the uuid state
  change intent from Bluez, which is asynchronous.
  Hence when the Settings app queries for the profiles
  to decide if headset profile was registered it would get false and
  the profile manager would be null causing crashes.
  This was not 100 % reproducible, well because it was a race condition.

Change-Id: I791eb63dfbc78aba4c06fd8db933069cb5fde00d
parent 4eb02a13
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -306,6 +306,9 @@ class BluetoothEventLoop {
                value = str.toString();
            }
            mBluetoothService.setProperty(name, value);
            if (name.equals("UUIDs")) {
                mBluetoothService.updateBluetoothState(value);
            }
        } else if (name.equals("Powered")) {
            // bluetoothd has restarted, re-read all our properties.
            // Note: bluez only sends this property change when it restarts.
+60 −39
Original line number Diff line number Diff line
@@ -96,8 +96,8 @@ public class BluetoothService extends IBluetooth.Stub {
    private boolean mRestart = false;  // need to call enable() after disable()
    private boolean mIsDiscovering;
    private boolean mTetheringOn;
    private int[] mAdapterSdpUuids;
    private int[] mAdapterSdpHandles;
    private ParcelUuid[] mAdapterUuids;

    private BluetoothAdapter mAdapter;  // constant after init()
    private final BondState mBondState = new BondState();  // local cache of bondings
@@ -438,6 +438,8 @@ public class BluetoothService extends IBluetooth.Stub {
        mProfilesConnecting = 0;
        mProfilesDisconnecting = 0;
        mAdapterConnectionState = BluetoothAdapter.STATE_DISCONNECTED;
        mAdapterUuids = null;
        mAdapterSdpHandles = null;

        if (saveSetting) {
            persistBluetoothOnSetting(false);
@@ -579,7 +581,6 @@ public class BluetoothService extends IBluetooth.Stub {
                }
            }


            if (res) {
                if (!setupNativeDataNative()) {
                    return;
@@ -587,33 +588,8 @@ public class BluetoothService extends IBluetooth.Stub {
                if (mSaveSetting) {
                    persistBluetoothOnSetting(true);
                }
                //Register SDP records.
                if (mContext.getResources().
                        getBoolean(com.android.internal.R.bool.config_voice_capable)) {
                     int[] uuids = {
                        BluetoothUuid.getServiceIdentifierFromParcelUuid(
                            BluetoothUuid.Handsfree_AG),
                        BluetoothUuid.getServiceIdentifierFromParcelUuid(
                            BluetoothUuid.HSP_AG),
                        BluetoothUuid.getServiceIdentifierFromParcelUuid(
                             BluetoothUuid.PBAP_PSE),
                        BluetoothUuid.getServiceIdentifierFromParcelUuid(
                             BluetoothUuid.ObexObjectPush),
                        };
                     mAdapterSdpUuids = uuids;

                } else {
                     int[] uuids = {
                         BluetoothUuid.getServiceIdentifierFromParcelUuid(
                             BluetoothUuid.HSP_AG),
                         BluetoothUuid.getServiceIdentifierFromParcelUuid(
                             BluetoothUuid.ObexObjectPush),
                         };
                      mAdapterSdpUuids = uuids;
                }

                mAdapterSdpHandles = addReservedServiceRecordsNative(mAdapterSdpUuids);
                setBluetoothTetheringNative(true, BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);
                updateSdpRecords();

                mIsDiscovering = false;
                mBondState.readAutoPairingData();
@@ -628,24 +604,67 @@ public class BluetoothService extends IBluetooth.Stub {
                } finally {
                    Binder.restoreCallingIdentity(ident);
                }
            } else {
                setBluetoothState(BluetoothAdapter.STATE_OFF);
            }

            mEnableThread = null;
        }
    }

            setBluetoothState(res ?
                              BluetoothAdapter.STATE_ON :
                              BluetoothAdapter.STATE_OFF);
    private synchronized void addReservedSdpRecords(final ArrayList<ParcelUuid> uuids) {
        //Register SDP records.
        int[] svcIdentifiers = new int[uuids.size()];
        for (int i = 0; i < uuids.size(); i++) {
            svcIdentifiers[i] = BluetoothUuid.getServiceIdentifierFromParcelUuid(uuids.get(i));
        }
        mAdapterSdpHandles = addReservedServiceRecordsNative(svcIdentifiers);
    }

            if (res) {
                // Update mode
    private synchronized void updateSdpRecords() {
        ArrayList<ParcelUuid> uuids = new ArrayList<ParcelUuid>();

        // Add the default records
        uuids.add(BluetoothUuid.HSP_AG);
        uuids.add(BluetoothUuid.ObexObjectPush);

        if (mContext.getResources().
                getBoolean(com.android.internal.R.bool.config_voice_capable)) {
            uuids.add(BluetoothUuid.Handsfree_AG);
            uuids.add(BluetoothUuid.PBAP_PSE);
        }

        // Add SDP records for profiles maintained by Android userspace
        addReservedSdpRecords(uuids);

        // Enable profiles maintained by Bluez userspace.
        setBluetoothTetheringNative(true, BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);

        // Add SDP records for profiles maintained by Bluez userspace
        uuids.add(BluetoothUuid.AudioSource);
        uuids.add(BluetoothUuid.AvrcpTarget);
        uuids.add(BluetoothUuid.NAP);

        // Cannot cast uuids.toArray directly since ParcelUuid is parcelable
        mAdapterUuids = new ParcelUuid[uuids.size()];
        for (int i = 0; i < uuids.size(); i++) {
            mAdapterUuids[i] = uuids.get(i);
        }
    }

    synchronized void updateBluetoothState(String uuids) {
        if (mBluetoothState == BluetoothAdapter.STATE_TURNING_ON) {
            ParcelUuid[] adapterUuids = convertStringToParcelUuid(uuids);

            if (mAdapterUuids != null &&
                    BluetoothUuid.containsAllUuids(adapterUuids, mAdapterUuids)) {
                setBluetoothState(BluetoothAdapter.STATE_ON);
                String[] propVal = {"Pairable", getProperty("Pairable")};
                mEventLoop.onPropertyChanged(propVal);
            }

                if (mIsAirplaneSensitive && isAirplaneModeOn() && !mIsAirplaneToggleable) {
                    disable(false);
                }

            }
        }
    }

@@ -1201,7 +1220,10 @@ public class BluetoothService extends IBluetooth.Stub {
        mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        String value =  getProperty("UUIDs");
        if (value == null) return null;
        return convertStringToParcelUuid(value);
    }

    private synchronized ParcelUuid[] convertStringToParcelUuid(String value) {
        String[] uuidStrings = null;
        // The UUIDs are stored as a "," separated string.
        uuidStrings = value.split(",");
@@ -1211,7 +1233,6 @@ public class BluetoothService extends IBluetooth.Stub {
            uuids[i] = ParcelUuid.fromString(uuidStrings[i]);
        }
        return uuids;

    }