Kaydet (Commit) 970b53e0 authored tarafından Tor Lillqvist's avatar Tor Lillqvist Kaydeden (comit) Tor Lillqvist

Enable storing some files gzipped in the .apk

We gzip them separately in the Makefile and the gzipped result will be
stored without (further) compression in the .apk.

Use this to store the ttf font files. Shaves off a bit .apk size.

This might seem a bit odd way to do it, why not store these files in
the normal Zip compressed fashion in the .apk? It seems hard to tell
Ant (based on path, not extension) what files to compress and what
not, so we have to keep telling it to not (further) compress any files
at all.

Change-Id: I0d40d8811e6c9df6b28c285845b1db225507f5d4
üst f5cc79a1
......@@ -59,6 +59,7 @@ public class Bootstrap extends NativeActivity
// seems.
private static native boolean setup(String dataDir,
String cacheDir,
String apkFile,
String[] ld_library_path);
......@@ -133,7 +134,10 @@ public class Bootstrap extends NativeActivity
String[] llpa = llp.split(":");
if (!setup(dataDir, activity.getApplication().getPackageResourcePath(), llpa))
if (!setup(dataDir,
activity.getApplication().getCacheDir().getAbsolutePath(),
activity.getApplication().getPackageResourcePath(),
llpa))
return;
// Extract files from the .apk that can't be used mmapped directly from it
......
......@@ -118,13 +118,13 @@ copy-stuff:
# understand "/assets" paths.
mkdir -p assets/unpack/etc/fonts
cp fonts.conf assets/unpack/etc/fonts
mkdir -p assets/unpack/user/fonts
# $UserInstallation/user/fonts is added to the fontconfig path in
# vcl/generic/fontmanager/helper.cxx: psp::getFontPath(). UserInstallation is
# set to the app's data dir above.
cp $(OUTDIR)/pck/Liberation*.ttf assets/unpack/user/fonts
cp $(OUTDIR)/pck/Gen*.ttf assets/unpack/user/fonts
cp $(OUTDIR)/pck/opens___.ttf assets/unpack/user/fonts
mkdir -p assets/gz.unpack/user/fonts
for F in $(OUTDIR)/pck/Liberation*.ttf $(OUTDIR)/pck/Gen*.ttf $(OUTDIR)/pck/opens___.ttf; do \
gzip -9 <$$F >assets/gz.unpack/user/fonts/`basename $$F`; \
done
#
# Then gdbserver and gdb.setup so that we can debug with ndk-gdb.
#
......
......@@ -41,6 +41,7 @@
#include <dlfcn.h>
#include <sys/mman.h>
#include <zlib.h>
#include <jni.h>
#include <android/log.h>
......@@ -82,6 +83,7 @@ static int sleep_time = 0;
/* These are valid / used in all apps. */
static const char *data_dir;
static const char *cache_dir;
static const char **library_locations;
static void *apk_file;
static int apk_file_size;
......@@ -312,21 +314,24 @@ JNI_OnLoad(JavaVM* vm, void* reserved)
}
// public static native boolean setup(String dataDir,
// String cacheDir,
// String apkFile,
// String[] ld_library_path);
__attribute__ ((visibility("default")))
jboolean
Java_org_libreoffice_android_Bootstrap_setup__Ljava_lang_String_2Ljava_lang_String_2_3Ljava_lang_String_2
Java_org_libreoffice_android_Bootstrap_setup__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2_3Ljava_lang_String_2
(JNIEnv* env,
jobject clazz,
jstring dataDir,
jstring cacheDir,
jstring apkFile,
jobjectArray ld_library_path)
{
struct stat st;
int i, n, fd;
const char *dataDirPath;
const char *cacheDirPath;
const char *apkFilePath;
char *lib_dir;
......@@ -359,6 +364,12 @@ Java_org_libreoffice_android_Bootstrap_setup__Ljava_lang_String_2Ljava_lang_Stri
for (n = 0; library_locations[n] != NULL; n++)
LOGI("library_locations[%d] = %s", n, library_locations[n]);
cacheDirPath = (*env)->GetStringUTFChars(env, cacheDir, NULL);
cache_dir = strdup(cacheDirPath);
(*env)->ReleaseStringUTFChars(env, cacheDir, cacheDirPath);
apkFilePath = (*env)->GetStringUTFChars(env, apkFile, NULL);
fd = open(apkFilePath, O_RDONLY);
......@@ -743,6 +754,7 @@ lo_dlcall_argc_argv(void *function,
}
#define UNPACK_TREE "/assets/unpack"
#define UNPACK_TREE_GZ "/assets/gz.unpack"
static int
mkdir_p(const char *dirname)
......@@ -770,8 +782,70 @@ mkdir_p(const char *dirname)
return 1;
}
static int
extract_gzipped(const char *filename,
const char *apkentry,
int size,
FILE *f)
{
gzFile gzfd;
int gzerrno;
int nbytes;
char buf[5000];
int total = 0;
char *tmpname;
FILE *tmp;
tmpname = malloc(strlen(cache_dir) + strlen("/tmp.gz") + 1);
strcpy(tmpname, cache_dir);
strcat(tmpname, "/tmp.gz");
tmp = fopen(tmpname, "w+");
unlink(tmpname);
if (tmp == NULL) {
LOGE("extract_gzipped: could not create %s: %s", tmpname, strerror(errno));
free(tmpname);
return 0;
}
if (fwrite(apkentry, size, 1, tmp) != 1) {
LOGE("extract_gzipped: could not write gzipped entry to %s: %s", tmpname, strerror(errno));
fclose(tmp);
free(tmpname);
return 0;
}
free(tmpname);
rewind(tmp);
gzfd = gzdopen(fileno(tmp), "rb");
if (gzfd == NULL) {
LOGE("extract_gzipped: gzdopen failed");
fclose(tmp);
return 0;
}
while ((nbytes = gzread(gzfd, buf, sizeof(buf))) > 0) {
fwrite(buf, nbytes, 1, f);
total += nbytes;
}
if (nbytes == -1) {
LOGE("extract_gzipped: Could not gzread from %s: %s", filename, gzerror(gzfd, &gzerrno));
return total;
}
if (gzclose(gzfd) == -1) {
LOGE("extract_gzipped: gzclose failed");
return total;
}
return total;
}
static void
extract_files(const char *prefix)
extract_files(const char *root,
const char *prefix,
int gzipped)
{
lo_apk_dir *tree = lo_apk_opendir(prefix);
struct dirent *dent;
......@@ -789,7 +863,7 @@ extract_files(const char *prefix)
strcpy(subdir, prefix);
strcat(subdir, "/");
strcat(subdir, dent->d_name);
extract_files(subdir);
extract_files(root, subdir, gzipped);
free(subdir);
} else {
char *filename;
......@@ -811,10 +885,10 @@ extract_files(const char *prefix)
continue;
}
newfilename = malloc(strlen(data_dir) + 1 + strlen(prefix) - sizeof(UNPACK_TREE) + 1 + strlen(dent->d_name) + 1);
newfilename = malloc(strlen(data_dir) + 1 + strlen(prefix) - strlen(root) + strlen(dent->d_name) + 1);
strcpy(newfilename, data_dir);
strcat(newfilename, "/");
strcat(newfilename, prefix + sizeof(UNPACK_TREE));
strcat(newfilename, prefix + strlen(root) + 1);
if (!mkdir_p(newfilename)) {
free(filename);
......@@ -826,7 +900,7 @@ extract_files(const char *prefix)
strcat(newfilename, dent->d_name);
if (stat(newfilename, &st) == 0 &&
st.st_size == size) {
(gzipped || st.st_size == size)) {
free(filename);
free(newfilename);
continue;
......@@ -840,12 +914,17 @@ extract_files(const char *prefix)
continue;
}
if (fwrite(apkentry, size, 1, f) != 1) {
LOGE("extract_files: Could not write %d bytes to %s: %s", size, newfilename, strerror(errno));
if (!gzipped) {
if (fwrite(apkentry, size, 1, f) != 1) {
LOGE("extract_files: Could not write %d bytes to %s: %s", size, newfilename, strerror(errno));
} else {
LOGI("extract_files: Copied %s to %s: %d bytes", filename, newfilename, size);
}
} else {
size = extract_gzipped(filename, apkentry, size, f);
LOGI("extract_files: Decompressed %s to %s: %d bytes", filename, newfilename, size);
}
LOGI("extract_files: Copied %s to %s: %d bytes", filename, newfilename, size);
fclose(f);
free(filename);
......@@ -865,7 +944,8 @@ Java_org_libreoffice_android_Bootstrap_extract_1files(JNIEnv* env,
(void) env;
(void) clazz;
extract_files(UNPACK_TREE);
extract_files(UNPACK_TREE, UNPACK_TREE, 0);
extract_files(UNPACK_TREE_GZ, UNPACK_TREE_GZ, 1);
}
/* Android's JNI works only to libraries loaded through Java's
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment