Fix hang after failed yank-media on Android
* java/org/gnu/emacs/EmacsClipboard.java (getClipboardTargets) (getClipboardData): * java/org/gnu/emacs/EmacsSdk11Clipboard.java (getClipboardTargets, getClipboardData): * java/org/gnu/emacs/EmacsSdk8Clipboard.java (getClipboardTargets, getClipboardData): Return string data as Strings rather than byte arrays. * src/androidselect.c (android_init_emacs_clipboard) (Fandroid_get_clipboard_targets): Adjust to match. (extract_fd_offsets): Remove duplicated semicolon. (Fandroid_get_clipboard_data): Call unblock_input before returning if extract_fd_offsets fails.
This commit is contained in:
parent
d0b36be59a
commit
e020f4e9ce
4 changed files with 45 additions and 67 deletions
|
@ -32,8 +32,8 @@ public abstract class EmacsClipboard
|
|||
public abstract boolean clipboardExists ();
|
||||
public abstract byte[] getClipboard ();
|
||||
|
||||
public abstract byte[][] getClipboardTargets ();
|
||||
public abstract AssetFileDescriptor getClipboardData (byte[] target);
|
||||
public abstract String[] getClipboardTargets ();
|
||||
public abstract AssetFileDescriptor getClipboardData (String target);
|
||||
|
||||
/* Create the correct kind of clipboard for this system. */
|
||||
|
||||
|
|
|
@ -172,12 +172,12 @@ public final class EmacsSdk11Clipboard extends EmacsClipboard
|
|||
clipboard, or NULL if there are none. */
|
||||
|
||||
@Override
|
||||
public byte[][]
|
||||
public String[]
|
||||
getClipboardTargets ()
|
||||
{
|
||||
ClipData clip;
|
||||
ClipDescription description;
|
||||
byte[][] typeArray;
|
||||
String[] typeArray;
|
||||
int i;
|
||||
|
||||
/* N.B. that Android calls the clipboard the ``primary clip''; it
|
||||
|
@ -189,17 +189,10 @@ public final class EmacsSdk11Clipboard extends EmacsClipboard
|
|||
|
||||
description = clip.getDescription ();
|
||||
i = description.getMimeTypeCount ();
|
||||
typeArray = new byte[i][i];
|
||||
typeArray = new String[i];
|
||||
|
||||
try
|
||||
{
|
||||
for (i = 0; i < description.getMimeTypeCount (); ++i)
|
||||
typeArray[i] = description.getMimeType (i).getBytes ("UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
for (i = 0; i < description.getMimeTypeCount (); ++i)
|
||||
typeArray[i] = description.getMimeType (i);
|
||||
|
||||
return typeArray;
|
||||
}
|
||||
|
@ -219,26 +212,17 @@ public final class EmacsSdk11Clipboard extends EmacsClipboard
|
|||
|
||||
@Override
|
||||
public AssetFileDescriptor
|
||||
getClipboardData (byte[] target)
|
||||
getClipboardData (String target)
|
||||
{
|
||||
ClipData data;
|
||||
String mimeType;
|
||||
AssetFileDescriptor assetFd;
|
||||
Uri uri;
|
||||
|
||||
/* Decode the target given by Emacs. */
|
||||
try
|
||||
{
|
||||
mimeType = new String (target, "UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Now obtain the clipboard data and the data corresponding to
|
||||
that MIME type. */
|
||||
|
||||
mimeType = target;
|
||||
data = manager.getPrimaryClip ();
|
||||
|
||||
if (data == null || data.getItemCount () < 1)
|
||||
|
|
|
@ -122,7 +122,7 @@ public final class EmacsSdk8Clipboard extends EmacsClipboard
|
|||
clipboard, or NULL if there are none. */
|
||||
|
||||
@Override
|
||||
public byte[][]
|
||||
public String[]
|
||||
getClipboardTargets ()
|
||||
{
|
||||
return null;
|
||||
|
@ -143,7 +143,7 @@ public final class EmacsSdk8Clipboard extends EmacsClipboard
|
|||
|
||||
@Override
|
||||
public AssetFileDescriptor
|
||||
getClipboardData (byte[] target)
|
||||
getClipboardData (String target)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -99,9 +99,10 @@ android_init_emacs_clipboard (void)
|
|||
FIND_METHOD (clipboard_exists, "clipboardExists", "()Z");
|
||||
FIND_METHOD (get_clipboard, "getClipboard", "()[B");
|
||||
FIND_METHOD (get_clipboard_targets, "getClipboardTargets",
|
||||
"()[[B");
|
||||
"()[Ljava/lang/String;");
|
||||
FIND_METHOD (get_clipboard_data, "getClipboardData",
|
||||
"([B)Landroid/content/res/AssetFileDescriptor;");
|
||||
"(Ljava/lang/String;)Landroid/content/res/"
|
||||
"AssetFileDescriptor;");
|
||||
|
||||
clipboard_class.make_clipboard
|
||||
= (*android_java_env)->GetStaticMethodID (android_java_env,
|
||||
|
@ -283,11 +284,11 @@ Value is a list of MIME types as strings, each defining a single extra
|
|||
data type available from the clipboard. */)
|
||||
(void)
|
||||
{
|
||||
jarray bytes_array;
|
||||
jbyteArray bytes;
|
||||
jarray all_targets;
|
||||
jstring string;
|
||||
jmethodID method;
|
||||
size_t length, length1, i;
|
||||
jbyte *data;
|
||||
size_t length, i;
|
||||
const char *data;
|
||||
Lisp_Object targets, tem;
|
||||
|
||||
if (!android_init_gui)
|
||||
|
@ -296,44 +297,42 @@ data type available from the clipboard. */)
|
|||
targets = Qnil;
|
||||
block_input ();
|
||||
method = clipboard_class.get_clipboard_targets;
|
||||
bytes_array = (*android_java_env)->CallObjectMethod (android_java_env,
|
||||
all_targets = (*android_java_env)->CallObjectMethod (android_java_env,
|
||||
clipboard, method);
|
||||
android_exception_check ();
|
||||
|
||||
if (!bytes_array)
|
||||
if (!all_targets)
|
||||
goto fail;
|
||||
|
||||
length = (*android_java_env)->GetArrayLength (android_java_env,
|
||||
bytes_array);
|
||||
all_targets);
|
||||
for (i = 0; i < length; ++i)
|
||||
{
|
||||
/* Retrieve the MIME type. */
|
||||
bytes
|
||||
string
|
||||
= (*android_java_env)->GetObjectArrayElement (android_java_env,
|
||||
bytes_array, i);
|
||||
android_exception_check_nonnull (bytes, bytes_array);
|
||||
all_targets, i);
|
||||
android_exception_check_nonnull (string, all_targets);
|
||||
|
||||
/* Cons it onto the list of targets. */
|
||||
length1 = (*android_java_env)->GetArrayLength (android_java_env,
|
||||
bytes);
|
||||
data = (*android_java_env)->GetByteArrayElements (android_java_env,
|
||||
bytes, NULL);
|
||||
android_exception_check_nonnull_1 (data, bytes, bytes_array);
|
||||
data = (*android_java_env)->GetStringUTFChars (android_java_env,
|
||||
string, NULL);
|
||||
android_exception_check_nonnull_1 ((void *) data, string,
|
||||
all_targets);
|
||||
|
||||
/* Decode the string. */
|
||||
tem = make_unibyte_string ((char *) data, length1);
|
||||
tem = code_convert_string_norecord (tem, Qutf_8, false);
|
||||
tem = build_unibyte_string ((char *) data);
|
||||
tem = code_convert_string_norecord (tem, Qandroid_jni, false);
|
||||
targets = Fcons (tem, targets);
|
||||
|
||||
/* Delete the retrieved data. */
|
||||
(*android_java_env)->ReleaseByteArrayElements (android_java_env,
|
||||
bytes, data,
|
||||
JNI_ABORT);
|
||||
ANDROID_DELETE_LOCAL_REF (bytes);
|
||||
(*android_java_env)->ReleaseStringUTFChars (android_java_env,
|
||||
string, data);
|
||||
ANDROID_DELETE_LOCAL_REF (string);
|
||||
}
|
||||
unblock_input ();
|
||||
|
||||
ANDROID_DELETE_LOCAL_REF (bytes_array);
|
||||
ANDROID_DELETE_LOCAL_REF (all_targets);
|
||||
return Fnreverse (targets);
|
||||
|
||||
fail:
|
||||
|
@ -432,7 +431,7 @@ extract_fd_offsets (jobject afd, int *fd, jlong *offset, jlong *length)
|
|||
#if __ANDROID_API__ <= 11
|
||||
static int (*jniGetFDFromFileDescriptor) (JNIEnv *, jobject);
|
||||
#endif /* __ANDROID_API__ <= 11 */
|
||||
static int (*AFileDescriptor_getFd) (JNIEnv *, jobject);;
|
||||
static int (*AFileDescriptor_getFd) (JNIEnv *, jobject);
|
||||
jmethodID method;
|
||||
|
||||
method = asset_fd_class.get_start_offset;
|
||||
|
@ -538,7 +537,7 @@ does not have any corresponding data. In that case, use
|
|||
(Lisp_Object type)
|
||||
{
|
||||
jobject afd;
|
||||
jbyteArray bytes;
|
||||
jstring mime_type;
|
||||
jmethodID method;
|
||||
int fd;
|
||||
ptrdiff_t rc;
|
||||
|
@ -549,25 +548,17 @@ does not have any corresponding data. In that case, use
|
|||
if (!android_init_gui)
|
||||
error ("No Android display connection!");
|
||||
|
||||
/* Encode the string as UTF-8. */
|
||||
CHECK_STRING (type);
|
||||
type = ENCODE_UTF_8 (type);
|
||||
|
||||
/* Then give it to the selection code. */
|
||||
/* Convert TYPE into a Java string. */
|
||||
block_input ();
|
||||
bytes = (*android_java_env)->NewByteArray (android_java_env,
|
||||
SBYTES (type));
|
||||
(*android_java_env)->SetByteArrayRegion (android_java_env, bytes,
|
||||
0, SBYTES (type),
|
||||
(jbyte *) SDATA (type));
|
||||
android_exception_check ();
|
||||
|
||||
mime_type = android_build_string (type, NULL);
|
||||
method = clipboard_class.get_clipboard_data;
|
||||
afd = (*android_java_env)->CallObjectMethod (android_java_env,
|
||||
clipboard, method,
|
||||
bytes);
|
||||
android_exception_check_1 (bytes);
|
||||
ANDROID_DELETE_LOCAL_REF (bytes);
|
||||
mime_type);
|
||||
android_exception_check_1 (mime_type);
|
||||
ANDROID_DELETE_LOCAL_REF (mime_type);
|
||||
|
||||
if (!afd)
|
||||
goto fail;
|
||||
|
@ -578,7 +569,10 @@ does not have any corresponding data. In that case, use
|
|||
record_unwind_protect_ptr (close_asset_fd, &afd);
|
||||
|
||||
if (extract_fd_offsets (afd, &fd, &offset, &length))
|
||||
return unbind_to (ref, Qnil);
|
||||
{
|
||||
unblock_input ();
|
||||
return unbind_to (ref, Qnil);
|
||||
}
|
||||
unblock_input ();
|
||||
|
||||
/* Now begin reading from fd. */
|
||||
|
|
Loading…
Add table
Reference in a new issue