mirror of
https://github.com/fankes/termux-app.git
synced 2025-09-07 03:05:18 +08:00
Keep track of background tasks
Also merge wake lock and wifi lock into one, and make it exposed to termux-wake-lock and termux-wake-unlock commands.
This commit is contained in:
@@ -19,11 +19,11 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public final class BackgroundJob {
|
public final class BackgroundJob {
|
||||||
|
|
||||||
private static final String LOG_TAG = "termux-job";
|
private static final String LOG_TAG = "termux-task";
|
||||||
|
|
||||||
final Process mProcess;
|
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);
|
String[] env = buildEnvironment(false, cwd);
|
||||||
if (cwd == null) cwd = TermuxService.HOME_PATH;
|
if (cwd == null) cwd = TermuxService.HOME_PATH;
|
||||||
|
|
||||||
@@ -61,6 +61,7 @@ public final class BackgroundJob {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
int exitCode = mProcess.waitFor();
|
int exitCode = mProcess.waitFor();
|
||||||
|
service.onBackgroundJobExited(BackgroundJob.this);
|
||||||
if (exitCode == 0) {
|
if (exitCode == 0) {
|
||||||
Log.i(LOG_TAG, "[" + pid + "] exited normally");
|
Log.i(LOG_TAG, "[" + pid + "] exited normally");
|
||||||
} else {
|
} else {
|
||||||
|
@@ -11,6 +11,7 @@ import android.content.res.Resources;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -48,12 +49,9 @@ public final class TermuxService extends Service implements SessionChangedCallba
|
|||||||
|
|
||||||
private static final int NOTIFICATION_ID = 1337;
|
private static final int NOTIFICATION_ID = 1337;
|
||||||
|
|
||||||
/** Intent action to stop the service. */
|
|
||||||
private static final String ACTION_STOP_SERVICE = "com.termux.service_stop";
|
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_wake_lock";
|
||||||
private static final String ACTION_LOCK_WAKE = "com.termux.service_toggle_wake_lock";
|
private static final String ACTION_UNLOCK_WAKE = "com.termux.service_wake_unlock";
|
||||||
/** 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";
|
|
||||||
/** Intent action to launch a new terminal session. Executed from TermuxWidgetProvider. */
|
/** Intent action to launch a new terminal session. Executed from TermuxWidgetProvider. */
|
||||||
public static final String ACTION_EXECUTE = "com.termux.service_execute";
|
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 IBinder mBinder = new LocalBinder();
|
||||||
|
|
||||||
|
private final Handler mHandler = new Handler();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The terminal sessions which this service manages.
|
* The terminal sessions which this service manages.
|
||||||
* <p/>
|
* <p/>
|
||||||
@@ -76,9 +76,12 @@ public final class TermuxService extends Service implements SessionChangedCallba
|
|||||||
*/
|
*/
|
||||||
final List<TerminalSession> mTerminalSessions = new ArrayList<>();
|
final List<TerminalSession> mTerminalSessions = new ArrayList<>();
|
||||||
|
|
||||||
|
final List<BackgroundJob> mBackgroundTasks = new ArrayList<>();
|
||||||
|
|
||||||
/** Note that the service may often outlive the activity, so need to clear this reference. */
|
/** Note that the service may often outlive the activity, so need to clear this reference. */
|
||||||
SessionChangedCallback mSessionChangeCallback;
|
SessionChangedCallback mSessionChangeCallback;
|
||||||
|
|
||||||
|
/** The wake lock and wifi lock are always acquired and released together. */
|
||||||
private PowerManager.WakeLock mWakeLock;
|
private PowerManager.WakeLock mWakeLock;
|
||||||
private WifiManager.WifiLock mWifiLock;
|
private WifiManager.WifiLock mWifiLock;
|
||||||
|
|
||||||
@@ -99,21 +102,25 @@ public final class TermuxService extends Service implements SessionChangedCallba
|
|||||||
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
|
||||||
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, EmulatorDebug.LOG_TAG);
|
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, EmulatorDebug.LOG_TAG);
|
||||||
mWakeLock.acquire();
|
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);
|
WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
|
||||||
mWifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, EmulatorDebug.LOG_TAG);
|
mWifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, EmulatorDebug.LOG_TAG);
|
||||||
mWifiLock.acquire();
|
mWifiLock.acquire();
|
||||||
} else {
|
updateNotification();
|
||||||
|
|
||||||
|
updateNotification();
|
||||||
|
}
|
||||||
|
} else if (ACTION_UNLOCK_WAKE.equals(action)) {
|
||||||
|
if (mWakeLock != null) {
|
||||||
|
mWakeLock.release();
|
||||||
|
mWakeLock = null;
|
||||||
|
|
||||||
mWifiLock.release();
|
mWifiLock.release();
|
||||||
mWifiLock = null;
|
mWifiLock = null;
|
||||||
|
updateNotification();
|
||||||
|
|
||||||
|
updateNotification();
|
||||||
}
|
}
|
||||||
updateNotification();
|
|
||||||
} else if (ACTION_EXECUTE.equals(action)) {
|
} else if (ACTION_EXECUTE.equals(action)) {
|
||||||
Uri executableUri = intent.getData();
|
Uri executableUri = intent.getData();
|
||||||
String executablePath = (executableUri == null ? null : executableUri.getPath());
|
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);
|
String cwd = intent.getStringExtra(EXTRA_CURRENT_WORKING_DIRECTORY);
|
||||||
|
|
||||||
if (intent.getBooleanExtra("com.termux.execute.background", false)) {
|
if (intent.getBooleanExtra("com.termux.execute.background", false)) {
|
||||||
new BackgroundJob(cwd, executablePath, arguments);
|
mBackgroundTasks.add(new BackgroundJob(cwd, executablePath, arguments, this));
|
||||||
|
updateNotification();
|
||||||
} else {
|
} else {
|
||||||
TerminalSession newSession = createTermSession(executablePath, arguments, cwd, false);
|
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:
|
// Make the newly created session the current one to be displayed:
|
||||||
TermuxPreferences.storeCurrentSession(this, newSession);
|
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));
|
startActivity(new Intent(this, TermuxActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||||
}
|
}
|
||||||
} else if (action != null) {
|
} 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. */
|
/** Update the shown foreground service notification after making any changes that affect it. */
|
||||||
private void updateNotification() {
|
private void updateNotification() {
|
||||||
if (mWakeLock == null && mWifiLock == null && getSessions().isEmpty()) {
|
if (mWakeLock == null && mTerminalSessions.isEmpty() && mBackgroundTasks.isEmpty()) {
|
||||||
// Exit if we are updating after the user disabled all locks with no sessions.
|
// Exit if we are updating after the user disabled all locks with no sessions or tasks running.
|
||||||
stopSelf();
|
stopSelf();
|
||||||
} else {
|
} else {
|
||||||
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).notify(NOTIFICATION_ID, buildNotification());
|
((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);
|
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notifyIntent, 0);
|
||||||
|
|
||||||
int sessionCount = mTerminalSessions.size();
|
int sessionCount = mTerminalSessions.size();
|
||||||
String contentText = sessionCount + " terminal session" + (sessionCount == 1 ? "" : "s");
|
int taskCount = mBackgroundTasks.size();
|
||||||
|
String contentText = sessionCount + " session" + (sessionCount == 1 ? "" : "s");
|
||||||
boolean wakeLockHeld = mWakeLock != null;
|
if (taskCount > 0) {
|
||||||
boolean wifiLockHeld = mWifiLock != null;
|
contentText += ", " + taskCount + " task" + (taskCount == 1 ? "" : "s");
|
||||||
if (wakeLockHeld && wifiLockHeld) {
|
|
||||||
contentText += " (wake&wifi lock held)";
|
|
||||||
} else if (wakeLockHeld) {
|
|
||||||
contentText += " (wake lock held)";
|
|
||||||
} else if (wifiLockHeld) {
|
|
||||||
contentText += " (wifi lock held)";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final boolean wakeLockHeld = mWakeLock != null;
|
||||||
|
if (wakeLockHeld) contentText += " (wake lock held)";
|
||||||
|
|
||||||
Notification.Builder builder = new Notification.Builder(this);
|
Notification.Builder builder = new Notification.Builder(this);
|
||||||
builder.setContentTitle(getText(R.string.application_name));
|
builder.setContentTitle(getText(R.string.application_name));
|
||||||
builder.setContentText(contentText);
|
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,
|
// 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:
|
// 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:
|
// No need to show a timestamp:
|
||||||
builder.setShowWhen(false);
|
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);
|
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));
|
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);
|
String newWakeAction = wakeLockHeld ? ACTION_UNLOCK_WAKE : ACTION_LOCK_WAKE;
|
||||||
builder.addAction(android.R.drawable.ic_lock_lock, res.getString(R.string.notification_action_wakelock),
|
Intent toggleWakeLockIntent = new Intent(this, TermuxService.class).setAction(newWakeAction);
|
||||||
PendingIntent.getService(this, 0, toggleWakeLockIntent, 0));
|
String actionTitle = res.getString(wakeLockHeld ?
|
||||||
|
R.string.notification_action_wake_unlock :
|
||||||
Intent toggleWifiLockIntent = new Intent(this, TermuxService.class).setAction(ACTION_LOCK_WIFI);
|
R.string.notification_action_wake_lock);
|
||||||
builder.addAction(android.R.drawable.ic_lock_lock, res.getString(R.string.notification_action_wifilock),
|
int actionIcon = wakeLockHeld ? android.R.drawable.ic_lock_idle_lock : android.R.drawable.ic_lock_lock;
|
||||||
PendingIntent.getService(this, 0, toggleWifiLockIntent, 0));
|
builder.addAction(actionIcon, actionTitle, PendingIntent.getService(this, 0, toggleWakeLockIntent, 0));
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
@@ -337,4 +342,13 @@ public final class TermuxService extends Service implements SessionChangedCallba
|
|||||||
if (mSessionChangeCallback != null) mSessionChangeCallback.onColorsChanged(session);
|
if (mSessionChangeCallback != null) mSessionChangeCallback.onColorsChanged(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onBackgroundJobExited(final BackgroundJob task) {
|
||||||
|
mHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mBackgroundTasks.remove(task);
|
||||||
|
updateNotification();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -50,8 +50,8 @@
|
|||||||
<string name="styling_install">Install</string>
|
<string name="styling_install">Install</string>
|
||||||
|
|
||||||
<string name="notification_action_exit">Exit</string>
|
<string name="notification_action_exit">Exit</string>
|
||||||
<string name="notification_action_wakelock">Wake</string>
|
<string name="notification_action_wake_lock">Acquire wakelock</string>
|
||||||
<string name="notification_action_wifilock">Wifi</string>
|
<string name="notification_action_wake_unlock">Release wakelock</string>
|
||||||
|
|
||||||
<string name="file_received_title">Save file in ~/downloads/</string>
|
<string name="file_received_title">Save file in ~/downloads/</string>
|
||||||
<string name="file_received_edit_button">Edit</string>
|
<string name="file_received_edit_button">Edit</string>
|
||||||
|
Reference in New Issue
Block a user