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

Commit 8de609c8 authored by pramod kotreshappa's avatar pramod kotreshappa Committed by Linux Build Service Account
Browse files

A2DP: Notify soft handoff triggered status to audio manager

-BT stack call back A2DP SM to notify when soft handoff is triggered.
A2DP SM will notify the audio manger to reconfigure the encoder
session in DSP.
-Read offload codec capabilities support property to initialize
split a2dp configuration.Disable multicast in split a2dp mode

Change-Id: I8872dda28205e3065cd0aef9d0a9f43804f4fb83
parent c3389bda
Loading
Loading
Loading
Loading
+28 −3
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ static jmethodID method_onConnectionStateChanged;
static jmethodID method_onAudioStateChanged;
static jmethodID method_onCheckConnectionPriority;
static jmethodID method_onMulticastStateChanged;
static jmethodID method_onReconfigA2dpTriggered;

static const btav_interface_t *sBluetoothA2dpInterface = NULL;
static jobject mCallbacksObj = NULL;
@@ -133,6 +134,22 @@ static void bta2dp_multicast_enabled_callback(int state) {
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
}

static void bta2dp_reconfig_a2dp_trigger_callback(int reason, bt_bdaddr_t* bd_addr) {
    jbyteArray addr;
    ALOGI("%s",__FUNCTION__);

    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
    if (!addr) {
        ALOGE("Fail to new jbyteArray bd addr for connection state");
        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
        return;
    }

    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReconfigA2dpTriggered, reason, addr);
    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
    sCallbackEnv->DeleteLocalRef(addr);
}
static btav_callbacks_t sBluetoothA2dpCallbacks = {
    sizeof(sBluetoothA2dpCallbacks),
    bta2dp_connection_state_callback,
@@ -140,6 +157,7 @@ static btav_callbacks_t sBluetoothA2dpCallbacks = {
    NULL,
    bta2dp_connection_priority_callback,
    bta2dp_multicast_enabled_callback,
    bta2dp_reconfig_a2dp_trigger_callback
};

static void classInitNative(JNIEnv* env, jclass clazz) {
@@ -154,14 +172,20 @@ static void classInitNative(JNIEnv* env, jclass clazz) {

    method_onMulticastStateChanged =
        env->GetMethodID(clazz, "onMulticastStateChanged", "(I)V");

    method_onReconfigA2dpTriggered =
        env->GetMethodID(clazz, "onReconfigA2dpTriggered", "(I[B)V");
    ALOGI("%s: succeeds", __FUNCTION__);
}

static void initNative(JNIEnv *env, jobject object, jint maxA2dpConnections,
        jint multiCastState) {
        jint multiCastState, jstring offload_cap) {
    const bt_interface_t* btInf;
    const char *offload_capabilities;
    bt_status_t status;

    offload_capabilities = env->GetStringUTFChars(offload_cap, NULL);

    if ( (btInf = getBluetoothInterface()) == NULL) {
        ALOGE("Bluetooth module is not loaded");
        return;
@@ -186,7 +210,8 @@ static void initNative(JNIEnv *env, jobject object, jint maxA2dpConnections,
    }

    if ( (status = sBluetoothA2dpInterface->init(&sBluetoothA2dpCallbacks,
            maxA2dpConnections, multiCastState)) != BT_STATUS_SUCCESS) {
            maxA2dpConnections, multiCastState,
            offload_capabilities)) != BT_STATUS_SUCCESS) {
        ALOGE("Failed to initialize Bluetooth A2DP, status: %d", status);
        sBluetoothA2dpInterface = NULL;
        return;
@@ -276,7 +301,7 @@ static void allowConnectionNative(JNIEnv *env, jobject object, int is_valid, jby

static JNINativeMethod sMethods[] = {
    {"classInitNative", "()V", (void *) classInitNative},
    {"initNative", "(II)V", (void *) initNative},
    {"initNative", "(IILjava/lang/String;)V", (void *) initNative},
    {"cleanupNative", "()V", (void *) cleanupNative},
    {"connectA2dpNative", "([B)Z", (void *) connectA2dpNative},
    {"disconnectA2dpNative", "([B)Z", (void *) disconnectA2dpNative},
+1 −1
Original line number Diff line number Diff line
@@ -168,7 +168,7 @@ static void initNative(JNIEnv *env, jobject object, jint maxA2dpConnections,
    }

    if ( (status = sBluetoothA2dpInterface->init(&sBluetoothA2dpCallbacks,
            maxA2dpConnections, multiCastState)) != BT_STATUS_SUCCESS) {
            maxA2dpConnections, multiCastState, NULL)) != BT_STATUS_SUCCESS) {
        ALOGE("Failed to initialize Bluetooth A2DP Sink, status: %d", status);
        sBluetoothA2dpInterface = NULL;
        return;
+7 −1
Original line number Diff line number Diff line
@@ -73,6 +73,12 @@ public class A2dpService extends ProfileService {
                SystemProperties.getInt("persist.bt.max.a2dp.connections", 1);
        int a2dpMultiCastState =
                SystemProperties.getInt("persist.bt.enable.multicast", 0);
        String offload_cap =
                SystemProperties.get("persist.bt.a2dp_offload_cap", null);
        if (offload_cap != null && a2dpMultiCastState == 1) {
            Log.i(TAG,"Split a2dp mode is enabled, disabling multicast");
            a2dpMultiCastState = 0;
        }
        if (a2dpMultiCastState == 1)
                multiCastState = a2dpMultiCastState;
        if (maxA2dpConnection == 2)
@@ -85,7 +91,7 @@ public class A2dpService extends ProfileService {
        log( "maxA2dpConnections = " + maxConnections);
        log( "multiCastState = " + multiCastState);
        mStateMachine = A2dpStateMachine.make(this, this,
                maxConnections, multiCastState);
                maxConnections, multiCastState, offload_cap);
        setA2dpService(this);
        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        mAvrcp = Avrcp.make(this, this, maxConnections);
+52 −5
Original line number Diff line number Diff line
@@ -148,7 +148,7 @@ final class A2dpStateMachine extends StateMachine {
    }

    private A2dpStateMachine(A2dpService svc, Context context, int
            maxConnections, int multiCastState) {
            maxConnections, int multiCastState, String offload_cap) {
        super("A2dpStateMachine");
        mService = svc;
        mContext = context;
@@ -162,7 +162,7 @@ final class A2dpStateMachine extends StateMachine {
            isMultiCastFeatureEnabled = false;
        }

        initNative(maxA2dpConnections, multiCastState);
        initNative(maxA2dpConnections, multiCastState, offload_cap);

        mDisconnected = new Disconnected();
        mPending = new Pending();
@@ -187,10 +187,10 @@ final class A2dpStateMachine extends StateMachine {
    }

    static A2dpStateMachine make(A2dpService svc, Context context,
             int maxConnections, int multiCastState) {
             int maxConnections, int multiCastState, String offload_cap) {
        Log.d("A2dpStateMachine", "make");
        A2dpStateMachine a2dpSm = new A2dpStateMachine(svc, context,
                 maxConnections, multiCastState);
                 maxConnections, multiCastState, offload_cap);
        a2dpSm.start();
        return a2dpSm;
    }
@@ -804,6 +804,9 @@ final class A2dpStateMachine extends StateMachine {
                        case EVENT_TYPE_AUDIO_STATE_CHANGED:
                            processAudioStateEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_RECONFIGURE_A2DP:
                            processReconfigA2dp(event.valueInt, event.device);
                            break;
                        default:
                            loge("Unexpected stack event: " + event.type);
                            break;
@@ -1085,6 +1088,17 @@ final class A2dpStateMachine extends StateMachine {
                  break;
            }
        }
        private void processReconfigA2dp(int state, BluetoothDevice device){
            log("processReconfigA2dp state" + state);
            switch (state) {
                case SOFT_HANDOFF:
                    broadcastReconfigureA2dp(device);
                    break;
                default:
                    loge("Unknown reconfigure state");
                    break;
            }
        }
    }
    /* Add MultiConnectionPending state when atleast 1 HS is connected
        and disconnect/connect is initiated for new HS */
@@ -1143,6 +1157,9 @@ final class A2dpStateMachine extends StateMachine {
                        case EVENT_TYPE_AUDIO_STATE_CHANGED:
                            processAudioStateEvent(event.valueInt, event.device);
                            break;
                        case EVENT_TYPE_RECONFIGURE_A2DP:
                            processReconfigA2dp(event.valueInt, event.device);
                            break;
                        default:
                            loge("Unexpected stack event: " + event.type);
                            break;
@@ -1476,6 +1493,18 @@ final class A2dpStateMachine extends StateMachine {
            }
        }

        private void processReconfigA2dp(int state, BluetoothDevice device){
            log("processReconfigA2dp state" + state);
            switch (state) {
                case SOFT_HANDOFF:
                    broadcastReconfigureA2dp(device);
                    break;
                default:
                    loge("Unknown reconfigure state");
                    break;
            }
        }

        private void processMultiA2dpDisconnected(BluetoothDevice device) {
            log("processMultiA2dpDisconnected state: processMultiA2dpDisconnected");

@@ -1672,6 +1701,11 @@ final class A2dpStateMachine extends StateMachine {
        log("A2DP Playing state : device: " + device + " State:" + prevState + "->" + state);
    }

    private void broadcastReconfigureA2dp(BluetoothDevice device) {
        log("broadcastReconfigureA2dp");
        mAudioManager.setParameters("reconfigA2dp=true");
    }

    private byte[] getByteAddress(BluetoothDevice device) {
        return Utils.getBytesFromAddress(device.getAddress());
    }
@@ -1712,6 +1746,15 @@ final class A2dpStateMachine extends StateMachine {
        }
    }

    private void onReconfigA2dpTriggered(int reason, byte[] address) {
        BluetoothDevice device = getDevice(address);
        Log.i(TAG,"onSoftHandoffTriggered to device " + device);
        StackEvent event = new StackEvent(EVENT_TYPE_RECONFIGURE_A2DP);
        event.valueInt = reason;//SOFT_HANDOFF;
        event.device = device;
        sendMessage(STACK_EVENT,event);
    }

    private BluetoothDevice getDevice(byte[] address) {
        return mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address));
    }
@@ -1762,6 +1805,10 @@ final class A2dpStateMachine extends StateMachine {
    final private static int EVENT_TYPE_NONE = 0;
    final private static int EVENT_TYPE_CONNECTION_STATE_CHANGED = 1;
    final private static int EVENT_TYPE_AUDIO_STATE_CHANGED = 2;
    final private static int EVENT_TYPE_RECONFIGURE_A2DP = 3;

    // Reason to Reconfig A2dp
    final private static int SOFT_HANDOFF = 1;

   // Do not modify without updating the HAL bt_av.h files.

@@ -1778,7 +1825,7 @@ final class A2dpStateMachine extends StateMachine {

    private native static void classInitNative();
    private native void initNative(int maxA2dpConnectionsAllowed,
            int multiCastState);
            int multiCastState, String offload_cap);
    private native void cleanupNative();
    private native boolean connectA2dpNative(byte[] address);
    private native boolean disconnectA2dpNative(byte[] address);