Skip to content

Fix: terminal freezes when activity is destroyed while new instance already bound#5094

Open
Frodotus wants to merge 1 commit into
termux:masterfrom
Frodotus:fix/terminal-freeze-on-activity-recreate
Open

Fix: terminal freezes when activity is destroyed while new instance already bound#5094
Frodotus wants to merge 1 commit into
termux:masterfrom
Frodotus:fix/terminal-freeze-on-activity-recreate

Conversation

@Frodotus
Copy link
Copy Markdown

Summary

When the activity is recreated — either after recreate() (e.g. theme/style reload) or when Termux is used as a home launcher and a new instance starts after Exit — the new TermuxActivity can bind to the service and call setTermuxTerminalSessionClient() before the old activity's onDestroy() runs.

The old onDestroy() then calls unsetTermuxTerminalSessionClient() unconditionally, replacing the new activity's session client with the no-op TermuxTerminalSessionServiceClient. This causes onTextChanged() to stop triggering terminal redraws — the terminal appears completely frozen until the app is force-stopped.

Root cause

TermuxActivity.onDestroy():

mTermuxService.unsetTermuxTerminalSessionClient(); // unconditional

Android's lifecycle guarantees the new instance reaches onResume() before the old one's onDestroy() fires. onServiceConnected() (which calls setTermuxTerminalSessionClient()) is delivered on the main thread shortly after bindService() in onCreate(), so it reliably arrives before onDestroy() of the outgoing activity.

Fix

Add a guarded overload unsetTermuxTerminalSessionClient(client) that only unsets if the stored client still matches the caller. Use it from onDestroy() instead of the unconditional version.

Reproduction

Reliable: configure Termux as a home launcher, tap "Exit" in the notification. The restarted terminal will be completely frozen (no output rendered). Toggling the soft keyboard or extra-keys bar forces a single redraw but the freeze persists until force-stop.

The same race occurs on any theme-reload that calls recreate().

…lready bound

When the activity is recreated (e.g. on theme reload or home-launcher
restart after Exit), the new TermuxActivity can bind to the service and
call setTermuxTerminalSessionClient() before the old activity's
onDestroy() runs. The old onDestroy() then calls
unsetTermuxTerminalSessionClient() unconditionally, replacing the new
activity's session client with the no-op service client. This causes
onTextChanged() to stop triggering terminal redraws, freezing the
terminal until the app is force-stopped.

Fix by passing the calling activity's own client to a new guarded
overload of unsetTermuxTerminalSessionClient() that skips the unset if
another activity has already taken over the client slot.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant