Bluetooth相关的服务在SystemServer.java中被启动。
Slog.i(TAG, "Bluetooth Service");
bluetooth = new BluetoothService(context);
ServiceManager.addService(BluetoothAdapter.BLUETOOTH_SERVICE, bluetooth);
bluetooth.initAfterRegistration();
if (!"0".equals(SystemProperties.get("system_init.startaudioservice"))) {
bluetoothA2dp = new BluetoothA2dpService(context, bluetooth);
ServiceManager.addService(BluetoothA2dpService.BLUETOOTH_A2DP_SERVICE,
bluetoothA2dp);
bluetooth.initAfterA2dpRegistration();
}
int airplaneModeOn = Settings.System.getInt(mContentResolver,
Settings.System.AIRPLANE_MODE_ON, 0);
int bluetoothOn = Settings.Secure.getInt(mContentResolver,
Settings.Secure.BLUETOOTH_ON, 0);
if (airplaneModeOn == 0 && bluetoothOn != 0) {
bluetooth.enable();
}
frameworks/base/core/java/android/server/BluetoothService.java
public synchronized void initAfterRegistration() {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothState = new BluetoothAdapterStateMachine(mContext, this, mAdapter);
mBluetoothState.start();
if (mContext.getResources().getBoolean
(com.android.internal.R.bool.config_bluetooth_adapter_quick_switch) &&
mBluetoothState.is_hot_off_enabled()) {
mBluetoothState.sendMessage(BluetoothAdapterStateMachine.TURN_HOT);
}
mEventLoop = mBluetoothState.getBluetoothEventLoop();
}
/** Bring up BT and persist BT on in settings */
public boolean enable() {
return enable(true, true);
}
/**
* Enable this Bluetooth device, asynchronously.
* This turns on/off the underlying hardware.
*
* @param saveSetting If true, persist the new state of BT in settings
* @param allowConnect If true, auto-connects device when BT is turned on
* and allows incoming A2DP/HSP connections
* @return True on success (so far)
*/
public synchronized boolean enable(boolean saveSetting, boolean allowConnect) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
// Airplane mode can prevent Bluetooth radio from being turned on.
if (mIsAirplaneSensitive && isAirplaneModeOn() && !mIsAirplaneToggleable) {
return false;
}
mAllowConnect = allowConnect;
mBluetoothState.sendMessage(BluetoothAdapterStateMachine.USER_TURN_ON,
saveSetting);
return true;
}
BluetoothAdapter
BluetoothAdapterStateMachine
BluetoothAdapterStateMachine(Context context, BluetoothService bluetoothService,
BluetoothAdapter bluetoothAdapter) {
super(TAG);
mContext = context;
mBluetoothService = bluetoothService;
mEventLoop = new BluetoothEventLoop(context, bluetoothAdapter, bluetoothService, this);
mBluetoothOn = new BluetoothOn();
mSwitching = new Switching();
mHotOff = new HotOff();
mWarmUp = new WarmUp();
mPreWarmUp = new PreWarmUp();
mPowerOff = new PowerOff();
mPerProcessState = new PerProcessState();
}
private class PowerOff extends State {
@Override
public void enter() {
if (DBG) log("Enter PowerOff: " + getCurrentMessage().what);
}
@Override
public boolean processMessage(Message message) {
log("PowerOff process message: " + message.what);
boolean retValue = HANDLED;
switch(message.what) {
case USER_TURN_ON:
// starts turning on BT module, broadcast this out
broadcastState(BluetoothAdapter.STATE_TURNING_ON);
transitionTo(mPreWarmUp);
if (prepareBluetooth()) {
// this is user request, save the setting
if ((Boolean) message.obj) {
persistSwitchSetting(true);
}
// We will continue turn the BT on all the way to the BluetoothOn state
deferMessage(obtainMessage(TURN_ON_CONTINUE));
} else {
Log.e(TAG, "failed to prepare bluetooth, abort turning on");
transitionTo(mPowerOff);
broadcastState(BluetoothAdapter.STATE_OFF);
}
break;
case TURN_HOT:
if (prepareBluetooth()) {
transitionTo(mPreWarmUp);
}
break;
}
}
/**
* Turn on Bluetooth Module, Load firmware, and do all the preparation
* needed to get the Bluetooth Module ready but keep it not discoverable
* and not connectable.
* The last step of this method sets up the local service record DB.
* There will be a event reporting the status of the SDP setup.
*/
private boolean prepareBluetooth() {
if (mBluetoothService.enableNative() != 0) {
return false;
}
// try to start event loop, give 2 attempts
int retryCount = 2;
boolean eventLoopStarted = false;
while ((retryCount-- > 0) && !eventLoopStarted) {
mEventLoop.start();
// it may take a moment for the other thread to do its
// thing. Check periodically for a while.
int pollCount = 5;
while ((pollCount-- > 0) && !eventLoopStarted) {
if (mEventLoop.isEventLoopRunning()) {
eventLoopStarted = true;
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
log("prepareBluetooth sleep interrupted: " + pollCount);
break;
}
}
frameworks/base/core/java/android/server/BluetoothA2dpService.java