From 720bafe8179e3fef780972cf7c1aa2e4bd32e1a8 Mon Sep 17 00:00:00 2001 From: Lilian <30466471+hlxid@users.noreply.github.com> Date: Mon, 29 Dec 2025 20:06:37 +0100 Subject: [PATCH 1/2] Resuse HashMaps in Wifi scanning/ranging code instead of creating them --- .../main/java/de/c3nav/droid/MainActivity.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/CongressRoutePlanner/app/src/main/java/de/c3nav/droid/MainActivity.java b/CongressRoutePlanner/app/src/main/java/de/c3nav/droid/MainActivity.java index 1e70e9c..eff0338 100644 --- a/CongressRoutePlanner/app/src/main/java/de/c3nav/droid/MainActivity.java +++ b/CongressRoutePlanner/app/src/main/java/de/c3nav/droid/MainActivity.java @@ -1257,12 +1257,11 @@ static class SuggestedWifiPeer { } public void processWifiScanResults(List results) { - Map resultMap = new HashMap<>(); + lastWifiScanResults.clear(); for (ScanResult scanRes : results) { - resultMap.put(scanRes.BSSID, scanRes); + lastWifiScanResults.put(scanRes.BSSID, scanRes); } - this.lastWifiScanResults = resultMap; - Log.d("c3nav", String.format("Nearby total ap count: %d", resultMap.size())); + Log.d("c3nav", String.format("Nearby total ap count: %d", lastWifiScanResults.size())); pushWifiResultsToApp(); } @@ -1369,7 +1368,7 @@ private void performWifiRangingScans(List rangingPeers, List(); + MainActivity.this.lastWifiRangingResults.clear(); isRanging = false; } @@ -1401,16 +1400,15 @@ public void onRangingResults(@NonNull List results) { private void processWifiRangingResults(List rangingResults) { isRanging = false; - Map resultMap = new HashMap<>(); + lastWifiRangingResults.clear(); for (RangingResult result : rangingResults) { MacAddress mac = result.getMacAddress(); if (mac != null && result.getStatus() == RangingResult.STATUS_SUCCESS) { - resultMap.put(mac.toString(), result); + lastWifiRangingResults.put(mac.toString(), result); } } - Log.d("rtt", String.format("finished wifi ranging. %d/%d ranged successfully", resultMap.size(), rangingResults.size())); - this.lastWifiRangingResults = resultMap; + Log.d("rtt", String.format("finished wifi ranging. %d/%d ranged successfully", lastWifiRangingResults.size(), rangingResults.size())); pushWifiResultsToApp(); } From ff4b381539fe3a609914263ec824dd88c3c60238 Mon Sep 17 00:00:00 2001 From: Lilian <30466471+hlxid@users.noreply.github.com> Date: Tue, 30 Dec 2025 00:09:57 +0100 Subject: [PATCH 2/2] Average wifi ranging results of last 10 seconds --- .../java/de/c3nav/droid/MainActivity.java | 78 +++++++++++++------ 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/CongressRoutePlanner/app/src/main/java/de/c3nav/droid/MainActivity.java b/CongressRoutePlanner/app/src/main/java/de/c3nav/droid/MainActivity.java index eff0338..3d5771c 100644 --- a/CongressRoutePlanner/app/src/main/java/de/c3nav/droid/MainActivity.java +++ b/CongressRoutePlanner/app/src/main/java/de/c3nav/droid/MainActivity.java @@ -29,6 +29,7 @@ import android.os.SystemClock; import android.preference.PreferenceManager; +import android.util.Pair; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; @@ -94,6 +95,7 @@ import java.nio.ByteBuffer; import java.util.*; import java.util.stream.Collectors; +import java.util.stream.Stream; import static android.net.wifi.ScanResult.*; import static android.net.wifi.rtt.ResponderConfig.RESPONDER_AP; @@ -129,7 +131,7 @@ public class MainActivity extends AppCompatActivity private WifiReceiver wifiReceiver; private List suggestedWifiPeers = new ArrayList<>(); private Map lastWifiScanResults = new HashMap<>(); - private Map lastWifiRangingResults = new HashMap<>(); + private Map>> lastWifiRangingResults = new HashMap<>(); private LinearLayout splashScreen; private VideoView logoAnimView; @@ -938,16 +940,19 @@ protected void startScan() { wifiManager.startScan(); // Range up to 10 times within interval, result in seconds - int rangeRate = Integer.parseInt(MainActivity.this.sharedPrefs.getString(getString(R.string.wifi_scan_rate_key), "30")) / 10; + int scanRate = Integer.parseInt(MainActivity.this.sharedPrefs.getString(getString(R.string.wifi_scan_rate_key), "30")); + int rangeRate = scanRate / 10; // Lower limit if scan rate is set low. Scanning more than once per 2s is not really feasible rangeRate = Math.max(rangeRate, 2); - new Timer().schedule(new TimerTask() { - @Override - public void run() { - MainActivity.this.startWifiRanging(); - } - }, 0, rangeRate * 1000L); + for (int delay = 0; delay < scanRate * 1000; delay += rangeRate * 1000) { + new Timer().schedule(new TimerTask() { + @Override + public void run() { + MainActivity.this.startWifiRanging(); + } + }, delay); + } } protected void setInEditor(boolean inEditor) { @@ -1313,6 +1318,7 @@ private void startWifiRanging() { if (rangingPeers.isEmpty()) { Log.d("rtt", "no aps found for wifi ranging"); + isRanging = false; return; } Log.d("rtt", String.format("starting rtt ranging with %d peers", rangingPeers.size())); @@ -1400,15 +1406,32 @@ public void onRangingResults(@NonNull List results) { private void processWifiRangingResults(List rangingResults) { isRanging = false; - lastWifiRangingResults.clear(); + // remove outdated data + final int rangingDateMaxAge = 10000; + for (Map.Entry>> entry : lastWifiRangingResults.entrySet()) { + List> withoutOutdated = entry.getValue().stream() + .filter(res -> System.currentTimeMillis() - res.first <= rangingDateMaxAge) + .collect(Collectors.toList()); + entry.setValue(withoutOutdated); + } + + // add new data + int successfulRanges = 0; for (RangingResult result : rangingResults) { MacAddress mac = result.getMacAddress(); if (mac != null && result.getStatus() == RangingResult.STATUS_SUCCESS) { - lastWifiRangingResults.put(mac.toString(), result); + List> existingResults = lastWifiRangingResults.get(mac.toString()); + + if (existingResults == null) + existingResults = new ArrayList<>(); + existingResults.add(new Pair<>(System.currentTimeMillis(), result)); + + lastWifiRangingResults.put(mac.toString(), existingResults); + successfulRanges++; } } - Log.d("rtt", String.format("finished wifi ranging. %d/%d ranged successfully", lastWifiRangingResults.size(), rangingResults.size())); + Log.d("rtt", String.format("finished wifi ranging. %d/%d ranged successfully", successfulRanges, rangingResults.size())); pushWifiResultsToApp(); } @@ -1489,24 +1512,35 @@ private JSONObject serializeWifiScanResult(ScanResult scan) throws JSONException return jo; } - private JSONObject serializeWifiRangingResult(RangingResult rttResult) throws JSONException { + private JSONObject serializeWifiRangingResult(List> rttResults) throws JSONException { JSONObject jo = new JSONObject(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) return jo; + if (rttResults.isEmpty()) + return jo; + + RangingResult latest = rttResults.get(rttResults.size() - 1).second; + + if (latest.getMacAddress() != null) + jo.put("bssid", latest.getMacAddress().toString()); + jo.put("frequency", latest.getMeasurementChannelFrequencyMHz()); - if (rttResult.getMacAddress() != null) - jo.put("bssid", rttResult.getMacAddress().toString()); - jo.put("frequency", rttResult.getMeasurementChannelFrequencyMHz()); + double distanceMm = rttResults.stream().mapToInt(res -> res.second.getDistanceMm()).average().orElse(0); + double distanceStdDevMm = rttResults.stream().mapToInt(res -> res.second.getDistanceStdDevMm()).average().orElse(0); + int attemptedMeasurements = rttResults.stream().mapToInt(res -> res.second.getNumAttemptedMeasurements()).sum(); + int successfulMeasurements = rttResults.stream().mapToInt(res -> res.second.getNumSuccessfulMeasurements()).sum(); + // timestamps are for outdated so we use the newest ones since we know the ap + // was heard in the last ranging averaging interval JSONObject rtt = new JSONObject(); - rtt.put("distance_mm", rttResult.getDistanceMm()); - rtt.put("distance_std_dev_mm", rttResult.getDistanceStdDevMm()); - rtt.put("num_attempted_measurements", rttResult.getNumAttemptedMeasurements()); - rtt.put("num_successful_measurements", rttResult.getNumSuccessfulMeasurements()); - rtt.put("ranging_timestamp_millis", rttResult.getRangingTimestampMillis()); - rtt.put("measurement_bandwidth", rttResult.getMeasurementBandwidth()); + rtt.put("distance_mm", distanceMm); + rtt.put("distance_std_dev_mm", distanceStdDevMm); + rtt.put("num_attempted_measurements", attemptedMeasurements); + rtt.put("num_successful_measurements", successfulMeasurements); + rtt.put("ranging_timestamp_millis", latest.getRangingTimestampMillis()); + rtt.put("measurement_bandwidth", latest.getMeasurementBandwidth()); jo.put("rtt", rtt); - jo.put("last", SystemClock.elapsedRealtime() - rttResult.getRangingTimestampMillis()); + jo.put("last", SystemClock.elapsedRealtime() - latest.getRangingTimestampMillis()); return jo; }