From f7904e0c7e472b84e4acace0310e904d3b087fc3 Mon Sep 17 00:00:00 2001
From: str4d <str4d@mail.i2p>
Date: Sun, 18 Aug 2013 14:27:17 +0000
Subject: [PATCH] Added TunnelEntry to format TunnelController data, expanded
 tunnel row layout

---
 res/layout/listitem_i2ptunnel.xml             | 53 ++++++++++++++++---
 .../adapter/TunnelControllerAdapter.java      | 41 --------------
 .../router/adapter/TunnelEntryAdapter.java    | 53 +++++++++++++++++++
 .../router/fragment/I2PTunnelFragment.java    | 22 ++++----
 .../android/router/loader/TunnelEntry.java    | 47 ++++++++++++++++
 ...llerLoader.java => TunnelEntryLoader.java} | 38 ++++++-------
 6 files changed, 173 insertions(+), 81 deletions(-)
 delete mode 100644 src/net/i2p/android/router/adapter/TunnelControllerAdapter.java
 create mode 100644 src/net/i2p/android/router/adapter/TunnelEntryAdapter.java
 create mode 100644 src/net/i2p/android/router/loader/TunnelEntry.java
 rename src/net/i2p/android/router/loader/{TunnelControllerLoader.java => TunnelEntryLoader.java} (77%)

diff --git a/res/layout/listitem_i2ptunnel.xml b/res/layout/listitem_i2ptunnel.xml
index 3a37b96d8..529bd69f5 100644
--- a/res/layout/listitem_i2ptunnel.xml
+++ b/res/layout/listitem_i2ptunnel.xml
@@ -1,8 +1,49 @@
 <?xml version="1.0" encoding="utf-8"?>
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/row_tunnel_name"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:padding="6dp"
-    android:textSize="16sp" >
-</TextView>
+    android:layout_height="wrap_content"
+    android:padding="5dp" >
+
+    <!-- The name of the tunnel -->
+    <TextView android:id="@+id/tunnel_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="3dp"
+        android:textSize="16sp"
+        android:layout_alignParentLeft="true"
+        android:layout_marginRight="5dp"
+        android:text="Tunnel name" />
+
+    <!-- The type of tunnel -->
+    <TextView android:id="@+id/tunnel_type"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/tunnel_name"
+        android:text="Tunnel type" />
+
+    <!-- Additional tunnel details -->
+    <TextView android:id="@+id/tunnel_details"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/tunnel_type"
+        android:text="Tunnel details" />
+
+    <!-- Interface:port the tunnel listens on or points to -->
+    <TextView android:id="@+id/tunnel_interface_port"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_toRightOf="@id/tunnel_name"
+        android:layout_alignParentRight="true"
+        android:layout_alignTop="@id/tunnel_name"
+        android:gravity="right"
+        android:text="Interface:port" />
+
+    <!-- Status star -->
+    <ImageView android:id="@+id/tunnel_status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_centerVertical="true"
+        android:contentDescription="Status" />
+
+</RelativeLayout>
diff --git a/src/net/i2p/android/router/adapter/TunnelControllerAdapter.java b/src/net/i2p/android/router/adapter/TunnelControllerAdapter.java
deleted file mode 100644
index dab0da5da..000000000
--- a/src/net/i2p/android/router/adapter/TunnelControllerAdapter.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package net.i2p.android.router.adapter;
-
-import java.util.List;
-
-import net.i2p.android.router.R;
-import net.i2p.i2ptunnel.TunnelController;
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.TextView;
-
-public class TunnelControllerAdapter extends ArrayAdapter<TunnelController> {
-    private final LayoutInflater mInflater;
-
-    public TunnelControllerAdapter(Context context) {
-        super(context, android.R.layout.simple_list_item_2);
-        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-    }
-
-    public void setData(List<TunnelController> controllers) {
-        clear();
-        if (controllers != null) {
-            for (TunnelController controller : controllers) {
-                add(controller);
-            }
-        }
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        View v = mInflater.inflate(R.layout.listitem_i2ptunnel, parent, false);
-        TunnelController controller = getItem(position);
-
-        TextView name = (TextView) v.findViewById(R.id.row_tunnel_name);
-        name.setText(controller.getName());
-
-        return v;
-    }
-}
diff --git a/src/net/i2p/android/router/adapter/TunnelEntryAdapter.java b/src/net/i2p/android/router/adapter/TunnelEntryAdapter.java
new file mode 100644
index 000000000..ad679119d
--- /dev/null
+++ b/src/net/i2p/android/router/adapter/TunnelEntryAdapter.java
@@ -0,0 +1,53 @@
+package net.i2p.android.router.adapter;
+
+import java.util.List;
+
+import net.i2p.android.router.R;
+import net.i2p.android.router.loader.TunnelEntry;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class TunnelEntryAdapter extends ArrayAdapter<TunnelEntry> {
+    private final LayoutInflater mInflater;
+
+    public TunnelEntryAdapter(Context context) {
+        super(context, android.R.layout.simple_list_item_2);
+        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+    }
+
+    public void setData(List<TunnelEntry> tunnels) {
+        clear();
+        if (tunnels != null) {
+            for (TunnelEntry tunnel : tunnels) {
+                add(tunnel);
+            }
+        }
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        View v = mInflater.inflate(R.layout.listitem_i2ptunnel, parent, false);
+        TunnelEntry tunnel = getItem(position);
+
+        TextView name = (TextView) v.findViewById(R.id.tunnel_name);
+        name.setText(tunnel.getName());
+
+        TextView type = (TextView) v.findViewById(R.id.tunnel_type);
+        type.setText(tunnel.getType());
+
+        TextView ifacePort = (TextView) v.findViewById(R.id.tunnel_interface_port);
+        ifacePort.setText(tunnel.getIfacePort());
+
+        TextView details = (TextView) v.findViewById(R.id.tunnel_details);
+        details.setText(tunnel.getDetails());
+
+        ImageView status = (ImageView) v.findViewById(R.id.tunnel_status);
+
+        return v;
+    }
+}
diff --git a/src/net/i2p/android/router/fragment/I2PTunnelFragment.java b/src/net/i2p/android/router/fragment/I2PTunnelFragment.java
index 096e3a4d6..73227f98b 100644
--- a/src/net/i2p/android/router/fragment/I2PTunnelFragment.java
+++ b/src/net/i2p/android/router/fragment/I2PTunnelFragment.java
@@ -3,9 +3,9 @@ package net.i2p.android.router.fragment;
 import java.util.List;
 
 import net.i2p.android.router.R;
-import net.i2p.android.router.adapter.TunnelControllerAdapter;
-import net.i2p.android.router.loader.TunnelControllerLoader;
-import net.i2p.i2ptunnel.TunnelController;
+import net.i2p.android.router.adapter.TunnelEntryAdapter;
+import net.i2p.android.router.loader.TunnelEntryLoader;
+import net.i2p.android.router.loader.TunnelEntry;
 import net.i2p.i2ptunnel.TunnelControllerGroup;
 import android.os.Bundle;
 import android.support.v4.app.ListFragment;
@@ -16,14 +16,14 @@ import android.view.MenuInflater;
 import android.view.MenuItem;
 
 public class I2PTunnelFragment extends ListFragment
-        implements LoaderManager.LoaderCallbacks<List<TunnelController>> {
+        implements LoaderManager.LoaderCallbacks<List<TunnelEntry>> {
     public static final String SHOW_CLIENT_TUNNELS = "show_client_tunnels";
 
     private static final int CLIENT_LOADER_ID = 1;
     private static final int SERVER_LOADER_ID = 2;
 
     private TunnelControllerGroup mGroup;
-    private TunnelControllerAdapter mAdapter;
+    private TunnelEntryAdapter mAdapter;
     private boolean mClientTunnels;
 
     @Override
@@ -35,7 +35,7 @@ public class I2PTunnelFragment extends ListFragment
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
-        mAdapter = new TunnelControllerAdapter(getActivity());
+        mAdapter = new TunnelEntryAdapter(getActivity());
         mClientTunnels = getArguments().getBoolean(SHOW_CLIENT_TUNNELS);
 
         String error;
@@ -63,12 +63,12 @@ public class I2PTunnelFragment extends ListFragment
                 : SERVER_LOADER_ID, null, this);
     }
 
-    public Loader<List<TunnelController>> onCreateLoader(int id, Bundle args) {
-        return new TunnelControllerLoader(getActivity(), mGroup, mClientTunnels);
+    public Loader<List<TunnelEntry>> onCreateLoader(int id, Bundle args) {
+        return new TunnelEntryLoader(getActivity(), mGroup, mClientTunnels);
     }
 
-    public void onLoadFinished(Loader<List<TunnelController>> loader,
-            List<TunnelController> data) {
+    public void onLoadFinished(Loader<List<TunnelEntry>> loader,
+            List<TunnelEntry> data) {
         if (loader.getId() == (mClientTunnels ?
                 CLIENT_LOADER_ID : SERVER_LOADER_ID)) {
             mAdapter.setData(data);
@@ -81,7 +81,7 @@ public class I2PTunnelFragment extends ListFragment
         }
     }
 
-    public void onLoaderReset(Loader<List<TunnelController>> loader) {
+    public void onLoaderReset(Loader<List<TunnelEntry>> loader) {
         if (loader.getId() == (mClientTunnels ?
                 CLIENT_LOADER_ID : SERVER_LOADER_ID)) {
             mAdapter.setData(null);
diff --git a/src/net/i2p/android/router/loader/TunnelEntry.java b/src/net/i2p/android/router/loader/TunnelEntry.java
new file mode 100644
index 000000000..6d522595c
--- /dev/null
+++ b/src/net/i2p/android/router/loader/TunnelEntry.java
@@ -0,0 +1,47 @@
+package net.i2p.android.router.loader;
+
+import net.i2p.i2ptunnel.TunnelController;
+
+public class TunnelEntry {
+    private final TunnelEntryLoader mLoader;
+    private final TunnelController mController;
+
+    public TunnelEntry(TunnelEntryLoader loader, TunnelController controller) {
+        mLoader = loader;
+        mController = controller;
+    }
+
+    public TunnelController getController() {
+        return mController;
+    }
+
+    public String getName() {
+        return mController.getName();
+    }
+
+    public boolean isClient() {
+        return isClient(mController.getType());
+    }
+
+    public static boolean isClient(String type) {
+        return ( ("client".equals(type)) ||
+                 ("httpclient".equals(type)) ||
+                 ("sockstunnel".equals(type)) ||
+                 ("socksirctunnel".equals(type)) ||
+                 ("connectclient".equals(type)) ||
+                 ("streamrclient".equals(type)) ||
+                 ("ircclient".equals(type)));
+    }
+
+    public String getType() {
+        return mController.getType();
+    }
+
+    public String getIfacePort() {
+        return "127.0.0.1:1234";
+    }
+
+    public String getDetails() {
+        return "Details";
+    }
+}
diff --git a/src/net/i2p/android/router/loader/TunnelControllerLoader.java b/src/net/i2p/android/router/loader/TunnelEntryLoader.java
similarity index 77%
rename from src/net/i2p/android/router/loader/TunnelControllerLoader.java
rename to src/net/i2p/android/router/loader/TunnelEntryLoader.java
index 6e43fe137..b0be157cc 100644
--- a/src/net/i2p/android/router/loader/TunnelControllerLoader.java
+++ b/src/net/i2p/android/router/loader/TunnelEntryLoader.java
@@ -10,14 +10,14 @@ import android.content.Context;
 import android.os.Handler;
 import android.support.v4.content.AsyncTaskLoader;
 
-public class TunnelControllerLoader extends AsyncTaskLoader<List<TunnelController>> {
+public class TunnelEntryLoader extends AsyncTaskLoader<List<TunnelEntry>> {
     private TunnelControllerGroup mGroup;
     private boolean mClientTunnels;
-    private List<TunnelController> mData;
+    private List<TunnelEntry> mData;
     private Handler mHandler;
     private TunnelControllerMonitor mMonitor;
 
-    public TunnelControllerLoader(Context context, TunnelControllerGroup tcg, boolean clientTunnels) {
+    public TunnelEntryLoader(Context context, TunnelControllerGroup tcg, boolean clientTunnels) {
         super(context);
         mGroup = tcg;
         mClientTunnels = clientTunnels;
@@ -25,27 +25,19 @@ public class TunnelControllerLoader extends AsyncTaskLoader<List<TunnelControlle
     }
 
     @Override
-    public List<TunnelController> loadInBackground() {
-        List<TunnelController> ret = new ArrayList<TunnelController>();
-        for (TunnelController controller : mGroup.getControllers())
-            if ( (mClientTunnels && isClient(controller.getType())) ||
-                 (!mClientTunnels && !isClient(controller.getType())) )
-                ret.add(controller);
+    public List<TunnelEntry> loadInBackground() {
+        List<TunnelEntry> ret = new ArrayList<TunnelEntry>();
+        for (TunnelController controller : mGroup.getControllers()) {
+            TunnelEntry tunnel = new TunnelEntry(this, controller);
+            if ( (mClientTunnels && tunnel.isClient()) ||
+                 (!mClientTunnels && !tunnel.isClient()) )
+                ret.add(tunnel);
+        }
         return ret;
     }
 
-    private static boolean isClient(String type) {
-        return ( ("client".equals(type)) ||
-                 ("httpclient".equals(type)) ||
-                 ("sockstunnel".equals(type)) ||
-                 ("socksirctunnel".equals(type)) ||
-                 ("connectclient".equals(type)) ||
-                 ("streamrclient".equals(type)) ||
-                 ("ircclient".equals(type)));
-    }
-
     @Override
-    public void deliverResult(List<TunnelController> data) {
+    public void deliverResult(List<TunnelEntry> data) {
         if (isReset()) {
             // The Loader has been reset; ignore the result and invalidate the data.
             if (data != null) {
@@ -56,7 +48,7 @@ public class TunnelControllerLoader extends AsyncTaskLoader<List<TunnelControlle
 
         // Hold a reference to the old data so it doesn't get garbage collected.
         // We must protect it until the new data has been delivered.
-        List<TunnelController> oldData = mData;
+        List<TunnelEntry> oldData = mData;
         mData = data;
 
         if (isStarted()) {
@@ -121,7 +113,7 @@ public class TunnelControllerLoader extends AsyncTaskLoader<List<TunnelControlle
     }
 
     @Override
-    public void onCanceled(List<TunnelController> data) {
+    public void onCanceled(List<TunnelEntry> data) {
         // Attempt to cancel the current asynchronous load.
         super.onCanceled(data);
 
@@ -130,7 +122,7 @@ public class TunnelControllerLoader extends AsyncTaskLoader<List<TunnelControlle
         releaseResources(data);
     }
 
-    private void releaseResources(List<TunnelController> data) {
+    private void releaseResources(List<TunnelEntry> data) {
         // For a simple List, there is nothing to do. For something like a Cursor, we 
         // would close it in this method. All resources associated with the Loader
         // should be released here.
-- 
GitLab