onTestNewFunction enhancements

EventHandler.onTestNewFunction
- add optional `options` Bundle parameter for receiving arguments

intent nodomain.freeyourgadget.gadgetbridge.command.DEBUG_TEST_NEW_FUNCTION
- add optional String extra `address` to specify the MAC address of the target device
- add optional Bundle extra `options` to pass arguments to EventHandler.onTestNewFunction
- construct a synthetic `options` bundle if the `options` extra is missing but there are `options_...` extras

Global setting `Settings / Developer options / Intent API / Allow Debug Command` must be enabled and the device(s) connected for the following examples.

Example to trigger onTestNewFunction for all currently connected devices:
`adb shell am broadcast -p nodomain.freeyourgadget.gadgetbridge -a "nodomain.freeyourgadget.gadgetbridge.command.DEBUG_TEST_NEW_FUNCTION"`

Example to trigger onTestNewFunction for a specific device:
`adb shell am broadcast -p nodomain.freeyourgadget.gadgetbridge -a "nodomain.freeyourgadget.gadgetbridge.command.DEBUG_TEST_NEW_FUNCTION" --es address "12:34:56:78:9A:BC" `

Example to trigger onTestNewFunction for a specific device with an option Bundle containing float x=4.2 and integer array y=[1,2,3] extras:
`adb.exe shell am broadcast -p nodomain.freeyourgadget.gadgetbridge -a "nodomain.freeyourgadget.gadgetbridge.command.DEBUG_TEST_NEW_FUNCTION" --es address "31:31:43:30:40:07" --ef options_x 4.2 --eia options_y 1,2,3`

Extras for some other types can also be specified via command line. See https://developer.android.com/tools/adb#IntentSpec for details.
This commit is contained in:
Thomas Kuehne
2026-06-06 07:28:51 +00:00
parent 8be39c99ea
commit bc20a1a874
49 changed files with 348 additions and 112 deletions
@@ -1,4 +1,4 @@
/* Copyright (C) 2016-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
/* Copyright (C) 2016-2026 Andreas Shimokawa, Arjan Schrijver, Carsten
Pfeiffer, Damien Gaignon, Daniel Dakhno, Daniele Gobbetti, Davis Mosenkovs,
fparri, José Rebelo, mamucho, maxirnilian, mkusnierz, Petr Vaněk, Taavi
Eomäe
@@ -948,7 +948,7 @@ public class GBDeviceAdapterv2 extends ListAdapter<GBDevice, GBDeviceAdapterv2.V
return true;
} else if (itemId == R.id.controlcenter_device_submenu_test_new_function) {
if (device.isInitialized()) {
GBApplication.deviceService(device).onTestNewFunction();
GBApplication.deviceService(device).onTestNewFunction(null);
showTransientSnackbar(R.string.controlcenter_test_new_function);
}
return true;
@@ -23,6 +23,7 @@ import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.UUID;
@@ -141,7 +142,7 @@ public interface EventHandler {
*/
void onReadConfiguration(String config);
void onTestNewFunction();
void onTestNewFunction(@Nullable Bundle options);
void onSendWeather();
@@ -1,4 +1,4 @@
/* Copyright (C) 2022-2024 José Rebelo, octospacc
/* Copyright (C) 2022-2026 José Rebelo, octospacc, Thomas Kuehne
This file is part of Gadgetbridge.
@@ -16,11 +16,17 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.externalevents;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_OPTIONS;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,9 +48,11 @@ import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.database.PeriodicDbExporter;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
@@ -56,7 +64,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.backup.PeriodicZipExporter;
public class IntentApiReceiver extends BroadcastReceiver {
private static final Logger LOG = LoggerFactory.getLogger(IntentApiReceiver.class);
private static final String msgDebugNotAllowed = "Intent API Allow Debug Commands not allowed";
private static final String msgDebugNotAllowed = "Intent API Allow Debug Commands not allowed: {}";
public static final String COMMAND_ACTIVITY_SYNC = "nodomain.freeyourgadget.gadgetbridge.command.ACTIVITY_SYNC";
@Deprecated
@@ -71,6 +79,10 @@ public class IntentApiReceiver extends BroadcastReceiver {
public static final String COMMAND_DEBUG_TEST_NEW_FUNCTION = "nodomain.freeyourgadget.gadgetbridge.command.DEBUG_TEST_NEW_FUNCTION";
public static final String COMMAND_DEBUG_HEAP_DUMP = "nodomain.freeyourgadget.gadgetbridge.command.DEBUG_HEAP_DUMP";
public static final String INTENT_API_ALLOW_DEBUG_COMMANDS = "intent_api_allow_debug_commands";
public static final String EXTRA_ADDRESS = "address";
private static final String MAC_ADDR_PATTERN = "^([0-9A-F]{2}:){5}[0-9A-F]{2}$";
@Override
@@ -136,8 +148,8 @@ public class IntentApiReceiver extends BroadcastReceiver {
break;
case COMMAND_DEBUG_SEND_NOTIFICATION:
if (!prefs.getBoolean("intent_api_allow_debug_commands", false)) {
LOG.warn(msgDebugNotAllowed);
if (!prefs.getBoolean(INTENT_API_ALLOW_DEBUG_COMMANDS, false)) {
LOG.warn(msgDebugNotAllowed, COMMAND_DEBUG_SEND_NOTIFICATION);
return;
}
LOG.info("Triggering Debug Send notification message");
@@ -187,8 +199,8 @@ public class IntentApiReceiver extends BroadcastReceiver {
break;
case COMMAND_DEBUG_INCOMING_CALL:
if (!prefs.getBoolean("intent_api_allow_debug_commands", false)) {
LOG.warn(msgDebugNotAllowed);
if (!prefs.getBoolean(INTENT_API_ALLOW_DEBUG_COMMANDS, false)) {
LOG.warn(msgDebugNotAllowed, COMMAND_DEBUG_INCOMING_CALL);
return;
}
LOG.info("Triggering Debug Incoming Call");
@@ -202,8 +214,8 @@ public class IntentApiReceiver extends BroadcastReceiver {
break;
case COMMAND_DEBUG_END_CALL:
if (!prefs.getBoolean("intent_api_allow_debug_commands", false)) {
LOG.warn(msgDebugNotAllowed);
if (!prefs.getBoolean(INTENT_API_ALLOW_DEBUG_COMMANDS, false)) {
LOG.warn(msgDebugNotAllowed, COMMAND_DEBUG_END_CALL);
return;
}
LOG.info("Triggering Debug End Call");
@@ -213,28 +225,27 @@ public class IntentApiReceiver extends BroadcastReceiver {
break;
case COMMAND_DEBUG_SET_DEVICE_ADDRESS:
if (!prefs.getBoolean("intent_api_allow_debug_commands", false)) {
LOG.warn(msgDebugNotAllowed);
if (!prefs.getBoolean(INTENT_API_ALLOW_DEBUG_COMMANDS, false)) {
LOG.warn(msgDebugNotAllowed, COMMAND_DEBUG_SET_DEVICE_ADDRESS);
return;
}
setDeviceAddress(intent);
break;
case COMMAND_DEBUG_SET_DEVICE_TYPE:
if (!prefs.getBoolean("intent_api_allow_debug_commands", false)) {
LOG.warn(msgDebugNotAllowed);
if (!prefs.getBoolean(INTENT_API_ALLOW_DEBUG_COMMANDS, false)) {
LOG.warn(msgDebugNotAllowed, COMMAND_DEBUG_SET_DEVICE_TYPE);
return;
}
setDeviceType(intent);
break;
case COMMAND_DEBUG_TEST_NEW_FUNCTION:
if (!prefs.getBoolean("intent_api_allow_debug_commands", false)) {
LOG.warn(msgDebugNotAllowed);
return;
if (!prefs.getBoolean(INTENT_API_ALLOW_DEBUG_COMMANDS, false)) {
LOG.warn(msgDebugNotAllowed, COMMAND_DEBUG_TEST_NEW_FUNCTION);
break;
}
LOG.info("Triggering Debug Test New Function");
GBApplication.deviceService().onTestNewFunction();
onTestNewFunction(intent);
break;
case COMMAND_DEBUG_HEAP_DUMP:
@@ -258,6 +269,82 @@ public class IntentApiReceiver extends BroadcastReceiver {
}
}
private void onTestNewFunction(@NonNull Intent intent) {
final String address = intent.getStringExtra(EXTRA_ADDRESS);
Bundle options = intent.getBundleExtra(EXTRA_OPTIONS);
if(options == null){
options = constructSyntheticOptions(intent.getExtras());
}
DeviceService deviceService = GBApplication.deviceService();
if (address != null && !address.isEmpty()) {
GBApplication application = GBApplication.app();
DeviceManager deviceManager = application.getDeviceManager();
GBDevice device = deviceManager.getDeviceByAddress(address);
if (device == null) {
if (validAddress(address)) {
LOG.warn("onTestNewFunction: device with address '{}' not found", address);
}
return;
}
deviceService = deviceService.forDevice(device);
LOG.info("Triggering onTestNewFunction for {} using {} options",
address, (options == null) ? "no" : options.size());
} else {
LOG.info("Triggering onTestNewFunction without device using {} options",
(options == null) ? "no" : options.size());
}
deviceService.onTestNewFunction(options);
}
/// Construct synthetic options Bundle by copying values for all options_xxx keys to xxx.
/// Only supports types that can be specified via `adb shell am broadcast ...`
private Bundle constructSyntheticOptions(Bundle extras) {
if (extras == null) {
return null;
}
final String prefix = "options_";
Bundle options = null;
for (String key : extras.keySet()) {
if (key != null && key.length() > prefix.length() && key.startsWith(prefix)) {
if (options == null) {
options = new Bundle();
}
String option = key.substring(prefix.length());
Object extra = extras.get(key);
if (extra == null) {
options.putSerializable(option, null);
} else if (extra instanceof String value) {
options.putString(option, value);
} else if (extra instanceof Boolean value) {
options.putBoolean(option, value);
} else if (extra instanceof Integer value) {
options.putInt(option, value);
} else if (extra instanceof Long value) {
options.putLong(option, value);
} else if (extra instanceof Float value) {
options.putFloat(option, value);
} else if (extra instanceof float[] value) {
options.putFloatArray(option, value);
} else if (extra instanceof int[] value) {
options.putIntArray(option, value);
} else if (extra instanceof long[] value) {
options.putLongArray(option, value);
} else if (extra instanceof Uri value) {
options.putParcelable(option, value);
} else {
LOG.warn("unhandled extra {} {} {}", option, extra, extra.getClass());
}
}
}
return options;
}
public IntentFilter buildFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(COMMAND_ACTIVITY_SYNC);
@@ -351,7 +438,7 @@ public class IntentApiReceiver extends BroadcastReceiver {
}
private void setDeviceType(final Intent intent) {
final String address = intent.getStringExtra("address");
final String address = intent.getStringExtra(EXTRA_ADDRESS);
if (!validAddress(address)) {
return;
}
@@ -32,6 +32,7 @@ import android.os.Bundle;
import android.provider.ContactsContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -515,8 +516,9 @@ public class GBDeviceService implements DeviceService {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
Intent intent = createIntent().setAction(ACTION_TEST_NEW_FUNCTION);
intent.putExtra(EXTRA_OPTIONS, options);
invokeService(intent);
}
@@ -26,6 +26,7 @@ import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -612,7 +613,7 @@ public abstract class AbstractDeviceSupport implements DeviceSupport {
* in the Debug menu.
*/
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
}
@@ -1150,7 +1150,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
deviceSupport.onAppReorder(uuids);
break;
}
case ACTION_INSTALL:
case ACTION_INSTALL: {
Uri uri = intentCopy.getParcelableExtra(EXTRA_URI);
Bundle options = Objects.requireNonNullElse(intentCopy.getBundleExtra(EXTRA_OPTIONS), Bundle.EMPTY);
if (uri != null) {
@@ -1160,6 +1160,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
LOG.error("Got null uri for app to install");
}
break;
}
case ACTION_SET_ALARMS:
ArrayList<? extends Alarm> alarms = (ArrayList<? extends Alarm>) intentCopy.getSerializableExtra(EXTRA_ALARMS);
deviceSupport.onSetAlarms(alarms);
@@ -1211,7 +1212,8 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
break;
}
case ACTION_TEST_NEW_FUNCTION: {
deviceSupport.onTestNewFunction();
Bundle options = intentCopy.getBundleExtra(EXTRA_OPTIONS);
deviceSupport.onTestNewFunction(options);
break;
}
case ACTION_SEND_WEATHER: {
@@ -1,4 +1,4 @@
/* Copyright (C) 2015-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
/* Copyright (C) 2015-2026 Andreas Shimokawa, Arjan Schrijver, Carsten
Pfeiffer, Daniel Dakhno, José Rebelo, Julien Pivotto, Kasha, Sebastian Kranz,
Steffen Liebergeld
@@ -25,6 +25,7 @@ import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -486,11 +487,11 @@ public class ServiceDeviceSupport implements DeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
if (checkBusy("test new function event")) {
return;
}
delegate.onTestNewFunction();
delegate.onTestNewFunction(options);
}
@Override
@@ -1,4 +1,4 @@
/* Copyright (C) 2019-2024 Albert, Andreas Shimokawa, Arjan Schrijver, Damien
/* Copyright (C) 2019-2026 Albert, Andreas Shimokawa, Arjan Schrijver, Damien
Gaignon, Gabriele Monaco, Ganblejs, gfwilliams, glemco, Gordon Williams,
halemmerich, illis, José Rebelo, Lukas, LukasEdl, Marc Nause, Martin Boonk,
rarder44, Richard de Boer, Simon Sievert
@@ -55,6 +55,7 @@ import android.os.Handler;
import android.util.Base64;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.text.HtmlCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@@ -2335,7 +2336,7 @@ public class BangleJSDeviceSupport extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
try {
final JSONObject json = new JSONObject();
//json.put("t", "http");
@@ -1,4 +1,4 @@
/* Copyright (C) 2023-2024 Andreas Böhler, foxstidious, Johannes Krude
/* Copyright (C) 2023-2026 Andreas Böhler, foxstidious, Johannes Krude
This file is part of Gadgetbridge.
@@ -19,6 +19,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.casio.gbx100;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Toast;
@@ -77,6 +78,8 @@ import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_
import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_STEPS_GOAL;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivityUser.PREF_USER_WEIGHT_KG;
import androidx.annotation.Nullable;
public class CasioGBX100DeviceSupport extends Casio2C2DSupport implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final Logger LOG = LoggerFactory.getLogger(CasioGBX100DeviceSupport.class);
@@ -633,7 +636,7 @@ public class CasioGBX100DeviceSupport extends Casio2C2DSupport implements Shared
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
byte[] data = new byte[2];
data[0] = (byte)0x2e;
data[1] = (byte)0x03;
@@ -1,4 +1,4 @@
/* Copyright (C) 2024 José Rebelo
/* Copyright (C) 2024-2026 José Rebelo
This file is part of Gadgetbridge.
@@ -978,7 +978,7 @@ public class CmfWatchProSupport extends AbstractBTLESingleDeviceSupport implemen
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
}
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2023-2024 Andreas Shimokawa, José Rebelo
/* Copyright (C) 2023-2026 Andreas Shimokawa, José Rebelo
This file is part of Gadgetbridge.
@@ -24,8 +24,10 @@ import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.apache.commons.lang3.ArrayUtils;
@@ -469,7 +471,7 @@ public class PixooProtocol extends GBDeviceProtocol {
}
@Override
public byte[] encodeTestNewFunction() {
public byte[] encodeTestNewFunction(@Nullable Bundle options) {
//return encodeAudioModeCommand(1); // works
//return encodeEffectModeCommand(5); // does nothing
//return encodeClockModeCommand(0, true, true, false, true, 127, 127, 127); // works r,g,b up to 127
@@ -1,4 +1,4 @@
/* Copyright (C) 2020-2024 Andreas Shimokawa, Arjan Schrijver
/* Copyright (C) 2020-2026 Andreas Shimokawa, Arjan Schrijver
This file is part of Gadgetbridge.
@@ -19,6 +19,9 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.domyos;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -283,7 +286,7 @@ public class DomyosT540Support extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
TransactionBuilder builder = createTransactionBuilder("xxx");
//setDisplayValues(builder, 1, 10, 10, 10, 10);
//writeChunked(builder, COMMAND_SET_DISPLAY);
@@ -1,7 +1,27 @@
/* Copyright (C) 2025-2026 Lars Berning, Thomas Kuehne
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.earfun.airpro4;
import static nodomain.freeyourgadget.gadgetbridge.service.devices.earfun.EarFunPacketEncoder.joinPackets;
import android.os.Bundle;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -17,7 +37,7 @@ public class EarFunAirPro4Protocol extends EarFunProtocol {
private static final Logger LOG = LoggerFactory.getLogger(EarFunAirPro4Protocol.class);
@Override
public byte[] encodeTestNewFunction() {
public byte[] encodeTestNewFunction(@Nullable Bundle options) {
return joinPackets(
// new EarFunPacket(EarFunPacket.Command.COMMAND_REBOOT).encode()
);
@@ -1,4 +1,4 @@
/* Copyright (C) 2021-2024 Arjan Schrijver, Damien Gaignon, Petr Vaněk
/* Copyright (C) 2021-2026 Arjan Schrijver, Damien Gaignon, Petr Vaněk
This file is part of Gadgetbridge.
@@ -89,8 +89,10 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.fitpro.FitProConstant
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.apache.commons.lang3.ArrayUtils;
@@ -541,7 +543,7 @@ public class FitProDeviceSupport extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
LOG.debug("Hello FitPro Test function");
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2022-2024 Daniel Dakhno
/* Copyright (C) 2022-2026 Daniel Dakhno
This file is part of Gadgetbridge.
@@ -22,8 +22,10 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import org.slf4j.Logger;
@@ -227,7 +229,7 @@ public class FlipperZeroSupport extends FlipperZeroBaseSupport{
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
try {
openApp("Infrared");
} catch (IOException e) {
@@ -253,6 +255,6 @@ public class FlipperZeroSupport extends FlipperZeroBaseSupport{
@Override
public void onFetchRecordedData(int dataTypes) {
onTestNewFunction();
onTestNewFunction(null);
}
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2021-2024 narektor, Petr Vaněk
/* Copyright (C) 2021-2026 narektor, Petr Vaněk
This file is part of Gadgetbridge.
@@ -20,6 +20,9 @@ import static nodomain.freeyourgadget.gadgetbridge.util.CheckSums.crc16_ccitt;
import static nodomain.freeyourgadget.gadgetbridge.util.GB.hexdump;
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -332,7 +335,7 @@ public class GalaxyBudsProtocol extends GBDeviceProtocol {
}
@Override
public byte[] encodeTestNewFunction() {
public byte[] encodeTestNewFunction(@Nullable Bundle options) {
//return encodeMessage(get_debug_build_info);
return null;
}
@@ -1,3 +1,19 @@
/* Copyright (C) 2024-2026 Daniele Gobbetti, José Rebelo, kuhy, Thomas Kuehne
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin;
import android.annotation.SuppressLint;
@@ -1503,7 +1519,7 @@ public class GarminSupport extends AbstractBTLESingleDeviceSupport implements IC
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
}
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2025 José Rebelo
/* Copyright (C) 2025-2026 José Rebelo
This file is part of Gadgetbridge.
@@ -20,6 +20,7 @@ import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCharacteristic
import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import nodomain.freeyourgadget.gadgetbridge.GBApplication
@@ -889,7 +890,7 @@ class GloryFitSupport() : AbstractBTLESingleDeviceSupport(LOG) {
// TODO onSendWeather
}
override fun onTestNewFunction() {
override fun onTestNewFunction(options: Bundle?) {
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2016-2024 Alberto, Andreas Shimokawa, Arjan Schrijver,
/* Copyright (C) 2016-2026 Alberto, Andreas Shimokawa, Arjan Schrijver,
Carsten Pfeiffer, Damien Gaignon, ivanovlev, João Paulo Barraca, Lesur
Frederic, Pavel Motyrev, Quallenauge, Sebastian Kranz
@@ -24,8 +24,11 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.hplus;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -595,7 +598,7 @@ public class HPlusSupport extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
LOG.info("Test New Function");
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2018-2024 Andreas Shimokawa, Arjan Schrijver, beardhatcode,
/* Copyright (C) 2018-2026 Andreas Shimokawa, Arjan Schrijver, beardhatcode,
Carsten Pfeiffer, Damien Gaignon, Daniel Dakhno, Daniele Gobbetti, Dmitry
Markin, José Rebelo, musover, Nathan Philipp Bo Seddig, NekoBox, Petr
Vaněk, Robbert Gurdeep Singh, Sebastian Kranz, Taavi Eomäe, Toby Murray,
@@ -35,6 +35,7 @@ import android.widget.Toast;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import net.e175.klaus.solarpositioning.DeltaT;
@@ -2788,7 +2789,7 @@ public abstract class HuamiSupport extends AbstractBTLESingleDeviceSupport
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
try {
final TransactionBuilder builder = performInitialized("test request");
writeToConfiguration(builder, HuamiService.COMMAND_REQUEST_WORKOUT_ACTIVITY_TYPES);
@@ -1,4 +1,4 @@
/* Copyright (C) 2025 José Rebelo
/* Copyright (C) 2025-2026 José Rebelo
This file is part of Gadgetbridge.
@@ -27,6 +27,7 @@ import android.util.SparseArray;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.apache.commons.lang3.RandomUtils;
import org.slf4j.Logger;
@@ -446,8 +447,8 @@ public class ZeppOsBtbrSupport extends AbstractBTBRDeviceSupport implements Zepp
}
@Override
public void onTestNewFunction() {
zeppOsSupport.onTestNewFunction();
public void onTestNewFunction(@Nullable Bundle options) {
zeppOsSupport.onTestNewFunction(options);
}
@Override
@@ -1,4 +1,4 @@
/* Copyright (C) 2025 José Rebelo
/* Copyright (C) 2025-2026 José Rebelo
This file is part of Gadgetbridge.
@@ -25,6 +25,7 @@ import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -203,8 +204,8 @@ public class ZeppOsBtleSupport extends AbstractBTLESingleDeviceSupport implement
}
@Override
public void onTestNewFunction() {
zeppOsSupport.onTestNewFunction();
public void onTestNewFunction(@Nullable Bundle options) {
zeppOsSupport.onTestNewFunction(options);
}
@Override
@@ -1,4 +1,4 @@
/* Copyright (C) 2022-2024 Daniel Dakhno, José Rebelo, Oleg Vasilev
/* Copyright (C) 2022-2026 Daniel Dakhno, José Rebelo, Oleg Vasilev
This file is part of Gadgetbridge.
@@ -319,7 +319,7 @@ public class ZeppOsSupport extends AbstractDeviceSupport
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
//final ZeppOsTransactionBuilder builder = createZeppOsTransactionBuilder("test new function");
//configService.requestConfig(
// builder,
@@ -1,4 +1,4 @@
/* Copyright (C) 2024 Damien Gaignon, Martin.JM
/* Copyright (C) 2024-2026 Damien Gaignon, Martin.JM
This file is part of Gadgetbridge.
@@ -23,6 +23,7 @@ import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -208,7 +209,7 @@ public class HuaweiBRSupport extends AbstractBTBRDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
supportProvider.onTestNewFunction();
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2024 Damien Gaignon, Martin.JM
/* Copyright (C) 2024-2026 Damien Gaignon, Martin.JM
This file is part of Gadgetbridge.
@@ -26,6 +26,7 @@ import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -213,7 +214,7 @@ public class HuaweiLESupport extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
supportProvider.onTestNewFunction();
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2019-2024 Arjan Schrijver, Damien Gaignon, Sophanimus
/* Copyright (C) 2019-2026 Arjan Schrijver, Damien Gaignon, Sophanimus
This file is part of Gadgetbridge.
@@ -53,8 +53,11 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.jyou;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -334,7 +337,7 @@ public class BFH16DeviceSupport extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
showNotification((byte)0xFF, "", "");
@@ -1,4 +1,4 @@
/* Copyright (C) 2021-2024 Arjan Schrijver, Damien Gaignon, Petr Vaněk
/* Copyright (C) 2021-2026 Arjan Schrijver, Damien Gaignon, Petr Vaněk
This file is part of Gadgetbridge.
@@ -93,8 +93,11 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.laxasfit.LaxasFitCons
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -495,7 +498,7 @@ public class LaxasFitDeviceSupport extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
LOG.debug("Hello LaxasFit Test function");
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2019-2024 Andreas Böhler, Andreas Shimokawa, Arjan
/* Copyright (C) 2019-2026 Andreas Böhler, Andreas Shimokawa, Arjan
Schrijver, Damien Gaignon, mamucho, mkusnierz, Taavi Eomäe
This file is part of Gadgetbridge.
@@ -24,10 +24,12 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Toast;
import androidx.annotation.IntRange;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger;
@@ -913,7 +915,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
requestBloodPressureMeasurement();
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2024 Andreas Shimokawa
/* Copyright (C) 2024-2026 Andreas Shimokawa
This file is part of Gadgetbridge.
@@ -25,7 +25,9 @@ import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger;
@@ -99,7 +101,7 @@ public class MarstekB2500DeviceSupport extends AbstractBTLESingleDeviceSupport {
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
sendCommand("get infos 1", COMMAND_GET_INFOS1);
sendCommand("get infos 2", COMMAND_GET_INFOS2);
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2015-2024 Andreas Shimokawa, Arjan Schrijver, atkyritsis,
/* Copyright (C) 2015-2026 Andreas Shimokawa, Arjan Schrijver, atkyritsis,
Carsten Pfeiffer, Christian Fischer, Daniele Gobbetti, Dmitry Markin,
freezed-or-frozen, JohnnySun, José Rebelo, Julien Pivotto, Kasha, Sebastian
Kranz, Sergey Trofimov, Steffen Liebergeld, Toby Murray
@@ -1170,7 +1170,7 @@ public class MiBandSupport extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
try {
TransactionBuilder builder = performInitialized("Toggle sensor reading");
if (isReadingSensorData) {
@@ -1,4 +1,4 @@
/* Copyright (C) 2019 krzys_h
/* Copyright (C) 2019-2026 krzys_h
This file is part of Gadgetbridge.
@@ -21,11 +21,13 @@ import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.text.format.DateFormat;
import android.util.Pair;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger;
@@ -1986,7 +1988,7 @@ public class MoyoungDeviceSupport extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
try {
new QuerySettingsOperation(this).perform();
} catch (IOException e) {
@@ -1,4 +1,4 @@
/* Copyright (C) 2021-2024 Arjan Schrijver, Daniele Gobbetti, Petr Vaněk
/* Copyright (C) 2021-2026 Arjan Schrijver, Daniele Gobbetti, Petr Vaněk
This file is part of Gadgetbridge.
@@ -17,6 +17,7 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.nothing;
import android.content.SharedPreferences;
import android.os.Bundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,6 +48,8 @@ import nodomain.freeyourgadget.gadgetbridge.service.btbr.TransactionBuilder;
import static nodomain.freeyourgadget.gadgetbridge.util.CheckSums.getCRC16ansi;
import static nodomain.freeyourgadget.gadgetbridge.util.GB.hexdump;
import androidx.annotation.Nullable;
public class Ear1Support extends AbstractHeadphoneBTBRDeviceSupport {
private static final Logger LOG = LoggerFactory.getLogger(Ear1Support.class);
private static final int MAX_MTU = 512;
@@ -60,7 +63,7 @@ public class Ear1Support extends AbstractHeadphoneBTBRDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
//getDeviceIOThread().write(((NothingProtocol) getDeviceProtocol()).encodeBatteryStatusReq());
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2015-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
/* Copyright (C) 2015-2026 Andreas Shimokawa, Arjan Schrijver, Carsten
Pfeiffer, Daniele Gobbetti, Kasha, Sebastian Kranz, Steffen Liebergeld,
Taavi Eomäe
@@ -24,6 +24,7 @@ import android.os.Bundle;
import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import org.json.JSONArray;
@@ -255,9 +256,9 @@ public class PebbleSupport extends AbstractSerialDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
if (reconnect()) {
super.onTestNewFunction();
super.onTestNewFunction(options);
}
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2021-2024 Daniel Dakhno
/* Copyright (C) 2021-2026 Daniel Dakhno
This file is part of Gadgetbridge.
@@ -17,6 +17,9 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qc35;
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -69,7 +72,7 @@ public class QC35Protocol extends GBDeviceProtocol {
}
@Override
public byte[] encodeTestNewFunction() {
public byte[] encodeTestNewFunction(@Nullable Bundle options) {
return new byte[]{0x02, 0x02, 0x01, 0x00};
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2019-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
/* Copyright (C) 2019-2026 Andreas Shimokawa, Arjan Schrijver, Carsten
Pfeiffer, Daniel Dakhno, Dmitriy Bogdanov, Taavi Eomäe
This file is part of Gadgetbridge.
@@ -29,6 +29,7 @@ import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@@ -705,8 +706,8 @@ public class QHybridSupport extends QHybridBaseSupport {
}
@Override
public void onTestNewFunction() {
watchAdapter.onTestNewFunction();
public void onTestNewFunction(@Nullable Bundle options) {
watchAdapter.onTestNewFunction(options);
}
@Override
@@ -21,6 +21,9 @@ import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.Nullable;
import org.json.JSONObject;
@@ -67,7 +70,7 @@ public abstract class WatchAdapter {
public abstract void setStepGoal(int stepGoal);
public abstract void setVibrationStrength(short strength);
public abstract void syncNotificationSettings();
public abstract void onTestNewFunction();
public abstract void onTestNewFunction(@Nullable Bundle options);
public abstract void setTimezoneOffsetMinutes(short offset);
public abstract void onInstallApp(Uri uri);
@@ -26,10 +26,13 @@ import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.json.JSONArray;
import org.json.JSONException;
import org.slf4j.Logger;
@@ -523,7 +526,7 @@ public class FossilWatchAdapter extends WatchAdapter {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
queueWrite(new FilePutRequest(
FileHandle.HAND_ACTIONS,
new byte[]{
@@ -55,6 +55,7 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@@ -1719,7 +1720,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
onSendCalendar();
}
@@ -25,9 +25,11 @@ import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.SparseArray;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger;
@@ -408,7 +410,7 @@ public class MisfitWatchAdapter extends WatchAdapter {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2022-2024 Andreas Shimokawa
/* Copyright (C) 2022-2026 Andreas Shimokawa
This file is part of Gadgetbridge.
@@ -19,8 +19,11 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.soflow;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -218,7 +221,7 @@ public class SoFlowSupport extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
TransactionBuilder builder;
try {
builder = performInitialized("request unknown");
@@ -1,4 +1,4 @@
/* Copyright (C) 2021-2024 José Rebelo
/* Copyright (C) 2021-2026 José Rebelo
This file is part of Gadgetbridge.
@@ -17,6 +17,9 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.sony.headphones;
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -300,7 +303,7 @@ public class SonyHeadphonesProtocol extends GBDeviceProtocol {
}
@Override
public byte[] encodeTestNewFunction() {
public byte[] encodeTestNewFunction(@Nullable Bundle options) {
//return Request.fromHex(MessageType.COMMAND_1, "c40100").encode(sequenceNumber);
return null;
@@ -1,3 +1,19 @@
/* Copyright (C) 2025-2026 Daniele Gobbetti, Thomas Kuehne, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.thermalprinter;
import android.bluetooth.BluetoothGatt;
@@ -19,6 +35,7 @@ import android.text.TextPaint;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -369,7 +386,7 @@ public class GenericThermalPrinterSupport extends AbstractBTLESingleDeviceSuppor
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
// send(PrinterCommand.feedPaper.message(new byte[]{1}));
sendTestPrint();
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2021-2024 Daniel Dakhno
/* Copyright (C) 2021-2026 Daniel Dakhno
This file is part of Gadgetbridge.
@@ -24,7 +24,9 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger;
@@ -212,7 +214,7 @@ public class VescDeviceSupport extends VescBaseDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
getValues();
// getDecodedADC();
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2023-2024 Ascense, Frank Ertl
/* Copyright (C) 2023-2026 Ascense, Frank Ertl
This file is part of Gadgetbridge.
@@ -28,11 +28,13 @@ import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import org.slf4j.Logger;
@@ -107,7 +109,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.withingssteelhr.comm
import nodomain.freeyourgadget.gadgetbridge.service.devices.withingssteelhr.communication.notification.NotificationProvider;
import nodomain.freeyourgadget.gadgetbridge.service.devices.withingssteelhr.communication.notification.NotificationSource;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_LANGUAGE;
@@ -426,7 +427,7 @@ public class WithingsSteelHRDeviceSupport extends AbstractBTLESingleDeviceSuppor
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
String hexMessage = "0105080015050900111006040102030507000000000000000000";
conversationQueue.clear();
addSimpleConversationToQueue(new SimpleHexToByteMessage(hexMessage));
@@ -1,4 +1,4 @@
/* Copyright (C) 2023-2024 Andreas Shimokawa, José Rebelo, Yoran Vulker
/* Copyright (C) 2023-2026 Andreas Shimokawa, José Rebelo, Yoran Vulker
This file is part of Gadgetbridge.
@@ -24,6 +24,7 @@ import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
@@ -238,7 +239,7 @@ public class XiaomiSupport extends AbstractDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
//sendCommand("test new function", 2, 29);
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2018-2024 Andreas Shimokawa, Arjan Schrijver, Carsten
/* Copyright (C) 2018-2026 Andreas Shimokawa, Arjan Schrijver, Carsten
Pfeiffer, chklump, Damien Gaignon, José Rebelo, Maxim Baz, Petr Vaněk,
Sebastian Kranz
@@ -21,6 +21,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.zetime;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.Toast;
import org.slf4j.Logger;
@@ -74,6 +75,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.calendar.CalendarManager;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_SYNC_CALENDAR;
import androidx.annotation.Nullable;
public class ZeTimeDeviceSupport extends AbstractBTLESingleDeviceSupport {
private static final Logger LOG = LoggerFactory.getLogger(ZeTimeDeviceSupport.class);
@@ -461,7 +463,7 @@ public class ZeTimeDeviceSupport extends AbstractBTLESingleDeviceSupport {
}
@Override
public void onTestNewFunction() {
public void onTestNewFunction(@Nullable Bundle options) {
// byte[] strength = {
// ZeTimeConstants.CMD_PREAMBLE,
// ZeTimeConstants.CMD_SHOCK_STRENGTH,
@@ -1,4 +1,4 @@
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo,
/* Copyright (C) 2015-2026 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo,
Julien Pivotto, Steffen Liebergeld
This file is part of Gadgetbridge.
@@ -18,6 +18,9 @@
package nodomain.freeyourgadget.gadgetbridge.service.serial;
import android.location.Location;
import android.os.Bundle;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -282,8 +285,8 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport
}
@Override
public void onTestNewFunction() {
byte[] bytes = gbDeviceProtocol.encodeTestNewFunction();
public void onTestNewFunction(@Nullable Bundle options) {
byte[] bytes = gbDeviceProtocol.encodeTestNewFunction(options);
sendToDevice(bytes);
}
@@ -1,10 +1,29 @@
/* Copyright (C) 2025-2026 José Rebelo, Thomas Kuehne
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.serial;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.location.Location;
import android.os.Bundle;
import android.os.ParcelUuid;
import androidx.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -249,8 +268,8 @@ public abstract class AbstractSerialDeviceSupportV2<T extends GBDeviceProtocol>
}
@Override
public void onTestNewFunction() {
byte[] bytes = mDeviceProtocol.encodeTestNewFunction();
public void onTestNewFunction(@Nullable Bundle options) {
byte[] bytes = mDeviceProtocol.encodeTestNewFunction(options);
sendToDevice(bytes);
}
@@ -1,4 +1,4 @@
/* Copyright (C) 2015-2024 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo,
/* Copyright (C) 2015-2026 Andreas Shimokawa, Carsten Pfeiffer, José Rebelo,
Julien Pivotto, Steffen Liebergeld
This file is part of Gadgetbridge.
@@ -18,6 +18,7 @@
package nodomain.freeyourgadget.gadgetbridge.service.serial;
import android.location.Location;
import android.os.Bundle;
import androidx.annotation.Nullable;
@@ -164,7 +165,7 @@ public abstract class GBDeviceProtocol {
}
@Nullable
public byte[] encodeTestNewFunction() { return null; }
public byte[] encodeTestNewFunction(@Nullable Bundle options) { return null; }
@Nullable
public GBDeviceEvent[] decodeResponse(byte[] responseData) {