Files
WHCandCursor 5538ed3412
ci / tcc-check (push) Successful in 1m8s
ci / linux (aarch64, 0) (push) Failing after 1h0m3s
ci / linux (x86, 1) (push) Failing after 1h0m3s
ci / linux (x86_64, 1) (push) Failing after 1h0m2s
ci / windows (push) Failing after 50s
refactor: archive GUI clients; keep minimal TUI with hooks/API
Move Qt/Tauri/full Web SPA under archive/, ship hermit as CLI/TUI plus
libcstcore and cst-webui/1 HTTP+SSE (turn lifecycle hooks, capabilities).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-30 22:49:23 +08:00

114 lines
5.8 KiB
XML

<?xml version="1.0"?>
<!-- The APK's manifest (QT_ANDROID_PACKAGE_SOURCE_DIR in app/CMakeLists.txt):
androiddeployqt copies this file and res/ into its gradle project and
fills in the INSERT_* placeholders below (version code and name, library
name, app arguments). An XML comment may not contain a double hyphen, so
the placeholder syntax is only spelled out in the attributes themselves.
The SDK levels are not here on purpose: they come from
QT_ANDROID_MIN_SDK_VERSION and QT_ANDROID_TARGET_SDK_VERSION in
app/CMakeLists.txt, and androiddeployqt writes them into the generated
gradle.properties. The app name and icon come from res/ next to this
file (values/strings.xml, drawable/ic_launcher.xml).
WHAT THIS APP IS: the engine runs in this process (no server, no port) and
writes everything (workspace, session store, settings, credentials) under
the app's own data directory, which main.cpp points the engine at (see
androidRoot() there).
Permissions: INTERNET for the providers the user configures,
POST_NOTIFICATIONS for the app's notification_send tool (Android 13+
asks at runtime; the tool stays hidden until it is granted), the
foreground-service permissions with WAKE_LOCK for the service that keeps
a turn going while the phone is in a pocket (CstService.java), and
MANAGE_EXTERNAL_STORAGE ("all files access", Android 11+) so the engine
can read a path in shared storage that a task names rather than picks:
Android only offers the Settings screen for it, so main.cpp opens that
once and everything still works without it: what the system picker (SAF)
hands over is copied into the app's own directory (AttachFile.java). No
cleartext traffic: every provider URL is https. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="xyz.whcself.cstagent"
android:installLocation="auto"
android:versionCode="-- %%INSERT_VERSION_CODE%% --"
android:versionName="-- %%INSERT_VERSION_NAME%% --">
<!-- %%INSERT_PERMISSIONS -->
<!-- %%INSERT_FEATURES -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- "All files access": without it the engine can only read the app's own
directory, so a task that names a file in shared storage cannot be
answered. Android 11+ has no runtime dialog for it, only the Settings
screen (AttachFile.java opens it once). Files the user picks work
either way: their content:// grant is copied into the app first. -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true" />
<application
android:name="org.qtproject.qt.android.bindings.QtApplication"
android:label="@string/app_name"
android:icon="@drawable/ic_launcher"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:enableOnBackInvokedCallback="false">
<activity
android:name="org.qtproject.qt.android.bindings.QtActivity"
android:label="@string/app_name"
android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|keyboard|keyboardHidden|navigation|density|mcc|mnc"
android:launchMode="singleTop"
android:screenOrientation="unspecified"
android:exported="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="-- %%INSERT_APP_LIB_NAME%% --" />
<meta-data
android:name="android.app.arguments"
android:value="-- %%INSERT_APP_ARGUMENTS%% --" />
</activity>
<!-- The share tool hands a file out of the workspace, and a file
crossing an app boundary has to travel as a content:// uri. This
is Qt's own provider (androidx.core.content.FileProvider, paths
from res/xml/qtprovider_paths.xml): its files-path is the app's
files directory, which is where the workspace lives. -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.qtprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/qtprovider_paths" />
</provider>
<!-- A turn can outlive the screen: while one is running the front end
starts this service (AgentCore::send -> app::holdForeground), which
makes the process a foreground one, so Android neither freezes nor
kills it in the background, and takes a partial wake lock so the
CPU keeps going with the phone in a pocket. dataSync is the type
that fits "the app is finishing some work". -->
<service
android:name="xyz.whcself.cstagent.CstService"
android:exported="false"
android:foregroundServiceType="dataSync" />
</application>
</manifest>