summaryrefslogtreecommitdiffstats
path: root/services/java
diff options
context:
space:
mode:
authorMatthew Xie <mattx@google.com>2013-05-14 23:18:04 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-05-14 23:18:04 +0000
commitf270fc3b5014e39614f7e6499cd6aa4ea18e8616 (patch)
treec73763175b8e5a7da4ae7846b62b8c32313f7694 /services/java
parent7c6ebac75dd75382dbc71e8a5ca943d29266af06 (diff)
parentdd9d17d45836bc1cc00136e088445fbca9244e0e (diff)
downloadframeworks_base-f270fc3b5014e39614f7e6499cd6aa4ea18e8616.zip
frameworks_base-f270fc3b5014e39614f7e6499cd6aa4ea18e8616.tar.gz
frameworks_base-f270fc3b5014e39614f7e6499cd6aa4ea18e8616.tar.bz2
Merge "cannot turn on bluetooth" into jb-mr2-dev
Diffstat (limited to 'services/java')
-rw-r--r--services/java/com/android/server/BluetoothManagerService.java64
1 files changed, 64 insertions, 0 deletions
diff --git a/services/java/com/android/server/BluetoothManagerService.java b/services/java/com/android/server/BluetoothManagerService.java
index f7a7fdf..bea2cca 100644
--- a/services/java/com/android/server/BluetoothManagerService.java
+++ b/services/java/com/android/server/BluetoothManagerService.java
@@ -60,6 +60,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private static final int TIMEOUT_SAVE_MS = 500; //Maximum msec to wait for a save
//Maximum msec to wait for service restart
private static final int SERVICE_RESTART_TIME_MS = 200;
+ //Maximum msec to wait for restart due to error
+ private static final int ERROR_RESTART_TIME_MS = 3000;
//Maximum msec to delay MESSAGE_USER_SWITCHED
private static final int USER_SWITCHED_TIME_MS = 200;
@@ -79,6 +81,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private static final int MESSAGE_SAVE_NAME_AND_ADDRESS=201;
private static final int MESSAGE_USER_SWITCHED = 300;
private static final int MAX_SAVE_RETRIES=3;
+ private static final int MAX_ERROR_RESTART_RETRIES=6;
+
// Bluetooth persisted setting is off
private static final int BLUETOOTH_OFF=0;
// Bluetooth persisted setting is on
@@ -118,6 +122,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private int mState;
private HandlerThread mThread;
private final BluetoothHandler mHandler;
+ private int mErrorRecoveryRetryCounter;
private void registerForAirplaneMode(IntentFilter filter) {
final ContentResolver resolver = mContext.getContentResolver();
@@ -203,6 +208,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
mEnableExternal = false;
mAddress = null;
mName = null;
+ mErrorRecoveryRetryCounter = 0;
mContentResolver = context.getContentResolver();
mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
@@ -847,6 +853,20 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
if (DBG) Log.d(TAG, "MESSAGE_BLUETOOTH_STATE_CHANGE: prevState = " + prevState + ", newState=" + newState);
mState = newState;
bluetoothStateChangeHandler(prevState, newState);
+ // handle error state transition case from TURNING_ON to OFF
+ // unbind and rebind bluetooth service and enable bluetooth
+ if ((prevState == BluetoothAdapter.STATE_TURNING_ON) &&
+ (newState == BluetoothAdapter.STATE_OFF) &&
+ (mBluetooth != null) && mEnable) {
+ recoverBluetoothServiceFromError();
+ }
+ if (newState == BluetoothAdapter.STATE_ON) {
+ // bluetooth is working, reset the counter
+ if (mErrorRecoveryRetryCounter != 0) {
+ Log.w(TAG, "bluetooth is recovered from error");
+ mErrorRecoveryRetryCounter = 0;
+ }
+ }
break;
}
case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED:
@@ -1181,4 +1201,48 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
}
return false;
}
+
+ private void recoverBluetoothServiceFromError() {
+ Log.e(TAG,"recoverBluetoothServiceFromError");
+ synchronized (mConnection) {
+ if (mBluetooth != null) {
+ //Unregister callback object
+ try {
+ mBluetooth.unregisterCallback(mBluetoothCallback);
+ } catch (RemoteException re) {
+ Log.e(TAG, "Unable to unregister",re);
+ }
+ }
+ }
+
+ SystemClock.sleep(500);
+
+ // disable
+ handleDisable();
+
+ waitForOnOff(false, true);
+
+ sendBluetoothServiceDownCallback();
+ synchronized (mConnection) {
+ if (mBluetooth != null) {
+ mBluetooth = null;
+ //Unbind
+ mContext.unbindService(mConnection);
+ }
+ }
+
+ mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
+ mState = BluetoothAdapter.STATE_OFF;
+
+ mEnable = false;
+
+ if (mErrorRecoveryRetryCounter++ < MAX_ERROR_RESTART_RETRIES) {
+ // Send a Bluetooth Restart message to reenable bluetooth
+ Message restartMsg = mHandler.obtainMessage(
+ MESSAGE_RESTART_BLUETOOTH_SERVICE);
+ mHandler.sendMessageDelayed(restartMsg, ERROR_RESTART_TIME_MS);
+ } else {
+ // todo: notify user to power down and power up phone to make bluetooth work.
+ }
+ }
}