aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorPo Lu2023-02-10 23:03:43 +0800
committerPo Lu2023-02-10 23:03:43 +0800
commitdc120c7ad62d5f79fe50f72431d3b9bb2d7f1558 (patch)
tree47e2993d9d3e92d23f7d328fd1d82e4c01ffcf71 /java
parent2489126e6856bf1b06a26127b73e4bfff857f68f (diff)
downloademacs-dc120c7ad62d5f79fe50f72431d3b9bb2d7f1558.tar.gz
emacs-dc120c7ad62d5f79fe50f72431d3b9bb2d7f1558.zip
Improve appearance of the Android preferences screen
* .gitignore: Add org/gnu/emacs/R.java. * cross/Makefile.in (top_builddir): Include verbose.mk. Rewrite rules to print nice looking statements. * doc/emacs/android.texi (Android, Android Startup) (Android Environment, Android Windowing, Android Fonts): * doc/emacs/emacs.texi (Top): Add an extra ``Android Troubleshooting'' node and move troubleshooting details there. * java/Makefile.in: Generate R.java; improve appearance by using verbose.mk. * java/org/gnu/emacs/EmacsPreferencesActivity.java: Reimplement in terms of PreferencesActivity. * java/org/gnu/emacs/EmacsView.java (handleDirtyBitmap): Avoid flicker. * java/res/xml/preferences.xml: New file. * src/verbose.mk.in (AM_V_AAPT, AM_V_SILENT): New variables.
Diffstat (limited to 'java')
-rw-r--r--java/Makefile.in104
-rw-r--r--java/org/gnu/emacs/EmacsPreferencesActivity.java123
-rw-r--r--java/org/gnu/emacs/EmacsView.java5
-rw-r--r--java/res/xml/preferences.xml28
4 files changed, 171 insertions, 89 deletions
diff --git a/java/Makefile.in b/java/Makefile.in
index 155754b59d2..fc0d23980e4 100644
--- a/java/Makefile.in
+++ b/java/Makefile.in
@@ -54,18 +54,33 @@ JARSIGNER_FLAGS =
54endif 54endif
55 55
56SIGN_EMACS = -keystore emacs.keystore -storepass emacs1 $(JARSIGNER_FLAGS) 56SIGN_EMACS = -keystore emacs.keystore -storepass emacs1 $(JARSIGNER_FLAGS)
57SIGN_EMACS_V2 = sign --v2-signing-enabled --ks emacs.keystore \ 57SIGN_EMACS_V2 = sign --v2-signing-enabled --ks emacs.keystore \
58 --debuggable-apk-permitted --ks-pass pass:emacs1 58 --debuggable-apk-permitted --ks-pass pass:emacs1
59 59
60JAVA_FILES = $(wildcard $(srcdir)/org/gnu/emacs/*.java) 60JAVA_FILES := $(wildcard $(srcdir)/org/gnu/emacs/*.java)
61RESOURCE_FILES = $(wildcard $(srcdir)/res/drawable/*) 61RESOURCE_FILES := $(foreach file,$(wildcard $(srcdir)/res/*), \
62CLASS_FILES = $(foreach file,$(JAVA_FILES),$(basename $(file)).class) 62 $(wildcard $(file)/*))
63
64# R.java is a file generated by the `aapt' utility containing
65# constants that can then be used to locate ``resource identifiers''.
66# It is not a regular file and should not be compiled as Java source
67# code. Instead, it is automatically included by the Java compiler.
68RESOURCE_FILE := $(srcdir)/org/gnu/emacs/R.java
69
70# CLASS_FILES is what should actually be built and included in the
71# resulting Emacs executable. The Java compiler might generate more
72# than one class file for each source file, so this only serves as a
73# list of dependencies for Make.
74CLASS_FILES := $(foreach file,$(JAVA_FILES),$(basename $(file)).class)
75
76# Remove RESOURCE_FILE from JAVA_FILES, if it is already present.
77JAVA_FILES := $(filter-out $(RESOURCE_FILE),$(JAVA_FILES))
63 78
64# Compute the name for the Emacs application package. This should be: 79# Compute the name for the Emacs application package. This should be:
65# emacs-<version>-<min-sdk>-<abi>.apk 80# emacs-<version>-<min-sdk>-<abi>.apk
66 81
67ANDROID_MIN_SDK = @ANDROID_MIN_SDK@ 82ANDROID_MIN_SDK := @ANDROID_MIN_SDK@
68APK_NAME = emacs-$(version)-$(ANDROID_MIN_SDK)-$(ANDROID_ABI).apk 83APK_NAME := emacs-$(version)-$(ANDROID_MIN_SDK)-$(ANDROID_ABI).apk
69 84
70# How this stuff works. 85# How this stuff works.
71 86
@@ -113,19 +128,25 @@ include $(top_builddir)/cross/ndk-build/ndk-build.mk
113$(libsrc)/asset-directory-tool: 128$(libsrc)/asset-directory-tool:
114 $(MAKE) -C $(libsrc) $(notdir $@) 129 $(MAKE) -C $(libsrc) $(notdir $@)
115 130
116emacs.apk-in: $(CROSS_BINS) $(CROSS_LIBS) $(libsrc)/asset-directory-tool \ 131# install_tmp is a directory used to generate emacs.apk-in.
117 AndroidManifest.xml $(NDK_BUILD_SHARED) $(RESOURCE_FILES) 132# That is then packaged into $(APK_NAME).
133
134.PHONY: install_temp install_temp/assets/directory-tree
135install_temp: $(CROSS_BINS) $(CROSS_LIBS) $(NDK_BUILD_SHARED) \
136 $(RESOURCE_FILES)
137 $(AM_V_GEN)
118# Make the working directory for this stuff 138# Make the working directory for this stuff
119 rm -rf install_temp 139 $(AM_V_SILENT) rm -rf install_temp
120 mkdir -p install_temp/lib/$(ANDROID_ABI) 140 $(AM_V_SILENT) mkdir -p install_temp/lib/$(ANDROID_ABI)
121 mkdir -p install_temp/assets/etc 141 $(AM_V_SILENT) mkdir -p install_temp/assets/etc
122 mkdir -p install_temp/assets/lisp 142 $(AM_V_SILENT) mkdir -p install_temp/assets/lisp
123 mkdir -p install_temp/assets/info 143 $(AM_V_SILENT) mkdir -p install_temp/assets/info
124# Install architecture independents to assets/etc and assets/lisp 144# Install architecture independents to assets/etc and assets/lisp
125 cp -r $(top_builddir)/lisp install_temp/assets 145 $(AM_V_SILENT) cp -r $(top_builddir)/lisp install_temp/assets
126 cp -r $(top_builddir)/etc install_temp/assets 146 $(AM_V_SILENT) cp -r $(top_builddir)/etc install_temp/assets
127 cp -r $(top_builddir)/info install_temp/assets 147 $(AM_V_SILENT) cp -r $(top_builddir)/info install_temp/assets
128# Remove undesirable files from those directories. 148# Remove undesirable files from those directories.
149 $(AM_V_SILENT) \
129 for subdir in `find install_temp -type d -print`; do \ 150 for subdir in `find install_temp -type d -print`; do \
130 chmod a+rx $${subdir} ; \ 151 chmod a+rx $${subdir} ; \
131 rm -rf $${subdir}/.gitignore ; \ 152 rm -rf $${subdir}/.gitignore ; \
@@ -139,34 +160,44 @@ emacs.apk-in: $(CROSS_BINS) $(CROSS_LIBS) $(libsrc)/asset-directory-tool \
139 rm -rf $${subdir}/Makefile; \ 160 rm -rf $${subdir}/Makefile; \
140 done 161 done
141# Generate the directory tree for those directories. 162# Generate the directory tree for those directories.
142 $(libsrc)/asset-directory-tool install_temp/assets \
143 install_temp/assets/directory-tree
144# Install architecture dependents to lib/$(ANDROID_ABI). This 163# Install architecture dependents to lib/$(ANDROID_ABI). This
145# perculiar naming scheme is required to make Android preserve these 164# perculiar naming scheme is required to make Android preserve these
146# binaries upon installation. 165# binaries upon installation.
166 $(AM_V_SILENT) \
147 for file in $(CROSS_BINS); do \ 167 for file in $(CROSS_BINS); do \
148 if [ -x $$file ]; then \ 168 if [ -x $$file ]; then \
149 filename=`basename $$file`; \ 169 filename=`basename $$file`; \
150 cp -f $$file install_temp/lib/$(ANDROID_ABI)/lib$${filename}.so; \ 170 cp -f $$file install_temp/lib/$(ANDROID_ABI)/lib$${filename}.so; \
151 fi \ 171 fi \
152 done 172 done
173 $(AM_V_SILENT) \
153 for file in $(CROSS_LIBS); do \ 174 for file in $(CROSS_LIBS); do \
154 if [ -x $$file ]; then \ 175 if [ -x $$file ]; then \
155 cp -f $$file install_temp/lib/$(ANDROID_ABI); \ 176 cp -f $$file install_temp/lib/$(ANDROID_ABI); \
156 fi \ 177 fi \
157 done 178 done
158ifneq ($(NDK_BUILD_SHARED),) 179ifneq ($(NDK_BUILD_SHARED),)
159 cp -f $(NDK_BUILD_SHARED) install_temp/lib/$(ANDROID_ABI) 180 $(AM_V_SILENT) cp -f $(NDK_BUILD_SHARED) \
181 install_temp/lib/$(ANDROID_ABI)
160endif 182endif
183
184install_temp/assets/directory-tree: $(libsrc)/asset-directory-tool install_temp
185 $(AM_V_GEN) $(libsrc)/asset-directory-tool install_temp/assets \
186 install_temp/assets/directory-tree
187
188emacs.apk-in: install_temp install_temp/assets/directory-tree \
189 AndroidManifest.xml
161# Package everything. Specifying the assets on this command line is 190# Package everything. Specifying the assets on this command line is
162# necessary for AAssetManager_getNextFileName to work on old versions 191# necessary for AAssetManager_getNextFileName to work on old versions
163# of Android. Make sure not to generate R.java, as it's not required 192# of Android. Make sure not to generate R.java, as it's already been
164# by Emacs. 193# generated.
165 $(AAPT) package -I "$(ANDROID_JAR)" -F $@ -f \ 194 $(AM_V_AAPT) $(AAPT) p -I "$(ANDROID_JAR)" -F $@ \
166 -M AndroidManifest.xml -A install_temp/assets \ 195 -f -M AndroidManifest.xml -A install_temp/assets \
167 -S res -J install_temp 196 -S res -J install_temp
168 pushd install_temp; $(AAPT) add ../$@ `find lib -type f`; popd 197 $(AM_V_SILENT) pushd install_temp &> /dev/null; \
169 rm -rf install_temp 198 $(AAPT) add ../$@ `find lib -type f`; \
199 popd &> /dev/null
200 $(AM_V_SILENT) rm -rf install_temp
170 201
171# Makefile itself. 202# Makefile itself.
172.PRECIOUS: ../config.status Makefile 203.PRECIOUS: ../config.status Makefile
@@ -180,6 +211,14 @@ AndroidManifest.xml: $(top_srcdir)/configure.ac $(top_srcdir)/m4/*.m4 \
180 AndroidManifest.xml.in 211 AndroidManifest.xml.in
181 pushd ..; ./config.status java/AndroidManifest.xml; popd 212 pushd ..; ./config.status java/AndroidManifest.xml; popd
182 213
214# R.java:
215$(RESOURCE_FILE): $(RESOURCE_FILES)
216 $(AM_V_GEN) $(AAPT) p -I "$(ANDROID_JAR)" -f \
217 -J $(dir $@) -M AndroidManifest.xml -S res
218
219# Make all class files depend on R.java being built.
220$(CLASS_FILES): $(RESOURCE_FILE)
221
183.SUFFIXES: .java .class 222.SUFFIXES: .java .class
184.java.class &: 223.java.class &:
185 $(AM_V_JAVAC) $(JAVAC) $(JAVAFLAGS) $< 224 $(AM_V_JAVAC) $(JAVAC) $(JAVAFLAGS) $<
@@ -199,17 +238,18 @@ classes.dex: $(CLASS_FILES)
199.PHONY: clean maintainer-clean 238.PHONY: clean maintainer-clean
200 239
201$(APK_NAME): classes.dex emacs.apk-in emacs.keystore 240$(APK_NAME): classes.dex emacs.apk-in emacs.keystore
202 cp -f emacs.apk-in $@.unaligned 241 $(AM_V_GEN)
203 $(AAPT) add $@.unaligned classes.dex 242 $(AM_V_SILENT) cp -f emacs.apk-in $@.unaligned
204 $(JARSIGNER) $(SIGN_EMACS) $@.unaligned "Emacs keystore" 243 $(AM_V_SILENT) $(AAPT) add $@.unaligned classes.dex
205 $(ZIPALIGN) -f 4 $@.unaligned $@ 244 $(AM_V_SILENT) $(JARSIGNER) $(SIGN_EMACS) $@.unaligned "Emacs keystore"
245 $(AM_V_SILENT) $(ZIPALIGN) -f 4 $@.unaligned $@
206# Signing must happen after alignment! 246# Signing must happen after alignment!
207 $(APKSIGNER) $(SIGN_EMACS_V2) $@ 247 $(AM_V_SILENT) $(APKSIGNER) $(SIGN_EMACS_V2) $@
208 rm -f $@.unaligned *.idsig 248 $(AM_V_SILENT) rm -f $@.unaligned *.idsig
209 249
210clean: 250clean:
211 rm -f *.apk emacs.apk-in *.dex *.unaligned *.class *.idsig 251 rm -f *.apk emacs.apk-in *.dex *.unaligned *.class *.idsig
212 rm -rf install-temp 252 rm -rf install-temp $(RESOURCE_FILE)
213 find . -name '*.class' -delete 253 find . -name '*.class' -delete
214 254
215maintainer-clean distclean bootstrap-clean: clean 255maintainer-clean distclean bootstrap-clean: clean
diff --git a/java/org/gnu/emacs/EmacsPreferencesActivity.java b/java/org/gnu/emacs/EmacsPreferencesActivity.java
index 6cef7c37516..85639fe9236 100644
--- a/java/org/gnu/emacs/EmacsPreferencesActivity.java
+++ b/java/org/gnu/emacs/EmacsPreferencesActivity.java
@@ -22,27 +22,28 @@ package org.gnu.emacs;
22import java.io.File; 22import java.io.File;
23 23
24import android.app.Activity; 24import android.app.Activity;
25
25import android.content.Intent; 26import android.content.Intent;
27
26import android.os.Bundle; 28import android.os.Bundle;
27import android.os.Build; 29import android.os.Build;
28import android.view.View;
29import android.view.ViewGroup.LayoutParams;
30import android.widget.LinearLayout;
31import android.widget.TextView;
32 30
33import android.R; 31import android.widget.Toast;
32
33import android.preference.*;
34 34
35/* This module provides a ``preferences'' display for Emacs. It is 35/* This module provides a ``preferences'' display for Emacs. It is
36 supposed to be launched from inside the Settings application to 36 supposed to be launched from inside the Settings application to
37 perform various actions, such as starting Emacs with the ``-Q'' 37 perform various actions, such as starting Emacs with the ``-Q''
38 option, which would not be possible otherwise, as there is no 38 option, which would not be possible otherwise, as there is no
39 command line on Android. */ 39 command line on Android.
40 40
41public class EmacsPreferencesActivity extends Activity 41 Android provides a preferences activity, but it is deprecated.
42{ 42 Unfortunately, there is no alternative that looks the same way. */
43 /* The linear layout associated with the activity. */
44 private LinearLayout layout;
45 43
44@SuppressWarnings ("deprecation")
45public class EmacsPreferencesActivity extends PreferenceActivity
46{
46 /* Restart Emacs with -Q. Call EmacsThread.exit to kill Emacs now, and 47 /* Restart Emacs with -Q. Call EmacsThread.exit to kill Emacs now, and
47 tell the system to EmacsActivity with some parameters later. */ 48 tell the system to EmacsActivity with some parameters later. */
48 49
@@ -59,72 +60,82 @@ public class EmacsPreferencesActivity extends Activity
59 System.exit (0); 60 System.exit (0);
60 } 61 }
61 62
63 /* Erase Emacs's dump file. */
64
65 private void
66 eraseDumpFile ()
67 {
68 String wantedDumpFile;
69 File file;
70 Toast toast;
71
72 wantedDumpFile = ("emacs-" + EmacsNative.getFingerprint ()
73 + ".pdmp");
74 file = new File (getFilesDir (), wantedDumpFile);
75
76 if (file.exists ())
77 file.delete ();
78
79 /* Make sure to clear EmacsApplication.dumpFileName, or
80 starting Emacs without restarting this program will
81 make Emacs try to load a nonexistent dump file. */
82 EmacsApplication.dumpFileName = null;
83
84 /* Display a message stating that the dump file has been
85 erased. */
86 toast = Toast.makeText (this, "Dump file removed",
87 Toast.LENGTH_SHORT);
88 toast.show ();
89 }
90
62 @Override 91 @Override
63 public void 92 public void
64 onCreate (Bundle savedInstanceState) 93 onCreate (Bundle savedInstanceState)
65 { 94 {
66 LinearLayout layout; 95 Preference tem;
67 TextView textView; 96 Preference.OnPreferenceClickListener listener;
68 LinearLayout.LayoutParams params;
69 int resid;
70 97
71 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 98 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
72 setTheme (R.style.Theme_DeviceDefault_Settings); 99 setTheme (android.R.style.Theme_DeviceDefault_Settings);
73 else if (Build.VERSION.SDK_INT 100 else if (Build.VERSION.SDK_INT
74 >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) 101 >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
75 setTheme (R.style.Theme_DeviceDefault); 102 setTheme (android.R.style.Theme_DeviceDefault);
103
104 /* This must come before using any preference APIs. */
105 super.onCreate (savedInstanceState);
76 106
77 layout = new LinearLayout (this); 107 /* Add preferences from the XML file where they are defined. */
78 layout.setOrientation (LinearLayout.VERTICAL); 108 addPreferencesFromResource (R.xml.preferences);
79 setContentView (layout);
80 109
81 textView = new TextView (this); 110 /* Now, set up on click handlers for each of the preferences
82 textView.setPadding (8, 20, 20, 8); 111 items. */
83 112
84 params = new LinearLayout.LayoutParams (LayoutParams.MATCH_PARENT, 113 tem = findPreference ("start_quick");
85 LayoutParams.WRAP_CONTENT); 114
86 textView.setLayoutParams (params); 115 listener = new Preference.OnPreferenceClickListener () {
87 textView.setText ("(Re)start Emacs with -Q");
88 textView.setOnClickListener (new View.OnClickListener () {
89 @Override 116 @Override
90 public void 117 public boolean
91 onClick (View view) 118 onPreferenceClick (Preference preference)
92 { 119 {
93 startEmacsQ (); 120 startEmacsQ ();
121 return true;
94 } 122 }
95 }); 123 };
96 layout.addView (textView); 124
125 tem.setOnPreferenceClickListener (listener);
97 126
98 textView = new TextView (this); 127 tem = findPreference ("erase_dump");
99 textView.setPadding (8, 20, 20, 8);
100 128
101 params = new LinearLayout.LayoutParams (LayoutParams.MATCH_PARENT, 129 listener = new Preference.OnPreferenceClickListener () {
102 LayoutParams.WRAP_CONTENT);
103 textView.setLayoutParams (params);
104 textView.setText ("Erase dump file");
105 textView.setOnClickListener (new View.OnClickListener () {
106 @Override 130 @Override
107 public void 131 public boolean
108 onClick (View view) 132 onPreferenceClick (Preference preference)
109 { 133 {
110 String wantedDumpFile; 134 eraseDumpFile ();
111 File file; 135 return true;
112
113 wantedDumpFile = ("emacs-" + EmacsNative.getFingerprint ()
114 + ".pdmp");
115 file = new File (getFilesDir (), wantedDumpFile);
116
117 if (file.exists ())
118 file.delete ();
119
120 /* Make sure to clear EmacsApplication.dumpFileName, or
121 starting Emacs without restarting this program will
122 make Emacs try to load a nonexistent dump file. */
123 EmacsApplication.dumpFileName = null;
124 } 136 }
125 }); 137 };
126 layout.addView (textView);
127 138
128 super.onCreate (savedInstanceState); 139 tem.setOnPreferenceClickListener (listener);
129 } 140 }
130}; 141};
diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java
index 0416301101c..4fc8104e31f 100644
--- a/java/org/gnu/emacs/EmacsView.java
+++ b/java/org/gnu/emacs/EmacsView.java
@@ -181,7 +181,10 @@ public class EmacsView extends ViewGroup
181 if (oldBitmap != null) 181 if (oldBitmap != null)
182 { 182 {
183 oldBitmap.recycle (); 183 oldBitmap.recycle ();
184 surfaceView.setBitmap (null, null); 184
185 /* Make sure to set the view's bitmap to the new bitmap, or
186 ugly flicker can result. */
187 surfaceView.setBitmap (bitmap, null);
185 } 188 }
186 189
187 /* Some Android versions still don't free the bitmap until the 190 /* Some Android versions still don't free the bitmap until the
diff --git a/java/res/xml/preferences.xml b/java/res/xml/preferences.xml
new file mode 100644
index 00000000000..f0c3abb52e7
--- /dev/null
+++ b/java/res/xml/preferences.xml
@@ -0,0 +1,28 @@
1<!-- Descriptions for the preferences screen for GNU Emacs on Android.
2
3Copyright (C) 2023 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. -->
19
20<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
21 <Preference android:key="start_quick"
22 android:title="Restart Emacs with -Q"
23 android:summary="Restart Emacs, but do not load site lisp or init files."/>
24
25 <Preference android:key="erase_dump"
26 android:title="Delete dump file"
27 android:summary="Remove the dumped state created when Emacs was installed"/>
28</PreferenceScreen>