diff --git a/app/src/main/java/com/termux/app/BackgroundJob.java b/app/src/main/java/com/termux/app/BackgroundJob.java
index 956c2c8d..1e8e63cd 100644
--- a/app/src/main/java/com/termux/app/BackgroundJob.java
+++ b/app/src/main/java/com/termux/app/BackgroundJob.java
@@ -19,11 +19,11 @@ import java.util.List;
*/
public final class BackgroundJob {
- private static final String LOG_TAG = "termux-job";
+ private static final String LOG_TAG = "termux-task";
final Process mProcess;
- public BackgroundJob(String cwd, String fileToExecute, final String[] args) {
+ public BackgroundJob(String cwd, String fileToExecute, final String[] args, final TermuxService service) {
String[] env = buildEnvironment(false, cwd);
if (cwd == null) cwd = TermuxService.HOME_PATH;
@@ -61,6 +61,7 @@ public final class BackgroundJob {
try {
int exitCode = mProcess.waitFor();
+ service.onBackgroundJobExited(BackgroundJob.this);
if (exitCode == 0) {
Log.i(LOG_TAG, "[" + pid + "] exited normally");
} else {
diff --git a/app/src/main/java/com/termux/app/TermuxService.java b/app/src/main/java/com/termux/app/TermuxService.java
index 25e272c1..61a9ed69 100644
--- a/app/src/main/java/com/termux/app/TermuxService.java
+++ b/app/src/main/java/com/termux/app/TermuxService.java
@@ -11,6 +11,7 @@ import android.content.res.Resources;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Binder;
+import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.util.Log;
@@ -48,12 +49,9 @@ public final class TermuxService extends Service implements SessionChangedCallba
private static final int NOTIFICATION_ID = 1337;
- /** Intent action to stop the service. */
private static final String ACTION_STOP_SERVICE = "com.termux.service_stop";
- /** Intent action to toggle the wake lock, {@link #mWakeLock}, which this service may hold. */
- private static final String ACTION_LOCK_WAKE = "com.termux.service_toggle_wake_lock";
- /** Intent action to toggle the wifi lock, {@link #mWifiLock}, which this service may hold. */
- private static final String ACTION_LOCK_WIFI = "com.termux.service_toggle_wifi_lock";
+ private static final String ACTION_LOCK_WAKE = "com.termux.service_wake_lock";
+ private static final String ACTION_UNLOCK_WAKE = "com.termux.service_wake_unlock";
/** Intent action to launch a new terminal session. Executed from TermuxWidgetProvider. */
public static final String ACTION_EXECUTE = "com.termux.service_execute";
@@ -68,6 +66,8 @@ public final class TermuxService extends Service implements SessionChangedCallba
private final IBinder mBinder = new LocalBinder();
+ private final Handler mHandler = new Handler();
+
/**
* The terminal sessions which this service manages.
*
@@ -76,9 +76,12 @@ public final class TermuxService extends Service implements SessionChangedCallba
*/
final List mTerminalSessions = new ArrayList<>();
+ final List mBackgroundTasks = new ArrayList<>();
+
/** Note that the service may often outlive the activity, so need to clear this reference. */
SessionChangedCallback mSessionChangeCallback;
+ /** The wake lock and wifi lock are always acquired and released together. */
private PowerManager.WakeLock mWakeLock;
private WifiManager.WifiLock mWifiLock;
@@ -99,21 +102,25 @@ public final class TermuxService extends Service implements SessionChangedCallba
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, EmulatorDebug.LOG_TAG);
mWakeLock.acquire();
- } else {
- mWakeLock.release();
- mWakeLock = null;
- }
- updateNotification();
- } else if (ACTION_LOCK_WIFI.equals(action)) {
- if (mWifiLock == null) {
+
WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
mWifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, EmulatorDebug.LOG_TAG);
mWifiLock.acquire();
- } else {
+ updateNotification();
+
+ updateNotification();
+ }
+ } else if (ACTION_UNLOCK_WAKE.equals(action)) {
+ if (mWakeLock != null) {
+ mWakeLock.release();
+ mWakeLock = null;
+
mWifiLock.release();
mWifiLock = null;
+ updateNotification();
+
+ updateNotification();
}
- updateNotification();
} else if (ACTION_EXECUTE.equals(action)) {
Uri executableUri = intent.getData();
String executablePath = (executableUri == null ? null : executableUri.getPath());
@@ -121,7 +128,8 @@ public final class TermuxService extends Service implements SessionChangedCallba
String cwd = intent.getStringExtra(EXTRA_CURRENT_WORKING_DIRECTORY);
if (intent.getBooleanExtra("com.termux.execute.background", false)) {
- new BackgroundJob(cwd, executablePath, arguments);
+ mBackgroundTasks.add(new BackgroundJob(cwd, executablePath, arguments, this));
+ updateNotification();
} else {
TerminalSession newSession = createTermSession(executablePath, arguments, cwd, false);
@@ -136,7 +144,7 @@ public final class TermuxService extends Service implements SessionChangedCallba
// Make the newly created session the current one to be displayed:
TermuxPreferences.storeCurrentSession(this, newSession);
- // Launch the main Termux app, which will now show to current session:
+ // Launch the main Termux app, which will now show the current session:
startActivity(new Intent(this, TermuxActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
} else if (action != null) {
@@ -160,8 +168,8 @@ public final class TermuxService extends Service implements SessionChangedCallba
/** Update the shown foreground service notification after making any changes that affect it. */
private void updateNotification() {
- if (mWakeLock == null && mWifiLock == null && getSessions().isEmpty()) {
- // Exit if we are updating after the user disabled all locks with no sessions.
+ if (mWakeLock == null && mTerminalSessions.isEmpty() && mBackgroundTasks.isEmpty()) {
+ // Exit if we are updating after the user disabled all locks with no sessions or tasks running.
stopSelf();
} else {
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).notify(NOTIFICATION_ID, buildNotification());
@@ -176,18 +184,15 @@ public final class TermuxService extends Service implements SessionChangedCallba
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notifyIntent, 0);
int sessionCount = mTerminalSessions.size();
- String contentText = sessionCount + " terminal session" + (sessionCount == 1 ? "" : "s");
-
- boolean wakeLockHeld = mWakeLock != null;
- boolean wifiLockHeld = mWifiLock != null;
- if (wakeLockHeld && wifiLockHeld) {
- contentText += " (wake&wifi lock held)";
- } else if (wakeLockHeld) {
- contentText += " (wake lock held)";
- } else if (wifiLockHeld) {
- contentText += " (wifi lock held)";
+ int taskCount = mBackgroundTasks.size();
+ String contentText = sessionCount + " session" + (sessionCount == 1 ? "" : "s");
+ if (taskCount > 0) {
+ contentText += ", " + taskCount + " task" + (taskCount == 1 ? "" : "s");
}
+ final boolean wakeLockHeld = mWakeLock != null;
+ if (wakeLockHeld) contentText += " (wake lock held)";
+
Notification.Builder builder = new Notification.Builder(this);
builder.setContentTitle(getText(R.string.application_name));
builder.setContentText(contentText);
@@ -197,7 +202,7 @@ public final class TermuxService extends Service implements SessionChangedCallba
// If holding a wake or wifi lock consider the notification of high priority since it's using power,
// otherwise use a minimal priority since this is just a background service notification:
- builder.setPriority((wakeLockHeld || wifiLockHeld) ? Notification.PRIORITY_HIGH : Notification.PRIORITY_MIN);
+ builder.setPriority((wakeLockHeld) ? Notification.PRIORITY_HIGH : Notification.PRIORITY_MIN);
// No need to show a timestamp:
builder.setShowWhen(false);
@@ -209,13 +214,13 @@ public final class TermuxService extends Service implements SessionChangedCallba
Intent exitIntent = new Intent(this, TermuxService.class).setAction(ACTION_STOP_SERVICE);
builder.addAction(android.R.drawable.ic_delete, res.getString(R.string.notification_action_exit), PendingIntent.getService(this, 0, exitIntent, 0));
- Intent toggleWakeLockIntent = new Intent(this, TermuxService.class).setAction(ACTION_LOCK_WAKE);
- builder.addAction(android.R.drawable.ic_lock_lock, res.getString(R.string.notification_action_wakelock),
- PendingIntent.getService(this, 0, toggleWakeLockIntent, 0));
-
- Intent toggleWifiLockIntent = new Intent(this, TermuxService.class).setAction(ACTION_LOCK_WIFI);
- builder.addAction(android.R.drawable.ic_lock_lock, res.getString(R.string.notification_action_wifilock),
- PendingIntent.getService(this, 0, toggleWifiLockIntent, 0));
+ String newWakeAction = wakeLockHeld ? ACTION_UNLOCK_WAKE : ACTION_LOCK_WAKE;
+ Intent toggleWakeLockIntent = new Intent(this, TermuxService.class).setAction(newWakeAction);
+ String actionTitle = res.getString(wakeLockHeld ?
+ R.string.notification_action_wake_unlock :
+ R.string.notification_action_wake_lock);
+ int actionIcon = wakeLockHeld ? android.R.drawable.ic_lock_idle_lock : android.R.drawable.ic_lock_lock;
+ builder.addAction(actionIcon, actionTitle, PendingIntent.getService(this, 0, toggleWakeLockIntent, 0));
return builder.build();
}
@@ -337,4 +342,13 @@ public final class TermuxService extends Service implements SessionChangedCallba
if (mSessionChangeCallback != null) mSessionChangeCallback.onColorsChanged(session);
}
+ public void onBackgroundJobExited(final BackgroundJob task) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mBackgroundTasks.remove(task);
+ updateNotification();
+ }
+ });
+ }
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 66496410..8caac3e6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -50,8 +50,8 @@
Install
Exit
- Wake
- Wifi
+ Acquire wakelock
+ Release wakelock
Save file in ~/downloads/
Edit