From 515a8cf4005cb146052256ff4b9ac2de895849ae Mon Sep 17 00:00:00 2001 From: Tomaž Vajngerl Date: Mon, 17 Nov 2014 10:47:02 +0100 Subject: android: use ByteBuffer to send or store pointers in JNI bindings Using direct ByteBuffer is much nicer option to store or send pointers between C(++) code and Java via JNI as it handles endiness and pointer size for us. Using "long" type can have unexpected results in 32-bit architectures (mostly Android). This was causing grief especially when Android introduced support for 64-bit architectures starting with SDK 19. Change-Id: Ie92d0f913b668e1724e846d70d1820445d9cb086 --- .../src/org/libreoffice/kit/Document.java | 4 ++-- .../src/org/libreoffice/kit/LibreOfficeKit.java | 3 ++- .../Bootstrap/src/org/libreoffice/kit/Office.java | 12 ++++++----- desktop/source/lib/lokandroid.cxx | 24 +++++++--------------- sal/android/libreofficekit-jni.c | 8 ++++++-- 5 files changed, 24 insertions(+), 27 deletions(-) diff --git a/android/Bootstrap/src/org/libreoffice/kit/Document.java b/android/Bootstrap/src/org/libreoffice/kit/Document.java index 52b9bfdc2674..aad4d5a6dcc4 100644 --- a/android/Bootstrap/src/org/libreoffice/kit/Document.java +++ b/android/Bootstrap/src/org/libreoffice/kit/Document.java @@ -24,9 +24,9 @@ public class Document { public static final int DOCTYPE_DRAWING = 3; public static final int DOCTYPE_OTHER = 4; - private final long handle; + private final ByteBuffer handle; - public Document(long handle) { + public Document(ByteBuffer handle) { this.handle = handle; } diff --git a/android/Bootstrap/src/org/libreoffice/kit/LibreOfficeKit.java b/android/Bootstrap/src/org/libreoffice/kit/LibreOfficeKit.java index 4fe2061c335b..2a60f848e0de 100644 --- a/android/Bootstrap/src/org/libreoffice/kit/LibreOfficeKit.java +++ b/android/Bootstrap/src/org/libreoffice/kit/LibreOfficeKit.java @@ -14,6 +14,7 @@ import android.content.pm.ApplicationInfo; import android.util.Log; import java.io.InputStream; +import java.nio.ByteBuffer; // Native methods in this class are all implemented in // sal/android/lo-bootstrap.c as the lo-bootstrap library is loaded with @@ -34,7 +35,7 @@ public final class LibreOfficeKit // Trigger initialization on the JNI - LOKit side. private static native boolean initializeNative(String dataDir, String cacheDir, String apkFile); - public static native long getLibreOfficeKitHandle(); + public static native ByteBuffer getLibreOfficeKitHandle(); // Wrapper for putenv() public static native void putenv(String string); diff --git a/android/Bootstrap/src/org/libreoffice/kit/Office.java b/android/Bootstrap/src/org/libreoffice/kit/Office.java index bd6144f64b8c..e7d26c5a9b8c 100644 --- a/android/Bootstrap/src/org/libreoffice/kit/Office.java +++ b/android/Bootstrap/src/org/libreoffice/kit/Office.java @@ -9,22 +9,24 @@ package org.libreoffice.kit; +import java.nio.ByteBuffer; + public class Office { - private long handle; + private ByteBuffer handle; - public Office(long handle) { + public Office(ByteBuffer handle) { this.handle = handle; } public native String getError(); - private native long documentLoadNative(String url); + private native ByteBuffer documentLoadNative(String url); public Document documentLoad(String url) { - long documentHandle = documentLoadNative(url); + ByteBuffer documentHandle = documentLoadNative(url); Document document = null; - if (documentHandle > 0) { + if (documentHandle != null) { document = new Document(documentHandle); } return document; diff --git a/desktop/source/lib/lokandroid.cxx b/desktop/source/lib/lokandroid.cxx index 707996ed1c88..0f408ea6c020 100644 --- a/desktop/source/lib/lokandroid.cxx +++ b/desktop/source/lib/lokandroid.cxx @@ -25,21 +25,14 @@ jfieldID getHandleField(JNIEnv* pEnv, jobject aObject) { jclass clazz = pEnv->GetObjectClass(aObject); - return pEnv->GetFieldID(clazz, "handle", "J"); + return pEnv->GetFieldID(clazz, "handle", "Ljava/nio/ByteBuffer;"); } template T* getHandle(JNIEnv* pEnv, jobject aObject) { - jlong aHandle = pEnv->GetLongField(aObject, getHandleField(pEnv, aObject)); - return reinterpret_cast(aHandle); -} - -template -void setHandle(JNIEnv* pEnv, jobject aObject, T* aType) -{ - jlong aHandle = reinterpret_cast(aType); - pEnv->SetLongField(aObject, getHandleField(pEnv, aObject), aHandle); + jobject aHandle = pEnv->GetObjectField(aObject, getHandleField(pEnv, aObject)); + return reinterpret_cast(pEnv->GetDirectBufferAddress(aHandle)); } const char* copyJavaString(JNIEnv* pEnv, jstring aJavaString) @@ -60,11 +53,6 @@ extern "C" SAL_JNI_EXPORT jstring JNICALL Java_org_libreoffice_kit_Office_getErr return pEnv->NewStringUTF(pError); } -extern "C" SAL_JNI_EXPORT void JNICALL Java_org_libreoffice_kit_Office_initialize(JNIEnv* pEnv, jobject aObject, jlong aLokHandle) -{ - pEnv->SetLongField(aObject, getHandleField(pEnv, aObject), aLokHandle); -} - extern "C" SAL_JNI_EXPORT void JNICALL Java_org_libreoffice_kit_Office_destroy(JNIEnv* pEnv, jobject aObject) { LibreOfficeKit* pLibreOfficeKit = getHandle(pEnv, aObject); @@ -80,13 +68,15 @@ extern "C" SAL_JNI_EXPORT void JNICALL Java_org_libreoffice_kit_Office_destroyAn _exit(0); } -extern "C" SAL_JNI_EXPORT jlong JNICALL Java_org_libreoffice_kit_Office_documentLoadNative(JNIEnv* pEnv, jobject aObject, jstring documentPath) +extern "C" SAL_JNI_EXPORT jobject JNICALL Java_org_libreoffice_kit_Office_documentLoadNative(JNIEnv* pEnv, jobject aObject, jstring documentPath) { const char* aCloneDocumentPath = copyJavaString(pEnv, documentPath); LibreOfficeKit* pLibreOfficeKit = getHandle(pEnv, aObject); LibreOfficeKitDocument* pDocument = pLibreOfficeKit->pClass->documentLoad(pLibreOfficeKit, aCloneDocumentPath); - return (jlong) pDocument; + jobject aHandle = pEnv->NewDirectByteBuffer((void*) pDocument, sizeof(LibreOfficeKitDocument)); + + return aHandle; } /* Document */ diff --git a/sal/android/libreofficekit-jni.c b/sal/android/libreofficekit-jni.c index 416198234051..41fa97e8273d 100644 --- a/sal/android/libreofficekit-jni.c +++ b/sal/android/libreofficekit-jni.c @@ -147,13 +147,17 @@ jboolean Java_org_libreoffice_kit_LibreOfficeKit_initializeNative } __attribute__ ((visibility("default"))) -jlong Java_org_libreoffice_kit_LibreOfficeKit_getLibreOfficeKitHandle +jobject Java_org_libreoffice_kit_LibreOfficeKit_getLibreOfficeKitHandle (JNIEnv* env, jobject clazz) { + LibreOfficeKit* aOffice; + (void) env; (void) clazz; - return (jlong) (intptr_t) libreofficekit_hook(full_program_dir); + aOffice = libreofficekit_hook(full_program_dir); + + return (*env)->NewDirectByteBuffer(env, (void*) aOffice, sizeof(LibreOfficeKit)); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3