mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-06 06:20:55 -08:00
* configure.ac (ANDROID_MIN_SDK): New variable. (DX): Remove and replace with D8. (XCONFIGURE): Check for the minimum version of Android the cross compiler compiles for. Generate java/AndroidManifest.xml from java/AndroidManifest.xml.in. Allow using Zlib on Android. * java/AndroidManifest.xml.in: New file. Use the minimum SDK detected by configure. * java/Makefile.in (top_srcdir, version): New variables. (DX, D8): Replace with D8. (ANDROID_MIN_SDK, APK_NAME): New variables. (.PHONY): (.PRECIOUS): (classes.dex): (emacs.apk): Generate $(APK_NAME) instead of `emacs.apk'. * java/debug.sh: New option --attach-existing. Attach to an existing Emacs instance when specified. * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity): New field `isPaused'. (invalidateFocus1): Fix infinite recursion. (detachWindow): Deiconify window. (attachWindow): Iconify the window if the activity is paused. (onCreate): Use the ``no title bar'' theme. (onPause, onResume): New functions. * java/org/gnu/emacs/EmacsNative.java (sendTouchUp, sendTouchDown) (sendTouchMove, sendWheel, sendIconified, sendDeiconified): New functions. * java/org/gnu/emacs/EmacsSdk7FontDriver.java (Sdk7Typeface): (list): Remove logging for code that is mostly going to be unused. * java/org/gnu/emacs/EmacsService.java (ringBell, queryTree) (getScreenWidth, getScreenHeight, detectMouse): New functions. * java/org/gnu/emacs/EmacsSurfaceView.java (EmacsSurfaceView) (surfaceChanged, surfaceCreated, surfaceDestroyed): Add extra debug logging. Avoid deadlock in surfaceCreated. * java/org/gnu/emacs/EmacsView.java (EmacsView): Try very hard to make the SurfaceView respect Z order. It didn't work. (handleDirtyBitmap): Copy over the contents from the old bitmap. (explicitlyDirtyBitmap): New function. (onLayout): Don't dirty bitmap if unnecessary. (damageRect, swapBuffers): Don't synchronize so hard. (onTouchEvent): Call window.onTouchEvent instead. (moveChildToBack, raise, lower): New functions. * java/org/gnu/emacs/EmacsWindow.java (Coordinate): New subclass. (pointerMap, isMapped, isIconified, dontFocusOnMap) (dontAcceptFocus): New fields. (EmacsWindow): Don't immediately register unmapped window. (viewLayout): Send configure event outside the lock. (requestViewLayout): Explicitly dirty the bitmap. (mapWindow): Register the window now. Respect dontFocusOnMap. (unmapWindow): Unregister the window now. (figureChange, onTouchEvent): New functions. (onSomeKindOfMotionEvent): Handle scroll wheel events. (reparentTo, makeInputFocus, raise, lower, getWindowGeometry) (noticeIconified, noticeDeiconified, setDontAcceptFocus) (setDontFocusOnMap, getDontFocusOnMap): New functions. * java/org/gnu/emacs/EmacsWindowAttachmentManager.java (registerWindow, detachWindow): Synchronize. (noticeIconified, noticeDeiconified): New functions. (copyWindows): New function. * lisp/frame.el (frame-geometry, frame-edges) (mouse-absolute-pixel-position, set-mouse-absolute-pixel-position) (frame-list-z-order, frame-restack, display-mouse-p) (display-monitor-attributes-list): Implement on Android. * lisp/mwheel.el (mouse-wheel-down-event): (mouse-wheel-up-event): (mouse-wheel-left-event): (mouse-wheel-right-event): Define on Android. * src/android.c (struct android_emacs_service): New methods `ringBell', `queryTree', `getScreenWidth', `getScreenHeight', and `detectMouse'. (struct android_event_queue, android_init_events) (android_next_event, android_write_event): Remove write limit. (android_file_access_p): Handle directories correcty. (android_close): Fix coding style. (android_fclose): New function. (android_init_emacs_service): Initialize new methods. (android_reparent_window): Implement function. (android_bell, android_set_input_focus, android_raise_window) (android_lower_window, android_query_tree, android_get_geometry) (android_get_screen_width, android_get_screen_height) (android_get_mm_width, android_get_mm_height, android_detect_mouse) (android_set_dont_focus_on_map, android_set_dont_accept_focus): New functions. (struct android_dir): New structure. (android_opendir, android_readdir, android_closedir): New functions. (emacs_abort): Implement here on Android and poke debuggerd into generating a tombstone. * src/android.h: Update prototypes. * src/androidfns.c (android_set_parent_frame): New function. (android_default_font_parameter): Use sane font size by default. (Fx_display_pixel_width, Fx_display_pixel_height) (Fx_display_mm_width, Fx_display_mm_height) (Fx_display_monitor_attributes_list): Rename to start with `android-'. Implement. Fiddle with documentation to introduce Android specific nuances. (Fandroid_display_monitor_attributes_list): New function. (Fx_frame_geometry, frame_geometry): New function. (Fandroid_frame_geometry): Implement correctly. (Fx_frame_list_z_order): Rename to start with `android-'. (android_frame_list_z_order, Fandroid_frame_list_z_order): Implement. (Fx_frame_restack): Rename to start with `android-'. (Fandroid_frame_restack): ``Implement''. (Fx_mouse_absolute_pixel_position): Rename to start with `android-'. (Fandroid_mouse_absolute_pixel_position): ``Implement''. (Fx_set_mouse_absolute_pixel_position): Rename to start with `android-'. (Fandroid_set_mouse_absolute_pixel_position): ``Implement''. (Fandroid_detect_mouse): New function. (android_set_menu_bar_lines): Use FRAME_ANDROID_DRAWABLE when clearing area. (android_set_no_focus_on_map, android_set_no_accept_focus): New functions. (android_frame_parm_handlers): Register new frame parameter handlers. (syms_of_androidfns): Update appropriately. * src/androidfont.c (androidfont_draw): Use FRAME_ANDROID_DRAWABLE instead of FRAME_ANDROID_WINDOW. * src/androidgui.h (enum android_event_type): New events. (struct android_touch_event, struct android_wheel_event) (struct android_iconify_event): New structures. (union android_event): Add new events. * src/androidterm.c (android_clear_frame): Use FRAME_ANDROID_DRAWABLE instead of FRAME_ANDROID_WINDOW. (android_flash, android_ring_bell): Implement bell ringing. (android_toggle_invisible_pointer): Don't TODO function that can't be implemented. (show_back_buffer, android_flush_dirty_back_buffer_on): Check if a buffer flip is required before doing the flip. (android_lower_frame, android_raise_frame): Implement functions. (android_update_tools, android_find_tool): New functions. (handle_one_android_event): Handle new iconification, wheel and touch events. (android_read_socket): Implement pending-autoraise-frames. (android_frame_up_to_date): Implement bell ringing. (android_buffer_flipping_unblocked_hook): Check if a buffer flip is required before doing the flip. (android_focus_frame, android_frame_highlight) (android_frame_unhighlight): New function. (android_frame_rehighlight): Implement functions. (android_iconify_frame): Always display error. (android_set_alpha): Update commentary. (android_free_frame_resources): Free frame touch points. (android_scroll_run, android_flip_and_flush) (android_clear_rectangle, android_draw_fringe_bitmap) (android_draw_glyph_string_background, android_fill_triangle) (android_clear_point, android_draw_relief_rect) (android_draw_box_rect, android_draw_glyph_string_bg_rect) (android_draw_image_foreground, android_draw_stretch_glyph_string) (android_draw_underwave, android_draw_glyph_string_foreground) (android_draw_composite_glyph_string_foreground) (android_draw_glyphless_glyph_string_foreground) (android_draw_glyph_string, android_clear_frame_area) (android_clear_under_internal_border, android_draw_hollow_cursor) (android_draw_bar_cursor, android_draw_vertical_window_border) (android_draw_window_divider): Use FRAME_ANDROID_DRAWABLE instead of FRAME_ANDROID_WINDOW for drawing operations. * src/androidterm.h (struct android_touch_point): New structure. (struct android_output): New fields. (FRAME_ANDROID_NEED_BUFFER_FLIP): New macro. * src/dired.c (emacs_readdir, open_directory) (directory_files_internal_unwind, read_dirent) (directory_files_internal, file_name_completion): Add indirection over readdir and opendir. Use android variants on Android. * src/dispnew.c (Fopen_termscript): * src/fileio.c (fclose_unwind): Use emacs_fclose. (Faccess_file): Call android_file_access_p. (file_accessible_directory_p): Append right suffix to Android assets directory. (do_auto_save_unwind): Use emacs_fclose. * src/keyboard.c (lispy_function_keys): Use right function key for page up and page down. (Fopen_dribble_file): Use emacs_fclose. * src/lisp.h: New prototype emacs_fclose. * src/lread.c (close_infile_unwind): Use emacs_fclose. * src/sfnt.c (sfnt_curve_is_flat): Fix area-squared computation. (sfnt_prepare_raster): Compute raster width and height consistently with outline building. (sfnt_build_outline_edges): Use the same offsets used to set offy and offx. (main): Adjust debug code. * src/sfntfont-android.c (sfntfont_android_saturate32): Delete function. (sfntfont_android_blend, sfntfont_android_blendrgb): Remove unnecessary debug code. (sfntfont_android_composite_bitmap): Prevent out of bounds write. (sfntfont_android_put_glyphs): Use FRAME_ANDROID_DRAWABLE. (init_sfntfont_android): Initialize Monospace Serif font to something sensible. * src/sfntfont.c (sfntfont_text_extents): Clear glyph metrics before summing up pcm. (sfntfont_draw): Use s->font instead of s->face->font. * src/sysdep.c (emacs_fclose): Wrap around android_fclose on android. * src/term.c (Fsuspend_tty): (delete_tty): Use emacs_fclose. * src/verbose.mk.in (AM_V_DX): Replace with D8 version.
249 lines
6.4 KiB
Bash
Executable file
249 lines
6.4 KiB
Bash
Executable file
#!/bin/bash
|
|
### Run Emacs under GDB or JDB on Android.
|
|
|
|
## Copyright (C) 2023 Free Software Foundation, Inc.
|
|
|
|
## This file is part of GNU Emacs.
|
|
|
|
## GNU Emacs is free software: you can redistribute it and/or modify
|
|
## it under the terms of the GNU General Public License as published by
|
|
## the Free Software Foundation, either version 3 of the License, or
|
|
## (at your option) any later version.
|
|
|
|
## GNU Emacs is distributed in the hope that it will be useful,
|
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
## GNU General Public License for more details.
|
|
|
|
## You should have received a copy of the GNU General Public License
|
|
## along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
set -m
|
|
oldpwd=`pwd`
|
|
cd `dirname $0`
|
|
|
|
devices=`adb devices | grep device | awk -- '/device\y/ { print $1 }' -`
|
|
device=
|
|
progname=$0
|
|
package=org.gnu.emacs
|
|
activity=org.gnu.emacs.EmacsActivity
|
|
gdb_port=5039
|
|
jdb_port=64013
|
|
jdb=no
|
|
attach_existing=no
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
## This option specifies the serial number of a device to use.
|
|
"--device" )
|
|
device="$2"
|
|
if [ -z device ]; then
|
|
echo "You must specify an argument to --device"
|
|
exit 1
|
|
fi
|
|
;;
|
|
"--help" )
|
|
echo "Usage: $progname [options] -- [gdb options]"
|
|
echo ""
|
|
echo " --device DEVICE run Emacs on the specified device"
|
|
echo " --port PORT run the GDB server on a specific port"
|
|
echo " --jdb-port PORT run the JDB server on a specific port"
|
|
echo " --jdb run JDB instead of GDB"
|
|
echo " --attach-existing attach to an existing process"
|
|
echo " --help print this message"
|
|
echo ""
|
|
echo "Available devices:"
|
|
for device in $devices; do
|
|
echo " " $device
|
|
done
|
|
echo ""
|
|
exit 0
|
|
;;
|
|
"--jdb" )
|
|
jdb=yes
|
|
;;
|
|
"--port" )
|
|
gdb_port=$1
|
|
;;
|
|
"--attach-existing" )
|
|
attach_existing=yes
|
|
;;
|
|
"--" )
|
|
shift
|
|
gdbargs=$@
|
|
break;
|
|
;;
|
|
* )
|
|
echo "$progname: Unrecognized argument $1"
|
|
exit 1
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [ -z $devices ]; then
|
|
echo "No devices are available."
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z $device ]; then
|
|
device=$devices
|
|
fi
|
|
|
|
if [ `wc -w <<< "$devices"` -gt 1 ] && [ -z device ]; then
|
|
echo "Multiple devices are available. Please pick one using"
|
|
echo "--device and try again."
|
|
fi
|
|
|
|
echo "Looking for $package on device $device"
|
|
|
|
# Find the application data directory
|
|
app_data_dir=`adb -s $device shell run-as $package sh -c 'pwd 2> /dev/null'`
|
|
|
|
if [ -z $app_data_dir ]; then
|
|
echo "The data directory for the package $package was not found."
|
|
echo "Is it installed?"
|
|
fi
|
|
|
|
echo "Found application data directory at $app_data_dir..."
|
|
|
|
# Find which PIDs are associated with org.gnu.emacs
|
|
package_uid=`adb -s $device shell run-as $package id -u`
|
|
|
|
if [ -z $package_uid ]; then
|
|
echo "Failed to obtain UID of packages named $package"
|
|
exit 1
|
|
fi
|
|
|
|
# First, run ps -u $package_uid -o PID,CMD to fetch the list of
|
|
# process IDs.
|
|
package_pids=`adb -s $device shell run-as $package ps -u $package_uid -o PID,CMD`
|
|
|
|
# Next, remove lines matching "ps" itself.
|
|
package_pids=`awk -- '{
|
|
if (!match ($0, /(PID|ps)/))
|
|
print $1
|
|
}' <<< $package_pids`
|
|
|
|
if [ "$attach_existing" != "yes" ]; then
|
|
# Finally, kill each existing process.
|
|
for pid in $package_pids; do
|
|
echo "Killing existing process $pid..."
|
|
adb -s $device shell run-as $package kill -9 $pid &> /dev/null
|
|
done
|
|
|
|
# Now run the main activity. This must be done as the adb user and
|
|
# not as the package user.
|
|
echo "Starting activity $activity and attaching debugger"
|
|
|
|
# Exit if the activity could not be started.
|
|
adb -s $device shell am start -D "$package/$activity"
|
|
if [ ! $? ]; then
|
|
exit 1;
|
|
fi
|
|
|
|
# Now look for processes matching the package again.
|
|
package_pids=`adb -s $device shell run-as $package ps -u $package_uid -o PID,CMD`
|
|
|
|
# Next, remove lines matching "ps" itself.
|
|
package_pids=`awk -- '{
|
|
if (!match ($0, /(PID|ps)/))
|
|
print $1
|
|
}' <<< $package_pids`
|
|
fi
|
|
|
|
pid=$package_pids
|
|
num_pids=`wc -w <<< "$package_pids"`
|
|
|
|
if [ $num_pids -gt 1 ]; then
|
|
echo "More than one process was started:"
|
|
echo ""
|
|
adb -s $device shell run-as $package ps -u $package_uid | awk -- '{
|
|
if (!match ($0, /ps/))
|
|
print $0
|
|
}'
|
|
echo ""
|
|
printf "Which one do you want to attach to? "
|
|
read pid
|
|
elif [ -z $package_pids ]; then
|
|
echo "No processes were found to attach to."
|
|
exit 1
|
|
fi
|
|
|
|
# Start JDB to make the wait dialog disappear.
|
|
echo "Attaching JDB to unblock the application."
|
|
adb -s $device forward --remove-all
|
|
adb -s $device forward "tcp:$jdb_port" "jdwp:$pid"
|
|
|
|
if [ ! $? ]; then
|
|
echo "Failed to forward jdwp:$pid to $jdb_port!"
|
|
echo "Perhaps you need to specify a different port with --port?"
|
|
exit 1;
|
|
fi
|
|
|
|
jdb_command="jdb -connect \
|
|
com.sun.jdi.SocketAttach:hostname=localhost,port=$jdb_port"
|
|
|
|
if [ $jdb = "yes" ]; then
|
|
# Just start JDB and then exit
|
|
$jdb_command
|
|
exit 1
|
|
fi
|
|
|
|
exec 4<> /tmp/file-descriptor-stamp
|
|
|
|
# Now run JDB with IO redirected to file descriptor 4 in a subprocess.
|
|
$jdb_command <&4 >&4 &
|
|
|
|
character=
|
|
# Next, wait until the prompt is found.
|
|
while read -n1 -u 4 character; do
|
|
if [ "$character" = ">" ]; then
|
|
echo "JDB attached successfully"
|
|
break;
|
|
fi
|
|
done
|
|
|
|
# Now start gdbserver on the device asynchronously.
|
|
|
|
echo "Attaching gdbserver to $pid on $device..."
|
|
exec 5<> /tmp/file-descriptor-stamp
|
|
adb -s $device shell run-as $package /system/bin/gdbserver --once \
|
|
"+debug.$package_uid.socket" --attach $pid >&5 &
|
|
|
|
# Wait until gdbserver successfully runs.
|
|
line=
|
|
while read -u 5 line; do
|
|
case "$line" in
|
|
*Attached* )
|
|
break;
|
|
;;
|
|
*error* | *Error* | failed )
|
|
echo $line
|
|
exit 1
|
|
;;
|
|
* )
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Send EOF to JDB to make it go away. This will also cause Android to
|
|
# allow Emacs to continue executing.
|
|
echo "Making JDB go away..."
|
|
echo "exit" >&4
|
|
read -u 4 line
|
|
echo "JDB has gone away with $line"
|
|
|
|
# Forward the gdb server port here.
|
|
adb -s $device forward "tcp:$gdb_port" \
|
|
"localfilesystem:$app_data_dir/debug.$package_uid.socket"
|
|
if [ ! $? ]; then
|
|
echo "Failed to forward $app_data_dir/debug.$package_uid.socket"
|
|
echo "to $gdb_port! Perhaps you need to specify a different port"
|
|
echo "with --port?"
|
|
exit 1;
|
|
fi
|
|
|
|
# Finally, start gdb with any extra arguments needed.
|
|
cd "$oldpwd"
|
|
gdb --eval-command "" --eval-command "target remote localhost:$gdb_port" $gdbargs
|