diff options
| author | Po Lu | 2024-05-08 16:03:49 +0800 |
|---|---|---|
| committer | Po Lu | 2024-05-08 16:03:49 +0800 |
| commit | e020f4e9ce5d98438033fea098d943c311b0fa3d (patch) | |
| tree | 9d7828ac6f6abe3405c9432bc3c4c1018d5ab54a /src/androidselect.c | |
| parent | d0b36be59ab9840eebbda45609bc8c075ece40c0 (diff) | |
| download | emacs-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.c | 74 |
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 | |||
| 283 | data type available from the clipboard. */) | 284 | data 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. */ |