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

Commit 7aa16ed0 authored by Łukasz Rymanowski's avatar Łukasz Rymanowski
Browse files

leaudio: Synchronize TBS and LeAudio

With this path, TBS notifies LeAudio if there is any call in any state.
With this information, LeAudio code can take better choices beased on
content type in the metadata update"

Bug: 232902624
Test: atest BluetoothInstrumentationTests
Tag: #feature
Change-Id: I13b2bea1cd8299584f950e3ff3374ee2f4be5edb
parent b5de90c4
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -532,6 +532,16 @@ static void setCcidInformationNative(JNIEnv* env, jobject object, jint ccid,
  sLeAudioClientInterface->SetCcidInformation(ccid, contextType);
}

static void setInCallNative(JNIEnv* env, jobject object, jboolean inCall) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sLeAudioClientInterface) {
    LOG(ERROR) << __func__ << ": Failed to get the Bluetooth LeAudio Interface";
    return;
  }

  sLeAudioClientInterface->SetInCall(inCall);
}

static JNINativeMethod sMethods[] = {
    {"classInitNative", "()V", (void*)classInitNative},
    {"initNative", "([Landroid/bluetooth/BluetoothLeAudioCodecConfig;)V",
@@ -547,6 +557,7 @@ static JNINativeMethod sMethods[] = {
     "BluetoothLeAudioCodecConfig;)V",
     (void*)setCodecConfigPreferenceNative},
    {"setCcidInformationNative", "(II)V", (void*)setCcidInformationNative},
    {"setInCallNative", "(Z)V", (void*)setInCallNative},
};

/* Le Audio Broadcaster */
+12 −0
Original line number Diff line number Diff line
@@ -287,6 +287,17 @@ public class LeAudioNativeInterface {
        setCcidInformationNative(ccid, contextType);
    }

    /**
     * Set in call call flag.
     * @param inCall true when device in call (any state), false otherwise
     */
    public void setInCall(boolean inCall) {
        if (DBG) {
            Log.d(TAG, "setInCall inCall: " + inCall);
        }
        setInCallNative(inCall);
    }

    // Native methods that call into the JNI interface
    private static native void classInitNative();
    private native void initNative(BluetoothLeAudioCodecConfig[] codecConfigOffloading);
@@ -300,4 +311,5 @@ public class LeAudioNativeInterface {
            BluetoothLeAudioCodecConfig inputCodecConfig,
            BluetoothLeAudioCodecConfig outputCodecConfig);
    private native void setCcidInformationNative(int ccid, int contextType);
    private native void setInCallNative(boolean inCall);
}
+31 −0
Original line number Diff line number Diff line
@@ -1710,6 +1710,18 @@ public class LeAudioService extends ProfileService {
                BluetoothLeAudio.AUDIO_LOCATION_INVALID);
    }

    /**
     * Set In Call state
     * @param inCall True if device in call (any state), false otherwise.
     */
    public void setInCall(boolean inCall) {
        if (!mLeAudioNativeIsInitialized) {
            Log.e(TAG, "Le Audio not initialized properly.");
            return;
        }
        mLeAudioNativeInterface.setInCall(inCall);
    }

    /**
     * Set connection policy of the profile and connects it if connectionPolicy is
     * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is
@@ -2401,6 +2413,25 @@ public class LeAudioService extends ProfileService {
            }
        }

        @Override
        public void setInCall(boolean inCall, AttributionSource source,
                SynchronousResultReceiver receiver) {
            try {
                Objects.requireNonNull(source, "source cannot be null");
                Objects.requireNonNull(receiver, "receiver cannot be null");

                LeAudioService service = getService(source);
                if (service == null) {
                    throw new IllegalStateException("service is null");
                }
                enforceBluetoothPrivilegedPermission(service);
                service.setInCall(inCall);
                receiver.send(null);
            } catch (RuntimeException e) {
                receiver.propagateException(e);
            }
        }

        @Override
        public void groupRemoveNode(int groupId, BluetoothDevice device,
                AttributionSource source, SynchronousResultReceiver receiver) {
+27 −0
Original line number Diff line number Diff line
@@ -32,7 +32,9 @@ import android.os.ParcelUuid;
import android.os.RemoteException;
import android.util.Log;

import com.android.bluetooth.btservice.ServiceFactory;
import com.android.bluetooth.le_audio.ContentControlIdKeeper;
import com.android.bluetooth.le_audio.LeAudioService;

import java.util.ArrayList;
import java.util.Arrays;
@@ -122,6 +124,8 @@ public class TbsGeneric {
    private List<String> mUriSchemes = new ArrayList<>(Arrays.asList("tel"));
    private Receiver mReceiver = null;
    private int mStoredRingerMode = -1;
    private final ServiceFactory mFactory = new ServiceFactory();
    private LeAudioService mLeAudioService;

    private final class Receiver extends BroadcastReceiver {
        @Override
@@ -1005,10 +1009,33 @@ public class TbsGeneric {
        mForegroundBearer = bearer;
    }

    private boolean isLeAudioServiceAvailable() {
        if (mLeAudioService != null) {
            return true;
        }

        mLeAudioService = mFactory.getLeAudioService();
        if (mLeAudioService == null) {
            Log.e(TAG, "leAudioService not available");
            return false;
        }

        return true;
    }

    private synchronized void notifyCclc() {
        if (DBG) {
            Log.d(TAG, "notifyCclc");
        }

        if (isLeAudioServiceAvailable()) {
            if (mCurrentCallsList.size() > 0) {
                mLeAudioService.setInCall(true);
            } else {
                mLeAudioService.setInCall(false);
            }
        }

        mTbsGatt.setCallState(mCurrentCallsList);
        mTbsGatt.setBearerListCurrentCalls(mCurrentCallsList);
    }
+2 −0
Original line number Diff line number Diff line
@@ -65,6 +65,8 @@ oneway interface IBluetoothLeAudio {
    void unregisterCallback(in IBluetoothLeAudioCallback callback, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
    void setCcidInformation(in ParcelUuid userUuid, in int ccid, in int contextType, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
    void setInCall(in boolean inCall, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);

    /* Same value as bluetooth::groups::kGroupUnknown */
    const int LE_AUDIO_GROUP_ID_INVALID = -1;
Loading