Skip to content

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 AirplaneModes 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 and WwanBlocked 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.
  • 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 same RFKILL_STATE_HARD_BLOCKED state.
  • 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.
Edited by Jan Zickermann

Merge request reports