Android Bluetooth源码分析总结 - framework部分


本篇主要包括如下内容:
1. 源码目录
2. 类图
3. use case举例

  • 蓝牙服务初始化
  • 打开蓝牙流程
  • 搜索蓝牙流程

4. 应用层开发总结


1,BT framework代码主要位于如下目录:

android/frameworks/base/core/java/android/bluetoothandroid/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.javaandroid/packages/apps/Bluetooth

2,class diagram如下图所示:

主要类设计意图说明如下(摘录源码):

  • BluetoothAdapter 
/** * Represents the local device Bluetooth adapter. The BluetoothAdapter * lets you perform fundamental Bluetooth tasks, such as initiate * device discovery, query a list of bonded (paired) devices, * instantiate a BluetoothDevice using a known MAC address, and create * a BluetoothServerSocket to listen for connection requests from other * devices, and start a scan for Bluetooth LE devices. * * To get a BluetoothAdapter representing the local Bluetooth * adapter, when running on JELLY_BEAN_MR1 and below, call the * static getDefaultAdapter method; when running on JELLY_BEAN_MR2 and * higher, retrieve it through * android.content.Context#getSystemService with * android.content.Context#BLUETOOTH_SERVICE. * Fundamentally, this is your starting point for all * Bluetooth actions. Once you have the local adapter, you can get a set of * BluetoothDevice objects representing all paired devices with * getBondedDevices(); start device discovery with * startDiscovery(); or create a BluetoothServerSocket to * listen for incoming connection requests with * listenUsingRfcommWithServiceRecord(String,UUID); or start a scan for * Bluetooth LE devices with startLeScan(LeScanCallback callback). * * Note: * Most methods require the android.Manifest.permission#BLUETOOTH * permission and some also require the * android.Manifest.permission#BLUETOOTH_ADMIN permission. * */public final class BluetoothAdapter {        ......}
  • BluetoothManagerService
class BluetoothManagerService extends IBluetoothManager.Stub {        ......}
/** * System private API for talking with the Bluetooth service. * * {@hide} */interface IBluetoothManager{    IBluetooth registerAdapter(in IBluetoothManagerCallback callback);    void unregisterAdapter(in IBluetoothManagerCallback callback);    void registerStateChangeCallback(in IBluetoothStateChangeCallback callback);    void unregisterStateChangeCallback(in IBluetoothStateChangeCallback callback);    boolean isEnabled();    boolean enable();    boolean enableNoAutoConnect();    boolean disable(boolean persist);    IBluetoothGatt getBluetoothGatt();    boolean bindBluetoothProfileService(int profile, IBluetoothProfileServiceConnection proxy);    void unbindBluetoothProfileService(int profile, IBluetoothProfileServiceConnection proxy);    String getAddress();    String getName();    boolean isBleScanAlwaysAvailable();    int updateBleAppCount(IBinder b, boolean enable);    boolean isBleAppPresent();}
  • IBluetooth
/** * System private API for talking with the Bluetooth service. * * {@hide} */interface IBluetooth{    boolean isEnabled();    int getState();    boolean enable();    boolean enableNoAutoConnect();    boolean disable();    String getAddress();    ParcelUuid[] getUuids();    boolean setName(in String name);    String getName();    int getScanMode();    boolean setScanMode(int mode, int duration);    int getDiscoverableTimeout();    boolean setDiscoverableTimeout(int timeout);    boolean startDiscovery();    boolean cancelDiscovery();    boolean isDiscovering();    int getAdapterConnectionState();    int getProfileConnectionState(int profile);    BluetoothDevice[] getBondedDevices();    boolean createBond(in BluetoothDevice device, in int transport);    boolean cancelBondProcess(in BluetoothDevice device);    boolean removeBond(in BluetoothDevice device);    int getBondState(in BluetoothDevice device);    int getConnectionState(in BluetoothDevice device); String getRemoteName(in BluetoothDevice device);    int getRemoteType(in BluetoothDevice device);    String getRemoteAlias(in BluetoothDevice device);    boolean setRemoteAlias(in BluetoothDevice device, in String name);    int getRemoteClass(in BluetoothDevice device);    ParcelUuid[] getRemoteUuids(in BluetoothDevice device);    boolean fetchRemoteUuids(in BluetoothDevice device);    boolean sdpSearch(in BluetoothDevice device, in ParcelUuid uuid);    boolean setPin(in BluetoothDevice device, boolean accept, int len, in byte[] pinCode);    boolean setPasskey(in BluetoothDevice device, boolean accept, int len, in byte[]    passkey);    boolean setPairingConfirmation(in BluetoothDevice device, boolean accept);    int getPhonebookAccessPermission(in BluetoothDevice device);    boolean setPhonebookAccessPermission(in BluetoothDevice device, int value);    int getMessageAccessPermission(in BluetoothDevice device);    boolean setMessageAccessPermission(in BluetoothDevice device, int value);    int getSimAccessPermission(in BluetoothDevice device);    boolean setSimAccessPermission(in BluetoothDevice device, int value);    void sendConnectionStateChange(in BluetoothDevice device, int profile, int state, int prevState);    void registerCallback(in IBluetoothCallback callback);    void unregisterCallback(in IBluetoothCallback callback);    // For Socket    ParcelFileDescriptor connectSocket(in BluetoothDevice device, int type, in ParcelUuid uuid, int port, int flag);    ParcelFileDescriptor createSocketChannel(int type, in String serviceName, in ParcelUuid uuid, int port, int flag);    boolean configHciSnoopLog(boolean enable);    boolean factoryReset();    boolean isMultiAdvertisementSupported();    boolean isPeripheralModeSupported();    boolean isOffloadedFilteringSupported();    boolean isOffloadedScanBatchingSupported();    boolean isActivityAndEnergyReportingSupported();    void getActivityEnergyInfoFromController();    BluetoothActivityEnergyInfo reportActivityInfo();    // For dumpsys support    void dump(in ParcelFileDescriptor fd);    void onLeServiceUp();    void onBrEdrDown();}

另外,IBluetooth的server端实现为AdapterService的内部类(位于android/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java),摘录如下:

    /**     * Handlers for incoming service calls     */    private AdapterServiceBinder mBinder;    /**     * The Binder implementation must be declared to be a static class, with     * the AdapterService instance passed in the constructor. Furthermore,     * when the AdapterService shuts down, the reference to the AdapterService     * must be explicitly removed.     *     * Otherwise, a memory leak can occur from repeated starting/stopping the     * service...Please refer to android.os.Binder for further details on     * why an inner instance class should be avoided.     *     */    private static class AdapterServiceBinder extends IBluetooth.Stub {                ......    }
  • BluetoothLeScanner
/** * This class provides methods to perform scan related operations for Bluetooth LE devices. An * application can scan for a particular type of Bluetooth LE devices using {@link ScanFilter}. It * can also request different types of callbacks for delivering the result. * 

* Use {@link BluetoothAdapter#getBluetoothLeScanner()} to get an instance of * {@link BluetoothLeScanner}. *

* Note: Most of the scan methods here require * {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission. * * @see ScanFilter */public final class BluetoothLeScanner { ......}

  • BluetoothLeAdvertiser
/** * This class provides a way to perform Bluetooth LE advertise operations, such as starting and * stopping advertising. An advertiser can broadcast up to 31 bytes of advertisement data * represented by {@link AdvertiseData}. * 

* To get an instance of {@link BluetoothLeAdvertiser}, call the * {@link BluetoothAdapter#getBluetoothLeAdvertiser()} method. *

* Note: Most of the methods here require {@link android.Manifest.permission#BLUETOOTH_ADMIN} * permission. * * @see AdvertiseData */public final class BluetoothLeAdvertiser { ......}

  • BluetoothProfile
/** * Public APIs for the Bluetooth Profiles. * * 

Clients should call {@link BluetoothAdapter#getProfileProxy}, * to get the Profile Proxy. Each public profile implements this * interface. */public interface BluetoothProfile { ......}

可以发现有一系列的应用层profile类存在,比如BluetoothA2dp,BluetoothA2dpSink、BluetoothGatt,BluetoothHeadset,BluetoothSap,BluetoothPan等等,上述图中没有罗列完全,而且这些类都继承自BluetoothProfile. (若是有新的profile添加,可以参考已存在profile进行相关实现。)另外,每个具体的profile类(比如BluetoothA2dp)都依赖于对应的service实现(对应于BluetoothA2dpService),而这些XXXProfileService就会依赖JNI,最终调用到HAL层。

3,序列图

3.1 蓝牙服务初始化

3.2 蓝牙打开流程

  • BluetoothEnabler->LocalBluetoothAdapter->BluetoothAdapter->BluetoothManagerService->IBluetooth.stub->AdapterService

各代码路径:

android/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothEnabler.javaandroid/frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.javaandroid/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.javaandroid/frameworks/base/services/core/java/com/android/server/BluetoothManagerService.javaandroid/frameworks/base/core/java/android/bluetooth/IBluetooth.aidlandroid/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
  • AdapterService->AdapterState->AdapterService->JNI->bluetooth.h

各代码路径及类说明:

android/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.javaandroid/packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterState.javaandroid/hardware/libhardware/include/hardware/bluetooth.h
/** * This state machine handles Bluetooth Adapter State. * States: *      {@link OnState} : Bluetooth is on at this state *      {@link OffState}: Bluetooth is off at this state. This is the initial *      state. *      {@link PendingCommandState} : An enable / disable operation is pending. * TODO(BT): Add per process on state. */final class AdapterState extends StateMachine {        ......}
/** * The Bluetooth Hardware Module ID */#define BT_HARDWARE_MODULE_ID "bluetooth"#define BT_STACK_MODULE_ID "bluetooth"#define BT_STACK_TEST_MODULE_ID "bluetooth_test"/* Bluetooth profile interface IDs */#define BT_PROFILE_HANDSFREE_ID "handsfree"#define BT_PROFILE_HANDSFREE_CLIENT_ID "handsfree_client"#define BT_PROFILE_ADVANCED_AUDIO_ID "a2dp"#define BT_PROFILE_ADVANCED_AUDIO_SINK_ID "a2dp_sink"#define BT_PROFILE_HEALTH_ID "health"#define BT_PROFILE_SOCKETS_ID "socket"#define BT_PROFILE_HIDHOST_ID "hidhost"#define BT_PROFILE_PAN_ID "pan"#define BT_PROFILE_MAP_CLIENT_ID "map_client"#define BT_PROFILE_SDP_CLIENT_ID "sdp"#define BT_PROFILE_GATT_ID "gatt"#define BT_PROFILE_AV_RC_ID "avrcp"#define BT_PROFILE_AV_RC_CTRL_ID "avrcp_ctrl"............/** NOTE: By default, no profiles are initialized at the time of init/enable. *  Whenever the application invokes the 'init' API of a profile, then one of *  the following shall occur: * *    1.) If Bluetooth is not enabled, then the Bluetooth core shall mark the *        profile as enabled. Subsequently, when the application invokes the *        Bluetooth 'enable', as part of the enable sequence the profile that were *        marked shall be enabled by calling appropriate stack APIs. The *        'adapter_properties_cb' shall return the list of UUIDs of the *        enabled profiles. * *    2.) If Bluetooth is enabled, then the Bluetooth core shall invoke the stack *        profile API to initialize the profile and trigger a *        'adapter_properties_cb' with the current list of UUIDs including the *        newly added profile's UUID. * *   The reverse shall occur whenever the profile 'cleanup' APIs are invoked *//** Represents the standard Bluetooth DM interface. */typedef struct {    /** set to sizeof(bt_interface_t) */    size_t size;    /**     * Opens the interface and provides the callback routines     * to the implemenation of this interface.     */    int (*init)(bt_callbacks_t* callbacks );    /** Enable Bluetooth. */    int (*enable)(void);    /** Disable Bluetooth. */    int (*disable)(void);    /** Closes the interface. */    void (*cleanup)(void);    /** Get all Bluetooth Adapter properties at init */    int (*get_adapter_properties)(void);    /** Get Bluetooth Adapter property of 'type' */    int (*get_adapter_property)(bt_property_type_t type);    /** Set Bluetooth Adapter property of 'type' */    /* Based on the type, val shall be one of     * bt_bdaddr_t or bt_bdname_t or bt_scanmode_t etc     */    int (*set_adapter_property)(const bt_property_t *property);    /** Get all Remote Device properties */    int (*get_remote_device_properties)(bt_bdaddr_t *remote_addr);    /** Get Remote Device property of 'type' */    int (*get_remote_device_property)(bt_bdaddr_t *remote_addr,                                      bt_property_type_t type);    /** Set Remote Device property of 'type' */    int (*set_remote_device_property)(bt_bdaddr_t *remote_addr,                                      const bt_property_t *property);    /** Get Remote Device's service record  for the given UUID */    int (*get_remote_service_record)(bt_bdaddr_t *remote_addr,                                     bt_uuid_t *uuid);    /** Start SDP to get remote services */    int (*get_remote_services)(bt_bdaddr_t *remote_addr);    /** Start Discovery */    int (*start_discovery)(void);    /** Cancel Discovery */    int (*cancel_discovery)(void);    /** Create Bluetooth Bonding */    int (*create_bond)(const bt_bdaddr_t *bd_addr, int transport);    /** Remove Bond */    int (*remove_bond)(const bt_bdaddr_t *bd_addr);    /** Cancel Bond */    int (*cancel_bond)(const bt_bdaddr_t *bd_addr);    /**     * Get the connection status for a given remote device.     * return value of 0 means the device is not connected,     * non-zero return status indicates an active connection.     */    int (*get_connection_state)(const bt_bdaddr_t *bd_addr);    /** BT Legacy PinKey Reply */    /** If accept==FALSE, then pin_len and pin_code shall be 0x0 */    int (*pin_reply)(const bt_bdaddr_t *bd_addr, uint8_t accept,                     uint8_t pin_len, bt_pin_code_t *pin_code);    /** BT SSP Reply - Just Works, Numeric Comparison and Passkey     * passkey shall be zero for BT_SSP_VARIANT_PASSKEY_COMPARISON &     * BT_SSP_VARIANT_CONSENT     * For BT_SSP_VARIANT_PASSKEY_ENTRY, if accept==FALSE, then passkey     * shall be zero */    int (*ssp_reply)(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,                     uint8_t accept, uint32_t passkey);    /** Get Bluetooth profile interface */    const void* (*get_profile_interface) (const char *profile_id);    /** Bluetooth Test Mode APIs - Bluetooth must be enabled for these APIs */    /* Configure DUT Mode - Use this mode to enter/exit DUT mode */    int (*dut_mode_configure)(uint8_t enable);    /* Send any test HCI (vendor-specific) command to the controller. Must be in DUT Mode */    int (*dut_mode_send)(uint16_t opcode, uint8_t *buf, uint8_t len);    /** BLE Test Mode APIs */    /* opcode MUST be one of: LE_Receiver_Test, LE_Transmitter_Test, LE_Test_End */    int (*le_test_mode)(uint16_t opcode, uint8_t *buf, uint8_t len);    /* enable or disable bluetooth HCI snoop log */    int (*config_hci_snoop_log)(uint8_t enable);    /** Sets the OS call-out functions that bluedroid needs for alarms and wake locks.      * This should be called immediately after a successful |init|.      */    int (*set_os_callouts)(bt_os_callouts_t *callouts);    /** Read Energy info details - return value indicates BT_STATUS_SUCCESS or BT_STATUS_NOT_READY      * Success indicates that the VSC command was sent to controller      */    int (*read_energy_info)();    /**     * Native support for dumpsys function     * Function is synchronous and |fd| is owned by caller.     */    void (*dump)(int fd);    /**     * Clear /data/misc/bt_config.conf and erase all stored connections     */    int (*config_clear)(void);    /**     * Clear (reset) the dynamic portion of the device interoperability database.     */    void (*interop_database_clear)(void);    /**     * Add a new device interoperability workaround for a remote device whose     * first |len| bytes of the its device address match |addr|.     * NOTE: |feature| has to match an item defined in interop_feature_t (interop.h).     */    void (*interop_database_add)(uint16_t feature, const bt_bdaddr_t *addr, size_t len);} bt_interface_t;/** TODO: Need to add APIs for Service Discovery, Service authorization and  *       connection management. Also need to add APIs for configuring  *       properties of remote bonded devices such as name, UUID etc. */typedef struct {    struct hw_device_t common;    const bt_interface_t* (*get_bluetooth_interface)();} bluetooth_device_t;typedef bluetooth_device_t bluetooth_module_t;

3.3 蓝牙搜索流程

  • BluetoothSetting->LocalBluetoothAdapter->BluetoothAdapter->IBluetooth.stub->AdapterService

  • AdapterService->JNI->bluetooth.h

4. 应用层开发

蓝牙app开发,官方文档说明的已经很详细,链接如下:

  • 传统蓝牙部分
  • BLE部分

更多相关文章

  1. Android中一个Activity调用另一个Activity — Intent对象的使用
  2. Android基于TextView实现跑马灯效果
  3. 在EeePC上运行Android!(转)(也是代码下载配置编译的流程!)
  4. Android(安卓)控件使用之SlidingDrawer
  5. Android中onInterceptTouchEvent与onTouchEvent
  6. Android原生(Native)C(JNI/NDK)开发之二:framebuffer篇
  7. Android简单自定义圆形和水平ProgressBar
  8. 转-Android原生(Native)C(JNI/NDK)开发之二:framebuffer篇
  9. Android系统启动流程 - 1

随机推荐

  1. android RadioButton 点击时候出现点击声
  2. android 屏幕适配之自动生成多重values
  3. android 下载文件图片圆形进度条
  4. Ubuntu下android真机调试Using Hardware
  5. Android开发之自定义PopupWindow记录
  6. (一)如何建立 Android(安卓)Application Pr
  7. android 入门demo 进度条
  8. Android下的OpenGl ES
  9. Android(安卓)Studio-build错误:app:merg
  10. Android应用程序中启动另一个应用程序