drukscode-v2/docs/developer/export-pipeline.md
OpenCode AI e9899d2e6d
Some checks failed
Android CI Build / check (push) Has been cancelled
Android CI Build / package-apks (push) Has been cancelled
Docs Deploy / build (push) Has been cancelled
Module Market Check / Validate modules/ (push) Has been cancelled
Module Market Publish / Generate submissions.json (push) Has been cancelled
Docs Deploy / deploy (push) Has been cancelled
Initial DruksCode V2: fresh fork of web-to-app (f3b488e) with DruksCode identity
- Package rename com.webtoapp -> br.com.drukstech.codeapp
- Product rename WebToApp/web-to-app -> DruksCode/drukscode
- Design system Wta* -> Dkc*
- applicationId br.com.drukstech.codeapp (.play for gplay flavor)
- rootProject.name DruksCode
- Fresh git history (upstream kept as remote for sync)
2026-09-12 02:42:02 +02:00

67 lines
3.4 KiB
Markdown

# Export Pipeline
The export pipeline turns a `WebApp` model into a signed APK. It lives in `app/src/main/java/br/com/drukstech/codeapp/core/apkbuilder/` (~24 files).
## Key classes
| File | Role |
| --- | --- |
| `ApkBuilder.kt` | Orchestrates APK assembly + signing. Contains `WebApp.toApkConfig(...)`. |
| `ApkConfig.kt` | The master config schema: `data class ApkConfig(meta, activation, adBlock, webView, proxy, dns, nodejs, phpApp, pythonApp, goApp, multiWeb, ...)`. Everything an exported APK can encode. |
| `ApkConfigJsonFactory.kt` | Serializes `ApkConfig` to the assets JSON the shell reads; includes `ApkConfigValidator`. |
| `ApkTemplate.kt` / `ShellTemplateProvider.kt` | Locate and load the shell template APK. |
| `ApkBuildCache.kt` | Incremental rebuild; defines `enum class IncrementalBuildMode` (`ModifyApkMode` only covers `FULL`/`CONTENT_OVERLAY`). |
| `AxmlEditor` / `AxmlRebuilder` | Edit/rebuild the binary AndroidManifest (AXML). |
| `ArscEditor` / `ArscRebuilder` | Edit/rebuild the binary resource table (resources.arsc). |
| `JarSigner.kt` | Signs the APK with the `com.android.apksig` library directly (`ApkSigner`, V1/V2/V3 toggles). |
| `ZipAligner` / `ZipUtils` | Zip alignment and low-level zip manipulation. |
| `ElfAligner16k.kt` | 16KB-page ELF alignment for native `.so` files. |
| `RuntimeAssetEmbedder.kt` | Injects runtime assets (Node/PHP/Python/Go) into the APK. |
| `NetworkSecurityConfigBuilder.kt` | Generates the network security config XML. |
Related: `core/playstore/aab/` handles AAB/Play packaging; `core/crypto/` (`AssetEncryptor`, `EncryptedApkBuilder`, `KeyManager`) handles asset encryption.
## The flow
```text
WebApp (editor model)
→ WebApp.toApkConfig() [ApkBuilder.kt]
→ ApkConfig [typed schema, *Block sub-objects]
→ ApkConfigJsonFactory [serialize to app_config.json]
→ embed into template assets
→ patch AXML / ARSC (identity, permissions, icon)
→ embed runtime assets (if a server runtime)
→ sign (V1/V2/V3)
→ output APK
```
## `ApkConfig` structure
`ApkConfig` is composed of a `MetaBlock` plus dozens of feature blocks (`WebViewBlock`, `ProxyBlock`, `DnsBlock`, `NodejsBlock`, `PhpAppBlock`, `PythonAppBlock`, `GoAppBlock`, `MultiWebBlock`, `AdBlockBlock`, …). Convenience getters on `ApkConfig` flatten these (`appName`, `targetUrl`, `adBlockEnabled`, …).
The JSON field names produced by `ApkConfigJsonFactory` **must match** the `@SerializedName` annotations in the shell config class — see [Config Field Drift](/developer/config-drift).
## Incremental rebuild (`ApkBuildCache`)
Three modes (`enum class IncrementalBuildMode`):
| Mode | Meaning |
| --- | --- |
| `FULL` | Rebuild from template. Always used for encrypted builds. |
| `CONTENT_OVERLAY` | Only app content changed; overlay onto a prior build. |
| `REUSE_UNSIGNED` | Re-sign a previously built unsigned APK. |
Rules:
- Cache keys are **content-stable hashes** — never mtime-based.
- Template / entry identities must be content-stable.
- Encrypted builds always force a full rebuild.
- **Do not** feed signed or renamed APKs back into full `modifyApk` as templates.
## Native library embedding
- **Node.js** export must embed `libnode_bridge.so` + `libnode.so` (16KB-aligned via `ElfAligner16k`) + `libc++_shared.so`.
- **Go** export must embed `libgo_exec_loader.so`.
Missing any native lib causes `loadNode` / `loadJniBridge` failure at runtime.