Skip to content

Update to latest version of maplibre-compose to reduce memory leaks - #1180

Merged
davecraig merged 6 commits into
Scottish-Tech-Army:mainfrom
davecraig:main
Oct 23, 2026
Merged

davecraig merged 6 commits into
Scottish-Tech-Army:mainfrom
davecraig:main

Conversation

@davecraig

Copy link
Copy Markdown
Contributor

No description provided.

davecraig and others added 5 commits October 23, 2026 18:12
…up again

The monkey can leave the app where LaunchHome couldn't get back to Home:
in Street Preview, whose Home has no search bar and isn't left by Back;
in the guided tutorial, whose dialogs only Continue closes; or with its
window shrunk to a pop-up or left blank by the phone's freeform modes.
Restore then failed and the phone was set up again, wiping the app, about
once an hour on each phone, so no process ran long enough to show whether
its memory levels off.

LaunchHome now leaves Street Preview, and continues the tutorial's dialogs
and cancels it from the menu. If Restore still fails, the farm restarts
the app and runs it once more before setting the phone up again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ex6Fdp5ftuhE1ZEyhZb7WQ
…live uptime and memory

- local_apk tests a locally built APK in place of the CI releases, on every
  phone or one. It's usually signed differently, so whatever is on the phone
  is uninstalled first; unsetting it goes back to the releases the same way.

- When Restore fails after the monkey soak, the app is first brought back to
  the front and Restore retried, keeping its process running: Home and
  am start (MainActivity is singleTask), with a floating task made briefly
  unresizeable so it leaves freeform, and dark mode switched over and back,
  which brought back the Moto's blank grey window, whose Compose content had
  stopped drawing. Only then is the app restarted.
- pause_on_restore_failure leaves a phone as it is before the farm would
  restart its app, until resume-<serial> exists or pause_minutes pass.
- LaunchHome leaves Street Preview from inside its Back loop too, as backing
  out of another screen can land on it; Restore starts by cancelling a
  guided tutorial left running without a dialog showing (CancelTour.yaml).

- The report's devices table shows how long the app has been running and its
  PSS now, read every minute with the battery, else as at the newest cycle
  that recorded them: cycles the farm's own restarts stop record neither.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ex6Fdp5ftuhE1ZEyhZb7WQ
… 1.12

On the bench the new map engine used about 50 MB less than 0.13.1 over the
same walk, giving memory back as the map moved on where the old engine kept it.

- Kotlin 2.3.10 -> 2.4.21, Compose Multiplatform 1.11.1 -> 1.12.2 (the
  Compose plugin's version now follows composeMultiplatform; it was pinned
  separately, which stopped the Res class being generated), KSP 2.3.12, and
  the forced kotlin-daemon-client follows the Kotlin version.
- maplibre-compose 0.13.1 -> 0.20.0, on MapLibre Native FFI with the OpenGL
  runtime (the Cubot has no Vulkan; the merged manifest declares no Vulkan
  feature). The MapLibre Android SDK, its OpenGL substitution and the unused
  annotation plugin are gone, and with them the SDK's prefab package, so the
  prefab comments are now history.
- MapContainerLibre rewritten for rememberMapState, MapInteractions (pan only
  full screen, no rotate or tilt), animateCamera/animateCameraToBounds and no
  overlay. Its parameters are unchanged. While a beacon is being edited its
  marker is drawn over the centre of the map rather than as a layer following
  the camera, so it doesn't lag a pan; it's laid out to match the layer: the
  pin's point at the centre, at 1.2x, with its number.
- DestroyMapWhenDisposed is gone: the map's state closes itself when it
  leaves the composition.
- iOS: MapLibre Native now comes in through the Shared framework, so the
  MapLibre SwiftPM package is dropped and the system libraries it needs are
  linked, as maplibre-compose's iOS setup lists them.

Checked on a Pixel: Home, full screen map (draws straight away), panning
only when full screen, editing a marker's location, and an offline map's
extract outline and fit. Not checked: the iOS build, route waypoint
markers, and pinch-to-zoom inside a scrolling screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tile source was resolved again for every new map centre, which on Home
is every location update: listing the extracts and opening and reading each
of them, on the main thread, about once a second while walking. Which extract
covers the map only changes when the centre moves into another z14 tile, so
it's now remembered against that tile. On a phone standing still, 40 seconds
of location updates resolved it once instead of about 17 times.

On iOS the whole style JSON was also rebuilt for every location, and then
compared in full by maplibre-compose against the one it had. It's now built
only when the tile source or the colours change, as on Android, and the
layer overrides are made inside that on both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The red arrow, a symbol layer that jumped once a second, is replaced by
maplibre-compose's location indicator: a dot with a wedge pointing the way
the user faces, which animates between fixes and turns the short way past
north. It's the same red in every theme, as the arrow was, and the arrow's
drawable, now unused, is removed.

It's given the location and heading the rest of the app is using - the head
tracker's heading when one is paired, otherwise the compass - rather than
maplibre-compose's own providers, which would make their own platform
requests and know nothing of the head tracker, GPX replay or a simulated
location.

On Home it also shows how accurate those are: a circle for the fix's
horizontal accuracy, which HomeState already had, and a sector either side
of the heading for its accuracy, which HomeState now keeps too. That's the
fused orientation's heading error, iOS's heading accuracy, or the head
tracker's; the plain Android sensor provider reports none, and so shows no
sector. They reach the map through new optional userLocationAccuracy and
userHeadingAccuracy parameters on PlatformMapContainer, MapContainerLibre
and rememberFullScreenableMap. The other screens don't pass them.

Unlike the symbol layer, the indicator takes no part in label placement, so
labels are no longer pushed out from under it, and it draws above the
beacon marker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DocumentationScreens.getHelp makes a ResourceEnvironment for each language
through its internal constructor, which Compose Resources 1.12 gave a script
qualifier, between the language and the region. Looking for the old
four-parameter constructor found none, and the test failed. It now uses the
five-parameter one, with no script, as none of the values folders has one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@davecraig
davecraig deployed to development October 23, 2026 17:32 — with GitHub Actions Active
@davecraig
davecraig deployed to development October 23, 2026 17:32 — with GitHub Actions Active
@davecraig
davecraig deployed to development October 23, 2026 17:32 — with GitHub Actions Active
@davecraig
davecraig deployed to development October 23, 2026 17:32 — with GitHub Actions Active
@davecraig
davecraig merged commit 80d05ea into Scottish-Tech-Army:main Oct 23, 2026
5 checks passed

This branch was successfully deployed

1 active deployment
development — d1596e69 Deployed Oct 23, 2026 by davecraig via Build and test iOS app #1631
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant