Skip to content

Modern maps API: vector MapView + build-hint-wired NativeMap providers#5264

Open
shai-almog wants to merge 13 commits into
masterfrom
feature/modern-maps-api
Open

Modern maps API: vector MapView + build-hint-wired NativeMap providers#5264
shai-almog wants to merge 13 commits into
masterfrom
feature/modern-maps-api

Conversation

@shai-almog

Copy link
Copy Markdown
Collaborator

Summary

Brings mapping back into core, modernized, replacing the deprecated tile-based MapComponent and the external codenameone-google-maps cn1lib. Two components share one MapSurface API:

  • MapView — a pure-vector map rendered entirely through Graphics (a new MVT engine built on the framework's ProtoReader + GZIPInputStream, GeneralPath/Stroke). No native peer, so it composes cleanly with CN1 UI and works identically everywhere (simulator, web). Pluggable tile sources (raster OSM default, MVT, bundled, demo) and styles (light/dark, MapLibre-subset JSON).
  • NativeMap — a native-provider map (Apple MapKit, Google Maps, …) that falls back to an embedded MapView when no provider is wired in or available at runtime.

Provider model — wired by build hints, not code

The public API never names a provider. A provider is selected with the maps.provider build hint (apple/google/…); the builders (MapsProviderInjector) inject that provider's native-method-bearing implementation into the app's com.codename1.maps package and wire it in — so core/ports carry no map SDK and unused providers cost zero project size. No NativeInterface, no CodenameOneImplementation hooks.

Verified

  • iOS Apple MapKit validated end-to-end on the simulator (maps.provider=apple): builds, links, and renders a live MapKit map with a marker via NativeMap.
  • 29 unit tests in core-unittests (value types, model, provider SPI registry, MVT decoder incl. all value types, styles, color/zoom/cache internals, Web Mercator) — all green against a from-source build.
  • New developer-guide chapter (Maps.asciidoc) and hellocodenameone screenshot tests (deterministic offline DemoTileSource).

A companion PR mirrors the builder injection into the BuildDaemon repo.

🤖 Generated with Claude Code

…iders

Replaces the deprecated tile-based MapComponent / external google-maps cn1lib
with a modern com.codename1.maps API:

- MapView: pure-vector map rendered entirely via Graphics (MVT engine built on
  ProtoReader/GZIP, GeneralPath/Stroke), no native peer. Tile sources
  (Raster OSM, MVT, bundled, demo) and styles (light/dark, MapLibre-subset JSON).
- NativeMap: native-provider map (Apple MapKit, Google, ...) selected by the
  maps.provider build hint, falling back to an embedded MapView when no provider
  is wired in or available. Provider impls are injected by the builders
  (MapsProviderInjector) so the core carries no map SDK and the API never names
  a provider.
- Shared MapSurface API (camera, markers, polylines/polygons/circles, listeners,
  coordinate conversion); clean LatLng/MapBounds/CameraPosition value types.
- iOS Apple MapKit provider verified end-to-end on the simulator (builds, links,
  renders) via the maps.provider=apple hint; Android Google provider template.
- Full unit-test coverage in core-unittests, developer-guide chapter, and
  hellocodenameone screenshot tests (deterministic offline DemoTileSource).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Developer Guide build artifacts are available for download from this workflow run:

Developer Guide quality checks:

  • AsciiDoc linter: No issues found (report)
  • Vale: No alerts found (report)
  • Paragraph capitalization: No paragraph capitalization issues (report)
  • LanguageTool: No grammar matches (report)
  • Image references: No unused images detected (report)

@shai-almog

shai-almog commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator Author

Android screenshot updates

Compared 134 screenshots: 129 matched, 5 missing references.

  • NativeMapFallback — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/android/screenshots/NativeMapFallback.png.

    NativeMapFallback
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as NativeMapFallback.png in workflow artifacts.

  • RealOsmVector — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/android/screenshots/RealOsmVector.png.

    RealOsmVector
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as RealOsmVector.png in workflow artifacts.

  • VectorMapDarkStyle — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/android/screenshots/VectorMapDarkStyle.png.

    VectorMapDarkStyle
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as VectorMapDarkStyle.png in workflow artifacts.

  • VectorMapMarkers — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/android/screenshots/VectorMapMarkers.png.

    VectorMapMarkers
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as VectorMapMarkers.png in workflow artifacts.

  • VectorMapShapes — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/android/screenshots/VectorMapShapes.png.

    VectorMapShapes
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as VectorMapShapes.png in workflow artifacts.

Native Android coverage

  • 📊 Line coverage: 14.39% (8785/61061 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 11.66% (43282/371228), branch 5.13% (1791/34893), complexity 6.14% (2053/33443), method 10.64% (1663/15633), class 17.42% (385/2210)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend scalar fallback (no native SIMD)
SIMD int-add (64K x300) java 189ms / native 138ms = 1.3x speedup
SIMD float-mul (64K x300) java 121ms / native 94ms = 1.2x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 519.000 ms
Base64 CN1 decode 270.000 ms
Base64 native encode 1106.000 ms
Base64 encode ratio (CN1/native) 0.469x (53.1% faster)
Base64 native decode 1187.000 ms
Base64 decode ratio (CN1/native) 0.227x (77.3% faster)
Image encode benchmark status skipped (SIMD unsupported)

@shai-almog

shai-almog commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator Author

Native Windows port (cross-compiled)

Compared 131 screenshots: 126 matched, 5 missing references.

  • NativeMapFallback — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/windows/screenshots/NativeMapFallback.png.

    NativeMapFallback
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as NativeMapFallback.png in workflow artifacts.

  • RealOsmVector — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/windows/screenshots/RealOsmVector.png.

    RealOsmVector
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as RealOsmVector.png in workflow artifacts.

  • VectorMapDarkStyle — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/windows/screenshots/VectorMapDarkStyle.png.

    VectorMapDarkStyle
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as VectorMapDarkStyle.png in workflow artifacts.

  • VectorMapMarkers — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/windows/screenshots/VectorMapMarkers.png.

    VectorMapMarkers
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as VectorMapMarkers.png in workflow artifacts.

  • VectorMapShapes — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/windows/screenshots/VectorMapShapes.png.

    VectorMapShapes
    Preview info: JPEG preview quality 60; JPEG preview quality 60.
    Full-resolution PNG saved as VectorMapShapes.png in workflow artifacts.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 69ms / native 4ms = 17.2x speedup
SIMD float-mul (64K x300) java 71ms / native 5ms = 14.2x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 281.000 ms
Base64 CN1 decode 173.000 ms
Base64 SIMD encode 131.000 ms
Base64 encode ratio (SIMD/CN1) 0.466x (53.4% faster)
Base64 SIMD decode 129.000 ms
Base64 decode ratio (SIMD/CN1) 0.746x (25.4% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 36.000 ms
Image createMask (SIMD on) 13.000 ms
Image createMask ratio (SIMD on/off) 0.361x (63.9% faster)
Image applyMask (SIMD off) 54.000 ms
Image applyMask (SIMD on) 24.000 ms
Image applyMask ratio (SIMD on/off) 0.444x (55.6% faster)
Image modifyAlpha (SIMD off) 58.000 ms
Image modifyAlpha (SIMD on) 2captureWindowToPngBytes: window target is not WIC-backed

@shai-almog

shai-almog commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator Author

JavaScript port screenshot updates

Compared 127 screenshots: 122 matched, 5 missing references.

  • NativeMapFallback — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/javascript/screenshots/NativeMapFallback.png.

    NativeMapFallback
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as NativeMapFallback.png in workflow artifacts.

  • RealOsmVector — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/javascript/screenshots/RealOsmVector.png.

    RealOsmVector
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as RealOsmVector.png in workflow artifacts.

  • VectorMapDarkStyle — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/javascript/screenshots/VectorMapDarkStyle.png.

    VectorMapDarkStyle
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as VectorMapDarkStyle.png in workflow artifacts.

  • VectorMapMarkers — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/javascript/screenshots/VectorMapMarkers.png.

    VectorMapMarkers
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as VectorMapMarkers.png in workflow artifacts.

  • VectorMapShapes — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/javascript/screenshots/VectorMapShapes.png.

    VectorMapShapes
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as VectorMapShapes.png in workflow artifacts.

@shai-almog

shai-almog commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator Author

Native Linux port (x64)

Compared 133 screenshots: 128 matched, 5 missing references.

  • NativeMapFallback — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/linux/screenshots/NativeMapFallback.png.

    NativeMapFallback
    Preview info: JPEG preview quality 60; JPEG preview quality 60.
    Full-resolution PNG saved as NativeMapFallback.png in workflow artifacts.

  • RealOsmVector — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/linux/screenshots/RealOsmVector.png.

    RealOsmVector
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as RealOsmVector.png in workflow artifacts.

  • VectorMapDarkStyle — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/linux/screenshots/VectorMapDarkStyle.png.

    VectorMapDarkStyle
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as VectorMapDarkStyle.png in workflow artifacts.

  • VectorMapMarkers — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/linux/screenshots/VectorMapMarkers.png.

    VectorMapMarkers
    Preview info: JPEG preview quality 60; JPEG preview quality 60.
    Full-resolution PNG saved as VectorMapMarkers.png in workflow artifacts.

  • VectorMapShapes — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/linux/screenshots/VectorMapShapes.png.

    VectorMapShapes
    Preview info: JPEG preview quality 60; JPEG preview quality 60.
    Full-resolution PNG saved as VectorMapShapes.png in workflow artifacts.

@shai-almog

shai-almog commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator Author

Native Linux port (arm64)

Compared 133 screenshots: 128 matched, 5 missing references.

  • NativeMapFallback — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/linux/screenshots-arm/NativeMapFallback.png.

    NativeMapFallback
    Preview info: JPEG preview quality 60; JPEG preview quality 60.
    Full-resolution PNG saved as NativeMapFallback.png in workflow artifacts.

  • RealOsmVector — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/linux/screenshots-arm/RealOsmVector.png.

    RealOsmVector
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as RealOsmVector.png in workflow artifacts.

  • VectorMapDarkStyle — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/linux/screenshots-arm/VectorMapDarkStyle.png.

    VectorMapDarkStyle
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as VectorMapDarkStyle.png in workflow artifacts.

  • VectorMapMarkers — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/linux/screenshots-arm/VectorMapMarkers.png.

    VectorMapMarkers
    Preview info: JPEG preview quality 60; JPEG preview quality 60.
    Full-resolution PNG saved as VectorMapMarkers.png in workflow artifacts.

  • VectorMapShapes — missing reference. Reference screenshot missing at /home/runner/work/CodenameOne/CodenameOne/scripts/linux/screenshots-arm/VectorMapShapes.png.

    VectorMapShapes
    Preview info: JPEG preview quality 60; JPEG preview quality 60.
    Full-resolution PNG saved as VectorMapShapes.png in workflow artifacts.

@github-actions

Copy link
Copy Markdown
Contributor

Cloudflare Preview

@shai-almog

shai-almog commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 210 screenshots: 210 matched.
✅ Native Apple Watch (watchOS, Core Graphics) screenshot tests passed.

@shai-almog

shai-almog commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator Author

iOS screenshot updates

Compared 130 screenshots: 125 matched, 5 missing references.

  • NativeMapProvider — missing reference. Reference screenshot missing at /Users/runner/work/CodenameOne/CodenameOne/scripts/ios/screenshots/NativeMapProvider.png.

    NativeMapProvider
    Preview info: JPEG preview quality 70; JPEG preview quality 70; downscaled to 825x1789.
    Full-resolution PNG saved as NativeMapProvider.png in workflow artifacts.

  • RealOsmVector — missing reference. Reference screenshot missing at /Users/runner/work/CodenameOne/CodenameOne/scripts/ios/screenshots/RealOsmVector.png.

    RealOsmVector
    Preview info: JPEG preview quality 20; JPEG preview quality 20; downscaled to 590x1278.
    Full-resolution PNG saved as RealOsmVector.png in workflow artifacts.

  • VectorMapDarkStyle — missing reference. Reference screenshot missing at /Users/runner/work/CodenameOne/CodenameOne/scripts/ios/screenshots/VectorMapDarkStyle.png.

    VectorMapDarkStyle
    Preview info: JPEG preview quality 30; JPEG preview quality 30; downscaled to 590x1278.
    Full-resolution PNG saved as VectorMapDarkStyle.png in workflow artifacts.

  • VectorMapMarkers — missing reference. Reference screenshot missing at /Users/runner/work/CodenameOne/CodenameOne/scripts/ios/screenshots/VectorMapMarkers.png.

    VectorMapMarkers
    Preview info: JPEG preview quality 20; JPEG preview quality 20; downscaled to 590x1278.
    Full-resolution PNG saved as VectorMapMarkers.png in workflow artifacts.

  • VectorMapShapes — missing reference. Reference screenshot missing at /Users/runner/work/CodenameOne/CodenameOne/scripts/ios/screenshots/VectorMapShapes.png.

    VectorMapShapes
    Preview info: JPEG preview quality 20; JPEG preview quality 20; downscaled to 590x1278.
    Full-resolution PNG saved as VectorMapShapes.png in workflow artifacts.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 480 seconds

Build and Run Timing

Metric Duration
Simulator Boot 110000 ms
Simulator Boot (Run) 2000 ms
App Install 26000 ms
App Launch 14000 ms
Test Execution 628000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 183ms / native 10ms = 18.3x speedup
SIMD float-mul (64K x300) java 165ms / native 5ms = 33.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 912.000 ms
Base64 CN1 decode 485.000 ms
Base64 native encode 1242.000 ms
Base64 encode ratio (CN1/native) 0.734x (26.6% faster)
Base64 native decode 541.000 ms
Base64 decode ratio (CN1/native) 0.896x (10.4% faster)
Base64 SIMD encode 108.000 ms
Base64 encode ratio (SIMD/CN1) 0.118x (88.2% faster)
Base64 SIMD decode 80.000 ms
Base64 decode ratio (SIMD/CN1) 0.165x (83.5% faster)
Base64 encode ratio (SIMD/native) 0.087x (91.3% faster)
Base64 decode ratio (SIMD/native) 0.148x (85.2% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 30.000 ms
Image createMask (SIMD on) 5.000 ms
Image createMask ratio (SIMD on/off) 0.167x (83.3% faster)
Image applyMask (SIMD off) 172.000 ms
Image applyMask (SIMD on) 119.000 ms
Image applyMask ratio (SIMD on/off) 0.692x (30.8% faster)
Image modifyAlpha (SIMD off) 126.000 ms
Image modifyAlpha (SIMD on) 140.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.111x (11.1% slower)
Image modifyAlpha removeColor (SIMD off) 569.000 ms
Image modifyAlpha removeColor (SIMD on) 167.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.293x (70.7% faster)

@shai-almog

shai-almog commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator Author

iOS Metal screenshot updates

Compared 132 screenshots: 120 matched, 3 missing references, 9 missing actuals.

  • RealOsmVector — missing reference. Reference screenshot missing at /Users/runner/work/CodenameOne/CodenameOne/scripts/ios/screenshots-metal/RealOsmVector.png.

    RealOsmVector
    Preview info: JPEG preview quality 30; JPEG preview quality 30; downscaled to 590x1278.
    Full-resolution PNG saved as RealOsmVector.png in workflow artifacts.

  • VectorMapDarkStyle — missing reference. Reference screenshot missing at /Users/runner/work/CodenameOne/CodenameOne/scripts/ios/screenshots-metal/VectorMapDarkStyle.png.

    VectorMapDarkStyle
    Preview info: JPEG preview quality 30; JPEG preview quality 30; downscaled to 590x1278.
    Full-resolution PNG saved as VectorMapDarkStyle.png in workflow artifacts.

  • VectorMapMarkers — missing reference. Reference screenshot missing at /Users/runner/work/CodenameOne/CodenameOne/scripts/ios/screenshots-metal/VectorMapMarkers.png.

    VectorMapMarkers
    Preview info: JPEG preview quality 20; JPEG preview quality 20; downscaled to 590x1278.
    Full-resolution PNG saved as VectorMapMarkers.png in workflow artifacts.

  • DesktopMode — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • Gpu3DAnimation — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • Gpu3DCube — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • Gpu3DModel — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • Gpu3DTexturedCube — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • LottieAnimatedScreenshotTest — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • SVGAnimatedScreenshotTest — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • SVGStatic — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

  • landscape — missing actual screenshot. Actual screenshot missing (test did not produce output).

    No preview available for this screenshot.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 492 seconds

Build and Run Timing

Metric Duration
Simulator Boot 106000 ms
Simulator Boot (Run) 1000 ms
App Install 16000 ms
App Launch 53000 ms
Test Execution 1504000 ms

… docs

- MapView now defaults to the free, keyless OpenFreeMap vector basemap (real
  OpenStreetMap data) instead of synthetic/raster, so vector maps render real
  data with zero configuration and no API key.
- HttpTileSource resolves TileJSON endpoints (URLs with no {z} token) on first
  use, supporting OpenFreeMap's versioned tile URLs (and any TileJSON source).
- Add MvtTileSource.openFreeMap() factory.
- Add a real-OSM screenshot test backed by a bundled San Francisco tile fixture
  (real OpenFreeMap tiles) so the baseline shows real streets/water/labels yet
  stays deterministic and offline. Verified rendering on the iOS simulator.
- Add docs/maps-provider-ci-setup.md: how native-provider (Apple/Google) tests
  work, creating Google Maps keys, and wiring them as GitHub Actions secrets.
- Extra unit tests for the OpenFreeMap and raster OSM sources.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@shai-almog

shai-almog commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator Author

Mac native screenshot updates

Compared 134 screenshots: 129 matched, 5 missing references.

  • NativeMapProvider — missing reference. Reference screenshot missing at /Users/runner/work/CodenameOne/CodenameOne/scripts/mac-native/screenshots/NativeMapProvider.png.

    NativeMapProvider
    Preview info: JPEG preview quality 70; JPEG preview quality 70.
    Full-resolution PNG saved as NativeMapProvider.png in workflow artifacts.

  • RealOsmVector — missing reference. Reference screenshot missing at /Users/runner/work/CodenameOne/CodenameOne/scripts/mac-native/screenshots/RealOsmVector.png.

    RealOsmVector
    Preview info: JPEG preview quality 30; JPEG preview quality 30.
    Full-resolution PNG saved as RealOsmVector.png in workflow artifacts.

  • VectorMapDarkStyle — missing reference. Reference screenshot missing at /Users/runner/work/CodenameOne/CodenameOne/scripts/mac-native/screenshots/VectorMapDarkStyle.png.

    VectorMapDarkStyle
    Preview info: JPEG preview quality 40; JPEG preview quality 40.
    Full-resolution PNG saved as VectorMapDarkStyle.png in workflow artifacts.

  • VectorMapMarkers — missing reference. Reference screenshot missing at /Users/runner/work/CodenameOne/CodenameOne/scripts/mac-native/screenshots/VectorMapMarkers.png.

    VectorMapMarkers
    Preview info: JPEG preview quality 30; JPEG preview quality 30.
    Full-resolution PNG saved as VectorMapMarkers.png in workflow artifacts.

  • VectorMapShapes — missing reference. Reference screenshot missing at /Users/runner/work/CodenameOne/CodenameOne/scripts/mac-native/screenshots/VectorMapShapes.png.

    VectorMapShapes
    Preview info: JPEG preview quality 20; JPEG preview quality 20.
    Full-resolution PNG saved as VectorMapShapes.png in workflow artifacts.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 174 seconds

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 54ms / native 3ms = 18.0x speedup
SIMD float-mul (64K x300) java 54ms / native 2ms = 27.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 278.000 ms
Base64 CN1 decode 199.000 ms
Base64 native encode 849.000 ms
Base64 encode ratio (CN1/native) 0.327x (67.3% faster)
Base64 native decode 657.000 ms
Base64 decode ratio (CN1/native) 0.303x (69.7% faster)
Base64 SIMD encode 55.000 ms
Base64 encode ratio (SIMD/CN1) 0.198x (80.2% faster)
Base64 SIMD decode 47.000 ms
Base64 decode ratio (SIMD/CN1) 0.236x (76.4% faster)
Base64 encode ratio (SIMD/native) 0.065x (93.5% faster)
Base64 decode ratio (SIMD/native) 0.072x (92.8% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 29.000 ms
Image createMask (SIMD on) 19.000 ms
Image createMask ratio (SIMD on/off) 0.655x (34.5% faster)
Image applyMask (SIMD off) 212.000 ms
Image applyMask (SIMD on) 196.000 ms
Image applyMask ratio (SIMD on/off) 0.925x (7.5% faster)
Image modifyAlpha (SIMD off) 178.000 ms
Image modifyAlpha (SIMD on) 146.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.820x (18.0% faster)
Image modifyAlpha removeColor (SIMD off) 174.000 ms
Image modifyAlpha removeColor (SIMD on) 147.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.845x (15.5% faster)

shai-almog and others added 5 commits June 20, 2026 12:38
Adds NativeMapProviderScreenshotTest: visual confirmation that a native map
provider actually renders, catching "builds and launches but draws nothing"
failures a smoke build misses.

- Low-variance scene (Italian peninsula + Mediterranean at regional zoom):
  stable geography, strong land/water contrast, no traffic/street churn.
- Emits a screenshot only when a native provider is active (isNativeMap());
  NativeMapFallbackScreenshotTest is its complement and skips when a provider
  is active, so exactly one runs per platform/build.
- The test app sets ios.maps.provider=apple, so the iOS device-runner captures
  a real MapKit baseline with no secret (verified on the simulator).
- Lenient per-platform .tolerance (maxChannelDelta=20, maxMismatchPercent=12)
  absorbs tile/label noise but still fails on a blank/blocked map.
- docs/maps-provider-ci-setup.md: the screenshot-test design plus key-generation
  walkthroughs for Apple (none), Google, Huawei (HMS) and Bing, with secret
  names and which providers are screenshot-testable vs smoke-only in CI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address all failing checks on the modern-maps PR:

- SpotBugs (build-test): replace Number ctors with valueOf across the
  maps + maps/vector classes (DM_NUMBER_CTOR/DM_FP_NUMBER_CTOR/
  DM_BOOLEAN_CTOR); rewrite LatLng longitude wrap with modulo instead
  of a float loop (FL_FLOATS_AS_LOOP_COUNTERS); make
  VectorMapEngine.tileSize static (SS_SHOULD_BE_STATIC); reference the
  enclosing instance in BundledTileSource's fetch Runnable
  (SIC_INNER_SHOULD_BE_STATIC_ANON, also fixes the latent getClass()
  resource-resolution); exclude EQ_DOESNT_OVERRIDE_EQUALS for the
  one-shot HttpTileSource ConnectionRequest subclasses.
- build-javadocs: add package-info.java for com.codename1.maps.spi and
  com.codename1.maps.vector (flagged by check-package-info.sh).
- Developer guide prose: contractions / "for example" / drop "freely"
  for Vale; add basemap/basemaps/Mapbox to the LanguageTool accept list.
- build-ios / build-ios-metal / build-mac-native: the native screenshot
  suite hung on NativeMap creation because AppleMapProvider.m's
  nativeCreate did dispatch_sync to the main queue, which deadlocks when
  the CN1 iOS EDT already runs on the main thread. Create inline when
  already on the main thread.
- build-ios-watch: MKMapView and the overlay renderers are unavailable
  on watchOS; guard the MapKit impl with TARGET_OS_WATCH and provide
  linkable no-op stubs (nativeCreate returns 0 -> NativeMap falls back
  to the vector MapView).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The build-test quality gate flagged PMD forbidden rules across the new
maps classes (SpotBugs already passed):

- MissingOverride (x105): annotate every override -- interface impls,
  equals/hashCode/toString and Runnable.run() -- matching the core
  convention (e.g. CodenameOneImplementation annotates interface run()).
- ForLoopCanBeForeach (x28): convert index loops over lists/arrays to
  enhanced-for, with distinct loop variables to avoid nested shadowing.
- EmptyCatchBlock (x2): give the malformed-input catches an explicit
  return instead of a bare comment.
- AvoidUsingVolatile (x1): drop volatile from HttpTileSource
  .resolvedTemplate and read it under the existing monitor, which also
  keeps SpotBugs IS2_INCONSISTENT_SYNC satisfied.
- UnnecessaryImport (x1): remove the unused ActionListener import.
- UnusedFormalParameter (x1): drop MvtDecoder.decodeGeometry's unused
  geometry-type argument.

Verified locally on JDK 8: compiles, SpotBugs check passes with 0 bugs,
0 forbidden PMD violations across core, 0 Checkstyle errors, 3544 tests
green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The iOS/Mac screenshot suites crashed (SIGABRT / doesNotRecognizeSelector)
when NativeMap showed its native MapKit peer. Root cause: the peer was
built in the constructor, detached from any form, then laid out on show,
which UIKit/MapKit rejects.

Fix: resolve the provider in the constructor (cheap, no peer) and create
the vector fallback eagerly only when there is no provider; create the
native peer lazily once the component is attached -- in initComponent(),
deferred via callSerially so it runs after the form is shown rather than
re-entering layout mid-attach. Markers added before the peer existed are
replayed, and the post-show revalidate is guarded on a non-null form.

Verified on the iOS simulator: the suite now runs to completion
(CN1SS:SUITE:FINISHED) with no native crash; NativeMapFallback skips
cleanly when a provider is active (the earlier NullPointerException is
gone). Compiles on JDK 8 with SpotBugs (0 bugs) and 0 forbidden PMD.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The watchOS screenshot job has no committed map goldens, so the six map
screenshots that render on the watch (the vector MapView tests plus the
NativeMap vector fallback) were streamed as missing_expected and failed
the watch run, which tolerates zero missing goldens. Map coverage is
meaningful on the phone/tablet form factors; skip these tests on the
watch via CN.isWatch() so the watch suite stays green. NativeMapProvider
already self-skips on the watch (no native provider -> not isNativeMap()).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

shai-almog and others added 6 commits June 20, 2026 19:35
invalidate() (called from native code when the peer's size changes) did
getComponentForm().revalidate() with no null check. When a native peer is
added to a container that isn't fully wired to a form yet -- e.g. a
NativeMap peer installed after the form is shown -- getComponentForm()
returns null and the unguarded call NPEs on the EDT. Null-check the form
before revalidating; an invalidate with no form is a no-op.

Verified on the iOS simulator: with this guard the NativeMap MapKit peer
is added without the previous addComponent-time NullPointerException.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
On the watch the provider is registered and reports available, so the
test did not self-skip via isNativeMap(); it then fell back to the vector
map and streamed a NativeMapProvider screenshot with no committed watch
golden, failing build-ios-watch (which tolerates zero missing goldens).
The iOS phone/metal jobs already pass. Skip explicitly on CN.isWatch(),
matching the other map screenshot tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Visual-quality pass on the map rendering:

- Default markers now draw the standard Material Design map pin
  (FontImage.MATERIAL_PLACE) anchored at the tip, instead of a plain dot,
  matching platform conventions.
- StyleLayer gains an excludeFilter(); the light/dark styles exclude
  class=ferry from the transportation layer so ferry routes are no longer
  drawn as roads running across the bay ("lines into the sea").
- The vector screenshot tests now render the bundled real San Francisco
  OSM tiles (dark style, SF-landmark markers, and a route/area/radius
  shape set) instead of the synthetic "CN1 city" demo tileset, which
  looked weird and tiled the same block repeatedly. The redundant
  VectorMapBasemap test is removed (RealOsmVector already covers the
  light real basemap). NativeMap's vector fallback uses the real tiles too.

Marker rendering verified on the iOS simulator; the tile/style changes
render on the CI device runners (the bundled tiles do not load on the
local simulator due to its flattened resource layout).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two fixes that make the Apple MapKit NativeMap actually render:

1. Lay the peer out (revalidate the form to give it a non-zero frame)
   before doing anything else, and never let a post-show provider call
   abort installation -- previously an exception left the peer 0-sized
   and invisible.
2. Set the map's initial region when the native peer is created rather
   than via a separate setCamera() call after attach. createPeer now
   reads the host's initial center/zoom (new package-private
   NativeMap.getInitialCenter/getInitialZoom) and passes them into
   nativeCreate, which applies the MKCoordinateRegion as the MKMapView
   is built.

Verified on the iOS simulator: NativeMapProvider renders a real Apple
Maps view centered on the configured region (Italy / the Mediterranean
at the test's 41,13 zoom 5), ~2MB of map content, instead of a blank
panel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Apple MapKit (and future Google) native map renders live imagery that
varies run-to-run; widen the tolerance (and add it to the Metal/Mac
backends) so it tolerates tile/label noise while still failing on a blank
or blocked map. Triggers a fresh native + vector render for golden capture.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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