这里记录上层应用的调用流程 !!!
packages/apps/TvSettings/Settings/src/com/android/tv/settings/accessories/BluetoothDevicePairer.java
public void startPairing(BluetoothDevice device) {
startPairing(device, true);
}
private void startPairing(BluetoothDevice device, boolean isManual) {
// TODO check if we're already paired/bonded to this device
// cancel auto-mode if applicable
mAutoMode = !isManual;
mTarget = device;
if (isInProgress()) {
throw new RuntimeException("Pairing already in progress, you must cancel the " +
"previous request first");
}
mHandler.removeCallbacksAndMessages(null);
mNextStageTimestamp = SystemClock.elapsedRealtime() +
(mAutoMode ? DELAY_AUTO_PAIRING : DELAY_MANUAL_PAIRING);
mHandler.sendEmptyMessageDelayed(MSG_PAIR,
mAutoMode ? DELAY_AUTO_PAIRING : DELAY_MANUAL_PAIRING);
// 发送MSG_PAIR
setStatus(STATUS_WAITING_TO_PAIR);
}
public BluetoothDevicePairer(Context context, EventListener listener) {
mContext = context.getApplicationContext();
mListener = listener;
addBluetoothDeviceCriteria();
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_PAIR:
startBonding(); //@ start Bonding
break;
case MSG_START:
start();
break;
default:
Log.d(TAG, "No handler case available for message: " + msg.what);
}
}
};
}
private void startBonding() {
stopScanning();
setStatus(STATUS_PAIRING);
if (mTarget.getBondState() != BluetoothDevice.BOND_BONDED) {
registerlinkStatusReceiver();
// create bond (pair) to the device
mTarget.createBond();
} else {
onBonded();
}
}
frameworks/base/core/java/android/bluetooth/BluetoothDevice.java
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean createBond() {
return createBond(TRANSPORT_AUTO);
}
@UnsupportedAppUsage
public boolean createBond(int transport) {
return createBondOutOfBand(transport, null);
}
public boolean createBondOutOfBand(int transport, OobData oobData) {
final IBluetooth service = sService;
if (service == null) {
Log.w(TAG, "BT not enabled, createBondOutOfBand failed");
return false;
}
try {
return service.createBond(this, transport, oobData);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
return false;
}
private static volatile IBluetooth sService;
这里通过AIDL通信,从Settings APK进场调用到 Bluetooth.APK进程
packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
@Override
public boolean createBond(BluetoothDevice device, int transport, OobData oobData) {
AdapterService service = getService();
if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "createBond")) {
return false;
}
enforceBluetoothAdminPermission(service);
return service.createBond(device, transport, oobData);
}
boolean createBond(BluetoothDevice device, int transport, OobData oobData) {
DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device);
if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) {
return false;
}
mRemoteDevices.setBondingInitiatedLocally(Utils.getByteAddress(device));
// Pairing is unreliable while scanning, so cancel discovery
// Note, remove this when native stack improves
cancelDiscoveryNative();
Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND);
//@ 向状态机发送BondStateMachine.CREATE_BOND消息
msg.obj = device;
msg.arg1 = transport;
if (oobData != null) {
Bundle oobDataBundle = new Bundle();
oobDataBundle.putParcelable(BondStateMachine.OOBDATA, oobData);
msg.setData(oobDataBundle);
}
mBondStateMachine.sendMessage(msg);
return true;
}
packages/apps/Bluetooth/src/com/android/bluetooth/btservice/BondStateMachine.java
private BondStateMachine(AdapterService service, AdapterProperties prop,
RemoteDevices remoteDevices) {
super("BondStateMachine:");
addState(mStableState);
addState(mPendingCommandState);
mRemoteDevices = remoteDevices;
mAdapterService = service;
mAdapterProperties = prop;
mAdapter = BluetoothAdapter.getDefaultAdapter();
setInitialState(mStableState);
}
初始化状态为mStableState
private class StableState extends State {
@Override
public void enter() {
infoLog("StableState(): Entering Off State");
}
@Override
public synchronized boolean processMessage(Message msg) {
BluetoothDevice dev = (BluetoothDevice) msg.obj;
switch (msg.what) {
case CREATE_BOND:
OobData oobData = null;
if (msg.getData() != null) {
oobData = msg.getData().getParcelable(OOBDATA);
}
//createBond !!!
createBond(dev, msg.arg1, oobData, true);
break;
case REMOVE_BOND:
removeBond(dev, true);
break;
case BONDING_STATE_CHANGE:
int newState = msg.arg1;
if (newState == BluetoothDevice.BOND_BONDING) {
sendIntent(dev, newState, 0);
transitionTo(mPendingCommandState);
} else if (newState == BluetoothDevice.BOND_NONE) {
sendIntent(dev, newState, 0);
} else {
Log.e(TAG, "In stable state, received invalid newState: "
+ state2str(newState));
}
break;
case UUID_UPDATe:
if (mPendingBondedDevices.contains(dev)) {
sendIntent(dev, BluetoothDevice.BOND_BONDED, 0);
}
break;
case CANCEL_BOND:
default:
Log.e(TAG, "Received unhandled state: " + msg.what);
return false;
}
return true;
}
}
private boolean createBond(BluetoothDevice dev, int transport, OobData oobData,
boolean transition) {
if (dev.getBondState() == BluetoothDevice.BOND_NONE) {
infoLog("Bond address is:" + dev);
byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
boolean result;
if (oobData != null) {
result = mAdapterService.createBondOutOfBandNative(addr, transport, oobData);
} else {
result = mAdapterService.createBondNative(addr, transport);
}
BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
mAdapterService.obfuscateAddress(dev), transport, dev.getType(),
BluetoothDevice.BOND_BONDING,
oobData == null ? BluetoothProtoEnums.BOND_SUB_STATE_UNKNOWN
: BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_OOB_DATA_PROVIDED,
BluetoothProtoEnums.UNBOND_REASON_UNKNOWN);
if (!result) {
BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
mAdapterService.obfuscateAddress(dev), transport, dev.getType(),
BluetoothDevice.BOND_NONE, BluetoothProtoEnums.BOND_SUB_STATE_UNKNOWN,
BluetoothDevice.UNBOND_REASON_REPEATED_ATTEMPTS);
// Using UNBOND_REASON_REMOVED for legacy reason
sendIntent(dev, BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_REMOVED);
return false;
} else if (transition) {
transitionTo(mPendingCommandState);
}
return true;
}
return false;
}
packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java
packages/apps/Bluetooth/src/com/android/bluetooth/btservice/AdapterService.java native boolean createBondNative(byte[] address, int transport); //native 接口调用到JNI
packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
static jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address,
jint transport) {
ALOGV("%s", __func__);
if (!sBluetoothInterface) return JNI_FALSE;
jbyte* addr = env->GetByteArrayElements(address, NULL);
if (addr == NULL) {
jniThrowIOException(env, EINVAL);
return JNI_FALSE;
}
int ret = sBluetoothInterface->create_bond((RawAddress*)addr, transport);
env->ReleaseByteArrayElements(address, addr, 0);
return (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}
#通过sBluetoothInterface接口调用到Bluedroid协议栈,下一篇学习。。。。



