1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-06 03:40:56 -08:00

Fix compatibility issues with Android clipboards

* java/org/gnu/emacs/EmacsClipboard.java (getClipboardData):
Return an AssetFileDescriptor.

* java/org/gnu/emacs/EmacsContextMenu.java (onMenuItemClick):
Typo corrections in commentary.

* java/org/gnu/emacs/EmacsOpenActivity.java (onCreate): Raise
minimum version on which to read file descriptors from
ParcelFileDescriptor objects to Honeycomb.

* java/org/gnu/emacs/EmacsSdk11Clipboard.java
(getClipboardData): Return the asset file descriptor.

* java/org/gnu/emacs/EmacsSdk8Clipboard.java (getClipboardData):
Adjust return type to match.

* src/android.h (struct android_parcel_file_descriptor_class):
Move from androidselect.c.

* src/androidselect.c (fd_class): Export function.
(android_init_emacs_clipboard): Adjust signature of
getClipboardData.
(android_init_asset_file_descriptor, close_asset_fd)
(extract_fd_offsets): New functions.
(Fandroid_get_clipboard_data): Extract file descriptor and
offset from the AssetFileDescriptor here, rather than in
getClipboardData.
(init_androidselect): Call android_init_asset_file_descriptor.

* src/androidvfs.c (android_init_fd_class): Export and enable
calling this function more than once.
This commit is contained in:
Po Lu 2024-05-01 11:45:53 +08:00
parent 294335b230
commit 2451456695
8 changed files with 251 additions and 114 deletions

View file

@ -19,6 +19,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
package org.gnu.emacs;
import android.content.res.AssetFileDescriptor;
import android.os.Build;
/* This class provides helper code for accessing the clipboard,
@ -32,7 +33,7 @@ public abstract class EmacsClipboard
public abstract byte[] getClipboard ();
public abstract byte[][] getClipboardTargets ();
public abstract long[] getClipboardData (byte[] target);
public abstract AssetFileDescriptor getClipboardData (byte[] target);
/* Create the correct kind of clipboard for this system. */

View file

@ -108,8 +108,8 @@ public final class EmacsContextMenu
will normally confuse Emacs into thinking that the
context menu has been dismissed. Wrong!
Setting this flag makes EmacsActivity to only handle
SubMenuBuilder being closed, which always means the menu
Setting this flag prompts EmacsActivity to only handle
SubMenuBuilders being closed, which always means the menu
has actually been dismissed.
However, these extraneous events aren't sent on devices

View file

@ -19,29 +19,23 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
package org.gnu.emacs;
/* This class makes the Emacs server work reasonably on Android.
/* Opening external documents on Android.
There is no way to make the Unix socket publicly available on
Android.
This activity is registered as an application capable of opening text
files and files in several other formats that Emacs understands, and
assumes responsibility for deriving file names from the files
provided to `onCreate', potentially copying them to temporary
directories in the process, and invoking `emacsclient' with suitable
arguments to open the same. In this respect, it fills the role of
`etc/emacs.desktop' on XDG systems.
Instead, this activity tries to connect to the Emacs server, to
make it open files the system asks Emacs to open, and to emulate
some reasonable behavior when Emacs has not yet started.
It is also registered as a handler for mailto URIs, in which capacity
it constructs invocations of `emacsclient' so as to start
`message-mailto' with their contents and attachments, much like
`etc/emacs-mail.desktop'.
First, Emacs registers itself as an application that can open text
and image files.
Then, when the user is asked to open a file and selects ``Emacs''
as the application that will open the file, the system pops up a
window, this activity, and calls the `onCreate' function.
`onCreate' then tries very to find the file name of the file that
was selected, and give it to emacsclient.
If emacsclient successfully opens the file, then this activity
starts EmacsActivity (to bring it on to the screen); otherwise, it
displays the output of emacsclient or any error message that occurs
and exits. */
As with all other activities, it is registered in the package
manifest file. */
import android.app.AlertDialog;
import android.app.Activity;
@ -628,11 +622,12 @@ public final class EmacsOpenActivity extends Activity
if (scheme.equals ("content")
/* Retrieving the native file descriptor of a
ParcelFileDescriptor requires Honeycomb, and
ParcelFileDescriptor requires Honeycomb MR1, 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)
&& (Build.VERSION.SDK_INT
>= Build.VERSION_CODES.HONEYCOMB_MR1))
{
/* This is one of the annoying Android ``content''
URIs. Most of the time, there is actually an

View file

@ -207,8 +207,9 @@ public final class EmacsSdk11Clipboard extends EmacsClipboard
/* Return the clipboard data for the given target, or NULL if it
does not exist.
Value is normally an array of three longs: the file descriptor,
the start offset of the data, and its length; length may be
Value is normally an asset file descriptor, which in turn holds
three important values: the file descriptor, the start offset of
the data, and its length; length may be
AssetFileDescriptor.UNKNOWN_LENGTH, meaning that the data extends
from that offset to the end of the file.
@ -217,15 +218,13 @@ public final class EmacsSdk11Clipboard extends EmacsClipboard
solely of a URI. */
@Override
public long[]
public AssetFileDescriptor
getClipboardData (byte[] target)
{
ClipData data;
String mimeType;
int fd;
AssetFileDescriptor assetFd;
Uri uri;
long[] value;
/* Decode the target given by Emacs. */
try
@ -245,8 +244,6 @@ public final class EmacsSdk11Clipboard extends EmacsClipboard
if (data == null || data.getItemCount () < 1)
return null;
fd = -1;
try
{
uri = data.getItemAt (0).getUri ();
@ -257,52 +254,15 @@ public final class EmacsSdk11Clipboard extends EmacsClipboard
/* Now open the file descriptor. */
assetFd = resolver.openTypedAssetFileDescriptor (uri, mimeType,
null);
/* Duplicate the file descriptor. */
fd = assetFd.getParcelFileDescriptor ().getFd ();
fd = EmacsNative.dup (fd);
/* Return the relevant information. */
value = new long[] { fd, assetFd.getStartOffset (),
assetFd.getLength (), };
/* Close the original offset. */
assetFd.close ();
return assetFd;
}
catch (SecurityException e)
{
/* Guarantee a file descriptor duplicated or detached is
ultimately closed if an error arises. */
if (fd != -1)
EmacsNative.close (fd);
return null;
}
catch (FileNotFoundException e)
{
/* Guarantee a file descriptor duplicated or detached is
ultimately closed if an error arises. */
if (fd != -1)
EmacsNative.close (fd);
return null;
}
catch (IOException e)
{
/* Guarantee a file descriptor duplicated or detached is
ultimately closed if an error arises. */
if (fd != -1)
EmacsNative.close (fd);
return null;
}
/* Don't return value if the file descriptor couldn't be
created. */
return fd != -1 ? value : null;
}
};

View file

@ -25,6 +25,8 @@ package org.gnu.emacs;
import android.text.*;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.util.Log;
import java.io.UnsupportedEncodingException;
@ -129,9 +131,10 @@ public final class EmacsSdk8Clipboard extends EmacsClipboard
/* Return the clipboard data for the given target, or NULL if it
does not exist.
Value is normally an array of three longs: the file descriptor,
the start offset of the data, and its length; length may be
AssetFileDescriptor.UNKOWN_LENGTH, meaning that the data extends
Value is normally an asset file descriptor, which in turn holds
three important values: the file descriptor, the start offset of
the data, and its length; length may be
AssetFileDescriptor.UNKNOWN_LENGTH, meaning that the data extends
from that offset to the end of the file.
Do not use this function to open text targets; use `getClipboard'
@ -139,7 +142,7 @@ public final class EmacsSdk8Clipboard extends EmacsClipboard
solely of a URI. */
@Override
public long[]
public AssetFileDescriptor
getClipboardData (byte[] target)
{
return null;