diff options
11 files changed, 80 insertions, 103 deletions
diff --git a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java index 12bc424..b275688 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java +++ b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmAccountTest.java @@ -60,12 +60,8 @@ public class OlmAccountTest { @BeforeClass public static void setUpClass(){ - // enable UTF-8 specific conversion for pre Marshmallow(23) android versions, - // due to issue described here: https://github.com/eclipsesource/J2V8/issues/142 - boolean isSpecificUtf8ConversionEnabled = android.os.Build.VERSION.SDK_INT < 23; - // load native lib - mOlmManager = new OlmManager(isSpecificUtf8ConversionEnabled); + mOlmManager = new OlmManager(); String olmLibVersion = mOlmManager.getOlmLibVersion(); assertNotNull(olmLibVersion); diff --git a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupSessionTest.java b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupSessionTest.java index 2152a8d..111032e 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupSessionTest.java +++ b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmGroupSessionTest.java @@ -61,13 +61,8 @@ public class OlmGroupSessionTest { @BeforeClass public static void setUpClass(){ - - // enable UTF-8 specific conversion for pre Marshmallow(23) android versions, - // due to issue described here: https://github.com/eclipsesource/J2V8/issues/142 - boolean isSpecificUtf8ConversionEnabled = android.os.Build.VERSION.SDK_INT < 23; - // load native lib - mOlmManager = new OlmManager(isSpecificUtf8ConversionEnabled); + mOlmManager = new OlmManager(); String version = mOlmManager.getOlmLibVersion(); assertNotNull(version); @@ -151,13 +146,18 @@ public class OlmGroupSessionTest { @Test public void test10InboundDecryptMessage() { - // test decrypted message - StringBuffer errorMsg = new StringBuffer(); - OlmInboundGroupSession.DecryptIndex index = new OlmInboundGroupSession.DecryptIndex(); + mBobDecryptedMessage = null; + OlmInboundGroupSession.DecryptMessageResult result = null; - mBobDecryptedMessage = mBobInboundGroupSession.decryptMessage(mAliceToBobMessage, index, errorMsg); + try { + result = mBobInboundGroupSession.decryptMessage(mAliceToBobMessage); + } catch (Exception e) { + } + + // test decrypted message + mBobDecryptedMessage = result.mDecryptedMessage; assertFalse(TextUtils.isEmpty(mBobDecryptedMessage)); - assertTrue(0==index.mIndex); + assertTrue(0 == result.mIndex); } @Test @@ -440,14 +440,17 @@ public class OlmGroupSessionTest { assertTrue("Exception in test18TestBadCharacterCrashInDecrypt, Exception code=" + e.getExceptionCode(), false); } - StringBuffer errorMsg = new StringBuffer(); - OlmInboundGroupSession.DecryptIndex index = new OlmInboundGroupSession.DecryptIndex(); + OlmInboundGroupSession.DecryptMessageResult result = null; - String decryptedMessage = bobInboundGroupSession.decryptMessage(msgToDecryptWithEmoji, index, errorMsg); - assertNotNull(decryptedMessage); - assertTrue(13==index.mIndex); - } + try { + result = bobInboundGroupSession.decryptMessage(msgToDecryptWithEmoji); + } catch (Exception e) { + assertTrue("Exception in test18TestBadCharacterCrashInDecrypt, Exception code=" + e.getMessage(), false); + } + assertNotNull(result.mDecryptedMessage); + assertTrue(13 == result.mIndex); + } /** * Specific test to check an error message is returned by decryptMessage() API.<br> @@ -458,8 +461,6 @@ public class OlmGroupSessionTest { public void test19TestErrorMessageReturnedInDecrypt() { OlmInboundGroupSession bobInboundGroupSession=null; final String EXPECTED_ERROR_MESSAGE= "INVALID_BASE64"; - StringBuffer errorMsg = new StringBuffer(); - OlmInboundGroupSession.DecryptIndex index = new OlmInboundGroupSession.DecryptIndex(); String sessionKeyRef = "AgAAAAycZE6AekIctJWYxd2AWLOY15YmxZODm/WkgbpWkyycp6ytSp/R+wo84jRrzBNWmv6ySLTZ9R0EDOk9VI2eZyQ6Efdwyo1mAvrWvTkZl9yALPdkOIVHywyG65f1SNiLrnsln3hgsT1vUrISGyKtsljoUgQpr3JDPEhD0ilAi63QBjhnGCW252b+7nF+43rb6O6lwm93LaVwe2341Gdp6EkhTUvetALezEqDOtKN00wVqAbq0RQAnUJIowxHbMswg+FyoR1K1oCjnVEoF23O9xlAn5g1XtuBZP3moJlR2lwsBA"; String corruptedEncryptedMsg = "AwgANYTHINGf87ge45ge7gr*/rg5ganything4gr41rrgr4re55tanythingmcsXUkhDv0UePj922kgf+"; @@ -471,12 +472,15 @@ public class OlmGroupSessionTest { assertTrue("Exception in test19TestErrorMessageReturnedInDecrypt, Exception code=" + e.getExceptionCode(), false); } - String decryptedMessage = bobInboundGroupSession.decryptMessage(corruptedEncryptedMsg, index, errorMsg); + String exceptionMessage = null; + try { + bobInboundGroupSession.decryptMessage(corruptedEncryptedMsg); + } catch (OlmInboundGroupSession.DecryptMessageException e) { + exceptionMessage = e.getMessage(); + } + assertTrue(0!=EXPECTED_ERROR_MESSAGE.length()); - assertTrue(EXPECTED_ERROR_MESSAGE.equals(errorMsg.toString())); - assertTrue(null==decryptedMessage); - assertTrue(0==index.mIndex); + assertTrue(EXPECTED_ERROR_MESSAGE.equals(exceptionMessage)); } - } diff --git a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java index b25d865..099f2a5 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java +++ b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmSessionTest.java @@ -53,12 +53,8 @@ public class OlmSessionTest { @BeforeClass public static void setUpClass(){ - // enable UTF-8 specific conversion for pre Marshmallow(23) android versions, - // due to issue described here: https://github.com/eclipsesource/J2V8/issues/142 - boolean isSpecificUtf8ConversionEnabled = android.os.Build.VERSION.SDK_INT < 23; - // load native lib - mOlmManager = new OlmManager(isSpecificUtf8ConversionEnabled); + mOlmManager = new OlmManager(); String version = mOlmManager.getOlmLibVersion(); assertNotNull(version); diff --git a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmUtilityTest.java b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmUtilityTest.java index 9a97205..e3ca544 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmUtilityTest.java +++ b/java/android/OlmLibSdk/olm-sdk/src/androidTest/java/org/matrix/olm/OlmUtilityTest.java @@ -44,12 +44,8 @@ public class OlmUtilityTest { @BeforeClass public static void setUpClass(){ - // enable UTF-8 specific conversion for pre Marshmallow(23) android versions, - // due to issue described here: https://github.com/eclipsesource/J2V8/issues/142 - boolean isSpecificUtf8ConversionEnabled = android.os.Build.VERSION.SDK_INT < 23; - // load native lib - mOlmManager = new OlmManager(isSpecificUtf8ConversionEnabled); + mOlmManager = new OlmManager(); String version = mOlmManager.getOlmLibVersion(); assertNotNull(version); diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java index 2e32a30..61d0ec6 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java +++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmInboundGroupSession.java @@ -42,14 +42,26 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri private transient long mNativeId; /** - * Wrapper class to be used in {@link #decryptMessage(String, DecryptIndex, StringBuffer)} + * Result in {@link #decryptMessage(String)} */ - static public class DecryptIndex { + static class DecryptMessageResult { + /** decrypt message **/ + public String mDecryptedMessage; + /** decrypt index **/ public long mIndex; } /** + * Exception triggered in {@link #decryptMessage(String)} + */ + static public class DecryptMessageException extends Exception { + public DecryptMessageException(String message) { + super(message); + } + } + + /** * Constructor.<br> * Create and save a new native session instance ID and start a new inbound group session. * The session key parameter is retrieved from an outbound group session @@ -59,7 +71,7 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri */ public OlmInboundGroupSession(String aSessionKey) throws OlmException { if(createNewSession()) { - if( 0 != initInboundGroupSessionWithSessionKey(aSessionKey)) { + if (0 != initInboundGroupSessionWithSessionKey(aSessionKey)) { releaseSession();// prevent memory leak before throwing throw new OlmException(OlmException.EXCEPTION_CODE_INIT_INBOUND_GROUP_SESSION,OlmException.EXCEPTION_MSG_INIT_INBOUND_GROUP_SESSION); } @@ -137,24 +149,24 @@ public class OlmInboundGroupSession extends CommonSerializeUtils implements Seri * Decrypt the message passed in parameter.<br> * In case of error, null is returned and an error message description is provided in aErrorMsg. * @param aEncryptedMsg the message to be decrypted - * @param aDecryptIndex_out decrypted message index - * @param aErrorMsg error message description - * @return the decrypted message if operation succeed, null otherwise. + * @return the decrypted message information + * @exception DecryptMessageException if there is an error while */ - public String decryptMessage(String aEncryptedMsg, DecryptIndex aDecryptIndex_out, StringBuffer aErrorMsg) { - String decryptedMessage = null; + public DecryptMessageResult decryptMessage(String aEncryptedMsg) throws DecryptMessageException { + DecryptMessageResult result = new DecryptMessageResult(); - // sanity check - if(null == aErrorMsg) { - Log.e(LOG_TAG,"## decryptMessage(): invalid parameter - aErrorMsg=null"); - } else { - aErrorMsg.setLength(0); - decryptedMessage = decryptMessageJni(aEncryptedMsg, aDecryptIndex_out, aErrorMsg, OlmManager.ENABLE_STRING_UTF8_SPECIFIC_CONVERSION); + StringBuffer errorMsg = new StringBuffer(); + result.mDecryptedMessage = decryptMessageJni(aEncryptedMsg, result, errorMsg); + + // check if there is an error while decrypting + if (0 != errorMsg.length()) { + throw new DecryptMessageException(errorMsg.toString()); } - return decryptedMessage; + + return result; } - private native String decryptMessageJni(String aEncryptedMsg, DecryptIndex aDecryptIndex_out, StringBuffer aErrorMsg, boolean aIsUtf8ConversionRequired); + private native String decryptMessageJni(String aEncryptedMsg, DecryptMessageResult aDecryptMessageResult, StringBuffer aErrorMsg); /** * Kick off the serialization mechanism. diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmManager.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmManager.java index 57170c4..1605392 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmManager.java +++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmManager.java @@ -26,17 +26,11 @@ import android.util.Log; public class OlmManager { private static final String LOG_TAG = "OlmManager"; private static final String SDK_OLM_VERSION = "V0.1.0_1"; - /** specific flag to enable UTF-8 specific conversion for pre Marshmallow(23) android versions.<br> - * <a href="https://github.com/eclipsesource/J2V8/issues/142">NDK NewStringUTF() UTF8 issue</a> - **/ - public static boolean ENABLE_STRING_UTF8_SPECIFIC_CONVERSION; /** * Constructor. - * @param aIsUtf8SpecificConversionEnabled true to enable JNI specific UTF-8 conversion, false otherwie */ - public OlmManager(boolean aIsUtf8SpecificConversionEnabled) { - ENABLE_STRING_UTF8_SPECIFIC_CONVERSION = aIsUtf8SpecificConversionEnabled; + public OlmManager() { } static { diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java index 23b2091..faf092e 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java +++ b/java/android/OlmLibSdk/olm-sdk/src/main/java/org/matrix/olm/OlmSession.java @@ -351,10 +351,10 @@ public class OlmSession extends CommonSerializeUtils implements Serializable { * @return the decrypted message if operation succeed, null otherwise */ public String decryptMessage(OlmMessage aEncryptedMsg) { - return decryptMessageJni(aEncryptedMsg, OlmManager.ENABLE_STRING_UTF8_SPECIFIC_CONVERSION); + return decryptMessageJni(aEncryptedMsg); } - private native String decryptMessageJni(OlmMessage aEncryptedMsg, boolean aIsUtf8ConversionRequired); + private native String decryptMessageJni(OlmMessage aEncryptedMsg); /** * Return true the object resources have been released.<br> diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.cpp b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.cpp index 535fd48..8a56a12 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.cpp +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.cpp @@ -183,7 +183,7 @@ JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(sessionIdentifierJni)(JNIEn } -JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jstring aEncryptedMsg, jobject aDecryptIndex, jobject aErrorMsg, jboolean aIsUtf8ConversionRequired) +JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jstring aEncryptedMsg, jobject aDecryptionResult, jobject aErrorMsg) { jstring decryptedMsgRetValue = 0; OlmInboundGroupSession *sessionPtr = NULL; @@ -204,7 +204,7 @@ JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv * { LOGE(" ## decryptMessageJni(): failure - invalid encrypted message"); } - else if (!aDecryptIndex) + else if (!aDecryptionResult) { LOGE(" ## decryptMessageJni(): failure - invalid index object"); } @@ -224,7 +224,7 @@ JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv * { LOGE(" ## decryptMessageJni(): failure - encrypted message JNI allocation OOM"); } - else if (!(indexObjJClass = env->GetObjectClass(aDecryptIndex))) + else if (!(indexObjJClass = env->GetObjectClass(aDecryptionResult))) { LOGE("## decryptMessageJni(): failure - unable to get index class"); } @@ -296,28 +296,18 @@ JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv * else { // update index - env->SetLongField(aDecryptIndex, indexMsgFieldId, (jlong)messageIndex); + env->SetLongField(aDecryptionResult, indexMsgFieldId, (jlong)messageIndex); - // UTF-8 conversion workaround for issue on Android versions older than Marshmallow (23) - if (aIsUtf8ConversionRequired) + // convert to utf8 + decryptedMsgRetValue = javaCStringToUtf8(env, plainTextMsgPtr, plaintextLength); + + if (!decryptedMsgRetValue) { - decryptedMsgRetValue = javaCStringToUtf8(env, plainTextMsgPtr, plaintextLength); - if(0 == decryptedMsgRetValue) - { - LOGE(" ## decryptMessageJni(): UTF-8 Conversion failure - javaCStringToUtf8() returns null"); - } - else - { - LOGD(" ## decryptMessageJni(): UTF-8 Conversion - decrypted returnedLg=%lu OK",static_cast<long unsigned int>(plaintextLength)); - } + LOGE(" ## decryptMessageJni(): UTF-8 Conversion failure - javaCStringToUtf8() returns null"); } else { - // update decrypted buffer size - plainTextMsgPtr[plaintextLength] = static_cast<char>('\0'); - - LOGD(" ## decryptMessageJni(): decrypted returnedLg=%lu plainTextMsgPtr=%s",static_cast<long unsigned int>(plaintextLength), (char*)plainTextMsgPtr); - decryptedMsgRetValue = env->NewStringUTF((const char*)plainTextMsgPtr); + LOGD(" ## decryptMessageJni(): UTF-8 Conversion - decrypted returnedLg=%lu OK",static_cast<long unsigned int>(plaintextLength)); } } diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.h b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.h index 132af43..7060df4 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.h +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_inbound_group_session.h @@ -34,7 +34,7 @@ JNIEXPORT jlong OLM_INBOUND_GROUP_SESSION_FUNC_DEF(createNewSessionJni)(JNIEnv * JNIEXPORT jint OLM_INBOUND_GROUP_SESSION_FUNC_DEF(initInboundGroupSessionWithSessionKeyJni)(JNIEnv *env, jobject thiz, jstring aSessionKey); JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(sessionIdentifierJni)(JNIEnv *env, jobject thiz); -JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jstring aEncryptedMsg, jobject aDecryptIndex, jobject aErrorMsg, jboolean aIsUtf8ConversionRequired); +JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jstring aEncryptedMsg, jobject aDecryptIndex, jobject aErrorMsg); // serialization JNIEXPORT jstring OLM_INBOUND_GROUP_SESSION_FUNC_DEF(serializeDataWithKeyJni)(JNIEnv *env, jobject thiz, jstring aKey, jobject aErrorMsg); diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp index 28edae1..0797ae6 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.cpp @@ -580,7 +580,7 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz * @param aEncryptedMsg message to decrypt * @return decrypted message if operation succeed, null otherwise */ -JNIEXPORT jstring OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg, jboolean aIsUtf8ConversionRequired) +JNIEXPORT jstring OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg) { jstring decryptedMsgRetValue = 0; jclass encryptedMsgJClass = 0; @@ -668,26 +668,15 @@ JNIEXPORT jstring OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject t } else { - // UTF-8 conversion workaround for issue on Android versions older than Marshmallow (23) - if (aIsUtf8ConversionRequired) + decryptedMsgRetValue = javaCStringToUtf8(env, plainTextMsgPtr, plaintextLength); + + if (!decryptedMsgRetValue) { - decryptedMsgRetValue = javaCStringToUtf8(env, plainTextMsgPtr, plaintextLength); - if(0 == decryptedMsgRetValue) - { - LOGE(" ## decryptMessageJni(): UTF-8 Conversion failure - javaCStringToUtf8() returns null"); - } - else - { - LOGD(" ## decryptMessageJni(): UTF-8 Conversion - decrypted returnedLg=%lu OK",static_cast<long unsigned int>(plaintextLength)); - } + LOGE(" ## decryptMessageJni(): UTF-8 Conversion failure - javaCStringToUtf8() returns null"); } else { - // update decrypted buffer size - plainTextMsgPtr[plaintextLength] = static_cast<char>('\0'); - - LOGD("## decryptMessageJni(): decrypted returnedLg=%lu plainTextMsgPtr=%s",static_cast<long unsigned int>(plaintextLength), (char*)(plainTextMsgPtr)); - decryptedMsgRetValue = env->NewStringUTF((const char*)(plainTextMsgPtr)); + LOGD(" ## decryptMessageJni(): UTF-8 Conversion - decrypted returnedLg=%lu OK",static_cast<long unsigned int>(plaintextLength)); } } } diff --git a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h index a43ce3a..22005d9 100644 --- a/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h +++ b/java/android/OlmLibSdk/olm-sdk/src/main/jni/olm_session.h @@ -45,7 +45,7 @@ JNIEXPORT jint OLM_SESSION_FUNC_DEF(matchesInboundSessionFromIdKeyJni)(JNIEnv *e // encrypt/decrypt JNIEXPORT jint OLM_SESSION_FUNC_DEF(encryptMessageJni)(JNIEnv *env, jobject thiz, jstring aClearMsg, jobject aEncryptedMsg); -JNIEXPORT jstring OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg, jboolean aIsUtf8ConversionRequired); +JNIEXPORT jstring OLM_SESSION_FUNC_DEF(decryptMessageJni)(JNIEnv *env, jobject thiz, jobject aEncryptedMsg); JNIEXPORT jstring OLM_SESSION_FUNC_DEF(getSessionIdentifierJni)(JNIEnv *env, jobject thiz); |