Limit the retry attemps on restarting Bluetooth
* Back off the delay time of resarting Bluetooth when
there's continous turn on failures.
* Stop to restart Bluetooth if we are seeing back to
back Bluetooth crashes, so we won't see endless
diaglogs popping out.
Bug: 144572641
Test: Manual
Change-Id: Ifeffa214256eab61901c123fc88b037fc6d7dd50
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 208b638..798a4c6 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -98,7 +98,7 @@
private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind
//Maximum msec to wait for service restart
- private static final int SERVICE_RESTART_TIME_MS = 200;
+ private static final int SERVICE_RESTART_TIME_MS = 400;
//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
@@ -1635,13 +1635,13 @@
// ActivityManager detects it.
// The waiting for (b) and (c) is accomplished by
// delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
- // message. On slower devices, that delay needs to be
- // on the order of (2 * SERVICE_RESTART_TIME_MS).
+ // message. The delay time is backed off if Bluetooth
+ // continuously failed to turn on itself.
//
waitForOnOff(false, true);
Message restartMsg =
mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
- mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
+ mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
}
break;
@@ -1820,7 +1820,7 @@
waitForOnOff(false, true);
Message restartMsg =
mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
- mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
+ mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
}
}
if (newState == BluetoothAdapter.STATE_ON
@@ -1863,7 +1863,7 @@
// Send a Bluetooth Restart message
Message restartMsg =
mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
- mHandler.sendMessageDelayed(restartMsg, SERVICE_RESTART_TIME_MS);
+ mHandler.sendMessageDelayed(restartMsg, getServiceRestartMs());
}
sendBluetoothServiceDownCallback();
@@ -1886,14 +1886,20 @@
break;
}
case MESSAGE_RESTART_BLUETOOTH_SERVICE: {
- Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE");
- /* Enable without persisting the setting as
- it doesnt change when IBluetooth
- service restarts */
- mEnable = true;
- addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED,
- mContext.getPackageName(), true);
- handleEnable(mQuietEnable);
+ mErrorRecoveryRetryCounter++;
+ Slog.d(TAG, "MESSAGE_RESTART_BLUETOOTH_SERVICE: retry count="
+ + mErrorRecoveryRetryCounter);
+ if (mErrorRecoveryRetryCounter < MAX_ERROR_RESTART_RETRIES) {
+ /* Enable without persisting the setting as
+ it doesnt change when IBluetooth
+ service restarts */
+ mEnable = true;
+ addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTARTED,
+ mContext.getPackageName(), true);
+ handleEnable(mQuietEnable);
+ } else {
+ Slog.e(TAG, "Reach maximum retry to restart Bluetooth!");
+ }
break;
}
case MESSAGE_TIMEOUT_BIND: {
@@ -2332,13 +2338,9 @@
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.
- }
+ // Send a Bluetooth Restart message to reenable bluetooth
+ Message restartMsg = mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
+ mHandler.sendMessageDelayed(restartMsg, ERROR_RESTART_TIME_MS);
}
private boolean isBluetoothDisallowed() {
@@ -2374,6 +2376,10 @@
}
}
+ private int getServiceRestartMs() {
+ return (mErrorRecoveryRetryCounter + 1) * SERVICE_RESTART_TIME_MS;
+ }
+
@Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) {