Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tool/src/main/java/io/netbird/client/tool/Preferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public void disableTraceLog() {
}

public boolean isConnectionForceRelayed() {
return sharedPref.getBoolean(keyForceRelayConnection, true);
return sharedPref.getBoolean(keyForceRelayConnection, false);
}
Comment on lines 29 to 31
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Defaulting to false here is an upgrade behavior break for unset prefs.

Line 30 now flips existing “never-set” users from forced relay to P2P because callers in EnvVarPackager and AdvancedFragment consume this value directly. Please add an explicit migration/rollout decision (and align tests) so this change is intentional and observable rather than silent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tool/src/main/java/io/netbird/client/tool/Preferences.java` around lines 29 -
31, The change to isConnectionForceRelayed() silently flips unset users to P2P;
restore explicit migration by detecting when keyForceRelayConnection is not
present and applying an intentional rollout decision: update
isConnectionForceRelayed() (and add a migration helper called from Preferences
init) to use sharedPref.contains(keyForceRelayConnection) — if absent, set the
preference to the old default value (or to a controlled rollout value) and
persist it before returning; reference keyForceRelayConnection,
isConnectionForceRelayed(), and ensure callers EnvVarPackager and
AdvancedFragment keep observing the migrated/stored boolean so the behavior is
explicit and tests can assert the migration path.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ForceRelay default change is from a separate PR (#152) and not part of this fix. It appears in the diff because this branch includes that commit. The scope of this PR is only the ConcreteNetworkAvailabilityListener change.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MichaelUray, understood — thank you for the context. Since the isConnectionForceRelayed() default flip to false was deliberately introduced in #152 and is merely included here due to branching, my concern doesn't apply to this PR. I'll disregard this comment for the current review.


✏️ Learnings added
Learnt from: MichaelUray
Repo: netbirdio/android-client PR: 165
File: tool/src/main/java/io/netbird/client/tool/Preferences.java:29-31
Timestamp: 2026-04-16T18:57:38.014Z
Learning: In `tool/src/main/java/io/netbird/client/tool/Preferences.java` (netbirdio/android-client), `isConnectionForceRelayed()` intentionally returns `false` as the default (i.e., `sharedPref.getBoolean(keyForceRelayConnection, false)`). This default was changed from `true` to `false` in PR `#152` to re-enable P2P by default now that underlying ICE fixes are in place. Do not flag this default as a silent behavior break or missing migration — it is an intentional rollout decision made in that PR.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: pappz
Repo: netbirdio/android-client PR: 163
File: app/src/main/res/layout/fragment_troubleshoot.xml:76-80
Timestamp: 2026-04-14T17:59:56.801Z
Learning: In `app/src/main/res/layout/fragment_troubleshoot.xml` (netbirdio/android-client), the `switch_anonymize` SwitchMaterial (`@+id/switch_anonymize`) intentionally defaults to unchecked (disabled). This is the expected UX design: users must explicitly opt-in to anonymizing sensitive data before uploading a debug bundle. Do not flag the unchecked default as a security issue.


public void enableForcedRelayConnection() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,27 @@ public ConcreteNetworkAvailabilityListener() {

@Override
public void onNetworkAvailable(@Constants.NetworkType int networkType) {
boolean isWifiAvailable = Boolean.TRUE.equals(availableNetworkTypes.get(Constants.NetworkType.WIFI));
boolean hadNetwork = !availableNetworkTypes.isEmpty();
boolean hadSameType = Boolean.TRUE.equals(availableNetworkTypes.get(networkType));

availableNetworkTypes.put(networkType, true);

// if wifi is available and wasn't before, notifies listener.
// Android prioritizes wifi over mobile data network by default.
if (!isWifiAvailable && networkType == Constants.NetworkType.WIFI) {
// Notify on any network type change:
// - new WiFi connection (Mobile → WiFi switch)
// - new Mobile connection when WiFi was lost (WiFi → Mobile switch)
// - first network connection
if (!hadSameType) {
notifyListener();
}
}

@Override
public void onNetworkLost(@Constants.NetworkType int networkType) {
boolean isMobileAvailable = Boolean.TRUE.equals(availableNetworkTypes.get(Constants.NetworkType.MOBILE));
boolean wasPresent = availableNetworkTypes.remove(networkType) != null;

availableNetworkTypes.remove(networkType);

// if wifi is lost and mobile data is available, notifies listener.
// No use to notify it if there's no other type of network available.
if (isMobileAvailable && networkType == Constants.NetworkType.WIFI) {
// Notify when a tracked network is lost and another type is still available.
// Guards against duplicate/out-of-order onLost callbacks.
if (wasPresent && !availableNetworkTypes.isEmpty()) {
notifyListener();
}
}
Expand Down