office-gobmx/sal/android/libreofficekit-jni.c
Jan Holesovsky ed52e65bcb android: LibreOfficeKit needs the path to program/ as the starting point.
Change-Id: I7d4534649361e1bfa2c285e67e6765a4be55ec69
2014-07-01 13:48:28 +02:00

162 lines
4.7 KiB
C

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <jni.h>
#include <android/log.h>
#include <osl/detail/android-bootstrap.h>
#include <LibreOfficeKit/LibreOfficeKit.h>
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "LibreOfficeKit", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "LibreOfficeKit", __VA_ARGS__))
/* These are valid / used in all apps. */
extern const char* data_dir;
extern const char* cache_dir;
extern void* apk_file;
extern int apk_file_size;
extern void Java_org_libreoffice_android_Bootstrap_putenv(JNIEnv* env, jobject clazz, jstring string);
extern void Java_org_libreoffice_android_Bootstrap_redirect_1stdio(JNIEnv* env, jobject clazz, jboolean state);
extern LibreOfficeKit* libreofficekit_hook(const char* install_path);
static LibreOfficeKit* gpOffice;
/// Call the same method from Bootstrap.
__attribute__ ((visibility("default")))
void
Java_org_libreoffice_kit_LibreOfficeKit_putenv
(JNIEnv* env, jobject clazz, jstring string)
{
Java_org_libreoffice_android_Bootstrap_putenv(env, clazz, string);
}
/// Call the same method from Bootstrap.
__attribute__ ((visibility("default")))
void Java_org_libreoffice_kit_LibreOfficeKit_redirectStdio
(JNIEnv* env, jobject clazz, jboolean state)
{
Java_org_libreoffice_android_Bootstrap_redirect_1stdio(env, clazz, state);
}
/// Initialize the LibreOfficeKit.
__attribute__ ((visibility("default")))
jboolean Java_org_libreoffice_kit_LibreOfficeKit_initializeNative
(JNIEnv* env, jobject clazz,
jstring dataDir, jstring cacheDir, jstring apkFile)
{
struct stat st;
int fd;
const char *dataDirPath;
const char *cacheDirPath;
const char *apkFilePath;
const char program_dir[] = "/program";
size_t data_dir_len;
char *full_program_dir;
(void) clazz;
dataDirPath = (*env)->GetStringUTFChars(env, dataDir, NULL);
data_dir = strdup(dataDirPath);
(*env)->ReleaseStringUTFChars(env, dataDir, dataDirPath);
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);
if (fd == -1) {
LOGE("Could not open %s", apkFilePath);
(*env)->ReleaseStringUTFChars(env, apkFile, apkFilePath);
return JNI_FALSE;
}
if (fstat(fd, &st) == -1) {
LOGE("Could not fstat %s", apkFilePath);
close(fd);
(*env)->ReleaseStringUTFChars(env, apkFile, apkFilePath);
return JNI_FALSE;
}
apk_file = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
close(fd);
if (apk_file == MAP_FAILED) {
LOGE("Could not mmap %s", apkFilePath);
(*env)->ReleaseStringUTFChars(env, apkFile, apkFilePath);
return JNI_FALSE;
}
apk_file_size = st.st_size;
(*env)->ReleaseStringUTFChars(env, apkFile, apkFilePath);
if (!setup_cdir())
{
LOGE("setup_cdir failed");
return JNI_FALSE;
}
if (!setup_assets_tree())
{
LOGE("setup_assets_tree failed");
return JNI_FALSE;
}
// Extract files from the .apk that can't be used mmapped directly from it
extract_files(UNPACK_TREE, UNPACK_TREE, 0);
extract_files(UNPACK_TREE_GZ, UNPACK_TREE_GZ, 1);
// LibreOfficeKit expects a path to the program/ directory
data_dir_len = strlen(data_dir);
full_program_dir = malloc(data_dir_len + sizeof(program_dir));
strncpy(full_program_dir, data_dir, data_dir_len);
strncpy(full_program_dir + data_dir_len, program_dir, sizeof(program_dir));
// Initialize LibreOfficeKit
gpOffice = libreofficekit_hook(full_program_dir);
free(full_program_dir);
if (!gpOffice)
{
LOGE("libreofficekit_hook returned null");
return JNI_FALSE;
}
LOGI("LibreOfficeKit successfully initialized");
return JNI_TRUE;
}
__attribute__ ((visibility("default")))
jlong Java_org_libreoffice_kit_LibreOfficeKit_getLibreOfficeKitHandle
(JNIEnv* env, jobject clazz)
{
(void) env;
(void) clazz;
return (jlong) (intptr_t) gpOffice;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */