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

Commit e37df32e authored by Pavlin Radoslavov's avatar Pavlin Radoslavov Committed by android-build-merger
Browse files

Merge "Update the A2DP Codec Config API" am: fd556cc7

am: ceb8ac80

Change-Id: I3e22d30a3c8057358ffc493239b6d1a156b0ef68
parents 52b4407c ceb8ac80
Loading
Loading
Loading
Loading
+69 −8
Original line number Diff line number Diff line
@@ -30,6 +30,11 @@ static jmethodID method_onConnectionStateChanged;
static jmethodID method_onAudioStateChanged;
static jmethodID method_onCodecConfigChanged;

static struct {
  jclass clazz;
  jmethodID constructor;
} android_bluetooth_BluetoothCodecConfig;

static const btav_source_interface_t* sBluetoothA2dpInterface = NULL;
static jobject mCallbacksObj = NULL;

@@ -73,19 +78,58 @@ static void bta2dp_audio_state_callback(btav_audio_state_t state,

static void bta2dp_audio_config_callback(
    btav_a2dp_codec_config_t codec_config,
    std::vector<btav_a2dp_codec_config_t> codec_capabilities) {
    std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities,
    std::vector<btav_a2dp_codec_config_t> codecs_selectable_capabilities) {
  ALOGI("%s", __func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

  sCallbackEnv->CallVoidMethod(
      mCallbacksObj, method_onCodecConfigChanged, (jint)codec_config.codec_type,
      (jint)codec_config.codec_priority, (jint)codec_config.sample_rate,
      (jint)codec_config.bits_per_sample, (jint)codec_config.channel_mode,
      (jlong)codec_config.codec_specific_1,
  jobject codecConfigObj = sCallbackEnv->NewObject(
      android_bluetooth_BluetoothCodecConfig.clazz,
      android_bluetooth_BluetoothCodecConfig.constructor,
      (jint)codec_config.codec_type, (jint)codec_config.codec_priority,
      (jint)codec_config.sample_rate, (jint)codec_config.bits_per_sample,
      (jint)codec_config.channel_mode, (jlong)codec_config.codec_specific_1,
      (jlong)codec_config.codec_specific_2,
      (jlong)codec_config.codec_specific_3,
      (jlong)codec_config.codec_specific_4);

  jsize i = 0;
  jobjectArray local_capabilities_array = sCallbackEnv->NewObjectArray(
      (jsize)codecs_local_capabilities.size(),
      android_bluetooth_BluetoothCodecConfig.clazz, NULL);
  for (auto const& cap : codecs_local_capabilities) {
    jobject capObj = sCallbackEnv->NewObject(
        android_bluetooth_BluetoothCodecConfig.clazz,
        android_bluetooth_BluetoothCodecConfig.constructor,
        (jint)cap.codec_type, (jint)cap.codec_priority, (jint)cap.sample_rate,
        (jint)cap.bits_per_sample, (jint)cap.channel_mode,
        (jlong)cap.codec_specific_1, (jlong)cap.codec_specific_2,
        (jlong)cap.codec_specific_3, (jlong)cap.codec_specific_4);
    sCallbackEnv->SetObjectArrayElement(local_capabilities_array, i++, capObj);
    sCallbackEnv->DeleteLocalRef(capObj);
  }

  i = 0;
  jobjectArray selectable_capabilities_array = sCallbackEnv->NewObjectArray(
      (jsize)codecs_selectable_capabilities.size(),
      android_bluetooth_BluetoothCodecConfig.clazz, NULL);
  for (auto const& cap : codecs_selectable_capabilities) {
    jobject capObj = sCallbackEnv->NewObject(
        android_bluetooth_BluetoothCodecConfig.clazz,
        android_bluetooth_BluetoothCodecConfig.constructor,
        (jint)cap.codec_type, (jint)cap.codec_priority, (jint)cap.sample_rate,
        (jint)cap.bits_per_sample, (jint)cap.channel_mode,
        (jlong)cap.codec_specific_1, (jlong)cap.codec_specific_2,
        (jlong)cap.codec_specific_3, (jlong)cap.codec_specific_4);
    sCallbackEnv->SetObjectArrayElement(selectable_capabilities_array, i++,
                                        capObj);
    sCallbackEnv->DeleteLocalRef(capObj);
  }

  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onCodecConfigChanged,
                               codecConfigObj, local_capabilities_array,
                               selectable_capabilities_array);
}

static btav_source_callbacks_t sBluetoothA2dpCallbacks = {
@@ -94,14 +138,21 @@ static btav_source_callbacks_t sBluetoothA2dpCallbacks = {
};

static void classInitNative(JNIEnv* env, jclass clazz) {
  jclass jniBluetoothCodecConfigClass =
      env->FindClass("android/bluetooth/BluetoothCodecConfig");
  android_bluetooth_BluetoothCodecConfig.constructor =
      env->GetMethodID(jniBluetoothCodecConfigClass, "<init>", "(IIIIIJJJJ)V");

  method_onConnectionStateChanged =
      env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V");

  method_onAudioStateChanged =
      env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V");

  method_onCodecConfigChanged =
      env->GetMethodID(clazz, "onCodecConfigChanged", "(IIIIIJJJJ)V");
  method_onCodecConfigChanged = env->GetMethodID(
      clazz, "onCodecConfigChanged",
      "(Landroid/bluetooth/BluetoothCodecConfig;[Landroid/bluetooth/"
      "BluetoothCodecConfig;[Landroid/bluetooth/BluetoothCodecConfig;)V");

  ALOGI("%s: succeeds", __func__);
}
@@ -130,6 +181,13 @@ static void initNative(JNIEnv* env, jobject object) {
    return;
  }

  android_bluetooth_BluetoothCodecConfig.clazz = (jclass)env->NewGlobalRef(
      env->FindClass("android/bluetooth/BluetoothCodecConfig"));
  if (android_bluetooth_BluetoothCodecConfig.clazz == nullptr) {
    ALOGE("Failed to allocate Global Ref for BluetoothCodecConfig class");
    return;
  }

  sBluetoothA2dpInterface =
      (btav_source_interface_t*)btInf->get_profile_interface(
          BT_PROFILE_ADVANCED_AUDIO_ID);
@@ -158,6 +216,9 @@ static void cleanupNative(JNIEnv* env, jobject object) {
    sBluetoothA2dpInterface = NULL;
  }

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

  if (mCallbacksObj != NULL) {
    env->DeleteGlobalRef(mCallbacksObj);
    mCallbacksObj = NULL;
+6 −5
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.bluetooth.a2dp;

import android.bluetooth.BluetoothCodecConfig;
import android.bluetooth.BluetoothCodecStatus;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
@@ -224,10 +225,10 @@ public class A2dpService extends ProfileService {
        return mStateMachine.isPlaying(device);
    }

    public BluetoothCodecConfig getCodecConfig() {
    public BluetoothCodecStatus getCodecStatus() {
        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
        if (DBG) Log.d(TAG, "getCodecConfig()");
        return mStateMachine.getCodecConfig();
        if (DBG) Log.d(TAG, "getCodecStatus()");
        return mStateMachine.getCodecStatus();
    }

    public void setCodecConfigPreference(BluetoothCodecConfig codecConfig) {
@@ -328,10 +329,10 @@ public class A2dpService extends ProfileService {
            return service.isA2dpPlaying(device);
        }

        public BluetoothCodecConfig getCodecConfig() {
        public BluetoothCodecStatus getCodecStatus() {
            A2dpService service = getService();
            if (service == null) return null;
            return service.getCodecConfig();
            return service.getCodecStatus();
        }

        public void setCodecConfigPreference(BluetoothCodecConfig codecConfig) {
+21 −15
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ package com.android.bluetooth.a2dp;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothCodecConfig;
import android.bluetooth.BluetoothCodecStatus;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
@@ -103,7 +104,7 @@ final class A2dpStateMachine extends StateMachine {
    private BluetoothDevice mIncomingDevice = null;
    private BluetoothDevice mPlayingA2dpDevice = null;

    private BluetoothCodecConfig mCodecConfig = null;
    private BluetoothCodecStatus mCodecStatus = null;

    static {
        classInitNative();
@@ -654,30 +655,35 @@ final class A2dpStateMachine extends StateMachine {
        return false;
    }

    BluetoothCodecConfig getCodecConfig() {
    BluetoothCodecStatus getCodecStatus() {
        synchronized (this) {
            return mCodecConfig;
            return mCodecStatus;
        }
    }

    private void onCodecConfigChanged(int codecType, int codecPriority, int sampleRate,
            int bitsPerSample, int channelMode, long codecSpecific1, long codecSpecific2,
            long codecSpecific3, long codecSpecific4) {
        BluetoothCodecConfig prevCodecConfig;
        BluetoothCodecConfig newCodecConfig = new BluetoothCodecConfig(codecType, codecPriority,
                sampleRate, bitsPerSample, channelMode, codecSpecific1, codecSpecific2,
                codecSpecific3, codecSpecific4);
    private void onCodecConfigChanged(BluetoothCodecConfig newCodecConfig,
            BluetoothCodecConfig[] codecsLocalCapabilities,
            BluetoothCodecConfig[] codecsSelectableCapabilities) {
        BluetoothCodecConfig prevCodecConfig = null;
        synchronized (this) {
            prevCodecConfig = mCodecConfig;
            mCodecConfig = newCodecConfig;
            if (mCodecStatus != null) {
                prevCodecConfig = mCodecStatus.getCodecConfig();
            }
            mCodecStatus = new BluetoothCodecStatus(
                    newCodecConfig, codecsLocalCapabilities, codecsSelectableCapabilities);
        }

        Intent intent = new Intent(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED);
        intent.putExtra(BluetoothCodecConfig.EXTRA_CODEC_CONFIG, newCodecConfig);
        intent.putExtra(BluetoothCodecConfig.EXTRA_PREVIOUS_CODEC_CONFIG, prevCodecConfig);
        intent.putExtra(BluetoothCodecStatus.EXTRA_CODEC_STATUS, mCodecStatus);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);

        log("A2DP Codec Config: " + prevCodecConfig + "->" + newCodecConfig);
        for (BluetoothCodecConfig codecConfig : codecsLocalCapabilities) {
            log("A2DP Codec Local Capability: " + codecConfig);
        }
        for (BluetoothCodecConfig codecConfig : codecsSelectableCapabilities) {
            log("A2DP Codec Selectable Capability: " + codecConfig);
        }

        // Inform the Audio Service about the codec configuration change,
        // so the Audio Service can reset accordingly the audio feeding