From 0d97d92c64237e5bbb1849f58a475e79e9aad144 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Sun, 12 Jun 2011 03:02:51 +0000
Subject: [PATCH] - Beginnings of a local Binder - Change min API to 7 (2.1),
 to make things a little easier.   This covers 95% of active devices and older
 ones are likely   too crappy to run I2P anyway.

---
 jni/build.sh                                  |   2 +-
 .../router/activity/I2PActivityBase.java      | 107 ++++++++++++++++++
 .../android/router/binder/RouterBinder.java   |  19 ++++
 .../android/router/receiver/I2PReceiver.java  |  33 +++++-
 .../android/router/service/RouterService.java |  36 +++++-
 5 files changed, 193 insertions(+), 4 deletions(-)
 create mode 100644 src/net/i2p/android/router/binder/RouterBinder.java

diff --git a/jni/build.sh b/jni/build.sh
index 15dfa5e6c..db752229d 100755
--- a/jni/build.sh
+++ b/jni/build.sh
@@ -13,7 +13,7 @@ export NDK=$(realpath ../../android-ndk-r5b/)
 #
 # API level, must match that in ../AndroidManifest.xml
 #
-LEVEL=3
+LEVEL=7
 ARCH=arm
 export SYSROOT=$NDK/platforms/android-$LEVEL/arch-$ARCH/
 export AABI=arm-linux-androideabi-4.4.3
diff --git a/src/net/i2p/android/router/activity/I2PActivityBase.java b/src/net/i2p/android/router/activity/I2PActivityBase.java
index 05d89a22b..225ba897d 100644
--- a/src/net/i2p/android/router/activity/I2PActivityBase.java
+++ b/src/net/i2p/android/router/activity/I2PActivityBase.java
@@ -3,10 +3,26 @@ package net.i2p.android.router.activity;
 import android.app.Activity;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.ServiceConnection;
 import android.os.Bundle;
+import android.os.IBinder;
+
+import net.i2p.android.router.binder.RouterBinder;
+import net.i2p.android.router.service.RouterService;
+import net.i2p.router.CommSystemFacade;
+import net.i2p.router.NetworkDatabaseFacade;
+import net.i2p.router.Router;
+import net.i2p.router.RouterContext;
+import net.i2p.router.TunnelManagerFacade;
+import net.i2p.router.peermanager.ProfileOrganizer;
+import net.i2p.router.transport.FIFOBandwidthLimiter;
+import net.i2p.stat.StatManager;
 
 public abstract class I2PActivityBase extends Activity {
     protected String _myDir;
+    protected boolean _isBound;
+    protected ServiceConnection _connection;
+    protected RouterService _routerService;
 
     /** Called when the activity is first created. */
     @Override
@@ -32,7 +48,12 @@ public abstract class I2PActivityBase extends Activity {
         intent.setClassName(this, "net.i2p.android.router.service.RouterService");
         System.err.println(this + " calling startService");
         ComponentName name = startService(intent);
+        if (name == null)
+            System.err.println(this + " XXXXXXXXXXXXXXXXXXXX got from startService: " + name);
         System.err.println(this + " got from startService: " + name);
+        boolean success = bindRouter();
+        if (!success)
+            System.err.println(this + " Bind router failed");
     }
 
     @Override
@@ -60,6 +81,7 @@ public abstract class I2PActivityBase extends Activity {
     public void onStop()
     {
         System.err.println(this + " onStop called");
+        unbindRouter();
         super.onStop();
     }
 
@@ -69,4 +91,89 @@ public abstract class I2PActivityBase extends Activity {
         System.err.println(this + "onDestroy called");
         super.onDestroy();
     }
+
+    protected boolean bindRouter() {
+        Intent intent = new Intent();
+        intent.setClassName(this, "net.i2p.android.router.service.RouterService");
+        System.err.println(this + " calling bindService");
+        _connection = new RouterConnection();
+        boolean success = bindService(intent, _connection, BIND_AUTO_CREATE);
+        System.err.println(this + " got from bindService: " + success);
+        return success;
+    }
+
+    protected void unbindRouter() {
+        if (_isBound) {
+            unbindService(_connection);
+            _isBound = false;
+        }
+    }
+
+    protected class RouterConnection implements ServiceConnection {
+
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            RouterBinder binder = (RouterBinder) service;
+            _routerService = binder.getService();
+            _isBound = true;
+        }
+
+        public void onServiceDisconnected(ComponentName name) {
+            _isBound = false;
+        }
+    }
+
+    protected RouterContext getRouterContext() {
+        if (_routerService == null || !_isBound)
+            return null;
+        return _routerService.getRouterContext();
+    }
+
+    protected Router getRouter() {
+        RouterContext ctx = getRouterContext();
+        if (ctx == null)
+            return null;
+        return ctx.router();
+    }
+
+    protected NetworkDatabaseFacade getNetDb() {
+        RouterContext ctx = getRouterContext();
+        if (ctx == null)
+            return null;
+        return ctx.netDb();
+    }
+
+    protected ProfileOrganizer getProfileOrganizer() {
+        RouterContext ctx = getRouterContext();
+        if (ctx == null)
+            return null;
+        return ctx.profileOrganizer();
+    }
+
+    protected TunnelManagerFacade getTunnelManager() {
+        RouterContext ctx = getRouterContext();
+        if (ctx == null)
+            return null;
+        return ctx.tunnelManager();
+    }
+
+    protected CommSystemFacade getCommSystem() {
+        RouterContext ctx = getRouterContext();
+        if (ctx == null)
+            return null;
+        return ctx.commSystem();
+    }
+
+    protected FIFOBandwidthLimiter getBandwidthLimiter() {
+        RouterContext ctx = getRouterContext();
+        if (ctx == null)
+            return null;
+        return ctx.bandwidthLimiter();
+    }
+
+    protected StatManager getStatManager() {
+        RouterContext ctx = getRouterContext();
+        if (ctx == null)
+            return null;
+        return ctx.statManager();
+    }
 }
diff --git a/src/net/i2p/android/router/binder/RouterBinder.java b/src/net/i2p/android/router/binder/RouterBinder.java
new file mode 100644
index 000000000..ad6df2877
--- /dev/null
+++ b/src/net/i2p/android/router/binder/RouterBinder.java
@@ -0,0 +1,19 @@
+package net.i2p.android.router.binder;
+
+import android.os.Binder;
+
+import net.i2p.android.router.service.RouterService;
+
+public class RouterBinder extends Binder {
+
+    private final RouterService _routerService;
+
+    public RouterBinder(RouterService service) {
+         super();
+         _routerService = service;
+    }
+
+    public RouterService getService() {
+        return _routerService;
+    }
+}
diff --git a/src/net/i2p/android/router/receiver/I2PReceiver.java b/src/net/i2p/android/router/receiver/I2PReceiver.java
index e4a566680..274b36419 100644
--- a/src/net/i2p/android/router/receiver/I2PReceiver.java
+++ b/src/net/i2p/android/router/receiver/I2PReceiver.java
@@ -1,16 +1,22 @@
 package net.i2p.android.router.receiver;
 
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.ServiceConnection;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
+import android.os.IBinder;
 
-import net.i2p.android.router.R;
+import net.i2p.android.router.binder.RouterBinder;
+import net.i2p.android.router.service.RouterService;
 
 public class I2PReceiver extends BroadcastReceiver {
     private final Context _context;
+    private boolean _isBound;
+    private RouterService _routerService;
 
     /**
      *  Registers itself
@@ -26,6 +32,9 @@ public class I2PReceiver extends BroadcastReceiver {
         intents.addAction(Intent.ACTION_SCREEN_ON);
         intents.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
         context.registerReceiver(this, intents);
+        boolean success = bindRouter();
+        if (!success)
+            System.err.println(this + " Bind router failed");
     }
 
     public void onReceive(Context context, Intent intent) {
@@ -76,4 +85,26 @@ public class I2PReceiver extends BroadcastReceiver {
              " failover: " + ni.isFailover());
 
     }
+
+    private boolean bindRouter() {
+        Intent intent = new Intent();
+        intent.setClassName(_context, "net.i2p.android.router.service.RouterService");
+        System.err.println(this + " calling bindService");
+        boolean success = _context.bindService(intent, new RouterConnection(), Context.BIND_AUTO_CREATE);
+        System.err.println(this + " got from bindService: " + success);
+        return success;
+    }
+
+    private class RouterConnection implements ServiceConnection {
+
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            RouterBinder binder = (RouterBinder) service;
+            _routerService = binder.getService();
+            _isBound = true;
+        }
+
+        public void onServiceDisconnected(ComponentName name) {
+            _isBound = false;
+        }
+    }
 }
diff --git a/src/net/i2p/android/router/service/RouterService.java b/src/net/i2p/android/router/service/RouterService.java
index 2c4cf7e90..ed9986639 100644
--- a/src/net/i2p/android/router/service/RouterService.java
+++ b/src/net/i2p/android/router/service/RouterService.java
@@ -12,6 +12,7 @@ import java.text.DecimalFormat;
 import java.util.List;
 
 import net.i2p.android.router.R;
+import net.i2p.android.router.binder.RouterBinder;
 import net.i2p.android.router.receiver.I2PReceiver;
 import net.i2p.data.DataHelper;
 import net.i2p.router.Job;
@@ -24,7 +25,9 @@ import net.i2p.util.NativeBigInteger;
  *  Runs the router
  */
 public class RouterService extends Service {
-    private enum State {INIT, WAITING, STARTING, RUNNING, STOPPING, STOPPED}
+    private enum State {INIT, WAITING, STARTING, RUNNING, STOPPING, STOPPED,
+                        MANUAL_STOPPING, MANUAL_STOPPED,
+                        NETWORK_STOPPING, NETWORK_STOPPED, RESTARTING}
 
     private RouterContext _context;
     private String _myDir;
@@ -34,6 +37,7 @@ public class RouterService extends Service {
     private Thread _statusThread;
     private StatusBar _statusBar;
     private I2PReceiver _receiver;
+    private IBinder _binder;
     private final Object _stateLock = new Object();
 
     private static final String MARKER = "**************************************  ";
@@ -49,6 +53,7 @@ public class RouterService extends Service {
         init.initialize();
         //_apkPath = init.getAPKPath();
         _statusBar = new StatusBar(this);
+        _binder = new RouterBinder(this);
     }
 
     @Override
@@ -191,9 +196,36 @@ public class RouterService extends Service {
     {
         System.err.println("onBind called" +
                            "Current state is: " + _state);
-        return null;
+        return _binder;
     }
 
+    // ******** following methods may be accessed from Activities and Receivers ************
+
+    public RouterContext getRouterContext() {
+        RouterContext rv = _context;
+        if (rv == null)
+            return null;
+        if (!rv.router().isAlive())
+            return null;
+        if (_state != State.RUNNING &&
+            _state != State.STOPPING &&
+            _state != State.MANUAL_STOPPING &&
+            _state != State.NETWORK_STOPPING)
+            return null;
+        return rv;
+    }
+
+    public void manualStop() {
+    }
+
+    public void networkStop() {
+    }
+
+    public void restart() {
+    }
+
+    // ******** end methods accessed from Activities and Receivers ************
+
     @Override
     public void onDestroy() {
         System.err.println("onDestroy called" +
-- 
GitLab