BluetoothService.java
广播连接事件
/* Broadcast the Uuid intent */
/*package*/ synchronized void sendUuidIntent(String address) {
ParcelUuid[] uuid = getUuidFromCache(address);
Intent intent = new Intent(BluetoothDevice.ACTION_UUID);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
intent.putExtra(BluetoothDevice.EXTRA_UUID, uuid);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
mUuidIntentTracker.remove(address);
}
BluetoothEventManager.java
BluetoothEventManager.java
addHandler(BluetoothDevice.ACTION_UUID, new UuidChangedHandler());//注册ACTION_UUID接收器
private class UuidChangedHandler implements Handler {
public void onReceive(Context context, Intent intent,
BluetoothDevice device) {
mDeviceManager.onUuidChanged(device);
}
}
CachedBluetoothDevice.java
void onUuidChanged() {
updateProfiles();//将devices中的UUID功能与profileManager进行一次同步
/*
* If a connect was attempted earlier without any UUID, we will do the
* connect now.
*/
if (!mProfiles.isEmpty()
&& (mConnectAttempted + MAX_UUID_DELAY_FOR_AUTO_CONNECT) > SystemClock
.elapsedRealtime()) {
connectWithoutResettingTimer(false);
}
dispatchAttributesChanged();
}
左
private void connectWithoutResettingTimer(boolean connectAllProfiles) {
// Try to initialize the profiles if they were not.
if (mProfiles.isEmpty()) {
if (!updateProfiles()) {
// If UUIDs are not available yet, connect will be happen
// upon arrival of the ACTION_UUID intent.
if (DEBUG) Log.d(TAG, "No profiles. Maybe we will connect later");
return;
}
}
// Reset the only-show-one-error-dialog tracking variable
mIsConnectingErrorPossible = true;
int preferredProfiles = 0;
for (LocalBluetoothProfile profile : mProfiles) {
if (connectAllProfiles ? profile.isConnectable() : profile.isAutoConnectable()) {
if (profile.isPreferred(mDevice)) {
++preferredProfiles;
connectInt(profile);//轮询将设备支持的profile连接一次
}
}
}
if (DEBUG) Log.d(TAG, "Preferred profiles = " + preferredProfiles);
if (preferredProfiles == 0) {
connectAutoConnectableProfiles();
}
}
private void connectInt(LocalBluetoothProfile profile) {
if (!ensurePaired()) {
return;
}
if (profile.connect(mDevice)) {
if (Utils.D) {
Log.d(TAG, "Command sent successfully:CONNECT " + describe(profile));
}
return;
}
Log.i(TAG, "Failed to connect " + profile.toString() + " to " + mName);
}
虫师上
HeadsetProfile.java
public boolean connect(BluetoothDevice device) {
List<BluetoothDevice> sinks = mService.getConnectedDevices();
if (sinks != null) {
for (BluetoothDevice sink : sinks) {
mService.disconnect(sink);
}
}
return mService.connect(device);
}
BluetoothHeadsetService.java
public boolean connect(BluetoothDevice device) {
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
synchronized (BluetoothHeadsetService.this) {
BluetoothDevice currDevice = getCurrentDevice();
if (currDevice == device ||
getPriority(device) == BluetoothProfile.PRIORITY_OFF) {
return false;
}
if (currDevice != null) {
disconnect(currDevice);
}
try {
return mBluetoothService.connectHeadset(device.getAddress());
} catch (RemoteException e) {
Log.e(TAG, "connectHeadset");
return false;
}
}
}
public boolean connectHeadset(String address) {
if (getBondState(address) != BluetoothDevice.BOND_BONDED) return false;
BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
if (state != null) {
Message msg = new Message();
msg.arg1 = BluetoothDeviceProfileState.CONNECT_HFP_OUTGOING;
msg.obj = state;
mHfpProfileState.sendMessage(msg);
return true;
}
return false;
}
BluetoothDeviceProfileState.java
processCommand
mHeadsetService.connectHeadsetInternal(mDevice);
public boolean connectHeadsetInternal(BluetoothDevice device) {
synchronized (BluetoothHeadsetService.this) {
BluetoothDevice currDevice = getCurrentDevice();
if (currDevice == null) {
BluetoothRemoteHeadset headset = new BluetoothRemoteHeadset();
mRemoteHeadsets.put(device, headset);
setState(device, BluetoothProfile.STATE_CONNECTING);
if (device.getUuids() == null) {
// We might not have got the UUID change notification from
// Bluez yet, if we have just paired. Try after 1.5 secs.
Message msg = new Message();
msg.what = CONNECT_HEADSET_DELAYED;
msg.obj = device;
mHandler.sendMessageDelayed(msg, 1500);
} else {
getSdpRecordsAndConnect(device);
}
return true;
} else {
Log.w(TAG, "connectHeadset(" + device + "): failed: already in state " +
mRemoteHeadsets.get(currDevice).mState +
" with headset " + currDevice);
}
return false;
}
}