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:
Fredrik Fornwall
2016-12-04 04:37:13 +01:00
parent 9fe0e49473
commit 9c19540759
3 changed files with 55 additions and 40 deletions

View File

@@ -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 {

View File

@@ -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.
* <p/>
@@ -76,9 +76,12 @@ public final class TermuxService extends Service implements SessionChangedCallba
*/
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. */
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();
}
} 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();
}
});
}
}

View File

@@ -50,8 +50,8 @@
<string name="styling_install">Install</string>
<string name="notification_action_exit">Exit</string>
<string name="notification_action_wakelock">Wake</string>
<string name="notification_action_wifilock">Wifi</string>
<string name="notification_action_wake_lock">Acquire wakelock</string>
<string name="notification_action_wake_unlock">Release wakelock</string>
<string name="file_received_title">Save file in ~/downloads/</string>
<string name="file_received_edit_button">Edit</string>