CDC Badge OS
Firmware for the CDC Badge v1.0 hardware security key
Loading...
Searching...
No Matches
PluginManager.h
Go to the documentation of this file.
1
13
14#pragma once
15
19
20#include <atomic>
21#include <cstdint>
22#include <functional>
23#include <memory>
24#include <optional>
25#include <string>
26#include <vector>
27
28namespace cdc::plugin_manager {
29
44
45class PluginManager {
46public:
47 [[nodiscard]] static PluginManager& instance() noexcept;
48
49 [[nodiscard]] bool init();
50 void deinit();
51
52 [[nodiscard]] std::vector<std::string> listInstalledIds() const;
53 [[nodiscard]] std::optional<PluginManifest> getManifest(const std::string& id) const;
54
58 [[nodiscard]] bool messageTypeInstalled(const char* mime) const;
62 bool activateForMessageType(const char* mime);
65 [[nodiscard]] bool featureInstalled(const char* feature) const;
67 [[nodiscard]] std::string featureProviderId(const char* feature) const;
68 [[nodiscard]] bool isPluginDisabled(const std::string& id) const;
69 bool setPluginDisabled(const std::string& id,
70 bool disabled);
71
72 [[nodiscard]] StartResult startPlugin(const std::string& id);
73 bool stopActivePlugin();
78 bool unloadFromRam(const std::string& id);
81 bool uninstallPlugin(const std::string& id);
86 void unloadAllFromRam();
90 bool reloadBackgroundPlugin(const std::string& id);
95 [[nodiscard]] bool hasActivePlugin() const noexcept;
96 [[nodiscard]] std::string activePluginId() const;
100 [[nodiscard]] uint8_t pluginBaseDepth() const noexcept { return plugin_base_depth_; }
102 [[nodiscard]] bool isLoaded(const std::string& id) const;
104 [[nodiscard]] bool isRunningInBackground(const std::string& id) const;
106 [[nodiscard]] bool hasBackgroundPlugin() const noexcept;
109 [[nodiscard]] bool activePluginIsBackground() const;
115 [[nodiscard]] bool activePluginPreventsSleep() const;
116
117 void dispatchButton(uint32_t button_code);
118 void dispatchAction(uint32_t action_id, uint32_t idx, uint32_t user_data);
121 void dispatchActionTo(Plugin* plugin, uint32_t action_id, uint32_t idx, uint32_t user_data);
122 void dispatchTick(uint64_t uptime_ms);
123
128 bool dispatchCmd(const std::string& id, const char* cmd, size_t len);
129
133 int consumeCmd(char* out, size_t out_size);
134
137 void dispatchEventAll(uint32_t event_type, uint32_t value);
138
140 void forEachPlugin(const std::function<bool(Plugin&)>& visitor);
141
148 char label[40];
149 uint32_t action_id;
150 };
151
153 uint8_t getLockscreenItems(LockscreenItem* out, uint8_t max) const;
154
156 void triggerLockscreenItem(const LockscreenItem& item);
157
163
164private:
165 PluginManager();
166 ~PluginManager();
167 PluginManager(const PluginManager&) = delete;
168 PluginManager& operator=(const PluginManager&) = delete;
169
170 void startTickTask();
171 void stopTickTask();
172 static void tickTaskTrampoline(void* arg);
173 void tickTaskLoop();
174
181 void teardownPlugin(Plugin& p, bool runWasmDeinit);
182
187 void handleTrap(Plugin& p, const char* fn);
188
192 bool loadIntoBackground(const std::string& id, const PluginManifest& mf);
193
197 void loadAutoloadPlugins();
198
200 void rebuildMessageIndex();
202 void maybeRefreshMessageIndex();
203
204 std::unique_ptr<Plugin> active_; // foreground (user-visible)
205 std::vector<std::unique_ptr<Plugin>> background_; // manually-started resident plugins
206 std::string pending_cmd_; // buffered for plugin_on_cmd pull
207 void* tick_task_ = nullptr; // FreeRTOS TaskHandle_t
208 void* call_mutex_ = nullptr; // FreeRTOS SemaphoreHandle_t
209 volatile bool tick_stop_ = false;
210 std::atomic<bool> pending_stop_{false};
211 bool initialised_ = false;
212 uint8_t plugin_base_depth_ = 0;
213
214 // MIME-type -> plugin-id index for auto-starting handler plugins on demand.
215 // Guarded by msg_index_mutex_ (read from the BLE host task). Parallel arrays.
216 void* msg_index_mutex_ = nullptr; // FreeRTOS SemaphoreHandle_t
217 std::vector<std::string> msg_index_mime_;
218 std::vector<std::string> msg_index_id_;
219 // External-feature -> plugin-id index, rebuilt together with the MIME index
220 // and guarded by the same mutex. Parallel arrays.
221 std::vector<std::string> feat_index_name_;
222 std::vector<std::string> feat_index_id_;
223 std::string installed_sig_;
224 uint32_t last_index_refresh_ms_ = 0;
225};
226
227} // namespace cdc::plugin_manager
In-memory representation of a plugin's meta.json.
Mounts the FAT-FS partition that holds plugin .wasm + .meta files.
Owned WAMR module instance + per-plugin state.
bool dispatchCmd(const std::string &id, const char *cmd, size_t len)
bool activateForMessageType(const char *mime)
Load + start (headless) the installed plugin that declares this MIME type, so its message handler bec...
uint8_t getLockscreenItems(LockscreenItem *out, uint8_t max) const
Snapshot of all plugin lockscreen items. Returns the number written.
void dispatchAction(uint32_t action_id, uint32_t idx, uint32_t user_data)
int consumeCmd(char *out, size_t out_size)
bool hasBackgroundPlugin() const noexcept
True if at least one plugin is currently resident in the background slot.
bool isLoaded(const std::string &id) const
True if a plugin with id is loaded in RAM (foreground or background).
void dispatchButton(uint32_t button_code)
bool hasActivePlugin() const noexcept
bool isRunningInBackground(const std::string &id) const
True if a plugin with id is currently resident in the background slot.
void forEachPlugin(const std::function< bool(Plugin &)> &visitor)
Iterate foreground + background plugins. Visitor returns false to stop.
std::vector< std::string > listInstalledIds() const
static PluginManager & instance() noexcept
uint8_t pluginBaseDepth() const noexcept
bool unloadFromRam(const std::string &id)
void dispatchActionTo(Plugin *plugin, uint32_t action_id, uint32_t idx, uint32_t user_data)
bool setPluginDisabled(const std::string &id, bool disabled)
void dispatchTick(uint64_t uptime_ms)
bool uninstallPlugin(const std::string &id)
void triggerLockscreenItem(const LockscreenItem &item)
Fire plugin_on_action(item.action_id, 0, 0) on the owning plugin.
bool reloadBackgroundPlugin(const std::string &id)
bool featureInstalled(const char *feature) const
True if any installed plugin's manifest provides this external feature. Reads the cached index (same ...
bool messageTypeInstalled(const char *mime) const
True if any installed plugin's manifest declares this MIME type for message transfer....
bool isPluginDisabled(const std::string &id) const
std::string featureProviderId(const char *feature) const
Installed plugin id providing this external feature, or empty.
std::optional< PluginManifest > getManifest(const std::string &id) const
void dispatchEventAll(uint32_t event_type, uint32_t value)
StartResult startPlugin(const std::string &id)