gui: Adding Route list/create operations
Change-Id: I5655b7a0d243eb0c59ad0fc8470a497810ca001d
Refs: #2642
diff --git a/app/build.gradle b/app/build.gradle
index 8214644..674060e 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -37,6 +37,10 @@
androidTest.setRoot('tests')
androidTest.java.srcDirs = ['tests/src']
}
+ packagingOptions {
+ exclude 'META-INF/LICENSE.txt'
+ exclude 'META-INF/NOTICE.txt'
+ }
splits {
abi {
@@ -137,4 +141,5 @@
compile 'com.google.protobuf:protobuf-java:2.6.1'
compile 'joda-time:joda-time:2.7'
+ compile 'commons-lang:commons-lang:2.6'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f8ebe5b..e28c78b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -32,6 +32,10 @@
android:name=".FaceListActivity"
android:label="Faces" />
+ <activity
+ android:name=".RouteListActivity"
+ android:label="Routes" />
+
<service
android:name=".service.NfdService"
android:process="net.named_data.nfd.service.NfdService"
diff --git a/app/src/main/java/net/named_data/nfd/MainActivity.java b/app/src/main/java/net/named_data/nfd/MainActivity.java
index 883bef1..c92011f 100644
--- a/app/src/main/java/net/named_data/nfd/MainActivity.java
+++ b/app/src/main/java/net/named_data/nfd/MainActivity.java
@@ -85,6 +85,22 @@
return true;
}
});
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Routes settings
+ ///////////////////////////////////////////////////////////////////////////
+ addPreferencesFromResource(R.xml.pref_routes);
+
+ findPreference("create_route")
+ .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference)
+ {
+ DialogFragment dialog = new RouteCreateDialog();
+ dialog.show(getFragmentManager(), "RouteCreateFragment");
+ return true;
+ }
+ });
}
})
.commit();
diff --git a/app/src/main/java/net/named_data/nfd/RouteCreateDialog.java b/app/src/main/java/net/named_data/nfd/RouteCreateDialog.java
new file mode 100644
index 0000000..aef371a
--- /dev/null
+++ b/app/src/main/java/net/named_data/nfd/RouteCreateDialog.java
@@ -0,0 +1,96 @@
+/* -*- Mode:jde; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2015 Regents of the University of California
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon) Android.
+ * See AUTHORS.md for complete list of NFD Android authors and contributors.
+ *
+ * NFD Android is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD Android 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD Android, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.named_data.nfd;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.WindowManager;
+import android.widget.EditText;
+
+import net.named_data.jndn.Name;
+import net.named_data.jndn_xx.util.FaceUri;
+import net.named_data.nfd.utils.Nfdc;
+import net.named_data.nfd.utils.NfdcAsyncTask;
+
+public class RouteCreateDialog extends DialogFragment
+{
+ @Override
+ public Dialog
+ onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ builder
+ .setView(inflater.inflate(R.layout.create_route, null))
+ .setPositiveButton("Create route", new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int id)
+ {
+ EditText prefixBox = (EditText)getDialog().findViewById(R.id.prefix);
+ EditText uriBox = (EditText)getDialog().findViewById(R.id.faceUri);
+ final String prefix = prefixBox.getText().toString();
+ final String uri = uriBox.getText().toString();
+ new NfdcAsyncTask(getActivity(),
+ new NfdcAsyncTask.Task()
+ {
+ public String
+ runTask() throws Exception
+ {
+ try {
+ Nfdc nfdc = new Nfdc();
+ int faceId = nfdc.faceCreate(m_uri);
+ boolean ok = nfdc.ribRegisterPrefix(new Name(prefix), faceId, 10, true, false);
+ nfdc.shutdown();
+ if (ok) {
+ return "OK";
+ }
+ else {
+ return "Failed register prefix";
+ }
+ } catch (FaceUri.CanonizeError e) {
+ return "Error creating face (" + e.getMessage() + ")";
+ } catch (FaceUri.Error e) {
+ return "Error creating face (" + e.getMessage() + ")";
+ }
+ }
+
+ ///////////////////////////
+ private String m_uri = uri;
+ }).execute();
+ }
+ })
+ .setNegativeButton("Cancel", new DialogInterface.OnClickListener()
+ {
+ public void onClick(DialogInterface dialog, int id)
+ {
+ RouteCreateDialog.this.getDialog().cancel();
+ }
+ })
+ ;
+
+ Dialog faceCreateDialog = builder.create();
+ faceCreateDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+ return faceCreateDialog;
+ }
+}
diff --git a/app/src/main/java/net/named_data/nfd/RouteListActivity.java b/app/src/main/java/net/named_data/nfd/RouteListActivity.java
new file mode 100644
index 0000000..5eca4cd
--- /dev/null
+++ b/app/src/main/java/net/named_data/nfd/RouteListActivity.java
@@ -0,0 +1,192 @@
+/* -*- Mode:jde; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2015 Regents of the University of California
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon) Android.
+ * See AUTHORS.md for complete list of NFD Android authors and contributors.
+ *
+ * NFD Android is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD Android 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD Android, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.named_data.nfd;
+
+import android.app.Activity;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.app.ListFragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import com.intel.jndn.management.types.RibEntry;
+import com.intel.jndn.management.types.Route;
+
+import net.named_data.nfd.utils.Nfdc;
+import net.named_data.nfd.utils.NfdcAsyncTask;
+
+import org.apache.commons.lang.StringUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RouteListActivity extends Activity
+{
+ @Override
+ public void
+ onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+
+ FragmentManager fm = getFragmentManager();
+ FragmentTransaction ft = fm.beginTransaction();
+ if (fm.findFragmentById(android.R.id.content) == null) {
+ ft.add(android.R.id.content, m_routeListFragment);
+ }
+ else {
+ ft.replace(android.R.id.content, m_routeListFragment);
+ }
+ ft.commit();
+ }
+
+ public static class RouteListFragment extends ListFragment {
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState)
+ {
+ super.onActivityCreated(savedInstanceState);
+
+ RouteListAdapter adapter = new RouteListAdapter(getActivity());
+ setListAdapter(adapter);
+
+ adapter.updateFaceList();
+ }
+
+ private class RouteListAdapter extends BaseAdapter
+ {
+ public RouteListAdapter(Context context)
+ {
+ this.m_inflater = LayoutInflater.from(context);
+ this.m_context = context;
+ }
+
+ public void
+ updateFaceList()
+ {
+ new NfdcAsyncTask(m_context,
+ new NfdcAsyncTask.Task() {
+ public String
+ runTask() throws Exception
+ {
+ synchronized (m_routesLock) {
+ Nfdc nfdc = new Nfdc();
+ m_routes = nfdc.ribList();
+ nfdc.shutdown();
+ }
+
+ getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run()
+ {
+ notifyDataSetChanged();
+ }
+ });
+ return null;
+ }
+ }).execute();
+ }
+
+ @Override
+ public int
+ getCount()
+ {
+ synchronized (m_routesLock) {
+ if (m_routes == null)
+ return 0;
+ else
+ return m_routes.size();
+ }
+ }
+
+ @Override
+ public Object
+ getItem(int position)
+ {
+ synchronized (m_routesLock) {
+ assert m_routes != null && position < m_routes.size();
+ return m_routes.get(position);
+ }
+ }
+
+ @Override
+ public long
+ getItemId(int position)
+ {
+ return position;
+ }
+
+ @Override
+ public View
+ getView(int position, View convertView, ViewGroup parent)
+ {
+ RouteListItemViewHolder holder;
+ if (convertView == null) {
+ convertView = this.m_inflater.inflate(android.R.layout.simple_list_item_2, parent, false);
+ holder = new RouteListItemViewHolder(convertView);
+ convertView.setTag(holder);
+ } else {
+ holder = (RouteListItemViewHolder)convertView.getTag();
+ }
+
+ RibEntry e;
+ synchronized (m_routesLock) {
+ e = m_routes.get(position);
+ }
+ holder.text1.setText(e.getName().toUri());
+
+ List<String> faceList = new ArrayList<>();
+ for (Route r : e.getRoutes()) {
+ faceList.add(String.valueOf(r.getFaceId()));
+ }
+ holder.text2.setText(StringUtils.join(faceList, ", "));
+
+ return convertView;
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ private LayoutInflater m_inflater;
+ private Context m_context;
+ private List<RibEntry> m_routes;
+ private final Object m_routesLock = new Object();
+
+ }
+
+ private static class RouteListItemViewHolder
+ {
+ RouteListItemViewHolder(View v)
+ {
+ text1 = (TextView)v.findViewById(android.R.id.text1);
+ text2 = (TextView)v.findViewById(android.R.id.text2);
+ }
+
+ /////////////////////////////////////////////////////////////////////////
+ public TextView text1;
+ public TextView text2;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////////////
+ private RouteListFragment m_routeListFragment = new RouteListFragment();
+}
diff --git a/app/src/main/java/net/named_data/nfd/utils/Nfdc.java b/app/src/main/java/net/named_data/nfd/utils/Nfdc.java
index a266ef2..5517449 100644
--- a/app/src/main/java/net/named_data/nfd/utils/Nfdc.java
+++ b/app/src/main/java/net/named_data/nfd/utils/Nfdc.java
@@ -21,8 +21,11 @@
import com.intel.jndn.management.NFD;
import com.intel.jndn.management.types.FaceStatus;
+import com.intel.jndn.management.types.RibEntry;
+import net.named_data.jndn.ControlParameters;
import net.named_data.jndn.Face;
+import net.named_data.jndn.ForwardingFlags;
import net.named_data.jndn.Name;
import net.named_data.jndn.security.*;
import net.named_data.jndn.security.identity.IdentityManager;
@@ -69,8 +72,8 @@
}
/**
- * @brief Adds a nexthop to a FIB entry
- *
+ * Adds a nexthop to a FIB entry
+ * <p>
* If the FIB entry does not exist, it is inserted automatically
*/
public void
@@ -79,36 +82,56 @@
}
/**
- * @brief Removes a nexthop from an existing FIB entry
- *
+ * Removes a nexthop from an existing FIB entry
+ * <p>
* If the last nexthop record in a FIB entry is removed, the FIB entry is also deleted
*/
public void
fibRemoveNextHop(Name prefix, int faceId)
{
-
}
/**
- * @brief Registers name to the given faceId or faceUri
+ * Registers name to the given faceId or faceUri
+ */
+ public boolean
+ ribRegisterPrefix(Name prefix, int faceId, int cost, boolean isChildInherit, boolean isCapture) throws Exception
+ {
+ ForwardingFlags flags = new ForwardingFlags();
+ flags.setChildInherit(isChildInherit);
+ flags.setCapture(isCapture);
+ return NFD.register(m_face,
+ new ControlParameters()
+ .setName(prefix)
+ .setFaceId(faceId)
+ .setCost(cost)
+ .setForwardingFlags(flags));
+ }
+
+ /**
+ * Unregisters name from the given faceId/faceUri
*/
public void
- ribRegisterPrefix(Name prefix, int faceId, int cost, boolean isChildInherit, boolean isCapture)
+ ribUnregisterPrefix(Name prefix, int faceId) throws Exception
{
+ NFD.unregister(m_face,
+ new ControlParameters()
+ .setName(prefix)
+ .setFaceId(faceId));
}
/**
- * @brief Unregisters name from the given faceId/faceUri
+ * List all of routes (RIB entries)
*/
- public void
- ribUnregisterPrefix(Name prefix, int faceIdName)
+ public List<RibEntry>
+ ribList() throws Exception
{
-
+ return NFD.getRouteList(m_face);
}
/**
- * @brief Creates new face
- *
+ * Creates new face
+ * <p>
* This command allows creation of UDP unicast and TCP faces only
*/
public int
@@ -118,7 +141,7 @@
}
/**
- * @brief Destroys face
+ * Destroys face
*/
public void
faceDestroy(int faceId) throws Exception
@@ -127,7 +150,7 @@
}
/**
- * @brief List all faces
+ * List all faces
*/
public List<FaceStatus>
faceList() throws Exception
@@ -136,16 +159,15 @@
}
/**
- * @brief Sets the strategy for a namespace
+ * Sets the strategy for a namespace
*/
public void
strategyChoiceSet(Name namespace, Name strategy)
{
-
}
/**
- * @brief Unset the strategy for a namespace
+ * Unset the strategy for a namespace
*/
public void
strategyChoiceUnset(Name namespace)
diff --git a/app/src/main/res/layout/create_route.xml b/app/src/main/res/layout/create_route.xml
new file mode 100644
index 0000000..ddf7fb2
--- /dev/null
+++ b/app/src/main/res/layout/create_route.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ style="@style/dialog_margin"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="Enter prefix and FaceUri to register with NDN daemon"
+ android:layout_gravity="center_horizontal"/>
+
+ <EditText
+ android:id="@+id/prefix"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/dialog_margin"
+ android:hint="Prefix"
+ android:inputType="text"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:selectAllOnFocus="true">
+ <requestFocus />
+ </EditText>
+
+ <EditText
+ android:id="@+id/faceUri"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/dialog_margin"
+ android:hint="Face URI"
+ android:inputType="text"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:selectAllOnFocus="true">
+ </EditText>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/xml/pref_routes.xml b/app/src/main/res/xml/pref_routes.xml
new file mode 100644
index 0000000..322f584
--- /dev/null
+++ b/app/src/main/res/xml/pref_routes.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ <PreferenceCategory
+ android:key="routes"
+ android:title="Routes">
+
+ <Preference android:title="Create route" android:key="create_route" />
+
+ <PreferenceScreen android:title="List routes" android:key="list_routes">
+ <intent android:action="android.intent.action.VIEW"
+ android:targetPackage="net.named_data.nfd"
+ android:targetClass="net.named_data.nfd.RouteListActivity" />
+ </PreferenceScreen>
+
+ </PreferenceCategory>
+</PreferenceScreen>