]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix hang after failed yank-media on Android
authorPo Lu <luangruo@yahoo.com>
Wed, 8 May 2024 08:03:49 +0000 (16:03 +0800)
committerEshel Yaron <me@eshelyaron.com>
Wed, 8 May 2024 16:53:00 +0000 (18:53 +0200)
* 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.

(cherry picked from commit e020f4e9ce5d98438033fea098d943c311b0fa3d)

java/org/gnu/emacs/EmacsClipboard.java
java/org/gnu/emacs/EmacsSdk11Clipboard.java
java/org/gnu/emacs/EmacsSdk8Clipboard.java
src/androidselect.c

index f27d96129ef754d18f7d0d2e05c0f92aa9682a7d..86553f478ed63d0cb303102d5b54ba9010f8529f 100644 (file)
@@ -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.  */
 
index 71381b0f114e9b1ddc9e518a3f729bf0bec10776..dfc714476ecb34f61ed36e9f4dce4d8710a55711 100644 (file)
@@ -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)
index 3d0504b192458a7b39f2ee083695f2f8e4ee83b9..344ec6f799726a4b6d62e391175d687a7ea3c948 100644 (file)
@@ -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;
   }
index d9c35746f11fa0602d8b581ddd5da2faab92e0d6..7c93607848a03e9168d0ed7cc0858abad0f4c8c5 100644 (file)
@@ -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.  */