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 ));
0 commit comments