rfkill: Rework airplane mode
Previously, the airplane mode (APM) behavior did not align with users' expectations. #288
Now, APM temporarily blocks all enabled RF devices when activated. It is possible to enable blocked devices during APM. However, enabling any WWAN device will disable APM. To avoid confusion, as in Android, the WWAN toggle in GNOME-Shell should not be sensitive in APM. Additionally, newly added devices in APM are blocked. When APM is deactivated, all previously enabled devices are re-enabled.
This new behavior follows the description given by @bberg:
Ideally the following holds true:
- Enabling Airplane mode disables all active devices (and stores them)
- Disabling Airplane mode re-enables these devices (this can be no device if all devices were off to begin with)
- Enabling Wifi and Bluetooth while in Airplane mode is allowed
- Enabling a modem while in Airplane mode is impossible
- Airplane mode is never enabled implicitly (i.e. disabling all devices will not enable airplane mode, and you may have airplane mode on with >an empty list of devices that should be re-enabled)
- Devices that appear should get the expected state for the device type
Since additional AirplaneMode
s for hardware
, wwan
, and bluetooth
types are not intended, I renamed the DBus properties accordingly, but kept the old names with a deprecation note:
AirplaneMode
HardwareBlocked = HardwareAirplaneMode
HasAirplaneMode
ShouldShowAirplaneMode
BluetoothBlocked = BluetoothAirplaneMode
BluetoothHardwareBlocked = BluetoothHardwareAirplaneMode
BluetoothAvailable = BluetoothHasAirplaneMode
WwanBlocked = WwanAirplaneMode
WwanHardwareBlocked = WwanHardwareAirplaneMode
WwanAvailable = WwanHasAirplaneMode
Test
Moreover, I found that it is necessary to send rfkill
events individually since writing them in bulk did not work on a real /dev/rfkill
device.
Following the test example by the power plugin, I use UMockdev
to mock /dev/rfkill
and dbusmock
to mock the network manager (NM) and modem manager (MM).
Workaround
This MR supersedes the workaround in !241 and reintroduces its Bluetooth unblock resend logic in !322 (0c017835).
Potential Future Work
Furthermore, there are some peculiarities which I believe should be addressed by separate MRs:
-
Atomicity/Isolation: Setting properties
AirplaneMode
,BluetoothBlocked
andWwanBlocked
very quickly may cause device state updates to be lost, i.e., disabling APM does not correctly re-enable devices.- Currently, this is only partially mitigated by throttling the rate at which the
AirplaneMode
property can be set.
- Currently, this is only partially mitigated by throttling the rate at which the
-
Consistency: Activating APM with a hardware blocked device additionally soft-locks the device. However, when disabling APM the soft-lock is not removed.
- This is due to it appearing as not
UNBLOCKED
when APM is activated. Both(soft:0, hard:1)
and(soft:1, hard:1)
share the sameRFKILL_STATE_HARD_BLOCKED
state.
- This is due to it appearing as not
-
Durability: APM state is not persistent after reboot and devices remain disabled if
gsd-rfkill
dies in APM.- If APM should persist in settings, I reckon that, instead of device indices, the device names
/sys/class/rfkill/rfkill{idx}/name
should be considered.
- If APM should persist in settings, I reckon that, instead of device indices, the device names