Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [v1.0.2]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep the changelog workflow consistent with the new release heading.

CHANGELOG.md now starts with ## [v1.0.2], but CONTRIBUTING.md Lines 86-91 still instruct contributors to use ## [Unreleased]. Add a new ## [Unreleased] section above v1.0.2, or update the contributor and release-workflow instructions. Otherwise, future release notes can be omitted from the tag-specific section.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CHANGELOG.md` at line 8, Update the changelog workflow so the release heading
remains consistent with contributor guidance: add a ## [Unreleased] section
above ## [v1.0.2] in CHANGELOG.md, preserving the existing v1.0.2 notes below
it.


### Added

- **Setup permissions**: storage and notification permissions are now requested on the welcome screen during setup instead of when the terminal opens.
- **Custom bash templates**: create your own named `.bashrc` templates in Settings → Bash templates, then edit or delete them; deleting a template resets any distro using it back to its original `.bashrc`.
- **Custom bash templates**: create your own named `.bashrc` templates in Settings → Bashrc templates, then edit or delete them; deleting a template resets any distro using it back to its original `.bashrc`.
- **Custom fonts**: import your own `.ttf`/`.otf` fonts in Settings — one at a time or several at once from the storage picker — then select them from the font dropdown or the terminal's Fonts menu; custom fonts can be renamed and removed, and names default to the file name without the extension.
- **Modern back button**: the back control is now a round, theme-aware chip; it also appears on the main page and in Settings, with the same style applied in the terminal, file browser and bash templates screens.

Expand All @@ -19,6 +19,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Theme sync**: changing the theme in Settings or from the terminal's Theme menu now broadcasts the change, so the main page and every other screen repaint immediately with the selected theme.
- The terminal's Fonts menu lists imported custom fonts and refreshes every time the menu opens.
- Settings page shows version v1.0.2.
- Settings label renamed to **Bashrc templates**.
- **Toolchain**: Gradle 8.13 → 8.14.5, Kotlin 2.3.0 → 2.4.10, `compileSdk` 35 → 36; dependency updates across androidx (lifecycle 2.8.7 → 2.11.0, activity 1.9.3 → 1.13.0, material 1.12.0 → 1.14.0, constraintlayout 2.2.0 → 2.2.2, appcompat, preference, viewpager2), commons-compress 1.27.1 → 1.28.0 and xz 1.10 → 1.12; `core-ktx` pinned at 1.18.0 (1.19.0 requires AGP 9.1 and compileSdk 37).
- GitHub Actions updated: `setup-android` v3 → v4, `setup-java` v4 → v5.6.0, `gradle/actions/wrapper-validation` v3 → v6.

### Fixed

- **Android 7.0/7.1 support**: the app no longer crashes on API 24–25 at startup (`NotificationChannel` is now only created on Android 8+), and distro extraction/repair no longer calls `java.nio.file` (API 26) or `Process#destroyForcibly` (API 26) unguarded — symlinks are created with `Os.symlink` (API 21+), so first-time setup and busybox repair work on Android 7+.
- CI: official Gradle wrapper jar (checksum validation was failing), compileSdk 36 for the new androidx versions, lint set to non-fatal, docs updated with the current build requirements.

## [v1.0.1]

Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ Requirements:
- JDK 17
- Android SDK with `build-tools` and platform `android-36`
(the app builds with `compileSdk 36`, `targetSdk 35`, `minSdk 24`)
- Gradle 8.13 (via the included wrapper)
- Android Gradle Plugin 8.13.2 and Kotlin 2.3.0 (declared in the root `build.gradle.kts`)
- Gradle 8.14.5 (via the included wrapper)
- Android Gradle Plugin 8.13.2 and Kotlin 2.4.10 (declared in the root `build.gradle.kts`)
- `ANDROID_HOME` (or `local.properties` pointing at your SDK)

```bash
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ Requirements:

- JDK 17
- Android SDK with `build-tools` and platform `android-36`
- Gradle 8.13 (via the included wrapper)
- Android Gradle Plugin 8.13.2, Kotlin 2.3.0 (managed by the project)
- Gradle 8.14.5 (via the included wrapper)
- Android Gradle Plugin 8.13.2, Kotlin 2.4.10 (managed by the project)

```bash
# Set ANDROID_HOME to your SDK location
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/com/redtermapp/RedTermApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class RedTermApp : Application() {
}

private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
val channel = NotificationChannel(
CHANNEL_TERMINAL,
getString(R.string.notification_channel_terminal),
Expand Down
20 changes: 12 additions & 8 deletions app/src/main/java/com/redtermapp/distro/DistroInstaller.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.redtermapp.distro

import android.content.Context
import android.os.Build
import android.util.Log
import com.redtermapp.DnsHelper
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -272,14 +273,21 @@ class DistroInstaller(private val context: Context) {
throw Exception("Native xz decompressor failed (exit $exitCode), falling back")
}
} catch (e: CancelledException) {
process.destroyForcibly()
killProcess(process)
throw e
} catch (e: Exception) {
process.destroyForcibly()
killProcess(process)
throw e
}
}

private fun killProcess(process: Process) {
process.destroy()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
process.destroyForcibly()
}
}

private fun extractWithJavaXz(
tarball: File, dest: File,
onProgress: (Progress) -> Unit
Expand Down Expand Up @@ -329,9 +337,7 @@ class DistroInstaller(private val context: Context) {
target.parentFile?.mkdirs()
try {
target.delete()
java.nio.file.Files.createSymbolicLink(
target.toPath(), java.nio.file.Paths.get(linkTarget)
)
android.system.Os.symlink(linkTarget, target.absolutePath)
} catch (e: Exception) {
Log.w("DistroInstaller", "Symlink failed ${entry.name}: ${e.message}")
}
Expand Down Expand Up @@ -527,9 +533,7 @@ class DistroInstaller(private val context: Context) {
if (!sh.exists() || !sh.canExecute()) {
sh.delete()
try {
java.nio.file.Files.createSymbolicLink(
sh.toPath(), java.nio.file.Paths.get("busybox")
)
android.system.Os.symlink("busybox", sh.absolutePath)
} catch (_: Exception) {
busybox.copyTo(sh, overwrite = true)
sh.setExecutable(true, false)
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout/activity_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="16dp"
android:text="Bash templates"
android:text="Bashrc templates"
android:textColor="?attr/terminalText"
android:textSize="14sp" />

Expand Down
Loading