ReviewOS

also looking at this

craft-native/craft

feat(android): getNetworkStatus — the action iOS cannot serve

#146
Merged glennmichael123 wants to merge feat/android-network-status into main
7 files +407 -3
9 days ago

Ratchet 96 → 95, and the most interesting one so far: iOS declares this action .status = .unavailable, and that refusal is correct.

The same action, opposite verdicts, for a real reason

bridge_mobile_device.zig refuses getNetworkStatus on iOS because no synchronous iOS API can answer isConnected without fabricating it:

  • NWPathMonitor delivers on a background queue where evaluateJavaScript: is illegal
  • SCNetworkReachability is deprecated since 17.4, can't see wired ethernet, and reports the host Mac's reachability on the simulator
  • getifaddrs knows which interfaces are up, not whether anything is reachable

The alternative there is {"isConnected":true,"type":"unknown"} — which a caller cannot tell from a real reading, making it strictly worse than an error.

Android has the API iOS lacks. getNetworkCapabilities is synchronous and answers null when nothing is connected, so isConnected is a fact here rather than a guess.

Worth stating plainly in the module, because the next person comparing the two platforms' tables will otherwise see one refusing what the other serves and assume someone gave up.

isConnected and type are not the same question

capabilities != null means something is connected. The transport is a separate lookup, and the Kotlin's when falls through to "none" on Bluetooth tethering, a VPN-only interface, and most emulators.

So {"isConnected":true,"type":"none"} is reachable and correct, not a contradiction to smooth over. Forcing type to "unknown" whenever connected, or isConnected false whenever the transport is unrecognised, would each be wrong in a way the page could not detect.

A comment that became a test

The module says the probes run in the Kotlin's order and stop at the first match, because when does. That was just a claim until a fake ConnectivityManager made it assertable:

a connection reporting both WIFI and ETHERNET — which a bridged emulator does — must answer "wifi"

Reordering the probes changes that answer without changing anything a reader would look at. Now it fails a test.

mutationresult
probes reordered (ethernet first)the two-transport test fails
null capabilities reported as connectedthe offline test fails

isWifi and isCellular are derived from the transport rather than read again — what the Kotlin does, and what stops the three disagreeing.

Verified

JNI gained CallBooleanMethodA. zig build test:android → 87 tests, 11/11 steps · both .so build · generator 10/10.

Correction to something I said earlier

I claimed the next Android candidates were structural walls. That was wrong — I'd looked at setKeepAwake and lockOrientation (which do need runOnUiThread, hence a Runnable) and generalised from two.

Measuring all 103: 32 need no evaluateJavascript, no runOnUiThread, no permission check and no listener. Eight are now migrated, so roughly two dozen remain reachable with the machinery already built — secureSet/Get/Remove/Clear, setBadge/clearBadge, vibrate, haptic, the notification cancels, and more. The walls are real but they are not next.

7 changed files on the files tab, with 0 review threads.

Sign in to comment on this pull request.