Compare commits
40 Commits
github-rel
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
53f75a8da3 | |
|
|
bcb61c387c | |
|
|
c6ec1cb64f | |
|
|
382c9708b3 | |
|
|
edd44d2ce9 | |
|
|
4183ffa122 | |
|
|
8aca6dbbf4 | |
|
|
1812a405ee | |
|
|
338fb66e5c | |
|
|
f852dca0ef | |
|
|
8174a995ae | |
|
|
7bceab88e2 | |
|
|
2c1bd650b0 | |
|
|
4a9ad910dd | |
|
|
9d2ac14557 | |
|
|
c6e2ca7fde | |
|
|
da3a0ac4e2 | |
|
|
4de0caac5b | |
|
|
bc321d0a7c | |
|
|
9ee1c9d5ad | |
|
|
a988383e01 | |
|
|
d2cd6ac2e5 | |
|
|
52da00e5c2 | |
|
|
b0e1dbc3da | |
|
|
078eea2b74 | |
|
|
fb01127ff2 | |
|
|
b84dc703e8 | |
|
|
8be53336c3 | |
|
|
d90e3fbca1 | |
|
|
245158ceb9 | |
|
|
6c00f1fc61 | |
|
|
03142590ff | |
|
|
4443b657bf | |
|
|
a8a69c6d80 | |
|
|
438cd73fff | |
|
|
36d811ea7d | |
|
|
c2d57f2ed8 | |
|
|
661c37501f | |
|
|
f80b46487d | |
|
|
a5de3d3a2b |
|
|
@ -17,7 +17,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ env.GITHUB_REF }}
|
||||
|
||||
|
|
@ -71,13 +71,14 @@ jobs:
|
|||
fi
|
||||
|
||||
echo "Attaching APKs to github release"
|
||||
if ! gh release upload "$RELEASE_VERSION_NAME" \
|
||||
"$APK_DIR_PATH/${APK_BASENAME_PREFIX}_universal.apk" \
|
||||
"$APK_DIR_PATH/${APK_BASENAME_PREFIX}_arm64-v8a.apk" \
|
||||
"$APK_DIR_PATH/${APK_BASENAME_PREFIX}_armeabi-v7a.apk" \
|
||||
"$APK_DIR_PATH/${APK_BASENAME_PREFIX}_x86_64.apk" \
|
||||
"$APK_DIR_PATH/${APK_BASENAME_PREFIX}_x86.apk" \
|
||||
"$APK_DIR_PATH/${APK_BASENAME_PREFIX}_sha256sums" \
|
||||
; then
|
||||
if ! hub release edit \
|
||||
-m "" \
|
||||
-a "$APK_DIR_PATH/${APK_BASENAME_PREFIX}_universal.apk" \
|
||||
-a "$APK_DIR_PATH/${APK_BASENAME_PREFIX}_arm64-v8a.apk" \
|
||||
-a "$APK_DIR_PATH/${APK_BASENAME_PREFIX}_armeabi-v7a.apk" \
|
||||
-a "$APK_DIR_PATH/${APK_BASENAME_PREFIX}_x86_64.apk" \
|
||||
-a "$APK_DIR_PATH/${APK_BASENAME_PREFIX}_x86.apk" \
|
||||
-a "$APK_DIR_PATH/${APK_BASENAME_PREFIX}_sha256sums" \
|
||||
"$RELEASE_VERSION_NAME"; then
|
||||
exit_on_error "Attach APKs to release failed for '$APK_VERSION_TAG' release."
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -19,7 +19,13 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup java 17
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
|
||||
- name: Build APKs
|
||||
shell: bash {0}
|
||||
|
|
@ -79,7 +85,7 @@ jobs:
|
|||
fi
|
||||
|
||||
- name: Attach universal APK file
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ env.APK_BASENAME_PREFIX }}_universal
|
||||
path: |
|
||||
|
|
@ -87,7 +93,7 @@ jobs:
|
|||
${{ env.APK_DIR_PATH }}/output-metadata.json
|
||||
|
||||
- name: Attach arm64-v8a APK file
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ env.APK_BASENAME_PREFIX }}_arm64-v8a
|
||||
path: |
|
||||
|
|
@ -95,7 +101,7 @@ jobs:
|
|||
${{ env.APK_DIR_PATH }}/output-metadata.json
|
||||
|
||||
- name: Attach armeabi-v7a APK file
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ env.APK_BASENAME_PREFIX }}_armeabi-v7a
|
||||
path: |
|
||||
|
|
@ -103,7 +109,7 @@ jobs:
|
|||
${{ env.APK_DIR_PATH }}/output-metadata.json
|
||||
|
||||
- name: Attach x86_64 APK file
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ env.APK_BASENAME_PREFIX }}_x86_64
|
||||
path: |
|
||||
|
|
@ -111,7 +117,7 @@ jobs:
|
|||
${{ env.APK_DIR_PATH }}/output-metadata.json
|
||||
|
||||
- name: Attach x86 APK file
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ env.APK_BASENAME_PREFIX }}_x86
|
||||
path: |
|
||||
|
|
@ -119,7 +125,7 @@ jobs:
|
|||
${{ env.APK_DIR_PATH }}/output-metadata.json
|
||||
|
||||
- name: Attach sha256sums file
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ env.APK_BASENAME_PREFIX }}_sha256sums
|
||||
path: |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
name: Automatic Dependency Submission
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ 'master' ]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
dependency-submission:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v6
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
- name: Generate and submit dependency graph
|
||||
uses: gradle/actions/dependency-submission@v5
|
||||
|
|
@ -15,5 +15,5 @@ jobs:
|
|||
name: "Validation"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: gradle/wrapper-validation-action@v3
|
||||
- uses: actions/checkout@v6
|
||||
- uses: gradle/actions/wrapper-validation@5
|
||||
|
|
|
|||
|
|
@ -15,7 +15,12 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: Setup java 17
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
- name: Execute tests
|
||||
run: |
|
||||
./gradlew test
|
||||
|
|
|
|||
31
README.md
31
README.md
|
|
@ -29,6 +29,7 @@ Quick how-to about Termux package management is available at [Package Management
|
|||
- [Debugging](#debugging)
|
||||
- [For Maintainers and Contributors](#for-maintainers-and-contributors)
|
||||
- [Forking](#forking)
|
||||
- [Sponsors and Funders](#sponsors-and-funders)
|
||||
##
|
||||
|
||||
|
||||
|
|
@ -49,7 +50,7 @@ The core [Termux](https://github.com/termux/termux-app) app comes with the follo
|
|||
|
||||
## Installation
|
||||
|
||||
Latest version is `v0.118.1`.
|
||||
Latest version is `v0.118.3`.
|
||||
|
||||
**NOTICE: It is highly recommended that you update to `v0.118.0` or higher ASAP for various bug fixes, including a critical world-readable vulnerability reported [here](https://termux.github.io/general/2022/02/15/termux-apps-vulnerability-disclosures.html). See [below](#google-play-store-experimental-branch) for information regarding Termux on Google Play.**
|
||||
|
||||
|
|
@ -264,3 +265,31 @@ Commit messages **must** use the [Conventional Commits](https://www.conventional
|
|||
- You also need to recompile bootstrap zip for the new package name. Check [building bootstrap](https://github.com/termux/termux-packages/wiki/For-maintainers#build-bootstrap-archives), [here](https://github.com/termux/termux-app/issues/1983) and [here](https://github.com/termux/termux-app/issues/2081#issuecomment-865280111).
|
||||
- Currently, not all plugins use `TermuxConstants` from `termux-shared` library and have hardcoded `com.termux` values and will need to be manually patched.
|
||||
- If forking termux plugins, check [Forking and Local Development](https://github.com/termux/termux-app/wiki/Termux-Libraries#forking-and-local-development) for info on how to use termux libraries for plugins.
|
||||
##
|
||||
|
||||
|
||||
|
||||
## Sponsors and Funders
|
||||
|
||||
[<img alt="GitHub Accelerator" width="25%" src="site/assets/sponsors/github.png" />](https://github.com)
|
||||
*[GitHub Accelerator](https://github.com/accelerator) ([1](https://github.blog/2023-04-12-github-accelerator-our-first-cohort-and-whats-next))*
|
||||
|
||||
|
||||
|
||||
[<img alt="GitHub Secure Open Source Fund" width="25%" src="site/assets/sponsors/github.png" />](https://github.com)
|
||||
*[GitHub Secure Open Source Fund](https://resources.github.com/github-secure-open-source-fund) ([1](https://github.blog/open-source/maintainers/securing-the-supply-chain-at-scale-starting-with-71-important-open-source-projects), [2](https://termux.dev/en/posts/general/2025/08/11/termux-selected-for-github-secure-open-source-fund-session-2.html))*
|
||||
|
||||
|
||||
|
||||
[<img alt="NLnet NGI Mobifree" width="25%" src="site/assets/sponsors/nlnet-ngi-mobifree.png" />](https://nlnet.nl/mobifree)
|
||||
*[NLnet NGI Mobifree](https://nlnet.nl/mobifree) ([1](https://nlnet.nl/news/2024/20241111-NGI-Mobifree-grants.html), [2](https://termux.dev/en/posts/general/2024/11/11/termux-selected-for-nlnet-ngi-mobifree-grant.html))*
|
||||
|
||||
|
||||
|
||||
[<img alt="Cloudflare" width="25%" src="site/assets/sponsors/cloudflare.png" />](https://www.cloudflare.com)
|
||||
*[Cloudflare](https://www.cloudflare.com) ([1](https://packages-cf.termux.dev))*
|
||||
|
||||
|
||||
|
||||
[<img alt="Warp" width="25%" src="https://github.com/warpdotdev/brand-assets/blob/640dffd347439bbcb535321ab36b7281cf4446c0/Github/Sponsor/Warp-Github-LG-03.png" />](https://www.warp.dev/?utm_source=github&utm_medium=readme&utm_campaign=termux)
|
||||
[*Warp, built for coding with multiple AI agents*](https://www.warp.dev/?utm_source=github&utm_medium=readme&utm_campaign=termux)
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
Check https://termux.dev/security for info on Termux security policies and how to report vulnerabilities.
|
||||
|
|
@ -10,16 +10,11 @@ ext {
|
|||
// by replacing $PREFIX since app code is dependant on the variant used to build the APK.
|
||||
// Currently supported values are: [ "apt-android-7" "apt-android-5" ]
|
||||
packageVariant = System.getenv("TERMUX_PACKAGE_VARIANT") ?: "apt-android-7" // Default: "apt-android-7"
|
||||
bootstrapMinSdk = packageVariant == "apt-android-5" ? 21 : 24
|
||||
bootstrapMinRelease = packageVariant == "apt-android-5" ? "5.0" : "7.0"
|
||||
bootstrapMaxSdk = packageVariant == "apt-android-5" ? 23 : null
|
||||
bootstrapMaxRelease = packageVariant == "apt-android-5" ? "6.0" : null
|
||||
|
||||
buildMinSdk = bootstrapMinSdk
|
||||
buildTargetSdk = project.properties.targetSdkVersion.toInteger()
|
||||
}
|
||||
|
||||
android {
|
||||
namespace "com.termux"
|
||||
|
||||
compileSdkVersion project.properties.compileSdkVersion.toInteger()
|
||||
ndkVersion = System.getenv("JITPACK_NDK_VERSION") ?: project.properties.ndkVersion
|
||||
def appVersionName = System.getenv("TERMUX_APP_VERSION_NAME") ?: ""
|
||||
|
|
@ -28,38 +23,32 @@ android {
|
|||
def splitAPKsForReleaseBuilds = System.getenv("TERMUX_SPLIT_APKS_FOR_RELEASE_BUILDS") ?: "0" // F-Droid does not support split APKs #1904
|
||||
|
||||
dependencies {
|
||||
implementation "androidx.annotation:annotation:1.3.0"
|
||||
implementation "androidx.core:core:1.6.0"
|
||||
implementation "androidx.drawerlayout:drawerlayout:1.1.1"
|
||||
implementation "androidx.preference:preference:1.1.1"
|
||||
implementation "androidx.annotation:annotation:1.9.0"
|
||||
implementation "androidx.core:core:1.13.1"
|
||||
implementation "androidx.drawerlayout:drawerlayout:1.2.0"
|
||||
implementation "androidx.preference:preference:1.2.1"
|
||||
implementation "androidx.viewpager:viewpager:1.0.0"
|
||||
implementation "com.google.android.material:material:1.4.0"
|
||||
implementation "com.google.android.material:material:1.12.0"
|
||||
implementation "com.google.guava:guava:24.1-jre"
|
||||
implementation "io.noties.markwon:core:$markwonVersion"
|
||||
implementation "io.noties.markwon:ext-strikethrough:$markwonVersion"
|
||||
implementation "io.noties.markwon:linkify:$markwonVersion"
|
||||
implementation "io.noties.markwon:recycler:$markwonVersion"
|
||||
implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
|
||||
|
||||
implementation project(":terminal-view")
|
||||
implementation project(":termux-shared")
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.termux"
|
||||
minSdk buildMinSdk
|
||||
targetSdk buildTargetSdk
|
||||
versionCode 1021
|
||||
versionName "0.119.0-beta.2"
|
||||
minSdkVersion project.properties.minSdkVersion.toInteger()
|
||||
targetSdkVersion project.properties.targetSdkVersion.toInteger()
|
||||
versionCode 118
|
||||
versionName "0.118.0"
|
||||
|
||||
if (appVersionName) versionName = appVersionName
|
||||
validateVersionName(versionName)
|
||||
|
||||
buildConfigField "Integer", "TERMUX_APP__BOOTSTRAP_MIN_SDK", project.ext.bootstrapMinSdk.toString()
|
||||
buildConfigField "String", "TERMUX_APP__BOOTSTRAP_MIN_RELEASE",
|
||||
project.ext.bootstrapMinRelease ? "\"" + project.ext.bootstrapMinRelease + "\"" : "null"
|
||||
buildConfigField "Integer", "TERMUX_APP__BOOTSTRAP_MAX_SDK", project.ext.bootstrapMaxSdk.toString()
|
||||
buildConfigField "String", "TERMUX_APP__BOOTSTRAP_MAX_RELEASE",
|
||||
project.ext.bootstrapMaxRelease ? "\"" + project.ext.bootstrapMaxRelease + "\"" : "null"
|
||||
buildConfigField "String", "TERMUX_PACKAGE_VARIANT", "\"" + project.ext.packageVariant + "\"" // Used by TermuxApplication class
|
||||
|
||||
manifestPlaceholders.TERMUX_PACKAGE_NAME = "com.termux"
|
||||
|
|
@ -123,7 +112,7 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
lint {
|
||||
disable 'ProtectedPermissions'
|
||||
}
|
||||
|
||||
|
|
@ -151,12 +140,15 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
buildConfig true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation "junit:junit:4.13.2"
|
||||
testImplementation "org.robolectric:robolectric:4.10"
|
||||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
|
||||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.1.2"
|
||||
}
|
||||
|
||||
task versionName {
|
||||
|
|
@ -227,17 +219,17 @@ task downloadBootstraps() {
|
|||
doLast {
|
||||
def packageVariant = project.ext.packageVariant
|
||||
if (packageVariant == "apt-android-7") {
|
||||
def version = "2025.03.28-r1" + "+" + packageVariant
|
||||
downloadBootstrap("aarch64", "c8d702b6f742935001c37cda81b8ac69504a95d5cf28f2899532dd8cd4b057eb", version)
|
||||
downloadBootstrap("arm", "f3bb9d1b32552b34fff41861dbf193ec5ba2848d67d779ac1c7256da6640f85d", version)
|
||||
downloadBootstrap("i686", "36db3e1ac3547f9a174fd763bd9a484fa1a3449cdd81e1cf2408ff0454f839c6", version)
|
||||
downloadBootstrap("x86_64", "1c124ec2396ee70a51b0b0a574f29aa659526aa2b9f558f993b2fb05d1e51855", version)
|
||||
def version = "2022.04.28-r5" + "+" + packageVariant
|
||||
downloadBootstrap("aarch64", "4a51a7eb209fe82efc24d52e3cccc13165f27377290687cb82038cbd8e948430", version)
|
||||
downloadBootstrap("arm", "6459a786acbae50d4c8a36fa1c3de6a4dd2d482572f6d54f73274709bd627325", version)
|
||||
downloadBootstrap("i686", "919d212b2f19e08600938db4079e794e947365022dbfd50ac342c50fcedcd7be", version)
|
||||
downloadBootstrap("x86_64", "61b02fdc03ea4f5d9da8d8cf018013fdc6659e6da6cbf44e9b24d1c623580b89", version)
|
||||
} else if (packageVariant == "apt-android-5") {
|
||||
def version = "2025.03.28-r3" + "+" + packageVariant
|
||||
downloadBootstrap("aarch64", "147c98e610a30588665a89776314833c293006b12c70e65dcde6eb54c2344113", version)
|
||||
downloadBootstrap("arm", "363c28dd4b70c995302498beae79fb5917af7d3b0ca9fbd9da7de96ab64c6122", version)
|
||||
downloadBootstrap("i686", "a2e742381ab24cf8c9a78ae4e2425ee44d8fb9625a2b0ef63e4cd32e292f7186", version)
|
||||
downloadBootstrap("x86_64", "4f6866c222b0f1ae1b180220ffc6e8e1afbc10b9cbb7a462c062c490eda90044", version)
|
||||
def version = "2022.04.28-r6" + "+" + packageVariant
|
||||
downloadBootstrap("aarch64", "913609d439415c828c5640be1b0561467e539cb1c7080662decaaca2fb4820e7", version)
|
||||
downloadBootstrap("arm", "26bfb45304c946170db69108e5eb6e3641aad751406ce106c80df80cad2eccf8", version)
|
||||
downloadBootstrap("i686", "46dcfeb5eef67ba765498db9fe4c50dc4690805139aa0dd141a9d8ee0693cd27", version)
|
||||
downloadBootstrap("x86_64", "615b590679ee6cd885b7fd2ff9473c845e920f9b422f790bb158c63fe42b8481", version)
|
||||
} else {
|
||||
throw new GradleException("Unsupported TERMUX_PACKAGE_VARIANT \"" + packageVariant + "\"")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,3 @@
|
|||
-dontobfuscate
|
||||
#-renamesourcefileattribute SourceFile
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# Temp fix for androidx.window:window:1.0.0-alpha09 imported by termux-shared
|
||||
# https://issuetracker.google.com/issues/189001730
|
||||
# https://android-review.googlesource.com/c/platform/frameworks/support/+/1757630
|
||||
-keep class androidx.window.** { *; }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.termux"
|
||||
android:installLocation="internalOnly"
|
||||
android:sharedUserId="${TERMUX_PACKAGE_NAME}"
|
||||
android:sharedUserLabel="@string/shared_user_label">
|
||||
|
|
|
|||
|
|
@ -774,7 +774,7 @@ public final class TermuxActivity extends AppCompatActivity implements ServiceCo
|
|||
|
||||
// If permission is granted, then also setup storage symlinks.
|
||||
if(PermissionUtils.checkAndRequestLegacyOrManageExternalStoragePermission(
|
||||
TermuxActivity.this, requestCode, true, !isPermissionCallback)) {
|
||||
TermuxActivity.this, requestCode, !isPermissionCallback)) {
|
||||
if (isPermissionCallback)
|
||||
Logger.logInfoAndShowToast(TermuxActivity.this, LOG_TAG,
|
||||
getString(com.termux.shared.R.string.msg_storage_permission_granted_on_request));
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public class TermuxApplication extends Application {
|
|||
boolean isTermuxFilesDirectoryAccessible = error == null;
|
||||
if (isTermuxFilesDirectoryAccessible) {
|
||||
Logger.logInfo(LOG_TAG, "Termux files directory is accessible");
|
||||
/*
|
||||
|
||||
error = TermuxFileUtils.isAppsTermuxAppDirectoryAccessible(true, true);
|
||||
if (error != null) {
|
||||
Logger.logErrorExtended(LOG_TAG, "Create apps/termux-app directory failed\n" + error);
|
||||
|
|
@ -61,7 +61,6 @@ public class TermuxApplication extends Application {
|
|||
|
||||
// Setup termux-am-socket server
|
||||
TermuxAmSocketServer.setupTermuxAmSocketServer(context);
|
||||
*/
|
||||
} else {
|
||||
Logger.logErrorExtended(LOG_TAG, "Termux files directory is not accessible\n" + error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,12 +10,8 @@ import android.system.Os;
|
|||
import android.util.Pair;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.termux.BuildConfig;
|
||||
import com.termux.R;
|
||||
import com.termux.shared.file.FileUtils;
|
||||
import com.termux.shared.shell.command.ExecutionCommand;
|
||||
import com.termux.shared.shell.command.runner.app.AppShell;
|
||||
import com.termux.shared.termux.TermuxBootstrap;
|
||||
import com.termux.shared.termux.crash.TermuxCrashUtils;
|
||||
import com.termux.shared.termux.file.TermuxFileUtils;
|
||||
import com.termux.shared.interact.MessageDialogUtils;
|
||||
|
|
@ -106,12 +102,6 @@ final class TermuxInstaller {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!checkIfMinOrMaxSdkVersionIsIncompatible(activity,
|
||||
BuildConfig.TERMUX_APP__BOOTSTRAP_MIN_SDK, BuildConfig.TERMUX_APP__BOOTSTRAP_MIN_RELEASE,
|
||||
BuildConfig.TERMUX_APP__BOOTSTRAP_MAX_SDK, BuildConfig.TERMUX_APP__BOOTSTRAP_MAX_RELEASE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If prefix directory exists, even if its a symlink to a valid directory and symlink is not broken/dangling
|
||||
if (FileUtils.directoryFileExists(TERMUX_PREFIX_DIR_PATH, true)) {
|
||||
if (TermuxFileUtils.isTermuxPrefixDirectoryEmpty()) {
|
||||
|
|
@ -205,8 +195,7 @@ final class TermuxInstaller {
|
|||
outStream.write(buffer, 0, readBytes);
|
||||
}
|
||||
if (zipEntryName.startsWith("bin/") || zipEntryName.startsWith("libexec") ||
|
||||
zipEntryName.startsWith("lib/apt/apt-helper") || zipEntryName.startsWith("lib/apt/methods") ||
|
||||
zipEntryName.equals("etc/termux/bootstrap/termux-bootstrap-second-stage.sh")) {
|
||||
zipEntryName.startsWith("lib/apt/apt-helper") || zipEntryName.startsWith("lib/apt/methods")) {
|
||||
//noinspection OctalInteger
|
||||
Os.chmod(targetFile.getAbsolutePath(), 0700);
|
||||
}
|
||||
|
|
@ -227,35 +216,6 @@ final class TermuxInstaller {
|
|||
throw new RuntimeException("Moving termux prefix staging to prefix directory failed");
|
||||
}
|
||||
|
||||
// Run Termux bootstrap second stage.
|
||||
String termuxBootstrapSecondStageFile = TERMUX_PREFIX_DIR_PATH + "/etc/termux/bootstrap/termux-bootstrap-second-stage.sh";
|
||||
if (!FileUtils.fileExists(termuxBootstrapSecondStageFile, false)) {
|
||||
Logger.logInfo(LOG_TAG, "Not running Termux bootstrap second stage since script not found at \"" + termuxBootstrapSecondStageFile + "\" path.");
|
||||
} else {
|
||||
if (!FileUtils.fileExists(TermuxConstants.TERMUX_BIN_PREFIX_DIR_PATH + "/bash", true)) {
|
||||
Logger.logInfo(LOG_TAG, "Not running Termux bootstrap second stage since bash not found.");
|
||||
}
|
||||
Logger.logInfo(LOG_TAG, "Running Termux bootstrap second stage.");
|
||||
|
||||
ExecutionCommand executionCommand = new ExecutionCommand(-1,
|
||||
termuxBootstrapSecondStageFile, null, null,
|
||||
null, ExecutionCommand.Runner.APP_SHELL.getName(), false);
|
||||
executionCommand.commandLabel = "Termux Bootstrap Second Stage Command";
|
||||
executionCommand.backgroundCustomLogLevel = Logger.LOG_LEVEL_NORMAL;
|
||||
AppShell appShell = AppShell.execute(activity, executionCommand, null, new TermuxShellEnvironment(), null, true);
|
||||
if (appShell == null || !executionCommand.isSuccessful() || executionCommand.resultData.exitCode != 0) {
|
||||
// Generate debug report before deleting broken prefix directory to get `stat` info at time of failure.
|
||||
showBootstrapErrorDialog(activity, whenDone, MarkdownUtils.getMarkdownCodeForString(executionCommand.toString(), true));
|
||||
|
||||
// Delete prefix directory as otherwise when app is restarted, the broken prefix directory would be used and logged into.
|
||||
Logger.logInfo(LOG_TAG, "Deleting broken termux prefix.");
|
||||
error = FileUtils.deleteFile("termux prefix directory", TERMUX_PREFIX_DIR_PATH, true);
|
||||
if (error != null)
|
||||
Logger.logErrorExtended(LOG_TAG, error.toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Logger.logInfo(LOG_TAG, "Bootstrap packages installed successfully.");
|
||||
|
||||
// Recreate env file since termux prefix was wiped earlier
|
||||
|
|
@ -279,42 +239,6 @@ final class TermuxInstaller {
|
|||
}.start();
|
||||
}
|
||||
|
||||
public static boolean checkIfMinOrMaxSdkVersionIsIncompatible(Activity activity,
|
||||
Integer minSdk, String minRelease,
|
||||
Integer maxSdk, String maxRelease) {
|
||||
if (minSdk != null && Build.VERSION.SDK_INT < minSdk) {
|
||||
String bootstrapErrorMessage = activity.getString(R.string.bootstrap_error_apk_bootstrap_variant_min_sdk_incompatible,
|
||||
MarkdownUtils.getMarkdownCodeForString(TermuxBootstrap.TERMUX_APP_PACKAGE_VARIANT.getName(), false),
|
||||
MarkdownUtils.getMarkdownCodeForString(Build.VERSION.RELEASE, false),
|
||||
Build.VERSION.SDK_INT,
|
||||
MarkdownUtils.getMarkdownCodeForString(minRelease, false),
|
||||
minSdk);
|
||||
Logger.logError(LOG_TAG, bootstrapErrorMessage);
|
||||
sendBootstrapCrashReportNotification(activity, bootstrapErrorMessage);
|
||||
MessageDialogUtils.exitAppWithErrorMessage(activity,
|
||||
activity.getString(R.string.bootstrap_error_title),
|
||||
bootstrapErrorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (maxSdk != null && Build.VERSION.SDK_INT > maxSdk) {
|
||||
String bootstrapErrorMessage = activity.getString(R.string.bootstrap_error_apk_bootstrap_variant_max_sdk_incompatible,
|
||||
MarkdownUtils.getMarkdownCodeForString(TermuxBootstrap.TERMUX_APP_PACKAGE_VARIANT.getName(), false),
|
||||
MarkdownUtils.getMarkdownCodeForString(Build.VERSION.RELEASE, false),
|
||||
Build.VERSION.SDK_INT,
|
||||
MarkdownUtils.getMarkdownCodeForString(maxRelease, false),
|
||||
maxSdk);
|
||||
Logger.logError(LOG_TAG, bootstrapErrorMessage);
|
||||
sendBootstrapCrashReportNotification(activity, bootstrapErrorMessage);
|
||||
MessageDialogUtils.exitAppWithErrorMessage(activity,
|
||||
activity.getString(R.string.bootstrap_error_title),
|
||||
bootstrapErrorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void showBootstrapErrorDialog(Activity activity, Runnable whenDone, String message) {
|
||||
Logger.logErrorExtended(LOG_TAG, "Bootstrap Error:\n" + message);
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ public final class HelpActivity extends AppCompatActivity {
|
|||
mWebView = new WebView(this);
|
||||
WebSettings settings = mWebView.getSettings();
|
||||
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
|
||||
settings.setAppCacheEnabled(false);
|
||||
setContentView(progressLayout);
|
||||
mWebView.clearCache(true);
|
||||
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ public class TermuxTerminalSessionActivityClient extends TermuxTerminalSessionCl
|
|||
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION).build()).build();
|
||||
|
||||
try {
|
||||
mBellSoundId = mBellSoundPool.load(mActivity, R.raw.bell, 1);
|
||||
mBellSoundId = mBellSoundPool.load(mActivity, com.termux.shared.R.raw.bell, 1);
|
||||
} catch (Exception e){
|
||||
// Catch java.lang.RuntimeException: Unable to resume activity {com.termux/com.termux.app.TermuxActivity}: android.content.res.Resources$NotFoundException: File res/raw/bell.ogg from drawable resource ID
|
||||
Logger.logStackTraceWithMessage(LOG_TAG, "Failed to load bell sound pool", e);
|
||||
|
|
|
|||
|
|
@ -735,8 +735,8 @@ public class TermuxTerminalViewClient extends TermuxTerminalViewClientBase {
|
|||
|
||||
MessageDialogUtils.showMessage(mActivity, TermuxConstants.TERMUX_APP_NAME + " Report Issue",
|
||||
mActivity.getString(R.string.msg_add_termux_debug_info),
|
||||
mActivity.getString(R.string.action_yes), (dialog, which) -> reportIssueFromTranscript(transcriptText, true),
|
||||
mActivity.getString(R.string.action_no), (dialog, which) -> reportIssueFromTranscript(transcriptText, false),
|
||||
mActivity.getString(com.termux.shared.R.string.action_yes), (dialog, which) -> reportIssueFromTranscript(transcriptText, true),
|
||||
mActivity.getString(com.termux.shared.R.string.action_no), (dialog, which) -> reportIssueFromTranscript(transcriptText, false),
|
||||
null);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,18 +27,10 @@
|
|||
|
||||
<!-- Termux Bootstrap Packages Installation -->
|
||||
<string name="bootstrap_installer_body">Installing bootstrap packages…</string>
|
||||
<string name="bootstrap_error_title">&TERMUX_APP_NAME; Bootstrap Error</string>
|
||||
<string name="bootstrap_error_title">Unable to install bootstrap</string>
|
||||
<string name="bootstrap_error_body">&TERMUX_APP_NAME; was unable to install the bootstrap packages.</string>
|
||||
<string name="bootstrap_error_abort">Abort</string>
|
||||
<string name="bootstrap_error_try_again">Try again</string>
|
||||
<string name="bootstrap_error_apk_bootstrap_variant_min_sdk_incompatible">The APK bootstrap variant %1$s
|
||||
of currently installed &TERMUX_APP_NAME; app is not compatible with the Android version %2$s
|
||||
(sdk `%3$d`) of the device and it requires minimum Android version %4$s (sdk `%5$d`).
|
||||
\n\nUninstall the &TERMUX_APP_NAME; app and reinstall the correct APK build variant.</string>
|
||||
<string name="bootstrap_error_apk_bootstrap_variant_max_sdk_incompatible">The APK bootstrap variant %1$s
|
||||
of currently installed &TERMUX_APP_NAME; app is not compatible with the Android version %2$s
|
||||
(sdk `%3$d`) of the device and it requires maximum Android version %4$s (sdk `%5$d`).
|
||||
\n\nUninstall the &TERMUX_APP_NAME; app and reinstall the correct APK build variant.</string>
|
||||
<string name="bootstrap_error_not_primary_user_message">&TERMUX_APP_NAME; can only be run as the primary user.
|
||||
\nBootstrap binaries compiled for &TERMUX_APP_NAME; have hardcoded $PREFIX path and cannot be installed
|
||||
under any path other than:\n%1$s.</string>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ buildscript {
|
|||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:4.2.2"
|
||||
classpath "com.android.tools.build:gradle:8.13.2"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -15,7 +15,3 @@ allprojects {
|
|||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,7 @@ android.useAndroidX=true
|
|||
|
||||
minSdkVersion=21
|
||||
targetSdkVersion=28
|
||||
ndkVersion=22.1.7171670
|
||||
compileSdkVersion=30
|
||||
ndkVersion=29.0.14206865
|
||||
compileSdkVersion=36
|
||||
|
||||
markwonVersion=4.6.2
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,5 +1,7 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env sh
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
# Copyright © 2015 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
|
@ -15,81 +15,114 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
|
@ -98,88 +131,118 @@ Please set the JAVA_HOME variable in your environment to match the
|
|||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
|
|
|||
|
|
@ -13,8 +13,10 @@
|
|||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
|
|
@ -25,7 +27,8 @@
|
|||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
|
|
@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
|
|
@ -56,32 +59,33 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
|
|
|||
|
|
@ -1,2 +1,4 @@
|
|||
jdk:
|
||||
- openjdk17
|
||||
env:
|
||||
JITPACK_NDK_VERSION: "21.1.6352462"
|
||||
JITPACK_NDK_VERSION: "29.0.14206865"
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
|
|
@ -2,6 +2,8 @@ apply plugin: 'com.android.library'
|
|||
apply plugin: 'maven-publish'
|
||||
|
||||
android {
|
||||
namespace "com.termux.emulator"
|
||||
|
||||
compileSdkVersion project.properties.compileSdkVersion.toInteger()
|
||||
ndkVersion = System.getenv("JITPACK_NDK_VERSION") ?: project.properties.ndkVersion
|
||||
|
||||
|
|
@ -50,13 +52,13 @@ tasks.withType(Test) {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation "androidx.annotation:annotation:1.3.0"
|
||||
implementation "androidx.annotation:annotation:1.9.0"
|
||||
testImplementation "junit:junit:4.13.2"
|
||||
}
|
||||
|
||||
task sourceJar(type: Jar) {
|
||||
from android.sourceSets.main.java.srcDirs
|
||||
classifier "sources"
|
||||
archiveClassifier = "sources"
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
|
|
@ -64,7 +66,7 @@ afterEvaluate {
|
|||
publications {
|
||||
// Creates a Maven publication called "release".
|
||||
release(MavenPublication) {
|
||||
from components.release
|
||||
from components.findByName('release')
|
||||
groupId = 'com.termux'
|
||||
artifactId = 'terminal-emulator'
|
||||
version = '0.118.0'
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
<manifest package="com.termux.terminal">
|
||||
<manifest>
|
||||
</manifest>
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ apply plugin: 'com.android.library'
|
|||
apply plugin: 'maven-publish'
|
||||
|
||||
android {
|
||||
namespace "com.termux.view"
|
||||
compileSdkVersion project.properties.compileSdkVersion.toInteger()
|
||||
|
||||
dependencies {
|
||||
implementation "androidx.annotation:annotation:1.3.0"
|
||||
implementation "androidx.annotation:annotation:1.9.0"
|
||||
api project(":terminal-emulator")
|
||||
}
|
||||
|
||||
|
|
@ -34,7 +35,7 @@ dependencies {
|
|||
|
||||
task sourceJar(type: Jar) {
|
||||
from android.sourceSets.main.java.srcDirs
|
||||
classifier "sources"
|
||||
archiveClassifier = "sources"
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
|
|
@ -42,7 +43,7 @@ afterEvaluate {
|
|||
publications {
|
||||
// Creates a Maven publication called "release".
|
||||
release(MavenPublication) {
|
||||
from components.release
|
||||
from components.findByName('release')
|
||||
groupId = 'com.termux'
|
||||
artifactId = 'terminal-view'
|
||||
version = '0.118.0'
|
||||
|
|
@ -51,3 +52,4 @@ afterEvaluate {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
<manifest package="com.termux.view">
|
||||
<manifest>
|
||||
</manifest>
|
||||
|
|
|
|||
|
|
@ -2,23 +2,24 @@ apply plugin: 'com.android.library'
|
|||
apply plugin: 'maven-publish'
|
||||
|
||||
android {
|
||||
namespace = "com.termux.shared"
|
||||
|
||||
compileSdkVersion project.properties.compileSdkVersion.toInteger()
|
||||
ndkVersion = System.getenv("JITPACK_NDK_VERSION") ?: project.properties.ndkVersion
|
||||
|
||||
dependencies {
|
||||
implementation "androidx.appcompat:appcompat:1.3.1"
|
||||
implementation "androidx.annotation:annotation:1.3.0"
|
||||
implementation "androidx.core:core:1.6.0"
|
||||
implementation "com.google.android.material:material:1.4.0"
|
||||
implementation "androidx.appcompat:appcompat:1.6.1"
|
||||
implementation "androidx.annotation:annotation:1.9.0"
|
||||
implementation "androidx.core:core:1.13.1"
|
||||
implementation "com.google.android.material:material:1.12.0"
|
||||
implementation "com.google.guava:guava:24.1-jre"
|
||||
implementation "io.noties.markwon:core:$markwonVersion"
|
||||
implementation "io.noties.markwon:ext-strikethrough:$markwonVersion"
|
||||
implementation "io.noties.markwon:linkify:$markwonVersion"
|
||||
implementation "io.noties.markwon:recycler:$markwonVersion"
|
||||
implementation "org.lsposed.hiddenapibypass:hiddenapibypass:5.0"
|
||||
implementation "org.lsposed.hiddenapibypass:hiddenapibypass:6.1"
|
||||
|
||||
// Do not increment version higher than 1.0.0-alpha09 since it will break ViewUtils and needs to be looked into
|
||||
// noinspection GradleDependency
|
||||
implementation "androidx.window:window:1.0.0-alpha09"
|
||||
implementation "androidx.window:window:1.1.0"
|
||||
|
||||
// Do not increment version higher than 2.5 or there
|
||||
// will be runtime exceptions on android < 8
|
||||
|
|
@ -31,6 +32,7 @@ android {
|
|||
}
|
||||
|
||||
defaultConfig {
|
||||
compileSdkVersion project.properties.compileSdkVersion.toInteger()
|
||||
minSdkVersion project.properties.minSdkVersion.toInteger()
|
||||
targetSdkVersion project.properties.targetSdkVersion.toInteger()
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
|
@ -55,6 +57,7 @@ android {
|
|||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
path file('src/main/cpp/Android.mk')
|
||||
|
|
@ -64,14 +67,13 @@ android {
|
|||
|
||||
dependencies {
|
||||
testImplementation "junit:junit:4.13.2"
|
||||
androidTestImplementation "androidx.test.ext:junit:1.1.3"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:3.4.0"
|
||||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
|
||||
androidTestImplementation "androidx.test.ext:junit:1.1.5"
|
||||
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.1.2"
|
||||
}
|
||||
|
||||
task sourceJar(type: Jar) {
|
||||
from android.sourceSets.main.java.srcDirs
|
||||
classifier "sources"
|
||||
archiveClassifier = "sources"
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
|
|
@ -79,7 +81,7 @@ afterEvaluate {
|
|||
publications {
|
||||
// Creates a Maven publication called "release".
|
||||
release(MavenPublication) {
|
||||
from components.release
|
||||
from components.findByName('release')
|
||||
groupId = 'com.termux'
|
||||
artifactId = 'termux-shared'
|
||||
version = '0.118.0'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.termux.shared">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
</manifest>
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ import android.content.Context;
|
|||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.os.Build;
|
||||
import android.system.Os;
|
||||
import android.system.OsConstants;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
|
|
@ -160,19 +158,7 @@ public class AndroidUtils {
|
|||
appendPropertyToMarkdown(markdownString, "BOARD", Build.BOARD);
|
||||
appendPropertyToMarkdown(markdownString, "HARDWARE", Build.HARDWARE);
|
||||
appendPropertyToMarkdown(markdownString, "DEVICE", Build.DEVICE);
|
||||
|
||||
appendPropertyToMarkdown(markdownString, "SUPPORTED_ABIS", Joiner.on(", ").skipNulls().join(Build.SUPPORTED_ABIS));
|
||||
appendPropertyToMarkdown(markdownString, "SUPPORTED_32_BIT_ABIS", Joiner.on(", ").skipNulls().join(Build.SUPPORTED_32_BIT_ABIS));
|
||||
appendPropertyToMarkdown(markdownString, "SUPPORTED_64_BIT_ABIS", Joiner.on(", ").skipNulls().join(Build.SUPPORTED_64_BIT_ABIS));
|
||||
|
||||
// If on Android >= 15
|
||||
if (Build.VERSION.SDK_INT >= 35) {
|
||||
try {
|
||||
appendPropertyToMarkdownIfSet(markdownString, "PAGE_SIZE", Os.sysconf(OsConstants._SC_PAGESIZE));
|
||||
} catch (Throwable t) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
markdownString.append("\n##\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -209,44 +209,31 @@ public class PermissionUtils {
|
|||
|
||||
/** If path is under primary external storage directory and storage permission is missing,
|
||||
* then legacy or manage external storage permission will be requested from the user via a call
|
||||
* to {@link #checkAndRequestLegacyOrManageExternalStoragePermission(Context, int, boolean, boolean)}.
|
||||
* to {@link #checkAndRequestLegacyOrManageExternalStoragePermission(Context, int, boolean)}.
|
||||
*
|
||||
* @param context The context for operations.
|
||||
* @param filePath The path to check.
|
||||
* @param requestCode The request code to use while asking for permission.
|
||||
* @param prioritizeManageExternalStoragePermission If {@link Manifest.permission#MANAGE_EXTERNAL_STORAGE}
|
||||
* permission should be requested if on
|
||||
* Android `>= 11` instead of getting legacy
|
||||
* storage permission.
|
||||
* @param showErrorMessage If an error message toast should be shown if permission is not granted.
|
||||
* @return Returns {@code true} if permission is granted, otherwise {@code false}.
|
||||
*/
|
||||
@SuppressLint("SdCardPath")
|
||||
public static boolean checkAndRequestLegacyOrManageExternalStoragePermissionIfPathOnPrimaryExternalStorage(
|
||||
@NonNull Context context, String filePath, int requestCode,
|
||||
boolean prioritizeManageExternalStoragePermission, boolean showErrorMessage) {
|
||||
@NonNull Context context, String filePath, int requestCode, boolean showErrorMessage) {
|
||||
// If path is under primary external storage directory, then check for missing permissions.
|
||||
if (!FileUtils.isPathInDirPaths(filePath,
|
||||
Arrays.asList(Environment.getExternalStorageDirectory().getAbsolutePath(), "/sdcard"), true))
|
||||
return true;
|
||||
|
||||
return checkAndRequestLegacyOrManageExternalStoragePermission(context, requestCode, prioritizeManageExternalStoragePermission, showErrorMessage);
|
||||
return checkAndRequestLegacyOrManageExternalStoragePermission(context, requestCode, showErrorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if legacy or manage external storage permissions has been granted.
|
||||
*
|
||||
* - If `prioritizeManageExternalStoragePermission` is `true and running on Android `>= 11`, then
|
||||
* it will be checked if app has been granted the
|
||||
* {@link Manifest.permission#MANAGE_EXTERNAL_STORAGE}.
|
||||
* - If `prioritizeManageExternalStoragePermission` is `false` and running on Android `>= 11`, then
|
||||
* if {@link #isLegacyExternalStoragePossible(Context)} returns `true`, them it will be
|
||||
* checked if app has has been granted {@link Manifest.permission#READ_EXTERNAL_STORAGE} and
|
||||
* {@link Manifest.permission#WRITE_EXTERNAL_STORAGE} permissions, otherwise it will be checked
|
||||
* if app has been granted the {@link Manifest.permission#MANAGE_EXTERNAL_STORAGE} permission.
|
||||
* - If running on Android `< 11`, then it will only be checked if app has been granted
|
||||
* {@link Manifest.permission#READ_EXTERNAL_STORAGE} and
|
||||
* {@link Manifest.permission#WRITE_EXTERNAL_STORAGE} permissions.
|
||||
* Check if legacy or manage external storage permissions has been granted. If
|
||||
* {@link #isLegacyExternalStoragePossible(Context)} returns {@code true}, them it will be
|
||||
* checked if app has has been granted {@link Manifest.permission#READ_EXTERNAL_STORAGE} and
|
||||
* {@link Manifest.permission#WRITE_EXTERNAL_STORAGE} permissions, otherwise it will be checked
|
||||
* if app has been granted the {@link Manifest.permission#MANAGE_EXTERNAL_STORAGE} permission.
|
||||
*
|
||||
* If storage permission is missing, it will be requested from the user if {@code context} is an
|
||||
* instance of {@link Activity} or {@link AppCompatActivity} and {@code requestCode}
|
||||
|
|
@ -269,34 +256,16 @@ public class PermissionUtils {
|
|||
*}
|
||||
* @param context The context for operations.
|
||||
* @param requestCode The request code to use while asking for permission.
|
||||
* @param prioritizeManageExternalStoragePermission If {@link Manifest.permission#MANAGE_EXTERNAL_STORAGE}
|
||||
* permission should be requested if on
|
||||
* Android `>= 11` instead of getting legacy
|
||||
* storage permission.
|
||||
* @param showErrorMessage If an error message toast should be shown if permission is not granted.
|
||||
* @return Returns {@code true} if permission is granted, otherwise {@code false}.
|
||||
*/
|
||||
public static boolean checkAndRequestLegacyOrManageExternalStoragePermission(@NonNull Context context,
|
||||
int requestCode,
|
||||
boolean prioritizeManageExternalStoragePermission,
|
||||
boolean showErrorMessage) {
|
||||
Logger.logVerbose(LOG_TAG, "Checking storage permission");
|
||||
|
||||
String errmsg;
|
||||
Boolean requestLegacyStoragePermission = null;
|
||||
|
||||
if (prioritizeManageExternalStoragePermission && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
|
||||
requestLegacyStoragePermission = false;
|
||||
|
||||
if (requestLegacyStoragePermission == null)
|
||||
requestLegacyStoragePermission = isLegacyExternalStoragePossible(context);
|
||||
|
||||
boolean requestLegacyStoragePermission = isLegacyExternalStoragePossible(context);
|
||||
boolean checkIfHasRequestedLegacyExternalStorage = checkIfHasRequestedLegacyExternalStorage(context);
|
||||
|
||||
Logger.logVerbose(LOG_TAG, "prioritizeManageExternalStoragePermission=" + prioritizeManageExternalStoragePermission +
|
||||
", requestLegacyStoragePermission=" + requestLegacyStoragePermission +
|
||||
", checkIfHasRequestedLegacyExternalStorage=" + checkIfHasRequestedLegacyExternalStorage);
|
||||
|
||||
if (requestLegacyStoragePermission && checkIfHasRequestedLegacyExternalStorage) {
|
||||
// Check if requestLegacyExternalStorage is set to true in app manifest
|
||||
if (!hasRequestedLegacyExternalStorage(context, showErrorMessage))
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public class MessageDialogUtils {
|
|||
final DialogInterface.OnClickListener onNegativeButton,
|
||||
final DialogInterface.OnDismissListener onDismiss) {
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.Theme_AppCompat_Light_Dialog);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context, androidx.appcompat.R.style.Theme_AppCompat_Light_Dialog);
|
||||
|
||||
LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
|
||||
View view = inflater.inflate(R.layout.dialog_show_message, null);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package com.termux.shared.models;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
|
||||
import com.termux.shared.markdown.MarkdownUtils;
|
||||
import com.termux.shared.android.AndroidUtils;
|
||||
|
||||
|
|
@ -10,6 +12,25 @@ import java.io.Serializable;
|
|||
*/
|
||||
public class ReportInfo implements Serializable {
|
||||
|
||||
/**
|
||||
* Explicitly define `serialVersionUID` to prevent exceptions on deserialization.
|
||||
*
|
||||
* Like when calling `Bundle.getSerializable()` on Android.
|
||||
* `android.os.BadParcelableException: Parcelable encountered IOException reading a Serializable object` (name = <class_name>)
|
||||
* `java.io.InvalidClassException: <class_name>; local class incompatible`
|
||||
*
|
||||
* The `@Keep` annotation is necessary to prevent the field from being removed by proguard when
|
||||
* app is compiled, even if its kept during library compilation.
|
||||
*
|
||||
* **See Also:**
|
||||
* - https://docs.oracle.com/javase/8/docs/platform/serialization/spec/version.html#a6678
|
||||
* - https://docs.oracle.com/javase/8/docs/platform/serialization/spec/class.html#a4100
|
||||
*/
|
||||
@Keep
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
|
||||
/** The user action that was being processed for which the report was generated. */
|
||||
public final String userAction;
|
||||
/** The internal app component that sent the report. */
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.termux.shared.models;
|
|||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.termux.shared.activities.TextIOActivity;
|
||||
|
|
@ -19,6 +20,25 @@ import java.io.Serializable;
|
|||
*/
|
||||
public class TextIOInfo implements Serializable {
|
||||
|
||||
/**
|
||||
* Explicitly define `serialVersionUID` to prevent exceptions on deserialization.
|
||||
*
|
||||
* Like when calling `Bundle.getSerializable()` on Android.
|
||||
* `android.os.BadParcelableException: Parcelable encountered IOException reading a Serializable object` (name = <class_name>)
|
||||
* `java.io.InvalidClassException: <class_name>; local class incompatible`
|
||||
*
|
||||
* The `@Keep` annotation is necessary to prevent the field from being removed by proguard when
|
||||
* app is compiled, even if its kept during library compilation.
|
||||
*
|
||||
* **See Also:**
|
||||
* - https://docs.oracle.com/javase/8/docs/platform/serialization/spec/version.html#a6678
|
||||
* - https://docs.oracle.com/javase/8/docs/platform/serialization/spec/class.html#a4100
|
||||
*/
|
||||
@Keep
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
|
||||
public static final int GENERAL_DATA_SIZE_LIMIT_IN_BYTES = 1000;
|
||||
public static final int LABEL_SIZE_LIMIT_IN_BYTES = 4000;
|
||||
public static final int TEXT_SIZE_LIMIT_IN_BYTES = 100000 - GENERAL_DATA_SIZE_LIMIT_IN_BYTES - LABEL_SIZE_LIMIT_IN_BYTES; // < 100KB
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.termux.shared.shell.command.environment;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
|
|
@ -21,20 +20,6 @@ import java.util.HashMap;
|
|||
*/
|
||||
public class AndroidShellEnvironment extends UnixShellEnvironment {
|
||||
|
||||
/** Environment variable scope for Android. */
|
||||
public static final String ANDROID_ENV_SCOPE = "ANDROID__"; // Default: "ANDROID__"
|
||||
|
||||
/**
|
||||
* Environment variable for the Android build SDK version currently running on the device that
|
||||
* is defined by {@link Build.VERSION#SDK_INT} and `ro.build.version.sdk` system property.
|
||||
*
|
||||
* - https://developer.android.com/reference/android/os/Build.VERSION#SDK_INT
|
||||
* - https://developer.android.com/reference/android/os/Build.VERSION_CODES
|
||||
*
|
||||
* Default value: `ANDROID__BUILD_VERSION_SDK`
|
||||
*/
|
||||
public static final String ENV_ANDROID__BUILD_VERSION_SDK = ANDROID_ENV_SCOPE + "BUILD_VERSION_SDK";
|
||||
|
||||
protected ShellCommandShellEnvironment shellCommandShellEnvironment;
|
||||
|
||||
public AndroidShellEnvironment() {
|
||||
|
|
@ -76,8 +61,6 @@ public class AndroidShellEnvironment extends UnixShellEnvironment {
|
|||
ShellEnvironmentUtils.putToEnvIfInSystemEnv(environment, "DEX2OATBOOTCLASSPATH");
|
||||
ShellEnvironmentUtils.putToEnvIfInSystemEnv(environment, "SYSTEMSERVERCLASSPATH");
|
||||
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_ANDROID__BUILD_VERSION_SDK, String.valueOf(Build.VERSION.SDK_INT));
|
||||
|
||||
return environment;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,13 +33,13 @@ public class ShellCommandShellEnvironment {
|
|||
public static final String ENV_SHELL_CMD__APP_SHELL_NUMBER_SINCE_BOOT = SHELL_CMD_ENV_PREFIX + "APP_SHELL_NUMBER_SINCE_BOOT";
|
||||
|
||||
/** Environment variable for the {{@link ExecutionCommand.Runner#TERMINAL_SESSION} number since boot. */
|
||||
public static final String ENV_SHELL_CMD__APP_TERMINAL_SESSION_NUMBER_SINCE_BOOT = SHELL_CMD_ENV_PREFIX + "APP_TERMINAL_SESSION_NUMBER_SINCE_BOOT";
|
||||
public static final String ENV_SHELL_CMD__TERMINAL_SESSION_NUMBER_SINCE_BOOT = SHELL_CMD_ENV_PREFIX + "TERMINAL_SESSION_NUMBER_SINCE_BOOT";
|
||||
|
||||
/** Environment variable for the {@link ExecutionCommand.Runner#APP_SHELL} number since app start. */
|
||||
public static final String ENV_SHELL_CMD__APP_SHELL_NUMBER_SINCE_APP_START = SHELL_CMD_ENV_PREFIX + "APP_SHELL_NUMBER_SINCE_APP_START";
|
||||
|
||||
/** Environment variable for the {@link ExecutionCommand.Runner#TERMINAL_SESSION} number since app start. */
|
||||
public static final String ENV_SHELL_CMD__APP_TERMINAL_SESSION_NUMBER_SINCE_APP_START = SHELL_CMD_ENV_PREFIX + "APP_TERMINAL_SESSION_NUMBER_SINCE_APP_START";
|
||||
public static final String ENV_SHELL_CMD__TERMINAL_SESSION_NUMBER_SINCE_APP_START = SHELL_CMD_ENV_PREFIX + "TERMINAL_SESSION_NUMBER_SINCE_APP_START";
|
||||
|
||||
|
||||
/** Get shell environment containing info for {@link ExecutionCommand}. */
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ public final class TermuxPropertyConstants {
|
|||
/** Defines the key for extra keys */
|
||||
public static final String KEY_EXTRA_KEYS = "extra-keys"; // Default: "extra-keys"
|
||||
//public static final String DEFAULT_IVALUE_EXTRA_KEYS = "[[ESC, TAB, CTRL, ALT, {key: '-', popup: '|'}, DOWN, UP]]"; // Single row
|
||||
public static final String DEFAULT_IVALUE_EXTRA_KEYS = "[['ESC',{key: 'DRAWER', popup: 'PASTE'},'SCROLL','HOME','UP','END','PGUP'], ['TAB','CTRL','ALT','LEFT','DOWN','RIGHT','PGDN']]"; // Double row
|
||||
public static final String DEFAULT_IVALUE_EXTRA_KEYS = "[['ESC','/',{key: '-', popup: '|'},'HOME','UP','END','PGUP'], ['TAB','CTRL','ALT','LEFT','DOWN','RIGHT','PGDN']]"; // Double row
|
||||
|
||||
/** Defines the key for extra keys style */
|
||||
public static final String KEY_EXTRA_KEYS_STYLE = "extra-keys-style"; // Default: "extra-keys-style"
|
||||
|
|
|
|||
|
|
@ -27,12 +27,6 @@ public class TermuxAppShellEnvironment {
|
|||
/** Termux app environment variables. */
|
||||
public static HashMap<String, String> termuxAppEnvironment;
|
||||
|
||||
/** Environment variable root scope. */
|
||||
public static final String TERMUX_ENV__S_ROOT = "TERMUX_"; // Default: "TERMUX_"
|
||||
|
||||
/** Environment variable scope for Termux. */
|
||||
public static final String TERMUX_ENV__S_TERMUX = TERMUX_ENV__S_ROOT + "_"; // Default: "TERMUX__"
|
||||
|
||||
/** Environment variable for the Termux app version. */
|
||||
public static final String ENV_TERMUX_VERSION = TermuxConstants.TERMUX_ENV_PREFIX_ROOT + "_VERSION";
|
||||
|
||||
|
|
@ -40,15 +34,15 @@ public class TermuxAppShellEnvironment {
|
|||
public static final String TERMUX_APP_ENV_PREFIX = TermuxConstants.TERMUX_ENV_PREFIX_ROOT + "_APP__";
|
||||
|
||||
/** Environment variable for the Termux app version name. */
|
||||
public static final String ENV_TERMUX_APP__APP_VERSION_NAME = TERMUX_APP_ENV_PREFIX + "APP_VERSION_NAME";
|
||||
public static final String ENV_TERMUX_APP__VERSION_NAME = TERMUX_APP_ENV_PREFIX + "VERSION_NAME";
|
||||
/** Environment variable for the Termux app version code. */
|
||||
public static final String ENV_TERMUX_APP__APP_VERSION_CODE = TERMUX_APP_ENV_PREFIX + "APP_VERSION_CODE";
|
||||
public static final String ENV_TERMUX_APP__VERSION_CODE = TERMUX_APP_ENV_PREFIX + "VERSION_CODE";
|
||||
/** Environment variable for the Termux app package name. */
|
||||
public static final String ENV_TERMUX_APP__PACKAGE_NAME = TERMUX_APP_ENV_PREFIX + "PACKAGE_NAME";
|
||||
/** Environment variable for the Termux app process id. */
|
||||
public static final String ENV_TERMUX_APP__PID = TERMUX_APP_ENV_PREFIX + "PID";
|
||||
/** Environment variable for the Termux app uid. */
|
||||
public static final String ENV_TERMUX__UID = TERMUX_ENV__S_TERMUX + "UID";
|
||||
public static final String ENV_TERMUX_APP__UID = TERMUX_APP_ENV_PREFIX + "UID";
|
||||
/** Environment variable for the Termux app targetSdkVersion. */
|
||||
public static final String ENV_TERMUX_APP__TARGET_SDK = TERMUX_APP_ENV_PREFIX + "TARGET_SDK";
|
||||
/** Environment variable for the Termux app is debuggable apk build. */
|
||||
|
|
@ -56,29 +50,28 @@ public class TermuxAppShellEnvironment {
|
|||
/** Environment variable for the Termux app {@link TermuxConstants} APK_RELEASE_*. */
|
||||
public static final String ENV_TERMUX_APP__APK_RELEASE = TERMUX_APP_ENV_PREFIX + "APK_RELEASE";
|
||||
/** Environment variable for the Termux app install path. */
|
||||
public static final String ENV_TERMUX_APP__APK_FILE = TERMUX_APP_ENV_PREFIX + "APK_FILE";
|
||||
public static final String ENV_TERMUX_APP__APK_PATH = TERMUX_APP_ENV_PREFIX + "APK_PATH";
|
||||
/** Environment variable for the Termux app is installed on external/portable storage. */
|
||||
public static final String ENV_TERMUX_APP__IS_INSTALLED_ON_EXTERNAL_STORAGE = TERMUX_APP_ENV_PREFIX + "IS_INSTALLED_ON_EXTERNAL_STORAGE";
|
||||
|
||||
/** Environment variable for the Termux app process selinux context. */
|
||||
public static final String ENV_TERMUX_APP__SE_PROCESS_CONTEXT = TERMUX_APP_ENV_PREFIX + "SE_PROCESS_CONTEXT";
|
||||
/** Environment variable for the Termux app data files selinux context. */
|
||||
public static final String ENV_TERMUX_APP__SE_FILE_CONTEXT = TERMUX_APP_ENV_PREFIX + "SE_FILE_CONTEXT";
|
||||
/** Environment variable for the Termux app seInfo tag found in selinux policy used to set app process and app data files selinux context. */
|
||||
public static final String ENV_TERMUX_APP__SE_INFO = TERMUX_APP_ENV_PREFIX + "SE_INFO";
|
||||
|
||||
/** Environment variable for the current Termux process selinux context. */
|
||||
public static final String ENV_TERMUX__SE_PROCESS_CONTEXT = TERMUX_ENV__S_TERMUX + "SE_PROCESS_CONTEXT";
|
||||
/** Environment variable for the Termux app user id. */
|
||||
public static final String ENV_TERMUX__USER_ID = TERMUX_ENV__S_TERMUX + "USER_ID";
|
||||
public static final String ENV_TERMUX_APP__USER_ID = TERMUX_APP_ENV_PREFIX + "USER_ID";
|
||||
/** Environment variable for the Termux app profile owner. */
|
||||
public static final String ENV_TERMUX__PROFILE_OWNER = TERMUX_ENV__S_TERMUX + "PROFILE_OWNER";
|
||||
public static final String ENV_TERMUX_APP__PROFILE_OWNER = TERMUX_APP_ENV_PREFIX + "PROFILE_OWNER";
|
||||
|
||||
/** Environment variable for the Termux app {@link TermuxBootstrap#TERMUX_APP_PACKAGE_MANAGER}. */
|
||||
public static final String ENV_TERMUX_APP__PACKAGE_MANAGER = TERMUX_APP_ENV_PREFIX + "PACKAGE_MANAGER";
|
||||
/** Environment variable for the Termux app {@link TermuxBootstrap#TERMUX_APP_PACKAGE_VARIANT}. */
|
||||
public static final String ENV_TERMUX_APP__PACKAGE_VARIANT = TERMUX_APP_ENV_PREFIX + "PACKAGE_VARIANT";
|
||||
/** Environment variable for the Termux app files directory. */
|
||||
public static final String ENV_TERMUX_APP__DATA_DIR = TERMUX_APP_ENV_PREFIX + "DATA_DIR";
|
||||
public static final String ENV_TERMUX_APP__LEGACY_DATA_DIR = TERMUX_APP_ENV_PREFIX + "LEGACY_DATA_DIR";
|
||||
public static final String ENV_TERMUX_APP__BUILD_DATA_DIR = TERMUX_APP_ENV_PREFIX + "BUILD_DATA_DIR";
|
||||
public static final String ENV_TERMUX_APP__FILES_DIR = TERMUX_APP_ENV_PREFIX + "FILES_DIR";
|
||||
|
||||
|
||||
/** Environment variable for the Termux app {@link TermuxAmSocketServer#getTermuxAppAMSocketServerEnabled(Context)}. */
|
||||
public static final String ENV_TERMUX_APP__AM_SOCKET_SERVER_ENABLED = TERMUX_APP_ENV_PREFIX + "AM_SOCKET_SERVER_ENABLED";
|
||||
|
|
@ -112,22 +105,21 @@ public class TermuxAppShellEnvironment {
|
|||
HashMap<String, String> environment = new HashMap<>();
|
||||
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_VERSION, PackageUtils.getVersionNameForPackage(packageInfo));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__APP_VERSION_NAME, PackageUtils.getVersionNameForPackage(packageInfo));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__APP_VERSION_CODE, String.valueOf(PackageUtils.getVersionCodeForPackage(packageInfo)));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__VERSION_NAME, PackageUtils.getVersionNameForPackage(packageInfo));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__VERSION_CODE, String.valueOf(PackageUtils.getVersionCodeForPackage(packageInfo)));
|
||||
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__PACKAGE_NAME, packageName);
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__PID, TermuxUtils.getTermuxAppPID(currentPackageContext));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX__UID, String.valueOf(PackageUtils.getUidForPackage(applicationInfo)));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__UID, String.valueOf(PackageUtils.getUidForPackage(applicationInfo)));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__TARGET_SDK, String.valueOf(PackageUtils.getTargetSDKForPackage(applicationInfo)));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__IS_DEBUGGABLE_BUILD, PackageUtils.isAppForPackageADebuggableBuild(applicationInfo));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__APK_FILE, PackageUtils.getBaseAPKPathForPackage(applicationInfo));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__APK_PATH, PackageUtils.getBaseAPKPathForPackage(applicationInfo));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__IS_INSTALLED_ON_EXTERNAL_STORAGE, PackageUtils.isAppInstalledOnExternalStorage(applicationInfo));
|
||||
|
||||
putTermuxAPKSignature(currentPackageContext, environment);
|
||||
|
||||
Context termuxPackageContext = TermuxUtils.getTermuxPackageContext(currentPackageContext);
|
||||
if (termuxPackageContext != null) {
|
||||
/*
|
||||
// An app that does not have the same sharedUserId as termux app will not be able to get
|
||||
// get termux context's classloader to get BuildConfig.TERMUX_PACKAGE_VARIANT via reflection.
|
||||
// Check TermuxBootstrap.setTermuxPackageManagerAndVariantFromTermuxApp()
|
||||
|
|
@ -135,28 +127,24 @@ public class TermuxAppShellEnvironment {
|
|||
environment.put(ENV_TERMUX_APP__PACKAGE_MANAGER, TermuxBootstrap.TERMUX_APP_PACKAGE_MANAGER.getName());
|
||||
if (TermuxBootstrap.TERMUX_APP_PACKAGE_VARIANT != null)
|
||||
environment.put(ENV_TERMUX_APP__PACKAGE_VARIANT, TermuxBootstrap.TERMUX_APP_PACKAGE_VARIANT.getName());
|
||||
*/
|
||||
|
||||
/*
|
||||
// Will not be set for plugins
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__AM_SOCKET_SERVER_ENABLED,
|
||||
TermuxAmSocketServer.getTermuxAppAMSocketServerEnabled(currentPackageContext));
|
||||
*/
|
||||
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__DATA_DIR, applicationInfo.dataDir);
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__LEGACY_DATA_DIR, "/data/data/" + applicationInfo.packageName);
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__BUILD_DATA_DIR, TermuxConstants.TERMUX_INTERNAL_PRIVATE_APP_DATA_DIR_PATH);
|
||||
String filesDirPath = currentPackageContext.getFilesDir().getAbsolutePath();
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__FILES_DIR, filesDirPath);
|
||||
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX__SE_PROCESS_CONTEXT, SELinuxUtils.getContext());
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__SE_FILE_CONTEXT, SELinuxUtils.getFileContext(applicationInfo.dataDir));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__SE_PROCESS_CONTEXT, SELinuxUtils.getContext());
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__SE_FILE_CONTEXT, SELinuxUtils.getFileContext(filesDirPath));
|
||||
|
||||
String seInfoUser = PackageUtils.getApplicationInfoSeInfoUserForPackage(applicationInfo);
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__SE_INFO, PackageUtils.getApplicationInfoSeInfoForPackage(applicationInfo) +
|
||||
(DataUtils.isNullOrEmpty(seInfoUser) ? "" : seInfoUser));
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX__USER_ID, String.valueOf(PackageUtils.getUserIdForPackage(currentPackageContext)));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX__PROFILE_OWNER, PackageUtils.getProfileOwnerPackageNameForUser(currentPackageContext));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__USER_ID, String.valueOf(PackageUtils.getUserIdForPackage(currentPackageContext)));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_TERMUX_APP__PROFILE_OWNER, PackageUtils.getProfileOwnerPackageNameForUser(currentPackageContext));
|
||||
}
|
||||
|
||||
termuxAppEnvironment = environment;
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ public class TermuxShellCommandShellEnvironment extends ShellCommandShellEnviron
|
|||
String.valueOf(TermuxShellManager.getAndIncrementAppShellNumberSinceAppStart()));
|
||||
|
||||
} else if (ExecutionCommand.Runner.TERMINAL_SESSION.equalsRunner(executionCommand.runner)) {
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_SHELL_CMD__APP_TERMINAL_SESSION_NUMBER_SINCE_BOOT,
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_SHELL_CMD__TERMINAL_SESSION_NUMBER_SINCE_BOOT,
|
||||
String.valueOf(preferences.getAndIncrementTerminalSessionNumberSinceBoot()));
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_SHELL_CMD__APP_TERMINAL_SESSION_NUMBER_SINCE_APP_START,
|
||||
ShellEnvironmentUtils.putToEnvIfSet(environment, ENV_SHELL_CMD__TERMINAL_SESSION_NUMBER_SINCE_APP_START,
|
||||
String.valueOf(TermuxShellManager.getAndIncrementTerminalSessionNumberSinceAppStart()));
|
||||
} else {
|
||||
return environment;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
package com.termux.shared.termux.shell.command.environment;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.termux.shared.android.PackageUtils;
|
||||
import com.termux.shared.errors.Error;
|
||||
import com.termux.shared.file.FileUtils;
|
||||
import com.termux.shared.logger.Logger;
|
||||
|
|
@ -74,25 +71,12 @@ public class TermuxShellEnvironment extends AndroidShellEnvironment {
|
|||
if (termuxAppEnvironment != null)
|
||||
environment.putAll(termuxAppEnvironment);
|
||||
|
||||
/*
|
||||
HashMap<String, String> termuxApiAppEnvironment = TermuxAPIShellEnvironment.getEnvironment(currentPackageContext);
|
||||
if (termuxApiAppEnvironment != null)
|
||||
environment.putAll(termuxApiAppEnvironment);
|
||||
*/
|
||||
|
||||
ApplicationInfo applicationInfo = PackageUtils.getApplicationInfoForPackage(currentPackageContext, TermuxConstants.TERMUX_PACKAGE_NAME);
|
||||
if (applicationInfo != null && !applicationInfo.enabled) {
|
||||
applicationInfo = null;
|
||||
}
|
||||
|
||||
if (applicationInfo != null) {
|
||||
environment.put("TERMUX__APPS_DIR", applicationInfo.dataDir + "/termux/apps");
|
||||
}
|
||||
environment.put("TERMUX__ROOTFS", TermuxConstants.TERMUX_FILES_DIR_PATH);
|
||||
environment.put(ENV_HOME, TermuxConstants.TERMUX_HOME_DIR_PATH);
|
||||
environment.put("TERMUX__HOME", TermuxConstants.TERMUX_HOME_DIR_PATH);
|
||||
environment.put(ENV_PREFIX, TermuxConstants.TERMUX_PREFIX_DIR_PATH);
|
||||
environment.put("TERMUX__PREFIX", TermuxConstants.TERMUX_PREFIX_DIR_PATH);
|
||||
|
||||
// If failsafe is not enabled, then we keep default PATH and TMPDIR so that system binaries can be used
|
||||
if (!isFailSafe) {
|
||||
|
|
|
|||
|
|
@ -185,12 +185,11 @@ public class ViewUtils {
|
|||
public static Point getDisplaySize( @NonNull Context context, boolean activitySize) {
|
||||
// android.view.WindowManager.getDefaultDisplay() and Display.getSize() are deprecated in
|
||||
// API 30 and give wrong values in API 30 for activitySize=false in multi-window
|
||||
androidx.window.WindowManager windowManager = new androidx.window.WindowManager(context);
|
||||
androidx.window.WindowMetrics windowMetrics;
|
||||
androidx.window.layout.WindowMetrics windowMetrics;
|
||||
if (activitySize)
|
||||
windowMetrics = windowManager.getCurrentWindowMetrics();
|
||||
windowMetrics = androidx.window.layout.WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context);
|
||||
else
|
||||
windowMetrics = windowManager.getMaximumWindowMetrics();
|
||||
windowMetrics = androidx.window.layout.WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(context);
|
||||
return new Point(windowMetrics.getBounds().width(), windowMetrics.getBounds().height());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue