32
32
import com .termux .app .utils .TextDataUtils ;
33
33
import com .termux .models .ExecutionCommand ;
34
34
import com .termux .models .ExecutionCommand .ExecutionState ;
35
+ import com .termux .app .terminal .TermuxTask ;
35
36
import com .termux .terminal .TerminalEmulator ;
36
37
import com .termux .terminal .TerminalSession ;
37
38
import com .termux .terminal .TerminalSessionClient ;
@@ -71,17 +72,17 @@ class LocalBinder extends Binder {
71
72
private final Handler mHandler = new Handler ();
72
73
73
74
/**
74
- * The termux sessions which this service manages.
75
+ * The foreground termux sessions which this service manages.
75
76
* Note that this list is observed by {@link TermuxActivity#mTermuxSessionListViewController},
76
77
* so any changes must be made on the UI thread and followed by a call to
77
78
* {@link ArrayAdapter#notifyDataSetChanged()} }.
78
79
*/
79
80
final List <TermuxSession > mTermuxSessions = new ArrayList <>();
80
81
81
82
/**
82
- * The background jobs which this service manages.
83
+ * The background termux tasks which this service manages.
83
84
*/
84
- final List <BackgroundJob > mBackgroundTasks = new ArrayList <>();
85
+ final List <TermuxTask > mTermuxTasks = new ArrayList <>();
85
86
86
87
/** The full implementation of the {@link TerminalSessionClient} interface to be used by {@link TerminalSession}
87
88
* that holds activity references for activity related functions.
@@ -204,15 +205,24 @@ private void requestStopService() {
204
205
stopSelf ();
205
206
}
206
207
207
-
208
-
209
208
/** Process action to stop service. */
210
209
private void actionStopService () {
211
210
mWantsToStop = true ;
212
211
finishAllTermuxSessions ();
213
212
requestStopService ();
214
213
}
215
214
215
+ /** Finish all termux sessions by sending SIGKILL to their shells. */
216
+ private synchronized void finishAllTermuxSessions () {
217
+ // TODO: Should SIGKILL also be send to background processes maintained by mTermuxTasks?
218
+ for (int i = 0 ; i < mTermuxSessions .size (); i ++)
219
+ mTermuxSessions .get (i ).getTerminalSession ().finishIfRunning ();
220
+ }
221
+
222
+
223
+
224
+
225
+
216
226
/** Process action to acquire Power and Wi-Fi WakeLocks. */
217
227
@ SuppressLint ({"WakelockTimeout" , "BatteryLife" })
218
228
private void actionAcquireWakeLock () {
@@ -306,36 +316,72 @@ private void actionServiceExecute(Intent intent) {
306
316
executionCommand .pluginPendingIntent = intent .getParcelableExtra (TERMUX_SERVICE .EXTRA_PENDING_INTENT );
307
317
308
318
if (executionCommand .inBackground ) {
309
- executeBackgroundCommand (executionCommand );
319
+ executeTermuxTaskCommand (executionCommand );
310
320
} else {
311
321
executeTermuxSessionCommand (executionCommand );
312
322
}
313
323
}
314
324
315
- /** Execute a shell command in background with {@link BackgroundJob}. */
316
- private void executeBackgroundCommand (ExecutionCommand executionCommand ) {
325
+
326
+
327
+
328
+
329
+ /** Execute a shell command in background {@link TermuxTask}. */
330
+ private void executeTermuxTaskCommand (ExecutionCommand executionCommand ) {
317
331
if (executionCommand == null ) return ;
318
-
319
- Logger .logDebug (LOG_TAG , "Starting background command" );
332
+
333
+ Logger .logDebug (LOG_TAG , "Starting background termux task command" );
334
+
335
+ TermuxTask newTermuxTask = createTermuxTask (executionCommand );
336
+ }
337
+
338
+ /** Create a {@link TermuxTask}. */
339
+ @ Nullable
340
+ public TermuxTask createTermuxTask (String executablePath , String [] arguments , String workingDirectory ) {
341
+ return createTermuxTask (new ExecutionCommand (getNextExecutionId (), executablePath , arguments , workingDirectory , true , false ));
342
+ }
343
+
344
+ /** Create a {@link TermuxTask}. */
345
+ @ Nullable
346
+ public synchronized TermuxTask createTermuxTask (ExecutionCommand executionCommand ) {
347
+ if (executionCommand == null ) return null ;
348
+
349
+ Logger .logDebug (LOG_TAG , "Creating termux task" );
350
+
351
+ if (!executionCommand .inBackground ) {
352
+ Logger .logDebug (LOG_TAG , "Ignoring a foreground execution command passed to createTermuxTask()" );
353
+ return null ;
354
+ }
320
355
321
356
if (Logger .getLogLevel () >= Logger .LOG_LEVEL_VERBOSE )
322
357
Logger .logVerbose (LOG_TAG , executionCommand .toString ());
323
358
324
- BackgroundJob task = new BackgroundJob (executionCommand , this );
359
+ TermuxTask newTermuxTask = TermuxTask .create (this , executionCommand );
360
+ if (newTermuxTask == null ) {
361
+ // Logger.logError(LOG_TAG, "Failed to execute new termux task command for:\n" + executionCommand.toString());
362
+ return null ;
363
+ };
364
+
365
+ mTermuxTasks .add (newTermuxTask );
325
366
326
- mBackgroundTasks .add (task );
327
367
updateNotification ();
368
+
369
+ return newTermuxTask ;
328
370
}
329
371
330
- /** Callback received when a {@link BackgroundJob } finishes. */
331
- public void onBackgroundJobExited (final BackgroundJob task ) {
372
+ /** Callback received when a {@link TermuxTask } finishes. */
373
+ public synchronized void onTermuxTaskExited (final TermuxTask task ) {
332
374
mHandler .post (() -> {
333
- mBackgroundTasks .remove (task );
375
+ mTermuxTasks .remove (task );
334
376
updateNotification ();
335
377
});
336
378
}
337
379
338
- /** Execute a shell command in a foreground terminal session. */
380
+
381
+
382
+
383
+
384
+ /** Execute a shell command in a foreground {@link TermuxSession}. */
339
385
private void executeTermuxSessionCommand (ExecutionCommand executionCommand ) {
340
386
if (executionCommand == null ) return ;
341
387
@@ -357,15 +403,15 @@ private void executeTermuxSessionCommand(ExecutionCommand executionCommand) {
357
403
}
358
404
359
405
/**
360
- * Create a termux session .
406
+ * Create a {@link TermuxSession} .
361
407
* Currently called by {@link TermuxSessionClient#addNewSession(boolean, String)} to add a new termux session.
362
408
*/
363
409
@ Nullable
364
410
public TermuxSession createTermuxSession (String executablePath , String [] arguments , String workingDirectory , boolean isFailSafe , String sessionName ) {
365
411
return createTermuxSession (new ExecutionCommand (getNextExecutionId (), executablePath , arguments , workingDirectory , false , isFailSafe ), sessionName );
366
412
}
367
413
368
- /** Create a termux session . */
414
+ /** Create a {@link TermuxSession} . */
369
415
@ Nullable
370
416
public synchronized TermuxSession createTermuxSession (ExecutionCommand executionCommand , String sessionName ) {
371
417
if (executionCommand == null ) return null ;
@@ -428,11 +474,7 @@ public synchronized int removeTermuxSession(TerminalSession sessionToRemove) {
428
474
return index ;
429
475
}
430
476
431
- /** Finish all termux sessions by sending SIGKILL to their shells. */
432
- private synchronized void finishAllTermuxSessions () {
433
- for (int i = 0 ; i < mTermuxSessions .size (); i ++)
434
- mTermuxSessions .get (i ).getTerminalSession ().finishIfRunning ();
435
- }
477
+
436
478
437
479
438
480
@@ -473,6 +515,10 @@ private void startTermuxActivity() {
473
515
startActivity (new Intent (this , TermuxActivity .class ).addFlags (Intent .FLAG_ACTIVITY_NEW_TASK ));
474
516
}
475
517
518
+
519
+
520
+
521
+
476
522
/** If {@link TermuxActivity} has not bound to the {@link TermuxService} yet or is destroyed, then
477
523
* interface functions requiring the activity should not be available to the terminal sessions,
478
524
* so we just return the {@link #mTermuxSessionClientBase}. Once {@link TermuxActivity} bind
@@ -519,6 +565,8 @@ public synchronized void unsetTermuxSessionClient() {
519
565
520
566
521
567
568
+
569
+
522
570
private Notification buildNotification () {
523
571
Intent notifyIntent = new Intent (this , TermuxActivity .class );
524
572
// PendingIntent#getActivity(): "Note that the activity will be started outside of the context of an existing
@@ -527,7 +575,7 @@ private Notification buildNotification() {
527
575
PendingIntent pendingIntent = PendingIntent .getActivity (this , 0 , notifyIntent , 0 );
528
576
529
577
int sessionCount = getTermuxSessionsSize ();
530
- int taskCount = mBackgroundTasks .size ();
578
+ int taskCount = mTermuxTasks .size ();
531
579
String contentText = sessionCount + " session" + (sessionCount == 1 ? "" : "s" );
532
580
if (taskCount > 0 ) {
533
581
contentText += ", " + taskCount + " task" + (taskCount == 1 ? "" : "s" );
@@ -587,7 +635,7 @@ private void setupNotificationChannel() {
587
635
588
636
/** Update the shown foreground service notification after making any changes that affect it. */
589
637
void updateNotification () {
590
- if (mWakeLock == null && mTermuxSessions .isEmpty () && mBackgroundTasks .isEmpty ()) {
638
+ if (mWakeLock == null && mTermuxSessions .isEmpty () && mTermuxTasks .isEmpty ()) {
591
639
// Exit if we are updating after the user disabled all locks with no sessions or tasks running.
592
640
requestStopService ();
593
641
} else {
@@ -597,6 +645,8 @@ void updateNotification() {
597
645
598
646
599
647
648
+
649
+
600
650
private void setCurrentStoredTerminalSession (TerminalSession session ) {
601
651
if (session == null ) return ;
602
652
// Make the newly created session the current one to be displayed:
0 commit comments