1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 06:20:55 -08:00

Prevent Android OS task trimming from deleting Emacs frames

* doc/emacs/android.texi (Android Windowing): Document proviso
on Android 7.0 and later.

* java/org/gnu/emacs/EmacsActivity.java (EmacsActivity)
<timeOfLastInteraction>: New field.
(onStop, onResume): Set and clear timeOfLastInteraction.
(isReallyFinishing): New function.
(onDestroy): Don't delete frame even in the event isFinishing
returns true if more than 4 hours have elapsed since the
activity last moved into the background.
This commit is contained in:
Po Lu 2024-03-28 19:56:31 +08:00
parent 4cee95815b
commit 755665d95a
2 changed files with 66 additions and 1 deletions

View file

@ -20,9 +20,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
package org.gnu.emacs;
import java.lang.IllegalStateException;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import android.app.Activity;
import android.content.ContentResolver;
@ -31,6 +34,7 @@ import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
@ -78,6 +82,9 @@ public class EmacsActivity extends Activity
/* The last context menu to be closed. */
private static Menu lastClosedMenu;
/* The time of the most recent call to onStop. */
private static long timeOfLastInteraction;
static
{
focusedActivities = new ArrayList<EmacsActivity> ();
@ -271,6 +278,50 @@ public class EmacsActivity extends Activity
syncFullscreenWith (window);
}
@Override
public final void
onStop ()
{
timeOfLastInteraction = SystemClock.elapsedRealtime ();
super.onStop ();
}
/* Return whether the task is being finished in response to explicit
user action. That is to say, Activity.isFinished, but as
documented. */
public final boolean
isReallyFinishing ()
{
long atime, dtime;
int hours;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.NOUGAT)
return isFinishing ();
/* When the number of tasks retained in the recents list exceeds a
threshold, Android 7 and later so destroy activities in trimming
them from recents on the expiry of a timeout that isFinishing
returns true, in direct contradiction to the documentation. This
timeout is generally 6 hours, but admits of customization by
individual system distributors, so to err on the side of the
caution, the timeout Emacs applies is a more conservative figure
of 4 hours. */
if (timeOfLastInteraction == 0)
return isFinishing ();
atime = timeOfLastInteraction;
/* Compare atime with the current system time. */
dtime = SystemClock.elapsedRealtime () - atime;
if (dtime + 1000000 < TimeUnit.HOURS.toMillis (4))
return isFinishing ();
return false;
}
@Override
public final void
onDestroy ()
@ -283,7 +334,8 @@ public class EmacsActivity extends Activity
/* The activity will die shortly hereafter. If there is a window
attached, close it now. */
isMultitask = this instanceof EmacsMultitaskActivity;
manager.removeWindowConsumer (this, isMultitask || isFinishing ());
manager.removeWindowConsumer (this, (isMultitask
|| isReallyFinishing ()));
focusedActivities.remove (this);
invalidateFocus (2);
@ -340,6 +392,7 @@ public class EmacsActivity extends Activity
onResume ()
{
isPaused = false;
timeOfLastInteraction = 0;
EmacsWindowAttachmentManager.MANAGER.noticeDeiconified (this);
super.onResume ();