data?.let {
val packet = Packet(peer.address, data)
- val (_, payload) = packet.getDecryptedAuthPayload(
- AppPayload.Deserializer, focCommunity.myPeer.key as PrivateKey
- )
+ val (_, payload) =
+ packet.getDecryptedAuthPayload(
+ AppPayload.Deserializer,
+ focCommunity.myPeer.key as PrivateKey
+ )
evaDownload.activeDownload = false
activity.runOnUiThread {
printToast("Torrent ${payload.appName} fetched through EVA protocol!")
@@ -127,7 +127,11 @@ class AppGossiper(
activity.runOnUiThread { printToast("Failed to fetch through EVA protocol because $exception! Retrying") }
retryActiveEvaDownload()
} else {
- activity.runOnUiThread { printToast("Can't fetch through EVA because of $exception will continue to retry via torrent") }
+ activity.runOnUiThread {
+ printToast(
+ "Can't fetch through EVA because of $exception will continue to retry via torrent"
+ )
+ }
evaDownload.activeDownload = false
downloadHasFailed()
}
@@ -155,7 +159,8 @@ class AppGossiper(
}
activity.runOnUiThread {
evaRetries = evaDownload.retryAttempts
- activity.evaRetryCounter.text = activity.getString(R.string.evaRetries, evaRetries)
+ activity.binding.debugLayout.evaRetryCounter.text =
+ activity.getString(R.string.evaRetries, evaRetries)
}
}
}
@@ -171,34 +176,43 @@ class AppGossiper(
}
private fun initializeTorrentSession() {
- sessionManager.addListener(object : AlertListener {
- override fun types(): IntArray? {
- return null
- }
+ sessionManager.addListener(
+ object : AlertListener {
+ override fun types(): IntArray? {
+ return null
+ }
- override fun alert(alert: Alert<*>) {
- when (alert.type()) {
- AlertType.ADD_TORRENT -> {
- logger.info { "Torrent added" }
- (alert as AddTorrentAlert).handle().resume()
- }
- AlertType.BLOCK_FINISHED -> {
- val a = alert as BlockFinishedAlert
- val p = (a.handle().status().progress() * 100).toInt()
- logger.info { "Progress: " + p + " for torrent name: " + a.torrentName() }
- printToast("Download in progress!")
- updateProgress(p)
- logger.info { java.lang.Long.toString(sessionManager.stats().totalDownload()) }
- }
- AlertType.TORRENT_FINISHED -> {
- signal.countDown()
- logger.info { "Torrent finished" }
- }
- else -> {
+ override fun alert(alert: Alert<*>) {
+ when (alert.type()) {
+ AlertType.ADD_TORRENT -> {
+ logger.info { "Torrent added" }
+ (alert as AddTorrentAlert).handle().resume()
+ }
+
+ AlertType.BLOCK_FINISHED -> {
+ val a = alert as BlockFinishedAlert
+ val p = (a.handle().status().progress() * 100).toInt()
+ logger.info { "Progress: " + p + " for torrent name: " + a.torrentName() }
+ printToast("Download in progress!")
+ updateProgress(p)
+ logger.info {
+ java.lang.Long.toString(
+ sessionManager.stats().totalDownload()
+ )
+ }
+ }
+
+ AlertType.TORRENT_FINISHED -> {
+ signal.countDown()
+ logger.info { "Torrent finished" }
+ }
+
+ else -> {
+ }
}
}
}
- })
+ )
}
/**
@@ -222,7 +236,11 @@ class AppGossiper(
if (!downloadingPaused) {
try {
downloadPendingFiles()
- if (evaDownload.activeDownload && evaDownload.lastRequest?.let { it -> System.currentTimeMillis() - it } ?: 0 > 30 * 1000) {
+ if (evaDownload.activeDownload && evaDownload.lastRequest?.let {
+ it ->
+ System.currentTimeMillis() - it
+ } ?: 0 > 30 * 1000
+ ) {
activity.runOnUiThread { printToast("EVA Protocol timed out, retrying") }
retryActiveEvaDownload()
}
@@ -239,8 +257,9 @@ class AppGossiper(
val peer = packet.first
val payload = packet.second
logger.info { peer.mid + ": " + payload.message }
- val torrentName = payload.message.substringAfter(displayNameAppender)
- .substringBefore('&')
+ val torrentName =
+ payload.message.substringAfter(DISPLAY_NAME_APPENDER)
+ .substringBefore('&')
activity.runOnUiThread {
val existingButton = activity.torrentList.find { btn -> btn.text == torrentName }
if (existingButton == null) {
@@ -254,16 +273,19 @@ class AppGossiper(
private fun downloadPendingFiles() {
addButtonsInAdvance(focCommunity.torrentMessagesList)
for ((peer, payload) in ArrayList(focCommunity.torrentMessagesList)) {
- val torrentName = payload.message.substringAfter(displayNameAppender)
- .substringBefore('&')
- val magnetLink = payload.message.substringAfter("FOC:")
- val torrentHash = magnetLink.substringAfter(preHashString)
- .substringBefore(displayNameAppender)
+ val torrentName =
+ payload.message.substringAfter(DISPLAY_NAME_APPENDER)
+ .substringBefore('&')
+ val magnetLink = payload.message.substringAfter("foc:")
+ val torrentHash =
+ magnetLink.substringAfter(PRE_HASH_STRING)
+ .substringBefore(DISPLAY_NAME_APPENDER)
if (torrentInfos.none { it.infoHash().toString() == torrentHash }) {
if (failedTorrents.containsKey(torrentName)) {
// Wait at least 1000 seconds if torrent failed before
- if (failedTorrents[torrentName]!! >= TORRENT_ATTEMPTS_THRESHOLD)
+ if (failedTorrents[torrentName]!! >= TORRENT_ATTEMPTS_THRESHOLD) {
continue
+ }
}
getMagnetLink(magnetLink, torrentName, peer)
}
@@ -297,12 +319,13 @@ class AppGossiper(
private fun populateKnownTorrents() {
appDirectory.listFiles()?.forEachIndexed { _, file ->
- if (file.name.endsWith(torrentExtension)) {
+ if (file.name.endsWith(TORRENT_EXTENSION)) {
TorrentInfo(file).let { torrentInfo ->
if (torrentInfo.isValid) {
if (isTorrentOkay(torrentInfo, appDirectory)) {
- if (!torrentInfos.any { it.infoHash() == torrentInfo.infoHash() })
+ if (!torrentInfos.any { it.infoHash() == torrentInfo.infoHash() }) {
torrentInfos.add(torrentInfo)
+ }
}
}
}
@@ -329,7 +352,10 @@ class AppGossiper(
}
}
- private fun isTorrentOkay(torrentInfo: TorrentInfo, saveDirectory: File): Boolean {
+ private fun isTorrentOkay(
+ torrentInfo: TorrentInfo,
+ saveDirectory: File
+ ): Boolean {
File(saveDirectory.path + "/" + torrentInfo.name()).run {
if (!supportedAppExtensions.contains(extension)) return false
if (length() >= torrentInfo.totalSize()) return true
@@ -337,26 +363,31 @@ class AppGossiper(
return false
}
- fun getMagnetLink(magnetLink: String, torrentName: String, peer: Peer) {
+ fun getMagnetLink(
+ magnetLink: String,
+ torrentName: String,
+ peer: Peer
+ ) {
// Handling of the case where the user is already downloading the
// same or another torrent
- if (sessionActive || !magnetLink.startsWith(magnetHeaderString) || evaDownload.activeDownload)
+ if (sessionActive || !magnetLink.startsWith(MAGNET_HEADER_STRING) || evaDownload.activeDownload) {
return
+ }
downloadHasStarted(torrentName)
activity.runOnUiThread {
printToast("Found new torrent $torrentName attempting to download!")
}
- val startIndexName = magnetLink.indexOf(displayNameAppender)
+ val startIndexName = magnetLink.indexOf(DISPLAY_NAME_APPENDER)
val stopIndexName =
- if (magnetLink.contains(addressTrackerAppender)) magnetLink.indexOf(addressTracker) else magnetLink.length
+ if (magnetLink.contains(ADDRESS_TRACKER_APPENDER)) magnetLink.indexOf(ADDRESS_TRACKER) else magnetLink.length
val magnetNameRaw = magnetLink.substring(startIndexName + 4, stopIndexName)
logger.info { magnetNameRaw }
val magnetName = magnetNameRaw.replace('+', ' ', false)
- val magnetInfoHash = magnetLink.substring(preHashString.length, startIndexName)
+ val magnetInfoHash = magnetLink.substring(PRE_HASH_STRING.length, startIndexName)
logger.info { magnetName }
val sp = SettingsPack()
@@ -378,7 +409,8 @@ class AppGossiper(
}
}
},
- 0, 1000
+ 0,
+ 1000
)
logger.info { "Fetching the magnet uri, please wait..." }
@@ -393,7 +425,6 @@ class AppGossiper(
}
if (data != null) {
-
val torrentInfo = TorrentInfo.bdecode(data)
sessionActive = true
signal = CountDownLatch(1)
@@ -437,11 +468,12 @@ class AppGossiper(
) {
downloadHasFailed()
if (focCommunity.evaProtocolEnabled && !evaDownload.activeDownload) {
- if (failedTorrents.containsKey(torrentName))
+ if (failedTorrents.containsKey(torrentName)) {
failedTorrents[torrentName] = failedTorrents[torrentName]!!.plus(1)
- else
+ } else {
failedTorrents[torrentName] = 1
- if (failedTorrents[torrentName] == TORRENT_ATTEMPTS_THRESHOLD)
+ }
+ if (failedTorrents[torrentName] == TORRENT_ATTEMPTS_THRESHOLD) {
focCommunity.let {
activity.runOnUiThread {
downloadHasStarted(torrentName)
@@ -450,56 +482,87 @@ class AppGossiper(
val attemptUUID = UUID.randomUUID().toString()
focCommunity.sendAppRequest(magnetInfoHash, peer, attemptUUID)
evaDownload =
- EvaDownload(true, System.currentTimeMillis(), magnetInfoHash, peer, 0, torrentName, attemptUUID)
+ EvaDownload(
+ true,
+ System.currentTimeMillis(),
+ magnetInfoHash,
+ peer,
+ 0,
+ torrentName,
+ attemptUUID
+ )
}
- else
+ } else {
activity.runOnUiThread { printToast("$torrentName download failed ${failedTorrents[torrentName]} times") }
+ }
}
}
fun removeTorrent(torrentName: String) {
- val torrentInfo: TorrentInfo? = this.torrentInfos.find { torrentInfo -> torrentInfo.name() == torrentName }
+ val torrentInfo: TorrentInfo? =
+ this.torrentInfos.find { torrentInfo -> torrentInfo.name() == torrentName }
if (torrentInfo != null) {
this.torrentInfos.remove(torrentInfo)
}
- if (failedTorrents.containsKey(torrentName))
+ if (failedTorrents.containsKey(torrentName)) {
failedTorrents.remove(torrentName)
+ }
}
fun printToast(s: String) {
- if (toastingEnabled)
+ if (toastingEnabled) {
Toast.makeText(activity.applicationContext, s, Toast.LENGTH_LONG).show()
+ }
}
private fun addDownloadToQueue() {
activity.runOnUiThread {
- activity.download_count.text = activity.getString(R.string.downloadsInProgress, ++downloadsInProgress)
- activity.inQueue.text =
- activity.getString(R.string.downloadsInQueue, kotlin.math.max(0, downloadsInProgress - 1))
+ val downloadCount = activity.binding.downloadCount
+ downloadCount.text =
+ activity.getString(R.string.downloadsInProgress, ++downloadsInProgress)
+
+ val inQueue = activity.binding.popUpLayout.inQueue
+ inQueue.text =
+ activity.getString(
+ R.string.downloadsInQueue,
+ kotlin.math.max(0, downloadsInProgress - 1)
+ )
}
}
fun updateProgress(progress: Int) {
activity.runOnUiThread {
- activity.progressBar.progress = progress
- activity.progressBarPercentage.text = activity.getString(R.string.downloadProgressPercentage, "$progress%")
+ val progressBar = activity.binding.popUpLayout.progressBar
+ progressBar.progress = progress
+
+ val progressBarPercentage = activity.binding.popUpLayout.progressBarPercentage
+ progressBarPercentage.text =
+ activity.getString(R.string.downloadProgressPercentage, "$progress%")
}
}
private fun downloadHasStarted(torrentName: String) {
currentDownloadInProgress = activity.getString(R.string.currentTorrentDownload, torrentName)
activity.runOnUiThread {
- activity.inQueue.text =
- activity.getString(R.string.downloadsInQueue, kotlin.math.max(0, downloadsInProgress - 1))
- activity.currentDownload.text = currentDownloadInProgress
+ val inQueue = activity.binding.popUpLayout.inQueue
+ inQueue.text =
+ activity.getString(
+ R.string.downloadsInQueue,
+ kotlin.math.max(0, downloadsInProgress - 1)
+ )
+ val currentDownload = activity.binding.popUpLayout.currentDownload
+ currentDownload.text = currentDownloadInProgress
}
}
private fun downloadHasFailed() {
currentDownloadInProgress = activity.getString(R.string.noDownloadInProgress)
activity.runOnUiThread {
- activity.currentDownload.text = currentDownloadInProgress
- activity.failedCounter.text = activity.getString(R.string.failedCounter, failedTorrents.toString())
+ val currentDownload = activity.binding.popUpLayout.currentDownload
+ currentDownload.text = currentDownloadInProgress
+ val failedCounter = activity.binding.debugLayout.failedCounter
+ failedCounter.text =
+ activity.getString(R.string.failedCounter, failedTorrents.toString())
}
updateProgress(0)
}
@@ -507,23 +570,47 @@ class AppGossiper(
private fun downloadHasPassed() {
currentDownloadInProgress = activity.getString(R.string.noDownloadInProgress)
activity.runOnUiThread {
- activity.download_count.text = activity.getString(R.string.downloadsInProgress, --downloadsInProgress)
- activity.inQueue.text =
- activity.getString(R.string.downloadsInQueue, kotlin.math.max(0, downloadsInProgress - 1))
- activity.currentDownload.text = currentDownloadInProgress
+ activity.binding.downloadCount.text =
+ activity.getString(R.string.downloadsInProgress, --downloadsInProgress)
+ val inQueue = activity.binding.popUpLayout.inQueue
+ inQueue.text =
+ activity.getString(
+ R.string.downloadsInQueue,
+ kotlin.math.max(0, downloadsInProgress - 1)
+ )
+
+ val currentDownload = activity.binding.popUpLayout.currentDownload
+ currentDownload.text = currentDownloadInProgress
}
updateProgress(0)
}
private fun initialUISettings() {
activity.runOnUiThread {
- activity.download_count.text = activity.getString(R.string.downloadsInProgress, 0)
- activity.inQueue.text =
- activity.getString(R.string.downloadsInQueue, kotlin.math.max(0, downloadsInProgress - 1))
- activity.currentDownload.text = currentDownloadInProgress
- activity.progressBarPercentage.text = activity.getString(R.string.downloadProgressPercentage, "0%")
- activity.evaRetryCounter.text = activity.getString(R.string.evaRetries, evaRetries)
- activity.failedCounter.text = activity.getString(R.string.failedCounter, failedTorrents.toString())
+ activity.binding.downloadCount.text =
+ activity.getString(R.string.downloadsInProgress, 0)
+
+ val inQueue = activity.binding.popUpLayout.inQueue
+ inQueue.text =
+ activity.getString(
+ R.string.downloadsInQueue,
+ kotlin.math.max(0, downloadsInProgress - 1)
+ )
+
+ val currentDownload = activity.binding.popUpLayout.currentDownload
+ currentDownload.text = currentDownloadInProgress
+
+ val progressBarPercentage = activity.binding.popUpLayout.progressBarPercentage
+ progressBarPercentage.text =
+ activity.getString(R.string.downloadProgressPercentage, "0%")
+
+ val evaRetryCounter = activity.binding.debugLayout.evaRetryCounter
+ evaRetryCounter.text =
+ activity.getString(R.string.evaRetries, evaRetries)
+
+ val failedCounter = activity.binding.debugLayout.failedCounter
+ failedCounter.text =
+ activity.getString(R.string.failedCounter, failedTorrents.toString())
}
}
}
diff --git a/freedomOfComputing/src/main/java/nl/tudelft/trustchain/FOC/EvaDownload.kt b/freedomOfComputing/src/main/java/nl/tudelft/trustchain/FOC/EvaDownload.kt
index 35498f5df..8dd01fef1 100644
--- a/freedomOfComputing/src/main/java/nl/tudelft/trustchain/FOC/EvaDownload.kt
+++ b/freedomOfComputing/src/main/java/nl/tudelft/trustchain/FOC/EvaDownload.kt
@@ -1,4 +1,4 @@
-package nl.tudelft.trustchain.FOC
+package nl.tudelft.trustchain.foc
import nl.tudelft.ipv8.Peer
diff --git a/freedomOfComputing/src/main/java/nl/tudelft/trustchain/FOC/ExecutionActivity.java b/freedomOfComputing/src/main/java/nl/tudelft/trustchain/FOC/ExecutionActivity.java
index 3a373e3be..877cba798 100644
--- a/freedomOfComputing/src/main/java/nl/tudelft/trustchain/FOC/ExecutionActivity.java
+++ b/freedomOfComputing/src/main/java/nl/tudelft/trustchain/FOC/ExecutionActivity.java
@@ -1,4 +1,4 @@
-package nl.tudelft.trustchain.FOC;
+package nl.tudelft.trustchain.foc;
import android.annotation.SuppressLint;
import android.content.Context;
@@ -7,6 +7,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
+import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.annotation.RequiresApi;
@@ -16,7 +17,6 @@
import androidx.fragment.app.FragmentTransaction;
import dalvik.system.DexClassLoader;
import dalvik.system.DexFile;
-
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -25,11 +25,14 @@
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.Objects;
+import nl.tudelft.trustchain.foc.databinding.ActivityExecutionBinding;
-import static nl.tudelft.trustchain.FOC.util.ExtensionUtils.dataDotExtension;
-import static nl.tudelft.trustchain.FOC.util.ExtensionUtils.dexExtension;
+import static nl.tudelft.trustchain.foc.util.ExtensionUtils.DATA_DOT_EXTENSION;
+import static nl.tudelft.trustchain.foc.util.ExtensionUtils.DEX_EXTENSION;
public class ExecutionActivity extends AppCompatActivity {
+
+ private ActivityExecutionBinding binding;
private Fragment mainFragment;
private FragmentManager manager;
private String apkName;
@@ -40,7 +43,7 @@ public class ExecutionActivity extends AppCompatActivity {
*/
private void storeState() {
// Store state next to apk
- String fileName = this.apkName + dataDotExtension;
+ String fileName = this.apkName + DATA_DOT_EXTENSION;
try {
FileOutputStream stream = new FileOutputStream(fileName);
Parcel p = Parcel.obtain();
@@ -59,10 +62,9 @@ private void storeState() {
*
* @return the latest known state of the dynamically loaded code or null if it does not exist
*/
- @RequiresApi(api = Build.VERSION_CODES.O)
private Fragment.SavedState getState() {
// states are stored in the same directories as apks themselves (in the app specific files)
- String fileName = this.apkName + dataDotExtension;
+ String fileName = this.apkName + DATA_DOT_EXTENSION;
try {
Path path = Paths.get(fileName);
byte[] data = Files.readAllBytes(path);
@@ -109,7 +111,9 @@ protected void onCreate(Bundle savedInstanceState) {
return;
}
- setContentView(R.layout.activity_execution);
+ binding = ActivityExecutionBinding.inflate(getLayoutInflater());
+ View view = binding.getRoot();
+ setContentView(view);
Context context = getApplicationContext();
//uncomment if you want to read from the actual phone storage (needs "write" permission)
@@ -122,11 +126,9 @@ protected void onCreate(Bundle savedInstanceState) {
String mainFragmentClass = getMainFragmentClass(apkPath);
Class> fragmentClass = classLoader.loadClass((mainFragmentClass != null) ? mainFragmentClass : "com.execmodule." + activeApp + ".MainFragment");
this.mainFragment = (Fragment) fragmentClass.newInstance();
- if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
- Fragment.SavedState state = this.getState();
- if (state != null) {
- this.mainFragment.setInitialSavedState(state);
- }
+ Fragment.SavedState state = this.getState();
+ if (state != null) {
+ this.mainFragment.setInitialSavedState(state);
}
LinearLayout tmpLayout = new LinearLayout(context);
@@ -137,7 +139,7 @@ protected void onCreate(Bundle savedInstanceState) {
transaction.add(tmpLayout.getId(), this.mainFragment, "mainFragment");
transaction.commit();
- ((LinearLayout) findViewById(R.id.llcontainer)).addView(tmpLayout);
+ binding.llcontainer.addView(tmpLayout);
} catch (Exception e) {
this.printToast(e.toString());
Log.i("personal", "Something went wrong");
@@ -147,7 +149,7 @@ protected void onCreate(Bundle savedInstanceState) {
/**
* Retrieves the main fragment class from the specified APK.
* This class can be in any package. The only requirement is the main fragment should be called exactly 'MainFragment'
- *
+ *
* Deprecation suppression required to use DexFile, which we use to loop through all classes.
*
* @param path to the APK.
@@ -156,8 +158,8 @@ protected void onCreate(Bundle savedInstanceState) {
@SuppressWarnings("deprecation")
private String getMainFragmentClass(String path) {
try {
- DexFile dx = DexFile.loadDex(path, File.createTempFile("opt", dexExtension,
- getCacheDir()).getPath(), 0);
+ DexFile dx = DexFile.loadDex(path, File.createTempFile("opt", DEX_EXTENSION,
+ getCacheDir()).getPath(), 0);
for (Enumeration classNames = dx.entries(); classNames.hasMoreElements(); ) {
String className = classNames.nextElement();
if (className.contains("MainFragment") && !className.contains("$"))
diff --git a/freedomOfComputing/src/main/java/nl/tudelft/trustchain/FOC/MainActivityFOC.kt b/freedomOfComputing/src/main/java/nl/tudelft/trustchain/FOC/MainActivityFOC.kt
index 07a150b16..81a65c25e 100644
--- a/freedomOfComputing/src/main/java/nl/tudelft/trustchain/FOC/MainActivityFOC.kt
+++ b/freedomOfComputing/src/main/java/nl/tudelft/trustchain/FOC/MainActivityFOC.kt
@@ -1,4 +1,4 @@
-package nl.tudelft.trustchain.FOC
+package nl.tudelft.trustchain.foc
import android.app.AlertDialog
import android.content.Intent
@@ -11,27 +11,40 @@ import android.text.InputType
import android.util.Log
import android.view.View
import android.view.ViewGroup
-import android.widget.*
+import android.widget.Button
+import android.widget.EditText
+import android.widget.FrameLayout
+import android.widget.LinearLayout
+import android.widget.RelativeLayout
+import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import com.frostwire.jlibtorrent.SessionManager
import com.frostwire.jlibtorrent.TorrentInfo
import com.frostwire.jlibtorrent.Vectors
-import com.frostwire.jlibtorrent.swig.*
-import kotlinx.android.synthetic.main.activity_main_foc.*
-import kotlinx.android.synthetic.main.fragment_debugging.*
-import kotlinx.android.synthetic.main.fragment_download.*
+import com.frostwire.jlibtorrent.swig.add_files_listener
+import com.frostwire.jlibtorrent.swig.create_flags_t
+import com.frostwire.jlibtorrent.swig.create_torrent
+import com.frostwire.jlibtorrent.swig.error_code
+import com.frostwire.jlibtorrent.swig.file_storage
+import com.frostwire.jlibtorrent.swig.libtorrent
+import com.frostwire.jlibtorrent.swig.set_piece_hashes_listener
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import nl.tudelft.ipv8.android.IPv8Android
-import nl.tudelft.trustchain.FOC.community.FOCCommunity
-import nl.tudelft.trustchain.FOC.util.ExtensionUtils.Companion.apkDotExtension
-import nl.tudelft.trustchain.FOC.util.ExtensionUtils.Companion.torrentDotExtension
-import nl.tudelft.trustchain.FOC.util.MagnetUtils.Companion.displayNameAppender
-import nl.tudelft.trustchain.FOC.util.MagnetUtils.Companion.preHashString
-import java.io.*
+import nl.tudelft.trustchain.foc.community.FOCCommunity
+import nl.tudelft.trustchain.foc.databinding.ActivityMainFocBinding
+import nl.tudelft.trustchain.foc.util.ExtensionUtils.Companion.APK_DOT_EXTENSION
+import nl.tudelft.trustchain.foc.util.ExtensionUtils.Companion.TORRENT_DOT_EXTENSION
+import nl.tudelft.trustchain.foc.util.MagnetUtils.Companion.DISPLAY_NAME_APPENDER
+import nl.tudelft.trustchain.foc.util.MagnetUtils.Companion.PRE_HASH_STRING
+import java.io.BufferedInputStream
+import java.io.File
+import java.io.FileOutputStream
+import java.io.IOException
+import java.io.OutputStream
import java.net.URL
import java.net.URLConnection
@@ -41,6 +54,8 @@ const val READ_TIMEOUT: Int = 5000
const val DEFAULT_APK = "search.apk"
open class MainActivityFOC : AppCompatActivity() {
+ lateinit var binding: ActivityMainFocBinding
+
private val scope = CoroutineScope(Dispatchers.IO)
var torrentList = ArrayList