Skip to content

Instantly share code, notes, and snippets.

@berberman
Last active April 8, 2023 16:54
Show Gist options
  • Select an option

  • Save berberman/48549b84973b0d40c1fb611c4dbab1d5 to your computer and use it in GitHub Desktop.

Select an option

Save berberman/48549b84973b0d40c1fb611c4dbab1d5 to your computer and use it in GitHub Desktop.
Fcitx 5 Android Plugin

Fcitx 5 Android Plugin

Plugin

  • May contain the shared library of an existing addon or a new addon created in plugin's native code, or only provide data e.g. tables/lua extensions
  • Has a particular prefix in the package name: org.fcitx.fcitx5.android.plugin
  • Has a plugin descriptor in resouce, a XML file which includes:
    • plugin api version
    • gettext message domain (optional)
  • Has a data descriptor and FHS hierarchy in assets
  • Always has an activity, either used for plugin version checking, i.e. warn the user if the version from the main program is different, or external configuration UI[1]
  • May have foreground services

Main program

The main program (fcitx5-android) records a mapping of loaded plugins to their data descriptors (loadedPlugins). loadedPlugins should be persisted.

Loading plugins:

  1. Create a temp descriptor (temp) that records the new FHS hierarchy being built. Initialize it with main program's data descriptor.

  2. Using package manager, list all packages with the specific package name prefix.

  3. For each package,

    1. obtain the plugin descriptor (plugin.xml) from its resources.
    2. If failed to find or decode the plugin descriptor (descriptor.json), drop it.
    3. If the plugin api version is inconsistent with the one built in, generate a warning message and drop it.
    4. Go through assets and find out the data descriptor.
    5. For plugin's data descriptor, if its checksum matches the one in loadedPlugins, directly add the old one to temp and continue to the next plugin.
    6. If there is a path in plugin's data descriptor conflict with temp, generate a warning message and drop it.
    7. Copy files whose checksums mismatch with the old ones in loadedPlugins (if have) from assets to main program's data dir.
    8. Update temp.
  4. Delete files presented in the hierarchy built by loadedPlugins but not temp.

  5. Update loadedPlugins to temp.

  6. Process main program's data descriptor, which is already implemented.

  7. Join each plugin's nativeLibraryDir to FCITX_ADDON_DIRS.

  8. Startup fcitx.

[1]: Does everything have to be implemented in JVM land? How to do that if the configuration requires addon's runtime, instead of a static data? How to reflect the changes to main program's data? Should it always be serialized?

Refs

@berberman
Copy link
Author

A note by @rocka: for [1], DocumentsProvider can be used for those addons that need to read/write main program's data dir, but it's not clear how to deal with the case when some of the addon's code is required to be executed to modify the configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment