diff --git a/.gitignore b/.gitignore index 2bf4837ac..5e6cae7b5 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ pnpm-lock.yaml .zed .idea ace-builds +fdroid.bool diff --git a/hooks/post-process.js b/hooks/post-process.js index 4e6e872cf..8f57ea98a 100644 --- a/hooks/post-process.js +++ b/hooks/post-process.js @@ -30,6 +30,37 @@ deleteDirRecursively(resPath, [ ]); copyDirRecursively(localResPath, resPath); enableLegacyJni() +enableStaticContext() +patchTargetSdkVersion() + + +function patchTargetSdkVersion() { + const prefix = execSync('npm prefix').toString().trim(); + const gradleFile = path.join(prefix, 'platforms/android/app/build.gradle'); + + if (!fs.existsSync(gradleFile)) { + console.warn('[Cordova Hook] ⚠️ build.gradle not found'); + return; + } + + let content = fs.readFileSync(gradleFile, 'utf-8'); + + const sdkRegex = /targetSdkVersion\s+(cordovaConfig\.SDK_VERSION|\d+)/; + + if (sdkRegex.test(content)) { + const fdroid = fs.readFileSync(path.join(prefix,'fdroid.bool'), 'utf-8').trim(); + var api = "34" + if(fdroid == "true"){ + api = "28" + } + + content = content.replace(sdkRegex, 'targetSdkVersion '+api); + fs.writeFileSync(gradleFile, content, 'utf-8'); + console.log('[Cordova Hook] ✅ Patched targetSdkVersion to '+api); + } else { + console.warn('[Cordova Hook] ⚠️ targetSdkVersion not found'); + } +} function enableLegacyJni() { @@ -59,6 +90,63 @@ function enableLegacyJni() { console.log('[Cordova Hook] ✅ Enabled legacy JNI packaging'); } +function enableStaticContext() { + try { + const prefix = execSync('npm prefix').toString().trim(); + const mainActivityPath = path.join( + prefix, + 'platforms/android/app/src/main/java/com/foxdebug/acode/MainActivity.java' + ); + + if (!fs.existsSync(mainActivityPath)) { + return; + } + + let content = fs.readFileSync(mainActivityPath, 'utf-8'); + + // Skip if fully patched + if ( + content.includes('WeakReference') && + content.includes('public static Context getContext()') && + content.includes('weakContext = new WeakReference<>(this);') + ) { + return; + } + + // Add missing imports + if (!content.includes('import java.lang.ref.WeakReference;')) { + content = content.replace( + /import org\.apache\.cordova\.\*;/, + match => + match + + '\nimport android.content.Context;\nimport java.lang.ref.WeakReference;' + ); + } + + // Inject static field and method into class body + content = content.replace( + /public class MainActivity extends CordovaActivity\s*\{/, + match => + match + + `\n\n private static WeakReference weakContext;\n\n` + + ` public static Context getContext() {\n` + + ` return weakContext != null ? weakContext.get() : null;\n` + + ` }\n` + ); + + // Insert weakContext assignment inside onCreate + content = content.replace( + /super\.onCreate\(savedInstanceState\);/, + `super.onCreate(savedInstanceState);\n weakContext = new WeakReference<>(this);` + ); + + fs.writeFileSync(mainActivityPath, content, 'utf-8'); + } catch (err) { + console.error('[Cordova Hook] ❌ Failed to patch MainActivity:', err.message); + } +} + + /** * Copy directory recursively * @param {string} src Source directory diff --git a/package-lock.json b/package-lock.json index 27557e028..a9a8dc556 100644 --- a/package-lock.json +++ b/package-lock.json @@ -46,7 +46,6 @@ "@types/url-parse": "^1.4.11", "autoprefixer": "^10.4.19", "babel-loader": "^9.1.3", - "com.foxdebug.acode.rk.exec.proot": "file:src/plugins/proot", "com.foxdebug.acode.rk.exec.terminal": "file:src/plugins/terminal", "cordova-android": "13.0.0", "cordova-clipboard": "^1.3.0", @@ -4003,10 +4002,6 @@ "dev": true, "license": "MIT" }, - "node_modules/com.foxdebug.acode.rk.exec.proot": { - "resolved": "src/plugins/proot", - "link": true - }, "node_modules/com.foxdebug.acode.rk.exec.terminal": { "resolved": "src/plugins/terminal", "link": true @@ -10804,7 +10799,7 @@ "src/plugins/proot": { "name": "com.foxdebug.acode.rk.exec.proot", "version": "1.0.0", - "dev": true, + "extraneous": true, "license": "MIT" }, "src/plugins/sdcard": { diff --git a/package.json b/package.json index 680aa1626..01b0c9261 100644 --- a/package.json +++ b/package.json @@ -37,8 +37,7 @@ "cordova-plugin-websocket": {}, "cordova-plugin-buildinfo": {}, "cordova-plugin-system": {}, - "com.foxdebug.acode.rk.exec.terminal": {}, - "com.foxdebug.acode.rk.exec.proot": {} + "com.foxdebug.acode.rk.exec.terminal": {} }, "platforms": [ "android" @@ -64,7 +63,6 @@ "@types/url-parse": "^1.4.11", "autoprefixer": "^10.4.19", "babel-loader": "^9.1.3", - "com.foxdebug.acode.rk.exec.proot": "file:src/plugins/proot", "com.foxdebug.acode.rk.exec.terminal": "file:src/plugins/terminal", "cordova-android": "13.0.0", "cordova-clipboard": "^1.3.0", diff --git a/readme.md b/readme.md index daf0a9c6a..67a6fee13 100644 --- a/readme.md +++ b/readme.md @@ -60,9 +60,12 @@ yarn setup 2. Build the project: ```shell -yarn build +yarn build [fdroid] ``` +**Note**: Add the fdroid flag only if you want to build the F-Droid-compatible version of Acode. +Omit this flag to build the regular APK (Play Store or normal version). + ## • Contributing Acode Editor is an open-source project, and we welcome contributions from the community. To contribute, follow these steps: diff --git a/src/plugins/terminal/www/Terminal.js b/src/plugins/terminal/www/Terminal.js index bda51ba6e..9187ee957 100644 --- a/src/plugins/terminal/www/Terminal.js +++ b/src/plugins/terminal/www/Terminal.js @@ -85,16 +85,22 @@ const Terminal = { try { let alpineUrl; let axsUrl; - let prootUrl = ""; - let libTalloc = ""; + let prootUrl; + let libTalloc; if (arch === "arm64-v8a") { + libTalloc = "https://raw.githubusercontent.com/Acode-Foundation/Acode/main/src/plugins/proot/libs/arm64/libtalloc.so"; + prootUrl = "https://raw.githubusercontent.com/Acode-Foundation/Acode/main/src/plugins/proot/libs/arm64/libproot-xed.so"; axsUrl = `https://github.com/bajrangCoder/acodex_server/releases/download/${AXS_VERSION_TAG}/axs-musl-android-arm64`; alpineUrl = "https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/aarch64/alpine-minirootfs-3.21.0-aarch64.tar.gz"; } else if (arch === "armeabi-v7a") { + libTalloc = "https://raw.githubusercontent.com/Acode-Foundation/Acode/main/src/plugins/proot/libs/arm32/libtalloc.so"; + prootUrl = "https://raw.githubusercontent.com/Acode-Foundation/Acode/main/src/plugins/proot/libs/arm32/libproot-xed.so"; axsUrl = `https://github.com/bajrangCoder/acodex_server/releases/download/${AXS_VERSION_TAG}/axs-musl-android-armv7`; alpineUrl = "https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/armhf/alpine-minirootfs-3.21.0-armhf.tar.gz"; } else if (arch === "x86_64") { + libTalloc = "https://raw.githubusercontent.com/Acode-Foundation/Acode/main/src/plugins/proot/libs/x64/libtalloc.so"; + prootUrl = "https://raw.githubusercontent.com/Acode-Foundation/Acode/main/src/plugins/proot/libs/x64/libproot-xed.so"; axsUrl = `https://github.com/bajrangCoder/acodex_server/releases/download/${AXS_VERSION_TAG}/axs-musl-android-x86_64`; alpineUrl = "https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/x86_64/alpine-minirootfs-3.21.0-x86_64.tar.gz"; } else { diff --git a/utils/scripts/build.sh b/utils/scripts/build.sh index 066bb3ab3..9a35bae4b 100644 --- a/utils/scripts/build.sh +++ b/utils/scripts/build.sh @@ -1,14 +1,21 @@ #! /bin/bash -platform="$1" -app="$2" -mode="$3" +app="$1" +mode="$2" +fdroidFlag="$3" webpackmode="development" cordovamode="" -if [ -z "$platform" ] -then -platform="android" +root=$(npm prefix) + + +if [[ "$fdroidFlag" == "fdroid" ]]; then + echo "true" > "$root/fdroid.bool" + cordova plugin remove com.foxdebug.acode.rk.exec.proot + +else + echo "false" > "$root/fdroid.bool" + cordova plugin add src/plugins/proot/ fi if [ -z "$mode" ] @@ -33,7 +40,7 @@ NC='' script1="node ./utils/config.js $mode $app" script2="webpack --progress --mode $webpackmode " script3="node ./utils/loadStyles.js" -script4="cordova build $platform $cordovamode" +script4="cordova build android $cordovamode" eval " echo \"${RED}$script1${NC}\"; $script1;