Skip to content

Commit ac8a61b

Browse files
Matthew XieAndroid (Google) Code Review
authored andcommitted
Merge "When turning off, broadcast STATE_OFF in the last HotOff state" into jb-dev
2 parents 06e8d66 + b12d6bc commit ac8a61b

File tree

2 files changed

+53
-17
lines changed

2 files changed

+53
-17
lines changed

core/java/android/server/BluetoothAdapterStateMachine.java

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
* (BluetootOn)<----------------------<-
4040
* | ^ -------------------->- |
4141
* | | | |
42-
* TURN_OFF | | SCAN_MODE_CHANGED m1 | | USER_TURN_ON
42+
* USER_TURN_OFF | | SCAN_MODE_CHANGED m1 | | USER_TURN_ON
4343
* AIRPLANE_MODE_ON | | | |
4444
* V | | |
4545
* (Switching) (PerProcessState)
@@ -121,8 +121,10 @@ final class BluetoothAdapterStateMachine extends StateMachine {
121121
private static final int DEVICES_DISCONNECT_TIMEOUT = 103;
122122
// Prepare Bluetooth timeout happens
123123
private static final int PREPARE_BLUETOOTH_TIMEOUT = 104;
124-
// Bluetooth Powerdown timeout happens
125-
private static final int POWER_DOWN_TIMEOUT = 105;
124+
// Bluetooth turn off wait timeout happens
125+
private static final int TURN_OFF_TIMEOUT = 105;
126+
// Bluetooth device power off wait timeout happens
127+
private static final int POWER_DOWN_TIMEOUT = 106;
126128

127129
private Context mContext;
128130
private BluetoothService mBluetoothService;
@@ -137,13 +139,17 @@ final class BluetoothAdapterStateMachine extends StateMachine {
137139

138140
// this is the BluetoothAdapter state that reported externally
139141
private int mPublicState;
142+
// When turning off, broadcast STATE_OFF in the last HotOff state
143+
// This is because we do HotOff -> PowerOff -> HotOff for USER_TURN_OFF
144+
private boolean mDelayBroadcastStateOff;
140145

141146
// timeout value waiting for all the devices to be disconnected
142147
private static final int DEVICES_DISCONNECT_TIMEOUT_TIME = 3000;
143148

144149
private static final int PREPARE_BLUETOOTH_TIMEOUT_TIME = 10000;
145150

146-
private static final int POWER_DOWN_TIMEOUT_TIME = 5000;
151+
private static final int TURN_OFF_TIMEOUT_TIME = 5000;
152+
private static final int POWER_DOWN_TIMEOUT_TIME = 20;
147153

148154
BluetoothAdapterStateMachine(Context context, BluetoothService bluetoothService,
149155
BluetoothAdapter bluetoothAdapter) {
@@ -168,6 +174,7 @@ final class BluetoothAdapterStateMachine extends StateMachine {
168174

169175
setInitialState(mPowerOff);
170176
mPublicState = BluetoothAdapter.STATE_OFF;
177+
mDelayBroadcastStateOff = false;
171178
}
172179

173180
/**
@@ -315,6 +322,10 @@ public boolean processMessage(Message message) {
315322
case SERVICE_RECORD_LOADED:
316323
removeMessages(PREPARE_BLUETOOTH_TIMEOUT);
317324
transitionTo(mHotOff);
325+
if (mDelayBroadcastStateOff) {
326+
broadcastState(BluetoothAdapter.STATE_OFF);
327+
mDelayBroadcastStateOff = false;
328+
}
318329
break;
319330
case PREPARE_BLUETOOTH_TIMEOUT:
320331
Log.e(TAG, "Bluetooth adapter SDP failed to load");
@@ -373,8 +384,17 @@ public boolean processMessage(Message message) {
373384
case AIRPLANE_MODE_ON:
374385
case TURN_COLD:
375386
shutoffBluetooth();
387+
// we cannot go to power off state yet, we need wait for the Bluetooth
388+
// device power off. Unfortunately the stack does not give a event back
389+
// so we wait a little bit here
390+
sendMessageDelayed(POWER_DOWN_TIMEOUT,
391+
POWER_DOWN_TIMEOUT_TIME);
392+
break;
393+
case POWER_DOWN_TIMEOUT:
376394
transitionTo(mPowerOff);
377-
broadcastState(BluetoothAdapter.STATE_OFF);
395+
if (!mDelayBroadcastStateOff) {
396+
broadcastState(BluetoothAdapter.STATE_OFF);
397+
}
378398
break;
379399
case AIRPLANE_MODE_OFF:
380400
if (getBluetoothPersistedSetting()) {
@@ -402,6 +422,9 @@ public boolean processMessage(Message message) {
402422
recoverStateMachine(TURN_HOT, null);
403423
}
404424
break;
425+
case TURN_HOT:
426+
deferMessage(message);
427+
break;
405428
default:
406429
return NOT_HANDLED;
407430
}
@@ -436,15 +459,17 @@ public boolean processMessage(Message message) {
436459
}
437460
break;
438461
case POWER_STATE_CHANGED:
439-
removeMessages(POWER_DOWN_TIMEOUT);
462+
removeMessages(TURN_OFF_TIMEOUT);
440463
if (!((Boolean) message.obj)) {
441464
if (mPublicState == BluetoothAdapter.STATE_TURNING_OFF) {
442465
transitionTo(mHotOff);
443-
finishSwitchingOff();
466+
mBluetoothService.finishDisable();
467+
mBluetoothService.cleanupAfterFinishDisable();
444468
deferMessage(obtainMessage(TURN_COLD));
445469
if (mContext.getResources().getBoolean
446470
(com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
447471
deferMessage(obtainMessage(TURN_HOT));
472+
mDelayBroadcastStateOff = true;
448473
}
449474
}
450475
} else {
@@ -461,7 +486,7 @@ public boolean processMessage(Message message) {
461486
case ALL_DEVICES_DISCONNECTED:
462487
removeMessages(DEVICES_DISCONNECT_TIMEOUT);
463488
mBluetoothService.switchConnectable(false);
464-
sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME);
489+
sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME);
465490
break;
466491
case DEVICES_DISCONNECT_TIMEOUT:
467492
sendMessage(ALL_DEVICES_DISCONNECTED);
@@ -473,7 +498,7 @@ public boolean processMessage(Message message) {
473498
deferMessage(obtainMessage(TURN_HOT));
474499
}
475500
break;
476-
case POWER_DOWN_TIMEOUT:
501+
case TURN_OFF_TIMEOUT:
477502
transitionTo(mHotOff);
478503
finishSwitchingOff();
479504
// reset the hardware for error recovery
@@ -536,7 +561,7 @@ public boolean processMessage(Message message) {
536561
DEVICES_DISCONNECT_TIMEOUT_TIME);
537562
} else {
538563
mBluetoothService.switchConnectable(false);
539-
sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME);
564+
sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME);
540565
}
541566

542567
// we turn all the way to PowerOff with AIRPLANE_MODE_ON
@@ -610,13 +635,12 @@ public boolean processMessage(Message message) {
610635
}
611636
break;
612637
case POWER_STATE_CHANGED:
613-
removeMessages(POWER_DOWN_TIMEOUT);
638+
removeMessages(TURN_OFF_TIMEOUT);
614639
if (!((Boolean) message.obj)) {
615640
transitionTo(mHotOff);
616-
deferMessage(obtainMessage(TURN_COLD));
617-
if (mContext.getResources().getBoolean
641+
if (!mContext.getResources().getBoolean
618642
(com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
619-
deferMessage(obtainMessage(TURN_HOT));
643+
deferMessage(obtainMessage(TURN_COLD));
620644
}
621645
} else {
622646
if (!isTurningOn) {
@@ -629,7 +653,7 @@ public boolean processMessage(Message message) {
629653
}
630654
}
631655
break;
632-
case POWER_DOWN_TIMEOUT:
656+
case TURN_OFF_TIMEOUT:
633657
transitionTo(mHotOff);
634658
Log.e(TAG, "Power-down timed out, resetting...");
635659
deferMessage(obtainMessage(TURN_COLD));
@@ -676,12 +700,12 @@ public boolean processMessage(Message message) {
676700
perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj);
677701
if (mBluetoothService.isApplicationStateChangeTrackerEmpty()) {
678702
mBluetoothService.switchConnectable(false);
679-
sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME);
703+
sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME);
680704
}
681705
break;
682706
case AIRPLANE_MODE_ON:
683707
mBluetoothService.switchConnectable(false);
684-
sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME);
708+
sendMessageDelayed(TURN_OFF_TIMEOUT, TURN_OFF_TIMEOUT_TIME);
685709
allProcessesCallback(false);
686710
// we turn all the way to PowerOff with AIRPLANE_MODE_ON
687711
deferMessage(obtainMessage(AIRPLANE_MODE_ON));

core/java/android/server/BluetoothService.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,12 @@ public boolean enableNoAutoConnect() {
526526
return false;
527527
}
528528
switchConnectable(false);
529+
530+
// Bluetooth stack needs a small delay here before adding
531+
// SDP records, otherwise dbus stalls for over 30 seconds 1 out of 50 runs
532+
try {
533+
Thread.sleep(20);
534+
} catch (InterruptedException e) {}
529535
updateSdpRecords();
530536
return true;
531537
}
@@ -593,6 +599,12 @@ private synchronized void updateSdpRecords() {
593599
// Add SDP records for profiles maintained by Android userspace
594600
addReservedSdpRecords(uuids);
595601

602+
// Bluetooth stack need some a small delay here before adding more
603+
// SDP records, otherwise dbus stalls for over 30 seconds 1 out of 50 runs
604+
try {
605+
Thread.sleep(20);
606+
} catch (InterruptedException e) {}
607+
596608
if (R.getBoolean(com.android.internal.R.bool.config_bluetooth_default_profiles)) {
597609
// Enable profiles maintained by Bluez userspace.
598610
setBluetoothTetheringNative(true, BluetoothPanProfileHandler.NAP_ROLE,

0 commit comments

Comments
 (0)