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);
63 [[nodiscard]] bool isPluginDisabled(const std::string& id) const;
64 bool setPluginDisabled(const std::string& id,
65 bool disabled);
66
67 [[nodiscard]] StartResult startPlugin(const std::string& id);
68 bool stopActivePlugin();
73 bool unloadFromRam(const std::string& id);
78 void unloadAllFromRam();
82 bool reloadBackgroundPlugin(const std::string& id);
87 [[nodiscard]] bool hasActivePlugin() const noexcept;
88 [[nodiscard]] std::string activePluginId() const;
92 [[nodiscard]] uint8_t pluginBaseDepth() const noexcept { return plugin_base_depth_; }
94 [[nodiscard]] bool isLoaded(const std::string& id) const;
96 [[nodiscard]] bool isRunningInBackground(const std::string& id) const;
98 [[nodiscard]] bool hasBackgroundPlugin() const noexcept;
101 [[nodiscard]] bool activePluginIsBackground() const;
107 [[nodiscard]] bool activePluginPreventsSleep() const;
108
109 void dispatchButton(uint32_t button_code);
110 void dispatchAction(uint32_t action_id, uint32_t idx, uint32_t user_data);
113 void dispatchActionTo(Plugin* plugin, uint32_t action_id, uint32_t idx, uint32_t user_data);
114 void dispatchTick(uint64_t uptime_ms);
115
120 bool dispatchCmd(const std::string& id, const char* cmd, size_t len);
121
125 int consumeCmd(char* out, size_t out_size);
126
129 void dispatchEventAll(uint32_t event_type, uint32_t value);
130
132 void forEachPlugin(const std::function<bool(Plugin&)>& visitor);
133
140 char label[40];
141 uint32_t action_id;
142 };
143
145 uint8_t getLockscreenItems(LockscreenItem* out, uint8_t max) const;
146
148 void triggerLockscreenItem(const LockscreenItem& item);
149
155
156private:
157 PluginManager();
158 ~PluginManager();
159 PluginManager(const PluginManager&) = delete;
160 PluginManager& operator=(const PluginManager&) = delete;
161
162 void startTickTask();
163 void stopTickTask();
164 static void tickTaskTrampoline(void* arg);
165 void tickTaskLoop();
166
173 void teardownPlugin(Plugin& p, bool runWasmDeinit);
174
179 void handleTrap(Plugin& p, const char* fn);
180
184 bool loadIntoBackground(const std::string& id, const PluginManifest& mf);
185
189 void loadAutoloadPlugins();
190
192 void rebuildMessageIndex();
194 void maybeRefreshMessageIndex();
195
196 std::unique_ptr<Plugin> active_; // foreground (user-visible)
197 std::vector<std::unique_ptr<Plugin>> background_; // manually-started resident plugins
198 std::string pending_cmd_; // buffered for plugin_on_cmd pull
199 void* tick_task_ = nullptr; // FreeRTOS TaskHandle_t
200 void* call_mutex_ = nullptr; // FreeRTOS SemaphoreHandle_t
201 volatile bool tick_stop_ = false;
202 std::atomic<bool> pending_stop_{false};
203 bool initialised_ = false;
204 uint8_t plugin_base_depth_ = 0;
205
206 // MIME-type -> plugin-id index for auto-starting handler plugins on demand.
207 // Guarded by msg_index_mutex_ (read from the BLE host task). Parallel arrays.
208 void* msg_index_mutex_ = nullptr; // FreeRTOS SemaphoreHandle_t
209 std::vector<std::string> msg_index_mime_;
210 std::vector<std::string> msg_index_id_;
211 std::string installed_sig_;
212 uint32_t last_index_refresh_ms_ = 0;
213};
214
215} // 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)
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 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::optional< PluginManifest > getManifest(const std::string &id) const
void dispatchEventAll(uint32_t event_type, uint32_t value)
StartResult startPlugin(const std::string &id)