Revised approach to addon compatibility #9055
This issue aims to discuss a revised approach to addon compatibility.
Issues with the existing Addon versioning checks
Consider the following situations:
The following use cases can be derived:
Addon API background
An addon specifies its window of compatibility with two manifest values, and will be considered compatible if the following are all True:
A more in depth look at these properties:
NVDA specifies a window for the API versions in (a new file)
When the two windows of compatibility overlap, then the add-on is considered compatible and can be enabled. For the ease of discussion, we will assume API version values are consecutive integers, however the exact scheme used for API version values will be discussed later. Consider an installation of NVDA 2020.2, with current API version of 6 and backwards compatible to API version 3:
First version with addon version checks
Release 2019.1 with add-on version check ASAP
Addon API Version Value Scheme
So far, we have used strings formatted as NVDA version strings for addon API version values. This caused difficulty when pulling the NVDA version string from the file information in the launcher executable because of the presence of other information. We have decided to ignore the minor part when considering whether an addon has been tested.
With regards to decoupling:
Alternatives to NVDA version string:
My preference is to use the tuple representation.
Changes to the UX
When there is an incompatibility, we would no longer state merely that the addon is untested and allow the user to override the incompatibility state. Instead, we will warn that it is incompatible, and the addon will be disabled after installation. The user should always be able to abort the installation.
One improvement could be to specifically detect and highlight incompatible addons that are providing the active synth / braille display. Since these are considered critical to the user.
Addon publishing platforms
Those responsible for addon publishing platforms and reviewing the addons contained there-in should note the importance of the accuracy of the last tested addon manifest value. If it is set to as-yet undeveloped future API versions, it will likely result in instability and reflect badly on the add-on publishing platform and those who reviewed the addon.
The text was updated successfully, but these errors were encountered:
Thanks for this extensive write-down!
This is very unlikely to happen.
Note that we would still have to parse a string within updateCheck.checkForUpdate. Alternatively, the update server should return json data for versions of NVDA that support it.
I believe that configobj can parse them quite will. a definition would look like:
That basically means the following:
Apart from that, I think that the gui wording and experience is pretty ok as it is now. Thus, I propose keeping the "I understand that these add-ons will be disabled" checkboxes, etc.
This makes sense, and is pretty straight forward when the add-on is running:
In my case, this only applies to the speech synthesizer.
Yes, but I'm not so worried about this, since we can be strict about the formatting of this. Unlike the version string coming from the executable's file info.
I'm happy for the definitions to remain as strings in the addon manifest, and parse them with regex as we currently do. I suggest that we strictly validate that there are 3 numbers provided.
Closes #9055 * The incompatible addons dialog is no longer shown on startup. Since there is no saved state, this would warn about any installed incompatible addons every time NVDA was started. * Replace compatibility checks - NVDA now uses two (internal) values to determine addon compatibility, in addition to the `lastTestedNVDAVersion` and `minimumNVDAVersion` from the addonManifest. These new values are `CURRENT` and `BACK_COMPAT_TO`, in the addonAPIVersion module. - An addon is considered compatible if there is an overlap of the two ranges formed by the addon manifest values and the internal NVDA values. - Renamed `_showAddonUntestedDialog` - Clarified the name of the function to report that an addon is no longer supported by NVDA. The addon is considered "too old". As opposed to NVDA being "too old" for a newly developed addon. * Introduce a new method of stopping incompatible addons from "running". - No longer "disable" them to stop them from running. - When being set to disabled, the state was being saved. This meant the launcher could interfere with an installed version of NVDA, even if the installation was aborted. - We rely on `_getAvailableAddonsFromPath` to be setting the blocked state. - Improve comment in `addToPackagePath`, which is currently the end point for "enabling" an addon. * Addon API version values are now used as tuples throughout code. - Read from addon manifest and validate and convert to tuple. - Validate manifest condition: `minRequiredVersion <= lastTested` - It's not sensible to have a minRequiredVersion later than the version tested against. * Update info for NVDA now keeps `APIVersion` and `backCompatibleToVersion` as tuples rather than strings. - When an update is postponed it is saved as a tuple. - This saves confusion about whether its a string or a tuple. * Fix freeze on exit when destroy not called manually for `AutoWidthColumnCheckListCtrl` - Removes need to manually call destroy on `IncompatibleAddonsDialog` - `accPropServices` needs to be cleaned up when the control is destroyed. The `Destroy` method is not called by the wx framework, but we can register to receive the event see wxWidgets/Phoenix#630 * Allow the possibility of using a parent window other than the addon manager when installing an addon. Useful in the case of installing via a shell extension, where gui.mainframe should be the parent. - Removed coupling between the `installAddon` function and `AddonManager` class - Reduced nesting of the `installAddon` function - Moved methods to module level. These had no dependence on instance, or class level members. * Use windows sounds for addon install warning / error dialogs. * Use context manager for writing to file in `_download` of class `UpdateDownloader` in `updateCheck.py` - There were several ways that the file could fail to be closed. * Unified the way that NVDA versions / API versions are formatted to a string, added tests - One function is for outputting a full version string (including build part). - The other is for formatting a version string for the GUI (which will remove the minor part when it is zero). * Moved the regex used to convert addon manifest API versions from strings to tuples into the `addonAPIVersion` module. * No longer raise error for failed audio ducking when it failed due to "access denied" - Ensure that a warning is put in the log for access denied errors when setting audio ducking.