R4SAS
4 months ago
24 changed files with 686 additions and 450 deletions
@ -0,0 +1,80 @@
@@ -0,0 +1,80 @@
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := i2pd |
||||
LOCAL_CPP_FEATURES := rtti exceptions |
||||
LOCAL_C_INCLUDES += $(IFADDRS_PATH) $(LIB_SRC_PATH) $(LIB_CLIENT_SRC_PATH) $(LANG_SRC_PATH) $(DAEMON_SRC_PATH) |
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
boost_system \
|
||||
boost_date_time \
|
||||
boost_filesystem \
|
||||
boost_program_options \
|
||||
crypto \
|
||||
ssl \
|
||||
miniupnpc |
||||
LOCAL_LDLIBS := -lz |
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
DaemonAndroid.cpp \
|
||||
i2pd_android.cpp \
|
||||
$(IFADDRS_PATH)/ifaddrs.cpp \
|
||||
$(IFADDRS_PATH)/bionic_netlink.cpp \
|
||||
$(wildcard $(LIB_SRC_PATH)/*.cpp) \
|
||||
$(wildcard $(LIB_CLIENT_SRC_PATH)/*.cpp) \
|
||||
$(wildcard $(LANG_SRC_PATH)/*.cpp) \
|
||||
$(DAEMON_SRC_PATH)/Daemon.cpp \
|
||||
$(DAEMON_SRC_PATH)/UPnP.cpp \
|
||||
$(DAEMON_SRC_PATH)/HTTPServer.cpp \
|
||||
$(DAEMON_SRC_PATH)/I2PControl.cpp \
|
||||
$(DAEMON_SRC_PATH)/I2PControlHandlers.cpp |
||||
|
||||
include $(BUILD_SHARED_LIBRARY) |
||||
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := boost_system |
||||
LOCAL_SRC_FILES := $(BOOST_PATH)/build/out/$(TARGET_ARCH_ABI)/lib/libboost_system.a |
||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/build/out/$(TARGET_ARCH_ABI)/include |
||||
include $(PREBUILT_STATIC_LIBRARY) |
||||
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := boost_date_time |
||||
LOCAL_SRC_FILES := $(BOOST_PATH)/build/out/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a |
||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/build/out/$(TARGET_ARCH_ABI)/include |
||||
include $(PREBUILT_STATIC_LIBRARY) |
||||
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := boost_filesystem |
||||
LOCAL_SRC_FILES := $(BOOST_PATH)/build/out/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a |
||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/build/out/$(TARGET_ARCH_ABI)/include |
||||
include $(PREBUILT_STATIC_LIBRARY) |
||||
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := boost_program_options |
||||
LOCAL_SRC_FILES := $(BOOST_PATH)/build/out/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a |
||||
LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/build/out/$(TARGET_ARCH_ABI)/include |
||||
include $(PREBUILT_STATIC_LIBRARY) |
||||
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := crypto |
||||
LOCAL_SRC_FILES := $(OPENSSL_PATH)/out/$(TARGET_ARCH_ABI)/lib/libcrypto.a |
||||
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/out/$(TARGET_ARCH_ABI)/include |
||||
include $(PREBUILT_STATIC_LIBRARY) |
||||
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := ssl |
||||
LOCAL_SRC_FILES := $(OPENSSL_PATH)/out/$(TARGET_ARCH_ABI)/lib/libssl.a |
||||
LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/out/$(TARGET_ARCH_ABI)/include |
||||
LOCAL_STATIC_LIBRARIES := crypto |
||||
include $(PREBUILT_STATIC_LIBRARY) |
||||
|
||||
LOCAL_PATH := $(call my-dir) |
||||
include $(CLEAR_VARS) |
||||
LOCAL_MODULE := miniupnpc |
||||
LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnpc/out/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a |
||||
LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnpc/out/$(TARGET_ARCH_ABI)/include |
||||
include $(PREBUILT_STATIC_LIBRARY) |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
NDK_TOOLCHAIN_VERSION := clang |
||||
APP_STL := c++_static |
||||
|
||||
# Enable c++17 extensions in source code
|
||||
APP_CPPFLAGS += -std=c++17 -fexceptions -frtti |
||||
|
||||
APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP -Wno-deprecated-declarations |
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) |
||||
APP_CPPFLAGS += -DANDROID_ARM7A |
||||
endif |
||||
|
||||
IFADDRS_PATH = $(NDK_MODULE_PATH)/android-ifaddrs |
||||
BOOST_PATH = $(NDK_MODULE_PATH)/boost |
||||
MINIUPNP_PATH = $(NDK_MODULE_PATH)/miniupnp |
||||
OPENSSL_PATH = $(NDK_MODULE_PATH)/openssl |
||||
|
||||
# don't change me
|
||||
I2PD_SRC_PATH = $(NDK_MODULE_PATH)/i2pd |
||||
|
||||
LIB_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd |
||||
LIB_CLIENT_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd_client |
||||
LANG_SRC_PATH = $(I2PD_SRC_PATH)/i18n |
||||
DAEMON_SRC_PATH = $(I2PD_SRC_PATH)/daemon |
@ -0,0 +1,138 @@
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2022, The PurpleI2P Project |
||||
* |
||||
* This file is part of Purple i2pd project and licensed under BSD3 |
||||
* |
||||
* See full license text in LICENSE file at top of project tree |
||||
*/ |
||||
|
||||
#include <iostream> |
||||
#include <chrono> |
||||
#include <thread> |
||||
#include <exception> |
||||
#include <boost/exception/diagnostic_information.hpp> |
||||
#include <boost/exception_ptr.hpp> |
||||
//#include "mainwindow.h"
|
||||
#include "FS.h" |
||||
#include "DaemonAndroid.h" |
||||
#include "Daemon.h" |
||||
#include "I18N.h" |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace android |
||||
{ |
||||
std::string dataDir = ""; |
||||
std::string language = ""; |
||||
|
||||
DaemonAndroidImpl::DaemonAndroidImpl () |
||||
{ |
||||
} |
||||
|
||||
DaemonAndroidImpl::~DaemonAndroidImpl () |
||||
{ |
||||
} |
||||
|
||||
bool DaemonAndroidImpl::init(int argc, char* argv[]) |
||||
{ |
||||
return Daemon.init(argc, argv); |
||||
} |
||||
|
||||
void DaemonAndroidImpl::start() |
||||
{ |
||||
Daemon.start(); |
||||
} |
||||
|
||||
void DaemonAndroidImpl::stop() |
||||
{ |
||||
Daemon.stop(); |
||||
} |
||||
|
||||
void DaemonAndroidImpl::restart() |
||||
{ |
||||
stop(); |
||||
start(); |
||||
} |
||||
|
||||
void DaemonAndroidImpl::setDataDir(std::string path) |
||||
{ |
||||
Daemon.setDataDir(path); |
||||
} |
||||
|
||||
static DaemonAndroidImpl daemon; |
||||
static char* argv[1]={strdup("tmp")}; |
||||
/**
|
||||
* returns error details if failed |
||||
* returns "ok" if daemon initialized and started okay |
||||
*/ |
||||
std::string start(/*int argc, char* argv[]*/) |
||||
{ |
||||
try |
||||
{ |
||||
{ |
||||
// make sure assets are ready before proceed
|
||||
i2p::fs::DetectDataDir(dataDir, false); |
||||
int numAttempts = 0; |
||||
do |
||||
{ |
||||
if (i2p::fs::Exists (i2p::fs::DataDirPath("assets.ready"))) break; // assets ready
|
||||
numAttempts++; |
||||
std::this_thread::sleep_for (std::chrono::seconds(1)); // otherwise wait for 1 more second
|
||||
} |
||||
while (numAttempts <= 10); // 10 seconds max
|
||||
|
||||
// Set application directory
|
||||
daemon.setDataDir(dataDir); |
||||
|
||||
bool daemonInitSuccess = daemon.init(1, argv); |
||||
if(!daemonInitSuccess) |
||||
{ |
||||
return "Daemon init failed"; |
||||
} |
||||
|
||||
// Set webconsole language from application
|
||||
i2p::i18n::SetLanguage(language); |
||||
|
||||
daemon.start(); |
||||
} |
||||
} |
||||
catch (boost::exception& ex) |
||||
{ |
||||
std::stringstream ss; |
||||
ss << boost::diagnostic_information(ex); |
||||
return ss.str(); |
||||
} |
||||
catch (std::exception& ex) |
||||
{ |
||||
std::stringstream ss; |
||||
ss << ex.what(); |
||||
return ss.str(); |
||||
} |
||||
catch(...) |
||||
{ |
||||
return "unknown exception"; |
||||
} |
||||
return "ok"; |
||||
} |
||||
|
||||
void stop() |
||||
{ |
||||
daemon.stop(); |
||||
} |
||||
|
||||
void SetDataDir(std::string jdataDir) |
||||
{ |
||||
dataDir = jdataDir; |
||||
} |
||||
|
||||
std::string GetDataDir(void) |
||||
{ |
||||
return dataDir; |
||||
} |
||||
|
||||
void SetLanguage(std::string jlanguage) |
||||
{ |
||||
language = jlanguage; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2022, The PurpleI2P Project |
||||
* |
||||
* This file is part of Purple i2pd project and licensed under BSD3 |
||||
* |
||||
* See full license text in LICENSE file at top of project tree |
||||
*/ |
||||
|
||||
#ifndef DAEMON_ANDROID_H |
||||
#define DAEMON_ANDROID_H |
||||
|
||||
#include <string> |
||||
|
||||
namespace i2p |
||||
{ |
||||
namespace android |
||||
{ |
||||
class DaemonAndroidImpl |
||||
{ |
||||
public: |
||||
|
||||
DaemonAndroidImpl (); |
||||
~DaemonAndroidImpl (); |
||||
|
||||
/**
|
||||
* @return success |
||||
*/ |
||||
bool init (int argc, char* argv[]); |
||||
void start (); |
||||
void stop (); |
||||
void restart (); |
||||
|
||||
void setDataDir (std::string path); |
||||
}; |
||||
|
||||
/**
|
||||
* returns "ok" if daemon init failed |
||||
* returns errinfo if daemon initialized and started okay |
||||
*/ |
||||
std::string start (); |
||||
|
||||
void stop (); |
||||
|
||||
// set datadir received from jni
|
||||
void SetDataDir (std::string jdataDir); |
||||
// get datadir
|
||||
std::string GetDataDir (void); |
||||
// set webconsole language
|
||||
void SetLanguage (std::string jlanguage); |
||||
} |
||||
} |
||||
|
||||
#endif // DAEMON_ANDROID_H
|
@ -0,0 +1,141 @@
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2022, The PurpleI2P Project |
||||
* |
||||
* This file is part of Purple i2pd project and licensed under BSD3 |
||||
* |
||||
* See full license text in LICENSE file at top of project tree |
||||
*/ |
||||
|
||||
#include <jni.h> |
||||
#include "org_purplei2p_i2pd_I2PD_JNI.h" |
||||
#include "DaemonAndroid.h" |
||||
#include "Config.h" |
||||
#include "RouterContext.h" |
||||
#include "ClientContext.h" |
||||
#include "Transports.h" |
||||
#include "Tunnel.h" |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith |
||||
(JNIEnv *env, jclass clazz) { |
||||
#if defined(__arm__) |
||||
#if defined(__ARM_ARCH_7A__) |
||||
#if defined(__ARM_NEON__) |
||||
#if defined(__ARM_PCS_VFP) |
||||
#define ABI "armeabi-v7a/NEON (hard-float)" |
||||
#else |
||||
#define ABI "armeabi-v7a/NEON" |
||||
#endif |
||||
#else |
||||
#if defined(__ARM_PCS_VFP) |
||||
#define ABI "armeabi-v7a (hard-float)" |
||||
#else |
||||
#define ABI "armeabi-v7a" |
||||
#endif |
||||
#endif |
||||
#else |
||||
#define ABI "armeabi" |
||||
#endif |
||||
#elif defined(__i386__) |
||||
#define ABI "x86" |
||||
#elif defined(__x86_64__) |
||||
#define ABI "x86_64" |
||||
#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */ |
||||
#define ABI "mips64" |
||||
#elif defined(__mips__) |
||||
#define ABI "mips" |
||||
#elif defined(__aarch64__) |
||||
#define ABI "arm64-v8a" |
||||
#else |
||||
#define ABI "unknown" |
||||
#endif |
||||
|
||||
return env->NewStringUTF(ABI); |
||||
} |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon |
||||
(JNIEnv *env, jclass clazz) { |
||||
return env->NewStringUTF(i2p::android::start().c_str()); |
||||
} |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getDataDir |
||||
(JNIEnv *env, jclass clazz) { |
||||
return env->NewStringUTF(i2p::android::GetDataDir().c_str()); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon |
||||
(JNIEnv *env, jclass clazz) { |
||||
i2p::android::stop(); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels |
||||
(JNIEnv *env, jclass clazz) { |
||||
i2p::context.SetAcceptsTunnels (false); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels |
||||
(JNIEnv *env, jclass clazz) { |
||||
i2p::context.SetAcceptsTunnels (true); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs |
||||
(JNIEnv *env, jclass clazz) { |
||||
i2p::client::context.ReloadConfig(); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged |
||||
(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) { |
||||
auto dataDir = env->GetStringUTFChars(jdataDir, NULL); |
||||
i2p::android::SetDataDir(dataDir); |
||||
env->ReleaseStringUTFChars(jdataDir, dataDir); |
||||
} |
||||
|
||||
JNIEXPORT jint JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getTransitTunnelsCount |
||||
(JNIEnv *env, jclass clazz) { |
||||
return i2p::tunnel::tunnels.CountTransitTunnels(); |
||||
} |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getWebConsAddr |
||||
(JNIEnv *env, jclass clazz) { |
||||
std::string httpAddr; i2p::config::GetOption("http.address", httpAddr); |
||||
uint16_t httpPort; i2p::config::GetOption("http.port", httpPort); |
||||
std::string result = "http://" + httpAddr + ":" + std::to_string(httpPort) + "/"; |
||||
return env->NewStringUTF(result.c_str()); |
||||
} |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setLanguage |
||||
(JNIEnv *env, jclass clazz, jstring jlanguage) { |
||||
auto language = env->GetStringUTFChars(jlanguage, NULL); |
||||
i2p::android::SetLanguage(language); |
||||
env->ReleaseStringUTFChars(jlanguage, language); |
||||
} |
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getHTTPProxyState |
||||
(JNIEnv *, jclass) { |
||||
return i2p::client::context.GetHttpProxy () ? true : false; |
||||
} |
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getSOCKSProxyState |
||||
(JNIEnv *, jclass) { |
||||
return i2p::client::context.GetSocksProxy() ? true : false; |
||||
} |
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getBOBState |
||||
(JNIEnv *, jclass) { |
||||
return i2p::client::context.GetBOBCommandChannel() ? true : false; |
||||
} |
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getSAMState |
||||
(JNIEnv *, jclass) { |
||||
return i2p::client::context.GetSAMBridge() ? true : false; |
||||
} |
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getI2CPState |
||||
(JNIEnv *, jclass) { |
||||
return i2p::client::context.GetI2CPServer() ? true : false; |
||||
} |
@ -0,0 +1,73 @@
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2022, The PurpleI2P Project |
||||
* |
||||
* This file is part of Purple i2pd project and licensed under BSD3 |
||||
* |
||||
* See full license text in LICENSE file at top of project tree |
||||
*/ |
||||
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */ |
||||
#include <jni.h> |
||||
/* Header for class org_purplei2p_i2pd_I2PD_JNI */ |
||||
|
||||
#ifndef _Included_org_purplei2p_i2pd_I2PD_JNI |
||||
#define _Included_org_purplei2p_i2pd_I2PD_JNI |
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setDataDir |
||||
(JNIEnv *env, jclass clazz, jstring jdataDir); |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_setLanguage |
||||
(JNIEnv *env, jclass clazz, jstring jlanguage); |
||||
|
||||
JNIEXPORT jint JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getTransitTunnelsCount |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getWebConsAddr |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getDataDir |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getHTTPProxyState |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getSOCKSProxyState |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getBOBState |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getSAMState |
||||
(JNIEnv *, jclass) ; |
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getI2CPState |
||||
(JNIEnv *, jclass); |
||||
|
||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged |
||||
(JNIEnv * env, jclass clazz, jboolean isConnected); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
#endif |
@ -1,7 +0,0 @@
@@ -1,7 +0,0 @@
|
||||
package org.purplei2p.i2pd; |
||||
|
||||
public interface AbstractProcess { |
||||
/** @param tr can be null |
||||
*/ |
||||
void kill(Throwable tr); |
||||
} |
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
package org.purplei2p.i2pd; |
||||
|
||||
public class I2PD_JNI { |
||||
public static native String getABICompiledWith(); |
||||
|
||||
public static void loadLibraries() { |
||||
System.loadLibrary("i2pd"); |
||||
} |
||||
|
||||
/** |
||||
* returns error info if failed |
||||
* returns "ok" if daemon initialized and started okay |
||||
*/ |
||||
public static native String startDaemon(); |
||||
public static native void stopDaemon(); |
||||
|
||||
public static native void startAcceptingTunnels(); |
||||
public static native void stopAcceptingTunnels(); |
||||
public static native void reloadTunnelsConfigs(); |
||||
|
||||
public static native void setDataDir(String jdataDir); |
||||
public static native void setLanguage(String jlanguage); |
||||
|
||||
public static native int getTransitTunnelsCount(); |
||||
public static native String getWebConsAddr(); |
||||
public static native String getDataDir(); |
||||
|
||||
public static native boolean getHTTPProxyState(); |
||||
public static native boolean getSOCKSProxyState(); |
||||
public static native boolean getBOBState(); |
||||
public static native boolean getSAMState(); |
||||
public static native boolean getI2CPState(); |
||||
|
||||
public static native void onNetworkStateChanged(boolean isConnected); |
||||
} |
@ -1,154 +0,0 @@
@@ -1,154 +0,0 @@
|
||||
package org.purplei2p.i2pd; |
||||
|
||||
import android.content.Context; |
||||
import android.util.Log; |
||||
|
||||
import java.io.BufferedInputStream; |
||||
import java.io.BufferedReader; |
||||
import java.io.File; |
||||
import java.io.InputStreamReader; |
||||
|
||||
/** i2pd process API calls via TCP between the Android Java app and i2pd C++-only process. |
||||
* TODO |
||||
*/ |
||||
public class I2pdApi { |
||||
private static String dataDir; |
||||
private static AbstractProcess i2pdProcess; |
||||
private static final String TAG = "I2pdApi"; |
||||
|
||||
/** |
||||
* returns error info if failed |
||||
* returns "ok" if daemon initialized and started okay |
||||
*/ |
||||
public static String startDaemon(final Context ctx, final String dataDir, String ignoredLanguage, final DaemonWrapper daemonWrapper){ |
||||
try { |
||||
i2pdProcess = null; |
||||
I2pdApi.dataDir = dataDir; |
||||
File pidFile = new File(dataDir, "i2pd.pid"); |
||||
Log.i(TAG,"Launching an i2pd process"); |
||||
final Process p = Runtime.getRuntime().exec(new String[]{ |
||||
"/system/bin/sh", |
||||
"-c", |
||||
"ulimit -c unlimited && "+ |
||||
ctx.getApplicationInfo().nativeLibraryDir + |
||||
"/libi2pd.so --datadir=" + dataDir + |
||||
" --pidfile=" + pidFile.getAbsolutePath() + |
||||
" > "+dataDir+"/s.log 2>&1" |
||||
}); |
||||
i2pdProcess = (Throwable tr) -> { |
||||
try { |
||||
if (tr != null) |
||||
Log.e(TAG, "destroying the subprocess \"i2pd\", reason: " + tr, tr); |
||||
else |
||||
Log.e(TAG, "destroying the subprocess \"i2pd\", reason: null"); |
||||
p.destroy(); |
||||
} catch (Throwable tr2) { |
||||
Log.e(TAG, "", tr2); |
||||
} |
||||
}; |
||||
new Thread(() -> { |
||||
try { |
||||
try (BufferedInputStream bis = new BufferedInputStream(p.getInputStream())) { |
||||
try (InputStreamReader sr = new InputStreamReader(bis)) { |
||||
try (BufferedReader r = new BufferedReader(sr)) { |
||||
while (true) { |
||||
String s = r.readLine(); |
||||
if (s == null) break; |
||||
Log.i(TAG, s); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} catch (Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
} |
||||
}, "i2pd-stdout").start(); |
||||
new Thread(() -> { |
||||
try { |
||||
try (BufferedInputStream bis = new BufferedInputStream(p.getErrorStream())) { |
||||
try (InputStreamReader sr = new InputStreamReader(bis)) { |
||||
try (BufferedReader r = new BufferedReader(sr)) { |
||||
while (true) { |
||||
String s = r.readLine(); |
||||
if (s == null) break; |
||||
Log.i(TAG, s); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} catch (Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
} |
||||
try { |
||||
p.waitFor(); |
||||
} catch (Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
} |
||||
final int errorLevel = p.exitValue(); |
||||
Log.i(TAG, "i2pd process exit code: " + errorLevel); |
||||
final Throwable trReason = new Throwable("subprocess \"i2pd\" exited with exit code " + errorLevel); |
||||
try { |
||||
stopDaemon(trReason); |
||||
Log.i(TAG, "stopDaemon completed"); |
||||
} catch (Throwable tr) { |
||||
Log.e(TAG, "Called stopDaemon, got exception", tr); |
||||
} |
||||
new Thread(() -> { |
||||
try { |
||||
daemonWrapper.stopDaemon(trReason); |
||||
Log.i(TAG, "daemonWrapper.stopDaemon completed"); |
||||
} catch (Throwable tr) { |
||||
Log.e(TAG, "Called daemonWrapper.stopDaemon, got exception", tr); |
||||
} |
||||
}, "stop the daemonWrapper thread").start(); |
||||
}, "i2pd-stderr").start(); |
||||
new Thread(() -> { |
||||
try { |
||||
// try (BufferedOutputStream bos = new BufferedOutputStream(p.getOutputStream())) {
|
||||
// try (OutputStreamWriter sr = new OutputStreamWriter(bos)) {
|
||||
// try (BufferedWriter r = new BufferedWriter(sr)) {
|
||||
while (true) { |
||||
synchronized (Thread.currentThread()) { |
||||
Thread.currentThread().wait(100); |
||||
} |
||||
} |
||||
// }
|
||||
// }
|
||||
// }
|
||||
} catch (Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
} |
||||
}, "i2pd-stdin").start(); |
||||
return "ok"; |
||||
} catch (Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
return "Error in exec(): " + tr; |
||||
} |
||||
} |
||||
|
||||
public static void stopDaemon(Throwable tr){ |
||||
AbstractProcess p = i2pdProcess; |
||||
if (p != null) { |
||||
p.kill(tr); |
||||
i2pdProcess = null; |
||||
} |
||||
} |
||||
|
||||
public static void startAcceptingTunnels(){} |
||||
public static void stopAcceptingTunnels(){} |
||||
public static void reloadTunnelsConfigs(){} |
||||
|
||||
public static int getTransitTunnelsCount(){return -1;} |
||||
public static String getWebConsAddr(){return "";} |
||||
public static String getDataDir() { |
||||
return dataDir; |
||||
} |
||||
|
||||
public static boolean getHTTPProxyState(){return false;} |
||||
public static boolean getSOCKSProxyState(){return false;} |
||||
public static boolean getBOBState(){return false;} |
||||
public static boolean getSAMState(){return false;} |
||||
public static boolean getI2CPState(){return false;} |
||||
|
||||
public static void onNetworkStateChanged(boolean isConnected){} |
||||
} |
@ -1,126 +0,0 @@
@@ -1,126 +0,0 @@
|
||||
package org.purplei2p.i2pd.appscope; |
||||
|
||||
import android.app.Application; |
||||
import android.content.ComponentName; |
||||
import android.content.Context; |
||||
import android.content.Intent; |
||||
import android.content.ServiceConnection; |
||||
import android.net.ConnectivityManager; |
||||
import android.os.IBinder; |
||||
import android.util.Log; |
||||
|
||||
import org.purplei2p.i2pd.BuildConfig; |
||||
import org.purplei2p.i2pd.I2PDActivity; |
||||
import org.purplei2p.i2pd.*; |
||||
|
||||
public class App extends Application { |
||||
private static final String TAG = "i2pd.app"; |
||||
|
||||
//private static final I2PD_JNI jniHolder = new I2PD_JNI();
|
||||
|
||||
private static volatile DaemonWrapper daemonWrapper; |
||||
private String versionName; |
||||
|
||||
private static volatile boolean mIsBound; |
||||
|
||||
|
||||
|
||||
public synchronized static DaemonWrapper getDaemonWrapper() { |
||||
return daemonWrapper; |
||||
} |
||||
|
||||
@Override |
||||
public void onCreate() { |
||||
super.onCreate(); |
||||
synchronized (this) { |
||||
if (getDaemonWrapper() == null) { |
||||
createDaemonWrapper(); |
||||
} |
||||
versionName = BuildConfig.VERSION_NAME; |
||||
doBindService(); |
||||
startService(new Intent(this, ForegroundService.class)); |
||||
} |
||||
} |
||||
|
||||
private void createDaemonWrapper() { |
||||
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService( |
||||
Context.CONNECTIVITY_SERVICE); |
||||
daemonWrapper = new DaemonWrapper(getApplicationContext(), getAssets(), connectivityManager); |
||||
ForegroundService.init(daemonWrapper); |
||||
} |
||||
|
||||
private synchronized void doBindService() { |
||||
if (mIsBound) |
||||
return; |
||||
// Establish a connection with the service. We use an explicit
|
||||
// class name because we want a specific service implementation that
|
||||
// we know will be running in our own process (and thus won't be
|
||||
// supporting component replacement by other applications).
|
||||
bindService(new Intent(this, ForegroundService.class), mConnection, Context.BIND_AUTO_CREATE); |
||||
mIsBound = true; |
||||
} |
||||
|
||||
private synchronized void doUnbindService() { |
||||
if (mIsBound) { |
||||
// Detach our existing connection.
|
||||
unbindService(mConnection); |
||||
mIsBound = false; |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void onTerminate() { |
||||
quit(); |
||||
super.onTerminate(); |
||||
} |
||||
|
||||
private final ServiceConnection mConnection = new ServiceConnection() { |
||||
public void onServiceConnected(ComponentName className, IBinder service) { |
||||
/* This is called when the connection with the service has been |
||||
established, giving us the service object we can use to |
||||
interact with the service. Because we have bound to a explicit |
||||
service that we know is running in our own process, we can |
||||
cast its IBinder to a concrete class and directly access it. */ |
||||
// mBoundService = ((LocalService.LocalBinder)service).getService();
|
||||
|
||||
/* Tell the user about this for our demo. */ |
||||
// Toast.makeText(Binding.this, R.string.local_service_connected,
|
||||
// Toast.LENGTH_SHORT).show();
|
||||
} |
||||
|
||||
public void onServiceDisconnected(ComponentName className) { |
||||
/* This is called when the connection with the service has been |
||||
unexpectedly disconnected -- that is, its process crashed. |
||||
Because it is running in our same process, we should never |
||||
see this happen. */ |
||||
// mBoundService = null;
|
||||
// Toast.makeText(Binding.this, R.string.local_service_disconnected,
|
||||
// Toast.LENGTH_SHORT).show();
|
||||
} |
||||
}; |
||||
|
||||
public synchronized void quit() { |
||||
try { |
||||
if(daemonWrapper!=null)daemonWrapper.stopDaemon(null); |
||||
} catch (Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
} |
||||
try { |
||||
doUnbindService(); |
||||
} catch (IllegalArgumentException ex) { |
||||
Log.e(TAG, "throwable caught and ignored", ex); |
||||
if (ex.getMessage().startsWith("Service not registered: " + I2PDActivity.class.getName())) { |
||||
Log.i(TAG, "Service not registered exception seems to be normal, not a bug it seems."); |
||||
} |
||||
} catch (Throwable tr) { |
||||
Log.e(TAG, "throwable caught and ignored", tr); |
||||
} |
||||
try{ |
||||
ForegroundService fs = ForegroundService.getInstance(); |
||||
if(fs!=null)fs.stop(); |
||||
}catch(Throwable tr) { |
||||
Log.e(TAG, "", tr); |
||||
} |
||||
|
||||
} |
||||
} |
Loading…
Reference in new issue