package com.polidea.rxandroidble.mockrxandroidble;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import com.polidea.rxandroidble.RxBleConnection;
import com.polidea.rxandroidble.RxBleDevice;
import com.polidea.rxandroidble.RxBleDeviceServices;
import com.polidea.rxandroidble.exceptions.BleAlreadyConnectedException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import rx.Observable;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.functions.Func0;
import rx.subjects.BehaviorSubject;
import static com.polidea.rxandroidble.RxBleConnection.RxBleConnectionState.CONNECTED;
import static com.polidea.rxandroidble.RxBleConnection.RxBleConnectionState.CONNECTING;
import static com.polidea.rxandroidble.RxBleConnection.RxBleConnectionState.DISCONNECTED;
public class RxBleDeviceMock implements RxBleDevice {
private RxBleConnection rxBleConnection;
private BehaviorSubject<RxBleConnection.RxBleConnectionState> connectionStateBehaviorSubject = BehaviorSubject.create(
DISCONNECTED
);
private String name;
private String macAddress;
private Integer rssi;
private byte[] scanRecord;
private List<UUID> advertisedUUIDs;
private AtomicBoolean isConnected = new AtomicBoolean(false);
public RxBleDeviceMock(String name,
String macAddress,
byte[] scanRecord,
Integer rssi,
RxBleDeviceServices rxBleDeviceServices,
Map<UUID, Observable<byte[]>> characteristicNotificationSources) {
this.name = name;
this.macAddress = macAddress;
this.rxBleConnection = new RxBleConnectionMock(rxBleDeviceServices,
rssi,
characteristicNotificationSources);
this.rssi = rssi;
this.scanRecord = scanRecord;
this.advertisedUUIDs = new ArrayList<>();
}
public void addAdvertisedUUID(UUID advertisedUUID) {
advertisedUUIDs.add(advertisedUUID);
}
@Override
@Deprecated
public Observable<RxBleConnection> establishConnection(Context context, boolean autoConnect) {
return establishConnection(autoConnect);
}
@Override
public Observable<RxBleConnection> establishConnection(boolean autoConnect) {
return Observable.defer(new Func0<Observable<RxBleConnection>>() {
@Override
public Observable<RxBleConnection> call() {
if (isConnected.compareAndSet(false, true)) {
return RxBleDeviceMock.this.emitConnectionWithoutCompleting()
.doOnSubscribe(new Action0() {
@Override
public void call() {
connectionStateBehaviorSubject.onNext(CONNECTING);
}
})
.doOnNext(new Action1<RxBleConnection>() {
@Override
public void call(RxBleConnection rxBleConnection) {
connectionStateBehaviorSubject.onNext(CONNECTED);
}
})
.doOnUnsubscribe(new Action0() {
@Override
public void call() {
connectionStateBehaviorSubject.onNext(DISCONNECTED);
isConnected.set(false);
}
});
} else {
return Observable.error(new BleAlreadyConnectedException(macAddress));
}
}
});
}
private Observable<RxBleConnection> emitConnectionWithoutCompleting() {
return Observable.<RxBleConnection>never().startWith(rxBleConnection);
}
public List<UUID> getAdvertisedUUIDs() {
return advertisedUUIDs;
}
@Override
public RxBleConnection.RxBleConnectionState getConnectionState() {
return observeConnectionStateChanges().toBlocking().first();
}
@Override
public String getMacAddress() {
return macAddress;
}
@Override
public BluetoothDevice getBluetoothDevice() {
throw new UnsupportedOperationException("Mock does not support returning a BluetoothDevice.");
}
@Override
public String getName() {
return name;
}
public Integer getRssi() {
return rssi;
}
public byte[] getScanRecord() {
return scanRecord;
}
@Override
public Observable<RxBleConnection.RxBleConnectionState> observeConnectionStateChanges() {
return connectionStateBehaviorSubject.distinctUntilChanged();
}
@Override
public String toString() {
return "RxBleDeviceImpl{" + "bluetoothDevice=" + name + '(' + macAddress + ')' + '}';
}
}