ReviewOS

also looking at this

craft-native/craft

feat(maps): add key-free native Android maps and shared map controls

#363
Merged chris wants to merge codex/wildloop-native-map-providers into main
28 files +1857 -481

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

.github/workflows/mobile-e2e.ymlmodified+1-1
Changes to .github/workflows/mobile-e2e.yml
@@ -607,7 +607,7 @@ jobs:
607607 api-level: ${{ fromJSON((inputs.scope != 'android-navigation' || inputs.android_suite == 'full') && '[34,35]' || inputs.android_suite == 'system-bars' && '[35]' || '[34]') }}
608608 env:
609609 CRAFT_ANDROID_NATIVE_SUITE: ${{ inputs.scope != 'android-navigation' && 'full' || inputs.android_suite || 'focused' }}
610 CRAFT_ANDROID_TEST_CLASS: ${{ inputs.scope == 'android-navigation' && inputs.android_suite == 'maps' && 'dev.craft.navigationtest.NativeMapTest#keyFreeBasemapsKeepTheRecordedRouteAndDirectionSignsVisible,dev.craft.navigationtest.NativeMapTest#nativeMapMutationsUpdateThePinAndCameraWithoutReloadingTheStyle,dev.craft.navigationtest.NativeMapTest#showingTheLocationDotDoesNotRequestPermissionDuringRendering' || inputs.scope == 'android-navigation' && inputs.android_suite == 'system-bars' && 'dev.craft.navigationtest.NativeNavigationTest#nativeScreenBackgroundOptionAppliesAndResets' || inputs.scope == 'android-navigation' && inputs.android_suite != 'full' && 'dev.craft.navigationtest.NativeNavigationTest#outgoingTabTapWinsOverSettlingSwipe,dev.craft.navigationtest.NativeNavigationTest#thirdTabTapWinsOverSettlingSwipe,dev.craft.navigationtest.NativeNavigationTest#cancelledSwipeTargetIsVisibleWhenSelectedLater,dev.craft.navigationtest.NativeNavigationTest#completedReverseSwipeKeepsRetainedTabVisible,dev.craft.navigationtest.NativeNavigationTest#nativePullToRefreshSurvivesViewReattachment,dev.craft.navigationtest.NativeNavigationTest#pushedScreenTabAccessoryOpensNativeRouteAndClearsOnBack,dev.craft.navigationtest.NativeFlatListTest#refreshAppearanceUsesTheScreenContrastFallback,dev.craft.navigationtest.NativeNavigationTest#nativeDatePickerKeepsFollowingControlsMounted' || '' }}
610 CRAFT_ANDROID_TEST_CLASS: ${{ inputs.scope == 'android-navigation' && inputs.android_suite == 'maps' && 'dev.craft.navigationtest.NativeMapTest#keyFreeBasemapsKeepTheRecordedRouteAndDirectionSignsVisible,dev.craft.navigationtest.NativeMapTest#nativeMapMutationsUpdateThePinAndCameraWithoutReloadingTheStyle,dev.craft.navigationtest.NativeMapTest#showingTheLocationDotDoesNotRequestPermissionDuringRendering,dev.craft.navigationtest.NativeMapTest#controlledRegionEchoPreservesTheCameraAfterANativeDrag' || inputs.scope == 'android-navigation' && inputs.android_suite == 'system-bars' && 'dev.craft.navigationtest.NativeNavigationTest#nativeScreenBackgroundOptionAppliesAndResets' || inputs.scope == 'android-navigation' && inputs.android_suite != 'full' && 'dev.craft.navigationtest.NativeNavigationTest#outgoingTabTapWinsOverSettlingSwipe,dev.craft.navigationtest.NativeNavigationTest#thirdTabTapWinsOverSettlingSwipe,dev.craft.navigationtest.NativeNavigationTest#cancelledSwipeTargetIsVisibleWhenSelectedLater,dev.craft.navigationtest.NativeNavigationTest#completedReverseSwipeKeepsRetainedTabVisible,dev.craft.navigationtest.NativeNavigationTest#nativePullToRefreshSurvivesViewReattachment,dev.craft.navigationtest.NativeNavigationTest#pushedScreenTabAccessoryOpensNativeRouteAndClearsOnBack,dev.craft.navigationtest.NativeFlatListTest#refreshAppearanceUsesTheScreenContrastFallback,dev.craft.navigationtest.NativeNavigationTest#nativeDatePickerKeepsFollowingControlsMounted' || '' }}
611611 if: ${{ inputs.scope != 'ios-navigation' && inputs.scope != 'ios-render' }}
612612 runs-on: ubuntu-latest
613613 timeout-minutes: 35
packages/android/fixtures/native-navigation/NativeMapTest.ktmodified+31-0
Changes to packages/android/fixtures/native-navigation/NativeMapTest.kt
@@ -207,6 +207,37 @@ class NativeMapTest {
207207 evidence("map-mutated-pin-and-camera")
208208 }
209209
210 @Test
211 fun controlledRegionEchoPreservesTheCameraAfterANativeDrag() = withMap { _, host, _, map, _ ->
212 val before = AtomicReference<org.maplibre.android.camera.CameraPosition>()
213 val after = AtomicReference<org.maplibre.android.camera.CameraPosition>()
214 val settled = CountDownLatch(1)
215 val origin = main {
216 host.onRegionChangeComplete = { region ->
217 before.set(map.cameraPosition)
218 host.configure(props().put("region", region), overlays()) {}
219 host.postDelayed({ after.set(map.cameraPosition); settled.countDown() }, 500)
220 }
221 IntArray(2).also { host.getLocationOnScreen(it) } to (host.width to host.height)
222 }
223 val downAt = SystemClock.uptimeMillis()
224 for (step in 0..8) {
225 val action = if (step == 0) android.view.MotionEvent.ACTION_DOWN else if (step == 8) android.view.MotionEvent.ACTION_UP else android.view.MotionEvent.ACTION_MOVE
226 val touch = android.view.MotionEvent.obtain(downAt, SystemClock.uptimeMillis(), action,
227 origin.first[0] + origin.second.first * (0.3f + step * 0.025f),
228 origin.first[1] + origin.second.second * (0.3f + step * 0.01f), 0)
229 try { assertTrue(instrumentation.uiAutomation.injectInputEvent(touch, true)) } finally { touch.recycle() }
230 SystemClock.sleep(35)
231 }
232 assertTrue("The native drag did not publish a settled region", settled.await(15, TimeUnit.SECONDS))
233 main {
234 assertEquals("Echoing a native region must preserve zoom", before.get().zoom, after.get().zoom, 0.001)
235 assertEquals("Echoing a native region must preserve latitude", before.get().target!!.latitude, after.get().target!!.latitude, 0.000001)
236 assertEquals("Echoing a native region must preserve longitude", before.get().target!!.longitude, after.get().target!!.longitude, 0.000001)
237 }
238 evidence("map-controlled-region-after-drag")
239 }
240
210241 @Test
211242 fun showingTheLocationDotDoesNotRequestPermissionDuringRendering() = withMap { activity, host, _, map, _ ->
212243 assertEquals(PackageManager.PERMISSION_DENIED, activity.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION))