Kaydet (Commit) 515a8cf4 authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl

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
üst 333a894b
...@@ -24,9 +24,9 @@ public class Document { ...@@ -24,9 +24,9 @@ public class Document {
public static final int DOCTYPE_DRAWING = 3; public static final int DOCTYPE_DRAWING = 3;
public static final int DOCTYPE_OTHER = 4; 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; this.handle = handle;
} }
......
...@@ -14,6 +14,7 @@ import android.content.pm.ApplicationInfo; ...@@ -14,6 +14,7 @@ import android.content.pm.ApplicationInfo;
import android.util.Log; import android.util.Log;
import java.io.InputStream; import java.io.InputStream;
import java.nio.ByteBuffer;
// Native methods in this class are all implemented in // Native methods in this class are all implemented in
// sal/android/lo-bootstrap.c as the lo-bootstrap library is loaded with // sal/android/lo-bootstrap.c as the lo-bootstrap library is loaded with
...@@ -34,7 +35,7 @@ public final class LibreOfficeKit ...@@ -34,7 +35,7 @@ public final class LibreOfficeKit
// Trigger initialization on the JNI - LOKit side. // Trigger initialization on the JNI - LOKit side.
private static native boolean initializeNative(String dataDir, String cacheDir, String apkFile); private static native boolean initializeNative(String dataDir, String cacheDir, String apkFile);
public static native long getLibreOfficeKitHandle(); public static native ByteBuffer getLibreOfficeKitHandle();
// Wrapper for putenv() // Wrapper for putenv()
public static native void putenv(String string); public static native void putenv(String string);
......
...@@ -9,22 +9,24 @@ ...@@ -9,22 +9,24 @@
package org.libreoffice.kit; package org.libreoffice.kit;
import java.nio.ByteBuffer;
public class Office { public class Office {
private long handle; private ByteBuffer handle;
public Office(long handle) { public Office(ByteBuffer handle) {
this.handle = handle; this.handle = handle;
} }
public native String getError(); public native String getError();
private native long documentLoadNative(String url); private native ByteBuffer documentLoadNative(String url);
public Document documentLoad(String url) { public Document documentLoad(String url) {
long documentHandle = documentLoadNative(url); ByteBuffer documentHandle = documentLoadNative(url);
Document document = null; Document document = null;
if (documentHandle > 0) { if (documentHandle != null) {
document = new Document(documentHandle); document = new Document(documentHandle);
} }
return document; return document;
......
...@@ -25,21 +25,14 @@ ...@@ -25,21 +25,14 @@
jfieldID getHandleField(JNIEnv* pEnv, jobject aObject) jfieldID getHandleField(JNIEnv* pEnv, jobject aObject)
{ {
jclass clazz = pEnv->GetObjectClass(aObject); jclass clazz = pEnv->GetObjectClass(aObject);
return pEnv->GetFieldID(clazz, "handle", "J"); return pEnv->GetFieldID(clazz, "handle", "Ljava/nio/ByteBuffer;");
} }
template <typename T> template <typename T>
T* getHandle(JNIEnv* pEnv, jobject aObject) T* getHandle(JNIEnv* pEnv, jobject aObject)
{ {
jlong aHandle = pEnv->GetLongField(aObject, getHandleField(pEnv, aObject)); jobject aHandle = pEnv->GetObjectField(aObject, getHandleField(pEnv, aObject));
return reinterpret_cast<T*>(aHandle); return reinterpret_cast<T*>(pEnv->GetDirectBufferAddress(aHandle));
}
template <typename T>
void setHandle(JNIEnv* pEnv, jobject aObject, T* aType)
{
jlong aHandle = reinterpret_cast<jlong>(aType);
pEnv->SetLongField(aObject, getHandleField(pEnv, aObject), aHandle);
} }
const char* copyJavaString(JNIEnv* pEnv, jstring aJavaString) const char* copyJavaString(JNIEnv* pEnv, jstring aJavaString)
...@@ -60,11 +53,6 @@ extern "C" SAL_JNI_EXPORT jstring JNICALL Java_org_libreoffice_kit_Office_getErr ...@@ -60,11 +53,6 @@ extern "C" SAL_JNI_EXPORT jstring JNICALL Java_org_libreoffice_kit_Office_getErr
return pEnv->NewStringUTF(pError); 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) extern "C" SAL_JNI_EXPORT void JNICALL Java_org_libreoffice_kit_Office_destroy(JNIEnv* pEnv, jobject aObject)
{ {
LibreOfficeKit* pLibreOfficeKit = getHandle<LibreOfficeKit>(pEnv, aObject); LibreOfficeKit* pLibreOfficeKit = getHandle<LibreOfficeKit>(pEnv, aObject);
...@@ -80,13 +68,15 @@ extern "C" SAL_JNI_EXPORT void JNICALL Java_org_libreoffice_kit_Office_destroyAn ...@@ -80,13 +68,15 @@ extern "C" SAL_JNI_EXPORT void JNICALL Java_org_libreoffice_kit_Office_destroyAn
_exit(0); _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); const char* aCloneDocumentPath = copyJavaString(pEnv, documentPath);
LibreOfficeKit* pLibreOfficeKit = getHandle<LibreOfficeKit>(pEnv, aObject); LibreOfficeKit* pLibreOfficeKit = getHandle<LibreOfficeKit>(pEnv, aObject);
LibreOfficeKitDocument* pDocument = pLibreOfficeKit->pClass->documentLoad(pLibreOfficeKit, aCloneDocumentPath); LibreOfficeKitDocument* pDocument = pLibreOfficeKit->pClass->documentLoad(pLibreOfficeKit, aCloneDocumentPath);
return (jlong) pDocument; jobject aHandle = pEnv->NewDirectByteBuffer((void*) pDocument, sizeof(LibreOfficeKitDocument));
return aHandle;
} }
/* Document */ /* Document */
......
...@@ -147,13 +147,17 @@ jboolean Java_org_libreoffice_kit_LibreOfficeKit_initializeNative ...@@ -147,13 +147,17 @@ jboolean Java_org_libreoffice_kit_LibreOfficeKit_initializeNative
} }
__attribute__ ((visibility("default"))) __attribute__ ((visibility("default")))
jlong Java_org_libreoffice_kit_LibreOfficeKit_getLibreOfficeKitHandle jobject Java_org_libreoffice_kit_LibreOfficeKit_getLibreOfficeKitHandle
(JNIEnv* env, jobject clazz) (JNIEnv* env, jobject clazz)
{ {
LibreOfficeKit* aOffice;
(void) env; (void) env;
(void) clazz; (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: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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