summaryrefslogtreecommitdiff
path: root/src/android-emacs.c
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2023-01-25 18:44:47 +0800
committerPo Lu <luangruo@yahoo.com>2023-01-25 18:44:47 +0800
commit0900bfbcc57c555909cb75c38eb0ed26fb6964ef (patch)
tree9a2fa4328defab79f1cb3dcfac4f3c071bf0a633 /src/android-emacs.c
parent6f9a2a8f29c7faf13d0d86001b140746efc455b5 (diff)
downloademacs-0900bfbcc57c555909cb75c38eb0ed26fb6964ef.tar.gz
Update Android port
* doc/emacs/android.texi (Android Startup, Android Environment): Document that restrictions on starting Emacs have been lifted. * java/README: Document Java for Emacs developers and how the Android port works. * java/org/gnu/emacs/EmacsApplication.java (EmacsApplication) (findDumpFile): New function. (onCreate): Factor out dump file finding functions to there. * java/org/gnu/emacs/EmacsNative.java (EmacsNative): Update function declarations. * java/org/gnu/emacs/EmacsNoninteractive.java (EmacsNoninteractive): New class. * java/org/gnu/emacs/EmacsService.java (EmacsService, getApkFile) (onCreate): Pass classpath to setEmacsParams. * java/org/gnu/emacs/EmacsThread.java (EmacsThread): Make run an override. * lisp/loadup.el: Don't dump on Android when noninteractive. * lisp/shell.el (shell--command-completion-data): Handle inaccessible directories. * src/Makefile.in (android-emacs): Link with gnulib. * src/android-emacs.c (main): Implement to launch app-process and then EmacsNoninteractive. * src/android.c (setEmacsParams): New argument `class_path'. Don't set stuff up when running noninteractive. * src/android.h (initEmacs): Likewise. * src/androidfont.c (init_androidfont): * src/androidselect.c (init_androidselect): Don't initialize when running noninteractive. * src/emacs.c (load_pdump): New argument `dump_file'. (android_emacs_init): Give new argument `dump_file' to `load_pdump'. * src/sfntfont-android.c (init_sfntfont_android): Don't initialize when running noninteractive.
Diffstat (limited to 'src/android-emacs.c')
-rw-r--r--src/android-emacs.c83
1 files changed, 79 insertions, 4 deletions
diff --git a/src/android-emacs.c b/src/android-emacs.c
index d4fa14e39fb..c1f2a6f43bb 100644
--- a/src/android-emacs.c
+++ b/src/android-emacs.c
@@ -18,13 +18,88 @@ You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <config.h>
-#include "android.h"
+#include <stdio.h>
+#include <alloca.h>
+#include <string.h>
+#include <unistd.h>
-/* android-emacs is a wrapper around libemacs. It simply calls
- android_emacs_init with the argv and argc given to it. */
+/* android-emacs is a wrapper around /system/bin/app_process(64).
+ It invokes app_process(64) with the right class path and then
+ starts org.gnu.emacs.EmacsNoninteractive.
+
+ The main function in that class tries to load an activity thread
+ and obtain a context and asset manager before calling
+ android_emacs_init, which is required for Emacs to find required
+ preloaded Lisp. */
int
main (int argc, char **argv)
{
- return android_emacs_init (argc, argv);
+ char **args;
+ int i;
+ char *bootclasspath, *emacs_class_path;
+
+ /* Allocate enough to hold the arguments to app_process. */
+ args = alloca ((10 + argc) * sizeof *args);
+
+ /* Clear args. */
+ memset (args, 0, (10 + argc) * sizeof *args);
+
+ /* First, figure out what program to start. */
+#if defined __x86_64__ || defined __aarch64__
+ args[0] = (char *) "/system/bin/app_process64";
+#else
+ args[0] = (char *) "/system/bin/app_process";
+#endif
+
+ /* Next, obtain the boot class path. */
+ bootclasspath = getenv ("BOOTCLASSPATH");
+
+ /* And the Emacs class path. */
+ emacs_class_path = getenv ("EMACS_CLASS_PATH");
+
+ if (!bootclasspath)
+ {
+ fprintf (stderr, "The BOOTCLASSPATH environment variable"
+ " is not set. As a result, Emacs does not know"
+ " how to start app_process.\n"
+ "This is likely a change in the Android platform."
+ " Please report this to bug-gnu-emacs@gnu.org.\n");
+ return 1;
+ }
+
+ if (!emacs_class_path)
+ {
+ fprintf (stderr, "EMACS_CLASS_PATH not set."
+ " Please make sure Emacs is being started"
+ " from within a running copy of Emacs.\n");
+ return 1;
+ }
+
+ if (asprintf (&bootclasspath, "-Djava.class.path=%s:%s",
+ bootclasspath, emacs_class_path) < 0)
+ {
+ perror ("asprintf");
+ return 1;
+ }
+
+ args[1] = bootclasspath;
+ args[2] = (char *) "/system/bin";
+ args[3] = (char *) "--nice-name=emacs";
+ args[4] = (char *) "org.gnu.emacs.EmacsNoninteractive";
+
+ /* Arguments from here on are passed to main in
+ EmacsNoninteractive.java. */
+ args[5] = argv[0];
+
+ /* Now copy the rest of the arguments over. */
+ for (i = 1; i < argc; ++i)
+ args[5 + i] = argv[i];
+
+ /* Finally, try to start the app_process. */
+ execvp (args[0], args);
+
+ /* If exit fails, return an error indication. */
+ perror ("exec");
+ return 1;
}