blob: a615df383bc6b7125dc7168e5f18832c7c7eee79 [file] [log] [blame]
/*
* Copyright (C) 2021 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.bluetooth.cts;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
import static org.junit.Assert.assertThrows;
import android.app.UiAutomation;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothStatusCodes;
import android.content.AttributionSource;
import android.content.pm.PackageManager;
import android.test.AndroidTestCase;
import androidx.test.InstrumentationRegistry;
public class BluetoothDeviceTest extends AndroidTestCase {
private boolean mHasBluetooth;
private boolean mHasCompanionDevice;
private BluetoothAdapter mAdapter;
private UiAutomation mUiAutomation;;
@Override
public void setUp() throws Exception {
super.setUp();
mHasBluetooth = getContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_BLUETOOTH);
mHasCompanionDevice = getContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_COMPANION_DEVICE_SETUP);
if (mHasBluetooth && mHasCompanionDevice) {
BluetoothManager manager = getContext().getSystemService(BluetoothManager.class);
mAdapter = manager.getAdapter();
mUiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
mUiAutomation.adoptShellPermissionIdentity(BLUETOOTH_CONNECT);
assertTrue(BTAdapterUtils.enableAdapter(mAdapter, mContext));
}
}
@Override
public void tearDown() throws Exception {
super.tearDown();
if (mHasBluetooth && mHasCompanionDevice) {
assertTrue(BTAdapterUtils.disableAdapter(mAdapter, mContext));
mAdapter = null;
mUiAutomation.dropShellPermissionIdentity();
}
}
public void test_setAlias_getAlias() {
if (!mHasBluetooth || !mHasCompanionDevice) {
// Skip the test if bluetooth or companion device are not present.
return;
}
int userId = mContext.getUser().getIdentifier();
String packageName = mContext.getOpPackageName();
String deviceAddress = "00:11:22:AA:BB:CC";
AttributionSource source = AttributionSource.myAttributionSource();
assertEquals("android.bluetooth.cts", source.getPackageName());
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
// Verifies that when there is no alias, we return the device name
assertNull(device.getAlias());
assertThrows(IllegalArgumentException.class, () -> device.setAlias(""));
String testDeviceAlias = "Test Device Alias";
// This should throw a SecurityException because there is no CDM association
assertThrows("BluetoothDevice.setAlias without"
+ " a CDM association or BLUETOOTH_PRIVILEGED permission",
SecurityException.class, () -> device.setAlias(testDeviceAlias));
runShellCommand(String.format(
"cmd companiondevice associate %d %s %s", userId, packageName, deviceAddress));
String output = runShellCommand("dumpsys companiondevice");
assertTrue("Package name missing from output", output.contains(packageName));
assertTrue("Device address missing from output", output.contains(deviceAddress));
// Takes time to update the CDM cache, so sleep to ensure the association is cached
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
/*
* Device properties don't exist for non-existent BluetoothDevice, so calling setAlias with
* permissions should return false
*/
assertEquals(BluetoothStatusCodes.ERROR_DEVICE_NOT_BONDED, device.setAlias(testDeviceAlias));
runShellCommand(String.format(
"cmd companiondevice disassociate %d %s %s", userId, packageName, deviceAddress));
}
public void test_getAnonymizedAddress() {
if (!mHasBluetooth || !mHasCompanionDevice) {
// Skip the test if bluetooth or companion device are not present.
return;
}
String deviceAddress = "00:11:22:AA:BB:CC";
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
assertEquals(device.getAnonymizedAddress(), "XX:XX:XX:AA:BB:CC");
}
public void test_getBatteryLevel() {
if (!mHasBluetooth || !mHasCompanionDevice) {
// Skip the test if bluetooth or companion device are not present.
return;
}
String deviceAddress = "00:11:22:AA:BB:CC";
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
assertEquals(BluetoothDevice.BATTERY_LEVEL_UNKNOWN, device.getBatteryLevel());
mUiAutomation.dropShellPermissionIdentity();
assertThrows(SecurityException.class, () -> device.getBatteryLevel());
mUiAutomation.adoptShellPermissionIdentity(BLUETOOTH_CONNECT);
}
public void test_getMessageAccessPermission() {
if (!mHasBluetooth || !mHasCompanionDevice) {
// Skip the test if bluetooth or companion device are not present.
return;
}
String deviceAddress = "00:11:22:AA:BB:CC";
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
assertEquals(BluetoothDevice.ACCESS_UNKNOWN, device.getMessageAccessPermission());
mUiAutomation.dropShellPermissionIdentity();
assertThrows(SecurityException.class, () -> device.getMessageAccessPermission());
mUiAutomation.adoptShellPermissionIdentity(BLUETOOTH_CONNECT);
}
public void test_getPhonebookAccessPermission() {
if (!mHasBluetooth || !mHasCompanionDevice) {
// Skip the test if bluetooth or companion device are not present.
return;
}
String deviceAddress = "00:11:22:AA:BB:CC";
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
assertEquals(BluetoothDevice.ACCESS_UNKNOWN, device.getPhonebookAccessPermission());
mUiAutomation.dropShellPermissionIdentity();
assertThrows(SecurityException.class, () -> device.getPhonebookAccessPermission());
mUiAutomation.adoptShellPermissionIdentity(BLUETOOTH_CONNECT);
}
public void test_isBondingInitiatedLocally() {
if (!mHasBluetooth || !mHasCompanionDevice) {
// Skip the test if bluetooth or companion device are not present.
return;
}
String deviceAddress = "00:11:22:AA:BB:CC";
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
assertFalse(device.isBondingInitiatedLocally());
mUiAutomation.dropShellPermissionIdentity();
assertThrows(SecurityException.class, () -> device.isBondingInitiatedLocally());
mUiAutomation.adoptShellPermissionIdentity(BLUETOOTH_CONNECT);
}
public void test_prepareToEnterProcess() {
if (!mHasBluetooth || !mHasCompanionDevice) {
// Skip the test if bluetooth or companion device are not present.
return;
}
String deviceAddress = "00:11:22:AA:BB:CC";
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
device.prepareToEnterProcess(null);
}
public void test_setPin() {
if (!mHasBluetooth || !mHasCompanionDevice) {
// Skip the test if bluetooth or companion device are not present.
return;
}
String deviceAddress = "00:11:22:AA:BB:CC";
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
assertFalse(device.setPin((String) null));
assertFalse(device.setPin("12345678901234567")); // check PIN too big
assertFalse(device.setPin("123456")); //device is not bonding
mUiAutomation.dropShellPermissionIdentity();
assertThrows(SecurityException.class, () -> device.setPin("123456"));
mUiAutomation.adoptShellPermissionIdentity(BLUETOOTH_CONNECT);
}
public void test_connect_disconnect() {
if (!mHasBluetooth || !mHasCompanionDevice) {
// Skip the test if bluetooth or companion device are not present.
return;
}
String deviceAddress = "00:11:22:AA:BB:CC";
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
// This should throw a SecurityException because no BLUETOOTH_PRIVILEGED permission
assertThrows(SecurityException.class, () -> device.connect());
assertThrows(SecurityException.class, () -> device.disconnect());
}
}