Android compatibility fixes

* doc/emacs/android.texi (Android Windowing): Document
restrictions on number of windows under Android 4.4 and earlier.

* java/AndroidManifest.xml.in <EmacsActivity>
<EmacsOpenActivity, EmacsMultitaskActivity>: Assign each class
of activity a unique task affinity.

* java/org/gnu/emacs/EmacsDesktopNotification.java (display1):
Remove redundant priority assignment.

* java/org/gnu/emacs/EmacsOpenActivity.java (onCreate): Handle
file URIs when processing attachments from a mailto URI, and
check for KitKat before opening content ones.

* java/org/gnu/emacs/EmacsWindow.java <pointerMap>
(figureChange): Replace coordinate HashMap with a SparseArray.

* java/org/gnu/emacs/EmacsWindowAttachmentManager.java
(registerWindow): Don't specify FLAG_ACTIVITY_NEW_DOCUMENT on
systems where it is absent.
This commit is contained in:
Po Lu 2024-03-21 14:23:40 +08:00
parent 0df28dc00e
commit ad0492c5a9
6 changed files with 70 additions and 30 deletions

View file

@ -864,6 +864,12 @@ behalf of a specific frame, Emacs deletes the frame displayed within
that window.
@end itemize
When the system predates Android 5.0, the window manager will not
accept more than one user-created Emacs window. If frame creation gives
rise to windows in excess of this limit, the window manager will
arbitrarily select one of their number to display, with the rest
remaining invisible until that window is destroyed with its frame.
@cindex windowing limitations, android
@cindex frame parameters, android
Emacs only supports a limited subset of GUI features on Android; the

View file

@ -218,6 +218,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. -->
<activity android:name="org.gnu.emacs.EmacsActivity"
android:launchMode="singleInstance"
android:taskAffinity="emacs.primary_frame"
android:windowSoftInputMode="adjustResize"
android:exported="true"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|locale|fontScale">
@ -229,7 +230,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. -->
</activity>
<activity android:name="org.gnu.emacs.EmacsOpenActivity"
android:taskAffinity="open.dialog"
android:taskAffinity="emacs.open_dialog"
android:excludeFromRecents="true"
android:exported="true">
@ -273,6 +274,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. -->
</activity>
<activity android:name="org.gnu.emacs.EmacsMultitaskActivity"
android:taskAffinity="emacs.secondary_frame"
android:windowSoftInputMode="adjustResize"
android:exported="true"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|locale|fontScale"/>

View file

@ -208,22 +208,6 @@ else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
distinct categories, but permit an importance to be
assigned to each individual notification. */
switch (importance)
{
case 2: /* IMPORTANCE_LOW */
default:
priority = Notification.PRIORITY_LOW;
break;
case 3: /* IMPORTANCE_DEFAULT */
priority = Notification.PRIORITY_DEFAULT;
break;
case 4: /* IMPORTANCE_HIGH */
priority = Notification.PRIORITY_HIGH;
break;
}
builder = new Notification.Builder (context);
builder.setContentTitle (title);
builder.setContentText (content);
@ -231,15 +215,28 @@ else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
{
switch (importance)
{
case 2: /* IMPORTANCE_LOW */
default:
priority = Notification.PRIORITY_LOW;
break;
case 3: /* IMPORTANCE_DEFAULT */
priority = Notification.PRIORITY_DEFAULT;
break;
case 4: /* IMPORTANCE_HIGH */
priority = Notification.PRIORITY_HIGH;
break;
}
builder.setPriority (priority);
insertActions (context, builder);
notification = builder.build ();
}
else
notification = builder.getNotification ();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN)
notification.priority = priority;
}
else
{

View file

@ -535,7 +535,9 @@ private class EmacsClientThread extends Thread
uri = intent.getParcelableExtra (Intent.EXTRA_STREAM);
if ((scheme = uri.getScheme ()) != null
&& scheme.equals ("content"))
&& scheme.equals ("content")
&& (Build.VERSION.SDK_INT
>= Build.VERSION_CODES.KITKAT))
{
tem1 = EmacsService.buildContentName (uri, resolver);
attachmentString = ("'(\"" + (tem1.replace ("\\", "\\\\")
@ -543,6 +545,14 @@ private class EmacsClientThread extends Thread
.replace ("$", "\\$"))
+ "\")");
}
else if (scheme != null && scheme.equals ("file"))
{
tem1 = uri.getPath ();
attachmentString = ("'(\"" + (tem1.replace ("\\", "\\\\")
.replace ("\"", "\\\"")
.replace ("$", "\\$"))
+ "\")");
}
}
else
{
@ -567,7 +577,9 @@ private class EmacsClientThread extends Thread
if (uri != null
&& (scheme = uri.getScheme ()) != null
&& scheme.equals ("content"))
&& scheme.equals ("content")
&& (Build.VERSION.SDK_INT
>= Build.VERSION_CODES.KITKAT))
{
tem1
= EmacsService.buildContentName (uri, resolver);
@ -577,6 +589,16 @@ private class EmacsClientThread extends Thread
.replace ("$", "\\$"));
builder.append ("\"");
}
else if (scheme != null
&& scheme.equals ("file"))
{
tem1 = uri.getPath ();
builder.append ("\"");
builder.append (tem1.replace ("\\", "\\\\")
.replace ("\"", "\\\"")
.replace ("$", "\\$"));
builder.append ("\"");
}
}
builder.append (")");
@ -604,7 +626,13 @@ private class EmacsClientThread extends Thread
{
fileName = null;
if (scheme.equals ("content"))
if (scheme.equals ("content")
/* Retrieving the native file descriptor of a
ParcelFileDescriptor requires Honeycomb, and
proceeding without this capability is pointless on
systems before KitKat, since Emacs doesn't support
opening content files on those. */
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
/* This is one of the annoying Android ``content''
URIs. Most of the time, there is actually an

View file

@ -23,7 +23,6 @@
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@ -50,6 +49,7 @@
import android.view.ViewManager;
import android.view.WindowManager;
import android.util.SparseArray;
import android.util.Log;
import android.os.Build;
@ -109,7 +109,7 @@ private static class Coordinate
/* Map between pointer identifiers and last known position. Used to
compute which pointer changed upon a touch event. */
private HashMap<Integer, Coordinate> pointerMap;
private SparseArray<Coordinate> pointerMap;
/* The window consumer currently attached, if it exists. */
private EmacsWindowAttachmentManager.WindowConsumer attached;
@ -166,7 +166,7 @@ private static class Coordinate
super (handle);
rect = new Rect (x, y, x + width, y + height);
pointerMap = new HashMap<Integer, Coordinate> ();
pointerMap = new SparseArray<Coordinate> ();
/* Create the view from the context's UI thread. The window is
unmapped, so the view is GONE. */
@ -1001,7 +1001,8 @@ private static class Coordinate
case MotionEvent.ACTION_CANCEL:
/* Primary pointer released with index 0. */
pointerID = event.getPointerId (0);
coordinate = pointerMap.remove (pointerID);
coordinate = pointerMap.get (pointerID);
pointerMap.delete (pointerID);
break;
case MotionEvent.ACTION_POINTER_DOWN:
@ -1020,7 +1021,8 @@ private static class Coordinate
/* Pointer removed. Remove it from the map. */
pointerIndex = event.getActionIndex ();
pointerID = event.getPointerId (pointerIndex);
coordinate = pointerMap.remove (pointerID);
coordinate = pointerMap.get (pointerID);
pointerMap.delete (pointerID);
break;
default:

View file

@ -124,10 +124,15 @@ public interface WindowConsumer
intent = new Intent (EmacsService.SERVICE,
EmacsMultitaskActivity.class);
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_DOCUMENT
| Intent.FLAG_ACTIVITY_NEW_TASK
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
/* Intent.FLAG_ACTIVITY_NEW_DOCUMENT is lamentably unavailable on
older systems than Lolipop. */
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
EmacsService.SERVICE.startActivity (intent);
else