/* How the front end hands a tool to the engine. * * A tool implemented in C++ is an ordinary cst_tool_def_t: the engine owns a * copy of the definition, so a static (or stack) value is enough, and * `ud`/`run_ex` keep pointing at the front end's state. The callback runs on * the turn's worker thread -- touch Qt objects only through queued signals. * * See app/src/platform/linux/NotifyTool.cpp for a worked example, and * tests/test_embed.c for the same contract without Qt. */ #ifndef CST_APP_TOOLPROVIDER_H #define CST_APP_TOOLPROVIDER_H #include #include "cst_tools.h" /* The engine wrapper of the front end (core/AgentCore.h). Only a pointer * travels through this header, so the class stays incomplete here. */ class AgentCore; /* Same for the document md_to_pdf lays out (PdfTools.cpp): the caller owns * it, and the test in ui/UiTest.cpp inspects how it draws. */ class QTextDocument; namespace app { /* Fill a definition in one place, so every front-end tool carries the same * metadata (class + policy name + platform list + probe). */ inline void setMeta(cst_tool_def_t *def, const char *name, const char *desc, cst_tool_perm_t perm, const char *perm_name, const char *const *platforms, int (*available)(char *, size_t)) { def->name = name; def->desc = desc; def->perm = perm; def->perm_name = perm_name; def->platforms = platforms; def->available = available; } /* Tools that only work on the phone. */ extern const char *const kAndroidOnly[]; /* Tools that only work on a desktop (linux / win / macos). */ extern const char *const kDesktopOnly[]; /* The platform tools this app provides. Called once the engine exists; * returns how many were registered. */ int registerPlatformTools(AgentCore *core); /* The tools this front end provides that are the same on every platform * (they are Qt, not a platform API): today md_to_pdf, owned by "app:qt". * Called next to registerPlatformTools(). */ int registerQtTools(AgentCore *core); /* The document md_to_pdf lays out from `html`: the page's own defaults * applied (text with no colour of its own is black, not the window's palette * colour). The caller owns the result. */ QTextDocument *paperDocument(const QString &html); /* Drop them again (they belong to the owners "app:*"). */ void unregisterPlatformTools(AgentCore *core); /* One entry point per platform, implemented by the file under * src/platform//; ToolProvider.cpp picks one at compile time. */ int platformRegisterLinux(AgentCore *core); int platformRegisterMac(AgentCore *core); int platformRegisterWindows(AgentCore *core); int platformRegisterAndroid(AgentCore *core); /* Hand a file of the session's store to the system: a phone opens it with * ACTION_VIEW through the app's FileProvider, a desktop gives it to whatever * the desktop uses. `title` is the name a person knows the file by (the * stored copy is named by its id, which means nothing outside), used for the * status line. Both return "" on success and a reason to show the user * otherwise; *status (optional) gets the line to put in the header. * CST_APP_NO_OPEN=1 makes both do nothing (--uitest drives the window without * opening anything for real). */ QString openLocalFile(const QString &path, const QString &title, QString *status); /* The same file through the share sheet where there is one (Android); a * desktop has no share sheet, so the path goes to the clipboard. */ QString shareLocalFile(const QString &path, const QString &title, QString *status); /* Hold the machine while a turn runs, so it survives the app leaving the * screen: a phone starts a foreground service with a partial wake lock (the * process is one Android will not freeze or kill, and the CPU keeps going * with the screen off) and shows a notification naming the work; a desktop * does nothing -- the window *is* the app there. Returns "" when the hold is * in place (or when the platform has nothing to do), a reason otherwise; the * turn runs either way. `text` is what the phone's notification says. */ QString holdForeground(const QString &text); /* Drop it again, at the end of the turn (a phone: the notification goes). */ void releaseForeground(); /* Turn what a file chooser handed over into a path the engine can open. A * desktop picker gives a path and nothing happens; a phone's is a SAF * content:// URI, which the app copies into its own directory first (the * grant travels with the URI, so no permission is involved -- and without * the copy the engine, which opens files by path, would fail with "cannot * read"). Returns the path to read, or "" with *err filled. */ QString materializeAttachment(const QString &pathOrUri, QString *err); /* Does this app have "all files access" (Android 11+)? A desktop always * does. Without it the app still attaches whatever the picker handed it; what * it cannot do is read shared storage by path. */ bool hasAllFilesAccess(); /* Ask for it, through the one screen Android offers (there is no runtime * dialog for it). A desktop, a phone that already has it or one too old to * know about it returns "" and nothing opens. */ QString requestAllFilesAccess(); /* Take the whole screen. A phone's status bar -- and a tablet's taskbar, which * is a status bar with icons in it -- is drawn *over* the window, and the * window here draws from its own first pixel, so the bars sit on the app's top * row and the controls there cannot be touched. Hiding them is what "full * screen" means on a phone; a desktop has no such bars to ask about and * returns "". Asking is repeatable and cheap: the bars come back with a swipe * from the edge or a switch to another app, so the front end asks again every * time the window comes to the front. Returns "" once they are gone, a reason * otherwise (which the front end logs). */ QString requestFullscreen(); /* The arguments the Android activity was started with (the * "applicationArguments" intent extra): the way * `cst-agent-app --uitest --workspace DIR` is reachable on a device, since * Qt's own plumbing for that extra does not reach this build. Empty * everywhere else, and empty on a device that was not started with any. */ QStringList activityArguments(); } // namespace app #endif /* CST_APP_TOOLPROVIDER_H */