APP/JAVA 层
蓝牙开启位于setting中,即 package:com.android.settings.bluetooth
BluetoothSettings.java 中。
蓝牙开关操作封装在BluetoothEnabler.java中,BluetoothEnabler便于蓝牙开关管理。
里面实现SwitchBar.OnSwitchChangeListener接口,监听状态改变
@Override
public void onSwitchChanged(Switch switchView, boolean isChecked) {
...........
//在LocalBluetoothAdapter中打开蓝牙
if (mLocalAdapter != null) {
mLocalAdapter.setBluetoothEnabled(isChecked);
}
mSwitch.setEnabled(false);
}
LocalBluetoothAdapter.setBluetoothEnabled
onSwitchChanged里面调用LocalBluetoothAdapter的setBluetoothEnabled方法
public void setBluetoothEnabled(boolean enabled) {
boolean success = enabled
? mAdapter.enable()
: mAdapter.disable();
......设置蓝牙状态.....
}
}
setBluetoothEnabled调用BluetoothAdapter.enable方法,
BluetoothAdapter.enable
public boolean enable() {
int state = STATE_OFF;
//已经打开返回
if (isEnabled() == true){
if (DBG) Log.d(TAG, "enable(): BT is already enabled..!");
return true;
}
//Use service interface to get the exact state
if (mService != null) {
try {
state = mService.getState();
} catch (RemoteException e) {Log.e(TAG, "", e);}
}
//当前状态为打开
if (state == BluetoothAdapter.STATE_BLE_ON) {
Log.e(TAG, "BT is in BLE_ON State");
notifyUserAction(true);
return true;
}
try {
//通过远程服务打开蓝牙
return mManagerService.enable();
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
enabled打来蓝牙时会先检查当前蓝牙状态,如果已经enbale直接返回,如果没有通过远程服务查询当前状态,如果是打开状态直接返回,经过以上检查没有满足,调用IBluetoothManager.enable方法,开启蓝牙。
IBluetoothManager.enable
IBluetoothManager实际定义的是AIDL 文件,具体的实现位于com.android.server包下的BluetoothManagerService.java文件
public boolean enable() {
//当前用户和系统用户,6.0多用户相关检查
if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
(!checkIfCallerIsForegroundUser())) {
Log.w(TAG,"enable(): not allowed for non-active and non system user");
return false;
}
//权限检查
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH ADMIN permission");
if (DBG) {
Log.d(TAG,"enable(): mBluetooth =" + mBluetooth +
" mBinding = " + mBinding);
}
synchronized(mReceiver) {
mQuietEnableExternal = false;
mEnableExternal = true;
// waive WRITE_SECURE_SETTINGS permission check
//通过handler集中处理消息
sendEnableMsg(false);
}
if (DBG) Log.d(TAG, "enable returning");
return true;
}
handler最后调用handleEnable方法处理该消息
BluetoothManagerService.handleEnable
handleEnable会检查是否绑定了IBluetooth Server,如果没有绑定已经绑定调用IBluetooth.enable方法打开蓝牙
private void handleEnable(boolean quietMode) {
mQuietEnable = quietMode;
synchronized(mConnection) {
//检查服务是否已经启动并且已经绑定
if ((mBluetooth == null) && (!mBinding)) {
//Start bind timeout and bind
Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
mConnection.setGetNameAddressOnly(false);
Intent i = new Intent(IBluetooth.class.getName());
//绑定服务,UserHandle为多用户考虑
if (!doBind(i, mConnection,Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
UserHandle.CURRENT)) {
mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
} else {
mBinding = true;
}
} else if (mBluetooth != null) {
if (mConnection.isGetNameAddressOnly()) {
// if GetNameAddressOnly is set, we can clear this flag,
// so the service won't be unbind
// after name and address are saved
mConnection.setGetNameAddressOnly(false);
//Register callback object
try {
mBluetooth.registerCallback(mBluetoothCallback);
} catch (RemoteException re) {
Log.e(TAG, "Unable to register BluetoothCallback",re);
}
//Inform BluetoothAdapter instances that service is up
sendBluetoothServiceUpCallback();
}
//Enable bluetooth
try {
if (!mQuietEnable) {
//使能蓝牙
if(!mBluetooth.enable()) {
Log.e(TAG,"IBluetooth.enable() returned false");
}
}
else {
if(!mBluetooth.enableNoAutoConnect()) {
Log.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");
}
}
} catch (RemoteException e) {
Log.e(TAG,"Unable to call enable()",e);
}
}
}
}
服务没有绑定使用bind绑定服务 Intent i = new Intent(IBluetooth.class.getName());服务绑定时,会发送Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_SERVICE_CONNECTED);
handler处理MESSAGE_BLUETOOTH_SERVICE_CONNECTED消息时,会做一下事情
- 赋值server
IBluetooth 赋值 - 注册IBluetooth回调函数
mBluetooth.registerCallback(mBluetoothCallback); - 调用enable方法方法开启蓝牙
IBluetooth.enable -->AdapterServiceBinder.enable
IBluetooth也是定义AIDL接口,具体实现是位于com.android.bluetooth.btservice包下的AdapterServiceBinder。
IBluetooth.enable方法会接着调用AdapterService.enable方法,最终向状态机AdapterState发送AdapterState.BLE_TURN_ON消息,由状态机处理消息
public synchronized boolean enable(boolean quietMode) {
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");
debugLog("enable() - Enable called with quiet mode status = " + mQuietmode);
mQuietmode = quietMode;
//由状态机处理
Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_ON);
mAdapterStateMachine.sendMessage(m);
return true;
}
AdapterState状态机
AdapterState状态机在AdapterService的onCreate方法中他通过一个静态函数AdapterState.make初始化。
private AdapterState(AdapterService service, AdapterProperties adapterProperties) {
super("BluetoothAdapterState:");
addState(mOnState);
addState(mBleOnState);
addState(mOffState);
addState(mPendingCommandState);
mAdapterService = service;
mAdapterProperties = adapterProperties;
//初始状态为关闭
setInitialState(mOffState);
}
setInitialState设置了该状态机的初始状态是OffState,AdapterState.BLE_TURN_ON消息由OffState首先处理,状态机中每个状态通过调用public boolean processMessage方法处理每个消息。
@Override
public boolean processMessage(Message msg) {
AdapterService adapterService = mAdapterService;
if (adapterService == null) {
errorLog("Received message in OffState after cleanup: " + msg.what);
return false;
}
debugLog("Current state: OFF, message: " + msg.what);
switch(msg.what) {
//初始状态是OffState,由OffState处理蓝牙开启操作
case BLE_TURN_ON:
//通知BluetoothmangerService蓝牙正在开启
notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_TURNING_ON);
mPendingCommandState.setBleTurningOn(true);
transitionTo(mPendingCommandState);
//发送延迟消息,检测打开超时任务
sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);
//批量启动 profile service
adapterService.BleOnProcessStart();
break;
case USER_TURN_OFF:
//TODO: Handle case of service started and stopped without enable
break;
default:
return false;
}
return true;
}
该方法主要工作
- 通过回调通知BluetoothMangerService,蓝牙正在启动中,
- 将状态机中下个状态设置为PendingCommandState
- 开启一个蓝牙开启的超时检测
- 调用BleOnProcessStart批量启动所需的各个profile server
BleOnProcessStart
void BleOnProcessStart() {
debugLog("BleOnProcessStart()");
//支持的profile service
Class[] supportedProfileServices = Config.getSupportedProfiles();
//Initialize data objects
for (int i=0; i < supportedProfileServices.length;i++) {
mProfileServicesState.put(supportedProfileServices[i].getName(),BluetoothAdapter.STATE_OFF);
}
//初始化远程蓝牙设备
mRemoteDevices = new RemoteDevices(this);
mAdapterProperties.init(mRemoteDevices);
debugLog("BleOnProcessStart() - Make Bond State Machine");
//启动蓝牙绑定状态状态
mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices);
mJniCallbacks.init(mBondStateMachine,mRemoteDevices);
//FIXME: Set static instance here???
setAdapterService(this);
//Start Gatt service
setGattProfileServiceState(supportedProfileServices,BluetoothAdapter.STATE_ON);
}
BleOnProcessStart首先获取支持的profile,支持的profile在 Config.java 中
/**
* List of profile services.
*/
@SuppressWarnings("rawtypes")
//Do not inclue OPP and PBAP, because their services
//are not managed by AdapterService
private static final Class[] PROFILE_SERVICES = {
HeadsetService.class,
A2dpService.class,
A2dpSinkService.class,
HidService.class,
HealthService.class,
PanService.class,
GattService.class,
BluetoothMapService.class,
HeadsetClientService.class,
AvrcpControllerService.class,
SapService.class
};
接着还会启动新的状态机BondStateMachine,
调用setGattProfileServiceState方法,批量启动Peofile server,启动的服务里会传入intent.putExtra(EXTRA_ACTION,ACTION_SERVICE_STATE_CHANGED);ACTION_SERVICE_STATE_CHANGED会在后面使用
到这里还是没有发现在哪里启动蓝牙,其实蓝牙的启动在刚才批量启动的一个服务里。即GattService.java
GattService
在onStartCommand里面没有做什么,看父类实现
public int onStartCommand(Intent intent, int flags, int startId) {
if (DBG) log("onStartCommand()");
if (mStartError || mAdapter == null) {
Log.w(mName, "Stopping profile service: device does not have BT");
doStop(intent);
return PROFILE_SERVICE_MODE;
}
if (checkCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM)!=PackageManager.PERMISSION_GRANTED) {
Log.e(mName, "Permission denied!");
return PROFILE_SERVICE_MODE;
}
if (intent == null) {
Log.d(mName, "Restarting profile service...");
return PROFILE_SERVICE_MODE;
} else {
String action = intent.getStringExtra(AdapterService.EXTRA_ACTION);
if (AdapterService.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
int state= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
if(state==BluetoothAdapter.STATE_OFF) {
Log.d(mName, "Received stop request...Stopping profile...");
doStop(intent);
} else if (state == BluetoothAdapter.STATE_ON) {
Log.d(mName, "Received start request. Starting profile...");
//启动
doStart(intent);
}
}
}
return PROFILE_SERVICE_MODE;
}
调用doStart方法,doStart再调用start方法,start是个抽象方法,子类实现该方法做相应的预处理。
调用notifyProfileServiceStateChanged(BluetoothAdapter.STATE_ON);通知蓝牙开启,notifyProfileServiceStateChanged调用AdapterService.onProfileServiceStateChanged方法,传递STATE_ON消息,该消息会包装在MESSAGE_PROFILE_SERVICE_STATE_CHANGED类型里,由AdapterService的handler方法处理,
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
debugLog("handleMessage() - Message: " + msg.what);
switch (msg.what) {
case MESSAGE_PROFILE_SERVICE_STATE_CHANGED: {
debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED");
processProfileServiceStateChanged((String) msg.obj, msg.arg1);
}
..............省略.......................
}
}
};
processProfileServiceStateChanged处理profile 状态改变,其中
//在OffState中,isBleTurningOn设置为true
if (isBleTurningOn) {
if (serviceName.equals("com.android.bluetooth.gatt.GattService")) {
debugLog("GattService is started");
mAdapterStateMachine.sendMessage(mAdapterStateMachine.obtainMessage(AdapterState.BLE_STARTED));
return;
}
}
会向AdapterStateMachine状态机发送BLE_STARTED消息,根据之前状态机的改变,该消息由PendingCommandState状态处理,看processMessage的处理
case BLE_STARTED:
//Remove start timeout
removeMessages(BLE_START_TIMEOUT);
//Enable,调用底层方法,开启蓝牙
if (!adapterService.enableNative()) {
errorLog("Error while turning Bluetooth on");
//开启失败,状态通知,切换到OffState状态
notifyAdapterStateChange(BluetoothAdapter.STATE_OFF);
transitionTo(mOffState);
} else {
//超时检测
sendMessageDelayed(ENABLE_TIMEOUT, ENABLE_TIMEOUT_DELAY);
}
break;
通过调用adapterService.enableNative()方法,开始调用JNI方法,进入C/C++层,到此java层调用至此。
JNI
adapterService.enableNative 具体位置位于
packages/apps/Bluetooth/jni目录下,对应的cpp文件为com_android_bluetooth_btservice_AdapterService.cpp
cpp 文件和源java文件命名类似,将对应的包名的.改为_;文件的java源文件命名cpp文件
enableNative
//蓝牙使能
static jboolean enableNative(JNIEnv* env, jobject obj) {
ALOGV("%s:",__FUNCTION__);
jboolean result = JNI_FALSE;
if (!sBluetoothInterface) return result;
int ret = sBluetoothInterface->enable();
result = (ret == BT_STATUS_SUCCESS || ret == BT_STATUS_DONE) ? JNI_TRUE : JNI_FALSE;
return result;
}
static int enable(void) {
LOG_INFO("%s", __func__);
//状态判断
if (!interface_ready())
return BT_STATUS_NOT_READY;
stack_manager_get_interface()->start_up_stack_async();
return BT_STATUS_SUCCESS;
}
enableNative 调用sBluetoothInterface的enable方法,enable方法会调用start_up_stack_async方法。直接看看start_up_stack_async如何启动。
start_up_stack_async的实现在stack_manager.c 文件中,通过thread_post异步event_start_up_stack,来启动蓝牙栈,
event_start_up_stack
//启动蓝牙栈
// Synchronous function to start up the stack
static void event_start_up_stack(UNUSED_ATTR void *context) {
if (stack_is_running) {
LOG_DEBUG("%s stack already brought up.", __func__);
return;
}
ensure_stack_is_initialized();
LOG_DEBUG("%s is bringing up the stack.", __func__);
hack_future = future_new();
// Include this for now to put btif config into a shutdown-able state
//加载配置文件,配置文件位于手机系统目录/data/misc/bluedroid/bt_config.xml
module_start_up(get_module(BTIF_CONFIG_MODULE));
//ble enable
bte_main_enable();
//启动失败
if (future_await(hack_future) != FUTURE_SUCCESS) {
stack_is_running = true; // So stack shutdown actually happens
//关闭蓝牙栈,里面还会调用
event_shut_down_stack(NULL);
return;
}
stack_is_running = true;
LOG_DEBUG("%s finished", __func__);
//发送蓝牙栈启动信息,适配已经打开
btif_thread_post(event_signal_stack_up, NULL);
}
event_start_up_stack工作
- 调用ensure_stack_is_initialized确保,栈已经初始化,如果没有,则进行初始化。
初始化内容表多,暂不分析
- 调用module_start_up加载配置文件
- 调用bte_main_enable启动蓝牙
内容比较多,暂不分析
- 如果成功调用event_signal_stack_up方法,event_signal_stack_up方法调用 HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_ON);通过回调调用adapter_state_changed_cb方法,回调java层方法,通知蓝牙当前状态BT_STATE_ON
- 如果失败调用event_shut_down_stack方法,里面调用event_signal_stack_down,最终调用HAL_CBACK(bt_hal_cbacks, adapter_state_changed_cb, BT_STATE_OFF);方法,回调java层方法,通知蓝牙当前状态为BT_STATE_OFF
adapter_state_changed_cb 回调方法
adapter_state_changed_cb 定义在哪以及如何建立java层到C++层的关系
adapter_state_changed_cb 的在bluetooth.h 文件中
/** Bluetooth DM callback structure. */
typedef struct {
/** set to sizeof(bt_callbacks_t) */
size_t size;
adapter_state_changed_callback adapter_state_changed_cb;
adapter_properties_callback adapter_properties_cb;
remote_device_properties_callback remote_device_properties_cb;
device_found_callback device_found_cb;
discovery_state_changed_callback discovery_state_changed_cb;
pin_request_callback pin_request_cb;
ssp_request_callback ssp_request_cb;
bond_state_changed_callback bond_state_changed_cb;
acl_state_changed_callback acl_state_changed_cb;
callback_thread_event thread_evt_cb;
dut_mode_recv_callback dut_mode_recv_cb;
le_test_mode_callback le_test_mode_cb;
energy_info_callback energy_info_cb;
} bt_callbacks_t;
bt_callbacks_t 定义了java层的回调接口,如果C++层有消息传递到java层,回调接口都定义在这里。将接口更换名称adapter_state_changed_callback -->adapter_state_changed_cb;调用adapter_state_changed_cb即调用adapter_state_changed_callback。
首先这些回调接口定义在java文件中,即AdapterService.java;
AdapterService.java中有静态native方法,classInitNative,看C++做那些
static void classInitNative(JNIEnv* env, jclass clazz) {
int err;
hw_module_t* module;
jclass jniCallbackClass =
env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
sJniCallbacksField = env->GetFieldID(clazz, "mJniCallbacks",
"Lcom/android/bluetooth/btservice/JniCallbacks;");
method_stateChangeCallback = env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");
method_adapterPropertyChangedCallback = env->GetMethodID(jniCallbackClass,
"adapterPropertyChangedCallback",
"([I[[B)V");
method_discoveryStateChangeCallback = env->GetMethodID(jniCallbackClass,
"discoveryStateChangeCallback", "(I)V");
........................省略..............................
}
该方法主要是将位于JniCallbacks.java定义的回调方法映射到对应的C++层方法,如method_stateChangeCallback 对应方法stateChangeCallback的id。
通过 initNative方法来初始化方法变量
static bool initNative(JNIEnv* env, jobject obj) {
ALOGV("%s:",__FUNCTION__);
sJniAdapterServiceObj = env->NewGlobalRef(obj);
sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
if (sBluetoothInterface) {
int ret = sBluetoothInterface->init(&sBluetoothCallbacks);
if (ret != BT_STATUS_SUCCESS) {
ALOGE("Error while setting the callbacks: %d\n", ret);
sBluetoothInterface = NULL;
return JNI_FALSE;
}
ret = sBluetoothInterface->set_os_callouts(&sBluetoothOsCallouts);
if (ret != BT_STATUS_SUCCESS) {
ALOGE("Error while setting Bluetooth callouts: %d\n", ret);
sBluetoothInterface->cleanup();
sBluetoothInterface = NULL;
return JNI_FALSE;
}
if ( (sBluetoothSocketInterface = (btsock_interface_t *)
sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) {
ALOGE("Error getting socket interface");
}
return JNI_TRUE;
}
return JNI_FALSE;
}
主要是将 sBluetoothCallbacks设置在sBluetoothInterface中。
余下便是JNI初始化
JNI_OnLoad,调用register_com_android_bluetooth_btservice_AdapterService注册使用的方法。这些方法存放在数组中
static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"classInitNative", "()V", (void *) classInitNative},
{"initNative", "()Z", (void *) initNative},
{"cleanupNative", "()V", (void*) cleanupNative},
{"enableNative", "()Z", (void*) enableNative},
{"disableNative", "()Z", (void*) disableNative},
{"setAdapterPropertyNative", "(I[B)Z", (void*) setAdapterPropertyNative},
{"getAdapterPropertiesNative", "()Z", (void*) getAdapterPropertiesNative},
{"getAdapterPropertyNative", "(I)Z", (void*) getAdapterPropertyNative},
{"getDevicePropertyNative", "([BI)Z", (void*) getDevicePropertyNative},
{"setDevicePropertyNative", "([BI[B)Z", (void*) setDevicePropertyNative},
{"startDiscoveryNative", "()Z", (void*) startDiscoveryNative},
{"cancelDiscoveryNative", "()Z", (void*) cancelDiscoveryNative},
{"createBondNative", "([BI)Z", (void*) createBondNative},
{"removeBondNative", "([B)Z", (void*) removeBondNative},
{"cancelBondNative", "([B)Z", (void*) cancelBondNative},
{"getConnectionStateNative", "([B)I", (void*) getConnectionStateNative},
{"pinReplyNative", "([BZI[B)Z", (void*) pinReplyNative},
{"sspReplyNative", "([BIZI)Z", (void*) sspReplyNative},
{"getRemoteServicesNative", "([B)Z", (void*) getRemoteServicesNative},
{"connectSocketNative", "([BI[BII)I", (void*) connectSocketNative},
{"createSocketChannelNative", "(ILjava/lang/String;[BII)I",
(void*) createSocketChannelNative},
{"configHciSnoopLogNative", "(Z)Z", (void*) configHciSnoopLogNative},
{"alarmFiredNative", "()V", (void *) alarmFiredNative},
{"readEnergyInfo", "()I", (void*) readEnergyInfo},
{"dumpNative", "(Ljava/io/FileDescriptor;)V", (void*) dumpNative},
{"factoryResetNative", "()Z", (void*)factoryResetNative}
};