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

Commit bd022f42 authored by Nick Pelly's avatar Nick Pelly
Browse files

Bluetooth: API change.

Split BluetoothDevice into BluetoothDevice and BluetoothAdapter.

BluetoothAdapter: Represents the local BT adapter. Operations on the local
                  adapter (start a scan, etc).
BluetoothDevice: Represents a remote BT device. Operations on remote devices
                 (pair, connect, etc).

IBluetoothDevice.aidl -> Bluetooth.aidl
BluetoothDeviceService.java -> BluetoothDeviceService.java

TODO:
Javadoc
parent 82e7408b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -88,8 +88,8 @@ LOCAL_SRC_FILES += \
	core/java/android/backup/IBackupManager.aidl \
	core/java/android/backup/IRestoreObserver.aidl \
	core/java/android/backup/IRestoreSession.aidl \
	core/java/android/bluetooth/IBluetooth.aidl \
	core/java/android/bluetooth/IBluetoothA2dp.aidl \
	core/java/android/bluetooth/IBluetoothDevice.aidl \
	core/java/android/bluetooth/IBluetoothHeadset.aidl \
	core/java/android/bluetooth/IBluetoothPbap.aidl \
	core/java/android/content/IContentService.aidl \
+12 −17
Original line number Diff line number Diff line
@@ -22,8 +22,8 @@ import com.google.android.collect.Maps;

import org.xmlpull.v1.XmlPullParserException;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.IBluetoothDevice;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetooth;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -158,8 +158,6 @@ class ApplicationContext extends Context {
    private static ConnectivityManager sConnectivityManager;
    private static WifiManager sWifiManager;
    private static LocationManager sLocationManager;
    private static boolean sIsBluetoothDeviceCached = false;
    private static BluetoothDevice sBluetoothDevice;
    private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =
            new HashMap<File, SharedPreferencesImpl>();

@@ -184,6 +182,8 @@ class ApplicationContext extends Context {
    private StatusBarManager mStatusBarManager = null;
    private TelephonyManager mTelephonyManager = null;
    private ClipboardManager mClipboardManager = null;
    private boolean mIsBluetoothAdapterCached = false;
    private BluetoothAdapter mBluetoothAdapter;
    private boolean mRestricted;

    private final Object mSync = new Object();
@@ -830,7 +830,7 @@ class ApplicationContext extends Context {
        } else if (SENSOR_SERVICE.equals(name)) {
            return getSensorManager();
        } else if (BLUETOOTH_SERVICE.equals(name)) {
            return getBluetoothDevice();
            return getBluetoothAdapter();
        } else if (VIBRATOR_SERVICE.equals(name)) {
            return getVibrator();
        } else if (STATUS_BAR_SERVICE.equals(name)) {
@@ -980,21 +980,16 @@ class ApplicationContext extends Context {
        return mSearchManager;
    }

    private BluetoothDevice getBluetoothDevice() {
        if (sIsBluetoothDeviceCached) {
            return sBluetoothDevice;
        }
        synchronized (sSync) {
    private synchronized BluetoothAdapter getBluetoothAdapter() {
        if (!mIsBluetoothAdapterCached) {
            mIsBluetoothAdapterCached = true;
            IBinder b = ServiceManager.getService(BLUETOOTH_SERVICE);
            if (b == null) {
                sBluetoothDevice = null;
            } else {
                IBluetoothDevice service = IBluetoothDevice.Stub.asInterface(b);
                sBluetoothDevice = new BluetoothDevice(service);
            if (b != null) {
                IBluetooth service = IBluetooth.Stub.asInterface(b);
                mBluetoothAdapter = new BluetoothAdapter(service);
            }
            sIsBluetoothDeviceCached = true;
        }
        return sBluetoothDevice;
        return mBluetoothAdapter;
    }

    private SensorManager getSensorManager() {
+36 −30
Original line number Diff line number Diff line
@@ -25,7 +25,10 @@ import android.os.RemoteException;
import android.os.IBinder;
import android.util.Log;

import java.util.List;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.HashSet;

/**
 * Public API for controlling the Bluetooth A2DP Profile Service.
@@ -47,7 +50,7 @@ import java.util.List;
 *
 * @hide
 */
public class BluetoothA2dp {
public final class BluetoothA2dp {
    private static final String TAG = "BluetoothA2dp";
    private static final boolean DBG = false;

@@ -79,6 +82,7 @@ public class BluetoothA2dp {
    /** Default priority for a2dp devices that should not allow incoming
     * connections */
    public static final int PRIORITY_OFF = 0;

    private final IBluetoothA2dp mService;
    private final Context mContext;

@@ -89,6 +93,7 @@ public class BluetoothA2dp {
     */
    public BluetoothA2dp(Context c) {
        mContext = c;

        IBinder b = ServiceManager.getService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE);
        if (b == null) {
            throw new RuntimeException("Bluetooth A2DP service not available!");
@@ -99,14 +104,14 @@ public class BluetoothA2dp {
    /** Initiate a connection to an A2DP sink.
     *  Listen for SINK_STATE_CHANGED_ACTION to find out when the
     *  connection is completed.
     *  @param address Remote BT address.
     *  @param device Remote BT device.
     *  @return Result code, negative indicates an immediate error.
     *  @hide
     */
    public int connectSink(String address) {
        if (DBG) log("connectSink(" + address + ")");
    public int connectSink(BluetoothDevice device) {
        if (DBG) log("connectSink(" + device + ")");
        try {
            return mService.connectSink(address);
            return mService.connectSink(device);
        } catch (RemoteException e) {
            Log.w(TAG, "", e);
            return BluetoothError.ERROR_IPC;
@@ -116,14 +121,14 @@ public class BluetoothA2dp {
    /** Initiate disconnect from an A2DP sink.
     *  Listen for SINK_STATE_CHANGED_ACTION to find out when
     *  disconnect is completed.
     *  @param address Remote BT address.
     *  @param device Remote BT device.
     *  @return Result code, negative indicates an immediate error.
     *  @hide
     */
    public int disconnectSink(String address) {
        if (DBG) log("disconnectSink(" + address + ")");
    public int disconnectSink(BluetoothDevice device) {
        if (DBG) log("disconnectSink(" + device + ")");
        try {
            return mService.disconnectSink(address);
            return mService.disconnectSink(device);
        } catch (RemoteException e) {
            Log.w(TAG, "", e);
            return BluetoothError.ERROR_IPC;
@@ -131,24 +136,25 @@ public class BluetoothA2dp {
    }

    /** Check if a specified A2DP sink is connected.
     *  @param address Remote BT address.
     *  @param device Remote BT device.
     *  @return True if connected (or playing), false otherwise and on error.
     *  @hide
     */
    public boolean isSinkConnected(String address) {
        if (DBG) log("isSinkConnected(" + address + ")");
        int state = getSinkState(address);
    public boolean isSinkConnected(BluetoothDevice device) {
        if (DBG) log("isSinkConnected(" + device + ")");
        int state = getSinkState(device);
        return state == STATE_CONNECTED || state == STATE_PLAYING;
    }

    /** Check if any A2DP sink is connected.
     * @return a List of connected A2DP sinks, or null on error.
     * @return a unmodifiable set of connected A2DP sinks, or null on error.
     * @hide
     */
    public List<String> listConnectedSinks() {
        if (DBG) log("listConnectedSinks()");
    public Set<BluetoothDevice> getConnectedSinks() {
        if (DBG) log("getConnectedSinks()");
        try {
            return mService.listConnectedSinks();
            return Collections.unmodifiableSet(
                    new HashSet<BluetoothDevice>(Arrays.asList(mService.getConnectedSinks())));
        } catch (RemoteException e) {
            Log.w(TAG, "", e);
            return null;
@@ -156,14 +162,14 @@ public class BluetoothA2dp {
    }

    /** Get the state of an A2DP sink
     *  @param address Remote BT address.
     *  @param device Remote BT device.
     *  @return State code, or negative on error
     *  @hide
     */
    public int getSinkState(String address) {
        if (DBG) log("getSinkState(" + address + ")");
    public int getSinkState(BluetoothDevice device) {
        if (DBG) log("getSinkState(" + device + ")");
        try {
            return mService.getSinkState(address);
            return mService.getSinkState(device);
        } catch (RemoteException e) {
            Log.w(TAG, "", e);
            return BluetoothError.ERROR_IPC;
@@ -177,15 +183,15 @@ public class BluetoothA2dp {
     * Sinks with priority greater than zero will accept incoming connections
     * (if no sink is currently connected).
     * Priority for unpaired sink must be PRIORITY_NONE.
     * @param address Paired sink
     * @param device Paired sink
     * @param priority Integer priority, for example PRIORITY_AUTO or
     *                 PRIORITY_NONE
     * @return Result code, negative indicates an error
     */
    public int setSinkPriority(String address, int priority) {
        if (DBG) log("setSinkPriority(" + address + ", " + priority + ")");
    public int setSinkPriority(BluetoothDevice device, int priority) {
        if (DBG) log("setSinkPriority(" + device + ", " + priority + ")");
        try {
            return mService.setSinkPriority(address, priority);
            return mService.setSinkPriority(device, priority);
        } catch (RemoteException e) {
            Log.w(TAG, "", e);
            return BluetoothError.ERROR_IPC;
@@ -194,13 +200,13 @@ public class BluetoothA2dp {

    /**
     * Get priority of a2dp sink.
     * @param address Sink
     * @param device Sink
     * @return non-negative priority, or negative error code on error.
     */
    public int getSinkPriority(String address) {
        if (DBG) log("getSinkPriority(" + address + ")");
    public int getSinkPriority(BluetoothDevice device) {
        if (DBG) log("getSinkPriority(" + device + ")");
        try {
            return mService.getSinkPriority(address);
            return mService.getSinkPriority(device);
        } catch (RemoteException e) {
            Log.w(TAG, "", e);
            return BluetoothError.ERROR_IPC;
+331 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2009 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 android.bluetooth;

import android.os.RemoteException;
import android.util.Log;

import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import java.util.HashSet;

/**
 * Represents the local Bluetooth adapter.
 *
 * @hide
 */
public final class BluetoothAdapter {
    private static final String TAG = "BluetoothAdapter";

    public static final int BLUETOOTH_STATE_OFF = 0;
    public static final int BLUETOOTH_STATE_TURNING_ON = 1;
    public static final int BLUETOOTH_STATE_ON = 2;
    public static final int BLUETOOTH_STATE_TURNING_OFF = 3;

    /** Inquiry scan and page scan are both off.
     *  Device is neither discoverable nor connectable */
    public static final int SCAN_MODE_NONE = 0;
    /** Page scan is on, inquiry scan is off.
     *  Device is connectable, but not discoverable */
    public static final int SCAN_MODE_CONNECTABLE = 1;
    /** Page scan and inquiry scan are on.
     *  Device is connectable and discoverable */
    public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 3;

    public static final int RESULT_FAILURE = -1;
    public static final int RESULT_SUCCESS = 0;

    /* The user will be prompted to enter a pin */
    public static final int PAIRING_VARIANT_PIN = 0;
    /* The user will be prompted to enter a passkey */
    public static final int PAIRING_VARIANT_PASSKEY = 1;
    /* The user will be prompted to confirm the passkey displayed on the screen */
    public static final int PAIRING_VARIANT_CONFIRMATION = 2;

    private final IBluetooth mService;

    /**
     * Do not use this constructor. Use Context.getSystemService() instead.
     * @hide
     */
    public BluetoothAdapter(IBluetooth service) {
        if (service == null) {
            throw new IllegalArgumentException("service is null");
        }
        mService = service;
    }

    /**
     * Get the remote BluetoothDevice associated with the given MAC address.
     * Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB".
     * @param address valid Bluetooth MAC address
     */
    public BluetoothDevice getRemoteDevice(String address) {
        return new BluetoothDevice(address);
    }

    /**
     * Is Bluetooth currently turned on.
     *
     * @return true if Bluetooth enabled, false otherwise.
     */
    public boolean isEnabled() {
        try {
            return mService.isEnabled();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    }

    /**
     * Get the current state of Bluetooth.
     *
     * @return One of BLUETOOTH_STATE_ or BluetoothError.ERROR.
     */
    public int getBluetoothState() {
        try {
            return mService.getBluetoothState();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return BluetoothError.ERROR;
    }

    /**
     * Enable the Bluetooth device.
     * Turn on the underlying hardware.
     * This is an asynchronous call,
     * BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION can be used to check if
     * and when the device is sucessfully enabled.
     * @return false if we cannot enable the Bluetooth device. True does not
     * imply the device was enabled, it only implies that so far there were no
     * problems.
     */
    public boolean enable() {
        try {
            return mService.enable();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    }

    /**
     * Disable the Bluetooth device.
     * This turns off the underlying hardware.
     *
     * @return true if successful, false otherwise.
     */
    public boolean disable() {
        try {
            return mService.disable(true);
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    }

    public String getAddress() {
        try {
            return mService.getAddress();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return null;
    }

    /**
     * Get the friendly Bluetooth name of this device.
     *
     * This name is visible to remote Bluetooth devices. Currently it is only
     * possible to retrieve the Bluetooth name when Bluetooth is enabled.
     *
     * @return the Bluetooth name, or null if there was a problem.
     */
    public String getName() {
        try {
            return mService.getName();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return null;
    }

    /**
     * Set the friendly Bluetooth name of this device.
     *
     * This name is visible to remote Bluetooth devices. The Bluetooth Service
     * is responsible for persisting this name.
     *
     * @param name the name to set
     * @return     true, if the name was successfully set. False otherwise.
     */
    public boolean setName(String name) {
        try {
            return mService.setName(name);
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    }

    /**
     * Get the current scan mode.
     * Used to determine if the local device is connectable and/or discoverable
     * @return Scan mode, one of SCAN_MODE_* or an error code
     */
    public int getScanMode() {
        try {
            return mService.getScanMode();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return BluetoothError.ERROR_IPC;
    }

    /**
     * Set the current scan mode.
     * Used to make the local device connectable and/or discoverable
     * @param scanMode One of SCAN_MODE_*
     */
    public void setScanMode(int scanMode) {
        try {
            mService.setScanMode(scanMode);
        } catch (RemoteException e) {Log.e(TAG, "", e);}
    }

    public int getDiscoverableTimeout() {
        try {
            return mService.getDiscoverableTimeout();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return -1;
    }

    public void setDiscoverableTimeout(int timeout) {
        try {
            mService.setDiscoverableTimeout(timeout);
        } catch (RemoteException e) {Log.e(TAG, "", e);}
    }

    public boolean startDiscovery() {
        try {
            return mService.startDiscovery();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    }

    public void cancelDiscovery() {
        try {
            mService.cancelDiscovery();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
    }

    public boolean isDiscovering() {
        try {
            return mService.isDiscovering();
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
    }

    /**
     * List remote devices that are bonded (paired) to the local adapter.
     *
     * Bonding (pairing) is the process by which the user enters a pin code for
     * the device, which generates a shared link key, allowing for
     * authentication and encryption of future connections. In Android we
     * require bonding before RFCOMM or SCO connections can be made to a remote
     * device.
     *
     * This function lists which remote devices we have a link key for. It does
     * not cause any RF transmission, and does not check if the remote device
     * still has it's link key with us. If the other side no longer has its
     * link key then the RFCOMM or SCO connection attempt will result in an
     * error.
     *
     * This function does not check if the remote device is in range.
     *
     * Remote devices that have an in-progress bonding attempt are not
     * returned.
     *
     * @return unmodifiable set of bonded devices, or null on error
     */
    public Set<BluetoothDevice> getBondedDevices() {
        try {
            return toDeviceSet(mService.listBonds());
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return null;
    }

    /**
     * Construct a listening, secure RFCOMM server socket.
     * The remote device connecting to this socket will be authenticated and
     * communication on this socket will be encrypted.
     * Call #accept to retrieve connections to this socket.
     * @return An RFCOMM BluetoothServerSocket
     * @throws IOException On error, for example Bluetooth not available, or
     *                     insufficient permissions.
     */
    public BluetoothServerSocket listenUsingRfcommOn(int port) throws IOException {
        BluetoothServerSocket socket = new BluetoothServerSocket(
                BluetoothSocket.TYPE_RFCOMM, true, true, port);
        try {
            socket.mSocket.bindListenNative();
        } catch (IOException e) {
            try {
                socket.close();
            } catch (IOException e2) { }
            throw e;
        }
        return socket;
    }

    /**
     * Construct an unencrypted, unauthenticated, RFCOMM server socket.
     * Call #accept to retrieve connections to this socket.
     * @return An RFCOMM BluetoothServerSocket
     * @throws IOException On error, for example Bluetooth not available, or
     *                     insufficient permissions.
     */
    public BluetoothServerSocket listenUsingInsecureRfcommOn(int port) throws IOException {
        BluetoothServerSocket socket = new BluetoothServerSocket(
                BluetoothSocket.TYPE_RFCOMM, false, false, port);
        try {
            socket.mSocket.bindListenNative();
        } catch (IOException e) {
            try {
                socket.close();
            } catch (IOException e2) { }
            throw e;
        }
        return socket;
    }

    /**
     * Construct a SCO server socket.
     * Call #accept to retrieve connections to this socket.
     * @return A SCO BluetoothServerSocket
     * @throws IOException On error, for example Bluetooth not available, or
     *                     insufficient permissions.
     */
    public static BluetoothServerSocket listenUsingScoOn() throws IOException {
        BluetoothServerSocket socket = new BluetoothServerSocket(
                BluetoothSocket.TYPE_SCO, false, false, -1);
        try {
            socket.mSocket.bindListenNative();
        } catch (IOException e) {
            try {
                socket.close();
            } catch (IOException e2) { }
            throw e;
        }
        return socket;
    }

    private Set<BluetoothDevice> toDeviceSet(String[] addresses) {
        Set<BluetoothDevice> devices = new HashSet<BluetoothDevice>(addresses.length);
        for (int i = 0; i < addresses.length; i++) {
            devices.add(getRemoteDevice(addresses[i]));
        }
        return Collections.unmodifiableSet(devices);
    }
}
+28 −32
Original line number Diff line number Diff line
@@ -9,24 +9,22 @@ import android.util.Log;
/**
 * Listen's for incoming RFCOMM connection for the headset / handsfree service.
 *
 * This class is planned for deletion, in favor of a generic Rfcomm class.
 * TODO: Use the new generic BluetoothSocket class instead of this legacy code
 *
 * @hide
 */
public class BluetoothAudioGateway {
public final class BluetoothAudioGateway {
    private static final String TAG = "BT Audio Gateway";
    private static final boolean DBG = false;

    private int mNativeData;
    static { classInitNative(); }

    private BluetoothDevice mBluetooth;

    /* in */
    private int mHandsfreeAgRfcommChannel = -1;
    private int mHeadsetAgRfcommChannel   = -1;

    /* out */
    /* out - written by native code */
    private String mConnectingHeadsetAddress;
    private int mConnectingHeadsetRfcommChannel; /* -1 when not connected */
    private int mConnectingHeadsetSocketFd;
@@ -35,17 +33,18 @@ public class BluetoothAudioGateway {
    private int mConnectingHandsfreeSocketFd;
    private int mTimeoutRemainingMs; /* in/out */

    private final BluetoothAdapter mAdapter;

    public static final int DEFAULT_HF_AG_CHANNEL = 10;
    public static final int DEFAULT_HS_AG_CHANNEL = 11;

    public BluetoothAudioGateway(BluetoothDevice bluetooth) {
        this(bluetooth, DEFAULT_HF_AG_CHANNEL, DEFAULT_HS_AG_CHANNEL);
    public BluetoothAudioGateway(BluetoothAdapter adapter) {
        this(adapter, DEFAULT_HF_AG_CHANNEL, DEFAULT_HS_AG_CHANNEL);
    }

    public BluetoothAudioGateway(BluetoothDevice bluetooth,
                                 int handsfreeAgRfcommChannel,
    public BluetoothAudioGateway(BluetoothAdapter adapter, int handsfreeAgRfcommChannel,
                int headsetAgRfcommChannel) {
        mBluetooth = bluetooth;
        mAdapter = adapter;
        mHandsfreeAgRfcommChannel = handsfreeAgRfcommChannel;
        mHeadsetAgRfcommChannel = headsetAgRfcommChannel;
        initializeNativeDataNative();
@@ -58,18 +57,17 @@ public class BluetoothAudioGateway {
    private Handler mCallback;

    public class IncomingConnectionInfo {
        IncomingConnectionInfo(BluetoothDevice bluetooth, String address, int socketFd,
                               int rfcommChan) {
            mBluetooth = bluetooth;
            mAddress = address;
        public BluetoothAdapter mAdapter;
        public BluetoothDevice mRemoteDevice;
        public int mSocketFd;
        public int mRfcommChan;
        IncomingConnectionInfo(BluetoothAdapter adapter, BluetoothDevice remoteDevice,
                int socketFd, int rfcommChan) {
            mAdapter = adapter;
            mRemoteDevice = remoteDevice;
            mSocketFd = socketFd;
            mRfcommChan = rfcommChan;
        }

        public BluetoothDevice mBluetooth;
        public String mAddress;
        public int mSocketFd;
        public int mRfcommChan;
    }

    public static final int MSG_INCOMING_HEADSET_CONNECTION   = 100;
@@ -111,10 +109,9 @@ public class BluetoothAudioGateway {
                                          mConnectingHeadsetRfcommChannel);
                                    Message msg = Message.obtain(mCallback);
                                    msg.what = MSG_INCOMING_HEADSET_CONNECTION;
                                    msg.obj = 
                                        new IncomingConnectionInfo(
                                            mBluetooth, 
                                            mConnectingHeadsetAddress,
                                    msg.obj = new IncomingConnectionInfo(
                                        mAdapter,
                                        mAdapter.getRemoteDevice(mConnectingHeadsetAddress),
                                        mConnectingHeadsetSocketFd,
                                        mConnectingHeadsetRfcommChannel);
                                    msg.sendToTarget();
@@ -126,10 +123,9 @@ public class BluetoothAudioGateway {
                                    Message msg = Message.obtain();
                                    msg.setTarget(mCallback);
                                    msg.what = MSG_INCOMING_HANDSFREE_CONNECTION;
                                    msg.obj = 
                                        new IncomingConnectionInfo(
                                            mBluetooth,
                                            mConnectingHandsfreeAddress,
                                    msg.obj = new IncomingConnectionInfo(
                                        mAdapter,
                                        mAdapter.getRemoteDevice(mConnectingHandsfreeAddress),
                                        mConnectingHandsfreeSocketFd,
                                        mConnectingHandsfreeRfcommChannel);
                                    msg.sendToTarget();
Loading