Add permanent face and route management memchanism
Change-Id: I23e77358e89c49473445994b8bd0c2c425d0e1b0
Refs: #3443
diff --git a/app/src/main/java/net/named_data/nfd/FaceCreateDialogFragment.java b/app/src/main/java/net/named_data/nfd/FaceCreateDialogFragment.java
index 5e5340a..89223c1 100644
--- a/app/src/main/java/net/named_data/nfd/FaceCreateDialogFragment.java
+++ b/app/src/main/java/net/named_data/nfd/FaceCreateDialogFragment.java
@@ -28,12 +28,13 @@
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.WindowManager;
+import android.widget.CheckBox;
import android.widget.EditText;
public class FaceCreateDialogFragment extends DialogFragment {
public static interface OnFaceCreateRequested {
public void
- createFace(String faceUri);
+ createFace(String faceUri, boolean isPermanent);
}
public static FaceCreateDialogFragment
@@ -54,7 +55,8 @@
{
EditText uriBox = (EditText) getDialog().findViewById(R.id.faceUri);
String uri = uriBox.getText().toString();
- ((OnFaceCreateRequested)getTargetFragment()).createFace(uri);
+ CheckBox permanent = (CheckBox) getDialog().findViewById(R.id.permanent);
+ ((OnFaceCreateRequested) getTargetFragment()).createFace(uri, permanent.isChecked());
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
diff --git a/app/src/main/java/net/named_data/nfd/FaceListFragment.java b/app/src/main/java/net/named_data/nfd/FaceListFragment.java
index 55d1860..4a605d1 100644
--- a/app/src/main/java/net/named_data/nfd/FaceListFragment.java
+++ b/app/src/main/java/net/named_data/nfd/FaceListFragment.java
@@ -24,9 +24,11 @@
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.app.ListFragment;
import android.util.Pair;
+import android.util.SparseArray;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -41,11 +43,14 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.intel.jndn.management.ManagementException;
import com.intel.jndn.management.types.FaceStatus;
+import net.named_data.jndn.Name;
import net.named_data.jndn_xx.util.FaceUri;
import net.named_data.nfd.utils.G;
import net.named_data.nfd.utils.NfdcHelper;
+import net.named_data.nfd.utils.PermanentFaceUriAndRouteManager;
import java.util.HashSet;
import java.util.List;
@@ -231,9 +236,9 @@
@Override
public void
- createFace(String faceUri)
+ createFace(String faceUri, boolean isPermanent)
{
- m_faceCreateAsyncTask = new FaceCreateAsyncTask(faceUri);
+ m_faceCreateAsyncTask = new FaceCreateAsyncTask(faceUri, isPermanent);
m_faceCreateAsyncTask.execute();
}
@@ -372,7 +377,7 @@
NfdcHelper nfdcHelper = new NfdcHelper();
List<FaceStatus> faceStatusList = null;
try {
- faceStatusList = nfdcHelper.faceList();
+ faceStatusList = nfdcHelper.faceList(getActivity().getApplicationContext());
} catch (Exception e) {
returnException = e;
}
@@ -423,16 +428,27 @@
NfdcHelper nfdcHelper = new NfdcHelper();
try {
+ Context context = getActivity().getApplicationContext();
+ SparseArray<FaceStatus> faceSparseArray = nfdcHelper.faceListAsSparseArray(context);
for (Set<Integer> faces : params) {
for (int faceId : faces) {
- nfdcHelper.faceDestroy(faceId);
+ FaceStatus one = faceSparseArray.get(faceId, null);
+ if (null != one){
+ removeRoutesOfFace(nfdcHelper, faceId);
+ // TODO: what if face was saved but is not in the face list? Is it possible?
+ PermanentFaceUriAndRouteManager.deletePermanentFaceUri(
+ context,
+ one.getRemoteUri()
+ );
+ PermanentFaceUriAndRouteManager.deletePermanentFaceId(context, faceId);
+ nfdcHelper.faceDestroy(faceId);
+ }
}
}
} catch (Exception e) {
retval = e;
}
nfdcHelper.shutdown();
-
return retval;
}
@@ -455,15 +471,30 @@
}
else {
// Reload face list
- retrieveFaceList();
+ m_timeoutHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ retrieveFaceList();
+ }
+ }, 500);
}
}
}
+ private void
+ removeRoutesOfFace(NfdcHelper nfdcHelper, int faceId) throws ManagementException {
+ SparseArray<Set<Name>> faceIdPrefixSparseArray = nfdcHelper.ribAsFaceIdPrefixNameArray();
+ Set<Name> prefixes = faceIdPrefixSparseArray.get(faceId, null);
+ if (null != prefixes){
+ RouteListFragment.removeRouteSyncs(getActivity().getApplicationContext(), faceId, prefixes);
+ }
+ }
+
private class FaceCreateAsyncTask extends AsyncTask<Void, Void, String> {
- public FaceCreateAsyncTask(String faceUri)
+ public FaceCreateAsyncTask(String faceUri, boolean isPermanent)
{
m_faceUri = faceUri;
+ m_isPermanent = isPermanent;
}
@Override
@@ -472,7 +503,15 @@
{
try {
NfdcHelper nfdcHelper = new NfdcHelper();
+ Context context = getActivity().getApplicationContext();
int faceId = nfdcHelper.faceCreate(m_faceUri);
+ if (m_isPermanent) {
+ PermanentFaceUriAndRouteManager.addPermanentFaceUri(
+ context,
+ NfdcHelper.formatFaceUri(m_faceUri)
+ );
+ PermanentFaceUriAndRouteManager.addPermanentFaceId(context, faceId);
+ }
nfdcHelper.shutdown();
return "OK. Face id: " + String.valueOf(faceId);
}
@@ -514,6 +553,7 @@
///////////////////////////////////////////////////////////////////////////
private String m_faceUri;
+ private boolean m_isPermanent;
}
/////////////////////////////////////////////////////////////////////////
@@ -548,4 +588,7 @@
private ProgressBar m_reloadingListProgressBar;
private FaceListAdapter m_faceListAdapter;
+
+ private Handler m_timeoutHandler = new Handler();
+
}
diff --git a/app/src/main/java/net/named_data/nfd/RouteCreateDialogFragment.java b/app/src/main/java/net/named_data/nfd/RouteCreateDialogFragment.java
index a6e0887..8e09e55 100644
--- a/app/src/main/java/net/named_data/nfd/RouteCreateDialogFragment.java
+++ b/app/src/main/java/net/named_data/nfd/RouteCreateDialogFragment.java
@@ -27,6 +27,7 @@
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.WindowManager;
+import android.widget.CheckBox;
import android.widget.EditText;
import net.named_data.jndn.Name;
@@ -35,7 +36,7 @@
{
public static interface OnRouteCreateRequested {
public void
- createRoute(Name prefix, String faceUri);
+ createRoute(Name prefix, String faceUri, boolean isPermanent);
}
public static RouteCreateDialogFragment
@@ -59,7 +60,8 @@
final String prefix = prefixBox.getText().toString();
final String uri = uriBox.getText().toString();
- ((OnRouteCreateRequested)getTargetFragment()).createRoute(new Name(prefix), uri);
+ CheckBox permanent = (CheckBox) getDialog().findViewById(R.id.permanent);
+ ((OnRouteCreateRequested)getTargetFragment()).createRoute(new Name(prefix), uri, permanent.isChecked());
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
diff --git a/app/src/main/java/net/named_data/nfd/RouteInfoFragment.java b/app/src/main/java/net/named_data/nfd/RouteInfoFragment.java
index 162f80b..4e77718 100644
--- a/app/src/main/java/net/named_data/nfd/RouteInfoFragment.java
+++ b/app/src/main/java/net/named_data/nfd/RouteInfoFragment.java
@@ -23,6 +23,7 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.intel.jndn.management.ManagementException;
import com.intel.jndn.management.enums.RouteFlags;
import com.intel.jndn.management.types.FaceStatus;
import com.intel.jndn.management.types.RibEntry;
@@ -351,7 +352,7 @@
NfdcHelper nfdcHelper = new NfdcHelper();
List<FaceStatus> faceStatusList = null;
try {
- faceStatusList = nfdcHelper.faceList();
+ faceStatusList = nfdcHelper.faceList(getActivity().getApplicationContext());
} catch (Exception e) {
returnException = e;
}
@@ -467,20 +468,11 @@
for (int routeFaceId : m_routeFaceList) {
nfdcHelper.ribUnregisterPrefix(m_prefix, routeFaceId);
}
-
nfdcHelper.shutdown();
return "OK";
- }
- catch (FaceUri.CanonizeError e) {
- return "Error Destroying dace (" + e.getMessage() + ")";
- }
- catch (FaceUri.Error e) {
- return "Error destroying face (" + e.getMessage() + ")";
- }
- catch (Exception e) {
- return "Error communicating with NFD (" + e.getMessage() + ")";
- }
- finally {
+ } catch (ManagementException e) {
+ return "Error removing face: " + e.toString();
+ } finally {
nfdcHelper.shutdown();
}
}
diff --git a/app/src/main/java/net/named_data/nfd/RouteListFragment.java b/app/src/main/java/net/named_data/nfd/RouteListFragment.java
index 69854a7..2201381 100644
--- a/app/src/main/java/net/named_data/nfd/RouteListFragment.java
+++ b/app/src/main/java/net/named_data/nfd/RouteListFragment.java
@@ -1,25 +1,24 @@
/* -*- Mode:jde; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2015 Regents of the University of California
- *
+ * Copyright (c) 2015-2016 Regents of the University of California
+ * <p>
* This file is part of NFD (Named Data Networking Forwarding Daemon) Android.
* See AUTHORS.md for complete list of NFD Android authors and contributors.
- *
+ * <p>
* 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.
- *
+ * <p>
* 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.
- *
+ * <p>
* 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.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -27,6 +26,7 @@
import android.support.v4.app.ListFragment;
import android.text.TextUtils;
import android.util.Pair;
+import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -43,6 +43,8 @@
import android.app.AlertDialog;
import android.content.DialogInterface;
+import com.intel.jndn.management.ManagementException;
+import com.intel.jndn.management.types.FaceStatus;
import com.intel.jndn.management.types.RibEntry;
import com.intel.jndn.management.types.Route;
@@ -50,6 +52,7 @@
import net.named_data.jndn_xx.util.FaceUri;
import net.named_data.nfd.utils.G;
import net.named_data.nfd.utils.NfdcHelper;
+import net.named_data.nfd.utils.PermanentFaceUriAndRouteManager;
import java.util.ArrayList;
import java.util.List;
@@ -91,8 +94,7 @@
}
@Override
- public void onViewCreated(View view, Bundle savedInstanceState)
- {
+ public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
View v = getLayoutInflater(savedInstanceState).inflate(R.layout.fragment_route_list_list_header, null);
getListView().addHeaderView(v, null, false);
@@ -101,29 +103,30 @@
m_routeListInfoUnavailableView = v.findViewById(R.id.route_list_info_unavailable);
// Get progress bar spinner view
- m_reloadingListProgressBar = (ProgressBar)v.findViewById(R.id.route_list_reloading_list_progress_bar);
+ m_reloadingListProgressBar = (ProgressBar) v.findViewById(R.id.route_list_reloading_list_progress_bar);
getListView().setLongClickable(true);
getListView().setOnItemLongClickListener(new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
- final RibEntry entry = (RibEntry)parent.getItemAtPosition(position);;
+ final RibEntry entry = (RibEntry) parent.getItemAtPosition(position);
+ ;
new AlertDialog.Builder(v.getContext())
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setTitle("Deleting route")
- .setMessage("Are you sure you want to delete " + entry.getName().toUri() + "?")
- .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- List<Integer> faceList = new ArrayList<>();
- for (Route r : entry.getRoutes()) {
- faceList.add(r.getFaceId());
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setTitle("Deleting route")
+ .setMessage("Are you sure you want to delete " + entry.getName().toUri() + "?")
+ .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ List<Integer> faceList = new ArrayList<>();
+ for (Route r : entry.getRoutes()) {
+ faceList.add(r.getFaceId());
+ }
+ removeRoute(entry.getName(), faceList);
+ Toast.makeText(getActivity(), "Route Deleted", Toast.LENGTH_LONG).show();
}
- removeRoute(entry.getName(), faceList);
- Toast.makeText(getActivity(), "Route Deleted", Toast.LENGTH_LONG).show();
- }
- })
- .setNegativeButton("No", null)
- .show();
+ })
+ .setNegativeButton("No", null)
+ .show();
return true;
@@ -132,8 +135,7 @@
}
@Override
- public void onActivityCreated(@Nullable Bundle savedInstanceState)
- {
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (m_routeListAdapter == null) {
m_routeListAdapter = new RouteListAdapter(getActivity());
@@ -144,15 +146,13 @@
}
@Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
- {
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_route_list, menu);
}
@Override
- public boolean onOptionsItemSelected(MenuItem item)
- {
+ public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.route_list_refresh:
retrieveRouteList();
@@ -186,36 +186,86 @@
}
@Override
- public void onDestroyView()
- {
+ public void onDestroyView() {
super.onDestroyView();
setListAdapter(null);
}
@Override
- public void onListItemClick(ListView l, View v, int position, long id)
- {
+ public void onListItemClick(ListView l, View v, int position, long id) {
if (m_callbacks != null) {
- RibEntry ribEntry = (RibEntry)l.getAdapter().getItem(position);
+ RibEntry ribEntry = (RibEntry) l.getAdapter().getItem(position);
m_callbacks.onRouteItemSelected(ribEntry);
}
}
@Override
public void
- createRoute(Name prefix, String faceUri)
- {
- m_routeCreateAsyncTask = new RouteCreateAsyncTask(prefix, faceUri);
+ createRoute(Name prefix, String faceUri, boolean isPermanent) {
+ m_routeCreateAsyncTask = new RouteCreateAsyncTask(prefix, faceUri, isPermanent);
m_routeCreateAsyncTask.execute();
}
public void
- removeRoute(Name prefix, List<Integer> faceIds)
- {
+ removeRoute(Name prefix, List<Integer> faceIds) {
m_routeRemoveAsyncTask = new RouteRemoveAsyncTask(prefix, faceIds);
m_routeRemoveAsyncTask.execute();
}
+ /**
+ * Synchronously remove route
+ */
+ public static void
+ removeOneRouteSync(Context applicationContext,
+ NfdcHelper nfdcHelper,
+ FaceStatus face,
+ Name prefix) throws ManagementException {
+ nfdcHelper.ribUnregisterPrefix(prefix, face.getFaceId());
+ PermanentFaceUriAndRouteManager.deletePermanentRoute(
+ applicationContext,
+ prefix.toString(),
+ face.getRemoteUri()
+ );
+ }
+
+ public static void
+ removeRouteSyncs(Context applicationContext,
+ Name prefix,
+ Iterable<Integer> faceIds) throws Exception {
+ NfdcHelper nfdcHelper = new NfdcHelper();
+ SparseArray<FaceStatus> faceSparseArray = nfdcHelper.faceListAsSparseArray(applicationContext);
+ try {
+ for (int faceId : faceIds) {
+ removeOneRouteSync(
+ applicationContext,
+ nfdcHelper,
+ faceSparseArray.get(faceId),
+ prefix);
+ }
+ } finally {
+ nfdcHelper.shutdown();
+ }
+ }
+
+ public static void
+ removeRouteSyncs(Context applicationContext,
+ Integer faceId,
+ Iterable<Name> prefixes) throws ManagementException {
+ NfdcHelper nfdcHelper = new NfdcHelper();
+ SparseArray<FaceStatus> faceSparseArray = nfdcHelper.faceListAsSparseArray(applicationContext);
+ try {
+ for (Name prefix : prefixes) {
+ removeOneRouteSync(
+ applicationContext,
+ nfdcHelper,
+ faceSparseArray.get(faceId),
+ prefix);
+ }
+ } finally {
+ nfdcHelper.shutdown();
+ }
+ }
+
/////////////////////////////////////////////////////////////////////////
/**
@@ -225,20 +275,22 @@
*
* @param list Update ListView with the given List<RibEntry>
*/
- private void updateRouteList(List<RibEntry> list) {
+ private void
+ updateRouteList(List<RibEntry> list) {
if (list == null) {
m_routeListInfoUnavailableView.setVisibility(View.VISIBLE);
return;
}
- ((RouteListAdapter)getListAdapter()).updateList(list);
+ ((RouteListAdapter) getListAdapter()).updateList(list);
}
/**
* Convenience method that starts the AsyncTask that retrieves the
* list of available routes.
*/
- private void retrieveRouteList() {
+ private void
+ retrieveRouteList() {
// Update UI
m_routeListInfoUnavailableView.setVisibility(View.GONE);
@@ -250,7 +302,8 @@
/**
* Create a new AsynTask for route list information retrieval.
*/
- private void startRouteListInfoRetrievalTask() {
+ private void
+ startRouteListInfoRetrievalTask() {
m_routeListAsyncTask = new RouteListAsyncTask();
m_routeListAsyncTask.execute();
}
@@ -258,7 +311,8 @@
/**
* Stops a previously started AsyncTask.
*/
- private void stopRouteListInfoRetrievalTask() {
+ private void
+ stopRouteListInfoRetrievalTask() {
if (m_routeListAsyncTask != null) {
m_routeListAsyncTask.cancel(false);
m_routeListAsyncTask = null;
@@ -269,34 +323,31 @@
private static class RouteListAdapter extends BaseAdapter {
- public RouteListAdapter(Context context) {
+ RouteListAdapter(Context context) {
m_layoutInflater = LayoutInflater.from(context);
}
- public void
+ void
updateList(List<RibEntry> ribEntries) {
m_ribEntries = ribEntries;
notifyDataSetChanged();
}
@Override
- public int getCount()
- {
+ public int getCount() {
return (m_ribEntries == null) ? 0 : m_ribEntries.size();
}
@Override
public RibEntry
- getItem(int i)
- {
+ getItem(int i) {
assert m_ribEntries != null;
return m_ribEntries.get(i);
}
@Override
public long
- getItemId(int i)
- {
+ getItemId(int i) {
return i;
}
@@ -357,8 +408,7 @@
List<RibEntry> routes = null;
try {
routes = nfdcHelper.ribList();
- }
- catch (Exception e) {
+ } catch (Exception e) {
returnException = e;
}
nfdcHelper.shutdown();
@@ -378,8 +428,8 @@
if (result.second != null) {
Toast.makeText(getActivity(),
- "Error communicating with NFD (" + result.second.getMessage() + ")",
- Toast.LENGTH_LONG).show();
+ "Error communicating with NFD (" + result.second.getMessage() + ")",
+ Toast.LENGTH_LONG).show();
}
updateRouteList(result.first);
@@ -387,50 +437,51 @@
}
private class RouteCreateAsyncTask extends AsyncTask<Void, Void, String> {
- public
- RouteCreateAsyncTask(Name prefix, String faceUri)
- {
+ RouteCreateAsyncTask(Name prefix, String faceUri, boolean isPermanent) {
m_prefix = prefix;
m_faceUri = faceUri;
+ m_isPermanent = isPermanent;
}
@Override
protected String
- doInBackground(Void... params)
- {
+ doInBackground(Void... params) {
NfdcHelper nfdcHelper = new NfdcHelper();
try {
int faceId = nfdcHelper.faceCreate(m_faceUri);
nfdcHelper.ribRegisterPrefix(new Name(m_prefix), faceId, 10, true, false);
+ if (m_isPermanent) {
+ Context context = getActivity().getApplicationContext();
+ PermanentFaceUriAndRouteManager
+ .addPermanentRoute(
+ context,
+ m_prefix.toUri(),
+ NfdcHelper.formatFaceUri(m_faceUri)
+ );
+ }
nfdcHelper.shutdown();
return "OK";
- }
- catch (FaceUri.CanonizeError e) {
+ } catch (FaceUri.CanonizeError e) {
return "Error creating face (" + e.getMessage() + ")";
- }
- catch (FaceUri.Error e) {
+ } catch (FaceUri.Error e) {
return "Error creating face (" + e.getMessage() + ")";
- }
- catch (Exception e) {
+ } catch (Exception e) {
return "Error communicating with NFD (" + e.getMessage() + ")";
- }
- finally {
+ } finally {
nfdcHelper.shutdown();
}
}
@Override
protected void
- onPreExecute()
- {
+ onPreExecute() {
// Display progress bar
m_reloadingListProgressBar.setVisibility(View.VISIBLE);
}
@Override
protected void
- onPostExecute(String status)
- {
+ onPostExecute(String status) {
// Display progress bar
m_reloadingListProgressBar.setVisibility(View.VISIBLE);
Toast.makeText(getActivity(), status, Toast.LENGTH_LONG).show();
@@ -440,8 +491,7 @@
@Override
protected void
- onCancelled()
- {
+ onCancelled() {
// Remove progress bar
m_reloadingListProgressBar.setVisibility(View.GONE);
}
@@ -450,55 +500,41 @@
private Name m_prefix;
private String m_faceUri;
+ private boolean m_isPermanent;
}
+
private class RouteRemoveAsyncTask extends AsyncTask<Void, Void, String> {
- public
- RouteRemoveAsyncTask(Name prefix, List<Integer> faceIds)
- {
+ public RouteRemoveAsyncTask(Name prefix, List<Integer> faceIds) {
m_prefix = prefix;
m_faceList = faceIds;
}
@Override
protected String
- doInBackground(Void... params)
- {
- NfdcHelper nfdcHelper = new NfdcHelper();
+ doInBackground(Void... params) {
try {
- for (int faceId : m_faceList) {
- nfdcHelper.ribUnregisterPrefix(m_prefix, faceId);
- }
-
- nfdcHelper.shutdown();
+ removeRouteSyncs(getActivity().getApplicationContext(), m_prefix, m_faceList);
return "OK";
- }
- catch (FaceUri.CanonizeError e) {
- return "Error Destroying dace (" + e.getMessage() + ")";
- }
- catch (FaceUri.Error e) {
+ } catch (FaceUri.CanonizeError e) {
return "Error destroying face (" + e.getMessage() + ")";
- }
- catch (Exception e) {
+ } catch (FaceUri.Error e) {
+ return "Error destroying face (" + e.getMessage() + ")";
+ } catch (Exception e) {
return "Error communicating with NFD (" + e.getMessage() + ")";
}
- finally {
- nfdcHelper.shutdown();
- }
}
@Override
protected void
- onPreExecute()
- {
+ onPreExecute() {
// Display progress bar
m_reloadingListProgressBar.setVisibility(View.VISIBLE);
}
@Override
protected void
- onPostExecute(String status)
- {
+ onPostExecute(String status) {
// Display progress bar
m_reloadingListProgressBar.setVisibility(View.VISIBLE);
Toast.makeText(getActivity(), status, Toast.LENGTH_LONG).show();
@@ -508,8 +544,7 @@
@Override
protected void
- onCancelled()
- {
+ onCancelled() {
// Remove progress bar
m_reloadingListProgressBar.setVisibility(View.GONE);
}
diff --git a/app/src/main/java/net/named_data/nfd/service/NfdService.java b/app/src/main/java/net/named_data/nfd/service/NfdService.java
index 74adec3..55a4f9d 100644
--- a/app/src/main/java/net/named_data/nfd/service/NfdService.java
+++ b/app/src/main/java/net/named_data/nfd/service/NfdService.java
@@ -20,17 +20,21 @@
package net.named_data.nfd.service;
import android.app.Service;
+import android.content.Context;
import android.content.Intent;
+import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
+import net.named_data.jndn.Name;
import net.named_data.nfd.utils.G;
+import net.named_data.nfd.utils.NfdcHelper;
+import net.named_data.nfd.utils.PermanentFaceUriAndRouteManager;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -86,6 +90,13 @@
public native static void
stopNfd();
+ /**
+ * Native API for getting NFD status
+ * @return if NFD is running return true; otherwise false.
+ */
+ public native static boolean
+ isNfdRunning();
+
public native static List<String>
getNfdLogModules();
@@ -101,17 +112,20 @@
/** Message to indicate that NFD Service is not running */
public static final int NFD_SERVICE_STOPPED = 4;
+ /** debug tag */
+ public static final String TAG = NfdService.class.getName();
+
@Override
public void onCreate() {
- G.Log("NFDService::onCreate()");
+ G.Log(TAG, "NFDService::onCreate()");
m_nfdServiceMessenger = new Messenger(new NfdServiceMessageHandler());
}
@Override
public int
onStartCommand(Intent intent, int flags, int startId) {
- G.Log("NFDService::onStartCommand()");
+ G.Log(TAG, "NFDService::onStartCommand()");
serviceStartNfd();
@@ -171,9 +185,33 @@
// from a Handler's message through binding with the service.
startService(new Intent(this, NfdService.class));
- G.Log("serviceStartNfd()");
+ // Restore PermanentFaceUriAndRoute once NFD is running
+ onNfdStart(new Runnable() {
+ @Override
+ public void run() {
+ createPermanentFaceUriAndRoute(getApplicationContext());
+ }
+ });
+
+ G.Log(TAG, "serviceStartNfd()");
} else {
- G.Log("serviceStartNfd(): NFD Service already running!");
+ G.Log(TAG, "serviceStartNfd(): NFD Service already running!");
+ }
+ }
+
+ private void onNfdStart(final Runnable task) {
+ final long checkInterval = 1000;
+ if (isNfdRunning()) {
+ G.Log(TAG, "onNfdStart: NFD is running, start executing task.");
+ task.run();
+ } else {
+ G.Log(TAG, "onNfdStart: NFD is not started yet, delay " + String.valueOf(checkInterval) + " ms.");
+ m_handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ onNfdStart(task);
+ }
+ }, checkInterval);
}
}
@@ -188,12 +226,85 @@
// TODO: Save NFD and NRD in memory data structures.
stopNfd();
-
+ PermanentFaceUriAndRouteManager.clearFaceIds(getApplicationContext());
stopSelf();
- G.Log("serviceStopNfd()");
+ G.Log(TAG, "serviceStopNfd()");
}
}
+
+ /**
+ * Create all permanent faces in the background
+ */
+ private static class FaceCreateAsyncTask extends AsyncTask<Void, Void, String> {
+ Context context;
+
+ FaceCreateAsyncTask(Context ctx) {
+ this.context = ctx;
+ }
+
+ @Override
+ protected String
+ doInBackground(Void... params) {
+ NfdcHelper nfdcHelper = new NfdcHelper();
+ try {
+ G.Log(TAG, "Try to create permanent face");
+ Set<String> permanentFace = PermanentFaceUriAndRouteManager.getPermanentFaceUris(this.context);
+ G.Log(TAG, "Permanent face list has " + permanentFace.size() + " item(s)");
+ for (String one : permanentFace) {
+ int faceId = nfdcHelper.faceCreate(one);
+ PermanentFaceUriAndRouteManager.addPermanentFaceId(this.context, faceId);
+ G.Log(TAG, "Create permanent face " + one);
+ }
+ } catch (Exception e) {
+ G.Log(TAG, "Error in FaceCreateAsyncTask: " + e.getMessage());
+ } finally {
+ nfdcHelper.shutdown();
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Create all permanent routes in the background
+ */
+ private static class RouteCreateAsyncTask extends AsyncTask<Void, Void, String> {
+ Context context;
+ RouteCreateAsyncTask(Context ctx) {
+ this.context = ctx;
+ }
+
+ @Override
+ protected String
+ doInBackground(Void... params) {
+ NfdcHelper nfdcHelper = new NfdcHelper();
+ try {
+ G.Log(TAG, "Try to create permanent route");
+ Set<String[]> prefixAndFacePairs = PermanentFaceUriAndRouteManager.getPermanentRoutes(this.context);
+ G.Log(TAG, "Permanent face list has " + prefixAndFacePairs.size() + " item(s)");
+ for (String[] prefixAndFaceUri : prefixAndFacePairs) {
+ int faceId = nfdcHelper.faceCreate(prefixAndFaceUri[1]);
+ nfdcHelper.ribRegisterPrefix(new Name(prefixAndFaceUri[0]), faceId, 10, true, false);
+ G.Log(TAG, "Create permanent route" + prefixAndFaceUri[0] + " - " + prefixAndFaceUri[1]);
+ }
+ } catch (Exception e) {
+ G.Log(TAG, "Error in RouteCreateAsyncTask: " + e.getMessage());
+ } finally {
+ nfdcHelper.shutdown();
+ }
+ return null;
+ }
+ }
+
+ /**
+ * create all permanent faces and routes in the background
+ * @param ctx: Application Context
+ */
+ public static void createPermanentFaceUriAndRoute(Context ctx) {
+ new FaceCreateAsyncTask(ctx).execute();
+ new RouteCreateAsyncTask(ctx).execute();
+ }
+
/**
* Message handler for the the NFD Service.
*/
@@ -233,4 +344,7 @@
/** Flag that denotes if the NFD has been started */
private boolean m_isNfdStarted = false;
+
+ /** Handler to deal with timeout behaviors */
+ private Handler m_handler = new Handler();
}
diff --git a/app/src/main/java/net/named_data/nfd/utils/G.java b/app/src/main/java/net/named_data/nfd/utils/G.java
index 3c05305..f251466 100644
--- a/app/src/main/java/net/named_data/nfd/utils/G.java
+++ b/app/src/main/java/net/named_data/nfd/utils/G.java
@@ -1,18 +1,18 @@
/* -*- Mode:jde; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2015 Regents of the University of California
- *
+ * <p>
* This file is part of NFD (Named Data Networking Forwarding Daemon) Android.
* See AUTHORS.md for complete list of NFD Android authors and contributors.
- *
+ * <p>
* 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.
- *
+ * <p>
* 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.
- *
+ * <p>
* 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/>.
*/
diff --git a/app/src/main/java/net/named_data/nfd/utils/NfdcHelper.java b/app/src/main/java/net/named_data/nfd/utils/NfdcHelper.java
index 35854f0..178870c 100644
--- a/app/src/main/java/net/named_data/nfd/utils/NfdcHelper.java
+++ b/app/src/main/java/net/named_data/nfd/utils/NfdcHelper.java
@@ -1,33 +1,39 @@
/* -*- Mode:jde; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2015 Regents of the University of California
- *
+ * Copyright (c) 2015-2016 Regents of the University of California
+ * <p>
* This file is part of NFD (Named Data Networking Forwarding Daemon) Android.
* See AUTHORS.md for complete list of NFD Android authors and contributors.
- *
+ * <p>
* 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.
- *
+ * <p>
* 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.
- *
+ * <p>
* 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.utils;
+import android.content.Context;
+import android.util.SparseArray;
+
import com.intel.jndn.management.ManagementException;
import com.intel.jndn.management.Nfdc;
+import com.intel.jndn.management.enums.FacePersistency;
import com.intel.jndn.management.types.FaceStatus;
import com.intel.jndn.management.types.ForwarderStatus;
import com.intel.jndn.management.types.RibEntry;
+import com.intel.jndn.management.types.Route;
import net.named_data.jndn.ControlParameters;
import net.named_data.jndn.Face;
import net.named_data.jndn.ForwardingFlags;
+import net.named_data.jndn.Interest;
import net.named_data.jndn.Name;
import net.named_data.jndn.security.*;
import net.named_data.jndn.security.SecurityException;
@@ -37,7 +43,12 @@
import net.named_data.jndn.security.policy.SelfVerifyPolicyManager;
import net.named_data.jndn_xx.util.FaceUri;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
public class NfdcHelper
{
@@ -72,7 +83,11 @@
* Registers name to the given faceId or faceUri
*/
public void
- ribRegisterPrefix(Name prefix, int faceId, int cost, boolean isChildInherit, boolean isCapture) throws Exception
+ ribRegisterPrefix(Name prefix,
+ int faceId,
+ int cost,
+ boolean isChildInherit,
+ boolean isCapture) throws Exception
{
ForwardingFlags flags = new ForwardingFlags();
flags.setChildInherit(isChildInherit);
@@ -89,8 +104,7 @@
* Unregisters name from the given faceId/faceUri
*/
public void
- ribUnregisterPrefix(Name prefix, int faceId) throws Exception
- {
+ ribUnregisterPrefix(Name prefix, int faceId) throws ManagementException {
Nfdc.unregister(m_face,
new ControlParameters()
.setName(prefix)
@@ -101,11 +115,28 @@
* List all of routes (RIB entries)
*/
public List<RibEntry>
- ribList() throws Exception
- {
+ ribList() throws ManagementException {
return Nfdc.getRouteList(m_face);
}
+ public SparseArray<Set<Name>>
+ ribAsFaceIdPrefixNameArray() throws ManagementException {
+ List<RibEntry> ribEntryList = ribList();
+ SparseArray<Set<Name>> faceIdPrefixArray = new SparseArray<>();
+
+ for (RibEntry rib: ribEntryList){
+ for (Route route : rib.getRoutes()){
+ Set<Name> prefixes = faceIdPrefixArray.get(route.getFaceId(), null);
+ if (null == prefixes){
+ prefixes = new HashSet<>();
+ faceIdPrefixArray.append(route.getFaceId(), prefixes);
+ }
+ prefixes.add(rib.getName());
+ }
+ }
+ return faceIdPrefixArray;
+ }
+
/**
* Creates new face
* <p>
@@ -114,7 +145,7 @@
public int
faceCreate(String faceUri) throws ManagementException, FaceUri.Error, FaceUri.CanonizeError
{
- return Nfdc.createFace(m_face, new FaceUri(faceUri).canonize().toString());
+ return Nfdc.createFace(m_face, formatFaceUri(faceUri));
}
/**
@@ -130,9 +161,42 @@
* List all faces
*/
public List<FaceStatus>
- faceList() throws Exception
+ faceList(Context context) throws ManagementException
{
- return Nfdc.getFaceList(m_face);
+ List<FaceStatus> result = Nfdc.getFaceList(m_face);
+ for(FaceStatus one : result) {
+ if(PermanentFaceUriAndRouteManager.isPermanentFace(context, one.getFaceId())) {
+ one.setFacePersistency(FacePersistency.PERMANENT);
+ }
+ }
+ return result;
+ }
+
+ public SparseArray<FaceStatus>
+ faceListAsSparseArray(Context context) throws ManagementException {
+ List<FaceStatus> faceList = faceList(context);
+ SparseArray<FaceStatus> array = new SparseArray<>();
+ for (FaceStatus face : faceList){
+ array.append(face.getFaceId(), face);
+ }
+ return array;
+ }
+
+ public Map<String, FaceStatus>
+ faceListAsFaceUriMap(Context context) throws ManagementException{
+ List<FaceStatus> faceList = faceList(context);
+ Map<String, FaceStatus> map = new HashMap<>();
+ for (FaceStatus face: faceList){
+ map.put(face.getRemoteUri(), face);
+ }
+ return map;
+ }
+
+ /**
+ * format a faceUri
+ */
+ public static String formatFaceUri(String faceUri) throws FaceUri.CanonizeError {
+ return new FaceUri(faceUri).canonize().toString();
}
// /**
diff --git a/app/src/main/java/net/named_data/nfd/utils/PermanentFaceUriAndRouteManager.java b/app/src/main/java/net/named_data/nfd/utils/PermanentFaceUriAndRouteManager.java
new file mode 100644
index 0000000..3f2ccdd
--- /dev/null
+++ b/app/src/main/java/net/named_data/nfd/utils/PermanentFaceUriAndRouteManager.java
@@ -0,0 +1,167 @@
+/* -*- Mode:jde; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2015-2016 Regents of the University of California
+ * <p>
+ * This file is part of NFD (Named Data Networking Forwarding Daemon) Android.
+ * See AUTHORS.md for complete list of NFD Android authors and contributors.
+ * <p>
+ * 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.
+ * <p>
+ * 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.
+ * <p>
+ * 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.utils;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * The manager to record and delete permanent faceUris and routes
+ */
+public class PermanentFaceUriAndRouteManager {
+ private static final String TAG = "Permanent Manager";
+ private static final String PREFS_NAME = "permanent";
+ private static final String PERMANENT_FACEURI = "permanentFaceUri";
+ private static final String PERMANENT_ROUTE = "permanentRoute";
+ private static final String PERMANENT_FACEID = "permanentFaceId";
+ private static final String PREFIX_FACEURI_DELIMITER = "\t";
+ // We need to cache permanent face IDs in order to display whether a face is permanent face or not.
+
+ @SuppressWarnings("deprecation")
+ public static void addPermanentFaceId(Context context, int faceId) {
+ SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
+ Set<String> permanentFace = setting.getStringSet(PERMANENT_FACEID, new HashSet<String>());
+ Set<String> newPermanentFace = new HashSet<>(permanentFace);
+
+ if (newPermanentFace.add(Integer.toString(faceId))) {
+ SharedPreferences.Editor editor = setting.edit();
+ editor.putStringSet(PERMANENT_FACEID, newPermanentFace);
+ editor.commit();
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ public static void deletePermanentFaceId(Context context, int faceId) {
+ SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
+ Set<String> permanentFace = setting.getStringSet(PERMANENT_FACEID, new HashSet<String>());
+ Set<String> newPermanentFace = new HashSet<>(permanentFace);
+
+ if (newPermanentFace.remove(Integer.toString(faceId))) {
+ SharedPreferences.Editor editor = setting.edit();
+ editor.putStringSet(PERMANENT_FACEID, newPermanentFace);
+ editor.commit();
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ static boolean isPermanentFace(Context context, int faceId) {
+ SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
+ Set<String> permanentFace = setting.getStringSet(PERMANENT_FACEID, new HashSet<String>());
+
+ return permanentFace.contains(Integer.toString(faceId));
+ }
+
+ @SuppressWarnings("deprecation")
+ public static void clearFaceIds(Context context) {
+ SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
+
+ SharedPreferences.Editor editor = setting.edit();
+ editor.putStringSet(PERMANENT_FACEID, new HashSet<String>());
+ editor.commit();
+ }
+
+ @SuppressWarnings("deprecation")
+ public static Set<String> getPermanentFaceUris(Context context){
+ SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
+ return setting.getStringSet(PERMANENT_FACEURI, new HashSet<String>());
+ }
+
+ @SuppressWarnings("deprecation")
+ public static Set<String[]> getPermanentRoutes(Context context){
+ SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
+ Set<String> permanentRoutes = setting.getStringSet(PERMANENT_ROUTE, new HashSet<String>());
+ Set<String[]> prefixAndFacePairs = new HashSet<>();
+ for (String oneRecord : permanentRoutes){
+ String[] prefixAndFaceUri = oneRecord.split(PREFIX_FACEURI_DELIMITER);
+ prefixAndFacePairs.add(prefixAndFaceUri);
+ }
+ return prefixAndFacePairs;
+ }
+
+ @SuppressWarnings("deprecation")
+ public static void addPermanentFaceUri(Context context, String faceUri) {
+ SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
+ Set<String> permanentFace = setting.getStringSet(PERMANENT_FACEURI, new HashSet<String>());
+ Set<String> newPermanentFace = new HashSet<>(permanentFace);
+
+ G.Log(TAG, "Try to record permanent face");
+ G.Log(TAG, "Permanent face list has " + permanentFace.size() + " item(s)");
+ if (newPermanentFace.add(faceUri)) {
+ SharedPreferences.Editor editor = setting.edit();
+ editor.putStringSet(PERMANENT_FACEURI, newPermanentFace);
+ editor.commit();
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ public static void addPermanentRoute(Context context, String prefix, String faceUri) {
+ SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
+ Set<String> permanentRoute = setting.getStringSet(PERMANENT_ROUTE, new HashSet<String>());
+ Set<String> newPermanentRoute = new HashSet<>(permanentRoute);
+
+ G.Log(TAG, "Try to record permanent route");
+ G.Log(TAG, "Permanent route list has " + permanentRoute.size() + " item(s)");
+ if (newPermanentRoute.add(prefix + PREFIX_FACEURI_DELIMITER + faceUri)) {
+ SharedPreferences.Editor editor = setting.edit();
+ editor.putStringSet(PERMANENT_ROUTE, newPermanentRoute);
+ editor.commit();
+ G.Log(TAG, "Record permanent route " + faceUri);
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ public static void deletePermanentFaceUri(Context context, String faceUri) {
+ SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
+ Set<String> permanentFace = setting.getStringSet(PERMANENT_FACEURI, new HashSet<String>());
+ Set<String> newPermanentFace = new HashSet<>(permanentFace);
+
+ G.Log(TAG, "Try to delete permanent face");
+ G.Log(TAG, "Permanent face list has " + permanentFace.size() + " item(s)");
+ if (newPermanentFace.remove(faceUri)) {
+ SharedPreferences.Editor editor = setting.edit();
+ editor.putStringSet(PERMANENT_FACEURI, newPermanentFace);
+ editor.commit();
+ G.Log(TAG, "Delete permanent face " + faceUri);
+ } else {
+ G.Log(TAG, faceUri + " is not a permanent face");
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ public static void deletePermanentRoute(Context context, String prefix, String faceUri) {
+ SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
+ Set<String> permanentRoute = setting.getStringSet(PERMANENT_ROUTE, new HashSet<String>());
+ Set<String> newPermanentRoute = new HashSet<>(permanentRoute);
+
+ G.Log(TAG, "Try to delete permanent route");
+ G.Log(TAG, "Permanent route list has " + permanentRoute.size() + " item(s)");
+ if (newPermanentRoute.remove(prefix + PREFIX_FACEURI_DELIMITER + faceUri)) {
+ SharedPreferences.Editor editor = setting.edit();
+ editor.putStringSet(PERMANENT_ROUTE, newPermanentRoute);
+ editor.commit();
+ G.Log(TAG, "Delete permanent route " + prefix + " " + faceUri);
+ } else {
+ G.Log(TAG, prefix + " " + faceUri + " is not a permanent route");
+ }
+ }
+}
diff --git a/app/src/main/jni/nfd-wrapper.cpp b/app/src/main/jni/nfd-wrapper.cpp
index 90e19ed..a04585e 100644
--- a/app/src/main/jni/nfd-wrapper.cpp
+++ b/app/src/main/jni/nfd-wrapper.cpp
@@ -293,6 +293,12 @@
}
}
+JNIEXPORT jboolean JNICALL
+Java_net_named_1data_nfd_service_NfdService_isNfdRunning(JNIEnv*, jclass)
+{
+ return nfd::g_runner.get() != nullptr;
+}
+
JNIEXPORT jobject JNICALL
Java_net_named_1data_nfd_service_NfdService_getNfdLogModules(JNIEnv* env, jclass)
{
diff --git a/app/src/main/jni/nfd-wrapper.hpp b/app/src/main/jni/nfd-wrapper.hpp
index fcd598d..69a0ab5 100644
--- a/app/src/main/jni/nfd-wrapper.hpp
+++ b/app/src/main/jni/nfd-wrapper.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2015 Regents of the University of California
+ * Copyright (c) 2015-2016 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.
@@ -45,6 +45,14 @@
/*
* Class: net_named_data_nfd_service_NfdService
+ * Method: isNfdRunning
+ * Signature: ()L/java/lang/Boolean;
+ */
+JNIEXPORT jboolean JNICALL
+Java_net_named_1data_nfd_service_NfdService_isNfdRunning(JNIEnv*, jclass);
+
+/*
+ * Class: net_named_data_nfd_service_NfdService
* Method: getNfdLogModules
* Signature: ()Ljava/util/List;
*/
diff --git a/app/src/main/res/layout/dialog_create_face.xml b/app/src/main/res/layout/dialog_create_face.xml
index 02d40a6..516c25a 100644
--- a/app/src/main/res/layout/dialog_create_face.xml
+++ b/app/src/main/res/layout/dialog_create_face.xml
@@ -9,7 +9,7 @@
android:layout_height="wrap_content"
style="@style/default_dialog_margin"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:text="Enter FaceUri for the remote NDN daemon"
+ android:text="@string/dialog_add_face_edit_title"
android:layout_gravity="center_horizontal"/>
<EditText
@@ -17,7 +17,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/default_dialog_margin"
- android:hint="Face URI"
+ android:hint="@string/dialog_add_route_edit_face_uri_hint"
android:inputType="text"
android:focusable="true"
android:focusableInTouchMode="true"
@@ -25,4 +25,12 @@
<requestFocus />
</EditText>
+ <CheckBox
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/dialog_add_route_or_face_as_permanent"
+ android:id="@+id/permanent"
+ android:layout_gravity="center_horizontal"
+ android:checked="false" />
+
</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_create_route.xml b/app/src/main/res/layout/dialog_create_route.xml
index 67c7677..5d8630d 100644
--- a/app/src/main/res/layout/dialog_create_route.xml
+++ b/app/src/main/res/layout/dialog_create_route.xml
@@ -9,7 +9,7 @@
android:layout_height="wrap_content"
style="@style/default_dialog_margin"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:text="Enter prefix and FaceUri to register with NDN daemon"
+ android:text="@string/dialog_add_route_edit_title"
android:layout_gravity="center_horizontal"/>
<EditText
@@ -17,7 +17,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/default_dialog_margin"
- android:hint="Prefix"
+ android:hint="@string/dialog_add_route_edit_prefix_hint"
android:inputType="text"
android:focusable="true"
android:focusableInTouchMode="true"
@@ -30,11 +30,18 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/default_dialog_margin"
- android:hint="Face URI"
+ android:hint="@string/dialog_add_route_edit_face_uri_hint"
android:inputType="text"
android:focusable="true"
android:focusableInTouchMode="true"
android:selectAllOnFocus="true">
</EditText>
+ <CheckBox
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/dialog_add_route_or_face_as_permanent"
+ android:id="@+id/permanent"
+ android:layout_gravity="center_horizontal" />
+
</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d25909a..ff141d1 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -31,10 +31,15 @@
<string name="route_list_list_of_routes_title">List of Routes</string>
<string name="route_list_refresh_route_list">Refresh Route List</string>
<string name="route_list_add_route">Add Route</string>
+ <string name="dialog_add_route_edit_title">Enter prefix and FaceUri to register with NDN daemon</string>
+ <string name="dialog_add_route_edit_prefix_hint">Prefix</string>
+ <string name="dialog_add_route_edit_face_uri_hint">Face URI</string>
+ <string name="dialog_add_route_or_face_as_permanent">Keep it permanent</string>
<string name="face_list_actions_title">Face List Actions</string>
<string name="face_list_refresh_face_list">Refresh Face List</string>
- <string name="face_list_add_face">Add Face</string>
<string name="face_list_list_of_faces_title">List of Faces</string>
+ <string name="face_list_add_face">Add Face</string>
+ <string name="dialog_add_face_edit_title">Enter FaceUri for the remote NDN daemon</string>
<string name="fragment_face_details_title">Face Details</string>
<string name="menu_item_delete_face_item">Delete</string>
<string name="expire_never">Never</string>