Follow-up to !363 (comment 949734) which we merged under the condition that we'd tweak the API (mostly meant as internal, but exposed anyway) before 6.2 Beta.
These recently introduced interface additions had some shortcomings:
- The distinction between "permanent" and "temporary" blocking ofinhibitors introduced excessive complexity in the interface.
- The new getter methods and change signals adopted the style of
ListInhibitors/InhibitorsChanged, which is both wrong (due tothe use of key/value arguments where a list is required) andincomplete (due to missing policy info and lack of ordering).On top of this, only one ofaddedorremovedwas ever providedin any given change signal. Neither of these were actually usedas value by the applet, instead it calledListInhibitorsagain. - The term "block" is used by both by the UI (i.e. "Block sleep")and by the login1 D-Bus interface ("block" mode for inhibitors,with the same meaning). Using "block inhibitors" in the D-Businterface with a different meaning is confusing.
This commit restructures the PolicyAgent D-Bus interface and adaptsthe relevant code both on the daemon and batterymonitor applet side.A lot of code is touched, but it boils down to a few essential changes:
- The distinction between permanent and temporary suppressions isdropped, all suppressions are now permanent. This simplifies APIas well as UX, so that the "Unblock" and "Block Again" buttons canbe simple click-buttons instead of button menus. In a later commit,we can use a Switch component instead of the unloved buttons.
- The terms "block inhibition" and "unblock inhibition" are replacedby "set inhibition allowed". Not allowed means the inhibition willbe suppressed.
ListInhibitionsandInhibitionsChangedare deprecated, therecently introduced getter methods and change signals are removed.- Instead, the D-Bus interface introduces properties named
ActiveInhibitionsandRequestedInhibitions(active + suppressed)complete with standard D-BusPropertiesChangedsignalsbeing emitted. - Both inhibition lists follow the same format, which includesthe standard login1 "what", "who", "why" and "mode", as well asa status flags parameter with "Active" and "Allowed" bits.
We keep the existing config entry name BlockedInhibitionsbecause it's far enough away from the API and UI strings to avoidgetting in the way.
Earlier description, for posterity
First shot, in case you want to follow along. This is fairly close in terms what I want for API structure, but I'll want a little more time to think about naming.
I realized that there really isn't any "key" as in key/value for a given inhibition, so for any type of InhibitionAdded or InhibitionRemoved kind of signal we'd need to pass all of its properties. But then one has to compare all properties of a removed inhibition, and if the only change is perhaps a change in permanent blocking or a newly added block type, state tracking will get complicated.
So instead I'm doing something entirely different: a property each for active and blocked inhibitions, paired with the standard PropertiesChanged signal that the D-Bus spec itself defines. This also preserves order and avoids weird naming ambiguities (e.g.: does BlockedInhibitionAdded get issued when BlockInhibition persists a block, or when an otherwise active inhibition appears and gets blocked?).
Furthermore, in order to allow a fix for BUG: 418433 later, this API refactoring also includes policies in each inhibition tuple. Plus the "permanently blocked" boolean, which I preliminarily renamed to "block later" so it can also be used in active inhibitions without confusion.
Both active and blocked inhibitions are therefore a list of tuples, each consisting of {what, who, why, block_later}. The three "w"s reflecting systemd naming, meaning the new API uses "sleep:idle" as what instead of a set of flags.
The reason why I'm still not 100% happy with this is that systemd also uses "block" in its terminology, and in fact exposes a BlockInhibited list of "what"s in addition to its less important sibling DelayInhibited. So a "block inhibitor" is an inhibitor lock that blocks, rather than delays something. But a "blocked inhibition" is a block inhibitor that gets blocked?
It would be really neat if we could avoid this overloading of terms, and perhaps instead expose something like BlockInhibitors next to SuppressedBlockInhibitors or such. Although at that point it also gets weird for the casual reader. Maybe instead each inhibitor should get the extra mode (block or delay) from systemd added to its properties, and we stick with ActiveInhibitors vs. perhaps SuppressedInhibitors.
Anyway. It builds and seems to work again like it currently does. API improvement as it stands. Have a look if you can, and I'll tweak this some more. The rest should be more straightforward.