Merge "Apply timeout for powerdown event and reset state machine when bluez crashes"
This commit is contained in:
@@ -109,6 +109,8 @@ final class BluetoothAdapterStateMachine extends StateMachine {
|
|||||||
private static final int DEVICES_DISCONNECT_TIMEOUT = 104;
|
private static final int DEVICES_DISCONNECT_TIMEOUT = 104;
|
||||||
// Prepare Bluetooth timeout happens
|
// Prepare Bluetooth timeout happens
|
||||||
private static final int PREPARE_BLUETOOTH_TIMEOUT = 105;
|
private static final int PREPARE_BLUETOOTH_TIMEOUT = 105;
|
||||||
|
// Bluetooth Powerdown timeout happens
|
||||||
|
private static final int POWER_DOWN_TIMEOUT = 106;
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private BluetoothService mBluetoothService;
|
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 PREPARE_BLUETOOTH_TIMEOUT_TIME = 10000;
|
||||||
|
|
||||||
|
private static final int POWER_DOWN_TIMEOUT_TIME = 5000;
|
||||||
|
|
||||||
BluetoothAdapterStateMachine(Context context, BluetoothService bluetoothService,
|
BluetoothAdapterStateMachine(Context context, BluetoothService bluetoothService,
|
||||||
BluetoothAdapter bluetoothAdapter) {
|
BluetoothAdapter bluetoothAdapter) {
|
||||||
super(TAG);
|
super(TAG);
|
||||||
@@ -386,6 +390,11 @@ final class BluetoothAdapterStateMachine extends StateMachine {
|
|||||||
break;
|
break;
|
||||||
case USER_TURN_OFF: // ignore
|
case USER_TURN_OFF: // ignore
|
||||||
break;
|
break;
|
||||||
|
case POWER_STATE_CHANGED:
|
||||||
|
if ((Boolean) message.obj) {
|
||||||
|
recoverStateMachine(TURN_HOT, null);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return NOT_HANDLED;
|
return NOT_HANDLED;
|
||||||
}
|
}
|
||||||
@@ -420,14 +429,27 @@ final class BluetoothAdapterStateMachine extends StateMachine {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case POWER_STATE_CHANGED:
|
case POWER_STATE_CHANGED:
|
||||||
|
removeMessages(POWER_DOWN_TIMEOUT);
|
||||||
if (!((Boolean) message.obj)) {
|
if (!((Boolean) message.obj)) {
|
||||||
transitionTo(mHotOff);
|
if (mPublicState == BluetoothAdapter.STATE_TURNING_OFF) {
|
||||||
finishSwitchingOff();
|
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;
|
break;
|
||||||
case ALL_DEVICES_DISCONNECTED:
|
case ALL_DEVICES_DISCONNECTED:
|
||||||
removeMessages(DEVICES_DISCONNECT_TIMEOUT);
|
removeMessages(DEVICES_DISCONNECT_TIMEOUT);
|
||||||
mBluetoothService.switchConnectable(false);
|
mBluetoothService.switchConnectable(false);
|
||||||
|
sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME);
|
||||||
break;
|
break;
|
||||||
case DEVICES_DISCONNECT_TIMEOUT:
|
case DEVICES_DISCONNECT_TIMEOUT:
|
||||||
sendMessage(ALL_DEVICES_DISCONNECTED);
|
sendMessage(ALL_DEVICES_DISCONNECTED);
|
||||||
@@ -439,6 +461,17 @@ final class BluetoothAdapterStateMachine extends StateMachine {
|
|||||||
deferMessage(obtainMessage(TURN_HOT));
|
deferMessage(obtainMessage(TURN_HOT));
|
||||||
}
|
}
|
||||||
break;
|
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 USER_TURN_ON:
|
||||||
case AIRPLANE_MODE_OFF:
|
case AIRPLANE_MODE_OFF:
|
||||||
case AIRPLANE_MODE_ON:
|
case AIRPLANE_MODE_ON:
|
||||||
@@ -501,6 +534,7 @@ final class BluetoothAdapterStateMachine extends StateMachine {
|
|||||||
DEVICES_DISCONNECT_TIMEOUT_TIME);
|
DEVICES_DISCONNECT_TIMEOUT_TIME);
|
||||||
} else {
|
} else {
|
||||||
mBluetoothService.switchConnectable(false);
|
mBluetoothService.switchConnectable(false);
|
||||||
|
sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
// we turn all the way to PowerOff with AIRPLANE_MODE_ON
|
// 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:
|
case PER_PROCESS_TURN_OFF:
|
||||||
perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj);
|
perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj);
|
||||||
break;
|
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:
|
default:
|
||||||
return NOT_HANDLED;
|
return NOT_HANDLED;
|
||||||
}
|
}
|
||||||
@@ -540,7 +580,7 @@ final class BluetoothAdapterStateMachine extends StateMachine {
|
|||||||
|
|
||||||
if (what == PER_PROCESS_TURN_ON) {
|
if (what == PER_PROCESS_TURN_ON) {
|
||||||
isTurningOn = true;
|
isTurningOn = true;
|
||||||
} else if (what == PER_PROCESS_TURN_OFF) {
|
} else if (what == USER_TURN_OFF) {
|
||||||
isTurningOn = false;
|
isTurningOn = false;
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "enter PerProcessState: wrong msg: " + what);
|
Log.e(TAG, "enter PerProcessState: wrong msg: " + what);
|
||||||
@@ -568,12 +608,31 @@ final class BluetoothAdapterStateMachine extends StateMachine {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case POWER_STATE_CHANGED:
|
case POWER_STATE_CHANGED:
|
||||||
|
removeMessages(POWER_DOWN_TIMEOUT);
|
||||||
if (!((Boolean) message.obj)) {
|
if (!((Boolean) message.obj)) {
|
||||||
transitionTo(mHotOff);
|
transitionTo(mHotOff);
|
||||||
if (!mContext.getResources().getBoolean
|
if (!mContext.getResources().getBoolean
|
||||||
(com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
|
(com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
|
||||||
deferMessage(obtainMessage(TURN_COLD));
|
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;
|
break;
|
||||||
case USER_TURN_ON:
|
case USER_TURN_ON:
|
||||||
@@ -616,10 +675,12 @@ final class BluetoothAdapterStateMachine extends StateMachine {
|
|||||||
perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj);
|
perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj);
|
||||||
if (mBluetoothService.isApplicationStateChangeTrackerEmpty()) {
|
if (mBluetoothService.isApplicationStateChangeTrackerEmpty()) {
|
||||||
mBluetoothService.switchConnectable(false);
|
mBluetoothService.switchConnectable(false);
|
||||||
|
sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AIRPLANE_MODE_ON:
|
case AIRPLANE_MODE_ON:
|
||||||
mBluetoothService.switchConnectable(false);
|
mBluetoothService.switchConnectable(false);
|
||||||
|
sendMessageDelayed(POWER_DOWN_TIMEOUT, POWER_DOWN_TIMEOUT_TIME);
|
||||||
allProcessesCallback(false);
|
allProcessesCallback(false);
|
||||||
// we turn all the way to PowerOff with AIRPLANE_MODE_ON
|
// we turn all the way to PowerOff with AIRPLANE_MODE_ON
|
||||||
deferMessage(obtainMessage(AIRPLANE_MODE_ON));
|
deferMessage(obtainMessage(AIRPLANE_MODE_ON));
|
||||||
@@ -699,6 +760,17 @@ final class BluetoothAdapterStateMachine extends StateMachine {
|
|||||||
mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
|
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) {
|
private void dump(PrintWriter pw) {
|
||||||
IState currentState = getCurrentState();
|
IState currentState = getCurrentState();
|
||||||
if (currentState == mPowerOff) {
|
if (currentState == mPowerOff) {
|
||||||
|
|||||||
@@ -59,9 +59,8 @@ class BluetoothEventLoop {
|
|||||||
// from remote device when Android is in Suspend state.
|
// from remote device when Android is in Suspend state.
|
||||||
private PowerManager.WakeLock mWakeLock;
|
private PowerManager.WakeLock mWakeLock;
|
||||||
|
|
||||||
private static final int EVENT_RESTART_BLUETOOTH = 1;
|
private static final int EVENT_PAIRING_CONSENT_DELAYED_ACCEPT = 1;
|
||||||
private static final int EVENT_PAIRING_CONSENT_DELAYED_ACCEPT = 2;
|
private static final int EVENT_AGENT_CANCEL = 2;
|
||||||
private static final int EVENT_AGENT_CANCEL = 3;
|
|
||||||
|
|
||||||
private static final int CREATE_DEVICE_ALREADY_EXISTS = 1;
|
private static final int CREATE_DEVICE_ALREADY_EXISTS = 1;
|
||||||
private static final int CREATE_DEVICE_SUCCESS = 0;
|
private static final int CREATE_DEVICE_SUCCESS = 0;
|
||||||
@@ -75,9 +74,6 @@ class BluetoothEventLoop {
|
|||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
String address = null;
|
String address = null;
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case EVENT_RESTART_BLUETOOTH:
|
|
||||||
mBluetoothService.restart();
|
|
||||||
break;
|
|
||||||
case EVENT_PAIRING_CONSENT_DELAYED_ACCEPT:
|
case EVENT_PAIRING_CONSENT_DELAYED_ACCEPT:
|
||||||
address = (String)msg.obj;
|
address = (String)msg.obj;
|
||||||
if (address != null) {
|
if (address != null) {
|
||||||
@@ -375,9 +371,6 @@ class BluetoothEventLoop {
|
|||||||
} else if (name.equals("Powered")) {
|
} else if (name.equals("Powered")) {
|
||||||
mBluetoothState.sendMessage(BluetoothAdapterStateMachine.POWER_STATE_CHANGED,
|
mBluetoothState.sendMessage(BluetoothAdapterStateMachine.POWER_STATE_CHANGED,
|
||||||
propValues[1].equals("true") ? new Boolean(true) : new Boolean(false));
|
propValues[1].equals("true") ? new Boolean(true) : new Boolean(false));
|
||||||
// bluetoothd has restarted, re-read all our properties.
|
|
||||||
// Note: bluez only sends this property change when it restarts.
|
|
||||||
onRestartRequired();
|
|
||||||
} else if (name.equals("DiscoverableTimeout")) {
|
} else if (name.equals("DiscoverableTimeout")) {
|
||||||
adapterProperties.setProperty(name, propValues[1]);
|
adapterProperties.setProperty(name, propValues[1]);
|
||||||
}
|
}
|
||||||
@@ -1033,14 +1026,6 @@ class BluetoothEventLoop {
|
|||||||
mBluetoothService.onHealthDeviceChannelChanged(devicePath, channelPath, exists);
|
mBluetoothService.onHealthDeviceChannelChanged(devicePath, channelPath, exists);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onRestartRequired() {
|
|
||||||
if (mBluetoothService.isEnabled()) {
|
|
||||||
Log.e(TAG, "*** A serious error occurred (did bluetoothd crash?) - " +
|
|
||||||
"restarting Bluetooth ***");
|
|
||||||
mHandler.sendEmptyMessage(EVENT_RESTART_BLUETOOTH);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void log(String msg) {
|
private static void log(String msg) {
|
||||||
Log.d(TAG, msg);
|
Log.d(TAG, msg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,6 @@ public class BluetoothService extends IBluetooth.Stub {
|
|||||||
private boolean mIsAirplaneSensitive;
|
private boolean mIsAirplaneSensitive;
|
||||||
private boolean mIsAirplaneToggleable;
|
private boolean mIsAirplaneToggleable;
|
||||||
private BluetoothAdapterStateMachine mBluetoothState;
|
private BluetoothAdapterStateMachine mBluetoothState;
|
||||||
private boolean mRestart = false; // need to call enable() after disable()
|
|
||||||
private int[] mAdapterSdpHandles;
|
private int[] mAdapterSdpHandles;
|
||||||
private ParcelUuid[] mAdapterUuids;
|
private ParcelUuid[] mAdapterUuids;
|
||||||
|
|
||||||
@@ -429,11 +428,6 @@ public class BluetoothService extends IBluetooth.Stub {
|
|||||||
} finally {
|
} finally {
|
||||||
Binder.restoreCallingIdentity(ident);
|
Binder.restoreCallingIdentity(ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mRestart) {
|
|
||||||
mRestart = false;
|
|
||||||
enable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -456,10 +450,6 @@ public class BluetoothService extends IBluetooth.Stub {
|
|||||||
// the adapter property could be changed before event loop is stoped, clear it again
|
// the adapter property could be changed before event loop is stoped, clear it again
|
||||||
mAdapterProperties.clear();
|
mAdapterProperties.clear();
|
||||||
disableNative();
|
disableNative();
|
||||||
if (mRestart) {
|
|
||||||
mRestart = false;
|
|
||||||
enable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Bring up BT and persist BT on in settings */
|
/** Bring up BT and persist BT on in settings */
|
||||||
@@ -500,17 +490,6 @@ public class BluetoothService extends IBluetooth.Stub {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Forcibly restart Bluetooth if it is on */
|
|
||||||
/* package */ synchronized void restart() {
|
|
||||||
if (getBluetoothStateInternal() != BluetoothAdapter.STATE_ON) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mRestart = true;
|
|
||||||
if (!disable(false)) {
|
|
||||||
mRestart = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Handler mHandler = new Handler() {
|
private final Handler mHandler = new Handler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
|
|||||||
Reference in New Issue
Block a user