am b390728b: am a224f70b: Fix interaction between BluetoothEventLoop and BluetoothService.
Merge commit 'b390728b54805ecba3e0690edf2b83b60933e6a7'
* commit 'b390728b54805ecba3e0690edf2b83b60933e6a7':
Fix interaction between BluetoothEventLoop and BluetoothService.
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 796aee8..ab79aaf 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -59,22 +59,14 @@
// from remote device when Android is in Suspend state.
private PowerManager.WakeLock mWakeLock;
- private static final int EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 1;
- private static final int EVENT_RESTART_BLUETOOTH = 2;
- private static final int EVENT_PAIRING_CONSENT_DELAYED_ACCEPT = 3;
- private static final int EVENT_AGENT_CANCEL = 4;
+ private static final int EVENT_RESTART_BLUETOOTH = 1;
+ private static final int EVENT_PAIRING_CONSENT_DELAYED_ACCEPT = 2;
+ private static final int EVENT_AGENT_CANCEL = 3;
private static final int CREATE_DEVICE_ALREADY_EXISTS = 1;
private static final int CREATE_DEVICE_SUCCESS = 0;
private static final int CREATE_DEVICE_FAILED = -1;
- // The time (in millisecs) to delay the pairing attempt after the first
- // auto pairing attempt fails. We use an exponential delay with
- // INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY as the initial value and
- // MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY as the max value.
- private static final long INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 3000;
- private static final long MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 12000;
-
private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
@@ -83,13 +75,6 @@
public void handleMessage(Message msg) {
String address = null;
switch (msg.what) {
- case EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY:
- address = (String)msg.obj;
- if (address != null) {
- mBluetoothService.createBond(address);
- return;
- }
- break;
case EVENT_RESTART_BLUETOOTH:
mBluetoothService.restart();
break;
@@ -102,8 +87,7 @@
case EVENT_AGENT_CANCEL:
// Set the Bond State to BOND_NONE.
// We always have only 1 device in BONDING state.
- String[] devices =
- mBluetoothService.getBondState().listInState(BluetoothDevice.BOND_BONDING);
+ String[] devices = mBluetoothService.listInState(BluetoothDevice.BOND_BONDING);
if (devices.length == 0) {
break;
} else if (devices.length > 1) {
@@ -111,7 +95,7 @@
break;
}
address = devices[0];
- mBluetoothService.getBondState().setBondState(address,
+ mBluetoothService.setBondState(address,
BluetoothDevice.BOND_NONE,
BluetoothDevice.UNBOND_REASON_REMOTE_AUTH_CANCELED);
break;
@@ -122,7 +106,7 @@
static { classInitNative(); }
private static native void classInitNative();
- /* pacakge */ BluetoothEventLoop(Context context, BluetoothAdapter adapter,
+ /* package */ BluetoothEventLoop(Context context, BluetoothAdapter adapter,
BluetoothService bluetoothService) {
mBluetoothService = bluetoothService;
mContext = context;
@@ -221,55 +205,7 @@
private void onCreatePairedDeviceResult(String address, int result) {
address = address.toUpperCase();
- if (result == BluetoothDevice.BOND_SUCCESS) {
- mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDED);
- if (mBluetoothService.getBondState().isAutoPairingAttemptsInProgress(address)) {
- mBluetoothService.getBondState().clearPinAttempts(address);
- }
- } else if (result == BluetoothDevice.UNBOND_REASON_AUTH_FAILED &&
- mBluetoothService.getBondState().getAttempt(address) == 1) {
- mBluetoothService.getBondState().addAutoPairingFailure(address);
- pairingAttempt(address, result);
- } else if (result == BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN &&
- mBluetoothService.getBondState().isAutoPairingAttemptsInProgress(address)) {
- pairingAttempt(address, result);
- } else {
- mBluetoothService.getBondState().setBondState(address,
- BluetoothDevice.BOND_NONE, result);
- if (mBluetoothService.getBondState().isAutoPairingAttemptsInProgress(address)) {
- mBluetoothService.getBondState().clearPinAttempts(address);
- }
- }
- }
-
- private void pairingAttempt(String address, int result) {
- // This happens when our initial guess of "0000" as the pass key
- // fails. Try to create the bond again and display the pin dialog
- // to the user. Use back-off while posting the delayed
- // message. The initial value is
- // INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY and the max value is
- // MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY. If the max value is
- // reached, display an error to the user.
- int attempt = mBluetoothService.getBondState().getAttempt(address);
- if (attempt * INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY >
- MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY) {
- mBluetoothService.getBondState().clearPinAttempts(address);
- mBluetoothService.getBondState().setBondState(address,
- BluetoothDevice.BOND_NONE, result);
- return;
- }
-
- Message message = mHandler.obtainMessage(EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY);
- message.obj = address;
- boolean postResult = mHandler.sendMessageDelayed(message,
- attempt * INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY);
- if (!postResult) {
- mBluetoothService.getBondState().clearPinAttempts(address);
- mBluetoothService.getBondState().setBondState(address,
- BluetoothDevice.BOND_NONE, result);
- return;
- }
- mBluetoothService.getBondState().attempt(address);
+ mBluetoothService.onCreatePairedDeviceResult(address, result);
}
private void onDeviceCreated(String deviceObjectPath) {
@@ -287,8 +223,8 @@
private void onDeviceRemoved(String deviceObjectPath) {
String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
if (address != null) {
- mBluetoothService.getBondState().setBondState(address.toUpperCase(),
- BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_REMOVED);
+ mBluetoothService.setBondState(address.toUpperCase(), BluetoothDevice.BOND_NONE,
+ BluetoothDevice.UNBOND_REASON_REMOVED);
mBluetoothService.setRemoteDeviceProperty(address, "UUIDs", null);
}
}
@@ -420,13 +356,11 @@
// If locally initiated pairing, we will
// not go to BOND_BONDED state until we have received a
// successful return value in onCreatePairedDeviceResult
- if (null == mBluetoothService.getBondState().getPendingOutgoingBonding()) {
- mBluetoothService.getBondState().setBondState(address,
- BluetoothDevice.BOND_BONDED);
+ if (null == mBluetoothService.getPendingOutgoingBonding()) {
+ mBluetoothService.setBondState(address, BluetoothDevice.BOND_BONDED);
}
} else {
- mBluetoothService.getBondState().setBondState(address,
- BluetoothDevice.BOND_NONE);
+ mBluetoothService.setBondState(address, BluetoothDevice.BOND_NONE);
mBluetoothService.setRemoteDeviceProperty(address, "Trusted", "false");
}
} else if (name.equals("Trusted")) {
@@ -494,8 +428,8 @@
// Also set it only when the state is not already Bonded, we can sometimes
// get an authorization request from the remote end if it doesn't have the link key
// while we still have it.
- if (mBluetoothService.getBondState().getBondState(address) != BluetoothDevice.BOND_BONDED)
- mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDING);
+ if (mBluetoothService.getBondState(address) != BluetoothDevice.BOND_BONDED)
+ mBluetoothService.setBondState(address, BluetoothDevice.BOND_BONDING);
return address;
}
@@ -509,7 +443,7 @@
* so we may get this request many times. Also if we respond immediately,
* the other end is unable to handle it. Delay sending the message.
*/
- if (mBluetoothService.getBondState().getBondState(address) == BluetoothDevice.BOND_BONDED) {
+ if (mBluetoothService.getBondState(address) == BluetoothDevice.BOND_BONDED) {
Message message = mHandler.obtainMessage(EVENT_PAIRING_CONSENT_DELAYED_ACCEPT);
message.obj = address;
mHandler.sendMessageDelayed(message, 1500);
@@ -563,7 +497,7 @@
if (address == null) return;
String pendingOutgoingAddress =
- mBluetoothService.getBondState().getPendingOutgoingBonding();
+ mBluetoothService.getPendingOutgoingBonding();
if (address.equals(pendingOutgoingAddress)) {
// we initiated the bonding
@@ -584,12 +518,7 @@
case BluetoothClass.Device.AUDIO_VIDEO_PORTABLE_AUDIO:
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
- if (!mBluetoothService.getBondState().hasAutoPairingFailed(address) &&
- !mBluetoothService.getBondState().isAutoPairingBlacklisted(address)) {
- mBluetoothService.getBondState().attempt(address);
- mBluetoothService.setPin(address, BluetoothDevice.convertPinToBytes("0000"));
- return;
- }
+ if (mBluetoothService.attemptAutoPair(address)) return;
}
}
// Acquire wakelock during PIN code request to bring up LCD display
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index f8fcdb5..7f160c4 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -113,6 +113,14 @@
private static final int MESSAGE_FINISH_DISABLE = 2;
private static final int MESSAGE_UUID_INTENT = 3;
private static final int MESSAGE_DISCOVERABLE_TIMEOUT = 4;
+ private static final int MESSAGE_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 5;
+
+ // The time (in millisecs) to delay the pairing attempt after the first
+ // auto pairing attempt fails. We use an exponential delay with
+ // INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY as the initial value and
+ // MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY as the max value.
+ private static final long INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 3000;
+ private static final long MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 12000;
private ArrayList<String> mBluetoothIfaceAddresses;
private int mMaxPanDevices;
@@ -536,6 +544,13 @@
setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE, -1);
}
break;
+ case MESSAGE_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY:
+ address = (String)msg.obj;
+ if (address != null) {
+ createBond(address);
+ return;
+ }
+ break;
}
}
};
@@ -629,8 +644,68 @@
Binder.restoreCallingIdentity(origCallerIdentityToken);
}
- /* package */ BondState getBondState() {
- return mBondState;
+ /*package*/ synchronized boolean attemptAutoPair(String address) {
+ if (!mBondState.hasAutoPairingFailed(address) &&
+ !mBondState.isAutoPairingBlacklisted(address)) {
+ mBondState.attempt(address);
+ setPin(address, BluetoothDevice.convertPinToBytes("0000"));
+ return true;
+ }
+ return false;
+ }
+
+ /*package*/ synchronized void onCreatePairedDeviceResult(String address, int result) {
+ if (result == BluetoothDevice.BOND_SUCCESS) {
+ setBondState(address, BluetoothDevice.BOND_BONDED);
+ if (mBondState.isAutoPairingAttemptsInProgress(address)) {
+ mBondState.clearPinAttempts(address);
+ }
+ } else if (result == BluetoothDevice.UNBOND_REASON_AUTH_FAILED &&
+ mBondState.getAttempt(address) == 1) {
+ mBondState.addAutoPairingFailure(address);
+ pairingAttempt(address, result);
+ } else if (result == BluetoothDevice.UNBOND_REASON_REMOTE_DEVICE_DOWN &&
+ mBondState.isAutoPairingAttemptsInProgress(address)) {
+ pairingAttempt(address, result);
+ } else {
+ setBondState(address, BluetoothDevice.BOND_NONE, result);
+ if (mBondState.isAutoPairingAttemptsInProgress(address)) {
+ mBondState.clearPinAttempts(address);
+ }
+ }
+ }
+
+ /*package*/ synchronized String getPendingOutgoingBonding() {
+ return mBondState.getPendingOutgoingBonding();
+ }
+
+ private void pairingAttempt(String address, int result) {
+ // This happens when our initial guess of "0000" as the pass key
+ // fails. Try to create the bond again and display the pin dialog
+ // to the user. Use back-off while posting the delayed
+ // message. The initial value is
+ // INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY and the max value is
+ // MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY. If the max value is
+ // reached, display an error to the user.
+ int attempt = mBondState.getAttempt(address);
+ if (attempt * INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY >
+ MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY) {
+ mBondState.clearPinAttempts(address);
+ setBondState(address, BluetoothDevice.BOND_NONE, result);
+ return;
+ }
+
+ Message message = mHandler.obtainMessage(MESSAGE_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY);
+ message.obj = address;
+ boolean postResult = mHandler.sendMessageDelayed(message,
+ attempt * INIT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY);
+ if (!postResult) {
+ mBondState.clearPinAttempts(address);
+ setBondState(address,
+ BluetoothDevice.BOND_NONE, result);
+ return;
+ }
+ mBondState.attempt(address);
}
/** local cache of bonding state.
@@ -1301,6 +1376,10 @@
return mBondState.listInState(BluetoothDevice.BOND_BONDED);
}
+ /*package*/ synchronized String[] listInState(int state) {
+ return mBondState.listInState(state);
+ }
+
public synchronized int getBondState(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
@@ -1309,6 +1388,15 @@
return mBondState.getBondState(address.toUpperCase());
}
+ /*package*/ synchronized boolean setBondState(String address, int state) {
+ return setBondState(address, state, 0);
+ }
+
+ /*package*/ synchronized boolean setBondState(String address, int state, int reason) {
+ mBondState.setBondState(address.toUpperCase(), state);
+ return true;
+ }
+
public synchronized boolean isBluetoothDock(String address) {
SharedPreferences sp = mContext.getSharedPreferences(SHARED_PREFERENCES_NAME,
mContext.MODE_PRIVATE);