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

Commit fccf0eba authored by Pavlin Radoslavov's avatar Pavlin Radoslavov Committed by Gerrit Code Review
Browse files

Merge "Added internal API to get/set the A2DP Active Device"

parents 170d63fe 88439fc6
Loading
Loading
Loading
Loading
+60 −0
Original line number Original line Diff line number Diff line
@@ -278,6 +278,48 @@ public class A2dpService extends ProfileService {
        return mStateMachine.getConnectionState(device);
        return mStateMachine.getConnectionState(device);
    }
    }


    /**
     * Set the active device.
     *
     * @param device the active device
     * @return true on success, otherwise false
     */
    public boolean setActiveDevice(BluetoothDevice device) {
        if (DBG) {
            Log.d(TAG, "setActiveDevice(): " + device);
        }

        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");

        if (getPriority(device) == BluetoothProfile.PRIORITY_OFF) {
            return false;
        }
        ParcelUuid[] featureUuids = device.getUuids();
        if ((BluetoothUuid.containsAnyUuid(featureUuids, A2DP_SOURCE_UUID))
                && !(BluetoothUuid.containsAllUuids(featureUuids, A2DP_SOURCE_SINK_UUIDS))) {
            Log.e(TAG, "Remote does not have A2dp Sink UUID");
            return false;
        }

        int connectionState = mStateMachine.getConnectionState(device);
        if (connectionState != BluetoothProfile.STATE_CONNECTED) {
            return false;
        }

        mStateMachine.sendMessage(A2dpStateMachine.SET_ACTIVE_DEVICE, device);
        return true;
    }

    /**
     * Get the active device.
     *
     * @return the active device or null if no device is active
     */
    public BluetoothDevice getActiveDevice() {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        return mStateMachine.getActiveDevice();
    }

    public boolean setPriority(BluetoothDevice device, int priority) {
    public boolean setPriority(BluetoothDevice device, int priority) {
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission");
        enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission");
        Settings.Global.putInt(getContentResolver(),
        Settings.Global.putInt(getContentResolver(),
@@ -472,6 +514,24 @@ public class A2dpService extends ProfileService {
            return service.getConnectionState(device);
            return service.getConnectionState(device);
        }
        }


        @Override
        public boolean setActiveDevice(BluetoothDevice device) {
            A2dpService service = getService();
            if (service == null) {
                return false;
            }
            return service.setActiveDevice(device);
        }

        @Override
        public BluetoothDevice getActiveDevice() {
            A2dpService service = getService();
            if (service == null) {
                return null;
            }
            return service.getActiveDevice();
        }

        @Override
        @Override
        public boolean setPriority(BluetoothDevice device, int priority) {
        public boolean setPriority(BluetoothDevice device, int priority) {
            A2dpService service = getService();
            A2dpService service = getService();
+60 −2
Original line number Original line Diff line number Diff line
@@ -63,6 +63,7 @@ final class A2dpStateMachine extends StateMachine {


    static final int CONNECT = 1;
    static final int CONNECT = 1;
    static final int DISCONNECT = 2;
    static final int DISCONNECT = 2;
    static final int SET_ACTIVE_DEVICE = 3;
    @VisibleForTesting
    @VisibleForTesting
    static final int STACK_EVENT = 101;
    static final int STACK_EVENT = 101;
    private static final int CONNECT_TIMEOUT = 201;
    private static final int CONNECT_TIMEOUT = 201;
@@ -82,6 +83,8 @@ final class A2dpStateMachine extends StateMachine {
    private final AudioManager mAudioManager;
    private final AudioManager mAudioManager;
    private BluetoothCodecConfig[] mCodecConfigPriorities;
    private BluetoothCodecConfig[] mCodecConfigPriorities;


    // mActiveDevice is the connected device that is connected and selected
    //     as active.
    // mCurrentDevice is the device connected before the state changes
    // mCurrentDevice is the device connected before the state changes
    // mTargetDevice is the device to be connected
    // mTargetDevice is the device to be connected
    // mIncomingDevice is the device connecting to us, valid only in Pending state
    // mIncomingDevice is the device connecting to us, valid only in Pending state
@@ -104,6 +107,7 @@ final class A2dpStateMachine extends StateMachine {
    //                        mCurrentDevice is not null, mTargetDevice is null
    //                        mCurrentDevice is not null, mTargetDevice is null
    //   Incoming connections Pending
    //   Incoming connections Pending
    //                        Both mCurrentDevice and mTargetDevice are null
    //                        Both mCurrentDevice and mTargetDevice are null
    private BluetoothDevice mActiveDevice = null;
    private BluetoothDevice mCurrentDevice = null;
    private BluetoothDevice mCurrentDevice = null;
    private BluetoothDevice mTargetDevice = null;
    private BluetoothDevice mTargetDevice = null;
    private BluetoothDevice mIncomingDevice = null;
    private BluetoothDevice mIncomingDevice = null;
@@ -277,12 +281,15 @@ final class A2dpStateMachine extends StateMachine {
            if (DBG) {
            if (DBG) {
                Log.d(TAG, "Disconnected process message: " + message.what);
                Log.d(TAG, "Disconnected process message: " + message.what);
            }
            }
            if (mCurrentDevice != null || mTargetDevice != null || mIncomingDevice != null) {
            if (mCurrentDevice != null || mTargetDevice != null
                    || mIncomingDevice != null || mActiveDevice != null) {
                Log.e(TAG, "ERROR: not null state in Disconnected: current = " + mCurrentDevice
                Log.e(TAG, "ERROR: not null state in Disconnected: current = " + mCurrentDevice
                        + " target = " + mTargetDevice + " incoming = " + mIncomingDevice);
                        + " target = " + mTargetDevice + " incoming = " + mIncomingDevice
                        + " active = " + mActiveDevice);
                mCurrentDevice = null;
                mCurrentDevice = null;
                mTargetDevice = null;
                mTargetDevice = null;
                mIncomingDevice = null;
                mIncomingDevice = null;
                mActiveDevice = null;
            }
            }


            boolean retValue = HANDLED;
            boolean retValue = HANDLED;
@@ -309,6 +316,13 @@ final class A2dpStateMachine extends StateMachine {
                case DISCONNECT:
                case DISCONNECT:
                    // ignore
                    // ignore
                    break;
                    break;
                case SET_ACTIVE_DEVICE:
                    BluetoothDevice activeDevice = (BluetoothDevice) message.obj;
                    // Cannot set the active device: not connected
                    Log.e(TAG, "Disconnected: Cannot set active device to "
                            + activeDevice);
                    broadcastActiveDevice(null);
                    break;
                case STACK_EVENT:
                case STACK_EVENT:
                    A2dpStackEvent event = (A2dpStackEvent) message.obj;
                    A2dpStackEvent event = (A2dpStackEvent) message.obj;
                    if (DBG) {
                    if (DBG) {
@@ -439,6 +453,13 @@ final class A2dpStateMachine extends StateMachine {
                        deferMessage(message);
                        deferMessage(message);
                    }
                    }
                    break;
                    break;
                case SET_ACTIVE_DEVICE:
                    BluetoothDevice activeDevice = (BluetoothDevice) message.obj;
                    // Cannot set the active device: not connected
                    Log.e(TAG, "Pending: Cannot set active device to "
                            + activeDevice);
                    broadcastActiveDevice(null);
                    break;
                case STACK_EVENT:
                case STACK_EVENT:
                    A2dpStackEvent event = (A2dpStackEvent) message.obj;
                    A2dpStackEvent event = (A2dpStackEvent) message.obj;
                    if (DBG) {
                    if (DBG) {
@@ -704,6 +725,21 @@ final class A2dpStateMachine extends StateMachine {
                    }
                    }
                }
                }
                break;
                break;
                case SET_ACTIVE_DEVICE: {
                    BluetoothDevice device = (BluetoothDevice) message.obj;
                    if (!mCurrentDevice.equals(device)) {
                        Log.e(TAG, "Connected: Cannot set active device to "
                                + device + " : current connected device is " + mCurrentDevice);
                        mActiveDevice = null;
                    } else {
                        if (DBG) {
                            Log.d(TAG, "Connected: Active device set to " + device);
                        }
                        mActiveDevice = device;
                    }
                    broadcastActiveDevice(mActiveDevice);
                }
                break;
                case CONNECT_TIMEOUT:
                case CONNECT_TIMEOUT:
                    if (mTargetDevice == null) {
                    if (mTargetDevice == null) {
                        Log.e(TAG, "CONNECT_TIMEOUT received for unknown device");
                        Log.e(TAG, "CONNECT_TIMEOUT received for unknown device");
@@ -844,6 +880,15 @@ final class A2dpStateMachine extends StateMachine {
        return devices;
        return devices;
    }
    }


    BluetoothDevice getActiveDevice() {
        synchronized (this) {
            if (getCurrentState() == mConnected) {
                return mActiveDevice;
            }
        }
        return null;
    }

    boolean isPlaying(BluetoothDevice device) {
    boolean isPlaying(BluetoothDevice device) {
        synchronized (this) {
        synchronized (this) {
            if (device.equals(mPlayingA2dpDevice)) {
            if (device.equals(mPlayingA2dpDevice)) {
@@ -997,6 +1042,18 @@ final class A2dpStateMachine extends StateMachine {
        mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
        mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
    }
    }


    private void broadcastActiveDevice(BluetoothDevice device) {
        if (DBG) {
            Log.d(TAG, "Active device: " + device);
        }

        Intent intent = new Intent(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                        | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
        mService.sendBroadcast(intent, ProfileService.BLUETOOTH_PERM);
    }

    private void broadcastAudioState(BluetoothDevice device, int newState,
    private void broadcastAudioState(BluetoothDevice device, int newState,
                                     int prevState) {
                                     int prevState) {
        if (DBG) {
        if (DBG) {
@@ -1013,6 +1070,7 @@ final class A2dpStateMachine extends StateMachine {
    }
    }


    public void dump(StringBuilder sb) {
    public void dump(StringBuilder sb) {
        ProfileService.println(sb, "mActiveDevice: " + mActiveDevice);
        ProfileService.println(sb, "mCurrentDevice: " + mCurrentDevice);
        ProfileService.println(sb, "mCurrentDevice: " + mCurrentDevice);
        ProfileService.println(sb, "mTargetDevice: " + mTargetDevice);
        ProfileService.println(sb, "mTargetDevice: " + mTargetDevice);
        ProfileService.println(sb, "mIncomingDevice: " + mIncomingDevice);
        ProfileService.println(sb, "mIncomingDevice: " + mIncomingDevice);