From 1242009b5514472457fbf24d0f9d4f045866e38c Mon Sep 17 00:00:00 2001 From: Yukai Li Date: Mon, 5 Oct 2020 15:08:11 -0600 Subject: [PATCH] Lefun: Add comments --- .../devices/lefun/LefunConstants.java | 15 +- .../devices/lefun/LefunDeviceCoordinator.java | 3 + .../devices/lefun/LefunFeatureSupport.java | 20 +++ .../devices/lefun/LefunSampleProvider.java | 7 +- .../devices/lefun/commands/BaseCommand.java | 145 +++++++++++++---- .../devices/lefun/LefunDeviceSupport.java | 151 ++++++++++++++++++ .../lefun/requests/MultiFetchRequest.java | 11 ++ .../devices/lefun/requests/Request.java | 60 +++++++ 8 files changed, 372 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunConstants.java index 77a6b1afe..4af1aee5e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunConstants.java @@ -22,6 +22,9 @@ import java.util.UUID; import static nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport.BASE_UUID; +/** + * Constants used with Lefun device support + */ public class LefunConstants { // BLE UUIDs public static final UUID UUID_SERVICE_LEFUN = UUID.fromString(String.format(BASE_UUID, "18D0")); @@ -31,16 +34,12 @@ public class LefunConstants { // Coordinator constants public static final String ADVERTISEMENT_NAME = "Lefun"; public static final String MANUFACTURER_NAME = "Teng Jin Da"; - public static int NUM_ALARM_SLOTS = 5; - // Commands - public static final byte CMD_REQUEST_ID = (byte)0xab; + public static final byte CMD_REQUEST_ID = (byte) 0xab; public static final byte CMD_RESPONSE_ID = 0x5a; - public static final int CMD_MAX_LENGTH = 20; // 3 header bytes plus checksum public static final int CMD_HEADER_LENGTH = 4; - public static final byte CMD_FIRMWARE_INFO = 0x00; public static final byte CMD_BONDING_REQUEST = 0x01; public static final byte CMD_SETTINGS = 0x02; @@ -67,25 +66,23 @@ public class LefunConstants { public static final byte CMD_LANGUAGE = 0x21; public static final byte CMD_UNKNOWN_22 = 0x22; public static final byte CMD_UNKNOWN_25 = 0x25; - public static final byte CMD_UNKNOWN_80 = (byte)0x80; - + public static final byte CMD_UNKNOWN_80 = (byte) 0x80; public static final int PPG_TYPE_INVALID = -1; public static final int PPG_TYPE_HEART_RATE = 0; public static final int PPG_TYPE_BLOOD_PRESSURE = 1; public static final int PPG_TYPE_BLOOD_OXYGEN = 2; public static final int PPG_TYPE_COUNT = 3; - // DB activity kinds public static final int DB_ACTIVITY_KIND_UNKNOWN = 0; public static final int DB_ACTIVITY_KIND_ACTIVITY = 1; public static final int DB_ACTIVITY_KIND_HEART_RATE = 2; public static final int DB_ACTIVITY_KIND_LIGHT_SLEEP = 3; public static final int DB_ACTIVITY_KIND_DEEP_SLEEP = 4; - // Pseudo-intensity public static final int INTENSITY_MIN = 0; public static final int INTENSITY_DEEP_SLEEP = 1; public static final int INTENSITY_LIGHT_SLEEP = 2; public static final int INTENSITY_AWAKE = 3; public static final int INTENSITY_MAX = 4; + public static int NUM_ALARM_SLOTS = 5; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunDeviceCoordinator.java index c8e59bfde..47c02022d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunDeviceCoordinator.java @@ -41,6 +41,9 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants. import static nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants.MANUFACTURER_NAME; import static nodomain.freeyourgadget.gadgetbridge.devices.lefun.LefunConstants.NUM_ALARM_SLOTS; +/** + * Device coordinator for Lefun band + */ public class LefunDeviceCoordinator extends AbstractDeviceCoordinator { @Override protected void deleteDevice(@NonNull GBDevice gbDevice, @NonNull Device device, @NonNull DaoSession session) throws GBException { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunFeatureSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunFeatureSupport.java index ba76fb046..9b7a11df3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunFeatureSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunFeatureSupport.java @@ -18,6 +18,9 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.devices.lefun; +/** + * Feature support utilities for Lefun devices + */ public class LefunFeatureSupport { public static final int SUPPORT_HEART_RATE = 1 << 2; public static final int SUPPORT_BLOOD_PRESSURE = 1 << 3; @@ -31,10 +34,27 @@ public class LefunFeatureSupport { public static final int RESERVE_WALLPAPER = 1 << 6; public static final int RESERVE_REMOTE_CAMERA = 1 << 7; + /** + * Checks whether a feature is supported + * + * @param deviceSupport the feature flags from the device + * @param featureSupport the feature you want to check + * @return whether feature is supported + */ public static boolean checkSupported(short deviceSupport, int featureSupport) { return (deviceSupport & featureSupport) == featureSupport; } + /** + * Checks whether a feature is not reserved + *

+ * Reserve flags indicate a feature is not available if set. This function takes care of the + * inverting for you, so if you get true, the feature is available. + * + * @param deviceReserve the reserve flags from the device + * @param featureReserve the reserve flag you want to check + * @return whether feature is supported + */ public static boolean checkNotReserved(short deviceReserve, int featureReserve) { return !((deviceReserve & featureReserve) == featureReserve); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunSampleProvider.java index 861cd089d..606782fc8 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/lefun/LefunSampleProvider.java @@ -24,14 +24,15 @@ import androidx.annotation.Nullable; import de.greenrobot.dao.AbstractDao; import de.greenrobot.dao.Property; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider; -import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; -import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.LefunActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.LefunActivitySampleDao; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; +/** + * Sample provider for Lefun devices + */ public class LefunSampleProvider extends AbstractSampleProvider { public LefunSampleProvider(GBDevice device, DaoSession session) { super(device, session); @@ -91,7 +92,7 @@ public class LefunSampleProvider extends AbstractSampleProvider>= 1; } } - return (byte)checksum; + return (byte) checksum; + } + + /** + * When implemented in a subclass, parses the response from a device + * + * @param id the command ID + * @param params the params buffer + */ + abstract protected void deserializeParams(byte id, ByteBuffer params); + + /** + * When implemented in a subclass, provides the arguments to send in the command + * + * @param params the params buffer to write to + * @return the command ID + */ + abstract protected byte serializeParams(ByteBuffer params); + + /** + * Deserialize a response from the device + * + * @param response the response data to deserialize + */ + public void deserialize(byte[] response) { + if (response.length < LefunConstants.CMD_HEADER_LENGTH || response.length < response[1]) + throw new IllegalArgumentException("Response is too short"); + if (calculateChecksum(response, 0, response[1] - 1) != response[response[1] - 1]) + throw new IllegalArgumentException("Incorrect message checksum"); + ByteBuffer buffer = ByteBuffer.wrap(response, LefunConstants.CMD_HEADER_LENGTH - 1, + response[1] - LefunConstants.CMD_HEADER_LENGTH); + buffer.order(ByteOrder.BIG_ENDIAN); + deserializeParams(response[2], buffer); + } + + /** + * Serializes a command to send to the device + * + * @return the data to send to the device + */ + public byte[] serialize() { + ByteBuffer buffer = ByteBuffer.allocate(LefunConstants.CMD_MAX_LENGTH - LefunConstants.CMD_HEADER_LENGTH); + buffer.order(ByteOrder.BIG_ENDIAN); + byte id = serializeParams(buffer); + return makeCommand(id, buffer); } /** @@ -87,25 +127,57 @@ public abstract class BaseCommand { return request; } + /** + * Throws a standard parameters length exception + */ protected void throwUnexpectedLength() { throw new IllegalArgumentException("Unexpected parameters length"); } + /** + * Checks for valid command ID and throws if wrong ID provided + * + * @param id command ID from device + * @param expectedId expected command ID + */ protected void validateId(byte id, byte expectedId) { if (id != expectedId) throw new IllegalArgumentException("Wrong command ID"); } + /** + * Checks for valid command ID and command length + * + * @param id command ID from device + * @param params params buffer from device + * @param expectedId expected command ID + * @param expectedLength expected params length + */ protected void validateIdAndLength(byte id, ByteBuffer params, byte expectedId, int expectedLength) { validateId(id, expectedId); if (params.limit() - params.position() != expectedLength) throwUnexpectedLength(); } + /** + * Gets whether a bit is set + * + * @param value the value to check against + * @param mask the bitmask + * @return whether the bits indicated by the bitmask are set + */ protected boolean getBit(int value, int mask) { return (value & mask) != 0; } + /** + * Sets a bit in a value + * + * @param value the value to modify + * @param mask the bitmask + * @param set whether to set or clear the bits + * @return the modified value + */ protected int setBit(int value, int mask, boolean set) { if (set) { return value | mask; @@ -114,26 +186,43 @@ public abstract class BaseCommand { } } + /** + * Sets a bit in a value + * + * @param value the value to modify + * @param mask the bitmask + * @param set whether to set or clear the bits + * @return the modified value + */ protected short setBit(short value, int mask, boolean set) { if (set) { - return (short)(value | mask); + return (short) (value | mask); } else { - return (short)(value & ~mask); + return (short) (value & ~mask); } } + /** + * Sets a bit in a value + * + * @param value the value to modify + * @param mask the bitmask + * @param set whether to set or clear the bits + * @return the modified value + */ protected byte setBit(byte value, int mask, boolean set) { if (set) { - return (byte)(value | mask); + return (byte) (value | mask); } else { - return (byte)(value & ~mask); + return (byte) (value & ~mask); } } /** * Find index of first bit that is set - * @param value - * @return + * + * @param value the value to look at + * @return the index of the lowest set bit, starting at 0 for least significant bit; -1 if no bits set */ protected int getLowestSetBitIndex(int value) { if (value == 0) return -1; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/LefunDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/LefunDeviceSupport.java index 9ae87a092..a71511160 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/LefunDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/LefunDeviceSupport.java @@ -102,6 +102,9 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.requests.Start import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; +/** + * Device support class for Lefun devices + */ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { private static final Logger LOG = LoggerFactory.getLogger(LefunDeviceSupport.class); @@ -111,6 +114,9 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { private int lastStepsCount = -1; private int lastStepsTimestamp; + /** + * Instantiates a new instance of LefunDeviceSupport + */ public LefunDeviceSupport() { super(LOG); addSupportedService(GattService.UUID_SERVICE_GENERIC_ACCESS); @@ -449,6 +455,11 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { } } + /** + * Sends unit of measurement to the device + * + * @param builder the transaction builder to append to + */ private void sendUnitsSetting(TransactionBuilder builder) { Prefs prefs = GBApplication.getPrefs(); String units = prefs.getString(SettingsActivity.PREF_MEASUREMENT_SYSTEM, @@ -463,6 +474,11 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { sendGeneralSettings(builder, (byte) 0xff, lefunUnits); } + /** + * Gets a features command with the currently enabled features set + * + * @return the features command + */ private FeaturesCommand getCurrentEnabledFeatures() { SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()); boolean raiseToWakeEnabled = prefs.getBoolean(DeviceSettingsPreferenceConst.PREF_LIFTWRIST_NOSHED, true); @@ -479,6 +495,13 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { return cmd; } + /** + * Sends general settings to the device + * + * @param builder the transaction builder to append to + * @param amPm AM/PM indicator setting + * @param units units of measurement setting + */ private void sendGeneralSettings(TransactionBuilder builder, byte amPm, byte units) { boolean givenBuilder = builder != null; try { @@ -497,6 +520,11 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { } } + /** + * Sends the user profile to the device + * + * @param builder the transaction builder to append to + */ private void sendUserProfile(TransactionBuilder builder) { boolean givenBuilder = builder != null; try { @@ -515,6 +543,11 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { } } + /** + * Sends enabled features settings to the device + * + * @param cmd the features command to send + */ private void sendEnabledFeaturesSetting(FeaturesCommand cmd) { try { TransactionBuilder builder = performInitialized(SetEnabledFeaturesRequest.class.getSimpleName()); @@ -529,6 +562,11 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { } } + /** + * Sends the sedentary reminder interval setting to the device + * + * @param period the reminder interval + */ private void sendSedentaryReminderIntervalSetting(int period) { try { TransactionBuilder builder = performInitialized(SetSedentaryReminderIntervalRequest.class.getSimpleName()); @@ -543,6 +581,11 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { } } + /** + * Sends the hydration reminder interval setting to the device + * + * @param period the reminder interval + */ private void sendHydrationReminderIntervalSetting(int period) { try { TransactionBuilder builder = performInitialized(SetHydrationReminderIntervalRequest.class.getSimpleName()); @@ -557,6 +600,11 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { } } + /** + * Sends the language selection to the device + * + * @param language the language selection + */ private void sendLanguageSetting(byte language) { try { TransactionBuilder builder = performInitialized(SetLanguageRequest.class.getSimpleName()); @@ -571,6 +619,12 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { } } + /** + * Stores received general settings to prefs + * + * @param amPm AM/PM indicator setting + * @param units units of measurement setting + */ public void receiveGeneralSettings(int amPm, int units) { SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()); boolean ampmEnabled = amPm == SettingsCommand.AM_PM_12_HOUR; @@ -579,6 +633,11 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { .apply(); } + /** + * Stores received enabled features settings to prefs + * + * @param cmd the features command + */ public void receiveEnabledFeaturesSetting(FeaturesCommand cmd) { SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()); prefs.edit() @@ -593,6 +652,11 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { .apply(); } + /** + * Stores received sedentary reminder interval setting to prefs + * + * @param period the interval + */ public void receiveSedentaryReminderIntervalSetting(int period) { SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()); prefs.edit() @@ -600,6 +664,11 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { .apply(); } + /** + * Stores received hydration reminder interval setting to prefs + * + * @param period the interval + */ public void receiveHydrationReminderIntervalSetting(int period) { SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()); prefs.edit() @@ -689,6 +758,13 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { return super.onCharacteristicChanged(gatt, characteristic); } + /** + * Handles commands from the device that are not typically associated with a request + * + * @param commandId the command ID + * @param data the entire response + * @return whether the response has been handled + */ private boolean handleAsynchronousResponse(byte commandId, byte[] data) { // Assume data already checked for correct response code and length switch (commandId) { @@ -702,6 +778,12 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { return false; } + /** + * Handles live steps data + * + * @param data the response + * @return whether the response has been handled + */ private boolean handleAsynchronousActivity(byte[] data) { try { GetStepsDataCommand cmd = new GetStepsDataCommand(); @@ -715,6 +797,12 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { } // Adapted from nodomain.freeyourgadget.gadgetbridge.service.devices.makibeshr3.MakibesHR3DeviceSupport.broadcastSample + + /** + * Broadcasts live sample + * + * @param command the steps data + */ private void broadcastSample(GetStepsDataCommand command) { Calendar now = Calendar.getInstance(); int timestamp = (int) (now.getTimeInMillis() / 1000); @@ -735,6 +823,12 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent); } + /** + * Handles PPG result from earlier request + * + * @param data the response + * @return whether the response has been handled + */ private boolean handleAsynchronousPpgResult(byte[] data) { try { PpgResultCommand cmd = new PpgResultCommand(); @@ -747,6 +841,12 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { } } + /** + * Handles find phone request + * + * @param data the response + * @return whether the response has been handled + */ private boolean handleAntiLoss(byte[] data) { try { FindPhoneCommand cmd = new FindPhoneCommand(); @@ -761,12 +861,26 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { } } + /** + * Callback when device info has been obtained + */ public void completeInitialization() { gbDevice.setState(GBDevice.State.INITIALIZED); gbDevice.sendDeviceUpdateIntent(getContext()); onReadConfiguration(""); } + /** + * Converts Lefun datetime format to Unix timestamp + * + * @param year the year (2 digits based on 2000) + * @param month the month + * @param day the day + * @param hour the hour + * @param minute the minute + * @param second the second + * @return Unix timestamp of the datetime + */ private int dateToTimestamp(byte year, byte month, byte day, byte hour, byte minute, byte second) { Calendar calendar = Calendar.getInstance(); calendar.set( @@ -780,6 +894,13 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { return (int) (calendar.getTimeInMillis() / 1000); } + /** + * Fetches an activity sample given the timestamp + * + * @param session DAO session + * @param timestamp the timestamp + * @return fetched activity or null if none exists + */ private LefunActivitySample getActivitySample(DaoSession session, int timestamp) { LefunActivitySampleDao dao = session.getLefunActivitySampleDao(); Long userId = DBHelper.getUser(session).getId(); @@ -792,6 +913,11 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { return q.unique(); } + /** + * Processes activity data and stores it + * + * @param command the activity data + */ public void handleActivityData(GetActivityDataCommand command) { try (DBHandler handler = GBApplication.acquireDB()) { DaoSession session = handler.getDaoSession(); @@ -818,6 +944,13 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { } } + /** + * Processes PPG data and stores it + * + * @param timestamp the timestamp + * @param ppgType the PPG type + * @param ppgData the data from the PPG operation + */ private void handlePpgData(int timestamp, int ppgType, byte[] ppgData) { int ppgData0 = ppgData[0] & 0xff; int ppgData1 = ppgData.length > 1 ? ppgData[1] & 0xff : 0; @@ -851,6 +984,11 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { } } + /** + * Processes PPG data from bulk get operation + * + * @param command the PPG data + */ public void handlePpgData(GetPpgDataCommand command) { int timestamp = dateToTimestamp(command.getYear(), command.getMonth(), command.getDay(), command.getHour(), command.getMinute(), command.getSecond()); @@ -859,6 +997,11 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { handlePpgData(timestamp, ppgType, ppgData); } + /** + * Processes PPG result received as a result of requesting PPG operation + * + * @param command the PPG result + */ public void handlePpgData(PpgResultCommand command) { int timestamp = (int) (Calendar.getInstance().getTimeInMillis() / 1000); int ppgType = command.getPpgType(); @@ -866,6 +1009,11 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { handlePpgData(timestamp, ppgType, ppgData); } + /** + * Processes bulk sleep data + * + * @param command the sleep data + */ public void handleSleepData(GetSleepDataCommand command) { try (DBHandler handler = GBApplication.acquireDB()) { DaoSession session = handler.getDaoSession(); @@ -915,6 +1063,9 @@ public class LefunDeviceSupport extends AbstractBTLEDeviceSupport { } } + /** + * Runs the next queued request + */ public void runNextQueuedRequest() { Request request = queuedRequests.poll(); if (request != null) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/requests/MultiFetchRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/requests/MultiFetchRequest.java index 031d8f6bd..1713739f4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/requests/MultiFetchRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/requests/MultiFetchRequest.java @@ -31,7 +31,14 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.lefun.LefunDeviceSup import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.OperationStatus; import nodomain.freeyourgadget.gadgetbridge.util.GB; +/** + * Represents a request that receives several responses + */ public abstract class MultiFetchRequest extends Request { + /** + * Instantiates a new MultiFetchRequest + * @param support the device support + */ protected MultiFetchRequest(LefunDeviceSupport support) { super(support, null); removeAfterHandling = false; @@ -97,5 +104,9 @@ public abstract class MultiFetchRequest extends Request { return true; } + /** + * Gets the display operation name + * @return the operation name + */ protected abstract String getOperationName(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/requests/Request.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/requests/Request.java index c11c33678..95d50e2cc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/requests/Request.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/lefun/requests/Request.java @@ -34,16 +34,31 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.operations.Op import nodomain.freeyourgadget.gadgetbridge.util.GB; // Ripped from nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request + +/** + * Basic request for operations with Lefun devices + */ public abstract class Request extends AbstractBTLEOperation { protected TransactionBuilder builder; protected boolean removeAfterHandling = true; private Logger logger = (Logger) LoggerFactory.getLogger(getName()); + /** + * Instantiates Request + * + * @param support the device support + * @param builder the transaction builder to use + */ protected Request(LefunDeviceSupport support, TransactionBuilder builder) { super(support); this.builder = builder; } + /** + * Gets the transaction builder + * + * @return the transaction builder + */ public TransactionBuilder getTransactionBuilder() { return builder; } @@ -57,36 +72,81 @@ public abstract class Request extends AbstractBTLEOperation getSupport().performConnected(builder.getTransaction()); } + /** + * When implemented in a subclass, provides the request bytes to send to the device + * + * @return the request bytes + */ public abstract byte[] createRequest(); + /** + * When overridden in a subclass, handles the response to the current command + * + * @param data the response data + */ public void handleResponse(byte[] data) { operationStatus = OperationStatus.FINISHED; } + /** + * Gets the class name of this instance + * + * @return the class name + */ public String getName() { Class thisClass = getClass(); while (thisClass.isAnonymousClass()) thisClass = thisClass.getSuperclass(); return thisClass.getSimpleName(); } + /** + * Logs a debug message + * + * @param message the message to log + */ protected void log(String message) { logger.debug(message); } + /** + * When implemented in a subclass, returns the command ID associated with the current request + * + * @return the command ID + */ public abstract int getCommandId(); + /** + * Gets whether the request will queue itself + * + * @return whether the request is self-queuing + */ public boolean isSelfQueue() { return false; } + /** + * Gets whether the request expects a response + * + * @return whether the request expects a response + */ public boolean expectsResponse() { return true; } + /** + * Gets whether the response should be removed from in progress requests list after handling + * + * @return whether the response should be removed after handling + */ public boolean shouldRemoveAfterHandling() { return removeAfterHandling; } + /** + * Reports an error to the user + * + * @param message the message to show + */ protected void reportFailure(String message) { GB.toast(getContext(), message, Toast.LENGTH_SHORT, GB.ERROR); }