diff options
| author | Po Lu | 2023-05-31 10:13:04 +0800 |
|---|---|---|
| committer | Po Lu | 2023-05-31 10:13:04 +0800 |
| commit | 57903519eb61632c4a85fbaf420109892955079a (patch) | |
| tree | 3dc2f961217870b96e0a1e96f52e9bdb331e4413 /java | |
| parent | 733a6776f9d665e5fd99bcc2a65c84c4360e277c (diff) | |
| download | emacs-57903519eb61632c4a85fbaf420109892955079a.tar.gz emacs-57903519eb61632c4a85fbaf420109892955079a.zip | |
Update Android port
* java/debug.sh (is_root): Go back to using unix sockets; allow
adb to forward them correctly.
* java/org/gnu/emacs/EmacsInputConnection.java
(getExtractedText): Don't print text if NULL.
* java/org/gnu/emacs/EmacsService.java (EmacsService): New field
`imSyncInProgress'.
(updateIC): If an IM sync might be in progress, avoid deadlocks.
* java/org/gnu/emacs/EmacsView.java (onCreateInputConnection):
Set `imSyncInProgress' across synchronization point.
* src/android.c (android_check_query): Use __atomic_store_n.
(android_answer_query): New function.
(android_begin_query): Set `android_servicing_query' to 2.
Check once, and don't spin waiting for query to complete.
(android_end_query): Use __atomic_store_n.
(android_run_in_emacs_thread): Compare-and-exchange flag. If
originally 1, fail.
* src/textconv.c (really_set_composing_text): Clear conversion
region if text is empty.
Diffstat (limited to 'java')
| -rwxr-xr-x | java/debug.sh | 17 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsInputConnection.java | 8 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsService.java | 28 | ||||
| -rw-r--r-- | java/org/gnu/emacs/EmacsView.java | 8 |
4 files changed, 54 insertions, 7 deletions
diff --git a/java/debug.sh b/java/debug.sh index 339b3604810..0458003fe72 100755 --- a/java/debug.sh +++ b/java/debug.sh | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | ## along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. | 19 | ## along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. |
| 20 | 20 | ||
| 21 | set -m | 21 | set -m |
| 22 | set -x | ||
| 22 | oldpwd=`pwd` | 23 | oldpwd=`pwd` |
| 23 | cd `dirname $0` | 24 | cd `dirname $0` |
| 24 | 25 | ||
| @@ -310,22 +311,26 @@ rm -f /tmp/file-descriptor-stamp | |||
| 310 | 311 | ||
| 311 | if [ -z "$gdbserver" ]; then | 312 | if [ -z "$gdbserver" ]; then |
| 312 | if [ "$is_root" = "yes" ]; then | 313 | if [ "$is_root" = "yes" ]; then |
| 313 | adb -s $device shell $gdbserver_bin --once \ | 314 | adb -s $device shell $gdbserver_bin --multi \ |
| 314 | "+/data/local/tmp/debug.$package.socket" --attach $pid >&5 & | 315 | "+/data/local/tmp/debug.$package.socket" --attach $pid >&5 & |
| 315 | gdb_socket="localfilesystem:/data/local/tmp/debug.$package.socket" | 316 | gdb_socket="localfilesystem:/data/local/tmp/debug.$package.socket" |
| 316 | else | 317 | else |
| 317 | adb -s $device shell run-as $package $gdbserver_bin --once \ | 318 | adb -s $device shell run-as $package $gdbserver_bin --multi \ |
| 318 | "+debug.$package.socket" --attach $pid >&5 & | 319 | "+debug.$package.socket" --attach $pid >&5 & |
| 319 | gdb_socket="localfilesystem:$app_data_dir/debug.$package.socket" | 320 | gdb_socket="localfilesystem:$app_data_dir/debug.$package.socket" |
| 320 | fi | 321 | fi |
| 321 | else | 322 | else |
| 322 | # Normally the program cannot access $gdbserver_bin when it is | 323 | # Normally the program cannot access $gdbserver_bin when it is |
| 323 | # placed in /data/local/tmp. | 324 | # placed in /data/local/tmp. |
| 324 | adb -s $device shell run-as $package $gdbserver_cmd --once \ | 325 | adb -s $device shell run-as $package $gdbserver_cmd --multi \ |
| 325 | "0.0.0.0:7654" --attach $pid >&5 & | 326 | "+debug.$package.socket" --attach $pid >&5 & |
| 326 | gdb_socket="tcp:7654" | 327 | gdb_socket="localfilesystem:$app_data_dir/debug.$package.socket" |
| 327 | fi | 328 | fi |
| 328 | 329 | ||
| 330 | # In order to allow adb to forward to the gdbserver socket, make the | ||
| 331 | # app data directory a+x. | ||
| 332 | adb -s $device shell run-as $package chmod a+x $app_data_dir | ||
| 333 | |||
| 329 | # Wait until gdbserver successfully runs. | 334 | # Wait until gdbserver successfully runs. |
| 330 | line= | 335 | line= |
| 331 | while read -u 5 line; do | 336 | while read -u 5 line; do |
diff --git a/java/org/gnu/emacs/EmacsInputConnection.java b/java/org/gnu/emacs/EmacsInputConnection.java index 21bbaca5d07..420da58c0f8 100644 --- a/java/org/gnu/emacs/EmacsInputConnection.java +++ b/java/org/gnu/emacs/EmacsInputConnection.java | |||
| @@ -286,6 +286,14 @@ public final class EmacsInputConnection extends BaseInputConnection | |||
| 286 | text = EmacsNative.getExtractedText (windowHandle, request, | 286 | text = EmacsNative.getExtractedText (windowHandle, request, |
| 287 | flags); | 287 | flags); |
| 288 | 288 | ||
| 289 | if (text == null) | ||
| 290 | { | ||
| 291 | if (EmacsService.DEBUG_IC) | ||
| 292 | Log.d (TAG, "getExtractedText: text is NULL"); | ||
| 293 | |||
| 294 | return null; | ||
| 295 | } | ||
| 296 | |||
| 289 | if (EmacsService.DEBUG_IC) | 297 | if (EmacsService.DEBUG_IC) |
| 290 | Log.d (TAG, "getExtractedText: " + text.text + " @" | 298 | Log.d (TAG, "getExtractedText: " + text.text + " @" |
| 291 | + text.startOffset + ":" + text.selectionStart | 299 | + text.startOffset + ":" + text.selectionStart |
diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java index 546d22627c5..2f35933a7d1 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java | |||
| @@ -104,6 +104,9 @@ public final class EmacsService extends Service | |||
| 104 | performing drawing calls. */ | 104 | performing drawing calls. */ |
| 105 | private static final boolean DEBUG_THREADS = false; | 105 | private static final boolean DEBUG_THREADS = false; |
| 106 | 106 | ||
| 107 | /* Whether or not onCreateInputMethod is calling getSelection. */ | ||
| 108 | public static volatile boolean imSyncInProgress; | ||
| 109 | |||
| 107 | /* Return the directory leading to the directory in which native | 110 | /* Return the directory leading to the directory in which native |
| 108 | library files are stored on behalf of CONTEXT. */ | 111 | library files are stored on behalf of CONTEXT. */ |
| 109 | 112 | ||
| @@ -636,16 +639,41 @@ public final class EmacsService extends Service | |||
| 636 | int newSelectionEnd, int composingRegionStart, | 639 | int newSelectionEnd, int composingRegionStart, |
| 637 | int composingRegionEnd) | 640 | int composingRegionEnd) |
| 638 | { | 641 | { |
| 642 | boolean wasSynchronous; | ||
| 643 | |||
| 639 | if (DEBUG_IC) | 644 | if (DEBUG_IC) |
| 640 | Log.d (TAG, ("updateIC: " + window + " " + newSelectionStart | 645 | Log.d (TAG, ("updateIC: " + window + " " + newSelectionStart |
| 641 | + " " + newSelectionEnd + " " | 646 | + " " + newSelectionEnd + " " |
| 642 | + composingRegionStart + " " | 647 | + composingRegionStart + " " |
| 643 | + composingRegionEnd)); | 648 | + composingRegionEnd)); |
| 649 | |||
| 650 | /* `updateSelection' holds an internal lock that is also taken | ||
| 651 | before `onCreateInputConnection' (in EmacsView.java) is called; | ||
| 652 | when that then asks the UI thread for the current selection, a | ||
| 653 | dead lock results. To remedy this, reply to any synchronous | ||
| 654 | queries now -- and prohibit more queries for the duration of | ||
| 655 | `updateSelection' -- if EmacsView may have been asking for the | ||
| 656 | value of the region. */ | ||
| 657 | |||
| 658 | wasSynchronous = false; | ||
| 659 | if (EmacsService.imSyncInProgress) | ||
| 660 | { | ||
| 661 | /* `beginSynchronous' will answer any outstanding queries and | ||
| 662 | signal that one is now in progress, thereby preventing | ||
| 663 | `getSelection' from blocking. */ | ||
| 664 | |||
| 665 | EmacsNative.beginSynchronous (); | ||
| 666 | wasSynchronous = true; | ||
| 667 | } | ||
| 668 | |||
| 644 | window.view.imManager.updateSelection (window.view, | 669 | window.view.imManager.updateSelection (window.view, |
| 645 | newSelectionStart, | 670 | newSelectionStart, |
| 646 | newSelectionEnd, | 671 | newSelectionEnd, |
| 647 | composingRegionStart, | 672 | composingRegionStart, |
| 648 | composingRegionEnd); | 673 | composingRegionEnd); |
| 674 | |||
| 675 | if (wasSynchronous) | ||
| 676 | EmacsNative.endSynchronous (); | ||
| 649 | } | 677 | } |
| 650 | 678 | ||
| 651 | public void | 679 | public void |
diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java index 09bc9d719d3..bb450bb8e6b 100644 --- a/java/org/gnu/emacs/EmacsView.java +++ b/java/org/gnu/emacs/EmacsView.java | |||
| @@ -628,8 +628,14 @@ public final class EmacsView extends ViewGroup | |||
| 628 | } | 628 | } |
| 629 | 629 | ||
| 630 | /* Obtain the current position of point and set it as the | 630 | /* Obtain the current position of point and set it as the |
| 631 | selection. */ | 631 | selection. Don't do this under one specific situation: if |
| 632 | `android_update_ic' is being called in the main thread, trying | ||
| 633 | to synchronize with it can cause a dead lock in the IM | ||
| 634 | manager. */ | ||
| 635 | |||
| 636 | EmacsService.imSyncInProgress = true; | ||
| 632 | selection = EmacsNative.getSelection (window.handle); | 637 | selection = EmacsNative.getSelection (window.handle); |
| 638 | EmacsService.imSyncInProgress = false; | ||
| 633 | 639 | ||
| 634 | if (selection != null) | 640 | if (selection != null) |
| 635 | Log.d (TAG, "onCreateInputConnection: current selection is: " | 641 | Log.d (TAG, "onCreateInputConnection: current selection is: " |