diff options
| author | Po Lu | 2023-02-25 20:11:48 +0800 |
|---|---|---|
| committer | Po Lu | 2023-02-25 20:11:48 +0800 |
| commit | df29bb71fc47b5e24fa971b668e4fa09dd6d244d (patch) | |
| tree | 78672c8e9f3b3db96f59a2bf6f81107d9eadb4af /java | |
| parent | 8e4c5db193dc7baee5846520fe8b63d8bea99148 (diff) | |
| download | emacs-df29bb71fc47b5e24fa971b668e4fa09dd6d244d.tar.gz emacs-df29bb71fc47b5e24fa971b668e4fa09dd6d244d.zip | |
Update Android port
* java/org/gnu/emacs/EmacsNoninteractive.java (main): Port to
Android 2.2.
* src/android-asset.h (AAsset_openFileDescriptor): Delete stub
function.
* src/android.c (android_check_compressed_file): Delete
function.
(android_open): Stop trying to find compressed files or to use
the system provided file descriptor. Explain why.
Diffstat (limited to 'java')
| -rw-r--r-- | java/org/gnu/emacs/EmacsNoninteractive.java | 118 |
1 files changed, 76 insertions, 42 deletions
diff --git a/java/org/gnu/emacs/EmacsNoninteractive.java b/java/org/gnu/emacs/EmacsNoninteractive.java index 4da82f2f894..30901edb75f 100644 --- a/java/org/gnu/emacs/EmacsNoninteractive.java +++ b/java/org/gnu/emacs/EmacsNoninteractive.java | |||
| @@ -87,56 +87,23 @@ public class EmacsNoninteractive | |||
| 87 | 87 | ||
| 88 | /* Create and attach the activity thread. */ | 88 | /* Create and attach the activity thread. */ |
| 89 | activityThread = method.invoke (null); | 89 | activityThread = method.invoke (null); |
| 90 | context = null; | ||
| 90 | 91 | ||
| 91 | /* Now get an LoadedApk. */ | 92 | /* Now get an LoadedApk. */ |
| 92 | loadedApkClass = Class.forName ("android.app.LoadedApk"); | ||
| 93 | 93 | ||
| 94 | /* Get a LoadedApk. How to do this varies by Android version. | 94 | try |
| 95 | On Android 2.3.3 and earlier, there is no | ||
| 96 | ``compatibilityInfo'' argument to getPackageInfo. */ | ||
| 97 | |||
| 98 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) | ||
| 99 | { | 95 | { |
| 100 | method | 96 | loadedApkClass = Class.forName ("android.app.LoadedApk"); |
| 101 | = activityThreadClass.getMethod ("getPackageInfo", | ||
| 102 | String.class, | ||
| 103 | int.class); | ||
| 104 | loadedApk = method.invoke (activityThread, "org.gnu.emacs", | ||
| 105 | 0); | ||
| 106 | } | 97 | } |
| 107 | else | 98 | catch (ClassNotFoundException exception) |
| 108 | { | 99 | { |
| 109 | compatibilityInfoClass | 100 | /* Android 2.2 has no LoadedApk class, but fortunately it |
| 110 | = Class.forName ("android.content.res.CompatibilityInfo"); | 101 | does not need to be used, since contexts can be |
| 111 | 102 | directly created. */ | |
| 112 | method | ||
| 113 | = activityThreadClass.getMethod ("getPackageInfo", | ||
| 114 | String.class, | ||
| 115 | compatibilityInfoClass, | ||
| 116 | int.class); | ||
| 117 | loadedApk = method.invoke (activityThread, "org.gnu.emacs", null, | ||
| 118 | 0); | ||
| 119 | } | ||
| 120 | |||
| 121 | if (loadedApk == null) | ||
| 122 | throw new RuntimeException ("getPackageInfo returned NULL"); | ||
| 123 | 103 | ||
| 124 | /* Now, get a context. */ | 104 | loadedApkClass = null; |
| 125 | contextImplClass = Class.forName ("android.app.ContextImpl"); | 105 | contextImplClass = Class.forName ("android.app.ContextImpl"); |
| 126 | 106 | ||
| 127 | try | ||
| 128 | { | ||
| 129 | method = contextImplClass.getDeclaredMethod ("createAppContext", | ||
| 130 | activityThreadClass, | ||
| 131 | loadedApkClass); | ||
| 132 | method.setAccessible (true); | ||
| 133 | context = (Context) method.invoke (null, activityThread, loadedApk); | ||
| 134 | } | ||
| 135 | catch (NoSuchMethodException exception) | ||
| 136 | { | ||
| 137 | /* Older Android versions don't have createAppContext, but | ||
| 138 | instead require creating a ContextImpl, and then | ||
| 139 | calling createPackageContext. */ | ||
| 140 | method = activityThreadClass.getDeclaredMethod ("getSystemContext"); | 107 | method = activityThreadClass.getDeclaredMethod ("getSystemContext"); |
| 141 | context = (Context) method.invoke (activityThread); | 108 | context = (Context) method.invoke (activityThread); |
| 142 | method = contextImplClass.getDeclaredMethod ("createPackageContext", | 109 | method = contextImplClass.getDeclaredMethod ("createPackageContext", |
| @@ -147,6 +114,73 @@ public class EmacsNoninteractive | |||
| 147 | 0); | 114 | 0); |
| 148 | } | 115 | } |
| 149 | 116 | ||
| 117 | /* If the context has not already been created, then do what | ||
| 118 | is appropriate for newer versions of Android. */ | ||
| 119 | |||
| 120 | if (context == null) | ||
| 121 | { | ||
| 122 | /* Get a LoadedApk. How to do this varies by Android version. | ||
| 123 | On Android 2.3.3 and earlier, there is no | ||
| 124 | ``compatibilityInfo'' argument to getPackageInfo. */ | ||
| 125 | |||
| 126 | if (Build.VERSION.SDK_INT | ||
| 127 | <= Build.VERSION_CODES.GINGERBREAD_MR1) | ||
| 128 | { | ||
| 129 | method | ||
| 130 | = activityThreadClass.getMethod ("getPackageInfo", | ||
| 131 | String.class, | ||
| 132 | int.class); | ||
| 133 | loadedApk = method.invoke (activityThread, "org.gnu.emacs", | ||
| 134 | 0); | ||
| 135 | } | ||
| 136 | else | ||
| 137 | { | ||
| 138 | compatibilityInfoClass | ||
| 139 | = Class.forName ("android.content.res.CompatibilityInfo"); | ||
| 140 | |||
| 141 | method | ||
| 142 | = activityThreadClass.getMethod ("getPackageInfo", | ||
| 143 | String.class, | ||
| 144 | compatibilityInfoClass, | ||
| 145 | int.class); | ||
| 146 | loadedApk = method.invoke (activityThread, "org.gnu.emacs", | ||
| 147 | null, 0); | ||
| 148 | } | ||
| 149 | |||
| 150 | if (loadedApk == null) | ||
| 151 | throw new RuntimeException ("getPackageInfo returned NULL"); | ||
| 152 | |||
| 153 | /* Now, get a context. */ | ||
| 154 | contextImplClass = Class.forName ("android.app.ContextImpl"); | ||
| 155 | |||
| 156 | try | ||
| 157 | { | ||
| 158 | method | ||
| 159 | = contextImplClass.getDeclaredMethod ("createAppContext", | ||
| 160 | activityThreadClass, | ||
| 161 | loadedApkClass); | ||
| 162 | method.setAccessible (true); | ||
| 163 | context = (Context) method.invoke (null, activityThread, | ||
| 164 | loadedApk); | ||
| 165 | } | ||
| 166 | catch (NoSuchMethodException exception) | ||
| 167 | { | ||
| 168 | /* Older Android versions don't have createAppContext, but | ||
| 169 | instead require creating a ContextImpl, and then | ||
| 170 | calling createPackageContext. */ | ||
| 171 | method | ||
| 172 | = activityThreadClass.getDeclaredMethod ("getSystemContext"); | ||
| 173 | context = (Context) method.invoke (activityThread); | ||
| 174 | method | ||
| 175 | = contextImplClass.getDeclaredMethod ("createPackageContext", | ||
| 176 | String.class, | ||
| 177 | int.class); | ||
| 178 | method.setAccessible (true); | ||
| 179 | context = (Context) method.invoke (context, "org.gnu.emacs", | ||
| 180 | 0); | ||
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 150 | /* Don't actually start the looper or anything. Instead, obtain | 184 | /* Don't actually start the looper or anything. Instead, obtain |
| 151 | an AssetManager. */ | 185 | an AssetManager. */ |
| 152 | assets = context.getAssets (); | 186 | assets = context.getAssets (); |