Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed issue #243 and improved Auto Join #256

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
16 changes: 14 additions & 2 deletions HeliPort/Appearance/StatusMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

// - MARK: Properties

private let heliPortUpdater = SUUpdater()

Check warning on line 24 in HeliPort/Appearance/StatusMenu.swift

View workflow job for this annotation

GitHub Actions / CI

'SUUpdater' is deprecated: Deprecated in Sparkle 2. Use SPUStandardUpdaterController instead, or SPUUpdater if you need more control.

private let networkListUpdatePeriod: Double = 5
private let statusUpdatePeriod: Double = 2
Expand All @@ -30,9 +30,12 @@
private var networkListUpdateTimer: Timer?
private var statusUpdateTimer: Timer?

private var isDisconnecting: Bool = false
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm guessing this flag is to prevent race conditions? Justification will be appreciated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This flag serves so that when the user manually disconnects from the network, the condition on line +49 will not attempt to disconnect again and will not call NetworkManager.scanSavedNetworks(), thus allowing the user to remain disconnected.


// One instance at a time
private lazy var preferenceWindow = PrefsWindow()

private var previousStatus: itl_80211_state = ITL80211_S_INIT
private var status: itl_80211_state = ITL80211_S_INIT {
didSet {
/* Only allow if network card is enabled or if the network card does not load
Expand All @@ -43,6 +46,11 @@

statusItem.title = NSLocalizedString(status.description)

if status != ITL80211_S_RUN && previousStatus == ITL80211_S_RUN && !isDisconnecting {
Copy link
Collaborator

Choose a reason for hiding this comment

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

The conditions here are not robust enough. For example, in OpenIntelWireless/itlwm#934 (comment) the router requests a reassociation. If we caught this event, we might mistakenly disconnect from the current network.

Many other factors might cause a change in state as well, such as firmware crash (goes directly back to S_INIT, no intervention from HeliPort required, itlwm will recover by itself), key expiring (-> S_AUTH), etc. The idea is to have our own state adapt and tolerate well with itlwm's internal state.

disassociateSSID(disconnectItem)
NetworkManager.scanSavedNetworks()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Currently we're only performing auto-join when HeliPort is initially launched. Users might want to temporarily disconnect while keeping WiFi enabled. Apple’s approach supports this (likely to maintain BSSID-based location services). Although there’s minimal justification for us to replicate this behavior aside from consistency with Apple (aligns with user habits and expectations) and allowing users to view the network list while disconnected. See #133.

}

switch status {
case ITL80211_S_INIT:
StatusBarIcon.disconnected()
Expand All @@ -68,6 +76,7 @@
default:
StatusBarIcon.error()
}
previousStatus = status
}
}

Expand Down Expand Up @@ -607,10 +616,13 @@
let ssid = String(sender.title).replacingOccurrences(of: String.disconnectNet, with: "",
options: .regularExpression,
range: nil)
isDisconnecting = true
DispatchQueue.global().async {
CredentialsManager.instance.setAutoJoin(ssid, false)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please correct me if I'm wrong, I did recall this is what Apple's implementation used to do back in the days - manually disconnecting a network will opt-out from auto-join, although this is not what the latest macOS versions are doing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are correct. Apple’s implementation used to work this way: manually disconnecting from a network would remove it from auto-join. However, more recent versions of macOS no longer follow this behavior; Apple made this change to improve user experience by reducing the need to manually reconfigure network preferences.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would you prefer to keep this behavior of automatically disabling autojoin when the user disconnects? I think this behavior is not very interesting and many users may not like this behavior. If you prefer to keep this behavior, I think it would be better to add an option in the preferences to activate and deactivate this behavior.

dis_associate_ssid(ssid)
Log.debug("Disconnected from \(ssid)")
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
self.isDisconnecting = false
Log.debug("Disconnected from \(ssid)")
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Justification required here as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These lines serve so that when the user disconnects, the isDisconnecting flag will be true for 2 seconds, thereby preventing the condition on line +49 from attempting to disconnect again and calling NetworkManager.scanSavedNetworks(). This allows the user to remain disconnected, as when isDisconnecting is true, the condition always returns false and does not execute what is inside it.

}
}

Expand Down
1 change: 0 additions & 1 deletion HeliPort/NetworkManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ final class NetworkManager {
if let savedNetworkAuth = CredentialsManager.instance.get(networkInfo) {
networkInfo.auth = savedNetworkAuth
Log.debug("Connecting to network \(networkInfo.ssid) with saved password")
CredentialsManager.instance.setAutoJoin(networkInfo.ssid, true)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I’m not certain if this is what Apple’s implementation used to do back in the days (feels unlikely and doesn't match with the current implementation). This is the root cause of #243.

getAuthInfoCallback(networkInfo.auth, false)
return
}
Expand Down
Loading