diff options
| author | Matthew Xie <mattx@google.com> | 2011-09-07 23:32:51 -0700 |
|---|---|---|
| committer | Matthew Xie <mattx@google.com> | 2011-09-08 15:05:19 -0700 |
| commit | 694c0b833b4235b396ec1b798610d617d0ec7b5c (patch) | |
| tree | 2733e36f4abb333f5c4eddc08d732d5ab240a406 /core/java/android/server/BluetoothAdapterStateMachine.java | |
| parent | 1d124d5037644ed66a78c181c4eff13a7da04443 (diff) | |
| download | frameworks_base-694c0b833b4235b396ec1b798610d617d0ec7b5c.zip frameworks_base-694c0b833b4235b396ec1b798610d617d0ec7b5c.tar.gz frameworks_base-694c0b833b4235b396ec1b798610d617d0ec7b5c.tar.bz2 | |
Apply timeout for powerdown event and reset state machine when bluez crashes
The powerdown event was missed some time for unknown reasons and bluez could
crash for unknown reasons. We will debug on the issue. But for the time
being, we add a powerdown timer and process power up event to recover from
bluez crash
bug 5239719
Change-Id: Ie7315fb01e029747951e1a97a2d2f1dce53a997b
Diffstat (limited to 'core/java/android/server/BluetoothAdapterStateMachine.java')
| -rw-r--r-- | core/java/android/server/BluetoothAdapterStateMachine.java | 78 |
1 files changed, 75 insertions, 3 deletions
diff --git a/core/java/android/server/BluetoothAdapterStateMachine.java b/core/java/android/server/BluetoothAdapterStateMachine.java index 69fbca3..ac46ee2 100644 --- a/core/java/android/server/BluetoothAdapterStateMachine.java +++ b/core/java/android/server/BluetoothAdapterStateMachine.java @@ -109,6 +109,8 @@ final class BluetoothAdapterStateMachine extends StateMachine { private static final int DEVICES_DISCONNECT_TIMEOUT = 104; // Prepare Bluetooth timeout happens private static final int PREPARE_BLUETOOTH_TIMEOUT = 105; + // Bluetooth Powerdown timeout happens + private static final int POWER_DOWN_TIMEOUT = 106; private Context mContext; private BluetoothService mBluetoothService; @@ -129,6 +131,8 @@ final class BluetoothAdapterStateMachine extends StateMachine { private static final int PREPARE_BLUETOOTH_TIMEOUT_TIME = 10000; + private static final int POWER_DOWN_TIMEOUT_TIME = 5000; + BluetoothAdapterStateMachine(Context context, BluetoothService bluetoothService, BluetoothAdapter bluetoothAdapter) { super(TAG); @@ -386,6 +390,11 @@ final class BluetoothAdapterStateMachine extends StateMachine { break; case USER_TURN_OFF: // ignore break; + case POWER_STATE_CHANGED: + if ((Boolean) message.obj) { + recoverStateMachine(TURN_HOT, null); + } + break; default: return NOT_HANDLED; } @@ -420,14 +429,27 @@ final class BluetoothAdapterStateMachine extends StateMachine { } break; case POWER_STATE_CHANGED: + removeMessages(POWER_DOWN_TIMEOUT); if (!((Boolean) message.obj)) { - transitionTo(mHotOff); - finishSwitchingOff(); + if (mPublicState == BluetoothAdapter.STATE_TURNING_OFF) { + transitionTo(mHotOff); + finishSwitchingOff(); + } + } else { + if (mPublicState != BluetoothAdapter.STATE_TURNING_ON) { + if (mContext.getResources().getBoolean + (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) { + recoverStateMachine(TURN_HOT, null); + } else { + recoverStateMachine(TURN_COLD, null); + } + } } break; case ALL_DEVICES_DISCONNECTED: removeMessages(DEVICES_DISCONNECT_TIMEOUT); mBluetoothService.switchConnectable(false); + sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME); break; case DEVICES_DISCONNECT_TIMEOUT: sendMessage(ALL_DEVICES_DISCONNECTED); @@ -439,6 +461,17 @@ final class BluetoothAdapterStateMachine extends StateMachine { deferMessage(obtainMessage(TURN_HOT)); } break; + case POWER_DOWN_TIMEOUT: + transitionTo(mHotOff); + finishSwitchingOff(); + // reset the hardware for error recovery + Log.e(TAG, "Devices failed to power down, reseting..."); + deferMessage(obtainMessage(TURN_COLD)); + if (mContext.getResources().getBoolean + (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) { + deferMessage(obtainMessage(TURN_HOT)); + } + break; case USER_TURN_ON: case AIRPLANE_MODE_OFF: case AIRPLANE_MODE_ON: @@ -501,6 +534,7 @@ final class BluetoothAdapterStateMachine extends StateMachine { DEVICES_DISCONNECT_TIMEOUT_TIME); } else { mBluetoothService.switchConnectable(false); + sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME); } // we turn all the way to PowerOff with AIRPLANE_MODE_ON @@ -520,6 +554,12 @@ final class BluetoothAdapterStateMachine extends StateMachine { case PER_PROCESS_TURN_OFF: perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj); break; + case POWER_STATE_CHANGED: + if ((Boolean) message.obj) { + // reset the state machine and send it TURN_ON_CONTINUE message + recoverStateMachine(USER_TURN_ON, false); + } + break; default: return NOT_HANDLED; } @@ -540,7 +580,7 @@ final class BluetoothAdapterStateMachine extends StateMachine { if (what == PER_PROCESS_TURN_ON) { isTurningOn = true; - } else if (what == PER_PROCESS_TURN_OFF) { + } else if (what == USER_TURN_OFF) { isTurningOn = false; } else { Log.e(TAG, "enter PerProcessState: wrong msg: " + what); @@ -568,12 +608,31 @@ final class BluetoothAdapterStateMachine extends StateMachine { } break; case POWER_STATE_CHANGED: + removeMessages(POWER_DOWN_TIMEOUT); if (!((Boolean) message.obj)) { transitionTo(mHotOff); if (!mContext.getResources().getBoolean (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) { deferMessage(obtainMessage(TURN_COLD)); } + } else { + if (!isTurningOn) { + recoverStateMachine(TURN_COLD, null); + for (IBluetoothStateChangeCallback c: + mBluetoothService.getApplicationStateChangeCallbacks()) { + perProcessCallback(false, c); + deferMessage(obtainMessage(PER_PROCESS_TURN_ON, c)); + } + } + } + break; + case POWER_DOWN_TIMEOUT: + transitionTo(mHotOff); + Log.e(TAG, "Power-down timed out, resetting..."); + deferMessage(obtainMessage(TURN_COLD)); + if (mContext.getResources().getBoolean + (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) { + deferMessage(obtainMessage(TURN_HOT)); } break; case USER_TURN_ON: @@ -616,10 +675,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); } break; case AIRPLANE_MODE_ON: mBluetoothService.switchConnectable(false); + sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME); allProcessesCallback(false); // we turn all the way to PowerOff with AIRPLANE_MODE_ON deferMessage(obtainMessage(AIRPLANE_MODE_ON)); @@ -699,6 +760,17 @@ final class BluetoothAdapterStateMachine extends StateMachine { mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM); } + /** + * bluetoothd has crashed and recovered, the adapter state machine has to + * reset itself and try to return to previous state + */ + private void recoverStateMachine(int what, Object obj) { + Log.e(TAG, "Get unexpected power on event, reset with: " + what); + transitionTo(mHotOff); + deferMessage(obtainMessage(TURN_COLD)); + deferMessage(obtainMessage(what, obj)); + } + private void dump(PrintWriter pw) { IState currentState = getCurrentState(); if (currentState == mPowerOff) { |
