/* * MIT License * * Copyright (c) 2017 Inova IT * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package si.inova.neatle.operation; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGattCharacteristic; import android.content.Context; import android.support.annotation.CheckResult; import android.support.annotation.RestrictTo; import java.nio.ByteBuffer; import java.util.LinkedList; import java.util.UUID; import java.util.concurrent.Callable; import si.inova.neatle.source.CalllableInputSource; import si.inova.neatle.source.InputSource; public class OperationBuilder { private Context context; private LinkedList<Command> commands = new LinkedList<>(); private OperationObserver masterObserver; private int retryCount; @RestrictTo(RestrictTo.Scope.LIBRARY) public OperationBuilder(Context context) { this.context = context.getApplicationContext(); } /** * Reads the the value of a characteristic from a service. * * @param serviceUUID the UUID of the service * @param characteristicsUUID the UUID of the characteristic. * @return this object */ public OperationBuilder read(UUID serviceUUID, UUID characteristicsUUID) { return read(serviceUUID, characteristicsUUID, null); } /** * Reads the the value of a characteristic from a service. * * @param serviceUUID the UUID of the service * @param characteristicsUUID the UUID of the characteristic. * @param observer the observer for this specific command * @return this object */ public OperationBuilder read(UUID serviceUUID, UUID characteristicsUUID, CommandObserver observer) { ReadCommand cmd = new ReadCommand(serviceUUID, characteristicsUUID, observer); commands.add(cmd); return this; } /** * Writes data to a characteristic of a service. * * @param serviceUUID the UUID of the service * @param characteristicsUUID the UUID of the characteristic. * @param source the source of data for the write command * @return this object */ public OperationBuilder write(UUID serviceUUID, UUID characteristicsUUID, InputSource source) { return write(serviceUUID, characteristicsUUID, source, null); } /** * Writes data provided by callable. The callable will be evaluated when it is time to * write. The callable will be re-evaluated if the operation is retried. * * @param serviceUUID the UUID of the service * @param characteristicsUUID the UUID of the characteristic. * @param callable the callable implantation that will be evaluated when it's time to write the value. * * @return this object */ public OperationBuilder write(UUID serviceUUID, UUID characteristicsUUID, Callable<ByteBuffer> callable) { return write(serviceUUID, characteristicsUUID, new CalllableInputSource(callable)); } /** * Writes data to a characteristic of a service. * * @param serviceUUID the UUID of the service * @param characteristicsUUID the UUID of the characteristic. * @param source the source of data for the write command * @param observer the operation observer - callback * @return this object */ public OperationBuilder write(UUID serviceUUID, UUID characteristicsUUID, InputSource source, CommandObserver observer) { WriteCommand cmd = new WriteCommand(serviceUUID, characteristicsUUID, BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT, source, observer); commands.add(cmd); return this; } /** * Writes data to a characteristic of a service, but does not require a response from the * BTLE device. * * @param serviceUUID the UUID of the service * @param characteristicsUUID the UUID of the characteristic. * @param source the source of data for the write command * @return this object */ public OperationBuilder writeNoResponse(UUID serviceUUID, UUID characteristicsUUID, InputSource source) { return writeNoResponse(serviceUUID, characteristicsUUID, source, null); } /** * Writes data to a characteristic of a service, but does not require a response from the BTLE * device. * * @param serviceUUID the UUID of the service * @param characteristicsUUID the UUID of the characteristic. * @param source the source of data for the write command * @param observer the operation observer - callback * @return this object */ public OperationBuilder writeNoResponse(UUID serviceUUID, UUID characteristicsUUID, InputSource source, CommandObserver observer) { WriteCommand cmd = new WriteCommand(serviceUUID, characteristicsUUID, BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE, source, observer); commands.add(cmd); return this; } /** * Executes the given custom command. * * @param cmd a custom command implementation. * * @return this object */ public OperationBuilder executeCommand(Command cmd) { commands.add(cmd); return this; } /** * Sets an {@link OperationObserver} that is triggered when all operations have been executed. * * @param operationObserver the operation observer * @return this object */ public OperationBuilder onFinished(OperationObserver operationObserver) { masterObserver = operationObserver; return this; } /** * Set how many times the operation should retry in case of an error. * * @param count the number of times to retry. The default is 0. Use -1 to retry indefinitely. * @return this builder instance. */ public OperationBuilder retryCount(int count) { this.retryCount = count; return this; } protected OperationBuilder subscribeNotification(UUID serviceUUID, UUID characteristicsUUID, CommandObserver observer) { SubscribeCommand cmd = new SubscribeCommand(SubscribeCommand.Type.SUBSCRIBE_NOTIFICATION, serviceUUID, characteristicsUUID, observer); commands.add(cmd); return this; } protected OperationBuilder unsubscribeNotification(UUID serviceUUID, UUID characteristicsUUID, CommandObserver observer) { SubscribeCommand cmd = new SubscribeCommand(SubscribeCommand.Type.UNSUBSCRIBE, serviceUUID, characteristicsUUID, observer); commands.add(cmd); return this; } /** * Creates the operation. Note that you still need to call {@link Operation#execute()} to start * the operation. * * @param device the device on which this operation will run * @return the created operation */ @CheckResult public Operation build(BluetoothDevice device) { if (device == null) { throw new IllegalArgumentException("Device cannot be null"); } return new OperationImpl(context, device, commands, retryCount, masterObserver); } }