BluetoothPbapClient的connect方法用于断开与外部蓝牙设备(手机)进行Pbap连接,代码如下:
//packages/modules/Bluetooth/framework/java/android/bluetooth/BluetoothPbapClient.java
public final class BluetoothPbapClient implements BluetoothProfile, AutoCloseable {
public boolean disconnect(BluetoothDevice device) {
if (DBG) {
log("disconnect(" + device + ")" + new Exception());
}
final IBluetoothPbapClient service = getService();
final boolean defaultValue = true;
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
} else if (isEnabled() && isValidDevice(device)) {
try {
final SynchronousResultReceiver<Boolean> recv = SynchronousResultReceiver.get();
service.disconnect(device, mAttributionSource, recv);
recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
return true;
} catch (RemoteException | TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
}
}
return defaultValue;
}
}
调用IBluetoothPbapClient的disconnect方法,IBluetoothPbapClient是一个接口,由PbapClientService的内部类BluetoothPbapClientBinder实现:
//packages/modules/Bluetooth/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java
public class PbapClientService extends ProfileService {
private static class BluetoothPbapClientBinder extends IBluetoothPbapClient.Stub
implements IProfileServiceBinder {
@Override
public void disconnect(BluetoothDevice device, AttributionSource source,
SynchronousResultReceiver receiver) {
try {
PbapClientService service = getService(source);
boolean defaultValue = false;
if (service != null) {
defaultValue = service.disconnect(device);
}
receiver.send(defaultValue);
} catch (RuntimeException e) {
receiver.propagateException(e);
}
}
}
}
PbapClientService disconnect
调用PbapClientService的disconnect方法:
//packages/modules/Bluetooth/android/app/src/com/android/bluetooth/pbapclient/PbapClientService.java
public class PbapClientService extends ProfileService {
private Map<BluetoothDevice, PbapClientStateMachine> mPbapClientStateMachineMap =
new ConcurrentHashMap<>();
public boolean disconnect(BluetoothDevice device) {
if (device == null) {
throw new IllegalArgumentException("Null device");
}
enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
"Need BLUETOOTH_PRIVILEGED permission");
PbapClientStateMachine pbapClientStateMachine = mPbapClientStateMachineMap.get(device);
if (pbapClientStateMachine != null) {
pbapClientStateMachine.disconnect(device);
return true;
} else {
Log.w(TAG, "disconnect() called on unconnected device.");
return false;
}
}
}
调用pbapClientStateMachine的disconnect方法:
//packages/modules/Bluetooth/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java
final class PbapClientStateMachine extends StateMachine {
class Connected extends State {
@Override
public boolean processMessage(Message message) {
switch (message.what) {
case MSG_DISCONNECT:
if ((message.obj instanceof BluetoothDevice)
&& ((BluetoothDevice) message.obj).equals(mCurrentDevice)) {
transitionTo(mDisconnecting); //迁移到Disconnecting状态
}
break;
}
return HANDLED;
}
}
}
迁移到Disconnecting状态,会调用Disconnecting的enter方法:
//packages/modules/Bluetooth/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java
final class PbapClientStateMachine extends StateMachine {
private PbapClientConnectionHandler mConnectionHandler;
class Disconnecting extends State {
@Override
public void enter() {
if (DBG) Log.d(TAG, "Enter Disconnecting: " + getCurrentMessage().what);
onConnectionStateChanged(mCurrentDevice, mMostRecentState,
BluetoothProfile.STATE_DISCONNECTING); //发送Pbap连接状态变为STATE_DISCONNECTING的广播
mMostRecentState = BluetoothProfile.STATE_DISCONNECTING;
mConnectionHandler.obtainMessage(PbapClientConnectionHandler.MSG_DISCONNECT)
.sendToTarget(); //发送MSG_DISCONNECT消息
sendMessageDelayed(MSG_DISCONNECT_TIMEOUT, DISCONNECT_TIMEOUT); //延迟发生MSG_DISCONNECT_TIMEOUT消息,也就是启动Timeout定时器
}
}
}
PbapClientConnectionHandler handleMessage
发送MSG_DISCONNECT消息,发送的消息在PbapClientConnectionHandler的handleMessage中处理:
//packages/modules/Bluetooth/android/app/src/com/android/bluetooth/pbapclient/PbapClientConnectionHandler.java
class PbapClientConnectionHandler extends Handler {
private ClientSession mObexSession;
@Override
public void handleMessage(Message msg) {
case MSG_DISCONNECT:
if (DBG) {
Log.d(TAG, "Starting Disconnect");
}
try {
if (mObexSession != null) {
if (DBG) {
Log.d(TAG, "obexSessionDisconnect" + mObexSession);
}
mObexSession.disconnect(null);
mObexSession.close();
}
if (DBG) {
Log.d(TAG, "Closing Socket");
}
closeSocket();
} catch (IOException e) {
Log.w(TAG, "DISCONNECT Failure ", e);
}
if (DBG) {
Log.d(TAG, "Completing Disconnect");
}
removeAccount(mAccount);
removeCallLog(mAccount);
mPbapClientStateMachine.sendMessage(PbapClientStateMachine.MSG_CONNECTION_CLOSED); //发送MSG_CONNECTION_CLOSED消息
break;
}
}
MSG_CONNECTION_CLOSED
发送MSG_CONNECTION_CLOSED消息,发送的消息会在PbapClientStateMachine的Disconnecting状态的processMessage中处理:
//packages/modules/Bluetooth/android/app/src/com/android/bluetooth/pbapclient/PbapClientStateMachine.java
final class PbapClientStateMachine extends StateMachine {
private PbapClientConnectionHandler mConnectionHandler;
class Disconnecting extends State {
@Override
public boolean processMessage(Message message) {
if (DBG) {
Log.d(TAG, "Processing MSG " + message.what + " from " + this.getName());
}
switch (message.what) {
case MSG_CONNECTION_CLOSED:
removeMessages(MSG_DISCONNECT_TIMEOUT); //删除MSG_DISCONNECT_TIMEOUT消息,也就清除Timeout计时器
mHandlerThread.quitSafely(); //结束线程
transitionTo(mDisconnected); //迁移到Disconnected状态
break;
}
return HANDLED;
}
}
}
到这里BluetoothPbapClient的disconnect流程就分析完了。