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

Commit 1cb7ac54 authored by Sal Savage's avatar Sal Savage
Browse files

Expose SCO control and state through Telecom APIs

This change allows others to move to formal Telecom APIs from hidden
BluetoothHeadsetClient APIs for SCO control and status.

Tag: #refactor
Bug: 157948464
Test: atest BluetoothInstrumentationTests
Change-Id: I2cd059f2cf8bdca2f23711c339be777492bfc3ad
parent 0d98563f
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.bluetooth.BluetoothHeadsetClient;
import android.bluetooth.BluetoothHeadsetClientCall;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.telecom.Connection;
import android.telecom.DisconnectCause;
import android.telecom.PhoneAccount;
@@ -32,6 +33,11 @@ public class HfpClientConnection extends Connection {
    private static final String TAG = "HfpClientConnection";
    private static final boolean DBG = false;

    private static final String KEY_SCO_STATE = "com.android.bluetooth.hfpclient.SCO_STATE";
    private static final String EVENT_SCO_CONNECT = "com.android.bluetooth.hfpclient.SCO_CONNECT";
    private static final String EVENT_SCO_DISCONNECT =
             "com.android.bluetooth.hfpclient.SCO_DISCONNECT";

    private final Context mContext;
    private final BluetoothDevice mDevice;
    private BluetoothHeadsetClient mHeadsetProfile;
@@ -58,6 +64,7 @@ public class HfpClientConnection extends Connection {
        }

        mCurrentCall = call;
        setScoState(BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED);
        handleCallChanged();
        finishInitializing();
    }
@@ -277,6 +284,34 @@ public class HfpClientConnection extends Connection {
        }
    }

    @Override
    public void onCallEvent(String event, Bundle extras) {
        if (DBG) {
            Log.d(TAG, "onCallEvent(" + event + ", " + extras + ")");
        }
        switch (event) {
            case EVENT_SCO_CONNECT:
                mHeadsetProfile.connectAudio(mDevice);
                break;
            case EVENT_SCO_DISCONNECT:
                mHeadsetProfile.disconnectAudio(mDevice);
                break;
        }
    }

    /**
     * Notify this connection of changes in the SCO state so we can update our call details
     */
    public void onScoStateChanged(int newState, int oldState) {
        setScoState(newState);
    }

    private void setScoState(int state) {
        Bundle bundle = new Bundle();
        bundle.putInt(KEY_SCO_STATE, state);
        setExtras(bundle);
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof HfpClientConnection)) {
+13 −0
Original line number Diff line number Diff line
@@ -110,6 +110,18 @@ public class HfpClientConnectionService extends ConnectionService {
                // the calls should
                // be added (see ACTION_CONNECTION_STATE_CHANGED intent above).
                block.handleCall(call);
            } else if (BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE,
                        BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED);
                int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
                        BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED);
                HfpClientDeviceBlock block = findBlockForDevice(device);
                if (block == null) {
                    Log.w(TAG, "Device audio state changed but no block for device");
                    return;
                }
                block.onAudioStateChange(newState, oldState);
            }
        }
    };
@@ -172,6 +184,7 @@ public class HfpClientConnectionService extends ConnectionService {
        } else {
            IntentFilter filter = new IntentFilter();
            filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
            filter.addAction(BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED);
            filter.addAction(BluetoothHeadsetClient.ACTION_CALL_CHANGED);
            registerReceiver(mBroadcastReceiver, filter);
            return START_STICKY;
+9 −0
Original line number Diff line number Diff line
@@ -106,6 +106,15 @@ public class HfpClientDeviceBlock {
        return connection;
    }

    synchronized void onAudioStateChange(int newState, int oldState) {
        if (DBG) {
            Log.d(mTAG, "Call audio state changed " + oldState + " -> " + newState);
        }
        for (HfpClientConnection connection : mConnections.values()) {
            connection.onScoStateChanged(newState, oldState);
        }
    }

    synchronized HfpClientConnection onCreateUnknownConnection(BluetoothHeadsetClientCall call) {
        Uri number = Uri.fromParts(PhoneAccount.SCHEME_TEL, call.getNumber(), null);
        HfpClientConnection connection = mConnections.get(call.getUUID());