【android bluetooth 框架分析 04】【bt-framework 层详解 5】【AbstractionLayer介绍】

1. AbstractionLayer 介绍

我们在阅读 native 和 java 层 蓝牙服务代码时,会发现很多 AbstractionLayer.xxxxx 的字段。 这些字段 虽然很容易理解是干什么的。 但是 大家有没有考虑过, 为啥要专门定义一个类来存放他们。 这样设计的意义是什么?

1.字段解释

  • packages/modules/Bluetooth/android/app/src/com/android/bluetooth/btservice/AbstractionLayer.java
c 复制代码
package com.android.bluetooth.btservice;

/*
 * @hide
 */

public final class AbstractionLayer {
    // Do not modify without upating the HAL files.

    // TODO: Some of the constants are repeated from BluetoothAdapter.java.
    // Get rid of them and maintain just one.
    static final int BT_STATE_OFF = 0x00;
    static final int BT_STATE_ON = 0x01;

    static final int BT_SCAN_MODE_NONE = 0x00;
    static final int BT_SCAN_MODE_CONNECTABLE = 0x01;
    static final int BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE = 0x02;

    static final int BT_PROPERTY_BDNAME = 0x01;
    static final int BT_PROPERTY_BDADDR = 0x02;
    static final int BT_PROPERTY_UUIDS = 0x03;
    static final int BT_PROPERTY_CLASS_OF_DEVICE = 0x04;
    static final int BT_PROPERTY_TYPE_OF_DEVICE = 0x05;
    static final int BT_PROPERTY_SERVICE_RECORD = 0x06;
    static final int BT_PROPERTY_ADAPTER_SCAN_MODE = 0x07;
    static final int BT_PROPERTY_ADAPTER_BONDED_DEVICES = 0x08;
    static final int BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT = 0x09;

    static final int BT_PROPERTY_REMOTE_FRIENDLY_NAME = 0x0A;
    static final int BT_PROPERTY_REMOTE_RSSI = 0x0B;

    static final int BT_PROPERTY_REMOTE_VERSION_INFO = 0x0C;
    static final int BT_PROPERTY_LOCAL_LE_FEATURES = 0x0D;

    static final int BT_PROPERTY_DYNAMIC_AUDIO_BUFFER = 0x10;
    static final int BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER = 0x11;

    public static final int BT_DEVICE_TYPE_BREDR = 0x01;
    public static final int BT_DEVICE_TYPE_BLE = 0x02;
    public static final int BT_DEVICE_TYPE_DUAL = 0x03;

    static final int BT_PROPERTY_LOCAL_IO_CAPS = 0x0e;
    static final int BT_PROPERTY_LOCAL_IO_CAPS_BLE = 0x0f;

    static final int BT_BOND_STATE_NONE = 0x00;
    static final int BT_BOND_STATE_BONDING = 0x01;
    static final int BT_BOND_STATE_BONDED = 0x02;

    static final int BT_SSP_VARIANT_PASSKEY_CONFIRMATION = 0x00;
    static final int BT_SSP_VARIANT_PASSKEY_ENTRY = 0x01;
    static final int BT_SSP_VARIANT_CONSENT = 0x02;
    static final int BT_SSP_VARIANT_PASSKEY_NOTIFICATION = 0x03;

    static final int BT_DISCOVERY_STOPPED = 0x00;
    static final int BT_DISCOVERY_STARTED = 0x01;

    static final int BT_ACL_STATE_CONNECTED = 0x00;
    static final int BT_ACL_STATE_DISCONNECTED = 0x01;

    static final int BT_UUID_SIZE = 16; // bytes

    public static final int BT_STATUS_SUCCESS = 0;
    public static final int BT_STATUS_FAIL = 1;
    public static final int BT_STATUS_NOT_READY = 2;
    public static final int BT_STATUS_NOMEM = 3;
    public static final int BT_STATUS_BUSY = 4;
    public static final int BT_STATUS_DONE = 5;
    public static final int BT_STATUS_UNSUPPORTED = 6;
    public static final int BT_STATUS_PARM_INVALID = 7;
    public static final int BT_STATUS_UNHANDLED = 8;
    public static final int BT_STATUS_AUTH_FAILURE = 9;
    public static final int BT_STATUS_RMT_DEV_DOWN = 10;
    public static final int BT_STATUS_AUTH_REJECTED = 11;
    public static final int BT_STATUS_AUTH_TIMEOUT = 12;
}

这段代码 用于定义蓝牙 HAL 与上层服务之间的通用常量(状态、属性、错误码等)。这些常量的设计目的是提供一个统一的"抽象层接口",便于 Bluetooth HAL(C/C++ 层)与 Java 层进行交互时传递标准化信息。

下面用表格的方式对这些常量的用途和适用场景进行整理说明:

类别 常量名 数值 含义/用途说明 使用场景示例
蓝牙状态 BT_STATE_OFF 0x00 蓝牙关闭状态 通知 Java 层当前蓝牙关闭
BT_STATE_ON 0x01 蓝牙开启状态 通知 Java 层当前蓝牙开启
扫描模式 BT_SCAN_MODE_NONE 0x00 不可连接也不可被发现 设置蓝牙扫描策略时
BT_SCAN_MODE_CONNECTABLE 0x01 可被连接但不可被发现 广播连接状态变化
BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE 0x02 可被连接也可被发现 配对时开启可发现
属性类型 BT_PROPERTY_BDNAME 0x01 本地设备名称 设置/获取本地蓝牙名称
BT_PROPERTY_BDADDR 0x02 本地设备地址 获取本地地址
BT_PROPERTY_UUIDS 0x03 支持的服务 UUID 列表 SDP 结果上报
BT_PROPERTY_CLASS_OF_DEVICE 0x04 设备类型编码 配对时判断设备类别
BT_PROPERTY_TYPE_OF_DEVICE 0x05 蓝牙设备类型(BR/EDR、BLE、Dual) 设置设备属性时
BT_PROPERTY_SERVICE_RECORD 0x06 远端设备服务记录(SDP) 服务搜索时返回
BT_PROPERTY_ADAPTER_SCAN_MODE 0x07 当前扫描模式 获取当前适配器属性
BT_PROPERTY_ADAPTER_BONDED_DEVICES 0x08 获取已配对设备列表 启动时获取已配对设备
BT_PROPERTY_ADAPTER_DISCOVERABLE_TIMEOUT 0x09 可被发现模式的超时时长 设置发现超时
BT_PROPERTY_REMOTE_FRIENDLY_NAME 0x0A 远程设备名称 获取远端名称
BT_PROPERTY_REMOTE_RSSI 0x0B 远程设备信号强度 BLE 扫描中上报
BT_PROPERTY_REMOTE_VERSION_INFO 0x0C 协议版本号(HCI/LMP) 配对成功后回调
BT_PROPERTY_LOCAL_LE_FEATURES 0x0D 本地 LE 特性 初始化时上报
BT_PROPERTY_DYNAMIC_AUDIO_BUFFER 0x10 音频缓冲设置 Audio streaming 配置
BT_PROPERTY_REMOTE_IS_COORDINATED_SET_MEMBER 0x11 是否为协调播放组成员(如多设备音频) LE Audio 使用
设备类型 BT_DEVICE_TYPE_BREDR 0x01 传统蓝牙设备 设置设备属性
BT_DEVICE_TYPE_BLE 0x02 低功耗蓝牙设备 BLE 配对等场景
BT_DEVICE_TYPE_DUAL 0x03 同时支持 BR/EDR 与 BLE 的双模设备 常见手机
本地 I/O 能力 BT_PROPERTY_LOCAL_IO_CAPS 0x0e 本地 IO 能力(配对时使用) SSP 配对时
BT_PROPERTY_LOCAL_IO_CAPS_BLE 0x0f 本地 BLE IO 能力 BLE 设备配对时
配对状态 BT_BOND_STATE_NONE 0x00 未配对 配对流程中状态变化
BT_BOND_STATE_BONDING 0x01 正在配对 显示进度
BT_BOND_STATE_BONDED 0x02 配对完成 保存设备记录
SSP 配对类型 BT_SSP_VARIANT_PASSKEY_CONFIRMATION 0x00 确认配对码 人机交互确认界面
BT_SSP_VARIANT_PASSKEY_ENTRY 0x01 输入配对码 输入框场景
BT_SSP_VARIANT_CONSENT 0x02 用户授权同意 弹窗授权
BT_SSP_VARIANT_PASSKEY_NOTIFICATION 0x03 显示配对码 显示数字码
发现流程状态 BT_DISCOVERY_STOPPED 0x00 发现已停止 搜索过程
BT_DISCOVERY_STARTED 0x01 发现已开始 搜索开始时广播
ACL 链接状态 BT_ACL_STATE_CONNECTED 0x00 ACL 已连接 ACL 连接建立后通知
BT_ACL_STATE_DISCONNECTED 0x01 ACL 已断开 ACL 断开后通知
UUID 尺寸 BT_UUID_SIZE 16 UUID 长度为 16 字节(128 bit) UUID 检查或转换时使用
状态码(返回值) BT_STATUS_SUCCESS 0 操作成功 HAL 接口返回
BT_STATUS_FAIL 1 操作失败 错误处理
BT_STATUS_NOT_READY 2 适配器未准备好 蓝牙未初始化时返回
BT_STATUS_NOMEM 3 内存不足 动态分配失败
BT_STATUS_BUSY 4 当前操作繁忙 多任务冲突时
BT_STATUS_DONE 5 操作已完成 异步操作结束
BT_STATUS_UNSUPPORTED 6 不支持的功能 某些设备不支持特性
BT_STATUS_PARM_INVALID 7 参数无效 参数检查失败
BT_STATUS_UNHANDLED 8 没有处理该情况 框架遗漏处理逻辑
BT_STATUS_AUTH_FAILURE 9 认证失败 配对失败
BT_STATUS_RMT_DEV_DOWN 10 远程设备断开 状态同步失败
BT_STATUS_AUTH_REJECTED 11 认证被拒绝 用户取消
BT_STATUS_AUTH_TIMEOUT 12 认证超时 蓝牙连接不响应
  • 当 HAL 层通过 JNI 通知 Java 蓝牙服务状态时,会使用这些常量进行信息编码。

  • 例如:

    • bt_property_type 用于表示 Bluetooth HAL 上报的属性类型;

    • BT_DISCOVERY_STARTED 会在 onDiscoveryStateChanged() 中通过广播发送;

    • BT_STATUS_SUCCESS 是很多 native 回调函数中的返回码,表示调用成功。

2. 设计的意义

这个 AbstractionLayer 类的设计在 AOSP 蓝牙服务中提供了一个"抽象层常量集中地 ",它本身不包含行为逻辑,而是定义了一批与蓝牙 HAL(Hardware Abstraction Layer)通信的核心常量。这样的设计有以下几个 重要好处


1. 设计好处汇总表

设计目的/优势 说明
统一管理常量,避免魔法数字 所有关键状态、属性、错误码、设备类型等都使用命名常量,避免代码中出现"0x03"、"0x0C"这类不可读的"魔法数字"。
代码可读性提升 例如 BT_STATUS_AUTH_TIMEOUT12 更清晰表达"认证超时"的语义,使维护者无需查表也能读懂逻辑。
易于维护和扩展 如果底层 HAL 接口更新(例如新增属性),只需在这里添加新常量,其他代码不需修改多处。
确保与 HAL 保持同步 HAL 和 Java 层可能用 AIDL 或 JNI 通信,必须确保状态码一致;集中定义可减少错漏风险。注释中也明确写道:"Do not modify without updating the HAL files"。
方便封装抽象 该类名为 AbstractionLayer,意图明确:它作为 Bluetooth native 层与 framework 层的桥梁,封装底层值定义,避免上层代码直接接触 native 细节。
跨模块复用性强 同一套常量可以在多个模块中共享,比如 BluetoothAdapter、BluetoothService、JNI 等模块都能引用这组常量,避免重复定义。
支持双向通信 常量可用于 Java → native 下发请求(如 scan mode 设置),也可用于 native → Java 回调(如 discovery started 通知),有助于状态映射和协议一致性。

3. 典型使用场景

这些常量通常用于以下几个场景:

场景 举例 涉及常量
设备属性设置与读取 读取本地设备名、地址等 BT_PROPERTY_BDNAME, BT_PROPERTY_BDADDR
状态通知与回调 蓝牙开关、扫描模式变化通知 BT_STATE_ON, BT_SCAN_MODE_CONNECTABLE
配对与绑定流程 显示绑定状态或配对方式提示 BT_BOND_STATE_BONDING, BT_SSP_VARIANT_PASSKEY_ENTRY
错误处理与状态返回 蓝牙操作失败时给上层状态反馈 BT_STATUS_FAIL, BT_STATUS_AUTH_TIMEOUT
连接状态监控 连接建立或断开通知 BT_ACL_STATE_CONNECTED, BT_ACL_STATE_DISCONNECTED
设备类型识别 判断是 BLE 还是 BR/EDR 设备 BT_DEVICE_TYPE_BLE, BT_DEVICE_TYPE_DUAL

4. 总结:

AbstractionLayer 的设计是面向 HAL 与 Framework 解耦的一种"常量协议集中定义"模式,既提升了可读性和维护性,也为不同层间通信提供了统一语言,符合 AOSP 架构的一贯风格(尤其在 HAL / JNI 层交互中非常常见)。

相关推荐
还鮟2 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡4 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi004 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体
zhangphil5 小时前
Android理解onTrimMemory中ComponentCallbacks2的内存警戒水位线值
android
你过来啊你5 小时前
Android View的绘制原理详解
android
移动开发者1号8 小时前
使用 Android App Bundle 极致压缩应用体积
android·kotlin
移动开发者1号8 小时前
构建高可用线上性能监控体系:从原理到实战
android·kotlin
ii_best13 小时前
按键精灵支持安卓14、15系统,兼容64位环境开发辅助工具
android
美狐美颜sdk13 小时前
跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能
android·人工智能·ios·架构·音视频·美颜sdk·第三方美颜sdk
恋猫de小郭18 小时前
Meta 宣布加入 Kotlin 基金会,将为 Kotlin 和 Android 生态提供全新支持
android·开发语言·ios·kotlin