1 package org.robolectric.shadows; 2 3 import static android.bluetooth.BluetoothDevice.BOND_NONE; 4 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2; 5 import static org.robolectric.shadow.api.Shadow.directlyOn; 6 7 import android.bluetooth.BluetoothDevice; 8 import android.bluetooth.BluetoothGatt; 9 import android.bluetooth.BluetoothGattCallback; 10 import android.bluetooth.IBluetooth; 11 import android.content.Context; 12 import android.os.ParcelUuid; 13 import org.robolectric.annotation.Implementation; 14 import org.robolectric.annotation.Implements; 15 import org.robolectric.annotation.RealObject; 16 import org.robolectric.util.ReflectionHelpers; 17 18 @Implements(BluetoothDevice.class) 19 public class ShadowBluetoothDevice { 20 newInstance(String address)21 public static BluetoothDevice newInstance(String address) { 22 return ReflectionHelpers.callConstructor( 23 BluetoothDevice.class, ReflectionHelpers.ClassParameter.from(String.class, address)); 24 } 25 26 @RealObject private BluetoothDevice realBluetoothDevice; 27 private String name; 28 private ParcelUuid[] uuids; 29 private int bondState = BOND_NONE; 30 private boolean createdBond = false; 31 private boolean fetchUuidsWithSdpResult = false; 32 private int fetchUuidsWithSdpCount = 0; 33 34 /** 35 * Implements getService() in the same way the original method does, but ignores any Exceptions 36 * from invoking {@link android.bluetooth.BluetoothAdapter#getBluetoothService}. 37 */ 38 @Implementation getService()39 protected static IBluetooth getService() { 40 // Attempt to call the underlying getService method, but ignore any Exceptions. This allows us 41 // to easily create BluetoothDevices for testing purposes without having any actual Bluetooth 42 // capability. 43 try { 44 return directlyOn(BluetoothDevice.class, "getService"); 45 } catch (Exception e) { 46 // No-op. 47 } 48 return null; 49 } 50 setName(String name)51 public void setName(String name) { 52 this.name = name; 53 } 54 55 @Implementation getName()56 protected String getName() { 57 return name; 58 } 59 60 /** Sets the return value for {@link BluetoothDevice#getUuids}. */ setUuids(ParcelUuid[] uuids)61 public void setUuids(ParcelUuid[] uuids) { 62 this.uuids = uuids; 63 } 64 65 /** 66 * Overrides behavior of {@link BluetoothDevice#getUuids} to return pre-set result. 67 * 68 * @returns Value set by calling {@link ShadowBluetoothDevice#setUuids}. If setUuids has not 69 * previously been called, will return null. 70 */ 71 @Implementation getUuids()72 protected ParcelUuid[] getUuids() { 73 return uuids; 74 } 75 76 /** Sets value of bond state for {@link BluetoothDevice#getBondState}. */ setBondState(int bondState)77 public void setBondState(int bondState) { 78 this.bondState = bondState; 79 } 80 81 /** 82 * Overrides behavior of {@link BluetoothDevice#getBondState} to return pre-set result. 83 * 84 * @returns Value set by calling {@link ShadowBluetoothDevice#setBondState}. If setBondState has 85 * not previously been called, will return {@link BluetoothDevice#BOND_NONE} to indicate the 86 * device is not bonded. 87 */ 88 @Implementation getBondState()89 protected int getBondState() { 90 return bondState; 91 } 92 93 /** Sets whether this device has been bonded with. */ setCreatedBond(boolean createdBond)94 public void setCreatedBond(boolean createdBond) { 95 this.createdBond = createdBond; 96 } 97 98 /** Returns whether this device has been bonded with. */ 99 @Implementation createBond()100 protected boolean createBond() { 101 return createdBond; 102 } 103 104 /** Sets value of the return result for {@link BluetoothDevice#fetchUuidsWithSdp}. */ setFetchUuidsWithSdpResult(boolean fetchUuidsWithSdpResult)105 public void setFetchUuidsWithSdpResult(boolean fetchUuidsWithSdpResult) { 106 this.fetchUuidsWithSdpResult = fetchUuidsWithSdpResult; 107 } 108 109 /** 110 * Overrides behavior of {@link BluetoothDevice#fetchUuidsWithSdp}. This method updates the 111 * counter which counts the number of invocations of this method. 112 * 113 * @returns Value set by calling {@link ShadowBluetoothDevice#setFetchUuidsWithSdpResult}. If not 114 * previously set, will return false by default. 115 */ 116 @Implementation fetchUuidsWithSdp()117 protected boolean fetchUuidsWithSdp() { 118 fetchUuidsWithSdpCount++; 119 return fetchUuidsWithSdpResult; 120 } 121 122 /** Returns the number of times fetchUuidsWithSdp has been called. */ getFetchUuidsWithSdpCount()123 public int getFetchUuidsWithSdpCount() { 124 return fetchUuidsWithSdpCount; 125 } 126 127 @Implementation(minSdk = JELLY_BEAN_MR2) connectGatt( Context context, boolean autoConnect, BluetoothGattCallback callback)128 protected BluetoothGatt connectGatt( 129 Context context, boolean autoConnect, BluetoothGattCallback callback) { 130 return ShadowBluetoothGatt.newInstance(realBluetoothDevice); 131 } 132 } 133