and the window was not previously closed by the system in order to
save resources, Emacs deletes any frame displayed within that window.
+However, on Android 7.0 and later, such frames are not deleted if the
+window is closed four or more hours after the window moves into the
+background, as the system automatically removes open windows once a
+certain period of inactivity elapses when the number of windows retained
+by the window manager surpasses a specific threshold, and window
+deletion by this mechanism is indistinguishable from window deletion by
+the user. Emacs begins to ignore window deletion after two hours less
+than the default value of this threshold both to err on the side of
+caution, in case the system's record of inactivity and Emacs's differ,
+and for the reason that this threshold is open to customization by OS
+distributors.
+
@item
When the user or the system closes any window created by Emacs on
behalf of a specific frame, Emacs deletes the frame displayed within
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;
import android.os.Build;
import android.os.Bundle;
+import android.os.SystemClock;
import android.util.Log;
/* 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> ();
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 ()
/* 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);
onResume ()
{
isPaused = false;
+ timeOfLastInteraction = 0;
EmacsWindowAttachmentManager.MANAGER.noticeDeiconified (this);
super.onResume ();