/* * Copyright (C) 2007 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 com.android.unit_tests; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothIntent; import android.bluetooth.BluetoothClass; import android.bluetooth.IBluetoothDeviceCallback; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.SystemProperties; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; import junit.framework.Assert; import java.util.List; import java.util.HashSet; public class BluetoothTest extends AndroidTestCase { private static final String TAG = "BluetoothTest"; @MediumTest public void testBluetoothSmokeTest() throws Exception { BluetoothDevice btDevice = (BluetoothDevice)getContext().getSystemService(Context.BLUETOOTH_SERVICE); // TODO: Use a more reliable check to see if this product should // support Bluetooth - see bug 988521 boolean shouldSupportBluetooth = SystemProperties.get("ro.kernel.qemu").equals("0"); assertFalse(shouldSupportBluetooth && btDevice == null); if (!shouldSupportBluetooth) { Log.i(TAG, "Skipping test - this device does not have bluetooth."); return; } boolean bluetoothWasEnabled = btDevice.isEnabled(); if (bluetoothWasEnabled) { Log.i(TAG, "Bluetooth already enabled"); } else { Log.i(TAG, "Enabling Bluetooth..."); btDevice.enable(); Log.i(TAG, "Bluetooth enabled"); } Assert.assertTrue(btDevice.isEnabled()); String myAddress = btDevice.getAddress(); Assert.assertTrue(myAddress != null); Log.i(TAG, "My Bluetooth Address is " + myAddress); Assert.assertFalse(myAddress.equals("00:00:00:00:00:00")); if (!bluetoothWasEnabled) { Log.i(TAG, "Disabling Bluetooth..."); btDevice.disable(); Log.i(TAG, "Bluetooth disabled"); } } private boolean listenA2dp = false; private void listenA2dp() { if (!listenA2dp) { listenA2dp = true; getContext().registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { int state = intent.getIntExtra(BluetoothA2dp.SINK_STATE, -1); int oldState = intent.getIntExtra(BluetoothA2dp.SINK_PREVIOUS_STATE, -1); Log.e(TAG, "A2DP INTENT: state = " + state + " oldState = " + oldState); } }, new IntentFilter(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION)); } } @MediumTest public void testA2dpSmokeTest() throws Exception { listenA2dp(); BluetoothA2dp a2dp = new BluetoothA2dp(getContext()); List sinks = a2dp.listConnectedSinks(); Log.e(TAG, "listConnectedSinks()..."); for (String sink : sinks) { Log.e(TAG, sink + " state = " + a2dp.getSinkState(sink)); } } @MediumTest public void testA2dpConnect() throws Exception { listenA2dp(); String address = SystemProperties.get("debug.a2dp.address", ""); BluetoothA2dp a2dp = new BluetoothA2dp(getContext()); int result = a2dp.connectSink(address); Log.e(TAG, "connectSink(" + address + ") = " + result); } @MediumTest public void testA2dpDisconnect() throws Exception { listenA2dp(); String address = SystemProperties.get("debug.a2dp.address", ""); BluetoothA2dp a2dp = new BluetoothA2dp(getContext()); int result = a2dp.disconnectSink(address); Log.e(TAG, "disconnectSink(" + address + ") = " + result); } @MediumTest public void testBluetoothEnabled() throws Exception { BluetoothDevice device = (BluetoothDevice)getContext().getSystemService(Context.BLUETOOTH_SERVICE); if (device == null) { Log.i(TAG, "Device not Bluetooth capable, skipping test"); return; } if (device.isEnabled()) { Log.i(TAG, "isEnabled() = yes"); } else { Log.i(TAG, "isEnabled() = no"); } } @MediumTest public void testEnableBluetooth() throws Exception { BluetoothDevice device = (BluetoothDevice)getContext().getSystemService(Context.BLUETOOTH_SERVICE); if (device == null) { Log.i(TAG, "Device not Bluetooth capable, skipping test"); return; } device.enable(); } @MediumTest public void testEnableBluetoothWithCallback() throws Exception { BluetoothDevice device = (BluetoothDevice)getContext().getSystemService(Context.BLUETOOTH_SERVICE); if (device == null) { Log.i(TAG, "Device not Bluetooth capable, skipping test"); return; } if (!device.enable(mCallback)) { Log.e(TAG, "enable() failed"); } } @MediumTest public void testDisableBluetooth() throws Exception { BluetoothDevice device = (BluetoothDevice)getContext().getSystemService(Context.BLUETOOTH_SERVICE); if (device == null) { Log.i(TAG, "Device not Bluetooth capable, skipping test"); return; } device.disable(); } @LargeTest public void testDiscovery() throws Exception { BluetoothDevice device = (BluetoothDevice)getContext().getSystemService(Context.BLUETOOTH_SERVICE); if (device == null) { Log.i(TAG, "Device not Bluetooth capable, skipping test"); return; } if (device.isEnabled()) { getContext().registerReceiver((BroadcastReceiver)new TestDiscoveryReceiver(), new IntentFilter(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION)); Log.i(TAG, "Starting discovery..."); String result = device.startDiscovery() ? "true" : "false"; Log.i(TAG, "startDiscovery() = " + result); } } @LargeTest public void testMultipleDiscovery() throws Exception { BluetoothDevice device = (BluetoothDevice)getContext().getSystemService(Context.BLUETOOTH_SERVICE); if (device == null) { Log.i(TAG, "Device not Bluetooth capable, skipping test"); return; } if (device.isEnabled()) { getContext().registerReceiver((BroadcastReceiver)new TestDiscoveryReceiver(), new IntentFilter(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION)); String result; Log.i(TAG, "Starting multiple discovery..."); for (int i = 0; i < 5; i++) { result = device.startDiscovery() ? "true" : "false"; Log.i(TAG, "startDiscovery() = " + result); } } } private class TestDiscoveryReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String address = intent.getStringExtra(BluetoothIntent.ADDRESS); int deviceClass = intent.getIntExtra(BluetoothIntent.CLASS, -1); short rssi = intent.getShortExtra(BluetoothIntent.RSSI, (short)-1); Log.i(TAG, "Discovered Device: " + address + " " + deviceClass + " " + rssi); } } private IBluetoothDeviceCallback mCallback = new IBluetoothDeviceCallback.Stub() { public void onEnableResult(int res) { String result = "unknown"; switch (res) { case BluetoothDevice.RESULT_SUCCESS: result = "success"; break; case BluetoothDevice.RESULT_FAILURE: result = "FAILURE"; break; } Log.i(TAG, "onEnableResult(" + result + ")"); } public void onCreateBondingResult(String device, int res) { String result = "unknown"; switch (res) { case BluetoothDevice.RESULT_SUCCESS: result = "success"; break; case BluetoothDevice.RESULT_FAILURE: result = "FAILURE"; break; } Log.i(TAG, "onEnableResult(" + device + ", " + result + ")"); } public void onGetRemoteServiceChannelResult(String device, int channel) {} }; @SmallTest public void testCreateBondingWithCallback() throws Exception { BluetoothDevice device = (BluetoothDevice)getContext().getSystemService(Context.BLUETOOTH_SERVICE); if (device == null) { Log.i(TAG, "Device not Bluetooth capable, skipping test"); return; } if (!device.createBonding("01:23:45:67:89:AB", mCallback)) { Log.e(TAG, "createBonding() failed"); } } @SmallTest public void testIsPeriodicDiscovery() throws Exception { BluetoothDevice device = (BluetoothDevice)getContext().getSystemService(Context.BLUETOOTH_SERVICE); if (device == null) { Log.i(TAG, "Device not Bluetooth capable, skipping test"); return; } boolean ret = device.isPeriodicDiscovery(); if (ret) { Log.i(TAG, "isPeriodicDiscovery() = TRUE"); } else { Log.i(TAG, "isPeriodicDiscovery() = FALSE"); } } @LargeTest public void testListBondings() throws Exception { BluetoothDevice device = (BluetoothDevice)getContext().getSystemService(Context.BLUETOOTH_SERVICE); if (device == null) { Log.i(TAG, "Device not Bluetooth capable, skipping test"); return; } String[] addresses = device.listBondings(); if (addresses == null) { Log.i(TAG, "Bluetooth disabled"); return; } for (String address : addresses) { String name = device.getRemoteName(address); Log.i(TAG, "BONDING: " + address + " (" + name + ")"); } } @LargeTest public void testListAclConnections() throws Exception { BluetoothDevice device = (BluetoothDevice)getContext().getSystemService(Context.BLUETOOTH_SERVICE); if (device == null) { Log.i(TAG, "Device not Bluetooth capable, skipping test"); return; } String[] addresses = device.listAclConnections(); if (addresses == null) { Log.i(TAG, "Bluetooth disabled"); return; } for (String address : addresses) { String name = device.getRemoteName(address); Log.i(TAG, "CONNECTION: " + address + " (" + name + ")"); } } @LargeTest public void testListRemoteDevices() throws Exception { BluetoothDevice device = (BluetoothDevice)getContext().getSystemService(Context.BLUETOOTH_SERVICE); if (device == null) { Log.i(TAG, "Device not Bluetooth capable, skipping test"); return; } String[] addresses = device.listRemoteDevices(); if (addresses == null) { Log.i(TAG, "Bluetooth disabled"); return; } for (String address : addresses) { String name = device.getRemoteName(address); Log.i(TAG, "KNOWN DEVICE: " + address + " (" + name + ")"); } } @MediumTest public void testSetupBTIntentRecv() throws Exception { BluetoothDevice device = (BluetoothDevice)getContext().getSystemService(Context.BLUETOOTH_SERVICE); if (device == null) { Log.i(TAG, "Device not Bluetooth capable, skipping test"); return; } if (device.isEnabled()) { IntentFilter filter = new IntentFilter(BluetoothIntent.ENABLED_ACTION); filter.addAction(BluetoothIntent.ENABLED_ACTION); filter.addAction(BluetoothIntent.DISABLED_ACTION); filter.addAction(BluetoothIntent.NAME_CHANGED_ACTION); filter.addAction(BluetoothIntent.MODE_CHANGED_ACTION); filter.addAction(BluetoothIntent.DISCOVERY_STARTED_ACTION); filter.addAction(BluetoothIntent.DISCOVERY_COMPLETED_ACTION); filter.addAction(BluetoothIntent.PAIRING_REQUEST_ACTION); filter.addAction(BluetoothIntent.PAIRING_CANCEL_ACTION); filter.addAction(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION); filter.addAction(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION); filter.addAction(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION); filter.addAction(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION); filter.addAction(BluetoothIntent.REMOTE_DEVICE_DISCONNECT_REQUESTED_ACTION); filter.addAction(BluetoothIntent.REMOTE_DEVICE_DISCONNECTED_ACTION); filter.addAction(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION); filter.addAction(BluetoothIntent.REMOTE_NAME_FAILED_ACTION); filter.addAction(BluetoothIntent.REMOTE_ALIAS_CHANGED_ACTION); filter.addAction(BluetoothIntent.REMOTE_ALIAS_CLEARED_ACTION); filter.addAction(BluetoothIntent.BONDING_CREATED_ACTION); filter.addAction(BluetoothIntent.BONDING_REMOVED_ACTION); filter.addAction(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION); getContext().registerReceiver( (BroadcastReceiver)new BluetoothIntentReceiver(), filter); Log.i(TAG, "Listening for BLUETOOTH INTENTS...."); } else { Log.e(TAG, "BT not enabled"); } } private class BluetoothIntentReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String msg = ""; String address = intent.getStringExtra(BluetoothIntent.ADDRESS); if (address != null) { msg += " address=" + address; } int deviceClass = intent.getIntExtra(BluetoothIntent.CLASS, BluetoothClass.ERROR); if (deviceClass != BluetoothClass.ERROR) { msg += " class=" + deviceClass; } int rssi = intent.getIntExtra(BluetoothIntent.RSSI, -1); if (rssi != -1) { msg += " rssi=" + rssi; } String name = intent.getStringExtra(BluetoothIntent.NAME); if (name != null) { msg += " name=" + name; } String alias = intent.getStringExtra(BluetoothIntent.ALIAS); if (alias != null) { msg += " alias=" + alias; } int mode = intent.getIntExtra(BluetoothIntent.MODE, -10); if (mode != -10) { msg += " mode=" + mode; } int state = intent.getIntExtra(BluetoothIntent.HEADSET_STATE, -10); if (state != -10) { msg += " headset state=" + state; } Log.i(TAG, "BLUETOOTH INTENT: " + intent.getAction() + msg); } } private static final int[] ALL_SERVICE_CLASSES = new int[] { BluetoothClass.Service.LIMITED_DISCOVERABILITY, BluetoothClass.Service.POSITIONING, BluetoothClass.Service.NETWORKING, BluetoothClass.Service.RENDER, BluetoothClass.Service.CAPTURE, BluetoothClass.Service.OBJECT_TRANSFER, BluetoothClass.Service.AUDIO, BluetoothClass.Service.TELEPHONY, BluetoothClass.Service.INFORMATION }; private void assertOnlyTheseServiceClassesAreSupported(int deviceClass, HashSet serviceClasses) { for (int serviceClassType : ALL_SERVICE_CLASSES) { Assert.assertEquals(serviceClasses.contains(new Integer(serviceClassType)), BluetoothClass.Service.hasService(deviceClass, serviceClassType)); } } @SmallTest public void testDeviceClass() throws Exception { // This test does not require bluetooth hardware int deviceClass; HashSet serviceClasses; deviceClass = BluetoothClass.ERROR; // bogus class serviceClasses = new HashSet(); assertOnlyTheseServiceClassesAreSupported(deviceClass, serviceClasses); Assert.assertEquals(BluetoothClass.ERROR, BluetoothClass.Device.Major.getDeviceMajor(deviceClass)); Assert.assertEquals(BluetoothClass.ERROR, BluetoothClass.Device.getDevice(deviceClass)); deviceClass = 0x10210C; // mac book pro serviceClasses = new HashSet(); serviceClasses.add(BluetoothClass.Service.OBJECT_TRANSFER); serviceClasses.add(BluetoothClass.Service.LIMITED_DISCOVERABILITY); assertOnlyTheseServiceClassesAreSupported(deviceClass, serviceClasses); Assert.assertEquals(BluetoothClass.Device.Major.COMPUTER, BluetoothClass.Device.Major.getDeviceMajor(deviceClass)); Assert.assertEquals(0x10C, BluetoothClass.Device.getDevice(deviceClass)); // mac book pro with some unused bits set. Expecting the same results deviceClass = 0xFF10210F; serviceClasses = new HashSet(); serviceClasses.add(BluetoothClass.Service.OBJECT_TRANSFER); serviceClasses.add(BluetoothClass.Service.LIMITED_DISCOVERABILITY); assertOnlyTheseServiceClassesAreSupported(deviceClass, serviceClasses); Assert.assertEquals(BluetoothClass.Device.Major.COMPUTER, BluetoothClass.Device.Major.getDeviceMajor(deviceClass)); Assert.assertEquals(0x10C, BluetoothClass.Device.getDevice(deviceClass)); deviceClass = 0x3E0100; // droid.corp.google.com serviceClasses = new HashSet(); serviceClasses.add(BluetoothClass.Service.AUDIO); serviceClasses.add(BluetoothClass.Service.OBJECT_TRANSFER); serviceClasses.add(BluetoothClass.Service.CAPTURE); serviceClasses.add(BluetoothClass.Service.RENDER); serviceClasses.add(BluetoothClass.Service.NETWORKING); assertOnlyTheseServiceClassesAreSupported(deviceClass, serviceClasses); Assert.assertEquals(BluetoothClass.Device.Major.COMPUTER, BluetoothClass.Device.Major.getDeviceMajor(deviceClass)); Assert.assertEquals(0x100, BluetoothClass.Device.getDevice(deviceClass)); deviceClass = 0x40020C; // Android serviceClasses = new HashSet(); serviceClasses.add(BluetoothClass.Service.TELEPHONY); assertOnlyTheseServiceClassesAreSupported(deviceClass, serviceClasses); Assert.assertEquals(BluetoothClass.Device.Major.PHONE, BluetoothClass.Device.Major.getDeviceMajor(deviceClass)); Assert.assertEquals(0x20C, BluetoothClass.Device.getDevice(deviceClass)); // Motorola T305 & Jabra BT125 & Jabra BT250V // This seems to be a very common headset & handsfree device code deviceClass = 0x200404; serviceClasses = new HashSet(); serviceClasses.add(BluetoothClass.Service.AUDIO); assertOnlyTheseServiceClassesAreSupported(deviceClass, serviceClasses); Assert.assertEquals(BluetoothClass.Device.Major.AUDIO_VIDEO, BluetoothClass.Device.Major.getDeviceMajor(deviceClass)); Assert.assertEquals(BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET, BluetoothClass.Device.getDevice(deviceClass)); // Audi UHV 0128 deviceClass = 0x200408; serviceClasses = new HashSet(); serviceClasses.add(BluetoothClass.Service.AUDIO); assertOnlyTheseServiceClassesAreSupported(deviceClass, serviceClasses); Assert.assertEquals(BluetoothClass.Device.Major.AUDIO_VIDEO, BluetoothClass.Device.Major.getDeviceMajor(deviceClass)); Assert.assertEquals(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE, BluetoothClass.Device.getDevice(deviceClass)); } }