diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 8c3d32be5..8bb553b03 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -10,7 +10,7 @@
-
+
diff --git a/res/layout/main.xml b/res/layout/main.xml
index 8a8b089d2..63329e86d 100644
--- a/res/layout/main.xml
+++ b/res/layout/main.xml
@@ -5,6 +5,7 @@
android:layout_height="fill_parent"
>
+
+
diff --git a/scripts/setversion.sh b/scripts/setversion.sh
index da24d62c8..fbc3c6a73 100755
--- a/scripts/setversion.sh
+++ b/scripts/setversion.sh
@@ -53,7 +53,7 @@ echo "Android version: '$VERSIONSTRING' (${VERSIONINT})"
echo "my.version.name=${VERSIONSTRING}" > version.properties
echo "my.version.code=${VERSIONINT}" >> version.properties
-SUBST='s/android.versionCode="[0-9]"/android.versionCode="'${VERSIONINT}'"/'
+SUBST='s/android.versionCode="[0-9]*"/android.versionCode="'${VERSIONINT}'"/'
sed "$SUBST" < $MANIFEST > $TMP
SUBST='s/android.versionName="[^"]*"/android.versionName="'${VERSIONSTRING}'"/'
sed "$SUBST" < $TMP > $MANIFEST
diff --git a/src/net/i2p/android/router/activity/I2PActivityBase.java b/src/net/i2p/android/router/activity/I2PActivityBase.java
index 225ba897d..342cd7d1b 100644
--- a/src/net/i2p/android/router/activity/I2PActivityBase.java
+++ b/src/net/i2p/android/router/activity/I2PActivityBase.java
@@ -28,6 +28,7 @@ public abstract class I2PActivityBase extends Activity {
@Override
public void onCreate(Bundle savedInstanceState)
{
+ System.err.println(this + " onCreate called");
super.onCreate(savedInstanceState);
_myDir = getFilesDir().getAbsolutePath();
}
diff --git a/src/net/i2p/android/router/activity/MainActivity.java b/src/net/i2p/android/router/activity/MainActivity.java
index cdc91c350..e0eb59dbc 100644
--- a/src/net/i2p/android/router/activity/MainActivity.java
+++ b/src/net/i2p/android/router/activity/MainActivity.java
@@ -2,13 +2,18 @@ package net.i2p.android.router.activity;
import android.content.Intent;
import android.os.Bundle;
+import android.os.Handler;
import android.view.View;
import android.widget.Button;
+import android.widget.TextView;
import net.i2p.android.router.R;
public class MainActivity extends I2PActivityBase {
+ private Handler _handler;
+ private Runnable _updater;
+
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
@@ -17,15 +22,74 @@ public class MainActivity extends I2PActivityBase {
setContentView(R.layout.main);
Button news = (Button) findViewById(R.id.news_button);
- if (news == null) {
- System.err.println("No button resource!");
- return;
- }
news.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), NewsActivity.class);
startActivityForResult(intent, 0);
}
});
+
+ Button start = (Button) findViewById(R.id.router_start_button);
+ start.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View view) {
+ if (_routerService != null && _isBound) {
+ _routerService.manualStart();
+ updateVisibility();
+ }
+ }
+ });
+
+ Button stop = (Button) findViewById(R.id.router_stop_button);
+ stop.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View view) {
+ if (_routerService != null && _isBound) {
+ _routerService.manualStop();
+ updateVisibility();
+ }
+ }
+ });
+
+ _handler = new Handler();
+ _updater = new Updater();
+ }
+
+
+ @Override
+ public void onStart()
+ {
+ super.onStart();
+ _handler.removeCallbacks(_updater);
+ _handler.postDelayed(_updater, 50);
+ }
+
+ @Override
+ public void onStop()
+ {
+ super.onStop();
+ _handler.removeCallbacks(_updater);
+ }
+
+ @Override
+ public void onResume()
+ {
+ super.onResume();
+ updateVisibility();
+ }
+
+ private class Updater implements Runnable {
+ public void run() {
+ updateVisibility();
+ _handler.postDelayed(this, 2500);
+ }
+ }
+
+ private void updateVisibility() {
+ boolean showStart = _routerService != null && _isBound && _routerService.canManualStart();
+ Button start = (Button) findViewById(R.id.router_start_button);
+ start.setVisibility(showStart ? View.VISIBLE : View.INVISIBLE);
+
+ boolean showStop = _routerService != null && _isBound && _routerService.canManualStop();
+ Button stop = (Button) findViewById(R.id.router_stop_button);
+ stop.setVisibility(showStop ? View.VISIBLE : View.INVISIBLE);
}
}
diff --git a/src/net/i2p/android/router/service/RouterService.java b/src/net/i2p/android/router/service/RouterService.java
index eb8d3eb79..c34888442 100644
--- a/src/net/i2p/android/router/service/RouterService.java
+++ b/src/net/i2p/android/router/service/RouterService.java
@@ -59,10 +59,11 @@ public class RouterService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.err.println(this + " onStart called" +
- "Current state is: " + _state);
+ " Current state is: " + _state);
synchronized (_stateLock) {
if (_state != State.INIT)
- return START_STICKY;
+ //return START_STICKY;
+ return START_NOT_STICKY;
_receiver = new I2PReceiver(this);
if (_receiver.isConnected()) {
_statusBar.update("I2P is starting up");
@@ -76,14 +77,15 @@ public class RouterService extends Service {
_starterThread.start();
}
}
- return START_STICKY;
+ //return START_STICKY;
+ return START_NOT_STICKY;
}
/** maybe this goes away when the receiver can bind to us */
private class Waiter implements Runnable {
public void run() {
System.err.println(MARKER + this + " waiter thread" +
- "Current state is: " + _state);
+ " Current state is: " + _state);
while (_state == State.WAITING) {
try {
Thread.sleep(30*1000);
@@ -110,7 +112,7 @@ public class RouterService extends Service {
private class Starter implements Runnable {
public void run() {
System.err.println(MARKER + this + " starter thread" +
- "Current state is: " + _state);
+ " 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");
@@ -139,7 +141,7 @@ 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);
+ " Current state is: " + _state);
Router router = _context.router();
while (_state == State.RUNNING && router.isAlive()) {
try {
@@ -187,7 +189,7 @@ public class RouterService extends Service {
}
_statusBar.update("Status thread died");
System.err.println(MARKER + this + " status thread finished" +
- "Current state is: " + _state);
+ " Current state is: " + _state);
}
}
@@ -195,7 +197,7 @@ public class RouterService extends Service {
public IBinder onBind(Intent intent)
{
System.err.println("onBind called" +
- "Current state is: " + _state);
+ " Current state is: " + _state);
return _binder;
}
@@ -218,13 +220,19 @@ public class RouterService extends Service {
return rv;
}
+ public boolean canManualStop() {
+ return _state == State.WAITING || _state == State.STARTING || _state == State.RUNNING;
+ }
+
/**
* Stop and don't restart
*/
public void manualStop() {
System.err.println("manualStop called" +
- "Current state is: " + _state);
+ " Current state is: " + _state);
synchronized (_stateLock) {
+ if (!canManualStop())
+ return;
if (_state == State.WAITING || _state == State.STARTING)
_starterThread.interrupt();
if (_state == State.STARTING || _state == State.RUNNING) {
@@ -240,7 +248,7 @@ public class RouterService extends Service {
*/
public void networkStop() {
System.err.println("networkStop called" +
- "Current state is: " + _state);
+ " Current state is: " + _state);
synchronized (_stateLock) {
if (_state == State.WAITING || _state == State.STARTING)
_starterThread.interrupt();
@@ -253,7 +261,21 @@ public class RouterService extends Service {
}
}
- public void restart() {
+ public boolean canManualStart() {
+ return _state == State.MANUAL_STOPPED;
+ }
+
+ public void manualStart() {
+ System.err.println("restart called" +
+ " Current state is: " + _state);
+ synchronized (_stateLock) {
+ if (!canManualStart())
+ return;
+ _statusBar.update("I2P is starting up");
+ _state = State.STARTING;
+ _starterThread = new Thread(new Starter());
+ _starterThread.start();
+ }
}
// ******** end methods accessed from Activities and Receivers ************
@@ -261,14 +283,17 @@ public class RouterService extends Service {
@Override
public void onDestroy() {
System.err.println("onDestroy called" +
- "Current state is: " + _state);
+ " Current state is: " + _state);
_statusBar.off(this);
I2PReceiver rcvr = _receiver;
if (rcvr != null) {
synchronized(rcvr) {
- unregisterReceiver(rcvr);
+ try {
+ // throws if not registered
+ unregisterReceiver(rcvr);
+ } catch (IllegalArgumentException iae) {}
//rcvr.unbindRouter();
//_receiver = null;
}
@@ -298,11 +323,11 @@ public class RouterService extends Service {
public void run() {
System.err.println(MARKER + this + " stopper thread" +
- "Current state is: " + _state);
+ " Current state is: " + _state);
if (_context != null)
_context.router().shutdown(Router.EXIT_HARD);
_statusBar.off(RouterService.this);
- System.err.println("shutdown complete");
+ System.err.println("********** Router shutdown complete");
synchronized (_stateLock) {
if (_state == nextState)
_state = stopState;
@@ -313,12 +338,15 @@ public class RouterService extends Service {
private class ShutdownHook implements Runnable {
public void run() {
System.err.println(this + " shutdown hook" +
- "Current state is: " + _state);
+ " Current state is: " + _state);
_statusBar.off(RouterService.this);
I2PReceiver rcvr = _receiver;
if (rcvr != null) {
synchronized(rcvr) {
- unregisterReceiver(rcvr);
+ try {
+ // throws if not registered
+ unregisterReceiver(rcvr);
+ } catch (IllegalArgumentException iae) {}
//rcvr.unbindRouter();
//_receiver = null;
}
diff --git a/src/net/i2p/util/LogWriter.java b/src/net/i2p/util/LogWriter.java
index 18ba54c8e..8de250199 100644
--- a/src/net/i2p/util/LogWriter.java
+++ b/src/net/i2p/util/LogWriter.java
@@ -47,7 +47,6 @@ class LogWriter implements Runnable {
flushRecords();
rereadConfig();
}
- System.err.println("Done writing");
} catch (Exception e) {
System.err.println("Error writing the logs: " + e.getMessage());
e.printStackTrace();