Commit Graph
16274 Commits
Author SHA1 Message Date
Thomas Kuehne eac3c94a0b persistence: add BaseActivitySummary support 2026-05-29 01:20:14 +00:00
Thomas Kuehne 422047de19 DBHelper: improve JavaDoc 2026-05-29 01:18:34 +00:00
Thomas Kuehne 38e43a32b6 GB.toast: improve JavaDoc 2026-05-28 23:26:38 +00:00
Gideon Zenz 6c70aa371d Health Connect: Drop out-of-range sample values to prevent sync abort
Health Connect enforces hard min/max bounds on each record-type field; a
single out-of-range value caused the record constructor to throw and
killed the entire batch insert. The trigger was a Garmin Venu 3
producing HRV > 200 ms, but several syncers shared the same gap (no
upper bound, only > 0 or no validation at all).

Add explicit per-syncer numeric guards matching the bounds enforced by
HC's record constructors, drop out-of-range samples, log them with the
existing [HC_SYNC] prefix, and continue the sync.

Bounds applied (per-record HC enforcement):
- HRV: 1..200 ms
- VO2Max: 0..100 ml/kg/min
- Weight: 0..1000 kg
- BloodGlucose: 0..900.91 mg/dL (= 50 mmol/L) -- previously unvalidated
- RespiratoryRate: 0..1000 breaths/min
- HeartRate / RestingHR: 1..300 / 0..300 bpm (widened from 20..250 to
  match HC's contract; downstream consumers can apply physiological
  filters)
- SpO2: 0..100 %
- Steps: 1..1000000 per record
- ActiveCalories: 0..1000000 kcal per record
- Distance: 0..1000000 m per record
- Skin temperature delta: -30..30 °C
- Body temperature: existing physiological clamp 25..45 °C kept (HC has
  no enforced bound)

Add Logger.skipOutOfRange extension in syncers/SyncerLogging.kt and
relax HC_SYNC_TAG visibility from private to internal so syncers can
share it.

HeartRateSync aggregates dropped-sample counts into one summary log
line per slice rather than per-sample, to avoid log spam from glitchy
firmware.

convertSample visibility relaxed from protected to internal in the two
abstract base syncers so the new boundary tests can call it directly.

30 new unit tests in SyncerRangeValidationTest cover boundary
conditions per syncer.
2026-05-27 11:44:35 +02:00
Gideon Zenz 7832f8a4a8 Health Connect: Sanitise GPS route to prevent ExerciseRoute crash
ExerciseRoute requires strictly increasing timestamps; duplicate-second
points from device GPS parsers (e.g. Xiaomi Smart Band 9 Pro outdoor
cycling) caused IllegalArgumentException at construction time, aborting
the workout sync entirely.

Extract route construction into buildSanitisedRoute, which:
- drops points outside the workout time window
- drops points with non-finite or out-of-range lat/lng (HC's Location
  constructor enforces lat in [-90, 90], lng in [-180, 180])
- drops points with non-finite or negative hdop/vdop accuracy (HC
  rejects negative accuracy)
- deduplicates points by Instant
- returns null if fewer than two usable points remain
- catches IllegalArgumentException as a safety net so future HC
  invariants degrade gracefully (workout saves without route rather
  than the whole sync aborting)

Logs dropped points with the [HC_SYNC] prefix so users can grep.
2026-05-27 10:20:07 +02:00
José Rebelo 35d926ce4e Merge pull request 'add missing @Override annotations' (#6187)
Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/6187
2026-05-26 01:11:48 +02:00
José Rebelo d9a3495d09 Merge pull request 'annotations: prefer androidx.annotation over org.jetbrains.annotations' (#6184)
Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/6184
2026-05-26 01:10:24 +02:00
Thomas Kuehne 2f2bb33ddf add missing @Override annotations 2026-05-25 17:24:58 +00:00
Thomas Kuehne dd2b864461 DeviceCoordinator: explicitly specify @Nullable for some returns 2026-05-25 16:01:16 +00:00
Thomas Kuehne 04c7f9e9e6 DeviceCoordinator: explicitly specify @NonNull for arguments 2026-05-25 16:00:49 +00:00
Thomas Kuehne f58130ba8d annotations: prefer androidx.annotation over org.jetbrains.annotations
The Androidx annotations are frequently used whereas Jetbrains annotations are infrequently used.
Where possible, use Androidx instead of Jetbrains annotations.
2026-05-24 18:17:04 +00:00
Thomas Kuehne 5cb0e6b70d Garmin: add more ANT+ gadget IDs 2026-05-24 13:31:49 +00:00
Dominik Riebeling d659225e7b CMF Buds 2 Plus: Enable touch configuration
- Enable touch options
- Add missing Play/Pause option to list
2026-05-24 09:32:36 +02:00
Dominik Riebeling 8acad7a853 CMF Buds: Enable spatial audio for more models
- Buds 2

Supported according to the product specs page.
2026-05-24 09:32:36 +02:00
Dominik Riebeling f32111a8b4 CMF Buds: Update EQ presets
Add preset list for

- Buds 2
- Buds 2 Pro

Lists taken from Nothing support pages.
2026-05-24 09:32:36 +02:00
Dominik Riebeling f66dc7d724 CMF Buds: Enable Low Latency on more devices
- ear(a): according to #3994
2026-05-24 09:32:36 +02:00
Dominik Riebeling f02937c321 CMF Buds: Enable Ultra Bass for more devices
Ultra Bass is supported by

- Buds Pro 2: according to #3924
- Buds 2: according to #5579

Needs verification.
2026-05-24 09:32:36 +02:00
Dominik Riebeling 9b00c3edaa CMF Buds 2 Plus: Add spatial mode
- Add support for spatial mode
- Enable for Buds 2 Plus
2026-05-24 09:32:36 +02:00
dependency-botandJosé Rebelo eaebdc8278 Update dependency org.json:json to v20260522 2026-05-23 23:50:41 +02:00
José Rebelo db550db8f1 Update changelog 2026-05-23 21:34:51 +01:00
wighawagandJosé Rebelo a1f710081e xplora xmove 2026-05-23 22:11:54 +02:00
José Rebelo defd82c01d Sony WF-1000XM5: Enable further capabilities (#3341) 2026-05-23 20:21:48 +01:00
José Rebelo 12af319b9b Sony WF-1000XM5: Enable further capabilities (#3341) 2026-05-23 20:21:13 +01:00
José Rebelo 86d42bab78 GPX: Fix parsing of timestamps without timezone
Although these are non-conforming, there are a lot of gpx files online
that do not contain a timezone and fail to be parsed.
2026-05-23 18:42:49 +01:00
José Rebelo 89e495c6b1 Garmin: Fix empty caller when unknown 2026-05-23 15:15:58 +01:00
José Rebelo 43eb4bc4b7 CMF Buds 2a: Fix touch options 2026-05-23 13:34:25 +01:00
José Rebelo f5b5416ca8 Garmin: Show toast on waypoint upload complete 2026-05-22 22:54:11 +01:00
José Rebelo f317b744eb Set up logging before database 2026-05-22 21:54:41 +01:00
dependency-botandJosé Rebelo a1b243ca69 Update dependency org.freemarker:freemarker to v2.3.34 2026-05-22 17:17:32 +01:00
dependency-botandJosé Rebelo 5ef311e29a Update protobuf to v4.35.0 2026-05-22 17:57:06 +02:00
José Rebelo e011d794e6 Only load map on focused workout details fragment (#5456)
Should reduce memory pressure when loading very large workouts, which
would be loading the maps in parallel in adjacent pages.
2026-05-21 20:06:41 +01:00
Martin BraunandJosé Rebelo b8a85e03ea Add Third Party Alarm Intent API: Set and Dismiss alarms for your device from any app (#6088)
Adds the capability to set and dismiss alarms from third party apps through an Intent API, fixes #5553

**This PR was co-authored by ChatGPT and José Rebelo (passively):**

- Scaffold for the core component `DeviceAlarmReceiver` was taken from José's `DeviceSettingsReceiver`
- The core implementation was written by me by hand, ChatGPT was used to review and find potential issues and bugs
- The `DeviceAlarmReceiverTest` unit tests were written by ChatGPT and reviewed by me

**About these changes:**

- Adds a new developer settings entry for the device that the user needs to enable, so other apps can use the Intent API for such device
- Supports app blacklisting as it is done in the `DeviceSettingsReceiver`
- `ConfigureAlarms.addMissingAlarms()` was migrated to `DBHelper.fillMissingAlarms()` to provide this abstraction globally
- `AlarmReceiver` was migrated to `SunriseSunsetAlarmReceiver` to avoid ambiguity with this feature; the formerly called `AlarmReceiver` was related to setting calendar events based on the sunrise/sunset via an Intent API
- The API is registered in the `DeviceCommunicationService`
- The `ConfigureAlarms` activity updates its list after setting alarms from a third party app by broadcasting `ACTION_SAVE_ALARMS`
- It is possible to set alarms of a device that is offline, it should sync when the device connects next time, unless it downloads the alarms from the device when connecting
- However, this device-to-GadgetBridge alarm sync API is not commonly abstracted, so we cannot respect existing alarms on the devices when changing alarms within the new Intent API; the database is the single source of truth and connecting the device after using the API will reset alarms
- ~~The API was designed to align with the `AlarmClock` API from Android, but~~ there is no feature parity to improve the design and interaction; after all the `AlarmClock` API is interacted with `startActivity`, but `GadgetBridge` uses `sendBroadcast` receivers, which is recommend for background tasks
- Errors are not raised to the caller (i.e. providing unknown or invalid Mac Address of device or trying to set an alarm on a nonexisting slot); these errors are logged though

**EDIT: Additional changes during the development:**

- Since slot IDs are unpredictable, the flow is title-driven (there is no way to provide an ID)
- Dismissing an alarm through the API removes its title
- Only alarms without a title can be overwritten and a title should be set through this API to retain the ability to dismiss it without dismissing all alarms of the user
- Dismissing all alarms regardless of the title is still possible
- The title is exposed in the UI not just when the device supports it, but also when this API is enabled in the developer settings of the device itself

**Example usage:**

- https://gitlab.com/martin-braun/warpclock-plus/-/blob/feat/gb/app/src/main/java/com/antonok/warpclock/AlarmIntentService.kt demonstrates dismissing all alarms and setting multiple alarms (search for `sendBroadcast`)
- `DeviceAlarmReceiverTest` should cover all cases for a more complete overview of the capabilities of the API

Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/6088
2026-05-21 19:57:07 +02:00
José Rebelo 0c11ba44f8 CMF Buds 2a: Add touch options 2026-05-21 09:51:14 +01:00
Jack Wilsdon 51b305fb04 Add Thunderbird support 2026-05-19 23:53:38 +01:00
José Rebelo 3c848e6ac0 Moondrop Space Travel 2 Ultra: Initial support 2026-05-19 20:26:16 +01:00
José Rebelo dec078a2a0 Xiaomi-protobuf: Fix swapped min and max temperatures 2026-05-19 18:59:29 +01:00
José Rebelo 0a149f873a Merge pull request 'Pebble: Add support for installing dual slot firmware' (#5985)
Reviewed-on: https://codeberg.org/Freeyourgadget/Gadgetbridge/pulls/5985
2026-05-19 19:45:40 +02:00
Steffen WinterandArjan Schrijver df6a1c73e4 Fix drawer being drawn behind status bar
Before this commit the Gadgetbridge logo in the open navigation drawer
was partly cut of due to missing window insets on the drawer content.
2026-05-19 15:53:33 +02:00
José Rebelo a6a1188a11 Huawei Watch Fit 5 / 5 Pro: Initial support 2026-05-18 22:10:12 +01:00
José Rebelo 61f4396805 Garmin GPSMAP H1: Initial support 2026-05-18 21:49:00 +01:00
José Rebelo 09022454b8 Amazfit Bip S: Attempt to fix reboot on notification without subject or body 2026-05-17 16:23:38 +01:00
Benjamin Temple ad08874466 Pebble: Don't sleep for 100ms when doing firmware installs
originally the 100ms sleep after writes was introduced to fix a bug where sending an appmessage right after ACKing a previous appmessage cuased the outgoing packet to be NACK'd by the 3.0+ firmware. 4fe498efc
Keeping because 100ms for most situations doesn't matter, but definitely worth avoiding when uploading new firmware to the watch.
2026-05-17 08:06:18 -07:00
Benjamin Temple 1f36e541e3 Pebble: Ensure that we always try to install on the inactive firmware slot for dual slot firmware watches 2026-05-17 08:06:17 -07:00
Benjamin Temple 309dffbe61 Pebble: Display active firmware slot (for 2 slot watches) in watch details 2026-05-17 08:06:15 -07:00
Benjamin Temple 9d46ba6bc9 Pebble: Keep mmSequence in 5-bit range and don't overflow into the command bits 2026-05-17 08:06:14 -07:00
Benjamin Temple 5cd9c40436 Pebble: Update firmware install protocol to better match rebble.
1. We should upload all of the firmware before starting the install process. Otherwise this can cause issues with the install sometimes failing
2. Updates the encoding of the upload start. There are different upload start packet structures
3. Encode the install firmwareStart packet correctly to include how big it will be so that the watch can pre-erase the flash region.
4. Send the firmware then resouces to match the order that the pebble app sends the files.
5. remove arbitrary 100ms sleep in the main loop, the state machine blocks on readWithException already.
2026-05-17 08:06:13 -07:00
Benjamin Temple 045787fa93 Pebble: Fix blocking for 1s after writing every chunk to the watch
vastly speeds up transfer speeds
2026-05-17 08:06:11 -07:00
Benjamin Temple c29064a36c Pebble: Add support for dual slot firmware 2026-05-17 08:06:10 -07:00
Benjamin Temple f920968deb Pebble: Fix not being able to install firmware since firmware util was comparing the wrong model string 2026-05-17 08:06:04 -07:00
José Rebelo 3fe42f3d8f Huami: Avoid infinite loop when fetching very short activity 2026-05-17 16:04:14 +01:00