diff --git a/android/jni/DaemonAndroid.cpp b/android/jni/DaemonAndroid.cpp index 7ff83d1f..c3a1b805 100644 --- a/android/jni/DaemonAndroid.cpp +++ b/android/jni/DaemonAndroid.cpp @@ -65,6 +65,8 @@ namespace android } } */ + std::string dataDir = ""; + DaemonAndroidImpl::DaemonAndroidImpl () //: /*mutex(nullptr), */ @@ -85,7 +87,7 @@ namespace android //m_IsRunning=false; // make sure assets are ready before proceed - i2p::fs::DetectDataDir("", false); + i2p::fs::DetectDataDir(dataDir, false); int numAttempts = 0; do { @@ -203,5 +205,10 @@ namespace android { daemon.stop(); } + + void SetDataDir(std::string jdataDir) + { + dataDir = jdataDir; + } } } diff --git a/android/jni/DaemonAndroid.h b/android/jni/DaemonAndroid.h index 396a4578..64bf64fd 100644 --- a/android/jni/DaemonAndroid.h +++ b/android/jni/DaemonAndroid.h @@ -42,6 +42,8 @@ namespace android // stops the daemon void stop(); + // set datadir received from jni + void SetDataDir(std::string jdataDir); /* class Worker : public QObject { diff --git a/android/jni/i2pd_android.cpp b/android/jni/i2pd_android.cpp index c258733f..da908648 100755 --- a/android/jni/i2pd_android.cpp +++ b/android/jni/i2pd_android.cpp @@ -5,7 +5,7 @@ #include "Transports.h" JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith - (JNIEnv * env, jclass clazz) { + (JNIEnv *env, jclass clazz) { #if defined(__arm__) #if defined(__ARM_ARCH_7A__) #if defined(__ARM_NEON__) @@ -42,27 +42,53 @@ JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith } JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon - (JNIEnv * env, jclass clazz) { + (JNIEnv *env, jclass clazz) { return env->NewStringUTF(i2p::android::start().c_str()); } JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon - (JNIEnv * env, jclass clazz) { + (JNIEnv *env, jclass clazz) { i2p::android::stop(); } JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels - (JNIEnv * env, jclass clazz) { + (JNIEnv *env, jclass clazz) { i2p::context.SetAcceptsTunnels (false); } JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels - (JNIEnv * env, jclass clazz) { + (JNIEnv *env, jclass clazz) { i2p::context.SetAcceptsTunnels (true); } JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged - (JNIEnv * env, jclass clazz, jboolean isConnected) { + (JNIEnv *env, jclass clazz, jboolean isConnected) { bool isConnectedBool = (bool) isConnected; i2p::transport::transports.SetOnline (isConnectedBool); } + +JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir + (JNIEnv *env, jclass clazz, jstring jdataDir) { + + /* + // Method 1: convert UTF-16 jstring to std::string (https://stackoverflow.com/a/41820336) + const jclass stringClass = env->GetObjectClass(jdataDir); + const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B"); + const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(jdataDir, getBytes, env->NewStringUTF("UTF-8")); + + size_t length = (size_t) env->GetArrayLength(stringJbytes); + jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL); + + std::string dataDir = std::string((char *)pBytes, length); + env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT); + + env->DeleteLocalRef(stringJbytes); + env->DeleteLocalRef(stringClass); */ + + // Method 2: get string chars and make char array. + auto dataDir = env->GetStringUTFChars(jdataDir, NULL); + env->ReleaseStringUTFChars(jdataDir, dataDir); + + // Set DataDir + i2p::android::SetDataDir(dataDir); +} diff --git a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h index 28b9118b..6939a153 100644 --- a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h +++ b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h @@ -30,6 +30,9 @@ JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged (JNIEnv * env, jclass clazz, jboolean isConnected); +JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir + (JNIEnv *env, jclass clazz, jstring jdataDir); + #ifdef __cplusplus } #endif diff --git a/android/src/org/purplei2p/i2pd/DaemonSingleton.java b/android/src/org/purplei2p/i2pd/DaemonSingleton.java index fa487b67..5f806024 100644 --- a/android/src/org/purplei2p/i2pd/DaemonSingleton.java +++ b/android/src/org/purplei2p/i2pd/DaemonSingleton.java @@ -2,7 +2,9 @@ package org.purplei2p.i2pd; import java.util.HashSet; import java.util.Set; +import android.os.Environment; import android.util.Log; + import org.purplei2p.i2pd.R; public class DaemonSingleton { @@ -80,6 +82,7 @@ public class DaemonSingleton { } try { synchronized (DaemonSingleton.this) { + I2PD_JNI.setDataDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd"); daemonStartResult = I2PD_JNI.startDaemon(); if("ok".equals(daemonStartResult)){ setState(State.startedOkay); diff --git a/android/src/org/purplei2p/i2pd/I2PD_JNI.java b/android/src/org/purplei2p/i2pd/I2PD_JNI.java index a929b703..31a8a4eb 100644 --- a/android/src/org/purplei2p/i2pd/I2PD_JNI.java +++ b/android/src/org/purplei2p/i2pd/I2PD_JNI.java @@ -18,6 +18,8 @@ public class I2PD_JNI { public static native void onNetworkStateChanged(boolean isConnected); + public static native void setDataDir(String jdataDir); + public static void loadLibraries() { //System.loadLibrary("c++_shared"); System.loadLibrary("i2pd");