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

Commit 0b53f5e2 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes from topic "parse_audio_config_for_le_device"

* changes:
  Rename function codecConfigOffloading() to getCodecConfigOffloading()
  Parse audio config codec capability for LE devices
parents cd3427d6 6392adde
Loading
Loading
Loading
Loading
+62 −3
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@
#include "com_android_bluetooth.h"
#include "hardware/bt_le_audio.h"

using bluetooth::le_audio::btle_audio_codec_config_t;
using bluetooth::le_audio::btle_audio_codec_index_t;
using bluetooth::le_audio::ConnectionState;
using bluetooth::le_audio::GroupNodeStatus;
using bluetooth::le_audio::GroupStatus;
@@ -39,6 +41,12 @@ static jmethodID method_onGroupStatus;
static jmethodID method_onGroupNodeStatus;
static jmethodID method_onAudioConf;

static struct {
  jclass clazz;
  jmethodID constructor;
  jmethodID getCodecType;
} android_bluetooth_BluetoothLeAudioCodecConfig;

static LeAudioClientInterface* sLeAudioClientInterface = nullptr;
static std::shared_timed_mutex interface_mutex;

@@ -121,6 +129,13 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks {
static LeAudioClientCallbacksImpl sLeAudioClientCallbacks;

static void classInitNative(JNIEnv* env, jclass clazz) {
  jclass jniBluetoothLeAudioCodecConfigClass =
      env->FindClass("android/bluetooth/BluetoothLeAudioCodecConfig");
  android_bluetooth_BluetoothLeAudioCodecConfig.constructor =
      env->GetMethodID(jniBluetoothLeAudioCodecConfigClass, "<init>", "(I)V");
  android_bluetooth_BluetoothLeAudioCodecConfig.getCodecType = env->GetMethodID(
      jniBluetoothLeAudioCodecConfigClass, "getCodecType", "()I");

  method_onGroupStatus = env->GetMethodID(clazz, "onGroupStatus", "(II)V");
  method_onGroupNodeStatus =
      env->GetMethodID(clazz, "onGroupNodeStatus", "([BII)V");
@@ -129,7 +144,34 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
      env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V");
}

static void initNative(JNIEnv* env, jobject object) {
std::vector<btle_audio_codec_config_t> prepareCodecPreferences(
    JNIEnv* env, jobject object, jobjectArray codecConfigArray) {
  std::vector<btle_audio_codec_config_t> codec_preferences;

  int numConfigs = env->GetArrayLength(codecConfigArray);
  for (int i = 0; i < numConfigs; i++) {
    jobject jcodecConfig = env->GetObjectArrayElement(codecConfigArray, i);
    if (jcodecConfig == nullptr) continue;
    if (!env->IsInstanceOf(
            jcodecConfig,
            android_bluetooth_BluetoothLeAudioCodecConfig.clazz)) {
      ALOGE("%s: Invalid BluetoothLeAudioCodecConfig instance", __func__);
      continue;
    }
    jint codecType = env->CallIntMethod(
        jcodecConfig,
        android_bluetooth_BluetoothLeAudioCodecConfig.getCodecType);

    btle_audio_codec_config_t codec_config = {
        .codec_type = static_cast<btle_audio_codec_index_t>(codecType)};

    codec_preferences.push_back(codec_config);
  }
  return codec_preferences;
}

static void initNative(JNIEnv* env, jobject object,
                       jobjectArray codecOffloadingArray) {
  std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
  std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex);

@@ -150,6 +192,15 @@ static void initNative(JNIEnv* env, jobject object) {
    return;
  }

  android_bluetooth_BluetoothLeAudioCodecConfig.clazz =
      (jclass)env->NewGlobalRef(
          env->FindClass("android/bluetooth/BluetoothLeAudioCodecConfig"));
  if (android_bluetooth_BluetoothLeAudioCodecConfig.clazz == nullptr) {
    LOG(ERROR) << "Failed to allocate Global Ref for "
                  "BluetoothLeAudioCodecConfig class";
    return;
  }

  sLeAudioClientInterface =
      (LeAudioClientInterface*)btInf->get_profile_interface(
          BT_PROFILE_LE_AUDIO_ID);
@@ -158,7 +209,11 @@ static void initNative(JNIEnv* env, jobject object) {
    return;
  }

  sLeAudioClientInterface->Initialize(&sLeAudioClientCallbacks);
  std::vector<btle_audio_codec_config_t> codec_offloading =
      prepareCodecPreferences(env, object, codecOffloadingArray);

  sLeAudioClientInterface->Initialize(&sLeAudioClientCallbacks,
                                      codec_offloading);
}

static void cleanupNative(JNIEnv* env, jobject object) {
@@ -176,6 +231,9 @@ static void cleanupNative(JNIEnv* env, jobject object) {
    sLeAudioClientInterface = nullptr;
  }

  env->DeleteGlobalRef(android_bluetooth_BluetoothLeAudioCodecConfig.clazz);
  android_bluetooth_BluetoothLeAudioCodecConfig.clazz = nullptr;

  if (mCallbacksObj != nullptr) {
    env->DeleteGlobalRef(mCallbacksObj);
    mCallbacksObj = nullptr;
@@ -272,7 +330,8 @@ static void groupSetActiveNative(JNIEnv* env, jobject object, jint group_id) {

static JNINativeMethod sMethods[] = {
    {"classInitNative", "()V", (void*)classInitNative},
    {"initNative", "()V", (void*)initNative},
    {"initNative", "([Landroid/bluetooth/BluetoothLeAudioCodecConfig;)V",
     (void*)initNative},
    {"cleanupNative", "()V", (void*)cleanupNative},
    {"connectLeAudioNative", "([B)Z", (void*)connectLeAudioNative},
    {"disconnectLeAudioNative", "([B)Z", (void*)disconnectLeAudioNative},
+2 −1
Original line number Diff line number Diff line
@@ -64,7 +64,8 @@ class A2dpCodecConfig {
          Log.w(TAG, "Can't obtain the codec offloading prefernece from null AudioManager");
          return;
        }
        mCodecConfigOffloading = audioManager.getHwOffloadEncodingFormatsSupportedForA2DP()
        mCodecConfigOffloading = audioManager.getHwOffloadFormatsSupportedForBluetoothMedia(
                                                    AudioManager.DEVICE_OUT_BLUETOOTH_A2DP)
                                             .toArray(mCodecConfigOffloading);
    }

+62 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.bluetooth.le_audio;

import android.bluetooth.BluetoothLeAudioCodecConfig;
import android.content.Context;
import android.media.AudioManager;
import android.util.Log;
/*
 * LeAudio Codec Configuration setup.
 */
class LeAudioCodecConfig {
    private static final boolean DBG = true;
    private static final String TAG = "LeAudioCodecConfig";

    private Context mContext;
    private BluetoothLeAudioCodecConfig[] mCodecConfigOffloading =
            new BluetoothLeAudioCodecConfig[0];

    LeAudioCodecConfig(Context context) {
        Log.i(TAG, "LeAudioCodecConfig init");
        mContext = context;

        AudioManager audioManager = mContext.getSystemService(AudioManager.class);
        if (audioManager == null) {
            Log.w(TAG, "Can't obtain the codec offloading prefernece from null AudioManager");
            return;
        }

        mCodecConfigOffloading = audioManager.getHwOffloadFormatsSupportedForBluetoothMedia(
                                                    AudioManager.DEVICE_OUT_BLE_HEADSET)
                                             .toArray(mCodecConfigOffloading);

        if (DBG) {
            Log.i(TAG, "mCodecConfigOffloading size for le -> " + mCodecConfigOffloading.length);

            for (int idx = 0; idx < mCodecConfigOffloading.length; idx++) {
                Log.i(TAG, String.format("mCodecConfigOffloading[%d] -> %s",
                        idx, mCodecConfigOffloading[idx].toString()));
            }
        }
    }

    BluetoothLeAudioCodecConfig[] getCodecConfigOffloading() {
        return mCodecConfigOffloading;
    }
}
+4 −3
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ package com.android.bluetooth.le_audio;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeAudioCodecConfig;
import android.util.Log;

import com.android.bluetooth.Utils;
@@ -145,8 +146,8 @@ public class LeAudioNativeInterface {
     *
     * priorities to configure.
     */
    public void init() {
        initNative();
    public void init(BluetoothLeAudioCodecConfig[] codecConfigOffloading) {
        initNative(codecConfigOffloading);
    }

    /**
@@ -204,7 +205,7 @@ public class LeAudioNativeInterface {

    // Native methods that call into the JNI interface
    private static native void classInitNative();
    private native void initNative();
    private native void initNative(BluetoothLeAudioCodecConfig[] codecConfigOffloading);
    private native void cleanupNative();
    private native boolean connectLeAudioNative(byte[] address);
    private native boolean disconnectLeAudioNative(byte[] address);
+5 −1
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ public class LeAudioService extends ProfileService {
    private HandlerThread mStateMachinesThread;
    private BluetoothDevice mActiveAudioOutDevice;
    private BluetoothDevice mActiveAudioInDevice;
    private LeAudioCodecConfig mLeAudioCodecConfig;
    ServiceFactory mServiceFactory = new ServiceFactory();

    LeAudioNativeInterface mLeAudioNativeInterface;
@@ -215,7 +216,10 @@ public class LeAudioService extends ProfileService {
        // Mark service as started
        setLeAudioService(this);

        mLeAudioNativeInterface.init();
        // Setup codec config
        mLeAudioCodecConfig = new LeAudioCodecConfig(this);

        mLeAudioNativeInterface.init(mLeAudioCodecConfig.getCodecConfigOffloading());

        return true;
    }
Loading