gui: Add option to enable unsolicited data caching

Change-Id: I53ccf0d7d63fc9212154d00298dab54188959535
diff --git a/app/src/main/java/net/named_data/nfd/MainFragment.java b/app/src/main/java/net/named_data/nfd/MainFragment.java
index e957491..39a0ba6 100644
--- a/app/src/main/java/net/named_data/nfd/MainFragment.java
+++ b/app/src/main/java/net/named_data/nfd/MainFragment.java
@@ -116,13 +116,26 @@
           setConnectNearestHubAutomatically(getActivity().getApplicationContext(), isOn);
         if (isOn) {
           // when nfd service is running, connect NDN hub, otherwise, do nothing
-          if(m_sharedPreferences.getBoolean(PREF_NFD_SERVICE_STATUS, true)) {
+          if (m_sharedPreferences.getBoolean(PREF_NFD_SERVICE_STATUS, true)) {
             connectNearestHub();
           }
         }
       }
     });
 
+    m_enableUnsolicitedDataSwitch = v.findViewById(R.id.enable_unsolicited_caching);
+    if (SharedPreferencesManager.getEnableUnsolicitedCaching(getActivity().getApplicationContext())) {
+      m_enableUnsolicitedDataSwitch.setChecked(true);
+    }
+    m_enableUnsolicitedDataSwitch.setOnCheckedChangeListener((CompoundButton compoundButton, boolean isOn) -> {
+      SharedPreferencesManager.setEnableUnsolicitedCaching(getActivity().getApplicationContext(), isOn);
+      if (m_sharedPreferences.getBoolean(PREF_NFD_SERVICE_STATUS, true)) {
+
+        Toast.makeText(getActivity().getApplicationContext(), "Please restart NFD to update cache preference setting",
+                       Toast.LENGTH_LONG).show();
+      }
+    });
+
     m_nfdStatusView = (ViewGroup) v.findViewById(R.id.status_view);
     m_nfdStatusView.setVisibility(View.GONE);
     m_versionView = (TextView) v.findViewById(R.id.version);
@@ -503,6 +516,11 @@
   private Switch m_connectNearestHubSwitch;
 
   /**
+   * Button that starts and stops the auto configuration
+   */
+  private Switch m_enableUnsolicitedDataSwitch;
+
+  /**
    * Flag that marks that application is connected to the NfdService
    */
   private boolean m_isNfdServiceConnected = false;
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 a3a3248..5ab0d40 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
@@ -209,6 +209,8 @@
       m_isNfdStarted = true;
       HashMap<String, String> params = new HashMap<>();
       params.put("homePath", getFilesDir().getAbsolutePath());
+      params.put("tables.cs_unsolicited_policy",
+                 SharedPreferencesManager.getEnableUnsolicitedCaching(getApplicationContext()) ? "admit-all" : "drop-all");
       Set<Map.Entry<String, String>> e = params.entrySet();
 
       startNfd(params);
diff --git a/app/src/main/java/net/named_data/nfd/utils/SharedPreferencesManager.java b/app/src/main/java/net/named_data/nfd/utils/SharedPreferencesManager.java
index 9214e59..7e4addb 100644
--- a/app/src/main/java/net/named_data/nfd/utils/SharedPreferencesManager.java
+++ b/app/src/main/java/net/named_data/nfd/utils/SharedPreferencesManager.java
@@ -1,18 +1,18 @@
 /* -*- Mode:jde; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2015-2017 Regents of the University of California
- * <p>
+/*
+ * Copyright (c) 2015-2019 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>
+ * <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>
+ * <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>
+ * <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/>.
  */
@@ -35,6 +35,7 @@
   private static final String PERMANENT_ROUTE = "permanentRoute";
   private static final String PERMANENT_FACEID = "permanentFaceId";
   private static final String CONNECT_NEAREAST_HUB = "connectNeareastHub";
+  private static final String ENABLE_UNSOLICITED_CACHING = "enableUnsolicitedCaching";
   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.
 
@@ -177,4 +178,17 @@
     SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
     return setting.getBoolean(CONNECT_NEAREAST_HUB, false);
   }
+
+  @SuppressWarnings("deprecation")
+  public static void setEnableUnsolicitedCaching(Context context, boolean isOn) {
+    SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
+    setting.edit().putBoolean(ENABLE_UNSOLICITED_CACHING, isOn).commit();
+  }
+
+  @SuppressWarnings("deprecation")
+  public static boolean getEnableUnsolicitedCaching(Context context) {
+    SharedPreferences setting = context.getSharedPreferences(PREFS_NAME, Context.MODE_MULTI_PROCESS);
+    return setting.getBoolean(ENABLE_UNSOLICITED_CACHING, false);
+  }
+
 }
diff --git a/app/src/main/jni/Android.mk b/app/src/main/jni/Android.mk
index 248db74..6237abf 100644
--- a/app/src/main/jni/Android.mk
+++ b/app/src/main/jni/Android.mk
@@ -4,9 +4,9 @@
 include $(CLEAR_VARS)
 LOCAL_MODULE := nfd-wrapper
 LOCAL_SRC_FILES := nfd-wrapper.cpp
-LOCAL_SHARED_LIBRARIES := nfd_shared ndn_cxx_shared boost_system_shared boost_thread_shared boost_log_shared
+LOCAL_SHARED_LIBRARIES := nfd_shared ndn_cxx_shared boost_system_shared boost_thread_shared boost_log_shared boost_stacktrace_basic_shared
 LOCAL_LDLIBS := -llog -latomic
-LOCAL_CFLAGS := -DBOOST_LOG_DYN_LINK=1
+LOCAL_CFLAGS := -DBOOST_LOG_DYN_LINK -DBOOST_STACKTRACE_DYN_LINK
 include $(BUILD_SHARED_LIBRARY)
 
 $(call import-module,../packages/nfd/0.6.6)
diff --git a/app/src/main/jni/nfd-wrapper.cpp b/app/src/main/jni/nfd-wrapper.cpp
index d7ebed5..7b72430 100644
--- a/app/src/main/jni/nfd-wrapper.cpp
+++ b/app/src/main/jni/nfd-wrapper.cpp
@@ -19,19 +19,20 @@
 
 #include "nfd-wrapper.hpp"
 
-#include <nfd.hpp>
-#include <rib/service.hpp>
+#include <daemon/common/config-file.hpp>
+#include <daemon/common/global.hpp>
+#include <daemon/common/logger.hpp>
+#include <daemon/common/privilege-helper.hpp>
+#include <daemon/nfd.hpp>
+#include <daemon/rib/service.hpp>
 
-#include <common/config-file.hpp>
-#include <common/global.hpp>
-#include <common/logger.hpp>
-#include <common/privilege-helper.hpp>
+#include <ndn-cxx/util/exception.hpp>
+#include <ndn-cxx/util/logging.hpp>
 
 #include <boost/property_tree/info_parser.hpp>
-#include <boost/thread.hpp>
+
+#include <thread>
 #include <mutex>
-#include <ndn-cxx/util/logging.hpp>
-#include <stdlib.h>
 
 NFD_LOG_INIT(NfdWrapper);
 
@@ -108,6 +109,12 @@
     std::istringstream input(initialConfig);
     boost::property_tree::read_info(input, m_config);
 
+    // now, the start procedure can update config if needed
+  }
+
+  void
+  finishInit()
+  {
     m_nfd.reset(new Nfd(m_config, m_keyChain));
     m_ribService.reset(new rib::Service(m_config, m_keyChain));
 
@@ -144,6 +151,12 @@
     }
   }
 
+  nfd::ConfigSection&
+  getConfig()
+  {
+    return m_config;
+  }
+
 private:
   std::mutex m_pointerMutex;
   boost::asio::io_service* m_io;
@@ -155,7 +168,7 @@
 };
 
 static unique_ptr<Runner> g_runner;
-static boost::thread g_thread;
+static std::thread g_thread;
 static std::map<std::string, std::string> g_params;
 
 } // namespace nfd
@@ -212,16 +225,25 @@
     ::setenv("HOME", nfd::g_params["homePath"].c_str(), true);
     NFD_LOG_INFO("Use [" << nfd::g_params["homePath"] << "] as a security storage");
 
-    nfd::g_thread = boost::thread([] {
+    nfd::g_thread = std::thread([] {
         nfd::resetGlobalIoService();
 
         NFD_LOG_INFO("Starting NFD...");
         try {
           nfd::g_runner.reset(new nfd::Runner());
+          // update config
+          for (const auto& pair : nfd::g_params) {
+            if (pair.first == "homePath")
+              continue;
+
+            nfd::g_runner->getConfig().put(pair.first, pair.second);
+          }
+          nfd::g_runner->finishInit();
+
           nfd::g_runner->run();
         }
         catch (const std::exception& e) {
-          NFD_LOG_FATAL(e.what());
+          NFD_LOG_FATAL(boost::diagnostic_information(e));
         }
         catch (const nfd::PrivilegeHelper::Error& e) {
           NFD_LOG_FATAL("PrivilegeHelper: " << e.what());
diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml
index 2fc1654..dfaf559 100644
--- a/app/src/main/res/layout/fragment_main.xml
+++ b/app/src/main/res/layout/fragment_main.xml
@@ -38,6 +38,14 @@
         android:text="@string/connect_nearest_hub_automatically"
         />
 
+    <Switch
+        android:id="@+id/enable_unsolicited_caching"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal"
+        android:text="@string/enable_unsolicited_caching"
+        />
+
     <LinearLayout android:id="@+id/status_view"
                   android:layout_width="match_parent"
                   android:layout_height="wrap_content"
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 43dbab0..4f2a7b3 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -118,6 +118,7 @@
     <string name="face_add_dialog_create_face">Create face</string>
     <string name="route_add_dialog_create_route">Create route</string>
     <string name="connect_nearest_hub_automatically">Connect to the nearest hub automatically</string>
+    <string name="enable_unsolicited_caching">Enable unsolicited data caching</string>
     <string name="ndn_fch_website">http://ndn-fch.named-data.net/</string>
     <string name="fragment_route_list_toast_cannot_connect_hub">Cannot connect to the nearest hub</string>
     <string name="fragment_route_details_title">Route Details</string>