diff --git a/.github/workflows/debug_build.yml b/.github/workflows/debug_build.yml index 0439523ebf..e1ea5e58f6 100644 --- a/.github/workflows/debug_build.yml +++ b/.github/workflows/debug_build.yml @@ -19,8 +19,38 @@ jobs: - name: Build run: | ./gradlew assembleDebug - - name: Store generated APK file + - name: Store generated universal APK file uses: actions/upload-artifact@v2 with: - name: termux-app - path: ./app/build/outputs/apk/debug + name: termux-app-universal + path: | + ./app/build/outputs/apk/debug/app-universal-debug.apk + ./app/build/outputs/apk/debug/output-metadata.json + - name: Store generated arm64-v8a APK file + uses: actions/upload-artifact@v2 + with: + name: termux-app-arm64-v8a + path: | + ./app/build/outputs/apk/debug/app-arm64-v8a-debug.apk + ./app/build/outputs/apk/debug/output-metadata.json + - name: Store generated armeabi-v7a APK file + uses: actions/upload-artifact@v2 + with: + name: termux-app-armeabi-v7a + path: | + ./app/build/outputs/apk/debug/app-armeabi-v7a-debug.apk + ./app/build/outputs/apk/debug/output-metadata.json + - name: Store generated x86_64 APK file + uses: actions/upload-artifact@v2 + with: + name: termux-app-x86_64 + path: | + ./app/build/outputs/apk/debug/app-x86_64-debug.apk + ./app/build/outputs/apk/debug/output-metadata.json + - name: Store generated x86 APK file + uses: actions/upload-artifact@v2 + with: + name: termux-app-x86 + path: | + ./app/build/outputs/apk/debug/app-x86-debug.apk + ./app/build/outputs/apk/debug/output-metadata.json diff --git a/.github/workflows/trigger_library_builds_on_jitpack.yml b/.github/workflows/trigger_library_builds_on_jitpack.yml new file mode 100644 index 0000000000..1cffbbf82d --- /dev/null +++ b/.github/workflows/trigger_library_builds_on_jitpack.yml @@ -0,0 +1,22 @@ +name: Trigger Termux Library Builds on Jitpack + +on: + release: + types: + - published + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Set tag + id: vars + run: echo ::set-output name=tag::${GITHUB_REF/refs\/tags\/v/} + - name: Trigger termux library builds on jitpack + env: + RELEASE_VERSION: ${{ steps.vars.outputs.tag }} + run: | + echo "Triggering termux library builds on jitpack for $RELEASE_VERSION" + curl --max-time 600 https://jitpack.io/com/termux/termux-app/terminal-emulator/$RELEASE_VERSION/terminal-emulator-$RELEASE_VERSION.pom + curl --max-time 600 https://jitpack.io/com/termux/termux-app/terminal-view/$RELEASE_VERSION/terminal-view-$RELEASE_VERSION.pom + curl --max-time 600 https://jitpack.io/com/termux/termux-app/termux-shared/$RELEASE_VERSION/termux-shared-$RELEASE_VERSION.pom diff --git a/.gitignore b/.gitignore index 5f7ee3c3dc..cb4634f567 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # Built application files build/ +release/ *.apk *.so .externalNativeBuild diff --git a/README.md b/README.md index 77f4c83657..6a17b939a4 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Quick how-to about Termux package management is available at [Package Management *** -**@termux is looking for Termux Application maintainers for implementing new features, fixing bugs and reviewing pull requests since current one (@fornwall) is inactive.** +**@termux is looking for Termux Application maintainers for implementing new features, fixing bugs and reviewing pull requests since the current one (@fornwall) is inactive.** Issue https://github.com/termux/termux-app/issues/1072 needs extra attention. @@ -48,36 +48,36 @@ The core [Termux](https://github.com/termux/termux-app) app comes with the follo Termux can be obtained through various sources listed below for **only** Android `>= 7`. Support was dropped for Android `5` and `6` on [2020-01-01](https://www.reddit.com/r/termux/comments/dnzdbs/end_of_android56_support_on_20200101/) at `v0.83`, old builds are available on [archive.org](https://archive.org/details/termux-repositories-legacy). -The APK files of different sources are signed with different signature keys. The `Termux` app and all its plugins use the same [sharedUserId](https://developer.android.com/guide/topics/manifest/manifest-element) `com.termux` and so all their APKs installed on a device must have been signed with the same signature key to work together and so they must all be installed from the same source. Do not attempt to mix them together, i.e do not try to install an app or plugin from F-Droid and another one from a different source. Android Package Manager will also normally not allow installation of APKs with a different signatures and you will get errors on installation like `App not installed`, `Failed to install due to an unknown error`, `INSTALL_FAILED_UPDATE_INCOMPATIBLE`, `INSTALL_FAILED_SHARED_USER_INCOMPATIBLE`, `signatures do not match previously installed version`, etc. This restriction can be bypassed with root or with custom roms. +The APK files of different sources are signed with different signature keys. The `Termux` app and all its plugins use the same [sharedUserId](https://developer.android.com/guide/topics/manifest/manifest-element) `com.termux` and so all their APKs installed on a device must have been signed with the same signature key to work together and so they must all be installed from the same source. Do not attempt to mix them together, i.e do not try to install an app or plugin from F-Droid and another one from a different source. Android Package Manager will also normally not allow installation of APKs with different signatures and you will get errors on installation like `App not installed`, `Failed to install due to an unknown error`, `INSTALL_FAILED_UPDATE_INCOMPATIBLE`, `INSTALL_FAILED_SHARED_USER_INCOMPATIBLE`, `signatures do not match previously installed version`, etc. This restriction can be bypassed with root or with custom roms. -If you wish to install from a different source, then you must uninstall **any and all existing Termux or its plugin app APKs** from your device first, then install all new APKs from the same new source. Check [Uninstallation](#Uninstallation) section for details. You may also want to consider [Backing up Termux](https://wiki.termux.com/wiki/Backing_up_Termux) before uninstallation. +If you wish to install from a different source, then you must uninstall **any and all existing Termux or its plugin app APKs** from your device first, then install all new APKs from the same new source. Check [Uninstallation](#Uninstallation) section for details. You may also want to consider [Backing up Termux](https://wiki.termux.com/wiki/Backing_up_Termux) before the uninstallation. ### F-Droid -Termux application can be obtained from F-Droid [here](https://f-droid.org/en/packages/com.termux/). It usually takes a few days (or even a week or more) for updates to be available on F-Droid once an update has been released on Github. F-Droid releases are built and published by F-Droid once they detect a new Github release. The Termux maintainers **do not** have any control over building and publishing of Termux app on F-Droid. Moreover, the Termux maintainers also do not have access to the APK signing keys of F-Droid releases, so we cannot release an APK ourselves on Github that would be compatible with F-Droid releases. +Termux application can be obtained from F-Droid [here](https://f-droid.org/en/packages/com.termux/). It usually takes a few days (or even a week or more) for updates to be available on F-Droid once an update has been released on Github. F-Droid releases are built and published by F-Droid once they detect a new Github release. The Termux maintainers **do not** have any control over the building and publishing of the Termux app on F-Droid. Moreover, the Termux maintainers also do not have access to the APK signing keys of F-Droid releases, so we cannot release an APK ourselves on Github that would be compatible with F-Droid releases. ### Debug Builds -For users who don't want to wait for F-Droid releases and want to try out the latest features immediately or want to test their pull requests can get the APKs from [Github Actions](https://github.com/termux/termux-app/actions) page from the workflow runs labeled `Build`. The APK will be listed under `Artifacts` section. These are published for each commit done to the repository. These APKs are [debuggable](https://developer.android.com/studio/debug) and are also not compatible with other sources. +For users who don't want to wait for F-Droid releases and want to try out the latest features immediately or want to test their pull requests can get the APKs from [Github Actions](https://github.com/termux/termux-app/actions) page from the workflow runs labelled `Build`. The APK will be listed under `Artifacts` section. These are published for each commit done to the repository. These APKs are [debuggable](https://developer.android.com/studio/debug) and are also not compatible with other sources. ### Google Playstore **(Deprecated)** **Termux and its plugins are no longer updated on [Google playstore](https://play.google.com/store/apps/details?id=com.termux) due to [android 10 issues](https://github.com/termux/termux-packages/wiki/Termux-and-Android-10).** The last version released for Android `>= 7` was `v0.101`. There are currently no immediate plans to resume updates on Google playstore. **It is highly recommended to not install Termux from playstore for now.** Any current users **should switch** to a different source like F-Droid. -If for some reason you don't want to switch, then at least check [Package Management](https://github.com/termux/termux-packages/wiki/Package-Management) to **change your mirror**, otherwise you will get **`repository is under maintenance or down`** errors when running `apt` or `pkg` commands. After that, it is also **highly advisable** to run `pkg upgrade` command to update all packages to the latest available versions, or at least update `termux-tools` package with `pkg install termux-tools` command. +If for some reason you don't want to switch, then at least check [Package Management](https://github.com/termux/termux-packages/wiki/Package-Management) to **change your mirror**, otherwise, you will get **`repository is under maintenance or down`** errors when running `apt` or `pkg` commands. After that, it is also **highly advisable** to run `pkg upgrade` command to update all packages to the latest available versions, or at least update `termux-tools` package with `pkg install termux-tools` command. ## ## Uninstallation -Uninstallation may be required if a user doesn't want Termux installed in their device anymore or is switching to a different [install source](#Installation). You may also want to consider [Backing up Termux](https://wiki.termux.com/wiki/Backing_up_Termux) before uninstallation. +Uninstallation may be required if a user doesn't want Termux installed in their device anymore or is switching to a different [install source](#Installation). You may also want to consider [Backing up Termux](https://wiki.termux.com/wiki/Backing_up_Termux) before the uninstallation. To uninstall Termux completely, you must uninstall **any and all existing Termux or its plugin app APKs** listed in [Termux App and Plugins](#Termux-App-and-Plugins). -Go to `Android Settings` -> `Applications` and then look for those apps. You can also use the search feature if its available on your device and search `termux` in the applications list. +Go to `Android Settings` -> `Applications` and then look for those apps. You can also use the search feature if it’s available on your device and search `termux` in the applications list. -Even if you think you have not installed any of the plugins, its strongly suggesting to go through the application list in Android settings and double check. +Even if you think you have not installed any of the plugins, it’s strongly suggesting to go through the application list in Android settings and double-check. ## @@ -142,6 +142,7 @@ The main ones are the following. ## For Devs and Contributors -The [termux-shared](termux-shared) library was added in [`v0.109`](https://github.com/termux/termux-app/releases/tag/v0.109). It defines shared constants and utils of Termux app and its plugins. It was created to allow for removal of all hardcoded paths in Termux app. The termux plugins will hopefully use this in future as well. If you are contributing code that is using a constant or a util that may be shared, then define it in `termux-shared` library if it currently doesn't exist and reference it from there. Update the relevant changelogs as well. Pull requests using hardcoded values **will/should not** be accepted. +The [termux-shared](termux-shared) library was added in [`v0.109`](https://github.com/termux/termux-app/releases/tag/v0.109). It defines shared constants and utils of the Termux app and its plugins. It was created to allow for the removal of all hardcoded paths in the Termux app. The termux plugins will hopefully use this in future as well. If you are contributing code that is using a constant or a util that may be shared, then define it in `termux-shared` library if it currently doesn't exist and reference it from there. Update the relevant changelogs as well. Pull requests using hardcoded values **will/should not** be accepted. The main Termux constants are defined by [`TermuxConstants`](https://github.com/termux/termux-app/blob/master/termux-shared/src/main/java/com/termux/shared/termux/TermuxConstants.java) class. It also contains information on how to fork Termux or build it with your own package name. Changing the package name will require building the bootstrap zip packages and other packages with the new `$PREFIX`, check [Building Packages](https://github.com/termux/termux-packages/wiki/Building-packages) for more info. + diff --git a/app/build.gradle b/app/build.gradle index ecee202c38..60c0514d03 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,8 +26,8 @@ android { applicationId "com.termux" minSdkVersion project.properties.minSdkVersion.toInteger() targetSdkVersion project.properties.targetSdkVersion.toInteger() - versionCode 116 - versionName "0.116" + versionCode 117 + versionName "0.117" manifestPlaceholders.TERMUX_PACKAGE_NAME = "com.termux" manifestPlaceholders.TERMUX_APP_NAME = "Termux" @@ -44,10 +44,14 @@ android { } } - ndk { - abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' + splits { + abi { + enable gradle.startParameter.taskNames.any { it.contains("Debug") } + reset () + include 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' + universalApk true + } } - } signingConfigs { diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 7365abb1dc..a01c038960 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -10,3 +10,8 @@ -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.** { *; } diff --git a/app/src/main/java/com/termux/app/RunCommandService.java b/app/src/main/java/com/termux/app/RunCommandService.java index 9817d78500..8c3fae2bcf 100644 --- a/app/src/main/java/com/termux/app/RunCommandService.java +++ b/app/src/main/java/com/termux/app/RunCommandService.java @@ -13,6 +13,7 @@ import com.termux.shared.data.DataUtils; import com.termux.shared.data.IntentUtils; import com.termux.shared.file.TermuxFileUtils; +import com.termux.shared.file.filesystem.FileType; import com.termux.shared.models.errors.Errno; import com.termux.shared.models.errors.Error; import com.termux.shared.termux.TermuxConstants; @@ -75,8 +76,7 @@ public int onStartCommand(Intent intent, int flags, int startId) { return Service.START_NOT_STICKY; } - executionCommand.executable = IntentUtils.getStringExtraIfSet(intent, RUN_COMMAND_SERVICE.EXTRA_COMMAND_PATH, null); - + String executableExtra = executionCommand.executable = IntentUtils.getStringExtraIfSet(intent, RUN_COMMAND_SERVICE.EXTRA_COMMAND_PATH, null); executionCommand.arguments = IntentUtils.getStringArrayExtraIfSet(intent, RUN_COMMAND_SERVICE.EXTRA_ARGUMENTS, null); /* @@ -176,9 +176,17 @@ public int onStartCommand(Intent intent, int flags, int startId) { } } + // If the executable passed as the extra was an applet for coreutils/busybox, then we must + // use it instead of the canonical path above since otherwise arguments would be passed to + // coreutils/busybox instead and command would fail. Broken symlinks would already have been + // validated so it should be fine to use it. + executableExtra = TermuxFileUtils.getExpandedTermuxPath(executableExtra); + if (FileUtils.getFileType(executableExtra, false) == FileType.SYMLINK) { + Logger.logVerbose(LOG_TAG, "The executableExtra path \"" + executableExtra + "\" is a symlink so using it instead of the canonical path \"" + executionCommand.executable + "\""); + executionCommand.executable = executableExtra; + } - - executionCommand.executableUri = new Uri.Builder().scheme(TERMUX_SERVICE.URI_SCHEME_SERVICE_EXECUTE).path(TermuxFileUtils.getExpandedTermuxPath(executionCommand.executable)).build(); + executionCommand.executableUri = new Uri.Builder().scheme(TERMUX_SERVICE.URI_SCHEME_SERVICE_EXECUTE).path(executionCommand.executable).build(); Logger.logVerbose(LOG_TAG, executionCommand.toString()); diff --git a/app/src/main/java/com/termux/app/TermuxActivity.java b/app/src/main/java/com/termux/app/TermuxActivity.java index 4da810f76c..729a636ae2 100644 --- a/app/src/main/java/com/termux/app/TermuxActivity.java +++ b/app/src/main/java/com/termux/app/TermuxActivity.java @@ -259,7 +259,7 @@ public void onStart() { if (mTermuxTerminalViewClient != null) mTermuxTerminalViewClient.onStart(); - if (!mProperties.isTerminalMarginAdjustmentDisabled()) + if (mPreferences.isTerminalMarginAdjustmentEnabled()) addTermuxActivityRootViewGlobalLayoutListener(); registerTermuxActivityBroadcastReceiver(); diff --git a/app/src/main/java/com/termux/app/TermuxInstaller.java b/app/src/main/java/com/termux/app/TermuxInstaller.java index 19ade92079..60c5dc00de 100644 --- a/app/src/main/java/com/termux/app/TermuxInstaller.java +++ b/app/src/main/java/com/termux/app/TermuxInstaller.java @@ -196,7 +196,7 @@ public static void showBootstrapErrorDialog(Activity activity, String PREFIX_FIL Logger.logErrorExtended(LOG_TAG, "Bootstrap Error:\n" + message); // Send a notification with the exception so that the user knows why bootstrap setup failed - CrashUtils.sendCrashReportNotification(activity, LOG_TAG, "## Bootstrap Error\n\n" + message, true); + CrashUtils.sendCrashReportNotification(activity, LOG_TAG, "## Bootstrap Error\n\n" + message, true, true); activity.runOnUiThread(() -> { try { @@ -231,7 +231,7 @@ public void run() { if (error != null) { Logger.logErrorAndShowToast(context, LOG_TAG, error.getMessage()); Logger.logErrorExtended(LOG_TAG, "Setup Storage Error\n" + error.toString()); - CrashUtils.sendCrashReportNotification(context, LOG_TAG, "## Setup Storage Error\n\n" + Error.getErrorMarkdownString(error), true); + CrashUtils.sendCrashReportNotification(context, LOG_TAG, "## Setup Storage Error\n\n" + Error.getErrorMarkdownString(error), true, true); return; } @@ -270,7 +270,7 @@ public void run() { } catch (Exception e) { Logger.logErrorAndShowToast(context, LOG_TAG, e.getMessage()); Logger.logStackTraceWithMessage(LOG_TAG, "Setup Storage Error: Error setting up link", e); - CrashUtils.sendCrashReportNotification(context, LOG_TAG, "## Setup Storage Error\n\n" + Logger.getStackTracesMarkdownString(null, Logger.getStackTracesStringArray(e)), true); + CrashUtils.sendCrashReportNotification(context, LOG_TAG, "## Setup Storage Error\n\n" + Logger.getStackTracesMarkdownString(null, Logger.getStackTracesStringArray(e)), true, true); } } }.start(); diff --git a/app/src/main/java/com/termux/app/fragments/settings/termux/TerminalViewPreferencesFragment.java b/app/src/main/java/com/termux/app/fragments/settings/termux/TerminalViewPreferencesFragment.java new file mode 100644 index 0000000000..ed10d18a5a --- /dev/null +++ b/app/src/main/java/com/termux/app/fragments/settings/termux/TerminalViewPreferencesFragment.java @@ -0,0 +1,77 @@ +package com.termux.app.fragments.settings.termux; + +import android.content.Context; +import android.os.Bundle; + +import androidx.annotation.Keep; +import androidx.preference.PreferenceDataStore; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.PreferenceManager; + +import com.termux.R; +import com.termux.shared.settings.preferences.TermuxAppSharedPreferences; + +@Keep +public class TerminalViewPreferencesFragment extends PreferenceFragmentCompat { + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + Context context = getContext(); + if (context == null) return; + + PreferenceManager preferenceManager = getPreferenceManager(); + preferenceManager.setPreferenceDataStore(TerminalViewPreferencesDataStore.getInstance(context)); + + setPreferencesFromResource(R.xml.termux_terminal_view_preferences, rootKey); + } + +} + +class TerminalViewPreferencesDataStore extends PreferenceDataStore { + + private final Context mContext; + private final TermuxAppSharedPreferences mPreferences; + + private static TerminalViewPreferencesDataStore mInstance; + + private TerminalViewPreferencesDataStore(Context context) { + mContext = context; + mPreferences = TermuxAppSharedPreferences.build(context, true); + } + + public static synchronized TerminalViewPreferencesDataStore getInstance(Context context) { + if (mInstance == null) { + mInstance = new TerminalViewPreferencesDataStore(context); + } + return mInstance; + } + + + + @Override + public void putBoolean(String key, boolean value) { + if (mPreferences == null) return; + if (key == null) return; + + switch (key) { + case "terminal_margin_adjustment": + mPreferences.setTerminalMarginAdjustment(value); + break; + default: + break; + } + } + + @Override + public boolean getBoolean(String key, boolean defValue) { + if (mPreferences == null) return false; + + switch (key) { + case "terminal_margin_adjustment": + return mPreferences.isTerminalMarginAdjustmentEnabled(); + default: + return false; + } + } + +} diff --git a/app/src/main/java/com/termux/app/terminal/TermuxTerminalViewClient.java b/app/src/main/java/com/termux/app/terminal/TermuxTerminalViewClient.java index 7b3592fb94..0853a80f26 100644 --- a/app/src/main/java/com/termux/app/terminal/TermuxTerminalViewClient.java +++ b/app/src/main/java/com/termux/app/terminal/TermuxTerminalViewClient.java @@ -484,7 +484,13 @@ public void onToggleSoftKeyboardRequest() { } public void setSoftKeyboardState(boolean isStartup, boolean isReloadTermuxProperties) { - boolean noRequestFocus = false; + boolean noShowKeyboard = false; + + // Requesting terminal view focus is necessary regardless of if soft keyboard is to be + // disabled or hidden at startup, otherwise if hardware keyboard is attached and user + // starts typing on hardware keyboard without tapping on the terminal first, then a colour + // tint will be added to the terminal as highlight for the focussed view. Test with a light + // theme. // If soft keyboard is disabled by user for Termux (check function docs for Termux behaviour info) if (KeyboardUtils.shouldSoftKeyboardBeDisabled(mActivity, @@ -492,7 +498,8 @@ public void setSoftKeyboardState(boolean isStartup, boolean isReloadTermuxProper mActivity.getPreferences().isSoftKeyboardEnabledOnlyIfNoHardware())) { Logger.logVerbose(LOG_TAG, "Maintaining disabled soft keyboard"); KeyboardUtils.disableSoftKeyboard(mActivity, mActivity.getTerminalView()); - noRequestFocus = true; + mActivity.getTerminalView().requestFocus(); + noShowKeyboard = true; // Delay is only required if onCreate() is called like when Termux app is exited with // double back press, not when Termux app is switched back from another app and keyboard // toggle is pressed to enable keyboard @@ -508,10 +515,12 @@ public void setSoftKeyboardState(boolean isStartup, boolean isReloadTermuxProper // If soft keyboard is to be hidden on startup if (isStartup && mActivity.getProperties().shouldSoftKeyboardBeHiddenOnStartup()) { Logger.logVerbose(LOG_TAG, "Hiding soft keyboard on startup"); - KeyboardUtils.hideSoftKeyboard(mActivity, mActivity.getTerminalView()); // Required to keep keyboard hidden when Termux app is switched back from another app KeyboardUtils.setSoftKeyboardAlwaysHiddenFlags(mActivity); - noRequestFocus = true; + + KeyboardUtils.hideSoftKeyboard(mActivity, mActivity.getTerminalView()); + mActivity.getTerminalView().requestFocus(); + noShowKeyboard = true; // Required to keep keyboard hidden on app startup mShowSoftKeyboardIgnoreOnce = true; } @@ -541,7 +550,7 @@ public void onFocusChange(View view, boolean hasFocus) { // Do not force show soft keyboard if termux-reload-settings command was run with hardware keyboard // or soft keyboard is to be hidden or is disabled - if (!isReloadTermuxProperties && !noRequestFocus) { + if (!isReloadTermuxProperties && !noShowKeyboard) { // Request focus for TerminalView // Also show the keyboard, since onFocusChange will not be called if TerminalView already // had focus on startup to show the keyboard, like when opening url with context menu diff --git a/app/src/main/java/com/termux/app/utils/CrashUtils.java b/app/src/main/java/com/termux/app/utils/CrashUtils.java index 1437e234ca..f9ebe779b3 100644 --- a/app/src/main/java/com/termux/app/utils/CrashUtils.java +++ b/app/src/main/java/com/termux/app/utils/CrashUtils.java @@ -20,6 +20,7 @@ import com.termux.shared.settings.preferences.TermuxPreferenceConstants; import com.termux.shared.data.DataUtils; import com.termux.shared.logger.Logger; +import com.termux.shared.termux.AndroidUtils; import com.termux.shared.termux.TermuxUtils; import com.termux.shared.termux.TermuxConstants; @@ -86,7 +87,7 @@ public void run() { Logger.logDebug(logTag, "A crash log file found at \"" + TermuxConstants.TERMUX_CRASH_LOG_FILE_PATH + "\"."); - sendCrashReportNotification(context, logTag, reportString, false); + sendCrashReportNotification(context, logTag, reportString, false, false); } }.start(); } @@ -97,13 +98,15 @@ public void run() { * * @param context The {@link Context} for operations. * @param logTag The log tag to use for logging. - * @param reportString The text for the crash report. + * @param message The message for the crash report. * @param forceNotification If set to {@code true}, then a notification will be shown * regardless of if pending intent is {@code null} or * {@link TermuxPreferenceConstants.TERMUX_APP#KEY_CRASH_REPORT_NOTIFICATIONS_ENABLED} * is {@code false}. + * @param addAppAndDeviceInfo If set to {@code true}, then app and device info will be appended + * to the message. */ - public static void sendCrashReportNotification(final Context context, String logTag, String reportString, boolean forceNotification) { + public static void sendCrashReportNotification(final Context context, String logTag, String message, boolean forceNotification, boolean addAppAndDeviceInfo) { if (context == null) return; TermuxAppSharedPreferences preferences = TermuxAppSharedPreferences.build(context); @@ -121,7 +124,14 @@ public static void sendCrashReportNotification(final Context context, String log Logger.logDebug(logTag, "Sending \"" + title + "\" notification."); - Intent notificationIntent = ReportActivity.newInstance(context, new ReportInfo(UserAction.CRASH_REPORT.getName(), logTag, title, null, reportString, "\n\n" + TermuxUtils.getReportIssueMarkdownString(context), true)); + StringBuilder reportString = new StringBuilder(message); + + if (addAppAndDeviceInfo) { + reportString.append("\n\n").append(TermuxUtils.getAppInfoMarkdownString(context, true)); + reportString.append("\n\n").append(AndroidUtils.getDeviceInfoMarkdownString(context)); + } + + Intent notificationIntent = ReportActivity.newInstance(context, new ReportInfo(UserAction.CRASH_REPORT.getName(), logTag, title, null, reportString.toString(), "\n\n" + TermuxUtils.getReportIssueMarkdownString(context), true)); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); // Setup the notification channel if not already set up diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5f396302d8..c5133bb2e0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -168,6 +168,20 @@ Soft keyboard will be enabled only if no hardware keyboard is connected. + + Terminal View + Preferences for terminal view + + + View + + + Terminal Margin Adjustment + Terminal margin adjustment will be disabled. + Terminal margin adjustment will be enabled. It should be enabled to try to fix the issue where soft keyboard covers part of extra keys/terminal view. If it causes screen flickering on your devices, then disable it. (Default) + + + &TERMUX_TASKER_APP_NAME; Preferences for &TERMUX_TASKER_APP_NAME; app diff --git a/app/src/main/res/xml/termux_preferences.xml b/app/src/main/res/xml/termux_preferences.xml index f28c775dc5..90353c51e1 100644 --- a/app/src/main/res/xml/termux_preferences.xml +++ b/app/src/main/res/xml/termux_preferences.xml @@ -10,4 +10,9 @@ app:summary="@string/termux_terminal_io_preferences_summary" app:fragment="com.termux.app.fragments.settings.termux.TerminalIOPreferencesFragment"/> + + diff --git a/app/src/main/res/xml/termux_terminal_view_preferences.xml b/app/src/main/res/xml/termux_terminal_view_preferences.xml new file mode 100644 index 0000000000..3f66863336 --- /dev/null +++ b/app/src/main/res/xml/termux_terminal_view_preferences.xml @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/terminal-emulator/build.gradle b/terminal-emulator/build.gradle index 014e3350e9..97f9ed7ea7 100644 --- a/terminal-emulator/build.gradle +++ b/terminal-emulator/build.gradle @@ -66,7 +66,7 @@ afterEvaluate { from components.release groupId = 'com.termux' artifactId = 'terminal-emulator' - version = '0.116' + version = '0.117' artifact(sourceJar) } } diff --git a/terminal-view/build.gradle b/terminal-view/build.gradle index 5c97f2cb0a..5bf11e100a 100644 --- a/terminal-view/build.gradle +++ b/terminal-view/build.gradle @@ -45,7 +45,7 @@ afterEvaluate { from components.release groupId = 'com.termux' artifactId = 'terminal-view' - version = '0.116' + version = '0.117' artifact(sourceJar) } } diff --git a/termux-shared/build.gradle b/termux-shared/build.gradle index 430762943e..34d2e7678c 100644 --- a/termux-shared/build.gradle +++ b/termux-shared/build.gradle @@ -8,7 +8,7 @@ android { implementation 'androidx.appcompat:appcompat:1.3.0' implementation "androidx.annotation:annotation:1.2.0" implementation "androidx.core:core:1.6.0-rc01" - implementation "androidx.window:window:1.0.0-alpha08" + implementation "androidx.window:window:1.0.0-alpha09" implementation "com.google.guava:guava:24.1-jre" implementation "io.noties.markwon:core:$markwonVersion" implementation "io.noties.markwon:ext-strikethrough:$markwonVersion" @@ -61,7 +61,7 @@ afterEvaluate { from components.release groupId = 'com.termux' artifactId = 'termux-shared' - version = '0.116' + version = '0.117' artifact(sourceJar) } } diff --git a/termux-shared/src/main/java/com/termux/shared/file/FileUtils.java b/termux-shared/src/main/java/com/termux/shared/file/FileUtils.java index 4bc81933b9..07179f272a 100644 --- a/termux-shared/src/main/java/com/termux/shared/file/FileUtils.java +++ b/termux-shared/src/main/java/com/termux/shared/file/FileUtils.java @@ -326,9 +326,10 @@ public static Error validateDirectoryFileExistenceAndPermissions(String label, f if (createDirectoryIfMissing && fileType == FileType.NO_EXIST) { Logger.logVerbose(LOG_TAG, "Creating " + label + "directory file at path \"" + filePath + "\""); // Create directory and update fileType if successful, otherwise return with error - if (file.mkdirs()) - fileType = getFileType(filePath, false); - else + // It "might" be possible that mkdirs returns false even though directory was created + boolean result = file.mkdirs(); + fileType = getFileType(filePath, false); + if (!result && fileType != FileType.DIRECTORY) return FileUtilsErrno.ERRNO_CREATING_FILE_FAILED.getError(label + "directory file", filePath); } diff --git a/termux-shared/src/main/java/com/termux/shared/settings/preferences/TermuxAppSharedPreferences.java b/termux-shared/src/main/java/com/termux/shared/settings/preferences/TermuxAppSharedPreferences.java index c2979ee08c..7bcf408a15 100644 --- a/termux-shared/src/main/java/com/termux/shared/settings/preferences/TermuxAppSharedPreferences.java +++ b/termux-shared/src/main/java/com/termux/shared/settings/preferences/TermuxAppSharedPreferences.java @@ -91,6 +91,16 @@ public boolean toogleShowTerminalToolbar() { + public boolean isTerminalMarginAdjustmentEnabled() { + return SharedPreferenceUtils.getBoolean(mSharedPreferences, TERMUX_APP.KEY_TERMINAL_MARGIN_ADJUSTMENT, TERMUX_APP.DEFAULT_TERMINAL_MARGIN_ADJUSTMENT); + } + + public void setTerminalMarginAdjustment(boolean value) { + SharedPreferenceUtils.setBoolean(mSharedPreferences, TERMUX_APP.KEY_TERMINAL_MARGIN_ADJUSTMENT, value, false); + } + + + public boolean isSoftKeyboardEnabled() { return SharedPreferenceUtils.getBoolean(mSharedPreferences, TERMUX_APP.KEY_SOFT_KEYBOARD_ENABLED, TERMUX_APP.DEFAULT_VALUE_KEY_SOFT_KEYBOARD_ENABLED); } diff --git a/termux-shared/src/main/java/com/termux/shared/settings/preferences/TermuxPreferenceConstants.java b/termux-shared/src/main/java/com/termux/shared/settings/preferences/TermuxPreferenceConstants.java index efec9d9863..074aa60232 100644 --- a/termux-shared/src/main/java/com/termux/shared/settings/preferences/TermuxPreferenceConstants.java +++ b/termux-shared/src/main/java/com/termux/shared/settings/preferences/TermuxPreferenceConstants.java @@ -1,7 +1,7 @@ package com.termux.shared.settings.preferences; /* - * Version: v0.10.0 + * Version: v0.11.0 * * Changelog * @@ -44,6 +44,10 @@ * - 0.10.0 (2021-05-12) * - Added following to `TERMUX_APP`: * `KEY_SOFT_KEYBOARD_ENABLED_ONLY_IF_NO_HARDWARE` and `DEFAULT_VALUE_KEY_SOFT_KEYBOARD_ENABLED_ONLY_IF_NO_HARDWARE`. + * + * - 0.11.0 (2021-07-08) + * - Added following to `TERMUX_APP`: + * `KEY_DISABLE_TERMINAL_MARGIN_ADJUSTMENT`. */ /** @@ -60,6 +64,15 @@ public final class TermuxPreferenceConstants { */ public static final class TERMUX_APP { + /** + * Defines the key for whether terminal view margin adjustment that is done to prevent soft + * keyboard from covering bottom part of terminal view on some devices is enabled or not. + * Margin adjustment may cause screen flickering on some devices and so should be disabled. + */ + public static final String KEY_TERMINAL_MARGIN_ADJUSTMENT = "terminal_margin_adjustment"; + public static final boolean DEFAULT_TERMINAL_MARGIN_ADJUSTMENT = true; + + /** * Defines the key for whether to show terminal toolbar containing extra keys and text input field. */ diff --git a/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxPropertyConstants.java b/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxPropertyConstants.java index cb3b352bea..fbc7c070ad 100644 --- a/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxPropertyConstants.java +++ b/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxPropertyConstants.java @@ -72,13 +72,6 @@ public final class TermuxPropertyConstants { /* boolean */ - /** Defines the key for whether terminal view margin adjustment that is done to prevent soft - * keyboard from covering bottom part of terminal view on some devices is disabled or not. - * Margin adjustment may cause screen flickering on some devices and so should be disabled. */ - public static final String KEY_DISABLE_TERMINAL_MARGIN_ADJUSTMENT = "disable-terminal-margin-adjustment"; // Default: "disable-terminal-margin-adjustment" - - - /** Defines the key for whether a toast will be shown when user changes the terminal session */ public static final String KEY_DISABLE_TERMINAL_SESSION_CHANGE_TOAST = "disable-terminal-session-change-toast"; // Default: "disable-terminal-session-change-toast" @@ -302,7 +295,6 @@ public final class TermuxPropertyConstants { * */ public static final Set TERMUX_PROPERTIES_LIST = new HashSet<>(Arrays.asList( /* boolean */ - KEY_DISABLE_TERMINAL_MARGIN_ADJUSTMENT, KEY_DISABLE_TERMINAL_SESSION_CHANGE_TOAST, KEY_ENFORCE_CHAR_BASED_INPUT, KEY_HIDE_SOFT_KEYBOARD_ON_STARTUP, @@ -343,7 +335,6 @@ public final class TermuxPropertyConstants { * default: false * */ public static final Set TERMUX_DEFAULT_BOOLEAN_BEHAVIOUR_PROPERTIES_LIST = new HashSet<>(Arrays.asList( - KEY_DISABLE_TERMINAL_MARGIN_ADJUSTMENT, KEY_DISABLE_TERMINAL_SESSION_CHANGE_TOAST, KEY_ENFORCE_CHAR_BASED_INPUT, KEY_HIDE_SOFT_KEYBOARD_ON_STARTUP, diff --git a/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxSharedProperties.java b/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxSharedProperties.java index 992c6f2e23..e3031764aa 100644 --- a/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxSharedProperties.java +++ b/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxSharedProperties.java @@ -460,10 +460,6 @@ public static String getVolumeKeysBehaviourInternalPropertyValueFromValue(String - public boolean isTerminalMarginAdjustmentDisabled() { - return (boolean) getInternalPropertyValue(TermuxPropertyConstants.KEY_DISABLE_TERMINAL_MARGIN_ADJUSTMENT, true); - } - public boolean areTerminalSessionChangeToastsDisabled() { return (boolean) getInternalPropertyValue(TermuxPropertyConstants.KEY_DISABLE_TERMINAL_SESSION_CHANGE_TOAST, true); }