diff --git a/AndroidManifest.xml b/AndroidManifest.xml index b95b5ba16ff8b8f25cb2bf0236a6d46f896761b5..64a2c42f89bf778ee09a70b0afeab2424ddf6cb4 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -6,6 +6,7 @@ android:installLocation="preferExternal" > <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 3 = 1.5, 2 = 1.1, 1 = 1.0; would probably work with 1 but don't have a 1.0 SDK to test against --> <!-- 3 required for NDK --> diff --git a/build.properties b/build.properties index 181724115d6453de5705a4d1fd7f7f682a345281..f620cd2fdb02b348e4a209af7cc4454296b89429 100644 --- a/build.properties +++ b/build.properties @@ -1 +1,3 @@ application-package=net.i2p.router +key.store=${user.home}/.android/${application-package}.keystore +key.alias=${application-package} diff --git a/build.xml b/build.xml index 63f3d86843baf4e982ea6e1e5ee412c0dfc95d59..37710b9ca35fd2476aeec32da824a83bc3c6bf3e 100644 --- a/build.xml +++ b/build.xml @@ -165,6 +165,66 @@ <delete file="scripts/version.properties" verbose="${verbose}" /> </target> + <!-- just to make it easier --> + <target name="create-signing-keys" > + <echo message="key store is ${key.store}" /> + <echo message="key store password is android" /> + <echo message="key alias is ${key.alias}" /> + <input message="Enter common name for new key (your name): " addproperty="release.cn" /> + <fail message="You must enter a name" > + <condition> + <equals arg1="${release.cn}" arg2="" /> + </condition> + </fail> + <input message="Enter password for new key (6 characters minimum): " addproperty="release.password" /> + <fail message="You must enter a password" > + <condition> + <equals arg1="${release.password}" arg2="" /> + </condition> + </fail> + <echo message="Generating keys..." /> + <exec executable="keytool" inputstring="${release.password}${line.separator}${release.password}${line.separator}" osfamily="unix" failonerror="true"> + <arg value="-genkey" /> + <arg value="-v" /> + <arg value="-alias" /> + <arg value="${key.alias}" /> + <arg value="-keystore" /> + <arg value="${key.store}" /> + <arg value="-validity" /> + <arg value="10000" /> + <arg value="-keyalg" /> + <arg value="RSA" /> + <arg value="-keysize" /> + <arg value="4096" /> + <arg value="-storepass" /> + <arg value="android" /> + <arg value="-dname" /> + <arg value="cn=${release.cn}, ou=Apps, o=I2P, c=DE" /> + </exec> + <echo message="Created keys:" /> + <exec executable="keytool" inputstring="android${line.separator}" osfamily="unix" failonerror="true"> + <arg value="-list" /> + <arg value="-v" /> + <arg value="-alias" /> + <arg value="${key.alias}" /> + <arg value="-keystore" /> + <arg value="${key.store}" /> + </exec> + </target> + + <target name="hint" > + <echo message="key store password is android" /> + </target> + + <target name="verify" depends="hint, release" > + <exec executable="jarsigner" osfamily="unix" failonerror="true"> + <arg value="-verify" /> + <arg value="-verbose" /> + <arg value="-certs" /> + <arg value="${out.release.file}" /> + </exec> + </target> + <!-- ================================================================================ From here down copied from SDK tools/ant/main_rules.xml from Tools version 11 diff --git a/jni/build.sh b/jni/build.sh index 28637a80c00dc484897641a87d96f7463bf9f554..15dfa5e6c753d69b17dd40b86bbe380e347f2cc9 100755 --- a/jni/build.sh +++ b/jni/build.sh @@ -20,11 +20,23 @@ export AABI=arm-linux-androideabi-4.4.3 export SYSTEM=linux-x86 export BINPREFIX=arm-linux-androideabi- export CC="$NDK/toolchains/$AABI/prebuilt/$SYSTEM/bin/${BINPREFIX}gcc --sysroot=$SYSROOT" +# worked without this on 4.3.2, but 5.0.2 couldn't find it +export NM="$NDK/toolchains/$AABI/prebuilt/$SYSTEM/bin/${BINPREFIX}nm" #echo "CC is $CC" JBIGI=$(realpath $I2PBASE/core/c/jbigi) -GMPVER=4.3.2 +# +# GMP Version +# +# prelim stats on a droid +# java (libcrypto) 29 ms +# 4.3.2 (jbigi) 34 ms +# 5.0.2 (jbigi) 32 ms +# libcrypto crashes on emulator, don't trust it +# jbigi about 20-25% slower than java on emulator +# +GMPVER=5.0.2 GMP=$JBIGI/gmp-$GMPVER if [ ! -d $GMP ] diff --git a/src/net/i2p/android/router/activity/I2PActivityBase.java b/src/net/i2p/android/router/activity/I2PActivityBase.java index 180f289abe10b8b08edf4c51f1026bc35f3e1b56..05d89a22b585e6e0c1c6cc100a866d3a953c42a8 100644 --- a/src/net/i2p/android/router/activity/I2PActivityBase.java +++ b/src/net/i2p/android/router/activity/I2PActivityBase.java @@ -49,6 +49,13 @@ public abstract class I2PActivityBase extends Activity { super.onPause(); } + @Override + public void onSaveInstanceState(Bundle outState) + { + System.err.println(this + " onSaveInstanceState called"); + super.onSaveInstanceState(outState); + } + @Override public void onStop() { diff --git a/src/net/i2p/android/router/receiver/I2PReceiver.java b/src/net/i2p/android/router/receiver/I2PReceiver.java new file mode 100644 index 0000000000000000000000000000000000000000..47e5c96059b6dd17087604e9058d971b89afdd98 --- /dev/null +++ b/src/net/i2p/android/router/receiver/I2PReceiver.java @@ -0,0 +1,31 @@ +package net.i2p.android.router.receiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.ConnectivityManager; + +import net.i2p.android.router.R; + +public class I2PReceiver extends BroadcastReceiver { + private final Context _context; + + public I2PReceiver(Context context) { + super(); + _context = context; + IntentFilter intents = new IntentFilter(); + intents.addAction(Intent.ACTION_TIME_CHANGED); + intents.addAction(Intent.ACTION_TIME_TICK); // once per minute, for testing + intents.addAction(Intent.ACTION_SCREEN_OFF); + intents.addAction(Intent.ACTION_SCREEN_ON); + intents.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + context.registerReceiver(this, intents); + } + + public void onReceive(Context context, Intent intent) { + System.out.println("Got broadcast: " + intent); + + ConnectivityManager cm = (ConnectivityManager) _context.getSystemService(Context.CONNECTIVITY_SERVICE); + } +} diff --git a/src/net/i2p/android/router/service/Init.java b/src/net/i2p/android/router/service/Init.java index 8928385e3d0f8eb4d53ee027b8e6e4817c886b04..9ca0a5e0491da24ed0b1b98e80ffe1cf2c33c3cf 100644 --- a/src/net/i2p/android/router/service/Init.java +++ b/src/net/i2p/android/router/service/Init.java @@ -43,6 +43,7 @@ class Init { System.err.println("user.home" + ": " + System.getProperty("user.home")); System.err.println("user.name" + ": " + System.getProperty("user.name")); System.err.println("getFilesDir()" + ": " + myDir); + System.err.println("max mem" + ": " + DataHelper.formatSize(Runtime.getRuntime().maxMemory())); System.err.println("Package" + ": " + ctx.getPackageName()); System.err.println("Version" + ": " + getOurVersion()); System.err.println("MODEL" + ": " + Build.MODEL); diff --git a/src/net/i2p/android/router/service/RouterService.java b/src/net/i2p/android/router/service/RouterService.java index 50d7cf644a268deb4b9283602199cdad11c4fc10..34804c5833dd57062dd6361ada164b8189525145 100644 --- a/src/net/i2p/android/router/service/RouterService.java +++ b/src/net/i2p/android/router/service/RouterService.java @@ -6,9 +6,11 @@ import android.content.Intent; import android.os.Bundle; import android.os.IBinder; +import java.text.DecimalFormat; import java.util.List; import net.i2p.android.router.R; +import net.i2p.data.DataHelper; import net.i2p.router.Router; import net.i2p.router.RouterContext; import net.i2p.router.RouterLaunch; @@ -22,6 +24,7 @@ public class RouterService extends Service { private String _myDir; private int _state; private Thread _starterThread; + private Thread _statusThread; private StatusBar _statusBar; private final Object _stateLock = new Object(); @@ -62,8 +65,11 @@ public class RouterService extends Service { private class Starter implements Runnable { public void run() { - System.err.println(MARKER + this + " starter thread"); + System.err.println(MARKER + this + " starter thread" + + "Current state is: " + _state); + System.err.println(MARKER + this + " JBigI speed test started"); NativeBigInteger.main(null); + System.err.println(MARKER + this + " JBigI speed test finished, launching router"); RouterLaunch.main(null); synchronized (_stateLock) { if (_state != STATE_STARTING) @@ -75,6 +81,8 @@ public class RouterService extends Service { _statusBar.update("I2P is running"); _context = (RouterContext)contexts.get(0); _context.router().setKillVMOnEnd(false); + _statusThread = new Thread(new StatusThread()); + _statusThread.start(); _context.addShutdownTask(new ShutdownHook()); _starterThread = null; } @@ -82,6 +90,59 @@ public class RouterService extends Service { } } + private class StatusThread implements Runnable { + public void run() { + System.err.println(MARKER + this + " status thread started" + + "Current state is: " + _state); + Router router = _context.router(); + while (_state == STATE_RUNNING && router.isAlive()) { + try { + Thread.sleep(5000); + } catch (InterruptedException ie) { + break; + } + int active = _context.commSystem().countActivePeers(); + int known = Math.max(_context.netDb().getKnownRouters() - 1, 0); + int inEx = _context.tunnelManager().getFreeTunnelCount(); + int outEx = _context.tunnelManager().getOutboundTunnelCount(); + int inCl = _context.tunnelManager().getInboundClientTunnelCount(); + int outCl = _context.tunnelManager().getOutboundClientTunnelCount(); + //int part = _context.tunnelManager().getParticipatingCount(); + double dLag = _context.statManager().getRate("jobQueue.jobLag").getRate(60000).getAverageValue(); + String jobLag = DataHelper.formatDuration((long) dLag); + String msgDelay = DataHelper.formatDuration(_context.throttle().getMessageDelay()); + String uptime = DataHelper.formatDuration(router.getUptime()); + //String tunnelStatus = _context.throttle().getTunnelStatus(); + double inBW = _context.bandwidthLimiter().getReceiveBps() / 1024; + double outBW = _context.bandwidthLimiter().getSendBps() / 1024; + // control total width + DecimalFormat fmt; + if (inBW >= 1000 || outBW >= 1000) + fmt = new DecimalFormat("#0"); + else if (inBW >= 100 || outBW >= 100) + fmt = new DecimalFormat("#0.0"); + else + fmt = new DecimalFormat("#0.00"); + + String status = + " Pr " + active + '/' + known + + " Ex " + inEx + '/' + outEx + + " Cl " + inCl + '/' + outCl + + //" Pt " + part + + " BW " + fmt.format(inBW) + '/' + fmt.format(outBW) + "K" + + " Lg " + jobLag + + " Dy " + msgDelay + + " Up " + uptime; + + System.out.println(status); + _statusBar.update(status); + } + _statusBar.update("Status thread died"); + System.err.println(MARKER + this + " status thread finished" + + "Current state is: " + _state); + } + } + @Override public IBinder onBind(Intent intent) { @@ -111,7 +172,8 @@ public class RouterService extends Service { private class Stopper implements Runnable { public void run() { - System.err.println(MARKER + this + " stopper thread"); + System.err.println(MARKER + this + " stopper thread" + + "Current state is: " + _state); _context.router().shutdown(Router.EXIT_HARD); _statusBar.off(RouterService.this); System.err.println("shutdown complete"); @@ -128,6 +190,8 @@ public class RouterService extends Service { synchronized (_stateLock) { if (_state == STATE_STARTING || _state == STATE_RUNNING) { _state = STATE_STOPPED; + if (_statusThread != null) + _statusThread.interrupt(); _statusBar.off(RouterService.this); stopSelf(); }