From 66315767611f4b7a8ee8ac9cd2f22ddc2cf348d3 Mon Sep 17 00:00:00 2001 From: Henrik Grimler Date: Sun, 28 Nov 2021 13:04:01 +0100 Subject: [PATCH 01/11] Use termux-shared library for constants This allows us to remove all hardcoded /data/data/com.termux paths, and makes future maintenance easier. --- app/build.gradle | 5 +++++ app/src/main/AndroidManifest.xml | 2 +- app/src/main/res/values/strings.xml | 12 ++++++++++-- build.gradle | 1 + 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d01ad3539..75c9750c2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,6 +9,10 @@ android { targetSdkVersion 28 versionCode 49 versionName "0.49" + + manifestPlaceholders.TERMUX_PACKAGE_NAME = "com.termux" + manifestPlaceholders.TERMUX_APP_NAME = "Termux" + manifestPlaceholders.TERMUX_API_APP_NAME = "Termux:API" } signingConfigs { @@ -45,6 +49,7 @@ dependencies { implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.biometric:biometric:1.2.0-alpha02' implementation 'androidx.media:media:1.4.1' + implementation 'com.termux.termux-app:termux-shared:f3ffc36bfd' } task versionName { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 974f38218..b68fca101 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,7 +2,7 @@ + android:sharedUserId="${TERMUX_PACKAGE_NAME}"> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bd13a9b20..3c789642a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,8 +1,16 @@ + + + + + + ]> + - Termux:API + &TERMUX_API_APP_NAME; Share with Grant permission - Termux:API needs the following permission(s):\n + This app needs the following permission(s):\n diff --git a/build.gradle b/build.gradle index 338aa18d5..5675f8e61 100644 --- a/build.gradle +++ b/build.gradle @@ -12,6 +12,7 @@ allprojects { repositories { google() mavenCentral() + maven { url "https://jitpack.io" } } } From 58f9d790900a1028c10ed8e642492c4febaad834 Mon Sep 17 00:00:00 2001 From: Henrik Grimler Date: Sun, 28 Nov 2021 13:05:16 +0100 Subject: [PATCH 02/11] NotificationAPI: use TERMUX_PREFIX_DIR_PATH from termux-shared Instead of hardcoding the prefix path. --- app/src/main/java/com/termux/api/NotificationAPI.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/termux/api/NotificationAPI.java b/app/src/main/java/com/termux/api/NotificationAPI.java index d1bc33914..d407cc243 100644 --- a/app/src/main/java/com/termux/api/NotificationAPI.java +++ b/app/src/main/java/com/termux/api/NotificationAPI.java @@ -29,12 +29,14 @@ import java.util.Objects; import java.util.UUID; +import static com.termux.shared.termux.TermuxConstants.TERMUX_PREFIX_DIR_PATH; + public class NotificationAPI { public static final String TERMUX_SERVICE = "com.termux.app.TermuxService"; public static final String ACTION_EXECUTE = "com.termux.service_execute"; public static final String EXTRA_ARGUMENTS = "com.termux.execute.arguments"; - public static final String BIN_SH = "/data/data/com.termux/files/usr/bin/sh"; + public static final String BIN_SH = TERMUX_PREFIX_DIR_PATH+"/bin/sh"; private static final String EXTRA_EXECUTE_IN_BACKGROUND = "com.termux.execute.background"; private static final String CHANNEL_ID = "termux-notification"; private static final String CHANNEL_TITLE = "Termux API notification channel"; From 25531cfff65b4ea6448c4dc0787c20a42613409d Mon Sep 17 00:00:00 2001 From: Henrik Grimler Date: Sun, 28 Nov 2021 13:05:47 +0100 Subject: [PATCH 03/11] Dialog: use constants from termux-shared to get property file paths Instead of hardcoding them. --- app/src/main/java/com/termux/api/DialogActivity.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/termux/api/DialogActivity.java b/app/src/main/java/com/termux/api/DialogActivity.java index 69c412ef0..25f5ddd56 100644 --- a/app/src/main/java/com/termux/api/DialogActivity.java +++ b/app/src/main/java/com/termux/api/DialogActivity.java @@ -57,6 +57,9 @@ import java.util.Objects; import java.util.Properties; +import static com.termux.shared.termux.TermuxConstants.TERMUX_PROPERTIES_PRIMARY_FILE_PATH; +import static com.termux.shared.termux.TermuxConstants.TERMUX_PROPERTIES_SECONDARY_FILE_PATH; + /** * API that allows receiving user input interactively in a variety of different ways */ @@ -65,10 +68,10 @@ public class DialogActivity extends AppCompatActivity { private boolean resultReturned = false; protected boolean getBlackUI() { - File propsFile = new File("/data/data/com.termux/files/home/.termux/termux.properties"); + File propsFile = new File(TERMUX_PROPERTIES_PRIMARY_FILE_PATH); if (!propsFile.exists()) - propsFile = new File("/data/data/com.termux/files/home/.config/termux.properties"); + propsFile = new File(TERMUX_PROPERTIES_SECONDARY_FILE_PATH); boolean mUseBlackUi = false; From e33dd4a8c8bd64e9784fdda469ef529df3128a66 Mon Sep 17 00:00:00 2001 From: Henrik Grimler Date: Sun, 5 Dec 2021 17:03:29 +0100 Subject: [PATCH 04/11] Manifest: remove hardcoded com.termux.api everywhere --- app/src/main/AndroidManifest.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b68fca101..8bef0b920 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,7 +48,7 @@ - + - - - + + + @@ -72,23 +72,23 @@ android:noHistory="true" android:excludeFromRecents="true" android:exported="false"/> - - - - + + - + android:name=".ShareAPI$ContentProvider" /> From c4955a53b3a908b23756f1faae186179f594cddf Mon Sep 17 00:00:00 2001 From: Henrik Grimler Date: Sun, 5 Dec 2021 17:09:31 +0100 Subject: [PATCH 05/11] Define TermuxAPIApplication As part of adaption for the termux-shared library. --- app/src/main/AndroidManifest.xml | 1 + .../com/termux/api/TermuxAPIApplication.java | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 app/src/main/java/com/termux/api/TermuxAPIApplication.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8bef0b920..ff328bb67 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -51,6 +51,7 @@ Date: Thu, 8 Jul 2021 08:28:31 +0500 Subject: [PATCH 06/11] Update .gitignore --- .gitignore | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6c8b41f86..247b4bcbc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,11 @@ -# .gitignore from https://gist.github.com/iainconnor/8605514: - # Built application files build/ +release/ +*.apk +*.so +.externalNativeBuild +.cxx +*.zip # Crashlytics configuations com_crashlytics_export_strings.xml From 6ef2618f65d276d32c8854cd8c25008b5ee41e7c Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Sat, 4 Sep 2021 09:15:09 +0500 Subject: [PATCH 07/11] Changed: Enable minifyEnabled But still keep shrinkResources and obfuscation disabled for testing reproducible builds and maintaining stacktraces of crashes. --- app/build.gradle | 3 ++- app/proguard-rules.pro | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 app/proguard-rules.pro diff --git a/app/build.gradle b/app/build.gradle index 75c9750c2..b9fa5704b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,7 +26,8 @@ android { buildTypes { release { - minifyEnabled false + minifyEnabled true + shrinkResources false // Reproducible builds proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' } diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 000000000..bd0e223e8 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,10 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in android-sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +-dontobfuscate From 818ad5483221d41acc0cd097491c781473dcf5a6 Mon Sep 17 00:00:00 2001 From: Henrik Grimler Date: Sun, 5 Dec 2021 18:37:47 +0100 Subject: [PATCH 08/11] Define sdk versions in build.gradle To have them easily accessible in only one place. --- app/build.gradle | 6 +++--- gradle.properties | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b9fa5704b..d071fbaab 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,12 +1,12 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 30 + compileSdkVersion project.properties.compileSdkVersion.toInteger() defaultConfig { applicationId "com.termux.api" - minSdkVersion 24 - targetSdkVersion 28 + minSdkVersion project.properties.minSdkVersion.toInteger() + targetSdkVersion project.properties.targetSdkVersion.toInteger() versionCode 49 versionName "0.49" diff --git a/gradle.properties b/gradle.properties index 1a04b66fb..8ec0981b8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,4 +18,8 @@ org.gradle.jvmargs=-Xmx2048M # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true android.enableJetifier=true -android.useAndroidX=true \ No newline at end of file +android.useAndroidX=true + +minSdkVersion=24 +targetSdkVersion=28 +compileSdkVersion=30 From ed20ebb990423cf45b0c246ff0531428ed6ab5f7 Mon Sep 17 00:00:00 2001 From: Henrik Grimler Date: Sun, 5 Dec 2021 18:39:21 +0100 Subject: [PATCH 09/11] gradle: use 7.3.1 --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ffed3a254..3cd8500c1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From ebf4511c81783be4bbf503ccaf473dee1559913d Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Wed, 22 Sep 2021 11:14:58 +0500 Subject: [PATCH 10/11] Changed!: use semantic versioning and add commit hash to APK file names The versionName will now follow semantic version "2.0.0" spec in the format major.minor.patch(-prerelease)(+buildmetadata). This will make versioning the prerelease and github debug builds versions easier and follow as spec. The @termux devs should make sure that when bumping versionName in build.gradle file and when creating a tag for new releases on github that they include the patch number as well, like v0.1.0 instead of just v0.1. The build.gradle file and attach_debug_apks_to_release workflow will now validate the version as well and the build/attachment will fail if versionName does not follow the spec. https://semver.org/spec/v2.0.0.html APKs released on github for debug build workflows and releases are now referred as Github releases as per termux/termux-app@7b10a35f and termux/termux-app@94e01d68, so APK filenames have been modified to include github in the filename. The APKs are still debuggable, so that tag remains too. For github workflows the apk filename format will be termux-api_+-github-debug_.apk, like termux-api_v0.1.0+xxxxxxxx-github-debug_arm64-v8a.apk and for github releases it will be termux-api_-github-debug_.apk, like termux-api_v0.1-github-debug_arm64-v8a.apk. The last_commit_hash will be the first 8 characters of the commit hash. The -github-debug will act as buildmetadata and will not affect versioning precedence. For github workflows triggered by push and pull_request triggers, + will be used as new versionName, like v0.1.0+xxxxxxxx. This will make tracking which build a user is using easier and help in resolving issues as well. The app/build.gradle now also supports following TERMUX_API_ scoped environmental variables and RELEASE_TAG variable will not be used anymore since it may conflict with possibly other variables used by users. - TERMUX_API_APP_VERSION_NAME will be used as versionName if its set. - TERMUX_API_APK_VERSION_TAG will be used as termux-api_.apk if its set. --- .../attach_debug_apks_to_release.yml | 36 +++++++++++++++++++ .github/workflows/debug_build.yml | 31 ++++++++++------ app/build.gradle | 30 +++++++++++++--- 3 files changed, 83 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/attach_debug_apks_to_release.yml diff --git a/.github/workflows/attach_debug_apks_to_release.yml b/.github/workflows/attach_debug_apks_to_release.yml new file mode 100644 index 000000000..05540dcf0 --- /dev/null +++ b/.github/workflows/attach_debug_apks_to_release.yml @@ -0,0 +1,36 @@ +name: Attach Debug APKs To Release + +on: + release: + types: + - published + +jobs: + attach-apks: + runs-on: ubuntu-latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Clone repository + uses: actions/checkout@v2 + with: + ref: ${{ env.GITHUB_REF }} + - name: Set vars + run: | + RELEASE_VERSION_NAME="${GITHUB_REF/refs\/tags\//}" + if ! printf "%s" "${RELEASE_VERSION_NAME/v/}" | grep -qP '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'; then + echo "The versionName '${RELEASE_VERSION_NAME/v/}' is not a valid version as per semantic version '2.0.0' spec in the format 'major.minor.patch(-prerelease)(+buildmetadata)'. https://semver.org/spec/v2.0.0.html." + exit 1 + fi + echo "TERMUX_API_RELEASE_TAG=$RELEASE_VERSION_NAME" >> $GITHUB_ENV + echo "TERMUX_API_APK_VERSION_TAG=$RELEASE_VERSION_NAME+github-debug" >> $GITHUB_ENV # Used by app/build.gradle + - name: Echo release + run: echo "Attaching debug APK to '${{ env.TERMUX_API_RELEASE_TAG }}' release" + - name: Build + run: ./gradlew assembleDebug + - name: Attach APKs to release + run: >- + hub release edit + -m "" + -a "./app/build/outputs/apk/debug/termux-api_${{ env.TERMUX_API_APK_VERSION_TAG }}.apk" + "${{ env.TERMUX_API_RELEASE_TAG }}" diff --git a/.github/workflows/debug_build.yml b/.github/workflows/debug_build.yml index 210c54a09..239a65dde 100644 --- a/.github/workflows/debug_build.yml +++ b/.github/workflows/debug_build.yml @@ -6,13 +6,24 @@ jobs: build: runs-on: ubuntu-latest steps: - - name: Clone repository - uses: actions/checkout@v2 - - name: Build - run: | - ./gradlew assembleDebug - - name: Store generated APK file - uses: actions/upload-artifact@v2 - with: - name: termux-api - path: ./app/build/outputs/apk/debug/app-debug.apk + - name: Clone repository + uses: actions/checkout@v2 + - name: Set vars + run: | + # Set NEW_VERSION_NAME to "+" + CURRENT_VERSION_NAME_REGEX='\s+versionName "([^"]+)"$' + CURRENT_VERSION_NAME="$(grep -m 1 -E "$CURRENT_VERSION_NAME_REGEX" ./app/build.gradle | sed -r "s/$CURRENT_VERSION_NAME_REGEX/\1/")" + NEW_VERSION_NAME="$CURRENT_VERSION_NAME+${GITHUB_SHA:0:7}" + echo "TERMUX_WIDGET_APP_VERSION_NAME=$NEW_VERSION_NAME" >> $GITHUB_ENV # Used by app/build.gradle + echo "TERMUX_WIDGET_APK_VERSION_TAG=v$NEW_VERSION_NAME-github-debug" >> $GITHUB_ENV # Used by app/build.gradle + - name: Echo version + run: echo "Building APK for '$TERMUX_WIDGET_APP_VERSION_NAME'" + - name: Build + run: ./gradlew assembleDebug + - name: Store generated APK file + uses: actions/upload-artifact@v2 + with: + name: termux-api + path: | + ./app/build/outputs/apk/debug/termux-api_${{ env.TERMUX_WIDGET_APK_VERSION_TAG }}.apk + ./app/build/outputs/apk/debug/output-metadata.json diff --git a/app/build.gradle b/app/build.gradle index d071fbaab..c6ab801af 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,13 +2,18 @@ apply plugin: 'com.android.application' android { compileSdkVersion project.properties.compileSdkVersion.toInteger() + def appVersionName = System.getenv("TERMUX_API_APP_VERSION_NAME") ?: "" + def apkVersionTag = System.getenv("TERMUX_API_APK_VERSION_TAG") ?: "" defaultConfig { applicationId "com.termux.api" minSdkVersion project.properties.minSdkVersion.toInteger() targetSdkVersion project.properties.targetSdkVersion.toInteger() versionCode 49 - versionName "0.49" + versionName "0.49.0" + + if (appVersionName) versionName = appVersionName + validateVersionName(versionName) manifestPlaceholders.TERMUX_PACKAGE_NAME = "com.termux" manifestPlaceholders.TERMUX_APP_NAME = "Termux" @@ -41,6 +46,16 @@ android { targetCompatibility JavaVersion.VERSION_1_8 } + applicationVariants.all { variant -> + variant.outputs.all { output -> + if (variant.buildType.name == "debug") { + outputFileName = new File("termux-api_" + (apkVersionTag ? apkVersionTag : "debug") + ".apk") + } else if (variant.buildType.name == "release") { + outputFileName = new File("termux-api_" + (apkVersionTag ? apkVersionTag : "release") + ".apk") + } + } + } + lintOptions { disable 'ExpiredTargetSdkVersion' } @@ -54,7 +69,14 @@ dependencies { } task versionName { - doLast { - print android.defaultConfig.versionName - } + doLast { + print android.defaultConfig.versionName + } +} + +def validateVersionName(String versionName) { + // https://semver.org/spec/v2.0.0.html#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string + // ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$ + if (!java.util.regex.Pattern.matches("^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?\$", versionName)) + throw new GradleException("The versionName '" + versionName + "' is not a valid version as per semantic version '2.0.0' spec in the format 'major.minor.patch(-prerelease)(+buildmetadata)'. https://semver.org/spec/v2.0.0.html.") } From 5ca50e0eb0533f922af030e54dfd4eb1382faedd Mon Sep 17 00:00:00 2001 From: Henrik Grimler Date: Sun, 5 Dec 2021 18:57:51 +0100 Subject: [PATCH 11/11] Update dependency versions androidx.biometric:biometric:1.2.0-alpha04 is available as well, but it requires compileSdkVersion 31, which we cannot use. --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index c6ab801af..2f13295bd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -63,8 +63,8 @@ android { dependencies { implementation 'com.google.android.material:material:1.4.0' - implementation 'androidx.biometric:biometric:1.2.0-alpha02' - implementation 'androidx.media:media:1.4.1' + implementation 'androidx.biometric:biometric:1.2.0-alpha03' + implementation 'androidx.media:media:1.4.3' implementation 'com.termux.termux-app:termux-shared:f3ffc36bfd' }