Android(安卓)Bluetooth源码分析总结 - framework部分
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部分
更多相关文章
- Android中一个Activity调用另一个Activity — Intent对象的使用
- Android基于TextView实现跑马灯效果
- 在EeePC上运行Android!(转)(也是代码下载配置编译的流程!)
- Android(安卓)控件使用之SlidingDrawer
- Android中onInterceptTouchEvent与onTouchEvent
- Android原生(Native)C(JNI/NDK)开发之二:framebuffer篇
- Android简单自定义圆形和水平ProgressBar
- 转-Android原生(Native)C(JNI/NDK)开发之二:framebuffer篇
- Android系统启动流程 - 1