Loading core/java/android/server/BluetoothAdapterStateMachine.java +41 −17 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ import java.io.PrintWriter; * (BluetootOn)<----------------------<- * | ^ -------------------->- | * | | | | * TURN_OFF | | SCAN_MODE_CHANGED m1 | | USER_TURN_ON * USER_TURN_OFF | | SCAN_MODE_CHANGED m1 | | USER_TURN_ON * AIRPLANE_MODE_ON | | | | * V | | | * (Switching) (PerProcessState) Loading Loading @@ -121,8 +121,10 @@ final class BluetoothAdapterStateMachine extends StateMachine { private static final int DEVICES_DISCONNECT_TIMEOUT = 103; // Prepare Bluetooth timeout happens private static final int PREPARE_BLUETOOTH_TIMEOUT = 104; // Bluetooth Powerdown timeout happens private static final int POWER_DOWN_TIMEOUT = 105; // Bluetooth turn off wait timeout happens private static final int TURN_OFF_TIMEOUT = 105; // Bluetooth device power off wait timeout happens private static final int POWER_DOWN_TIMEOUT = 106; private Context mContext; private BluetoothService mBluetoothService; Loading @@ -137,13 +139,17 @@ final class BluetoothAdapterStateMachine extends StateMachine { // this is the BluetoothAdapter state that reported externally private int mPublicState; // When turning off, broadcast STATE_OFF in the last HotOff state // This is because we do HotOff -> PowerOff -> HotOff for USER_TURN_OFF private boolean mDelayBroadcastStateOff; // timeout value waiting for all the devices to be disconnected private static final int DEVICES_DISCONNECT_TIMEOUT_TIME = 3000; private static final int PREPARE_BLUETOOTH_TIMEOUT_TIME = 10000; private static final int POWER_DOWN_TIMEOUT_TIME = 5000; private static final int TURN_OFF_TIMEOUT_TIME = 5000; private static final int POWER_DOWN_TIMEOUT_TIME = 20; BluetoothAdapterStateMachine(Context context, BluetoothService bluetoothService, BluetoothAdapter bluetoothAdapter) { Loading @@ -168,6 +174,7 @@ final class BluetoothAdapterStateMachine extends StateMachine { setInitialState(mPowerOff); mPublicState = BluetoothAdapter.STATE_OFF; mDelayBroadcastStateOff = false; } /** Loading Loading @@ -315,6 +322,10 @@ final class BluetoothAdapterStateMachine extends StateMachine { case SERVICE_RECORD_LOADED: removeMessages(PREPARE_BLUETOOTH_TIMEOUT); transitionTo(mHotOff); if (mDelayBroadcastStateOff) { broadcastState(BluetoothAdapter.STATE_OFF); mDelayBroadcastStateOff = false; } break; case PREPARE_BLUETOOTH_TIMEOUT: Log.e(TAG, "Bluetooth adapter SDP failed to load"); Loading Loading @@ -373,8 +384,17 @@ final class BluetoothAdapterStateMachine extends StateMachine { case AIRPLANE_MODE_ON: case TURN_COLD: shutoffBluetooth(); // we cannot go to power off state yet, we need wait for the Bluetooth // device power off. Unfortunately the stack does not give a event back // so we wait a little bit here sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME); break; case POWER_DOWN_TIMEOUT: transitionTo(mPowerOff); if (!mDelayBroadcastStateOff) { broadcastState(BluetoothAdapter.STATE_OFF); } break; case AIRPLANE_MODE_OFF: if (getBluetoothPersistedSetting()) { Loading Loading @@ -402,6 +422,9 @@ final class BluetoothAdapterStateMachine extends StateMachine { recoverStateMachine(TURN_HOT, null); } break; case TURN_HOT: deferMessage(message); break; default: return NOT_HANDLED; } Loading Loading @@ -436,15 +459,17 @@ final class BluetoothAdapterStateMachine extends StateMachine { } break; case POWER_STATE_CHANGED: removeMessages(POWER_DOWN_TIMEOUT); removeMessages(TURN_OFF_TIMEOUT); if (!((Boolean) message.obj)) { if (mPublicState == BluetoothAdapter.STATE_TURNING_OFF) { transitionTo(mHotOff); finishSwitchingOff(); mBluetoothService.finishDisable(); mBluetoothService.cleanupAfterFinishDisable(); deferMessage(obtainMessage(TURN_COLD)); if (mContext.getResources().getBoolean (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) { deferMessage(obtainMessage(TURN_HOT)); mDelayBroadcastStateOff = true; } } } else { Loading @@ -461,7 +486,7 @@ final class BluetoothAdapterStateMachine extends StateMachine { case ALL_DEVICES_DISCONNECTED: removeMessages(DEVICES_DISCONNECT_TIMEOUT); mBluetoothService.switchConnectable(false); sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME); sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME); break; case DEVICES_DISCONNECT_TIMEOUT: sendMessage(ALL_DEVICES_DISCONNECTED); Loading @@ -473,7 +498,7 @@ final class BluetoothAdapterStateMachine extends StateMachine { deferMessage(obtainMessage(TURN_HOT)); } break; case POWER_DOWN_TIMEOUT: case TURN_OFF_TIMEOUT: transitionTo(mHotOff); finishSwitchingOff(); // reset the hardware for error recovery Loading Loading @@ -536,7 +561,7 @@ final class BluetoothAdapterStateMachine extends StateMachine { DEVICES_DISCONNECT_TIMEOUT_TIME); } else { mBluetoothService.switchConnectable(false); sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME); sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME); } // we turn all the way to PowerOff with AIRPLANE_MODE_ON Loading Loading @@ -610,13 +635,12 @@ final class BluetoothAdapterStateMachine extends StateMachine { } break; case POWER_STATE_CHANGED: removeMessages(POWER_DOWN_TIMEOUT); removeMessages(TURN_OFF_TIMEOUT); if (!((Boolean) message.obj)) { transitionTo(mHotOff); deferMessage(obtainMessage(TURN_COLD)); if (mContext.getResources().getBoolean if (!mContext.getResources().getBoolean (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) { deferMessage(obtainMessage(TURN_HOT)); deferMessage(obtainMessage(TURN_COLD)); } } else { if (!isTurningOn) { Loading @@ -629,7 +653,7 @@ final class BluetoothAdapterStateMachine extends StateMachine { } } break; case POWER_DOWN_TIMEOUT: case TURN_OFF_TIMEOUT: transitionTo(mHotOff); Log.e(TAG, "Power-down timed out, resetting..."); deferMessage(obtainMessage(TURN_COLD)); Loading Loading @@ -676,12 +700,12 @@ final class BluetoothAdapterStateMachine extends StateMachine { perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj); if (mBluetoothService.isApplicationStateChangeTrackerEmpty()) { mBluetoothService.switchConnectable(false); sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME); sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME); } break; case AIRPLANE_MODE_ON: mBluetoothService.switchConnectable(false); sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME); sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME); allProcessesCallback(false); // we turn all the way to PowerOff with AIRPLANE_MODE_ON deferMessage(obtainMessage(AIRPLANE_MODE_ON)); Loading core/java/android/server/BluetoothService.java +12 −0 Original line number Diff line number Diff line Loading @@ -526,6 +526,12 @@ public class BluetoothService extends IBluetooth.Stub { return false; } switchConnectable(false); // Bluetooth stack needs a small delay here before adding // SDP records, otherwise dbus stalls for over 30 seconds 1 out of 50 runs try { Thread.sleep(20); } catch (InterruptedException e) {} updateSdpRecords(); return true; } Loading Loading @@ -593,6 +599,12 @@ public class BluetoothService extends IBluetooth.Stub { // Add SDP records for profiles maintained by Android userspace addReservedSdpRecords(uuids); // Bluetooth stack need some a small delay here before adding more // SDP records, otherwise dbus stalls for over 30 seconds 1 out of 50 runs try { Thread.sleep(20); } catch (InterruptedException e) {} if (R.getBoolean(com.android.internal.R.bool.config_bluetooth_default_profiles)) { // Enable profiles maintained by Bluez userspace. setBluetoothTetheringNative(true, BluetoothPanProfileHandler.NAP_ROLE, Loading Loading
core/java/android/server/BluetoothAdapterStateMachine.java +41 −17 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ import java.io.PrintWriter; * (BluetootOn)<----------------------<- * | ^ -------------------->- | * | | | | * TURN_OFF | | SCAN_MODE_CHANGED m1 | | USER_TURN_ON * USER_TURN_OFF | | SCAN_MODE_CHANGED m1 | | USER_TURN_ON * AIRPLANE_MODE_ON | | | | * V | | | * (Switching) (PerProcessState) Loading Loading @@ -121,8 +121,10 @@ final class BluetoothAdapterStateMachine extends StateMachine { private static final int DEVICES_DISCONNECT_TIMEOUT = 103; // Prepare Bluetooth timeout happens private static final int PREPARE_BLUETOOTH_TIMEOUT = 104; // Bluetooth Powerdown timeout happens private static final int POWER_DOWN_TIMEOUT = 105; // Bluetooth turn off wait timeout happens private static final int TURN_OFF_TIMEOUT = 105; // Bluetooth device power off wait timeout happens private static final int POWER_DOWN_TIMEOUT = 106; private Context mContext; private BluetoothService mBluetoothService; Loading @@ -137,13 +139,17 @@ final class BluetoothAdapterStateMachine extends StateMachine { // this is the BluetoothAdapter state that reported externally private int mPublicState; // When turning off, broadcast STATE_OFF in the last HotOff state // This is because we do HotOff -> PowerOff -> HotOff for USER_TURN_OFF private boolean mDelayBroadcastStateOff; // timeout value waiting for all the devices to be disconnected private static final int DEVICES_DISCONNECT_TIMEOUT_TIME = 3000; private static final int PREPARE_BLUETOOTH_TIMEOUT_TIME = 10000; private static final int POWER_DOWN_TIMEOUT_TIME = 5000; private static final int TURN_OFF_TIMEOUT_TIME = 5000; private static final int POWER_DOWN_TIMEOUT_TIME = 20; BluetoothAdapterStateMachine(Context context, BluetoothService bluetoothService, BluetoothAdapter bluetoothAdapter) { Loading @@ -168,6 +174,7 @@ final class BluetoothAdapterStateMachine extends StateMachine { setInitialState(mPowerOff); mPublicState = BluetoothAdapter.STATE_OFF; mDelayBroadcastStateOff = false; } /** Loading Loading @@ -315,6 +322,10 @@ final class BluetoothAdapterStateMachine extends StateMachine { case SERVICE_RECORD_LOADED: removeMessages(PREPARE_BLUETOOTH_TIMEOUT); transitionTo(mHotOff); if (mDelayBroadcastStateOff) { broadcastState(BluetoothAdapter.STATE_OFF); mDelayBroadcastStateOff = false; } break; case PREPARE_BLUETOOTH_TIMEOUT: Log.e(TAG, "Bluetooth adapter SDP failed to load"); Loading Loading @@ -373,8 +384,17 @@ final class BluetoothAdapterStateMachine extends StateMachine { case AIRPLANE_MODE_ON: case TURN_COLD: shutoffBluetooth(); // we cannot go to power off state yet, we need wait for the Bluetooth // device power off. Unfortunately the stack does not give a event back // so we wait a little bit here sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME); break; case POWER_DOWN_TIMEOUT: transitionTo(mPowerOff); if (!mDelayBroadcastStateOff) { broadcastState(BluetoothAdapter.STATE_OFF); } break; case AIRPLANE_MODE_OFF: if (getBluetoothPersistedSetting()) { Loading Loading @@ -402,6 +422,9 @@ final class BluetoothAdapterStateMachine extends StateMachine { recoverStateMachine(TURN_HOT, null); } break; case TURN_HOT: deferMessage(message); break; default: return NOT_HANDLED; } Loading Loading @@ -436,15 +459,17 @@ final class BluetoothAdapterStateMachine extends StateMachine { } break; case POWER_STATE_CHANGED: removeMessages(POWER_DOWN_TIMEOUT); removeMessages(TURN_OFF_TIMEOUT); if (!((Boolean) message.obj)) { if (mPublicState == BluetoothAdapter.STATE_TURNING_OFF) { transitionTo(mHotOff); finishSwitchingOff(); mBluetoothService.finishDisable(); mBluetoothService.cleanupAfterFinishDisable(); deferMessage(obtainMessage(TURN_COLD)); if (mContext.getResources().getBoolean (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) { deferMessage(obtainMessage(TURN_HOT)); mDelayBroadcastStateOff = true; } } } else { Loading @@ -461,7 +486,7 @@ final class BluetoothAdapterStateMachine extends StateMachine { case ALL_DEVICES_DISCONNECTED: removeMessages(DEVICES_DISCONNECT_TIMEOUT); mBluetoothService.switchConnectable(false); sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME); sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME); break; case DEVICES_DISCONNECT_TIMEOUT: sendMessage(ALL_DEVICES_DISCONNECTED); Loading @@ -473,7 +498,7 @@ final class BluetoothAdapterStateMachine extends StateMachine { deferMessage(obtainMessage(TURN_HOT)); } break; case POWER_DOWN_TIMEOUT: case TURN_OFF_TIMEOUT: transitionTo(mHotOff); finishSwitchingOff(); // reset the hardware for error recovery Loading Loading @@ -536,7 +561,7 @@ final class BluetoothAdapterStateMachine extends StateMachine { DEVICES_DISCONNECT_TIMEOUT_TIME); } else { mBluetoothService.switchConnectable(false); sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME); sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME); } // we turn all the way to PowerOff with AIRPLANE_MODE_ON Loading Loading @@ -610,13 +635,12 @@ final class BluetoothAdapterStateMachine extends StateMachine { } break; case POWER_STATE_CHANGED: removeMessages(POWER_DOWN_TIMEOUT); removeMessages(TURN_OFF_TIMEOUT); if (!((Boolean) message.obj)) { transitionTo(mHotOff); deferMessage(obtainMessage(TURN_COLD)); if (mContext.getResources().getBoolean if (!mContext.getResources().getBoolean (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) { deferMessage(obtainMessage(TURN_HOT)); deferMessage(obtainMessage(TURN_COLD)); } } else { if (!isTurningOn) { Loading @@ -629,7 +653,7 @@ final class BluetoothAdapterStateMachine extends StateMachine { } } break; case POWER_DOWN_TIMEOUT: case TURN_OFF_TIMEOUT: transitionTo(mHotOff); Log.e(TAG, "Power-down timed out, resetting..."); deferMessage(obtainMessage(TURN_COLD)); Loading Loading @@ -676,12 +700,12 @@ final class BluetoothAdapterStateMachine extends StateMachine { perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj); if (mBluetoothService.isApplicationStateChangeTrackerEmpty()) { mBluetoothService.switchConnectable(false); sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME); sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME); } break; case AIRPLANE_MODE_ON: mBluetoothService.switchConnectable(false); sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME); sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME); allProcessesCallback(false); // we turn all the way to PowerOff with AIRPLANE_MODE_ON deferMessage(obtainMessage(AIRPLANE_MODE_ON)); Loading
core/java/android/server/BluetoothService.java +12 −0 Original line number Diff line number Diff line Loading @@ -526,6 +526,12 @@ public class BluetoothService extends IBluetooth.Stub { return false; } switchConnectable(false); // Bluetooth stack needs a small delay here before adding // SDP records, otherwise dbus stalls for over 30 seconds 1 out of 50 runs try { Thread.sleep(20); } catch (InterruptedException e) {} updateSdpRecords(); return true; } Loading Loading @@ -593,6 +599,12 @@ public class BluetoothService extends IBluetooth.Stub { // Add SDP records for profiles maintained by Android userspace addReservedSdpRecords(uuids); // Bluetooth stack need some a small delay here before adding more // SDP records, otherwise dbus stalls for over 30 seconds 1 out of 50 runs try { Thread.sleep(20); } catch (InterruptedException e) {} if (R.getBoolean(com.android.internal.R.bool.config_bluetooth_default_profiles)) { // Enable profiles maintained by Bluez userspace. setBluetoothTetheringNative(true, BluetoothPanProfileHandler.NAP_ROLE, Loading