Extension Manager
Relevant source files
The following files were used as context for generating this wiki page:
- app/src/main/kotlin/dev/patrickgold/florisboard/lib/ext/ExtensionManager.kt
- app/src/main/kotlin/dev/patrickgold/florisboard/lib/ext/Extension.kt
- app/src/main/kotlin/dev/patrickgold/florisboard/lib/ext/ExtensionMeta.kt
- app/src/main/kotlin/dev/patrickgold/florisboard/app/ext/ExtensionEditScreen.kt
- app/src/main/kotlin/dev/patrickgold/florisboard/lib/devtools/Devtools.kt
The Extension Manager is a core component of the Ownkey Keyboard (FlorisBoard) project responsible for managing the lifecycle, indexing, and persistence of keyboard extensions. It handles various types of extensions, including keyboard layouts, themes, and language packs, packaged as .flex archive files.
This system provides the infrastructure to discover extensions stored in both the application's assets (read-only) and the device's internal storage (writable). It enables users to expand the keyboard's functionality by importing new layouts or custom themes.
Sources: ExtensionManager.kt:73-82, Extension.kt:37-43
Architecture and Indexing Logic
The Extension Manager utilizes a specialized inner class, ExtensionIndex, to maintain reactive lists of available extensions. Each index tracks a specific subdirectory within the internal storage and application assets.
Indexing Flow
The indexing process involves two primary stages: scanning static assets bundled with the APK and monitoring dynamic files in the app's internal data directory.
The system uses a FileObserver to detect filesystem changes (writes, deletes, moves) in real-time, ensuring the UI reflects newly imported or deleted extensions immediately.
Sources: ExtensionManager.kt:148-180
Core Components
| Class | Responsibility |
|---|---|
ExtensionManager | High-level API for import, export, and global extension state. |
ExtensionIndex | Specialized tracker for specific extension types (Themes, Keyboards, etc.). |
Extension | Abstract base class representing a loaded extension package. |
ExtensionMeta | Data model for the extension.json configuration file. |
| Sources: ExtensionManager.kt:82-95, Extension.kt:37-43, ExtensionMeta.kt:36-41 |
Extension Lifecycle
Extensions move through several states: indexed, loaded, and unloaded.
Loading Mechanism
When an extension is requested for use, it is "loaded" by extracting the contents of its .flex archive into a working directory in the application's cache.
Loading ensures that assets like images or JSON layouts are available as plain files for the keyboard engine. unload(context) is called to purge the cache and free resources.
Sources: Extension.kt:59-83
Import and Export Operations
The manager provides specialized methods to handle the movement of extension archives.
Importing
The import function persists an extension by:
- Creating a standardized
.flexfilename based on the extension ID. - Determining the correct group path (e.g.,
ime/theme). - Writing the updated
extension.jsonmanifest. - Zipping the working directory into the internal storage location.
Sources: ExtensionManager.kt:105-117
Exporting
Exporting involves loading the extension to ensure its files are present in the cache, then zipping that cache directory into a URI provided by the system's file picker.
Sources: ExtensionManager.kt:119-124
Data Models
Extension Metadata
Every extension must contain an extension.json file. The ExtensionMeta class defines the structure of this configuration.
| Field | Type | Description |
|---|---|---|
id | String | Unique identifier (Java package name format). |
version | String | Version string for update tracking. |
title | String | User-visible label. |
maintainers | List | List of contributors (format: Name <email> (url)). |
license | String | SPDX license identifier. |
| Sources: ExtensionMeta.kt:41-94 |
Extension Types
The manager currently supports three primary polymorphic types, handled via ExtensionJsonConfig serialization:
- KeyboardExtension: Defines layouts and input logic.
- ThemeExtension: Contains stylesheets and visual assets.
- LanguagePackExtension: Groups locale-relevant predictive models and emoji data.
Sources: ExtensionManager.kt:55-71, ROADMAP.md:15-18
Integration with Developer Tools
The Extension Manager is integrated into the system's diagnostic tools. The Devtools utility can generate reports listing all installed theme and language pack IDs currently registered with the manager.
Sources: Devtools.kt:98-106
Summary
The Extension Manager acts as the central hub for the keyboard's modular architecture. By abstracting the complexities of ZIP manipulation, filesystem monitoring, and polymorphic serialization, it allows the keyboard to be highly customizable while maintaining a consistent internal state. It bridges the gap between raw .flex archives and the runtime components that consume their data.
Sources: ExtensionManager.kt:73-82, ExtensionEditScreen.kt:233-255