From faac35cd1e868d888bba722164b7b3037af0ce46 Mon Sep 17 00:00:00 2001 From: unlnown542a Date: Sat, 21 Apr 2018 21:55:45 +0300 Subject: [PATCH] Revert "Change jni to build executable. Clone with minimal changes DaemonUnix into DaemonAndroid" This reverts commit f11266972e81a6db65aeecc3f77fe2b47418385c. --- android/jni/Android.mk | 8 +- android/jni/Application.mk | 8 +- android/jni/DaemonAndroid.cpp | 366 +++++++++++----------- android/jni/DaemonAndroid.h | 113 ++++--- android/jni/i2pd_android.cpp | 66 ++++ android/jni/org_purplei2p_i2pd_I2PD_JNI.h | 33 ++ 6 files changed, 359 insertions(+), 235 deletions(-) create mode 100755 android/jni/i2pd_android.cpp create mode 100644 android/jni/org_purplei2p_i2pd_I2PD_JNI.h diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 90284995..d5a8f05f 100755 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -12,15 +12,15 @@ LOCAL_STATIC_LIBRARIES := \ miniupnpc LOCAL_LDLIBS := -lz -LOCAL_SRC_FILES := DaemonAndroid.cpp $(IFADDRS_PATH)/ifaddrs.c \ +LOCAL_SRC_FILES := DaemonAndroid.cpp i2pd_android.cpp $(IFADDRS_PATH)/ifaddrs.c \ $(wildcard $(LIB_SRC_PATH)/*.cpp)\ $(wildcard $(LIB_CLIENT_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)/i2pd.cpp -include $(BUILD_EXECUTABLE) + $(DAEMON_SRC_PATH)/I2PControl.cpp + +include $(BUILD_SHARED_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) diff --git a/android/jni/Application.mk b/android/jni/Application.mk index acc6f895..0fa116c2 100755 --- a/android/jni/Application.mk +++ b/android/jni/Application.mk @@ -9,14 +9,12 @@ APP_PLATFORM := android-14 # http://stackoverflow.com/a/21386866/529442 http://stackoverflow.com/a/15616255/529442 to enable c++11 support in Eclipse NDK_TOOLCHAIN_VERSION := 4.9 # APP_STL := stlport_shared --> does not seem to contain C++11 features -#APP_STL := gnustl_shared -APP_STL := gnustl_static +APP_STL := gnustl_shared # Enable c++11 extensions in source code -APP_CPPFLAGS += -std=c++11 -fvisibility=default -fPIE +APP_CPPFLAGS += -std=c++11 APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP -APP_LDFLAGS += -rdynamic -fPIE -pie ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) APP_CPPFLAGS += -DANDROID_ARM7A endif @@ -28,7 +26,7 @@ APP_OPTIM := debug # git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/android-ifaddrs.git # change to your own -I2PD_LIBS_PATH = /home/u/build/i2p/daemon/static.libs +I2PD_LIBS_PATH = /path/to/libraries BOOST_PATH = $(I2PD_LIBS_PATH)/Boost-for-Android-Prebuilt OPENSSL_PATH = $(I2PD_LIBS_PATH)/OpenSSL-for-Android-Prebuilt MINIUPNP_PATH = $(I2PD_LIBS_PATH)/MiniUPnP-for-Android-Prebuilt diff --git a/android/jni/DaemonAndroid.cpp b/android/jni/DaemonAndroid.cpp index 94c679be..75584740 100644 --- a/android/jni/DaemonAndroid.cpp +++ b/android/jni/DaemonAndroid.cpp @@ -1,193 +1,193 @@ #include "DaemonAndroid.h" - -#ifndef _WIN32 - -#include -#include -#include -#include -#include -#include -#include - -#include "Config.h" -#include "FS.h" -#include "Log.h" -#include "Tunnel.h" -#include "RouterContext.h" -#include "ClientContext.h" - -void handle_signal(int sig) -{ - switch (sig) - { - case SIGHUP: - LogPrint(eLogInfo, "Daemon: Got SIGHUP, reopening tunnel configuration..."); - i2p::client::context.ReloadConfig(); - break; - case SIGUSR1: - LogPrint(eLogInfo, "Daemon: Got SIGUSR1, reopening logs..."); - i2p::log::Logger().Reopen (); - break; - case SIGINT: - if (i2p::context.AcceptsTunnels () && !Daemon.gracefulShutdownInterval) - { - i2p::context.SetAcceptsTunnels (false); - Daemon.gracefulShutdownInterval = 10*60; // 10 minutes - LogPrint(eLogInfo, "Graceful shutdown after ", Daemon.gracefulShutdownInterval, " seconds"); - } - else - Daemon.running = 0; - break; - case SIGABRT: - case SIGTERM: - Daemon.running = 0; // Exit loop - break; - case SIGPIPE: - LogPrint(eLogInfo, "SIGPIPE received"); - break; - } -} +#include "Daemon.h" +#include +#include +#include +#include +//#include "mainwindow.h" namespace i2p { - namespace util +namespace android +{ +/* Worker::Worker (DaemonAndroidImpl& daemon): + m_Daemon (daemon) { - bool DaemonAndroid::start() - { - if (isDaemon) - { - pid_t pid; - pid = fork(); - if (pid > 0) // parent - ::exit (EXIT_SUCCESS); + } - if (pid < 0) // error - { - LogPrint(eLogError, "Daemon: could not fork: ", strerror(errno)); - return false; - } + void Worker::startDaemon() + { + Log.d(TAG"Performing daemon start..."); + m_Daemon.start(); + Log.d(TAG"Daemon started."); + emit resultReady(); + } + void Worker::restartDaemon() + { + Log.d(TAG"Performing daemon restart..."); + m_Daemon.restart(); + Log.d(TAG"Daemon restarted."); + emit resultReady(); + } + void Worker::stopDaemon() { + Log.d(TAG"Performing daemon stop..."); + m_Daemon.stop(); + Log.d(TAG"Daemon stopped."); + emit resultReady(); + } - // child - umask(S_IWGRP | S_IRWXO); // 0027 - int sid = setsid(); - if (sid < 0) - { - LogPrint(eLogError, "Daemon: could not create process group."); - return false; - } - std::string d = i2p::fs::GetDataDir(); - if (chdir(d.c_str()) != 0) - { - LogPrint(eLogError, "Daemon: could not chdir: ", strerror(errno)); - return false; - } - - // point std{in,out,err} descriptors to /dev/null - freopen("/dev/null", "r", stdin); - freopen("/dev/null", "w", stdout); - freopen("/dev/null", "w", stderr); - } - - // set proc limits - struct rlimit limit; - uint16_t nfiles; i2p::config::GetOption("limits.openfiles", nfiles); - getrlimit(RLIMIT_NOFILE, &limit); - if (nfiles == 0) { - LogPrint(eLogInfo, "Daemon: using system limit in ", limit.rlim_cur, " max open files"); - } else if (nfiles <= limit.rlim_max) { - limit.rlim_cur = nfiles; - if (setrlimit(RLIMIT_NOFILE, &limit) == 0) { - LogPrint(eLogInfo, "Daemon: set max number of open files to ", - nfiles, " (system limit is ", limit.rlim_max, ")"); - } else { - LogPrint(eLogError, "Daemon: can't set max number of open files: ", strerror(errno)); - } - } else { - LogPrint(eLogError, "Daemon: limits.openfiles exceeds system limit: ", limit.rlim_max); - } - uint32_t cfsize; i2p::config::GetOption("limits.coresize", cfsize); - if (cfsize) // core file size set - { - cfsize *= 1024; - getrlimit(RLIMIT_CORE, &limit); - if (cfsize <= limit.rlim_max) { - limit.rlim_cur = cfsize; - if (setrlimit(RLIMIT_CORE, &limit) != 0) { - LogPrint(eLogError, "Daemon: can't set max size of coredump: ", strerror(errno)); - } else if (cfsize == 0) { - LogPrint(eLogInfo, "Daemon: coredumps disabled"); - } else { - LogPrint(eLogInfo, "Daemon: set max size of core files to ", cfsize / 1024, "Kb"); - } - } else { - LogPrint(eLogError, "Daemon: limits.coresize exceeds system limit: ", limit.rlim_max); - } - } - - // Pidfile - // this code is c-styled and a bit ugly - std::string pidfile; i2p::config::GetOption("pidfile", pidfile); - if (pidfile == "") { - pidfile = i2p::fs::DataDirPath("i2pd.pid"); - } - if (pidfile != "") { - pidFH = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600); - if (pidFH < 0) - { - LogPrint(eLogError, "Daemon: could not create pid file ", pidfile, ": ", strerror(errno)); - return false; - } - char pid[10]; - sprintf(pid, "%d\n", getpid()); - ftruncate(pidFH, 0); - if (write(pidFH, pid, strlen(pid)) < 0) - { - LogPrint(eLogError, "Daemon: could not write pidfile: ", strerror(errno)); - return false; - } - } - gracefulShutdownInterval = 0; // not specified - - // Signal handler - struct sigaction sa; - sa.sa_handler = handle_signal; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; - sigaction(SIGHUP, &sa, 0); - sigaction(SIGUSR1, &sa, 0); - sigaction(SIGABRT, &sa, 0); - sigaction(SIGTERM, &sa, 0); - sigaction(SIGINT, &sa, 0); - sigaction(SIGPIPE, &sa, 0); - - return Daemon_Singleton::start(); - } - - bool DaemonAndroid::stop() - { - i2p::fs::Remove(pidfile); - - return Daemon_Singleton::stop(); - } - - void DaemonAndroid::run () - { - while (running) - { - std::this_thread::sleep_for (std::chrono::seconds(1)); - if (gracefulShutdownInterval) - { - gracefulShutdownInterval--; // - 1 second - if (gracefulShutdownInterval <= 0 || i2p::tunnel::tunnels.CountTransitTunnels() <= 0) - { - LogPrint(eLogInfo, "Graceful shutdown"); - return; - } - } - } + Controller::Controller(DaemonAndroidImpl& daemon): + m_Daemon (daemon) + { + Worker *worker = new Worker (m_Daemon); + worker->moveToThread(&workerThread); + connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); + connect(this, &Controller::startDaemon, worker, &Worker::startDaemon); + connect(this, &Controller::stopDaemon, worker, &Worker::stopDaemon); + connect(this, &Controller::restartDaemon, worker, &Worker::restartDaemon); + connect(worker, &Worker::resultReady, this, &Controller::handleResults); + workerThread.start(); + } + Controller::~Controller() + { + Log.d(TAG"Closing and waiting for daemon worker thread..."); + workerThread.quit(); + workerThread.wait(); + Log.d(TAG"Waiting for daemon worker thread finished."); + if(m_Daemon.isRunning()) + { + Log.d(TAG"Stopping the daemon..."); + m_Daemon.stop(); + Log.d(TAG"Stopped the daemon."); } } -} +*/ + DaemonAndroidImpl::DaemonAndroidImpl () + //: + /*mutex(nullptr), */ + //m_IsRunning(false), + //m_RunningChangedCallback(nullptr) + { + } -#endif + DaemonAndroidImpl::~DaemonAndroidImpl () + { + //delete mutex; + } + + bool DaemonAndroidImpl::init(int argc, char* argv[]) + { + //mutex=new QMutex(QMutex::Recursive); + //setRunningCallback(0); + //m_IsRunning=false; + return Daemon.init(argc,argv); + } + + void DaemonAndroidImpl::start() + { + //QMutexLocker locker(mutex); + //setRunning(true); + Daemon.start(); + } + + void DaemonAndroidImpl::stop() + { + //QMutexLocker locker(mutex); + Daemon.stop(); + //setRunning(false); + } + + void DaemonAndroidImpl::restart() + { + //QMutexLocker locker(mutex); + stop(); + start(); + } + /* + void DaemonAndroidImpl::setRunningCallback(runningChangedCallback cb) + { + m_RunningChangedCallback = cb; + } + + bool DaemonAndroidImpl::isRunning() + { + return m_IsRunning; + } + + void DaemonAndroidImpl::setRunning(bool newValue) + { + bool oldValue = m_IsRunning; + if(oldValue!=newValue) + { + m_IsRunning = newValue; + if(m_RunningChangedCallback) + m_RunningChangedCallback(); + } + } +*/ + 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 + { + //int result; + + { + //Log.d(TAG"Initialising the daemon..."); + bool daemonInitSuccess = daemon.init(1,argv); + if(!daemonInitSuccess) + { + //QMessageBox::critical(0, "Error", "Daemon init failed"); + return "Daemon init failed"; + } + //Log.d(TAG"Initialised, creating the main window..."); + //MainWindow w; + //Log.d(TAG"Before main window.show()..."); + //w.show (); + + { + //i2p::qt::Controller daemonQtController(daemon); + //Log.d(TAG"Starting the daemon..."); + //emit daemonQtController.startDaemon(); + //daemon.start (); + //Log.d(TAG"Starting GUI event loop..."); + //result = app.exec(); + //daemon.stop (); + daemon.start(); + } + } + + //QMessageBox::information(&w, "Debug", "demon stopped"); + //Log.d(TAG"Exiting the application"); + //return result; + } + 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(); + } +} +} diff --git a/android/jni/DaemonAndroid.h b/android/jni/DaemonAndroid.h index c62d7c76..9cc8219b 100644 --- a/android/jni/DaemonAndroid.h +++ b/android/jni/DaemonAndroid.h @@ -1,60 +1,87 @@ -#ifndef DAEMON_H__ -#define DAEMON_H__ +#ifndef DAEMON_ANDROID_H +#define DAEMON_ANDROID_H -#include #include namespace i2p { -namespace util +namespace android { - class Daemon_Singleton_Private; - class Daemon_Singleton - { - public: - virtual bool init(int argc, char* argv[]); - virtual bool start(); - virtual bool stop(); - virtual void run () {}; + class DaemonAndroidImpl + { + public: - bool isDaemon; - bool running; + DaemonAndroidImpl (); + ~DaemonAndroidImpl (); - protected: - Daemon_Singleton(); - virtual ~Daemon_Singleton(); + //typedef void (*runningChangedCallback)(); - bool IsService () const; + /** + * @return success + */ + bool init(int argc, char* argv[]); + void start(); + void stop(); + void restart(); + //void setRunningCallback(runningChangedCallback cb); + //bool isRunning(); + private: + //void setRunning(bool running); + private: + //QMutex* mutex; + //bool m_IsRunning; + //runningChangedCallback m_RunningChangedCallback; + }; - // d-pointer for httpServer, httpProxy, etc. - class Daemon_Singleton_Private; - Daemon_Singleton_Private &d; - }; + /** + * returns "ok" if daemon init failed + * returns errinfo if daemon initialized and started okay + */ + std::string start(); -#if defined(ANDROID) -#define Daemon i2p::util::DaemonAndroid::Instance() - class DaemonAndroid : public Daemon_Singleton - { - public: - static DaemonAndroid& Instance() - { - static DaemonAndroid instance; - return instance; - } + // stops the daemon + void stop(); - bool start(); - bool stop(); - void run (); + /* + class Worker : public QObject + { + Q_OBJECT + public: - private: - std::string pidfile; - int pidFH; + Worker (DaemonAndroidImpl& daemon); - public: - int gracefulShutdownInterval; // in seconds - }; -#endif + private: + + DaemonAndroidImpl& m_Daemon; + + public slots: + void startDaemon(); + void restartDaemon(); + void stopDaemon(); + + signals: + void resultReady(); + }; + + class Controller : public QObject + { + Q_OBJECT + QThread workerThread; + public: + Controller(DaemonAndroidImpl& daemon); + ~Controller(); + private: + DaemonAndroidImpl& m_Daemon; + + public slots: + void handleResults(){} + signals: + void startDaemon(); + void stopDaemon(); + void restartDaemon(); + }; + */ } } -#endif // DAEMON_H__ +#endif // DAEMON_ANDROID_H diff --git a/android/jni/i2pd_android.cpp b/android/jni/i2pd_android.cpp new file mode 100755 index 00000000..8791c90b --- /dev/null +++ b/android/jni/i2pd_android.cpp @@ -0,0 +1,66 @@ + +//#include +#include +#include "org_purplei2p_i2pd_I2PD_JNI.h" +#include "DaemonAndroid.h" +#include "RouterContext.h" +#include "Transports.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 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_onNetworkStateChanged + (JNIEnv * env, jclass clazz, jboolean isConnected) +{ + bool isConnectedBool = (bool) isConnected; + i2p::transport::transports.SetOnline (isConnectedBool); +} diff --git a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h new file mode 100644 index 00000000..04923d22 --- /dev/null +++ b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h @@ -0,0 +1,33 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* 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 +/* + * Class: org_purplei2p_i2pd_I2PD_JNI + * Method: stringFromJNI + * Signature: ()Ljava/lang/String; + */ +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_stopAcceptingTunnels + (JNIEnv *, jclass); + +JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged + (JNIEnv * env, jclass clazz, jboolean isConnected); + +#ifdef __cplusplus +} +#endif +#endif