From 4e7e4750b4a709e361917d0e615c4b6be4572407 Mon Sep 17 00:00:00 2001 From: "Luis Guzman (AppDevForAll)" Date: Wed, 19 Aug 2026 05:22:48 -0600 Subject: [PATCH 1/2] ADFA-5192 refactor(terminal): re-home the Debian terminal into TerminalActivity --- controller/app/src/main/AndroidManifest.xml | 11 ++ .../org/iiab/controller/TerminalActivity.java | 118 ++++++++++++++++++ .../controller/TerminalSessionService.java | 9 +- .../redesign/SettingsSubFragment.java | 7 +- .../src/main/res/layout/terminal_activity.xml | 117 +++++++++++++++++ 5 files changed, 252 insertions(+), 10 deletions(-) create mode 100644 controller/app/src/main/java/org/iiab/controller/TerminalActivity.java create mode 100644 controller/app/src/main/res/layout/terminal_activity.xml diff --git a/controller/app/src/main/AndroidManifest.xml b/controller/app/src/main/AndroidManifest.xml index 7d264777a..12278a572 100644 --- a/controller/app/src/main/AndroidManifest.xml +++ b/controller/app/src/main/AndroidManifest.xml @@ -70,6 +70,17 @@ adjustPan, so the IME covered the ExtraKeys bar and the text stuck. adjustResize shrinks the window so the extra-keys bar + terminal sit above the keyboard. --> + + + terminalController.openFullTerminal(); + if (root != null) root.post(open); + else open.run(); + } + + /** + * Swiping the terminal sheet down finishes back to the caller instead of exposing an + * empty surface. Mirrors MainActivity.attachTerminalOnlyFinish (ADFA-4987): no peek + * stop — a swipe-down goes straight to HIDDEN -> finish(). + */ + private void attachFinishOnHide() { + View sheet = findViewById(R.id.terminal_bottom_sheet); + if (sheet == null) return; + BottomSheetBehavior b = BottomSheetBehavior.from(sheet); + b.setHideable(true); + b.setSkipCollapsed(true); + b.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { + @Override + public void onStateChanged(@NonNull View bottomSheet, int newState) { + if (newState == BottomSheetBehavior.STATE_HIDDEN) { + finish(); + } + } + + @Override + public void onSlide(@NonNull View bottomSheet, float slideOffset) { } + }); + } + + @Override + protected void onDestroy() { + // Release the terminal UI delegate so the app-scoped session store never holds a + // destroyed Activity; running sessions keep going (ADFA-4696). + if (terminalController != null) terminalController.detach(); + super.onDestroy(); + } + + // --- TerminalController.Host --------------------------------------------- + @Override + public void addToLog(String message) { + // Single source of truth; the Usage console observes LogRepository (ADFA-4640). + LogRepository.get().append(message); + } + + @Override + public void vibrateDevice() { + android.os.Vibrator v = (android.os.Vibrator) getSystemService(Context.VIBRATOR_SERVICE); + if (v != null && v.hasVibrator()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + v.vibrate(android.os.VibrationEffect.createOneShot(50, android.os.VibrationEffect.DEFAULT_AMPLITUDE)); + } else { + v.vibrate(50); + } + } + } +} diff --git a/controller/app/src/main/java/org/iiab/controller/TerminalSessionService.java b/controller/app/src/main/java/org/iiab/controller/TerminalSessionService.java index e7a795e3d..fbc9bbb88 100644 --- a/controller/app/src/main/java/org/iiab/controller/TerminalSessionService.java +++ b/controller/app/src/main/java/org/iiab/controller/TerminalSessionService.java @@ -93,11 +93,10 @@ CHANNEL_ID, getString(R.string.terminal_channel_name), } private Notification buildNotification() { - // Tapping the notification opens the terminal directly, bypassing the hidden - // version-footer gesture (ADFA-4696). SINGLE_TOP reuses the running Activity. - Intent open = new Intent(this, MainActivity.class) - .putExtra(MainActivity.EXTRA_OPEN_TERMINAL, true) - .putExtra(MainActivity.EXTRA_TERMINAL_ONLY, true) + // Tapping the notification opens the terminal directly (ADFA-4696). ADFA-5192: the terminal + // is its own Activity now, so no terminal-only extras are needed. SINGLE_TOP reuses the + // running instance. + Intent open = new Intent(this, TerminalActivity.class) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pending = PendingIntent.getActivity( this, 0, open, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); diff --git a/controller/app/src/main/java/org/iiab/controller/redesign/SettingsSubFragment.java b/controller/app/src/main/java/org/iiab/controller/redesign/SettingsSubFragment.java index 6761ee648..3570948dc 100644 --- a/controller/app/src/main/java/org/iiab/controller/redesign/SettingsSubFragment.java +++ b/controller/app/src/main/java/org/iiab/controller/redesign/SettingsSubFragment.java @@ -205,12 +205,9 @@ private void openAppSettings(Context ctx) { } catch (Exception ignore) { /* no-op */ } } - /** The full Debian terminal lives in MainActivity; EXTRA_OPEN_TERMINAL opens it directly. */ + /** The full Debian terminal lives in its own TerminalActivity (ADFA-5192). */ private void openTerminal(Context ctx) { - Intent i = new Intent(ctx, org.iiab.controller.MainActivity.class); - i.putExtra(org.iiab.controller.MainActivity.EXTRA_OPEN_TERMINAL, true); - i.putExtra(org.iiab.controller.MainActivity.EXTRA_TERMINAL_ONLY, true); - ctx.startActivity(i); + ctx.startActivity(new Intent(ctx, org.iiab.controller.TerminalActivity.class)); } // ---- Advanced (power-user features — preview for now) ---- diff --git a/controller/app/src/main/res/layout/terminal_activity.xml b/controller/app/src/main/res/layout/terminal_activity.xml new file mode 100644 index 000000000..5dd5b9c73 --- /dev/null +++ b/controller/app/src/main/res/layout/terminal_activity.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +