[Bluetooth] Android Framework BluetoothA2dpService

来源:互联网 发布:网络使人更亲近的例子 编辑:程序博客网 时间:2024/06/07 08:36

android_server_BluetoothA2dpService.cpp


回调函数:

DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env) {    DBusError err;    if (!nat) {        ALOGV("... skipping %s\n", __FUNCTION__);        ALOGV("... ignored\n");        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;    }       dbus_error_init(&err);    if (dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_SIGNAL) {        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;    }       DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;    if (dbus_message_is_signal(msg, "org.bluez.AudioSink",                                      "PropertyChanged")) {        jobjectArray str_array =                    parse_property_change(env, msg, (Properties *)&sink_properties,                                sizeof(sink_properties) / sizeof(Properties));        const char *c_path = dbus_message_get_path(msg);        jstring path = env->NewStringUTF(c_path);        env->CallVoidMethod(nat->me,                            method_onSinkPropertyChanged,                            path,                            str_array);        env->DeleteLocalRef(path);        result = DBUS_HANDLER_RESULT_HANDLED;        return result;    } else if (dbus_message_is_signal(msg, "org.bluez.Control",                                      "GetPlayStatus")) {

frameworks/base/core/java/android/server/BluetoothA2dpService.java

    /**     * Called by native code on a PropertyChanged signal from     * org.bluez.AudioSink.     *     * @param path the object path for the changed device     * @param propValues a string array containing the key and one or more     *  values.     */    private synchronized void onSinkPropertyChanged(String path, String[] propValues) {        if (!mBluetoothService.isEnabled()) {            return;        }        String name = propValues[0];        String address = mBluetoothService.getAddressFromObjectPath(path);        if (address == null) {            Log.e(TAG, "onSinkPropertyChanged: Address of the remote device in null");            return;        }        BluetoothDevice device = mAdapter.getRemoteDevice(address);        if (name.equals(PROPERTY_STATE)) {            int state = convertBluezSinkStringToState(propValues[1]);            log("A2DP: onSinkPropertyChanged newState is: " + state + "mPlayingA2dpDevice: " + mPlayingA2dpDevice);            if (mAudioDevices.get(device) == null) {                // This is for an incoming connection for a device not known to us.                // We have authorized it and bluez state has changed.                addAudioSink(device);                handleSinkStateChange(device, BluetoothA2dp.STATE_DISCONNECTED, state);            } else {                if (state == BluetoothA2dp.STATE_PLAYING && mPlayingA2dpDevice == null) {                    if (tmgr.getCallState() == TelephonyManager.CALL_STATE_IDLE) {                        mPlayingA2dpDevice = device;                        handleSinkPlayingStateChange(device, state, BluetoothA2dp.STATE_NOT_PLAYING);                    } else {                       log("suspend Sink");                       // During call active a2dp device is in suspended state                       // so audio will not be routed to A2dp. To avoid IOP                       // issues send a SUSPEND on A2dp if remote device asks                       // for PLAY during call active state.                       suspendSinkNative(mBluetoothService.getObjectPathFromAddress(                                device.getAddress()));                    }                } else if (state == BluetoothA2dp.STATE_CONNECTED && mPlayingA2dpDevice != null) {                    mPlayingA2dpDevice = null;                    handleSinkPlayingStateChange(device, BluetoothA2dp.STATE_NOT_PLAYING,                        BluetoothA2dp.STATE_PLAYING);                } else {                   mPlayingA2dpDevice = null;                   int prevState = mAudioDevices.get(device);                   handleSinkStateChange(device, prevState, state);                }            }        }    }

    private void handleSinkPlayingStateChange(BluetoothDevice device, int state, int prevState) {        Intent intent = new Intent(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED);        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);        intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);        intent.putExtra(BluetoothProfile.EXTRA_STATE, state);        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);        mContext.sendBroadcast(intent, BLUETOOTH_PERM);        if (DBG) log("A2DP Playing state : device: " + device + " State:" + prevState + "->" + state);    }    
handleSinkPlayingStateChange() 会发送一个ACTION_PLAYING_STATE_CHANGED的Intent,会被BluetoothService收到。


原创粉丝点击