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

Commit abc3642d authored by Matthew Xie's avatar Matthew Xie
Browse files

Set service priority of A2DP and Headset from BluetoothService via IPC call

We used to do the priority change in the 2 services after the broadcasted
intent reach them. But that left a small time gap that could reject
incoming connection due to undefined priorities.

Bug 4096186

Change-Id: I9bb6aedc7ed98c53a9b00c48eedd20b0cf5f1660
parent 8d9f9953
Loading
Loading
Loading
Loading
+0 −14
Original line number Original line Diff line number Diff line
@@ -83,19 +83,6 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
                    onBluetoothDisable();
                    onBluetoothDisable();
                    break;
                    break;
                }
                }
            } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
                int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
                                                   BluetoothDevice.ERROR);
                switch(bondState) {
                case BluetoothDevice.BOND_BONDED:
                    if (getPriority(device) == BluetoothA2dp.PRIORITY_UNDEFINED) {
                        setPriority(device, BluetoothA2dp.PRIORITY_ON);
                    }
                    break;
                case BluetoothDevice.BOND_NONE:
                    setPriority(device, BluetoothA2dp.PRIORITY_UNDEFINED);
                    break;
                }
            } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
            } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
                synchronized (this) {
                synchronized (this) {
                    if (mAudioDevices.containsKey(device)) {
                    if (mAudioDevices.containsKey(device)) {
@@ -158,7 +145,6 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mAdapter = BluetoothAdapter.getDefaultAdapter();


        mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        mIntentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        mIntentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        mIntentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        mIntentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        mIntentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        mIntentFilter.addAction(AudioManager.VOLUME_CHANGED_ACTION);
        mIntentFilter.addAction(AudioManager.VOLUME_CHANGED_ACTION);
+82 −4
Original line number Original line Diff line number Diff line
@@ -18,6 +18,9 @@ package android.server;


import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothHeadset;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.util.Log;
import android.util.Log;
@@ -68,6 +71,8 @@ class BluetoothBondState {
    private final Context mContext;
    private final Context mContext;
    private final BluetoothService mService;
    private final BluetoothService mService;
    private final BluetoothInputProfileHandler mBluetoothInputProfileHandler;
    private final BluetoothInputProfileHandler mBluetoothInputProfileHandler;
    private BluetoothA2dp mA2dpProxy;
    private BluetoothHeadset mHeadsetProxy;


    BluetoothBondState(Context context, BluetoothService service) {
    BluetoothBondState(Context context, BluetoothService service) {
        mContext = context;
        mContext = context;
@@ -126,14 +131,15 @@ class BluetoothBondState {


        if (state == BluetoothDevice.BOND_BONDED) {
        if (state == BluetoothDevice.BOND_BONDED) {
            mService.addProfileState(address);
            mService.addProfileState(address);
        } else if (state == BluetoothDevice.BOND_BONDING) {
            if (mA2dpProxy == null || mHeadsetProxy == null) {
                getProfileProxy();
            }
        } else if (state == BluetoothDevice.BOND_NONE) {
        } else if (state == BluetoothDevice.BOND_NONE) {
            mService.removeProfileState(address);
            mService.removeProfileState(address);
        }
        }


        // HID is handled by BluetoothService, other profiles
        setProfilePriorities(address, state);
        // will be handled by their respective services.
        mBluetoothInputProfileHandler.setInitialInputDevicePriority(
            mService.getRemoteDevice(address), state);


        if (DBG) {
        if (DBG) {
            Log.d(TAG, address + " bond state " + oldState + " -> " + state
            Log.d(TAG, address + " bond state " + oldState + " -> " + state
@@ -261,6 +267,52 @@ class BluetoothBondState {
        mPinAttempt.put(address, new Integer(newAttempt));
        mPinAttempt.put(address, new Integer(newAttempt));
    }
    }


    private void getProfileProxy() {
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        if (mA2dpProxy == null) {
            bluetoothAdapter.getProfileProxy(mContext, mProfileServiceListener,
                                             BluetoothProfile.A2DP);
        }

        if (mHeadsetProxy == null) {
            bluetoothAdapter.getProfileProxy(mContext, mProfileServiceListener,
                                             BluetoothProfile.HEADSET);
        }
    }

    private void closeProfileProxy() {
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        if (mA2dpProxy != null) {
            bluetoothAdapter.closeProfileProxy(BluetoothProfile.A2DP, mA2dpProxy);
        }

        if (mHeadsetProxy != null) {
            bluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetProxy);
        }
    }

    private BluetoothProfile.ServiceListener mProfileServiceListener =
        new BluetoothProfile.ServiceListener() {

        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            if (profile == BluetoothProfile.A2DP) {
                mA2dpProxy = (BluetoothA2dp) proxy;
            } else if (profile == BluetoothProfile.HEADSET) {
                mHeadsetProxy = (BluetoothHeadset) proxy;
            }
        }

        public void onServiceDisconnected(int profile) {
            if (profile == BluetoothProfile.A2DP) {
                mA2dpProxy = null;
            } else if (profile == BluetoothProfile.HEADSET) {
                mHeadsetProxy = null;
            }
        }
    };

    private void copyAutoPairingData() {
    private void copyAutoPairingData() {
        FileInputStream in = null;
        FileInputStream in = null;
        FileOutputStream out = null;
        FileOutputStream out = null;
@@ -365,4 +417,30 @@ class BluetoothBondState {
            }
            }
        }
        }
    }
    }

    // Set service priority of Hid, A2DP and Headset profiles depending on
    // the bond state change
    private void setProfilePriorities(String address, int state) {
        BluetoothDevice remoteDevice = mService.getRemoteDevice(address);
        // HID is handled by BluetoothService
        mBluetoothInputProfileHandler.setInitialInputDevicePriority(remoteDevice, state);

        // Set service priority of A2DP and Headset
        // We used to do the priority change in the 2 services after the broadcast
        //   intent reach them. But that left a small time gap that could reject
        //   incoming connection due to undefined priorities.
        if (state == BluetoothDevice.BOND_BONDED) {
            if (mA2dpProxy.getPriority(remoteDevice) == BluetoothProfile.PRIORITY_UNDEFINED) {
                mA2dpProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_ON);
            }

            if (mHeadsetProxy.getPriority(remoteDevice) == BluetoothProfile.PRIORITY_UNDEFINED) {
                mHeadsetProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_ON);
            }
        } else if (state == BluetoothDevice.BOND_NONE) {
            mA2dpProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_UNDEFINED);
            mHeadsetProxy.setPriority(remoteDevice, BluetoothProfile.PRIORITY_UNDEFINED);
        }
    }

}
}