aboutsummaryrefslogtreecommitdiffstats
path: root/src/androidselect.c
diff options
context:
space:
mode:
authorPo Lu2024-05-08 16:03:49 +0800
committerPo Lu2024-05-08 16:03:49 +0800
commite020f4e9ce5d98438033fea098d943c311b0fa3d (patch)
tree9d7828ac6f6abe3405c9432bc3c4c1018d5ab54a /src/androidselect.c
parentd0b36be59ab9840eebbda45609bc8c075ece40c0 (diff)
downloademacs-e020f4e9ce5d98438033fea098d943c311b0fa3d.tar.gz
emacs-e020f4e9ce5d98438033fea098d943c311b0fa3d.zip
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.
Diffstat (limited to 'src/androidselect.c')
-rw-r--r--src/androidselect.c74
1 files changed, 34 insertions, 40 deletions
diff --git a/src/androidselect.c b/src/androidselect.c
index d9c35746f11..7c93607848a 100644
--- a/src/androidselect.c
+++ b/src/androidselect.c
@@ -99,9 +99,10 @@ android_init_emacs_clipboard (void)
99 FIND_METHOD (clipboard_exists, "clipboardExists", "()Z"); 99 FIND_METHOD (clipboard_exists, "clipboardExists", "()Z");
100 FIND_METHOD (get_clipboard, "getClipboard", "()[B"); 100 FIND_METHOD (get_clipboard, "getClipboard", "()[B");
101 FIND_METHOD (get_clipboard_targets, "getClipboardTargets", 101 FIND_METHOD (get_clipboard_targets, "getClipboardTargets",
102 "()[[B"); 102 "()[Ljava/lang/String;");
103 FIND_METHOD (get_clipboard_data, "getClipboardData", 103 FIND_METHOD (get_clipboard_data, "getClipboardData",
104 "([B)Landroid/content/res/AssetFileDescriptor;"); 104 "(Ljava/lang/String;)Landroid/content/res/"
105 "AssetFileDescriptor;");
105 106
106 clipboard_class.make_clipboard 107 clipboard_class.make_clipboard
107 = (*android_java_env)->GetStaticMethodID (android_java_env, 108 = (*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
283data type available from the clipboard. */) 284data type available from the clipboard. */)
284 (void) 285 (void)
285{ 286{
286 jarray bytes_array; 287 jarray all_targets;
287 jbyteArray bytes; 288 jstring string;
288 jmethodID method; 289 jmethodID method;
289 size_t length, length1, i; 290 size_t length, i;
290 jbyte *data; 291 const char *data;
291 Lisp_Object targets, tem; 292 Lisp_Object targets, tem;
292 293
293 if (!android_init_gui) 294 if (!android_init_gui)
@@ -296,44 +297,42 @@ data type available from the clipboard. */)
296 targets = Qnil; 297 targets = Qnil;
297 block_input (); 298 block_input ();
298 method = clipboard_class.get_clipboard_targets; 299 method = clipboard_class.get_clipboard_targets;
299 bytes_array = (*android_java_env)->CallObjectMethod (android_java_env, 300 all_targets = (*android_java_env)->CallObjectMethod (android_java_env,
300 clipboard, method); 301 clipboard, method);
301 android_exception_check (); 302 android_exception_check ();
302 303
303 if (!bytes_array) 304 if (!all_targets)
304 goto fail; 305 goto fail;
305 306
306 length = (*android_java_env)->GetArrayLength (android_java_env, 307 length = (*android_java_env)->GetArrayLength (android_java_env,
307 bytes_array); 308 all_targets);
308 for (i = 0; i < length; ++i) 309 for (i = 0; i < length; ++i)
309 { 310 {
310 /* Retrieve the MIME type. */ 311 /* Retrieve the MIME type. */
311 bytes 312 string
312 = (*android_java_env)->GetObjectArrayElement (android_java_env, 313 = (*android_java_env)->GetObjectArrayElement (android_java_env,
313 bytes_array, i); 314 all_targets, i);
314 android_exception_check_nonnull (bytes, bytes_array); 315 android_exception_check_nonnull (string, all_targets);
315 316
316 /* Cons it onto the list of targets. */ 317 /* Cons it onto the list of targets. */
317 length1 = (*android_java_env)->GetArrayLength (android_java_env, 318 data = (*android_java_env)->GetStringUTFChars (android_java_env,
318 bytes); 319 string, NULL);
319 data = (*android_java_env)->GetByteArrayElements (android_java_env, 320 android_exception_check_nonnull_1 ((void *) data, string,
320 bytes, NULL); 321 all_targets);
321 android_exception_check_nonnull_1 (data, bytes, bytes_array);
322 322
323 /* Decode the string. */ 323 /* Decode the string. */
324 tem = make_unibyte_string ((char *) data, length1); 324 tem = build_unibyte_string ((char *) data);
325 tem = code_convert_string_norecord (tem, Qutf_8, false); 325 tem = code_convert_string_norecord (tem, Qandroid_jni, false);
326 targets = Fcons (tem, targets); 326 targets = Fcons (tem, targets);
327 327
328 /* Delete the retrieved data. */ 328 /* Delete the retrieved data. */
329 (*android_java_env)->ReleaseByteArrayElements (android_java_env, 329 (*android_java_env)->ReleaseStringUTFChars (android_java_env,
330 bytes, data, 330 string, data);
331 JNI_ABORT); 331 ANDROID_DELETE_LOCAL_REF (string);
332 ANDROID_DELETE_LOCAL_REF (bytes);
333 } 332 }
334 unblock_input (); 333 unblock_input ();
335 334
336 ANDROID_DELETE_LOCAL_REF (bytes_array); 335 ANDROID_DELETE_LOCAL_REF (all_targets);
337 return Fnreverse (targets); 336 return Fnreverse (targets);
338 337
339 fail: 338 fail:
@@ -432,7 +431,7 @@ extract_fd_offsets (jobject afd, int *fd, jlong *offset, jlong *length)
432#if __ANDROID_API__ <= 11 431#if __ANDROID_API__ <= 11
433 static int (*jniGetFDFromFileDescriptor) (JNIEnv *, jobject); 432 static int (*jniGetFDFromFileDescriptor) (JNIEnv *, jobject);
434#endif /* __ANDROID_API__ <= 11 */ 433#endif /* __ANDROID_API__ <= 11 */
435 static int (*AFileDescriptor_getFd) (JNIEnv *, jobject);; 434 static int (*AFileDescriptor_getFd) (JNIEnv *, jobject);
436 jmethodID method; 435 jmethodID method;
437 436
438 method = asset_fd_class.get_start_offset; 437 method = asset_fd_class.get_start_offset;
@@ -538,7 +537,7 @@ does not have any corresponding data. In that case, use
538 (Lisp_Object type) 537 (Lisp_Object type)
539{ 538{
540 jobject afd; 539 jobject afd;
541 jbyteArray bytes; 540 jstring mime_type;
542 jmethodID method; 541 jmethodID method;
543 int fd; 542 int fd;
544 ptrdiff_t rc; 543 ptrdiff_t rc;
@@ -549,25 +548,17 @@ does not have any corresponding data. In that case, use
549 if (!android_init_gui) 548 if (!android_init_gui)
550 error ("No Android display connection!"); 549 error ("No Android display connection!");
551 550
552 /* Encode the string as UTF-8. */
553 CHECK_STRING (type); 551 CHECK_STRING (type);
554 type = ENCODE_UTF_8 (type);
555 552
556 /* Then give it to the selection code. */ 553 /* Convert TYPE into a Java string. */
557 block_input (); 554 block_input ();
558 bytes = (*android_java_env)->NewByteArray (android_java_env, 555 mime_type = android_build_string (type, NULL);
559 SBYTES (type));
560 (*android_java_env)->SetByteArrayRegion (android_java_env, bytes,
561 0, SBYTES (type),
562 (jbyte *) SDATA (type));
563 android_exception_check ();
564
565 method = clipboard_class.get_clipboard_data; 556 method = clipboard_class.get_clipboard_data;
566 afd = (*android_java_env)->CallObjectMethod (android_java_env, 557 afd = (*android_java_env)->CallObjectMethod (android_java_env,
567 clipboard, method, 558 clipboard, method,
568 bytes); 559 mime_type);
569 android_exception_check_1 (bytes); 560 android_exception_check_1 (mime_type);
570 ANDROID_DELETE_LOCAL_REF (bytes); 561 ANDROID_DELETE_LOCAL_REF (mime_type);
571 562
572 if (!afd) 563 if (!afd)
573 goto fail; 564 goto fail;
@@ -578,7 +569,10 @@ does not have any corresponding data. In that case, use
578 record_unwind_protect_ptr (close_asset_fd, &afd); 569 record_unwind_protect_ptr (close_asset_fd, &afd);
579 570
580 if (extract_fd_offsets (afd, &fd, &offset, &length)) 571 if (extract_fd_offsets (afd, &fd, &offset, &length))
581 return unbind_to (ref, Qnil); 572 {
573 unblock_input ();
574 return unbind_to (ref, Qnil);
575 }
582 unblock_input (); 576 unblock_input ();
583 577
584 /* Now begin reading from fd. */ 578 /* Now begin reading from fd. */