aboutsummaryrefslogtreecommitdiffstats
path: root/src/androidvfs.c
diff options
context:
space:
mode:
authorPo Lu2024-06-12 16:44:21 +0800
committerPo Lu2024-06-12 16:44:21 +0800
commit02e70821b3800a082aec215a9ab8adbfafe9ad76 (patch)
tree87daf46f3c3efadaaa93ea859f48541bfe7e6b34 /src/androidvfs.c
parentf543ec18f44fa64d06e1ab45e1484326f8451ebe (diff)
downloademacs-02e70821b3800a082aec215a9ab8adbfafe9ad76.tar.gz
emacs-02e70821b3800a082aec215a9ab8adbfafe9ad76.zip
Restore functionality on Android 2.2
* java/Makefile.in (install_temp): Do not compress directory-tree and generate such files in a special format that stores file sizes. * lib-src/asset-directory-tool.c (struct directory_tree): New field st_size. (need_file_size): New variable. (main_1, main_2, main): Write file sizes before sibling offsets if `--api-8' is specified. * src/android-asset.h (struct android_asset_manager): New field open. (struct android_asset): New field name. (AAssetManager_fromJava): Load AssetManager#open. (AAssetManager_open): If a directory tree has already been loaded, search for a matching asset and load its size thence, to avoid the requirement of an AssetFileDescriptor. (AAsset_close): Don't assume asset->fd exists. Release asset->name. (AAsset_getLength): Likewise. (android_asset_create_stream): If asset->name exists, call AssetManager#open, in order to open compressed files. * src/androidvfs.c (OLD_ANDROID_ASSETS): Define to 1 on API 8. (android_extract_long, android_scan_directory_tree): Mark arguments as const. Adjust offsets when OLD_ANDROID_ASSETS. (android_is_directory, android_init_assets, android_afs_readdir): Likewise. * src/lread.c (lread_fstat): Define to sys_fstat, not fstat.
Diffstat (limited to 'src/androidvfs.c')
-rw-r--r--src/androidvfs.c62
1 files changed, 47 insertions, 15 deletions
diff --git a/src/androidvfs.c b/src/androidvfs.c
index c0bd86e54b8..d28a74918f6 100644
--- a/src/androidvfs.c
+++ b/src/androidvfs.c
@@ -46,8 +46,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
46#if __ANDROID_API__ >= 9 46#if __ANDROID_API__ >= 9
47#include <android/asset_manager.h> 47#include <android/asset_manager.h>
48#include <android/asset_manager_jni.h> 48#include <android/asset_manager_jni.h>
49#define OLD_ANDROID_ASSETS 0
49#else /* __ANDROID_API__ < 9 */ 50#else /* __ANDROID_API__ < 9 */
50#include "android-asset.h" 51#include "android-asset.h"
52#define OLD_ANDROID_ASSETS 1
51#endif /* __ANDROID_API__ >= 9 */ 53#endif /* __ANDROID_API__ >= 9 */
52 54
53#include <android/log.h> 55#include <android/log.h>
@@ -1001,7 +1003,7 @@ static AAssetManager *asset_manager;
1001/* Read an unaligned (32-bit) long from the address POINTER. */ 1003/* Read an unaligned (32-bit) long from the address POINTER. */
1002 1004
1003static unsigned int 1005static unsigned int
1004android_extract_long (char *pointer) 1006android_extract_long (const char *pointer)
1005{ 1007{
1006 unsigned int number; 1008 unsigned int number;
1007 1009
@@ -1022,16 +1024,20 @@ android_extract_long (char *pointer)
1022 directory. */ 1024 directory. */
1023 1025
1024static const char * 1026static const char *
1025android_scan_directory_tree (char *file, size_t *limit_return) 1027android_scan_directory_tree (const char *file, size_t *limit_return)
1026{ 1028{
1027 char *token, *saveptr, *copy, *start, *max, *limit; 1029 char *token, *saveptr, *copy, *start, *max, *limit;
1028 size_t token_length, ntokens, i, len; 1030 size_t token_length, ntokens, i, len;
1029 char *tokens[10]; 1031 char *tokens[20];
1030 1032
1031 USE_SAFE_ALLOCA; 1033 USE_SAFE_ALLOCA;
1032 1034
1033 /* Skip past the 5 byte header. */ 1035 /* Skip past the 5 or 9 byte header. */
1036#if !OLD_ANDROID_ASSETS
1034 start = (char *) directory_tree + 5; 1037 start = (char *) directory_tree + 5;
1038#else /* OLD_ANDROID_ASSETS */
1039 start = (char *) directory_tree + 9;
1040#endif /* OLD_ANDROID_ASSETS */
1035 1041
1036 /* Figure out the current limit. */ 1042 /* Figure out the current limit. */
1037 limit = (char *) directory_tree + directory_tree_size; 1043 limit = (char *) directory_tree + directory_tree_size;
@@ -1098,9 +1104,9 @@ android_scan_directory_tree (char *file, size_t *limit_return)
1098 { 1104 {
1099 /* They probably match. Find the NULL byte. It must be 1105 /* They probably match. Find the NULL byte. It must be
1100 either one byte past start + token_length, with the last 1106 either one byte past start + token_length, with the last
1101 byte a trailing slash (indicating that it is a 1107 byte a trailing slash (indicating that it is a directory),
1102 directory), or just start + token_length. Return 4 bytes 1108 or just start + token_length. Return 4 or 8 bytes past the
1103 past the next NULL byte. */ 1109 next NULL byte. */
1104 1110
1105 max = memchr (start, 0, limit - start); 1111 max = memchr (start, 0, limit - start);
1106 1112
@@ -1113,13 +1119,14 @@ android_scan_directory_tree (char *file, size_t *limit_return)
1113 last token. Otherwise, set it as start and the limit as 1119 last token. Otherwise, set it as start and the limit as
1114 start + the offset and continue the loop. */ 1120 start + the offset and continue the loop. */
1115 1121
1116 if (max && max + 5 <= limit) 1122 if (max && max + (OLD_ANDROID_ASSETS ? 9 : 5) <= limit)
1117 { 1123 {
1118 if (i < ntokens - 1) 1124 if (i < ntokens - 1)
1119 { 1125 {
1120 start = max + 5; 1126 start = max + (OLD_ANDROID_ASSETS ? 9 : 5);
1121 limit = ((char *) directory_tree 1127 limit = ((char *) directory_tree
1122 + android_extract_long (max + 1)); 1128 + android_extract_long (max + (OLD_ANDROID_ASSETS
1129 ? 5 : 1)));
1123 1130
1124 /* Make sure limit is still in range. */ 1131 /* Make sure limit is still in range. */
1125 if (limit > directory_tree + directory_tree_size 1132 if (limit > directory_tree + directory_tree_size
@@ -1137,10 +1144,12 @@ android_scan_directory_tree (char *file, size_t *limit_return)
1137 { 1144 {
1138 /* Figure out the limit. */ 1145 /* Figure out the limit. */
1139 if (limit_return) 1146 if (limit_return)
1140 *limit_return = android_extract_long (max + 1); 1147 *limit_return
1148 = android_extract_long (max + (OLD_ANDROID_ASSETS
1149 ? 5 : 1));
1141 1150
1142 /* Go to the end of this file. */ 1151 /* Go to the end of this file. */
1143 max += 5; 1152 max += (OLD_ANDROID_ASSETS ? 9 : 5);
1144 } 1153 }
1145 1154
1146 SAFE_FREE (); 1155 SAFE_FREE ();
@@ -1161,11 +1170,12 @@ android_scan_directory_tree (char *file, size_t *limit_return)
1161 1170
1162 start = memchr (start, 0, limit - start); 1171 start = memchr (start, 0, limit - start);
1163 1172
1164 if (!start || start + 5 > limit) 1173 if (!start || start + (OLD_ANDROID_ASSETS ? 9 : 5) > limit)
1165 goto fail; 1174 goto fail;
1166 1175
1167 start = ((char *) directory_tree 1176 start = ((char *) directory_tree
1168 + android_extract_long (start + 1)); 1177 + android_extract_long (start
1178 + (OLD_ANDROID_ASSETS ? 5 : 1)));
1169 1179
1170 /* Make sure start is still in bounds. */ 1180 /* Make sure start is still in bounds. */
1171 1181
@@ -1192,13 +1202,20 @@ android_is_directory (const char *dir)
1192{ 1202{
1193 /* If the directory is the directory tree, then it is a 1203 /* If the directory is the directory tree, then it is a
1194 directory. */ 1204 directory. */
1195 if (dir == directory_tree + 5) 1205 if (dir == directory_tree + (OLD_ANDROID_ASSETS ? 9 : 5))
1196 return true; 1206 return true;
1197 1207
1208#if !OLD_ANDROID_ASSETS
1198 /* Otherwise, look 5 bytes behind. If it is `/', then it is a 1209 /* Otherwise, look 5 bytes behind. If it is `/', then it is a
1199 directory. */ 1210 directory. */
1200 return (dir - 6 >= directory_tree 1211 return (dir - 6 >= directory_tree
1201 && *(dir - 6) == '/'); 1212 && *(dir - 6) == '/');
1213#else /* OLD_ANDROID_ASSETS */
1214 /* Otherwise, look 9 bytes behind. If it is `/', then it is a
1215 directory. */
1216 return (dir - 10 >= directory_tree
1217 && *(dir - 10) == '/');
1218#endif /* OLD_ANDROID_ASSETS */
1202} 1219}
1203 1220
1204/* Initialize asset retrieval. ENV should be a JNI environment for 1221/* Initialize asset retrieval. ENV should be a JNI environment for
@@ -1232,6 +1249,7 @@ android_init_assets (JNIEnv *env, jobject manager)
1232 /* Now figure out how big the directory tree is, and compare the 1249 /* Now figure out how big the directory tree is, and compare the
1233 first few bytes. */ 1250 first few bytes. */
1234 directory_tree_size = AAsset_getLength (asset); 1251 directory_tree_size = AAsset_getLength (asset);
1252#if !OLD_ANDROID_ASSETS
1235 if (directory_tree_size < 5 1253 if (directory_tree_size < 5
1236 || memcmp (directory_tree, "EMACS", 5)) 1254 || memcmp (directory_tree, "EMACS", 5))
1237 { 1255 {
@@ -1239,6 +1257,15 @@ android_init_assets (JNIEnv *env, jobject manager)
1239 "Directory tree has bad magic"); 1257 "Directory tree has bad magic");
1240 emacs_abort (); 1258 emacs_abort ();
1241 } 1259 }
1260#else /* OLD_ANDROID_ASSETS */
1261 if (directory_tree_size < 9
1262 || memcmp (directory_tree, "EMACS____", 9))
1263 {
1264 __android_log_print (ANDROID_LOG_FATAL, __func__,
1265 "Directory tree has bad magic");
1266 emacs_abort ();
1267 }
1268#endif /* OLD_ANDROID_ASSETS */
1242 1269
1243 /* Hold a VM reference to the asset manager to prevent the native 1270 /* Hold a VM reference to the asset manager to prevent the native
1244 object from being deleted. */ 1271 object from being deleted. */
@@ -2287,8 +2314,13 @@ android_afs_readdir (struct android_vdir *vdir)
2287 dirent.d_type = DT_REG; 2314 dirent.d_type = DT_REG;
2288 2315
2289 /* Forward dir->asset_dir to the file past last. */ 2316 /* Forward dir->asset_dir to the file past last. */
2317#if !OLD_ANDROID_ASSETS
2290 dir->asset_dir = ((char *) directory_tree 2318 dir->asset_dir = ((char *) directory_tree
2291 + android_extract_long ((char *) last)); 2319 + android_extract_long ((char *) last));
2320#else /* OLD_ANDROID_ASSETS */
2321 dir->asset_dir = ((char *) directory_tree
2322 + android_extract_long ((char *) last + 4));
2323#endif /* OLD_ANDROID_ASSETS */
2292 2324
2293 return &dirent; 2325 return &dirent;
2294} 2326}