diff options
| author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:45 -0800 |
|---|---|---|
| committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:45 -0800 |
| commit | d83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (patch) | |
| tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /core/java/android/server/BluetoothEventLoop.java | |
| parent | 076357b8567458d4b6dfdcf839ef751634cd2bfb (diff) | |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'core/java/android/server/BluetoothEventLoop.java')
| -rw-r--r-- | core/java/android/server/BluetoothEventLoop.java | 373 |
1 files changed, 0 insertions, 373 deletions
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java deleted file mode 100644 index 8b09583492d4..000000000000 --- a/core/java/android/server/BluetoothEventLoop.java +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.server; - -import android.bluetooth.BluetoothA2dp; -import android.bluetooth.BluetoothClass; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothError; -import android.bluetooth.BluetoothIntent; -import android.bluetooth.IBluetoothDeviceCallback; -import android.content.Context; -import android.content.Intent; -import android.os.Handler; -import android.os.Message; -import android.os.RemoteException; -import android.util.Log; - -import java.util.HashMap; - -/** - * TODO: Move this to - * java/services/com/android/server/BluetoothEventLoop.java - * and make the contructor package private again. - * - * @hide - */ -class BluetoothEventLoop { - private static final String TAG = "BluetoothEventLoop"; - private static final boolean DBG = false; - - private int mNativeData; - private Thread mThread; - private boolean mInterrupted; - private HashMap<String, Integer> mPasskeyAgentRequestData; - private HashMap<String, IBluetoothDeviceCallback> mGetRemoteServiceChannelCallbacks; - private BluetoothDeviceService mBluetoothService; - private Context mContext; - - private static final int EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 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; - - private final Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY: - String address = (String)msg.obj; - if (address != null) { - mBluetoothService.createBond(address); - return; - } - break; - } - } - }; - - static { classInitNative(); } - private static native void classInitNative(); - - /* pacakge */ BluetoothEventLoop(Context context, BluetoothDeviceService bluetoothService) { - mBluetoothService = bluetoothService; - mContext = context; - mPasskeyAgentRequestData = new HashMap(); - mGetRemoteServiceChannelCallbacks = new HashMap(); - initializeNativeDataNative(); - } - private native void initializeNativeDataNative(); - - protected void finalize() throws Throwable { - try { - cleanupNativeDataNative(); - } finally { - super.finalize(); - } - } - private native void cleanupNativeDataNative(); - - /* pacakge */ HashMap<String, IBluetoothDeviceCallback> getRemoteServiceChannelCallbacks() { - return mGetRemoteServiceChannelCallbacks; - } - - /* pacakge */ HashMap<String, Integer> getPasskeyAgentRequestData() { - return mPasskeyAgentRequestData; - } - - private synchronized boolean waitForAndDispatchEvent(int timeout_ms) { - return waitForAndDispatchEventNative(timeout_ms); - } - private native boolean waitForAndDispatchEventNative(int timeout_ms); - - /* package */ synchronized void start() { - - if (mThread != null) { - // Already running. - return; - } - mThread = new Thread("Bluetooth Event Loop") { - @Override - public void run() { - try { - if (setUpEventLoopNative()) { - while (!mInterrupted) { - waitForAndDispatchEvent(0); - sleep(500); - } - tearDownEventLoopNative(); - } - } catch (InterruptedException e) { } - if (DBG) log("Event Loop thread finished"); - } - }; - if (DBG) log("Starting Event Loop thread"); - mInterrupted = false; - mThread.start(); - } - private native boolean setUpEventLoopNative(); - private native void tearDownEventLoopNative(); - - public synchronized void stop() { - if (mThread != null) { - mInterrupted = true; - try { - mThread.join(); - mThread = null; - } catch (InterruptedException e) { - Log.i(TAG, "Interrupted waiting for Event Loop thread to join"); - } - } - } - - public synchronized boolean isEventLoopRunning() { - return mThread != null; - } - - /*package*/ void onModeChanged(String bluezMode) { - int mode = BluetoothDeviceService.bluezStringToScanMode(bluezMode); - if (mode >= 0) { - Intent intent = new Intent(BluetoothIntent.SCAN_MODE_CHANGED_ACTION); - intent.putExtra(BluetoothIntent.SCAN_MODE, mode); - mContext.sendBroadcast(intent, BLUETOOTH_PERM); - } - } - - private void onDiscoveryStarted() { - mBluetoothService.setIsDiscovering(true); - Intent intent = new Intent(BluetoothIntent.DISCOVERY_STARTED_ACTION); - mContext.sendBroadcast(intent, BLUETOOTH_PERM); - } - private void onDiscoveryCompleted() { - mBluetoothService.setIsDiscovering(false); - Intent intent = new Intent(BluetoothIntent.DISCOVERY_COMPLETED_ACTION); - mContext.sendBroadcast(intent, BLUETOOTH_PERM); - } - - private void onRemoteDeviceFound(String address, int deviceClass, short rssi) { - Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION); - intent.putExtra(BluetoothIntent.ADDRESS, address); - intent.putExtra(BluetoothIntent.CLASS, deviceClass); - intent.putExtra(BluetoothIntent.RSSI, rssi); - mContext.sendBroadcast(intent, BLUETOOTH_PERM); - } - private void onRemoteDeviceDisappeared(String address) { - Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION); - intent.putExtra(BluetoothIntent.ADDRESS, address); - mContext.sendBroadcast(intent, BLUETOOTH_PERM); - } - private void onRemoteClassUpdated(String address, int deviceClass) { - Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION); - intent.putExtra(BluetoothIntent.ADDRESS, address); - intent.putExtra(BluetoothIntent.CLASS, deviceClass); - mContext.sendBroadcast(intent, BLUETOOTH_PERM); - } - private void onRemoteDeviceConnected(String address) { - Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION); - intent.putExtra(BluetoothIntent.ADDRESS, address); - mContext.sendBroadcast(intent, BLUETOOTH_PERM); - } - private void onRemoteDeviceDisconnectRequested(String address) { - Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_DISCONNECT_REQUESTED_ACTION); - intent.putExtra(BluetoothIntent.ADDRESS, address); - mContext.sendBroadcast(intent, BLUETOOTH_PERM); - } - private void onRemoteDeviceDisconnected(String address) { - Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_DISCONNECTED_ACTION); - intent.putExtra(BluetoothIntent.ADDRESS, address); - mContext.sendBroadcast(intent, BLUETOOTH_PERM); - } - private void onRemoteNameUpdated(String address, String name) { - Intent intent = new Intent(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION); - intent.putExtra(BluetoothIntent.ADDRESS, address); - intent.putExtra(BluetoothIntent.NAME, name); - mContext.sendBroadcast(intent, BLUETOOTH_PERM); - } - private void onRemoteNameFailed(String address) { - Intent intent = new Intent(BluetoothIntent.REMOTE_NAME_FAILED_ACTION); - intent.putExtra(BluetoothIntent.ADDRESS, address); - mContext.sendBroadcast(intent, BLUETOOTH_PERM); - } - private void onRemoteNameChanged(String address, String name) { - Intent intent = new Intent(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION); - intent.putExtra(BluetoothIntent.ADDRESS, address); - intent.putExtra(BluetoothIntent.NAME, name); - mContext.sendBroadcast(intent, BLUETOOTH_PERM); - } - - private void onCreateBondingResult(String address, int result) { - address = address.toUpperCase(); - if (result == BluetoothError.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_NOT_BONDED, 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_NOT_BONDED, 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_NOT_BONDED, result); - return; - } - mBluetoothService.getBondState().attempt(address); - } - - private void onBondingCreated(String address) { - mBluetoothService.getBondState().setBondState(address.toUpperCase(), - BluetoothDevice.BOND_BONDED); - } - - private void onBondingRemoved(String address) { - mBluetoothService.getBondState().setBondState(address.toUpperCase(), - BluetoothDevice.BOND_NOT_BONDED, BluetoothDevice.UNBOND_REASON_REMOVED); - } - - private void onNameChanged(String name) { - Intent intent = new Intent(BluetoothIntent.NAME_CHANGED_ACTION); - intent.putExtra(BluetoothIntent.NAME, name); - mContext.sendBroadcast(intent, BLUETOOTH_PERM); - } - - private void onPasskeyAgentRequest(String address, int nativeData) { - address = address.toUpperCase(); - mPasskeyAgentRequestData.put(address, new Integer(nativeData)); - - if (mBluetoothService.getBondState().getBondState(address) == - BluetoothDevice.BOND_BONDING) { - // we initiated the bonding - int btClass = mBluetoothService.getRemoteClass(address); - - // try 0000 once if the device looks dumb - switch (BluetoothClass.Device.getDevice(btClass)) { - case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET: - case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE: - case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES: - 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; - } - } - } - Intent intent = new Intent(BluetoothIntent.PAIRING_REQUEST_ACTION); - intent.putExtra(BluetoothIntent.ADDRESS, address); - mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM); - } - - private void onPasskeyAgentCancel(String address) { - address = address.toUpperCase(); - mPasskeyAgentRequestData.remove(address); - Intent intent = new Intent(BluetoothIntent.PAIRING_CANCEL_ACTION); - intent.putExtra(BluetoothIntent.ADDRESS, address); - mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM); - mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_NOT_BONDED, - BluetoothDevice.UNBOND_REASON_AUTH_CANCELED); - } - - private boolean onAuthAgentAuthorize(String address, String service, String uuid) { - boolean authorized = false; - if (service.endsWith("service_audio")) { - BluetoothA2dp a2dp = new BluetoothA2dp(mContext); - authorized = a2dp.getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF; - if (authorized) { - Log.i(TAG, "Allowing incoming A2DP connection from " + address); - } else { - Log.i(TAG, "Rejecting incoming A2DP connection from " + address); - } - } else { - Log.i(TAG, "Rejecting incoming " + service + " connection from " + address); - } - return authorized; - } - - private void onAuthAgentCancel(String address, String service, String uuid) { - // We immediately response to DBUS Authorize() so this should not - // usually happen - log("onAuthAgentCancel(" + address + ", " + service + ", " + uuid + ")"); - } - - private void onGetRemoteServiceChannelResult(String address, int channel) { - IBluetoothDeviceCallback callback = mGetRemoteServiceChannelCallbacks.get(address); - if (callback != null) { - mGetRemoteServiceChannelCallbacks.remove(address); - try { - callback.onGetRemoteServiceChannelResult(address, channel); - } catch (RemoteException e) {} - } - } - - private static void log(String msg) { - Log.d(TAG, msg); - } -} |
