From 0078501dbacd01cc38abf16511ae7943cbbf78b7 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Sat, 29 Sep 2018 00:15:10 +0200 Subject: [PATCH 01/28] Initial work on a RetroShare cross-platform service This doesn't need any interacion of the user at startup, unlike retroshare-nogui which requires the user to login on the shell this doesn't even need a TTY. At startup this just parse command line, read the PGP keyring, look for available locations, and start listening for JSON API requests. Another difference with retroshare-nogui is that this is capable to generate/import PGP identities, generate locations, and in general anything possible through the RetroShare API. retroshare-service is suitable also to run it as a system service, even in very constrained systems such as Android ot a Docker container. retroshare-service drop support for libresapi so only the new JSON API is exposed, it will completely obsolete retroshare-android-service once retroshare-qml-app is ported to the new JSON API. --- RetroShare.pro | 17 +- .../Android/prepare-toolchain-clang.sh | 334 ++++++++++++++++++ libretroshare/src/libretroshare.pro | 20 +- libretroshare/src/use_libretroshare.pri | 4 +- libretroshare/src/util/rsurl.cc | 4 +- retroshare-service/src/android/.gitignore | 3 + .../src/android/AndroidManifest.xml | 54 +++ retroshare-service/src/android/build.gradle | 57 +++ .../android/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + retroshare-service/src/android/gradlew | 172 +++++++++ retroshare-service/src/android/gradlew.bat | 84 +++++ .../res/drawable/retroshare_128x128.png | 1 + .../android/res/drawable/retroshare_48x48.png | 1 + .../src/android/res/values/libs.xml | 25 ++ retroshare-service/src/retroshare-service.cc | 73 ++++ retroshare-service/src/retroshare-service.pro | 27 ++ retroshare.pri | 30 ++ 18 files changed, 894 insertions(+), 17 deletions(-) create mode 100755 build_scripts/Android/prepare-toolchain-clang.sh create mode 100644 retroshare-service/src/android/.gitignore create mode 100644 retroshare-service/src/android/AndroidManifest.xml create mode 100644 retroshare-service/src/android/build.gradle create mode 100644 retroshare-service/src/android/gradle/wrapper/gradle-wrapper.jar create mode 100644 retroshare-service/src/android/gradle/wrapper/gradle-wrapper.properties create mode 100755 retroshare-service/src/android/gradlew create mode 100644 retroshare-service/src/android/gradlew.bat create mode 120000 retroshare-service/src/android/res/drawable/retroshare_128x128.png create mode 120000 retroshare-service/src/android/res/drawable/retroshare_48x48.png create mode 100644 retroshare-service/src/android/res/values/libs.xml create mode 100644 retroshare-service/src/retroshare-service.cc create mode 100644 retroshare-service/src/retroshare-service.pro diff --git a/RetroShare.pro b/RetroShare.pro index 4197db2e0..a1283a1bb 100644 --- a/RetroShare.pro +++ b/RetroShare.pro @@ -23,7 +23,7 @@ TEMPLATE = subdirs SUBDIRS += openpgpsdk openpgpsdk.file = openpgpsdk/src/openpgpsdk.pro -rs_jsonapi { +rs_jsonapi:isEmpty(JSONAPI_GENERATOR_EXE) { SUBDIRS += jsonapi-generator jsonapi-generator.file = jsonapi-generator/src/jsonapi-generator.pro libretroshare.depends += jsonapi-generator @@ -36,9 +36,11 @@ libretroshare.depends = openpgpsdk libbitdht SUBDIRS += libretroshare libretroshare.file = libretroshare/src/libretroshare.pro -SUBDIRS += libresapi -libresapi.file = libresapi/src/libresapi.pro -libresapi.depends = libretroshare +libresapi { + SUBDIRS += libresapi + libresapi.file = libresapi/src/libresapi.pro + libresapi.depends = libretroshare +} retroshare_gui { SUBDIRS += retroshare_gui @@ -79,6 +81,13 @@ retroshare_qml_app { } } +retroshare_service { + SUBDIRS += retroshare_service + retroshare_service.file = retroshare-service/src/retroshare-service.pro + retroshare_service.depends = libretroshare + retroshare_service.target = retroshare_service +} + retroshare_plugins { SUBDIRS += plugins plugins.file = plugins/plugins.pro diff --git a/build_scripts/Android/prepare-toolchain-clang.sh b/build_scripts/Android/prepare-toolchain-clang.sh new file mode 100755 index 000000000..0e9fdb7f7 --- /dev/null +++ b/build_scripts/Android/prepare-toolchain-clang.sh @@ -0,0 +1,334 @@ +#!/bin/bash + +## Define default value for variable, take two arguments, $1 variable name, +## $2 default variable value, if the variable is not already define define it +## with default value. +function define_default_value() +{ + VAR_NAME="${1}" + DEFAULT_VALUE="${2}" + + [ -z "${!VAR_NAME}" ] && export ${VAR_NAME}="${DEFAULT_VALUE}" +} + +## You are supposed to provide the following variables according to your system setup +define_default_value ANDROID_NDK_PATH "/opt/android-ndk/" +define_default_value ANDROID_NDK_ARCH "arm" +define_default_value ANDROID_PLATFORM_VER "21" +define_default_value NATIVE_LIBS_TOOLCHAIN_PATH "${HOME}/Builds/android-toolchains/retroshare-android-${ANDROID_PLATFORM_VER}-${ANDROID_NDK_ARCH}/" +define_default_value HOST_NUM_CPU $(nproc) + +define_default_value BZIP2_SOURCE_VERSION "1.0.6" +define_default_value BZIP2_SOURCE_SHA256 a2848f34fcd5d6cf47def00461fcb528a0484d8edef8208d6d2e2909dc61d9cd + +define_default_value OPENSSL_SOURCE_VERSION "1.1.1" +define_default_value OPENSSL_SOURCE_SHA256 2836875a0f89c03d0fdf483941512613a50cfb421d6fd94b9f41d7279d586a3d + +define_default_value SQLITE_SOURCE_YEAR "2018" +define_default_value SQLITE_SOURCE_VERSION "3250200" +define_default_value SQLITE_SOURCE_SHA256 da9a1484423d524d3ac793af518cdf870c8255d209e369bd6a193e9f9d0e3181 + +define_default_value SQLCIPHER_SOURCE_VERSION "3.4.2" +define_default_value SQLCIPHER_SOURCE_SHA256 69897a5167f34e8a84c7069f1b283aba88cdfa8ec183165c4a5da2c816cfaadb + +define_default_value LIBUPNP_SOURCE_VERSION "1.6.25" +define_default_value LIBUPNP_SOURCE_SHA256 c5a300b86775435c076d58a79cc0d5a977d76027d2a7d721590729b7f369fa43 + +define_default_value INSTALL_QT_ANDROID "false" +define_default_value QT_VERSION "5.9.6" +define_default_value QT_ANDROID_INSTALLER_SHA256 a214084e2295c9a9f8727e8a0131c37255bf724bfc69e80f7012ba3abeb1f763 + +define_default_value RESTBED_SOURCE_VERSION "4.6" + +## $1 filename, $2 sha256 hash +function check_sha256() +{ + echo ${2} "${1}" | sha256sum -c &> /dev/null +} + +## $1 filename, $2 sha256 hash, $3 url +function verified_download() +{ + FILENAME="$1" + SHA256="$2" + URL="$3" + + check_sha256 "${FILENAME}" "${SHA256}" || + { + rm -rf "${FILENAME}" + + wget -O "${FILENAME}" "$URL" || + { + echo "Failed downloading ${FILENAME} from $URL" + exit 1 + } + + check_sha256 "${FILENAME}" "${SHA256}" || + { + echo "SHA256 mismatch for ${FILENAME} from ${URL} expected sha256 ${SHA256} got $(sha256sum ${FILENAME} | awk '{print $1}')" + exit 1 + } + } +} + + + +if [ "${ANDROID_NDK_ARCH}" == "x86" ]; then + cArch="i686" + eABI="" +else + cArch="${ANDROID_NDK_ARCH}" + eABI="eabi" +fi +export SYSROOT="${NATIVE_LIBS_TOOLCHAIN_PATH}/sysroot/" +export PREFIX="${SYSROOT}/usr/" +export CC="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-clang" +export CXX="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-clang++" +export AR="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-ar" +export RANLIB="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-ranlib" + + +## More information available at https://android.googlesource.com/platform/ndk/+/ics-mr0/docs/STANDALONE-TOOLCHAIN.html +build_toolchain() +{ + rm -rf ${NATIVE_LIBS_TOOLCHAIN_PATH} + ${ANDROID_NDK_PATH}/build/tools/make_standalone_toolchain.py --verbose \ + --arch ${ANDROID_NDK_ARCH} --install-dir ${NATIVE_LIBS_TOOLCHAIN_PATH} \ + --api ${ANDROID_PLATFORM_VER} +} + +## More information available at https://gitlab.com/relan/provisioners/merge_requests/1 and http://stackoverflow.com/a/34032216 +install_qt_android() +{ + QT_VERSION_CODE=$(echo $QT_VERSION | tr -d .) + QT_INSTALL_PATH=${NATIVE_LIBS_TOOLCHAIN_PATH}/Qt + QT_INSTALLER="qt-unified-linux-x64-3.0.2-online.run" + + verified_download $QT_INSTALLER $QT_ANDROID_INSTALLER_SHA256 \ + http://master.qt.io/archive/online_installers/3.0/${QT_INSTALLER} + + chmod a+x ${QT_INSTALLER} + + QT_INSTALLER_SCRIPT="qt_installer_script.js" + cat << EOF > "${QT_INSTALLER_SCRIPT}" +function Controller() { + installer.autoRejectMessageBoxes(); + installer.installationFinished.connect(function() { + gui.clickButton(buttons.NextButton); + }); + + var welcomePage = gui.pageWidgetByObjectName("WelcomePage"); + welcomePage.completeChanged.connect(function() { + if (gui.currentPageWidget().objectName == welcomePage.objectName) + gui.clickButton(buttons.NextButton); + }); +} + +Controller.prototype.WelcomePageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.CredentialsPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.IntroductionPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.TargetDirectoryPageCallback = function() { + gui.currentPageWidget().TargetDirectoryLineEdit.setText("$QT_INSTALL_PATH"); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ComponentSelectionPageCallback = function() { + var widget = gui.currentPageWidget(); + + // You can get these component names by running the installer with the + // --verbose flag. It will then print out a resource tree. + + widget.deselectComponent("qt.tools.qtcreator"); + widget.deselectComponent("qt.tools.doc"); + widget.deselectComponent("qt.tools.examples"); + + widget.selectComponent("qt.$QT_VERSION_CODE.android_armv7"); + + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.LicenseAgreementPageCallback = function() { + gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.StartMenuDirectoryPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.ReadyForInstallationPageCallback = function() { + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.FinishedPageCallback = function() { + var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm; + if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) + checkBoxForm.launchQtCreatorCheckBox.checked = false; + gui.clickButton(buttons.FinishButton); +} +EOF + +QT_QPA_PLATFORM=minimal ./${QT_INSTALLER} --script ${QT_INSTALLER_SCRIPT} +} + +## More information available at retroshare://file?name=Android%20Native%20Development%20Kit%20Cookbook.pdf&size=29214468&hash=0123361c1b14366ce36118e82b90faf7c7b1b136 +build_bzlib() +{ + B_dir="bzip2-${BZIP2_SOURCE_VERSION}" + rm -rf $B_dir + + verified_download $B_dir.tar.gz $BZIP2_SOURCE_SHA256 \ + http://trumpetti.atm.tut.fi/gentoo/distfiles/bzip2-${BZIP2_SOURCE_VERSION}.tar.gz + + tar -xf $B_dir.tar.gz + cd $B_dir + sed -i "/^CC=.*/d" Makefile + sed -i "/^AR=.*/d" Makefile + sed -i "/^RANLIB=.*/d" Makefile + sed -i "/^LDFLAGS=.*/d" Makefile + sed -i "s/^all: libbz2.a bzip2 bzip2recover test/all: libbz2.a bzip2 bzip2recover/" Makefile + make -j${HOST_NUM_CPU} + make install PREFIX=${PREFIX} +# sed -i "/^CC=.*/d" Makefile-libbz2_so +# make -f Makefile-libbz2_so -j${HOST_NUM_CPU} +# cp libbz2.so.1.0.6 ${SYSROOT}/usr/lib/libbz2.so + cd .. +} + +## More information available at http://doc.qt.io/qt-5/opensslsupport.html +build_openssl() +{ + B_dir="openssl-${OPENSSL_SOURCE_VERSION}" + rm -rf $B_dir + + verified_download $B_dir.tar.gz $OPENSSL_SOURCE_SHA256 \ + https://www.openssl.org/source/$B_dir.tar.gz + + tar -xf $B_dir.tar.gz + cd $B_dir +## We link openssl statically to avoid android silently sneaking in his own +## version of libssl.so (we noticed this because it had some missing symbol +## that made RS crash), the crash in some android version is only one of the +## possible problems the fact that android insert his own binary libssl.so pose +## non neglegible security concerns. + oBits="32" + [[ ${ANDROID_NDK_ARCH} =~ .*64.* ]] && oBits=64 + + ANDROID_NDK="${ANDROID_NDK_PATH}" PATH="${SYSROOT}/bin/:${PATH}" \ + ./Configure linux-generic${oBits} --prefix="${PREFIX}" \ + --openssldir="${SYSROOT}/etc/ssl" +# sed -i 's/LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \\/LIBNAME=$$i \\/g' Makefile +# sed -i '/LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \\/d' Makefile + make -j${HOST_NUM_CPU} + make install +# cp *.so "${SYSROOT}/usr/lib" + cd .. +} + +build_sqlite() +{ + B_dir="sqlite-autoconf-${SQLITE_SOURCE_VERSION}" + + verified_download $B_dir.tar.gz $SQLITE_SOURCE_SHA256 \ + https://www.sqlite.org/${SQLITE_SOURCE_YEAR}/$B_dir.tar.gz + + tar -xf $B_dir.tar.gz + cd $B_dir + ./configure --prefix="${PREFIX}" --host=${ANDROID_NDK_ARCH}-linux + make -j${HOST_NUM_CPU} + make install + rm -f ${PREFIX}/lib/libsqlite3.so* +# ${CC} -shared -o libsqlite3.so -fPIC sqlite3.o -ldl +# cp libsqlite3.so "${SYSROOT}/usr/lib" + cd .. +} + +build_sqlcipher() +{ + B_dir="sqlcipher-${SQLCIPHER_SOURCE_VERSION}" + rm -rf $B_dir + + T_file="${B_dir}.tar.gz" + + verified_download $T_file $SQLCIPHER_SOURCE_SHA256 \ + https://github.com/sqlcipher/sqlcipher/archive/v${SQLCIPHER_SOURCE_VERSION}.tar.gz + + tar -xf $T_file + cd $B_dir + ./configure --build=$(sh ./config.guess) \ + --host=${ANDROID_NDK_ARCH}-linux \ + --prefix="${PREFIX}" --with-sysroot="${SYSROOT}" \ + --enable-tempstore=yes \ + --disable-tcl --disable-shared \ + CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="${PREFIX}/lib/libcrypto.a" + make -j${HOST_NUM_CPU} + make install + cd .. +} + +build_libupnp() +{ + B_dir="libupnp-${LIBUPNP_SOURCE_VERSION}" + rm -rf $B_dir + + verified_download $B_dir.tar.bz2 $LIBUPNP_SOURCE_SHA256 \ + https://sourceforge.net/projects/pupnp/files/pupnp/libUPnP%20${LIBUPNP_SOURCE_VERSION}/$B_dir.tar.bz2 + + tar -xf $B_dir.tar.bz2 + cd $B_dir +## liupnp must be configured as static library because if not the linker will +## look for libthreadutils.so.6 at runtime that cannot be packaged on android +## as it supports only libname.so format for libraries, thus resulting in a +## crash at startup. + ./configure --enable-static --disable-shared --disable-samples --prefix="${PREFIX}" --host=${ANDROID_NDK_ARCH}-linux + make -j${HOST_NUM_CPU} + make install + cd .. +} + +build_rapidjson() +{ + B_dir="rapidjson-1.1.0" + [ -f $B_dir.tar.gz ] || wget -O $B_dir.tar.gz https://github.com/Tencent/rapidjson/archive/v1.1.0.tar.gz + tar -xf $B_dir.tar.gz + cp -r rapidjson-1.1.0/include/rapidjson/ "${PREFIX}/include/rapidjson" +} + +build_restbed() +{ + [ -d restbed ] || git clone --depth=2000 https://github.com/Corvusoft/restbed.git + cd restbed + git fetch --tags + git checkout tags/${RESTBED_SOURCE_VERSION} + git submodule update --init dependency/asio + git submodule update --init dependency/catch + git submodule update --init dependency/kashmir + cd .. + + rm -rf restbed-build; mkdir restbed-build ; cd restbed-build + cmake -DBUILD_SSL=OFF -DCMAKE_INSTALL_PREFIX=${PREFIX} -B. -H../restbed + make -j${HOST_NUM_CPU} + make install + cd .. +} + +build_toolchain +[ "${INSTALL_QT_ANDROID}X" != "trueX" ] || install_qt_android +build_bzlib +build_openssl +build_sqlite +build_sqlcipher +build_libupnp +build_rapidjson +build_restbed + +echo NATIVE_LIBS_TOOLCHAIN_PATH=${NATIVE_LIBS_TOOLCHAIN_PATH} diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 4bafccec7..3f9d13331 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -862,16 +862,19 @@ rs_gxs_trans { rs_jsonapi { JSONAPI_GENERATOR_SRC=$$clean_path($${RS_SRC_PATH}/jsonapi-generator/src/) JSONAPI_GENERATOR_OUT=$$clean_path($${RS_BUILD_PATH}/jsonapi-generator/src/) - win32 { - CONFIG(release, debug|release) { - JSONAPI_GENERATOR_EXE=$$clean_path($${JSONAPI_GENERATOR_OUT}/release/jsonapi-generator.exe) + isEmpty(JSONAPI_GENERATOR_EXE) { + win32 { + CONFIG(release, debug|release) { + JSONAPI_GENERATOR_EXE=$$clean_path($${JSONAPI_GENERATOR_OUT}/release/jsonapi-generator.exe) + } + CONFIG(debug, debug|release) { + JSONAPI_GENERATOR_EXE=$$clean_path($${JSONAPI_GENERATOR_OUT}/debug/jsonapi-generator.exe) + } + } else { + JSONAPI_GENERATOR_EXE=$$clean_path($${JSONAPI_GENERATOR_OUT}/jsonapi-generator) } - CONFIG(debug, debug|release) { - JSONAPI_GENERATOR_EXE=$$clean_path($${JSONAPI_GENERATOR_OUT}/debug/jsonapi-generator.exe) - } - } else { - JSONAPI_GENERATOR_EXE=$$clean_path($${JSONAPI_GENERATOR_OUT}/jsonapi-generator) } + DOXIGEN_INPUT_DIRECTORY=$$clean_path($${PWD}) DOXIGEN_CONFIG_SRC=$$clean_path($${RS_SRC_PATH}/jsonapi-generator/src/jsonapi-generator-doxygen.conf) DOXIGEN_CONFIG_OUT=$$clean_path($${JSONAPI_GENERATOR_OUT}/jsonapi-generator-doxygen-final.conf) @@ -899,6 +902,7 @@ rs_jsonapi { jsonwrappersincl.target = $${WRAPPERS_INCL_FILE} jsonwrappersincl.commands = \ + mkdir -p $${JSONAPI_GENERATOR_OUT}; \ cp $${DOXIGEN_CONFIG_SRC} $${DOXIGEN_CONFIG_OUT}; \ echo OUTPUT_DIRECTORY=$$shell_path($${JSONAPI_GENERATOR_OUT}) >> $${DOXIGEN_CONFIG_OUT};\ echo INPUT=$$shell_path($${DOXIGEN_INPUT_DIRECTORY}) >> $${DOXIGEN_CONFIG_OUT}; \ diff --git a/libretroshare/src/use_libretroshare.pri b/libretroshare/src/use_libretroshare.pri index 8129f8132..64d6dbce0 100644 --- a/libretroshare/src/use_libretroshare.pri +++ b/libretroshare/src/use_libretroshare.pri @@ -57,9 +57,7 @@ rs_jsonapi { QMAKE_LIBDIR *= $$clean_path($${RESTBED_BUILD_PATH}/library/) # Using sLibs would fail as librestbed.a is generated at compile-time LIBS *= -L$$clean_path($${RESTBED_BUILD_PATH}/library/) -lrestbed - win32-g++ { - LIBS += -lwsock32 - } + win32-g++:LIBS += -lwsock32 } linux-* { diff --git a/libretroshare/src/util/rsurl.cc b/libretroshare/src/util/rsurl.cc index efaab9777..3775f8436 100644 --- a/libretroshare/src/util/rsurl.cc +++ b/libretroshare/src/util/rsurl.cc @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -//#include "util/rsurl.h" + #include "rsurl.h" #include @@ -245,7 +245,7 @@ RsUrl& RsUrl::setFragment(const std::string& fragment) if(str[i] == '%' && i < boundary) { - decoded << static_cast(stoi(str.substr(++i, 2), 0, 16)); + decoded << static_cast(std::stoi(str.substr(++i, 2), 0, 16)); ++i; } else decoded << str[i]; diff --git a/retroshare-service/src/android/.gitignore b/retroshare-service/src/android/.gitignore new file mode 100644 index 000000000..dfe00b261 --- /dev/null +++ b/retroshare-service/src/android/.gitignore @@ -0,0 +1,3 @@ +*~ +gradle.properties +local.properties diff --git a/retroshare-service/src/android/AndroidManifest.xml b/retroshare-service/src/android/AndroidManifest.xml new file mode 100644 index 000000000..ca062305c --- /dev/null +++ b/retroshare-service/src/android/AndroidManifest.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/retroshare-service/src/android/build.gradle b/retroshare-service/src/android/build.gradle new file mode 100644 index 000000000..8affd3c0b --- /dev/null +++ b/retroshare-service/src/android/build.gradle @@ -0,0 +1,57 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.0.1' + } +} + +repositories { + google() + jcenter() +} + +apply plugin: 'com.android.application' + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) +} + +android { + /******************************************************* + * The following variables: + * - androidBuildToolsVersion, + * - androidCompileSdkVersion + * - qt5AndroidDir - holds the path to qt android files + * needed to build any Qt application + * on Android. + * + * are defined in gradle.properties file. This file is + * updated by QtCreator and androiddeployqt tools. + * Changing them manually might break the compilation! + *******************************************************/ + + compileSdkVersion androidCompileSdkVersion.toInteger() + + buildToolsVersion androidBuildToolsVersion + + sourceSets { + main { + manifest.srcFile 'AndroidManifest.xml' + java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java'] + aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl'] + res.srcDirs = [qt5AndroidDir + '/res', 'res'] + resources.srcDirs = ['src'] + renderscript.srcDirs = ['src'] + assets.srcDirs = ['assets'] + jniLibs.srcDirs = ['libs'] + } + } + + lintOptions { + abortOnError false + } +} diff --git a/retroshare-service/src/android/gradle/wrapper/gradle-wrapper.jar b/retroshare-service/src/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..f6b961fd5a86aa5fbfe90f707c3138408be7c718 GIT binary patch literal 54329 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

<5G2M1WZP5 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 F{|7XC?P&l2 literal 0 HcmV?d00001 diff --git a/retroshare-service/src/android/gradle/wrapper/gradle-wrapper.properties b/retroshare-service/src/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..bf3de2183 --- /dev/null +++ b/retroshare-service/src/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/retroshare-service/src/android/gradlew b/retroshare-service/src/android/gradlew new file mode 100755 index 000000000..cccdd3d51 --- /dev/null +++ b/retroshare-service/src/android/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/retroshare-service/src/android/gradlew.bat b/retroshare-service/src/android/gradlew.bat new file mode 100644 index 000000000..f9553162f --- /dev/null +++ b/retroshare-service/src/android/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/retroshare-service/src/android/res/drawable/retroshare_128x128.png b/retroshare-service/src/android/res/drawable/retroshare_128x128.png new file mode 120000 index 000000000..9fd712c47 --- /dev/null +++ b/retroshare-service/src/android/res/drawable/retroshare_128x128.png @@ -0,0 +1 @@ +../../../../../data/128x128/apps/retroshare.png \ No newline at end of file diff --git a/retroshare-service/src/android/res/drawable/retroshare_48x48.png b/retroshare-service/src/android/res/drawable/retroshare_48x48.png new file mode 120000 index 000000000..d22c7e812 --- /dev/null +++ b/retroshare-service/src/android/res/drawable/retroshare_48x48.png @@ -0,0 +1 @@ +../../../../../data/48x48/apps/retroshare.png \ No newline at end of file diff --git a/retroshare-service/src/android/res/values/libs.xml b/retroshare-service/src/android/res/values/libs.xml new file mode 100644 index 000000000..4009a7785 --- /dev/null +++ b/retroshare-service/src/android/res/values/libs.xml @@ -0,0 +1,25 @@ + + + + https://download.qt.io/ministro/android/qt5/qt-5.9 + + + + + + + + + + + + + + + + + + + + diff --git a/retroshare-service/src/retroshare-service.cc b/retroshare-service/src/retroshare-service.cc new file mode 100644 index 000000000..5b4dd0e15 --- /dev/null +++ b/retroshare-service/src/retroshare-service.cc @@ -0,0 +1,73 @@ +/* + * RetroShare Service + * Copyright (C) 2016-2018 Gioacchino Mazzurco + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include "retroshare/rsinit.h" +#include "retroshare/rsiface.h" + +#ifdef __ANDROID__ +# include "util/androiddebug.h" +#endif + +#ifndef RS_JSONAPI +# error Inconsistent build configuration retroshare_service needs rs_jsonapi +#endif + +int main(int argc, char* argv[]) +{ +#ifdef __ANDROID__ + AndroidStdIOCatcher dbg; (void) dbg; +#endif + + QCoreApplication app(argc, argv); + + signal(SIGINT, QCoreApplication::exit); + signal(SIGTERM, QCoreApplication::exit); +#ifdef SIGBREAK + signal(SIGBREAK, QCoreApplication::exit); +#endif // ifdef SIGBREAK + + RsInit::InitRsConfig(); + + // clumsy way to enable JSON API by default + if(!QCoreApplication::arguments().contains("--jsonApiPort")) + { + int argc2 = argc + 2; + char* argv2[argc2]; for (int i = 0; i < argc; ++i ) argv2[i] = argv[i]; + char opt[] = "--jsonApiPort"; + char val[] = "9092"; + argv2[argc] = opt; + argv2[argc+1] = val; + RsInit::InitRetroShare(argc2, argv2, true); + } + else RsInit::InitRetroShare(argc, argv, true); + + RsControl::earlyInitNotificationSystem(); + rsControl->setShutdownCallback(QCoreApplication::exit); + QObject::connect( + &app, &QCoreApplication::aboutToQuit, + [](){ + if(RsControl::instance()->isReady()) + RsControl::instance()->rsGlobalShutDown(); } ); + + return app.exec(); +} diff --git a/retroshare-service/src/retroshare-service.pro b/retroshare-service/src/retroshare-service.pro new file mode 100644 index 000000000..e1911f179 --- /dev/null +++ b/retroshare-service/src/retroshare-service.pro @@ -0,0 +1,27 @@ +!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri") + +TARGET = retroshare-service + +QT += core +QT -= gui + +!include("../../libretroshare/src/use_libretroshare.pri"):error("Including") + +SOURCES += retroshare-service.cc + +android-* { + ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android + + DISTFILES += android/AndroidManifest.xml \ + android/res/drawable/retroshare_128x128.png \ + android/res/drawable/retroshare_retroshare_48x48.png +} + +DISTFILES += \ + android/AndroidManifest.xml \ + android/gradle/wrapper/gradle-wrapper.jar \ + android/gradlew \ + android/res/values/libs.xml \ + android/build.gradle \ + android/gradle/wrapper/gradle-wrapper.properties \ + android/gradlew.bat diff --git a/retroshare.pri b/retroshare.pri index 497281134..213d10832 100644 --- a/retroshare.pri +++ b/retroshare.pri @@ -64,6 +64,16 @@ retroshare_android_notify_service:CONFIG -= no_retroshare_android_notify_service CONFIG *= no_retroshare_qml_app retroshare_qml_app:CONFIG -= no_retroshare_qml_app +# To enable RetroShare service append the following assignation to +# qmake command line "CONFIG+=retroshare_service" +CONFIG *= no_retroshare_service +retroshare_service:CONFIG -= no_retroshare_service + +# To disable libresapi append the following assignation to qmake command line +#"CONFIG+=no_libresapi" +CONFIG *= libresapi +no_libresapi:CONFIG -= libresapi + # To enable libresapi via local socket (unix domain socket or windows named # pipes) append the following assignation to qmake command line #"CONFIG+=libresapilocalserver" @@ -144,6 +154,12 @@ CONFIG+=no_rs_deep_search CONFIG *= rs_deep_search no_rs_deep_search:CONFIG -= rs_deep_search +# Specify host precompiled jsonapi-generator path, appending the following +# assignation to qmake command line +# 'JSONAPI_GENERATOR_EXE=/myBuildDir/jsonapi-generator'. Required for JSON API +# cross-compiling +#JSONAPI_GENERATOR_EXE=/myBuildDir/jsonapi-generator + # Specify RetroShare major version appending the following assignation to qmake # command line 'RS_MAJOR_VERSION=0' #RS_MAJOR_VERSION=0 @@ -299,6 +315,16 @@ defineReplace(linkDynamicLibs) { ## RS_THREAD_LIB String viariable containing the name of the multi threading ## library to use (pthread, "") it usually depend on platform. +isEmpty(QMAKE_HOST_SPEC):QMAKE_HOST_SPEC=$$[QMAKE_SPEC] +isEmpty(QMAKE_TARGET_SPEC):QMAKE_TARGET_SPEC=$$[QMAKE_XSPEC] +equals(QMAKE_HOST_SPEC, $$QMAKE_TARGET_SPEC) { + CONFIG *= no_rs_cross_compiling + CONFIG -= rs_cross_compiling +} else { + CONFIG *= rs_cross_compiling + CONFIG -= no_rs_cross_compiling +} + defined(RS_MAJOR_VERSION,var):\ defined(RS_MINOR_VERSION,var):\ defined(RS_MINI_VERSION,var):\ @@ -408,6 +434,10 @@ rs_chatserver { } rs_jsonapi { + rs_cross_compiling:!exists($$JSONAPI_GENERATOR_EXE):error("Inconsistent \ +build configuration, cross-compiling JSON API requires JSONAPI_GENERATOR_EXE \ +to contain the path to an host executable jsonapi-generator") + DEFINES *= RS_JSONAPI } From 8f3f2cd7cb15985dd213ef7c646f918a76113b2a Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 3 Oct 2018 15:53:18 +0200 Subject: [PATCH 02/28] retroshare-service improve building process --- RetroShare.pro | 14 +- .../Android/prepare-toolchain-clang.sh | 2 +- data/retroshare.svg | 263 ++++++++++++++++++ libretroshare/src/libretroshare.pro | 3 +- .../data/retroshare-service.desktop | 10 + .../data/retroshare-service.svg | 188 +++++++++++++ .../src/retroshare-service.inkscape.svg | 241 ++++++++++++++++ retroshare-service/src/retroshare-service.pro | 30 +- 8 files changed, 738 insertions(+), 13 deletions(-) create mode 100644 data/retroshare.svg create mode 100644 retroshare-service/data/retroshare-service.desktop create mode 100644 retroshare-service/data/retroshare-service.svg create mode 100644 retroshare-service/src/retroshare-service.inkscape.svg diff --git a/RetroShare.pro b/RetroShare.pro index a1283a1bb..a54336847 100644 --- a/RetroShare.pro +++ b/RetroShare.pro @@ -45,15 +45,25 @@ libresapi { retroshare_gui { SUBDIRS += retroshare_gui retroshare_gui.file = retroshare-gui/src/retroshare-gui.pro - retroshare_gui.depends = libretroshare libresapi retroshare_gui.target = retroshare_gui + + libresapi { + retroshare_gui.depends = libresapi + } else { + retroshare_gui.depends = libretroshare + } } retroshare_nogui { SUBDIRS += retroshare_nogui retroshare_nogui.file = retroshare-nogui/src/retroshare-nogui.pro - retroshare_nogui.depends = libretroshare libresapi retroshare_nogui.target = retroshare_nogui + + libresapi { + retroshare_gui.depends = libresapi + } else { + retroshare_gui.depends = libretroshare + } } retroshare_android_service { diff --git a/build_scripts/Android/prepare-toolchain-clang.sh b/build_scripts/Android/prepare-toolchain-clang.sh index 0e9fdb7f7..158d3b28a 100755 --- a/build_scripts/Android/prepare-toolchain-clang.sh +++ b/build_scripts/Android/prepare-toolchain-clang.sh @@ -329,6 +329,6 @@ build_sqlite build_sqlcipher build_libupnp build_rapidjson -build_restbed +#build_restbed # qmake build it already echo NATIVE_LIBS_TOOLCHAIN_PATH=${NATIVE_LIBS_TOOLCHAIN_PATH} diff --git a/data/retroshare.svg b/data/retroshare.svg new file mode 100644 index 000000000..403f4fb52 --- /dev/null +++ b/data/retroshare.svg @@ -0,0 +1,263 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 3f9d13331..0bbc52969 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -890,7 +890,8 @@ rs_jsonapi { git submodule update --init --recommend-shallow dependency/catch;\ git submodule update --init --recommend-shallow dependency/kashmir;\ mkdir -p $${RESTBED_BUILD_PATH}; cd $${RESTBED_BUILD_PATH};\ - cmake -DBUILD_SSL=OFF -DCMAKE_INSTALL_PREFIX=. -B. -H$$shell_path($${RESTBED_SRC_PATH});\ + cmake -DCMAKE_CXX_COMPILER=$$QMAKE_CXX -DBUILD_SSL=OFF \ + -DCMAKE_INSTALL_PREFIX=. -B. -H$$shell_path($${RESTBED_SRC_PATH});\ make; make install QMAKE_EXTRA_TARGETS += restbed libretroshare.depends += restbed diff --git a/retroshare-service/data/retroshare-service.desktop b/retroshare-service/data/retroshare-service.desktop new file mode 100644 index 000000000..5d077597b --- /dev/null +++ b/retroshare-service/data/retroshare-service.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Encoding=UTF-8 +Version=1.0 +Name=RetroShare System Service +Comment=Securely share files with your friends (system service) +Exec=retroshare-service %U +Icon=retroshare-service +Terminal=false +Type=Application +Categories=Application;Network; diff --git a/retroshare-service/data/retroshare-service.svg b/retroshare-service/data/retroshare-service.svg new file mode 100644 index 000000000..74e38942a --- /dev/null +++ b/retroshare-service/data/retroshare-service.svg @@ -0,0 +1,188 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/retroshare-service/src/retroshare-service.inkscape.svg b/retroshare-service/src/retroshare-service.inkscape.svg new file mode 100644 index 000000000..911297753 --- /dev/null +++ b/retroshare-service/src/retroshare-service.inkscape.svg @@ -0,0 +1,241 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/retroshare-service/src/retroshare-service.pro b/retroshare-service/src/retroshare-service.pro index e1911f179..5574cbabc 100644 --- a/retroshare-service/src/retroshare-service.pro +++ b/retroshare-service/src/retroshare-service.pro @@ -14,14 +14,26 @@ android-* { DISTFILES += android/AndroidManifest.xml \ android/res/drawable/retroshare_128x128.png \ - android/res/drawable/retroshare_retroshare_48x48.png + android/res/drawable/retroshare_retroshare_48x48.png \ + android/gradle/wrapper/gradle-wrapper.jar \ + android/gradlew \ + android/res/values/libs.xml \ + android/build.gradle \ + android/gradle/wrapper/gradle-wrapper.properties \ + android/gradlew.bat } -DISTFILES += \ - android/AndroidManifest.xml \ - android/gradle/wrapper/gradle-wrapper.jar \ - android/gradlew \ - android/res/values/libs.xml \ - android/build.gradle \ - android/gradle/wrapper/gradle-wrapper.properties \ - android/gradlew.bat +appimage { + icon_files.path = "$${PREFIX}/share/icons/hicolor/scalable/" + icon_files.files = ../data/retroshare-service.svg + INSTALLS += icon_files + + desktop_files.path = "$${PREFIX}/share/applications" + desktop_files.files = ../data/retroshare-service.desktop + INSTALLS += desktop_files +} + +unix { + target.path = "$${RS_BIN_DIR}" + INSTALLS += target +} From f26a0c793ef659114e282c23ef568ea5934b75b3 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 3 Oct 2018 18:17:29 +0200 Subject: [PATCH 03/28] jsonapi-generator Fix warning that cause errors on mageia --- jsonapi-generator/src/jsonapi-generator.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/jsonapi-generator/src/jsonapi-generator.cpp b/jsonapi-generator/src/jsonapi-generator.cpp index 21f2a1b93..154406594 100644 --- a/jsonapi-generator/src/jsonapi-generator.cpp +++ b/jsonapi-generator/src/jsonapi-generator.cpp @@ -45,7 +45,7 @@ int main(int argc, char *argv[]) if(argc != 3) { qDebug() << "Usage: jsonapi-generator SOURCE_PATH OUTPUT_PATH"; - return EINVAL; + return -EINVAL; } QString sourcePath(argv[1]); @@ -56,17 +56,23 @@ int main(int argc, char *argv[]) QFile wrappersDefFile(wrappersDefFilePath); wrappersDefFile.remove(); if(!wrappersDefFile.open(QIODevice::WriteOnly|QIODevice::Append|QIODevice::Text)) - qFatal(QString("Can't open: " + wrappersDefFilePath).toLatin1().data()); + { + qDebug() << "Can't open: " << wrappersDefFilePath; + return -errno; + } QString cppApiIncludesFilePath(outputPath + "/jsonapi-includes.inl"); QFile cppApiIncludesFile(cppApiIncludesFilePath); cppApiIncludesFile.remove(); if(!cppApiIncludesFile.open(QIODevice::WriteOnly|QIODevice::Append|QIODevice::Text)) - qFatal(QString("Can't open: " + cppApiIncludesFilePath).toLatin1().data()); + { + qDebug() << "Can't open: " << cppApiIncludesFilePath; + return -errno; + } QSet cppApiIncludesSet; auto fatalError = [&]( - std::initializer_list errors, int ernum = EINVAL ) + std::initializer_list errors, int ernum = -EINVAL ) { QString errorMsg; for(const QVariant& error: errors) From e6e5700ed633fd89563e240dff8a97ad83d52e26 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 3 Oct 2018 19:04:02 +0200 Subject: [PATCH 04/28] Fix warning caused by clang defining _GNUC_ --- libretroshare/src/file_sharing/p3filelists.cc | 12 ++++++++++-- libretroshare/src/util/cxx11retrocompat.h | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/libretroshare/src/file_sharing/p3filelists.cc b/libretroshare/src/file_sharing/p3filelists.cc index 156490e18..7ab77f929 100644 --- a/libretroshare/src/file_sharing/p3filelists.cc +++ b/libretroshare/src/file_sharing/p3filelists.cc @@ -777,10 +777,14 @@ template<> bool p3FileDatabase::convertPointerToEntryIndex<4>(const void *p, Ent { // trust me, I can do this ;-) -#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#if defined(__GNUC__) && !defined(__clang__) +# pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // defined(__GNUC__) && !defined(__clang__) e = EntryIndex( *reinterpret_cast(&p) & ENTRY_INDEX_BIT_MASK_32BITS ) ; friend_index = (*reinterpret_cast(&p)) >> NB_ENTRY_INDEX_BITS_32BITS ; -#pragma GCC diagnostic pop +#if defined(__GNUC__) && !defined(__clang__) +# pragma GCC diagnostic pop +#endif // defined(__GNUC__) && !defined(__clang__) if(friend_index == 0) { @@ -817,10 +821,14 @@ template<> bool p3FileDatabase::convertPointerToEntryIndex<8>(const void *p, Ent { // trust me, I can do this ;-) +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // defined(__GNUC__) && !defined(__clang__) e = EntryIndex( *reinterpret_cast(&p) & ENTRY_INDEX_BIT_MASK_64BITS ) ; friend_index = (*reinterpret_cast(&p)) >> NB_ENTRY_INDEX_BITS_64BITS ; +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic pop +#endif // defined(__GNUC__) && !defined(__clang__) if(friend_index == 0) { diff --git a/libretroshare/src/util/cxx11retrocompat.h b/libretroshare/src/util/cxx11retrocompat.h index 98dd998db..f210cf87b 100644 --- a/libretroshare/src/util/cxx11retrocompat.h +++ b/libretroshare/src/util/cxx11retrocompat.h @@ -21,7 +21,7 @@ *******************************************************************************/ #pragma once -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__clang__) # define GCC_VERSION (__GNUC__*10000+__GNUC_MINOR__*100+__GNUC_PATCHLEVEL__) # if GCC_VERSION < 40700 # define override @@ -30,4 +30,4 @@ # if GCC_VERSION < 40600 # define nullptr NULL # endif // GCC_VERSION < 40600 -#endif //defined GNUC +#endif // defined(__GNUC__) && !defined(__clang__) From 7cc15c703c4eae11ec629f06d89c6cffb651275f Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Wed, 3 Oct 2018 19:05:02 +0200 Subject: [PATCH 05/28] Fix forward declarations class struct missmatch --- libretroshare/src/pgp/rscertificate.h | 2 +- libretroshare/src/pqi/authgpg.h | 2 +- libretroshare/src/pqi/p3linkmgr.h | 2 +- libretroshare/src/pqi/pqi_base.h | 4 ++-- libretroshare/src/pqi/pqihandler.h | 2 +- libretroshare/src/pqi/pqiperson.h | 2 +- libretroshare/src/pqi/pqipersongrp.h | 2 +- libretroshare/src/retroshare/rsiface.h | 2 +- libretroshare/src/retroshare/rsnotify.h | 2 +- libretroshare/src/rsitems/rsconfigitems.h | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libretroshare/src/pgp/rscertificate.h b/libretroshare/src/pgp/rscertificate.h index b0fd70801..177440530 100644 --- a/libretroshare/src/pgp/rscertificate.h +++ b/libretroshare/src/pgp/rscertificate.h @@ -47,7 +47,7 @@ #include #include -class RsPeerDetails ; +struct RsPeerDetails; class RsCertificate { diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index 6d3337580..6bfab7935 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -38,7 +38,7 @@ #define MAX_GPG_SIGNATURE_SIZE 4096 -class RsPeerDetails; +struct RsPeerDetails; /*! * gpgcert is the identifier for a person. diff --git a/libretroshare/src/pqi/p3linkmgr.h b/libretroshare/src/pqi/p3linkmgr.h index 57638c174..afcd94b45 100644 --- a/libretroshare/src/pqi/p3linkmgr.h +++ b/libretroshare/src/pqi/p3linkmgr.h @@ -129,7 +129,7 @@ class peerConnectState class p3tunnel; class RsPeerGroupItem_deprecated; -class RsGroupInfo; +struct RsGroupInfo; class p3PeerMgr; class p3NetMgr; diff --git a/libretroshare/src/pqi/pqi_base.h b/libretroshare/src/pqi/pqi_base.h index 0741df1c5..b7c2746d2 100644 --- a/libretroshare/src/pqi/pqi_base.h +++ b/libretroshare/src/pqi/pqi_base.h @@ -31,7 +31,7 @@ #include "pqi/pqinetwork.h" -class RSTrafficClue ; +struct RSTrafficClue; /*** Base DataTypes: ****/ #include "serialiser/rsserial.h" @@ -46,7 +46,7 @@ class RSTrafficClue ; int getPQIsearchId(); int fixme(char *str, int n); -class RsPeerCryptoParams ; +struct RsPeerCryptoParams; //! controlling data rates /*! diff --git a/libretroshare/src/pqi/pqihandler.h b/libretroshare/src/pqi/pqihandler.h index 755b13cfd..40a2c3a27 100644 --- a/libretroshare/src/pqi/pqihandler.h +++ b/libretroshare/src/pqi/pqihandler.h @@ -32,7 +32,7 @@ #include "util/rsthreads.h" // for RsStackMutex, RsMutex class PQInterface; -class RSTrafficClue; +struct RSTrafficClue; class RsBwRates; struct RsItem; class RsRawItem; diff --git a/libretroshare/src/pqi/pqiperson.h b/libretroshare/src/pqi/pqiperson.h index 895af2925..e5b6f7f2c 100644 --- a/libretroshare/src/pqi/pqiperson.h +++ b/libretroshare/src/pqi/pqiperson.h @@ -30,7 +30,7 @@ #include class pqiperson; -class RsPeerCryptoParams ; +struct RsPeerCryptoParams; static const int CONNECT_RECEIVED = 1; static const int CONNECT_SUCCESS = 2; diff --git a/libretroshare/src/pqi/pqipersongrp.h b/libretroshare/src/pqi/pqipersongrp.h index 0afd00a78..5b57aebb1 100644 --- a/libretroshare/src/pqi/pqipersongrp.h +++ b/libretroshare/src/pqi/pqipersongrp.h @@ -40,7 +40,7 @@ const unsigned long PQIPERSON_NO_LISTENER = 0x0001; const unsigned long PQIPERSON_ALL_BW_LIMITED = 0x0010; -class RsPeerCryptoParams ; +struct RsPeerCryptoParams; class pqipersongrp: public pqihandler, public pqiMonitor, public p3ServiceServer, public pqiNetListener { diff --git a/libretroshare/src/retroshare/rsiface.h b/libretroshare/src/retroshare/rsiface.h index 83eda2eae..1f9041d3e 100644 --- a/libretroshare/src/retroshare/rsiface.h +++ b/libretroshare/src/retroshare/rsiface.h @@ -29,7 +29,7 @@ class RsServer; class RsInit; -class RsPeerCryptoParams; +struct RsPeerCryptoParams; class RsControl; /// RsInit -> Configuration Parameters for RetroShare Startup diff --git a/libretroshare/src/retroshare/rsnotify.h b/libretroshare/src/retroshare/rsnotify.h index cf7777e9e..d2077e7f0 100644 --- a/libretroshare/src/retroshare/rsnotify.h +++ b/libretroshare/src/retroshare/rsnotify.h @@ -33,7 +33,7 @@ class ChatId; class ChatMessage; -class RsGxsChanges; +struct RsGxsChanges; class RsNotify; extern RsNotify *rsNotify; diff --git a/libretroshare/src/rsitems/rsconfigitems.h b/libretroshare/src/rsitems/rsconfigitems.h index 376bebb78..4bb41150c 100644 --- a/libretroshare/src/rsitems/rsconfigitems.h +++ b/libretroshare/src/rsitems/rsconfigitems.h @@ -37,7 +37,7 @@ #include "serialiser/rsserializer.h" -class RsGroupInfo; +struct RsGroupInfo; const uint8_t RS_PKT_TYPE_GENERAL_CONFIG = 0x01; const uint8_t RS_PKT_TYPE_PEER_CONFIG = 0x02; From 7c986b926d6ea1bd6b18fbb8499860501bb0178b Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 4 Oct 2018 19:14:16 +0200 Subject: [PATCH 06/28] Remove overloaded GetRetroshareInvite method now the original method has default paramether that return invite for own node, this way JSON API is more friendly --- libretroshare/src/retroshare/rspeers.h | 15 ++++----------- libretroshare/src/rsserver/p3peers.cc | 10 +++------- libretroshare/src/rsserver/p3peers.h | 8 ++------ 3 files changed, 9 insertions(+), 24 deletions(-) diff --git a/libretroshare/src/retroshare/rspeers.h b/libretroshare/src/retroshare/rspeers.h index 04634166a..75fd91bbc 100644 --- a/libretroshare/src/retroshare/rspeers.h +++ b/libretroshare/src/retroshare/rspeers.h @@ -527,13 +527,15 @@ public: /** * @brief Get RetroShare invite of the given peer * @jsonapi{development} - * @param[in] sslId Id of the peer of which we want to generate an invite + * @param[in] sslId Id of the peer of which we want to generate an invite, + * a null id (all 0) is passed, an invite for own node is returned. * @param[in] includeSignatures true to add key signatures to the invite * @param[in] includeExtraLocators false to avoid to add extra locators * @return invite string */ virtual std::string GetRetroshareInvite( - const RsPeerId& sslId, bool includeSignatures = false, + const RsPeerId& sslId = RsPeerId(), + bool includeSignatures = false, bool includeExtraLocators = true ) = 0; /** @@ -547,15 +549,6 @@ public: const std::string& invite, ServicePermissionFlags flags = RS_NODE_PERM_DEFAULT ) = 0; - /** - * @brief Get RetroShare invite of our own peer - * @param[in] includeSignatures true to add key signatures to the invite - * @param[in] includeExtraLocators false to avoid to add extra locators - * @return invite string - */ - virtual std::string GetRetroshareInvite( - bool includeSignatures = false, - bool includeExtraLocators = true ) = 0; /* Auth Stuff */ virtual std::string getPGPKey(const RsPgpId& pgp_id,bool include_signatures) = 0; diff --git a/libretroshare/src/rsserver/p3peers.cc b/libretroshare/src/rsserver/p3peers.cc index 616884248..d950d1e26 100644 --- a/libretroshare/src/rsserver/p3peers.cc +++ b/libretroshare/src/rsserver/p3peers.cc @@ -1054,12 +1054,7 @@ bool p3Peers::setProxyServer(const uint32_t type, const std::string &addr_str, c //=========================================================================== /* Auth Stuff */ -std::string p3Peers::GetRetroshareInvite( - bool include_signatures, bool includeExtraLocators ) -{ - return GetRetroshareInvite( - getOwnId(), include_signatures, includeExtraLocators ); -} + std::string p3Peers::getPGPKey(const RsPgpId& pgp_id,bool include_signatures) { unsigned char *mem_block = NULL; @@ -1176,12 +1171,13 @@ bool p3Peers::acceptInvite( const std::string& invite, } std::string p3Peers::GetRetroshareInvite( - const RsPeerId& ssl_id, bool include_signatures, + const RsPeerId& sslId, bool include_signatures, bool includeExtraLocators ) { #ifdef P3PEERS_DEBUG std::cerr << __PRETTY_FUNCTION__ << std::endl; #endif + const RsPeerId& ssl_id(sslId.isNull() ? getOwnId() : sslId); //add the sslid, location, ip local and external address after the signature RsPeerDetails detail; diff --git a/libretroshare/src/rsserver/p3peers.h b/libretroshare/src/rsserver/p3peers.h index 3b96ab380..f5f61a43e 100644 --- a/libretroshare/src/rsserver/p3peers.h +++ b/libretroshare/src/rsserver/p3peers.h @@ -117,14 +117,10 @@ public: /* Auth Stuff */ // Get the invitation (GPG cert + local/ext address + SSL id for the given peer) virtual std::string GetRetroshareInvite( - const RsPeerId& ssl_id, bool include_signatures = false, - bool includeExtraLocators = true ); + const RsPeerId& ssl_id = RsPeerId(), + bool include_signatures = false, bool includeExtraLocators = true ); virtual std::string getPGPKey(const RsPgpId& pgp_id,bool include_signatures); - // same but for own id - virtual std::string GetRetroshareInvite( - bool include_signatures = false, - bool includeExtraLocators = true ); virtual bool GetPGPBase64StringAndCheckSum(const RsPgpId& gpg_id,std::string& gpg_base64_string,std::string& gpg_base64_checksum); /// @see RsPeers::acceptInvite From 184fac95ae719b17a2cd398264f9d65339caaacd Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 4 Oct 2018 22:12:23 +0200 Subject: [PATCH 07/28] Fix deep_search enable/disable at build time --- retroshare.pri | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/retroshare.pri b/retroshare.pri index 213d10832..ac36972d0 100644 --- a/retroshare.pri +++ b/retroshare.pri @@ -150,9 +150,8 @@ CONFIG *= no_rs_jsonapi rs_jsonapi:CONFIG -= no_rs_jsonapi # To disable deep search append the following assignation to qmake command line -CONFIG+=no_rs_deep_search -CONFIG *= rs_deep_search -no_rs_deep_search:CONFIG -= rs_deep_search +CONFIG *= no_rs_deep_search +rs_deep_search:CONFIG -= no_rs_deep_search # Specify host precompiled jsonapi-generator path, appending the following # assignation to qmake command line From 321d2e84bd0e334a056ba76a059f75e41537111a Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 4 Oct 2018 23:36:01 +0200 Subject: [PATCH 08/28] gxschannel expose blocking create post and channels API --- libretroshare/src/retroshare/rsgxschannels.h | 19 ++++++++-- libretroshare/src/services/p3gxschannels.cc | 38 ++++++++++++++++++-- libretroshare/src/services/p3gxschannels.h | 6 ++++ 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxschannels.h b/libretroshare/src/retroshare/rsgxschannels.h index 31bad28b4..50e8e47d2 100644 --- a/libretroshare/src/retroshare/rsgxschannels.h +++ b/libretroshare/src/retroshare/rsgxschannels.h @@ -137,6 +137,23 @@ public: std::vector& posts, std::vector& comments ) = 0; + /** + * @brief Create channel. Blocking API. + * @jsonapi{development} + * @param[inout] channel Channel data (name, description...) + * @return false on error, true otherwise + */ + virtual bool createChannel(RsGxsChannelGroup& channel) = 0; + + /** + * @brief Create channel post. Blocking API. + * @jsonapi{development} + * @param[inout] post + * @return false on error, true otherwise + */ + virtual bool createPost(RsGxsChannelPost& post) = 0; + + /* Specific Service Data * TODO: change the orrible const uint32_t &token to uint32_t token * TODO: create a new typedef for token so code is easier to read @@ -225,7 +242,6 @@ public: * @brief Request channel creation. * The action is performed asyncronously, so it could fail in a subsequent * phase even after returning true. - * @jsonapi{development} * @param[out] token Storage for RsTokenService token to track request * status. * @param[in] group Channel data (name, description...) @@ -237,7 +253,6 @@ public: * @brief Request post creation. * The action is performed asyncronously, so it could fail in a subsequent * phase even after returning true. - * @jsonapi{development} * @param[out] token Storage for RsTokenService token to track request * status. * @param[in] post diff --git a/libretroshare/src/services/p3gxschannels.cc b/libretroshare/src/services/p3gxschannels.cc index 386fe4ee0..35caff413 100644 --- a/libretroshare/src/services/p3gxschannels.cc +++ b/libretroshare/src/services/p3gxschannels.cc @@ -34,17 +34,22 @@ #include "rsserver/p3face.h" #include "retroshare/rsnotify.h" -#include +#include // For Dummy Msgs. #include "util/rsrandom.h" #include "util/rsstring.h" +#ifdef RS_DEEP_SEARCH +# include "deep_search/deep_search.h" +#endif // RS_DEEP_SEARCH + + /**** * #define GXSCHANNEL_DEBUG 1 ****/ -RsGxsChannels *rsGxsChannels = NULL; +/*extern*/ RsGxsChannels *rsGxsChannels = nullptr; #define GXSCHANNEL_STOREPERIOD (3600 * 24 * 30) @@ -1036,6 +1041,35 @@ bool p3GxsChannels::getChannelsContent( return getPostData(token, posts, comments); } +bool p3GxsChannels::createChannel(RsGxsChannelGroup& channel) +{ + uint32_t token; + if( !createGroup(token, channel) + || waitToken(token) != RsTokenService::COMPLETE ) return false; + +// TODO: Need a way to get the channel id back! +//#ifdef RS_DEEP_SEARCH +// DeepSearch::indexChannelGroup(channel); +//#endif // RS_DEEP_SEARCH + + return true; +} + +bool p3GxsChannels::createPost(RsGxsChannelPost& post) +{ + uint32_t token; + if( !createPost(token, post) + || waitToken(token) != RsTokenService::COMPLETE ) return false; + +// TODO: Need a way to get the post id back! +//#ifdef RS_DEEP_SEARCH +// DeepSearch::indexChannelPost(post); +//#endif // RS_DEEP_SEARCH + + return true; +} + + //////////////////////////////////////////////////////////////////////////////// /// Blocking API implementation end //////////////////////////////////////////////////////////////////////////////// diff --git a/libretroshare/src/services/p3gxschannels.h b/libretroshare/src/services/p3gxschannels.h index 4f24f88b9..b3c027342 100644 --- a/libretroshare/src/services/p3gxschannels.h +++ b/libretroshare/src/services/p3gxschannels.h @@ -182,6 +182,12 @@ virtual bool ExtraFileRemove(const RsFileHash &hash); std::vector& posts, std::vector& comments ); + /// Implementation of @see RsGxsChannels::createChannel + virtual bool createChannel(RsGxsChannelGroup& channel); + + /// Implementation of @see RsGxsChannels::createPost + virtual bool createPost(RsGxsChannelPost& post); + protected: // Overloaded from GxsTokenQueue for Request callbacks. virtual void handleResponse(uint32_t token, uint32_t req_type); From 0f01f110ad9aefe3490972fa05d6735b7b2d4cdb Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Thu, 4 Oct 2018 23:37:39 +0200 Subject: [PATCH 09/28] jsonapi-generator fix param initialization on Android without this patch Android compilation would fail in cases like RsPeerId sslid(RsPeerId()); --- jsonapi-generator/src/jsonapi-generator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsonapi-generator/src/jsonapi-generator.cpp b/jsonapi-generator/src/jsonapi-generator.cpp index 154406594..aa20eda01 100644 --- a/jsonapi-generator/src/jsonapi-generator.cpp +++ b/jsonapi-generator/src/jsonapi-generator.cpp @@ -302,7 +302,7 @@ int main(int argc, char *argv[]) const MethodParam& mp(paramsMap[pn]); paramsDeclaration += "\t\t" + mp.type + " " + mp.name; if(!mp.defval.isEmpty()) - paramsDeclaration += "(" + mp.defval + ")"; + paramsDeclaration += " = " + mp.defval; paramsDeclaration += ";\n"; if(mp.in) inputParamsDeserialization += "\t\t\tRS_SERIAL_PROCESS(" From 341a68ce0787a384f59a1432dfca513243113bcf Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Fri, 5 Oct 2018 01:23:17 +0200 Subject: [PATCH 10/28] rstypeserializer fix uninitialized variable usage --- libretroshare/src/serialiser/rstypeserializer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretroshare/src/serialiser/rstypeserializer.h b/libretroshare/src/serialiser/rstypeserializer.h index fc13d42e4..4ff512c49 100644 --- a/libretroshare/src/serialiser/rstypeserializer.h +++ b/libretroshare/src/serialiser/rstypeserializer.h @@ -655,7 +655,7 @@ struct RsTypeSerializer break; case RsGenericSerializer::FROM_JSON: { - uint32_t f; + uint32_t f = 0; ctx.mOk &= (ctx.mOk || ctx.mFlags & RsGenericSerializer::SERIALIZATION_FLAG_YIELDING) && from_JSON(memberName, f, ctx.mJson); From 1d8bb448115c0b7d68b3d717145b43325e7375e2 Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Fri, 5 Oct 2018 01:55:18 +0200 Subject: [PATCH 11/28] Fix warnings --- libretroshare/src/jsonapi/jsonapi.cpp | 4 ++-- libretroshare/src/pqi/p3peermgr.h | 2 +- libretroshare/src/pqi/pqissl.h | 2 +- libretroshare/src/pqi/pqisslpersongrp.h | 2 +- libretroshare/src/retroshare/rsplugin.h | 2 +- libretroshare/src/rsserver/rsaccounts.cc | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libretroshare/src/jsonapi/jsonapi.cpp b/libretroshare/src/jsonapi/jsonapi.cpp index ad4fd801b..08290a06f 100644 --- a/libretroshare/src/jsonapi/jsonapi.cpp +++ b/libretroshare/src/jsonapi/jsonapi.cpp @@ -140,10 +140,10 @@ JsonApiServer::JsonApiServer(uint16_t port, const std::string& bindAddress, }, false); registerHandler("/rsControl/rsGlobalShutDown", - [this](const std::shared_ptr session) + [](const std::shared_ptr session) { size_t reqSize = session->get_request()->get_header("Content-Length", 0); - session->fetch( reqSize, [this]( + session->fetch( reqSize, []( const std::shared_ptr session, const rb::Bytes& body ) { diff --git a/libretroshare/src/pqi/p3peermgr.h b/libretroshare/src/pqi/p3peermgr.h index 70d74f141..510fdabce 100644 --- a/libretroshare/src/pqi/p3peermgr.h +++ b/libretroshare/src/pqi/p3peermgr.h @@ -103,7 +103,7 @@ class peerState }; class RsNodeGroupItem; -class RsGroupInfo; +struct RsGroupInfo; std::string textPeerState(peerState &state); diff --git a/libretroshare/src/pqi/pqissl.h b/libretroshare/src/pqi/pqissl.h index 712e06a11..13d0eccce 100644 --- a/libretroshare/src/pqi/pqissl.h +++ b/libretroshare/src/pqi/pqissl.h @@ -76,7 +76,7 @@ class cert; class pqissllistener; class p3LinkMgr; -class RsPeerCryptoParams ; +struct RsPeerCryptoParams; class pqissl: public NetBinInterface { diff --git a/libretroshare/src/pqi/pqisslpersongrp.h b/libretroshare/src/pqi/pqisslpersongrp.h index aa574e617..ea94e616a 100644 --- a/libretroshare/src/pqi/pqisslpersongrp.h +++ b/libretroshare/src/pqi/pqisslpersongrp.h @@ -25,7 +25,7 @@ #include "pqi/pqipersongrp.h" class p3PeerMgr; -class RsPeerCryptoParams; +struct RsPeerCryptoParams; class pqissl ; class pqisslpersongrp: public pqipersongrp diff --git a/libretroshare/src/retroshare/rsplugin.h b/libretroshare/src/retroshare/rsplugin.h index af553b785..c6b238496 100644 --- a/libretroshare/src/retroshare/rsplugin.h +++ b/libretroshare/src/retroshare/rsplugin.h @@ -65,7 +65,7 @@ class ToasterNotify; class ChatWidget; class ChatWidgetHolder; // for gxs based plugins -class RsIdentity; +struct RsIdentity; class RsNxsNetMgr; class RsGxsIdExchange; class RsGcxs; diff --git a/libretroshare/src/rsserver/rsaccounts.cc b/libretroshare/src/rsserver/rsaccounts.cc index 557981dcc..17ab2d8cc 100644 --- a/libretroshare/src/rsserver/rsaccounts.cc +++ b/libretroshare/src/rsserver/rsaccounts.cc @@ -811,7 +811,7 @@ static bool checkAccount(const std::string &accountdir, AccountDetails &account, /* Use RetroShare's exe dir */ dataDirectory = "."; #elif defined(ANDROID) - dataDirectory = defaultBaseDirectory()+"/usr/share/retroshare"; + dataDirectory = PathBaseDirectory()+"/usr/share/retroshare"; #elif defined(DATA_DIR) // cppcheck-suppress ConfigurationNotChecked dataDirectory = DATA_DIR; From b28512b88936c2acec38e451fb05fc0741c5f77d Mon Sep 17 00:00:00 2001 From: Gioacchino Mazzurco Date: Fri, 5 Oct 2018 22:29:49 +0200 Subject: [PATCH 12/28] retroshare-service now build and runs fine on android (even older ones) --- README-Android.asciidoc | 1 + .../Android/prepare-toolchain-clang.sh | 22 ++++-- libretroshare/src/libretroshare.pro | 38 +++++------ libretroshare/src/use_libretroshare.pri | 25 +++++-- .../data/retroshare-service_128x128.png | Bin 0 -> 8200 bytes .../data/retroshare-service_48x48.png | Bin 0 -> 2946 bytes .../src/android/AndroidManifest.xml | 49 +++++++++++--- .../res/drawable/retroshare_128x128.png | 1 - .../android/res/drawable/retroshare_48x48.png | 1 - .../drawable/retroshare_service_128x128.png | 1 + .../res/drawable/retroshare_service_48x48.png | 1 + .../retroshare_service_control_layout.xml | 11 +++ .../service/AppUpdatedReceiver.java | 35 ++++++++++ .../service/BootCompletedReceiver.java | 34 ++++++++++ .../service/RetroShareServiceAndroid.java | 47 +++++++++++++ .../RetroShareServiceControlActivity.java | 64 ++++++++++++++++++ retroshare-service/src/retroshare-service.cc | 9 ++- retroshare-service/src/retroshare-service.pro | 3 + 18 files changed, 296 insertions(+), 46 deletions(-) create mode 100644 retroshare-service/data/retroshare-service_128x128.png create mode 100644 retroshare-service/data/retroshare-service_48x48.png delete mode 120000 retroshare-service/src/android/res/drawable/retroshare_128x128.png delete mode 120000 retroshare-service/src/android/res/drawable/retroshare_48x48.png create mode 120000 retroshare-service/src/android/res/drawable/retroshare_service_128x128.png create mode 120000 retroshare-service/src/android/res/drawable/retroshare_service_48x48.png create mode 100644 retroshare-service/src/android/res/layout/retroshare_service_control_layout.xml create mode 100644 retroshare-service/src/android/src/org/retroshare/service/AppUpdatedReceiver.java create mode 100644 retroshare-service/src/android/src/org/retroshare/service/BootCompletedReceiver.java create mode 100644 retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceAndroid.java create mode 100644 retroshare-service/src/android/src/org/retroshare/service/RetroShareServiceControlActivity.java diff --git a/README-Android.asciidoc b/README-Android.asciidoc index 40efe9c12..f64336c1c 100644 --- a/README-Android.asciidoc +++ b/README-Android.asciidoc @@ -252,3 +252,4 @@ your work-station running - link:https://source.android.com/devices/tech/debug/gdb[] - link:https://fw4spl-org.github.io/fw4spl-blog/2015/07/27/Native-debugging-on-Android-with-QtCreator.html[] - link:https://fragglet.livejournal.com/19646.html[] +- link:https://github.com/android-ndk/ndk/issues/773[How to build without using standalone toolchain?] diff --git a/build_scripts/Android/prepare-toolchain-clang.sh b/build_scripts/Android/prepare-toolchain-clang.sh index 158d3b28a..d767b617e 100755 --- a/build_scripts/Android/prepare-toolchain-clang.sh +++ b/build_scripts/Android/prepare-toolchain-clang.sh @@ -14,7 +14,7 @@ function define_default_value() ## You are supposed to provide the following variables according to your system setup define_default_value ANDROID_NDK_PATH "/opt/android-ndk/" define_default_value ANDROID_NDK_ARCH "arm" -define_default_value ANDROID_PLATFORM_VER "21" +define_default_value ANDROID_PLATFORM_VER "16" define_default_value NATIVE_LIBS_TOOLCHAIN_PATH "${HOME}/Builds/android-toolchains/retroshare-android-${ANDROID_PLATFORM_VER}-${ANDROID_NDK_ARCH}/" define_default_value HOST_NUM_CPU $(nproc) @@ -35,7 +35,7 @@ define_default_value LIBUPNP_SOURCE_VERSION "1.6.25" define_default_value LIBUPNP_SOURCE_SHA256 c5a300b86775435c076d58a79cc0d5a977d76027d2a7d721590729b7f369fa43 define_default_value INSTALL_QT_ANDROID "false" -define_default_value QT_VERSION "5.9.6" +define_default_value QT_VERSION "5.12.0" define_default_value QT_ANDROID_INSTALLER_SHA256 a214084e2295c9a9f8727e8a0131c37255bf724bfc69e80f7012ba3abeb1f763 define_default_value RESTBED_SOURCE_VERSION "4.6" @@ -95,6 +95,15 @@ build_toolchain() ${ANDROID_NDK_PATH}/build/tools/make_standalone_toolchain.py --verbose \ --arch ${ANDROID_NDK_ARCH} --install-dir ${NATIVE_LIBS_TOOLCHAIN_PATH} \ --api ${ANDROID_PLATFORM_VER} + find "${PREFIX}/include/" -not -type d > "${NATIVE_LIBS_TOOLCHAIN_PATH}/deletefiles" +} + +## This avoid include errors due to -isystem and -I ordering issue +delete_copied_includes() +{ + cat "${NATIVE_LIBS_TOOLCHAIN_PATH}/deletefiles" | while read delFile ; do + rm "$delFile" + done } ## More information available at https://gitlab.com/relan/provisioners/merge_requests/1 and http://stackoverflow.com/a/34032216 @@ -230,7 +239,8 @@ build_openssl() # sed -i '/LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \\/d' Makefile make -j${HOST_NUM_CPU} make install -# cp *.so "${SYSROOT}/usr/lib" + rm -f ${PREFIX}/lib/libssl.so* + rm -f ${PREFIX}/lib/libcrypto.so* cd .. } @@ -315,9 +325,10 @@ build_restbed() cd .. rm -rf restbed-build; mkdir restbed-build ; cd restbed-build - cmake -DBUILD_SSL=OFF -DCMAKE_INSTALL_PREFIX=${PREFIX} -B. -H../restbed + cmake -DBUILD_SSL=OFF -DCMAKE_INSTALL_PREFIX="${PREFIX}" -B. -H../restbed make -j${HOST_NUM_CPU} make install + cp "${PREFIX}/library/librestbed.a" "${PREFIX}/lib/" cd .. } @@ -329,6 +340,7 @@ build_sqlite build_sqlcipher build_libupnp build_rapidjson -#build_restbed # qmake build it already +build_restbed +delete_copied_includes echo NATIVE_LIBS_TOOLCHAIN_PATH=${NATIVE_LIBS_TOOLCHAIN_PATH} diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 0bbc52969..cdc1f2326 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -881,21 +881,23 @@ rs_jsonapi { WRAPPERS_INCL_FILE=$$clean_path($${JSONAPI_GENERATOR_OUT}/jsonapi-includes.inl) WRAPPERS_REG_FILE=$$clean_path($${JSONAPI_GENERATOR_OUT}/jsonapi-wrappers.inl) - restbed.target = $$clean_path($${RESTBED_BUILD_PATH}/library/librestbed.a) - restbed.commands = \ - cd $${RS_SRC_PATH};\ - git submodule update --init --recommend-shallow supportlibs/restbed;\ - cd $${RESTBED_SRC_PATH};\ - git submodule update --init --recommend-shallow dependency/asio;\ - git submodule update --init --recommend-shallow dependency/catch;\ - git submodule update --init --recommend-shallow dependency/kashmir;\ - mkdir -p $${RESTBED_BUILD_PATH}; cd $${RESTBED_BUILD_PATH};\ - cmake -DCMAKE_CXX_COMPILER=$$QMAKE_CXX -DBUILD_SSL=OFF \ - -DCMAKE_INSTALL_PREFIX=. -B. -H$$shell_path($${RESTBED_SRC_PATH});\ - make; make install - QMAKE_EXTRA_TARGETS += restbed - libretroshare.depends += restbed - PRE_TARGETDEPS *= $${restbed.target} + no_rs_cross_compiling { + restbed.target = $$clean_path($${RESTBED_BUILD_PATH}/library/librestbed.a) + restbed.commands = \ + cd $${RS_SRC_PATH};\ + git submodule update --init --recommend-shallow supportlibs/restbed;\ + cd $${RESTBED_SRC_PATH};\ + git submodule update --init --recommend-shallow dependency/asio;\ + git submodule update --init --recommend-shallow dependency/catch;\ + git submodule update --init --recommend-shallow dependency/kashmir;\ + mkdir -p $${RESTBED_BUILD_PATH}; cd $${RESTBED_BUILD_PATH};\ + cmake -DCMAKE_CXX_COMPILER=$$QMAKE_CXX -DBUILD_SSL=OFF \ + -DCMAKE_INSTALL_PREFIX=. -B. -H$$shell_path($${RESTBED_SRC_PATH});\ + make; make install + QMAKE_EXTRA_TARGETS += restbed + libretroshare.depends += restbed + PRE_TARGETDEPS *= $${restbed.target} + } PRE_TARGETDEPS *= $${JSONAPI_GENERATOR_EXE} INCLUDEPATH *= $${JSONAPI_GENERATOR_OUT} @@ -968,12 +970,6 @@ test_bitdht { ################################# Android ##################################### android-* { -## ifaddrs is missing on Android to add them don't use the one from -## https://github.com/morristech/android-ifaddrs -## because it crash, use QNetworkInterface from Qt instead - CONFIG *= qt - QT *= network - DEFINES *= "fopen64=fopen" DEFINES *= "fseeko64=fseeko" DEFINES *= "ftello64=ftello" diff --git a/libretroshare/src/use_libretroshare.pri b/libretroshare/src/use_libretroshare.pri index 64d6dbce0..855bc0d48 100644 --- a/libretroshare/src/use_libretroshare.pri +++ b/libretroshare/src/use_libretroshare.pri @@ -50,14 +50,17 @@ dLibs = rs_jsonapi { RS_SRC_PATH=$$clean_path($${PWD}/../../) RS_BUILD_PATH=$$clean_path($${OUT_PWD}/../../) - RESTBED_SRC_PATH=$$clean_path($${RS_SRC_PATH}/supportlibs/restbed) - RESTBED_BUILD_PATH=$$clean_path($${RS_BUILD_PATH}/supportlibs/restbed) - INCLUDEPATH *= $$clean_path($${RESTBED_BUILD_PATH}/include/) - QMAKE_LIBDIR *= $$clean_path($${RESTBED_BUILD_PATH}/library/) - # Using sLibs would fail as librestbed.a is generated at compile-time - LIBS *= -L$$clean_path($${RESTBED_BUILD_PATH}/library/) -lrestbed - win32-g++:LIBS += -lwsock32 + no_cross_compiling { + RESTBED_SRC_PATH=$$clean_path($${RS_SRC_PATH}/supportlibs/restbed) + RESTBED_BUILD_PATH=$$clean_path($${RS_BUILD_PATH}/supportlibs/restbed) + INCLUDEPATH *= $$clean_path($${RESTBED_BUILD_PATH}/include/) + QMAKE_LIBDIR *= $$clean_path($${RESTBED_BUILD_PATH}/library/) + # Using sLibs would fail as librestbed.a is generated at compile-time + LIBS *= -L$$clean_path($${RESTBED_BUILD_PATH}/library/) -lrestbed + } else:sLibs *= restbed + + win32-g++:dLibs *= wsock32 } linux-* { @@ -79,3 +82,11 @@ LIBS += $$linkStaticLibs(sLibs) PRE_TARGETDEPS += $$pretargetStaticLibs(sLibs) LIBS += $$linkDynamicLibs(dLibs) + +android-* { +## ifaddrs is missing on Android to add them don't use the one from +## https://github.com/morristech/android-ifaddrs +## because it crash, use QNetworkInterface from Qt instead + CONFIG *= qt + QT *= network +} diff --git a/retroshare-service/data/retroshare-service_128x128.png b/retroshare-service/data/retroshare-service_128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..84ef9e84bf4de95b1f846a66702f2aef93beab2f GIT binary patch literal 8200 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 literal 0 HcmV?d00001 diff --git a/retroshare-service/src/android/AndroidManifest.xml b/retroshare-service/src/android/AndroidManifest.xml index ca062305c..7a3930f89 100644 --- a/retroshare-service/src/android/AndroidManifest.xml +++ b/retroshare-service/src/android/AndroidManifest.xml @@ -1,13 +1,34 @@ - - - - + + + + + + + + + + + + + + + + + + + - + + + + + + - - + + + + + + + - + @@ -33,7 +64,7 @@ - +