From 1b752a6725e43c7614fcdf08ea601c0d3a3aee7a Mon Sep 17 00:00:00 2001 From: Nathaniel Brandes Date: Mon, 6 Dec 2021 20:33:58 -0800 Subject: [PATCH 1/2] Add caching to adapter lookup If we request an adapter with the same settings multiple times, we will now return the same instance. --- .../core/app/settings/ServerSetting.java | 6 +- .../transdroid/core/gui/DetailsActivity.java | 5 +- .../transdroid/core/gui/TorrentsActivity.java | 9 +-- .../core/gui/rss/RssFeedsActivity.java | 5 +- .../core/service/ControlService.java | 3 +- .../core/service/ServerCheckerJobRunner.java | 5 +- .../core/widget/ListWidgetConfigActivity.java | 4 +- .../core/widget/ListWidgetViewsService.java | 3 +- .../org/transdroid/daemon/DaemonFactory.java | 42 ++++++++++++++ .../org/transdroid/daemon/DaemonSettings.java | 58 +++++++++++++++++++ 10 files changed, 112 insertions(+), 28 deletions(-) create mode 100644 app/src/main/java/org/transdroid/daemon/DaemonFactory.java diff --git a/app/src/main/java/org/transdroid/core/app/settings/ServerSetting.java b/app/src/main/java/org/transdroid/core/app/settings/ServerSetting.java index d359755a..e5a5e9f5 100644 --- a/app/src/main/java/org/transdroid/core/app/settings/ServerSetting.java +++ b/app/src/main/java/org/transdroid/core/app/settings/ServerSetting.java @@ -18,10 +18,10 @@ package org.transdroid.core.app.settings; import android.content.Context; import android.text.TextUtils; - import org.transdroid.core.gui.lists.SimpleListItem; import org.transdroid.core.gui.log.Log_; import org.transdroid.daemon.Daemon; +import org.transdroid.daemon.DaemonFactory; import org.transdroid.daemon.DaemonSettings; import org.transdroid.daemon.IDaemonAdapter; import org.transdroid.daemon.OS; @@ -308,8 +308,8 @@ public class ServerSetting implements SimpleListItem { * @param context A context to access the logger * @return An IDaemonAdapter instance of the specific torrent client daemon type */ - public IDaemonAdapter createServerAdapter(String connectedToNetwork, Context context) { - return type.createAdapter(convertToDaemonSettings(connectedToNetwork, context)); + public IDaemonAdapter getServerAdapter(String connectedToNetwork, Context context) { + return DaemonFactory.getServerAdapter(convertToDaemonSettings(connectedToNetwork, context)); } /** diff --git a/app/src/main/java/org/transdroid/core/gui/DetailsActivity.java b/app/src/main/java/org/transdroid/core/gui/DetailsActivity.java index 41fdd85f..5e6c95fd 100644 --- a/app/src/main/java/org/transdroid/core/gui/DetailsActivity.java +++ b/app/src/main/java/org/transdroid/core/gui/DetailsActivity.java @@ -20,13 +20,10 @@ import android.annotation.TargetApi; import android.content.Intent; import android.os.Build; import android.os.Bundle; - import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; - import com.nispok.snackbar.Snackbar; import com.nispok.snackbar.SnackbarManager; - import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.Background; import org.androidannotations.annotations.Bean; @@ -136,7 +133,7 @@ public class DetailsActivity extends AppCompatActivity implements TorrentTasksEx // Connect to the last used server ServerSetting lastUsed = applicationSettings.getLastUsedServer(); fragmentDetails.setCurrentServerSettings(lastUsed); - currentConnection = lastUsed.createServerAdapter(connectivityHelper.getConnectedNetworkName(), this); + currentConnection = lastUsed.getServerAdapter(connectivityHelper.getConnectedNetworkName(), this); // Show details and load fine stats and torrent files fragmentDetails.updateTorrent(torrent); diff --git a/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java b/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java index ec40eeb5..9002f96f 100644 --- a/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java +++ b/app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java @@ -31,7 +31,6 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; - import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.AppCompatActivity; @@ -39,13 +38,11 @@ import androidx.appcompat.widget.ActionMenuView; import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.Toolbar; import androidx.drawerlayout.widget.DrawerLayout; - import com.getbase.floatingactionbutton.FloatingActionButton; import com.getbase.floatingactionbutton.FloatingActionsMenu; import com.nispok.snackbar.Snackbar; import com.nispok.snackbar.SnackbarManager; import com.nispok.snackbar.enums.SnackbarType; - import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.Background; import org.androidannotations.annotations.Bean; @@ -337,7 +334,7 @@ public class TorrentsActivity extends AppCompatActivity implements TorrentTasksE } else { // Resume after instead of fully loading the torrents list; create connection and set action bar title ServerSetting lastUsed = applicationSettings.getLastUsedServer(); - currentConnection = lastUsed.createServerAdapter(connectivityHelper.getConnectedNetworkName(), this); + currentConnection = lastUsed.getServerAdapter(connectivityHelper.getConnectedNetworkName(), this); serverSelectionView.updateCurrentServer(currentConnection); serverSelectionView.updateCurrentFilter(currentFilter); } @@ -380,7 +377,7 @@ public class TorrentsActivity extends AppCompatActivity implements TorrentTasksE if (currentConnection == null) { filterSelected(lastUsed, true); } else { - currentConnection = lastUsed.createServerAdapter(connectivityHelper.getConnectedNetworkName(), this); + currentConnection = lastUsed.getServerAdapter(connectivityHelper.getConnectedNetworkName(), this); } // Start auto refresh @@ -564,7 +561,7 @@ public class TorrentsActivity extends AppCompatActivity implements TorrentTasksE } // Update connection to the newly selected server and refresh - currentConnection = server.createServerAdapter(connectivityHelper.getConnectedNetworkName(), this); + currentConnection = server.getServerAdapter(connectivityHelper.getConnectedNetworkName(), this); applicationSettings.setLastUsedServer(server); serverSelectionView.updateCurrentServer(currentConnection); if (forceNewConnection) { diff --git a/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java b/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java index 11af9ad5..c05d999c 100644 --- a/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java +++ b/app/src/main/java/org/transdroid/core/gui/rss/RssFeedsActivity.java @@ -25,19 +25,16 @@ import android.os.Parcel; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.viewpager.widget.PagerAdapter; import androidx.viewpager.widget.ViewPager; - import com.google.android.material.tabs.TabLayout; import com.nispok.snackbar.Snackbar; import com.nispok.snackbar.SnackbarManager; import com.nispok.snackbar.enums.SnackbarType; - import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.Background; import org.androidannotations.annotations.Bean; @@ -269,7 +266,7 @@ public class RssFeedsActivity extends AppCompatActivity { protected IDaemonAdapter getCurrentConnection() { ServerSetting lastUsed = applicationSettings.getLastUsedServer(); - return lastUsed.createServerAdapter(connectivityHelper.getConnectedNetworkName(), this); + return lastUsed.getServerAdapter(connectivityHelper.getConnectedNetworkName(), this); } // @Background diff --git a/app/src/main/java/org/transdroid/core/service/ControlService.java b/app/src/main/java/org/transdroid/core/service/ControlService.java index e9ac264d..03e7915c 100644 --- a/app/src/main/java/org/transdroid/core/service/ControlService.java +++ b/app/src/main/java/org/transdroid/core/service/ControlService.java @@ -3,7 +3,6 @@ package org.transdroid.core.service; import android.app.IntentService; import android.appwidget.AppWidgetManager; import android.content.Intent; - import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.EService; import org.transdroid.core.app.settings.ApplicationSettings; @@ -100,7 +99,7 @@ public class ControlService extends IntentService { } // See which action should be performed on the server - IDaemonAdapter adapter = server.createServerAdapter(connectivityHelper.getConnectedNetworkName(), this); + IDaemonAdapter adapter = server.getServerAdapter(connectivityHelper.getConnectedNetworkName(), this); DaemonTask task = null; switch (intent.getAction()) { case INTENT_RESUMEALL: diff --git a/app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java b/app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java index 42b9a384..3e7b3b14 100644 --- a/app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java +++ b/app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java @@ -21,11 +21,8 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.text.TextUtils; - import androidx.core.app.NotificationCompat; - import com.evernote.android.job.Job; - import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.EBean; import org.androidannotations.annotations.RootContext; @@ -85,7 +82,7 @@ public class ServerCheckerJobRunner { JSONArray lastStats = applicationSettings.getServerLastStats(server); // Synchronously retrieve torrents listing - IDaemonAdapter adapter = server.createServerAdapter(connectivityHelper.getConnectedNetworkName(), context); + IDaemonAdapter adapter = server.getServerAdapter(connectivityHelper.getConnectedNetworkName(), context); DaemonTaskResult result = RetrieveTask.create(adapter).execute(log); if (!(result instanceof RetrieveTaskSuccessResult)) { // Cannot retrieve torrents at this time diff --git a/app/src/main/java/org/transdroid/core/widget/ListWidgetConfigActivity.java b/app/src/main/java/org/transdroid/core/widget/ListWidgetConfigActivity.java index 995cbe70..7ca10ef1 100644 --- a/app/src/main/java/org/transdroid/core/widget/ListWidgetConfigActivity.java +++ b/app/src/main/java/org/transdroid/core/widget/ListWidgetConfigActivity.java @@ -30,10 +30,8 @@ import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.ListView; import android.widget.Spinner; import android.widget.TextView; - import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; - import org.androidannotations.annotations.AfterViews; import org.androidannotations.annotations.Background; import org.androidannotations.annotations.Bean; @@ -209,7 +207,7 @@ public class ListWidgetConfigActivity extends AppCompatActivity { // Create a connection object and retrieve the live torrents IDaemonAdapter connection = - ((ServerSetting) serverSpinner.getSelectedItem()).createServerAdapter(connectivityHelper.getConnectedNetworkName(), this); + ((ServerSetting) serverSpinner.getSelectedItem()).getServerAdapter(connectivityHelper.getConnectedNetworkName(), this); DaemonTaskResult result = RetrieveTask.create(connection).execute(log); if (result instanceof RetrieveTaskSuccessResult) { // Success; show the active torrents in the widget preview diff --git a/app/src/main/java/org/transdroid/core/widget/ListWidgetViewsService.java b/app/src/main/java/org/transdroid/core/widget/ListWidgetViewsService.java index 0530eabc..96c6c6db 100644 --- a/app/src/main/java/org/transdroid/core/widget/ListWidgetViewsService.java +++ b/app/src/main/java/org/transdroid/core/widget/ListWidgetViewsService.java @@ -24,7 +24,6 @@ import android.os.Build; import android.view.View; import android.widget.RemoteViews; import android.widget.RemoteViewsService; - import org.androidannotations.annotations.EService; import org.transdroid.R; import org.transdroid.core.app.settings.ApplicationSettings; @@ -109,7 +108,7 @@ class WidgetViewsFactory implements RemoteViewsService.RemoteViewsFactory { // Load the torrents; synchronously IDaemonAdapter connection = - server.createServerAdapter(ConnectivityHelper_.getInstance_(context).getConnectedNetworkName(), + server.getServerAdapter(ConnectivityHelper_.getInstance_(context).getConnectedNetworkName(), context); DaemonTaskResult result = RetrieveTask.create(connection).execute(log); if (!(result instanceof RetrieveTaskSuccessResult)) { diff --git a/app/src/main/java/org/transdroid/daemon/DaemonFactory.java b/app/src/main/java/org/transdroid/daemon/DaemonFactory.java new file mode 100644 index 00000000..b86b04c2 --- /dev/null +++ b/app/src/main/java/org/transdroid/daemon/DaemonFactory.java @@ -0,0 +1,42 @@ +/* + * This file is part of Transdroid + * + * Transdroid 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. + * + * Transdroid 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 Transdroid. If not, see . + * + */ +package org.transdroid.daemon; + +import java.util.HashMap; +import java.util.Map; + +public class DaemonFactory { + + private static final Map adapterMap = new HashMap<>(); + private static final Map settingsMap = new HashMap<>(); + + public static synchronized IDaemonAdapter getServerAdapter(DaemonSettings daemonSettings) { + + String idString = daemonSettings.getIdString(); + IDaemonAdapter daemonAdapter = adapterMap.get(idString); + + //If there is no adapter or the settings have changed, generate a new instance + if(daemonAdapter == null || !daemonSettings.equals(settingsMap.get(idString))) { + daemonAdapter = daemonSettings.getType().createAdapter(daemonSettings); + adapterMap.put(idString, daemonAdapter); + settingsMap.put(idString, daemonSettings); + } + + return daemonAdapter; + } +} diff --git a/app/src/main/java/org/transdroid/daemon/DaemonSettings.java b/app/src/main/java/org/transdroid/daemon/DaemonSettings.java index 7b7f226f..56619455 100644 --- a/app/src/main/java/org/transdroid/daemon/DaemonSettings.java +++ b/app/src/main/java/org/transdroid/daemon/DaemonSettings.java @@ -189,6 +189,64 @@ public final class DaemonSettings { return isAutoGenerated; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + DaemonSettings that = (DaemonSettings) o; + + if (port != that.port) return false; + if (ssl != that.ssl) return false; + if (sslTrustAll != that.sslTrustAll) return false; + if (useAuthentication != that.useAuthentication) return false; + if (timeout != that.timeout) return false; + if (alarmOnFinishedDownload != that.alarmOnFinishedDownload) return false; + if (alarmOnNewTorrent != that.alarmOnNewTorrent) return false; + if (isAutoGenerated != that.isAutoGenerated) return false; + if (name != null ? !name.equals(that.name) : that.name != null) return false; + if (type != that.type) return false; + if (address != null ? !address.equals(that.address) : that.address != null) return false; + if (sslTrustKey != null ? !sslTrustKey.equals(that.sslTrustKey) : that.sslTrustKey != null) return false; + if (folder != null ? !folder.equals(that.folder) : that.folder != null) return false; + if (username != null ? !username.equals(that.username) : that.username != null) return false; + if (password != null ? !password.equals(that.password) : that.password != null) return false; + if (extraPass != null ? !extraPass.equals(that.extraPass) : that.extraPass != null) return false; + if (authToken != null ? !authToken.equals(that.authToken) : that.authToken != null) return false; + if (os != that.os) return false; + if (downloadDir != null ? !downloadDir.equals(that.downloadDir) : that.downloadDir != null) return false; + if (ftpUrl != null ? !ftpUrl.equals(that.ftpUrl) : that.ftpUrl != null) return false; + if (ftpPassword != null ? !ftpPassword.equals(that.ftpPassword) : that.ftpPassword != null) return false; + return idString != null ? idString.equals(that.idString) : that.idString == null; + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + (type != null ? type.hashCode() : 0); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + port; + result = 31 * result + (ssl ? 1 : 0); + result = 31 * result + (sslTrustAll ? 1 : 0); + result = 31 * result + (sslTrustKey != null ? sslTrustKey.hashCode() : 0); + result = 31 * result + (folder != null ? folder.hashCode() : 0); + result = 31 * result + (useAuthentication ? 1 : 0); + result = 31 * result + (username != null ? username.hashCode() : 0); + result = 31 * result + (password != null ? password.hashCode() : 0); + result = 31 * result + (extraPass != null ? extraPass.hashCode() : 0); + result = 31 * result + (authToken != null ? authToken.hashCode() : 0); + result = 31 * result + (os != null ? os.hashCode() : 0); + result = 31 * result + (downloadDir != null ? downloadDir.hashCode() : 0); + result = 31 * result + (ftpUrl != null ? ftpUrl.hashCode() : 0); + result = 31 * result + (ftpPassword != null ? ftpPassword.hashCode() : 0); + result = 31 * result + timeout; + result = 31 * result + (alarmOnFinishedDownload ? 1 : 0); + result = 31 * result + (alarmOnNewTorrent ? 1 : 0); + result = 31 * result + (idString != null ? idString.hashCode() : 0); + result = 31 * result + (isAutoGenerated ? 1 : 0); + return result; + } + /** * Builds a text that can be used by a human reader to identify this daemon settings * From d3ddf34b8870e76d772559652dd12f7ef5c6742b Mon Sep 17 00:00:00 2001 From: Nathaniel Brandes Date: Mon, 6 Dec 2021 20:39:55 -0800 Subject: [PATCH 2/2] Prevent multiple threads from initing http at once --- .../daemon/adapters/aria2c/Aria2Adapter.java | 17 +++++---- .../adapters/bitComet/BitCometAdapter.java | 11 +++--- .../daemon/adapters/bitflu/BitfluAdapter.java | 11 +++--- .../buffaloNas/BuffaloNasAdapter.java | 12 +++--- .../dLinkRouterBT/DLinkRouterBTAdapter.java | 11 +++--- .../daemon/adapters/deluge/DelugeAdapter.java | 23 ++++-------- .../adapters/kTorrent/KTorrentAdapter.java | 9 ++--- .../qBittorrent/QBittorrentAdapter.java | 3 +- .../adapters/rTorrent/RTorrentAdapter.java | 25 +++++-------- .../adapters/synology/SynologyAdapter.java | 19 +++++----- .../adapters/tTorrent/TTorrentAdapter.java | 11 +++--- .../daemon/adapters/tfb4rt/Tfb4rtAdapter.java | 19 ++++------ .../transmission/TransmissionAdapter.java | 11 +++--- .../adapters/uTorrent/UTorrentAdapter.java | 37 ++++++------------- .../daemon/adapters/vuze/VuzeAdapter.java | 12 +++--- 15 files changed, 93 insertions(+), 138 deletions(-) diff --git a/app/src/main/java/org/transdroid/daemon/adapters/aria2c/Aria2Adapter.java b/app/src/main/java/org/transdroid/daemon/adapters/aria2c/Aria2Adapter.java index a96018ab..49e8dd4b 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/aria2c/Aria2Adapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/aria2c/Aria2Adapter.java @@ -19,9 +19,7 @@ package org.transdroid.daemon.adapters.aria2c; import android.net.Uri; import android.text.TextUtils; - import net.iharder.Base64; - import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPost; @@ -86,6 +84,14 @@ public class Aria2Adapter implements IDaemonAdapter { this.settings = settings; } + private synchronized void initialise() throws DaemonException { + if (httpclient == null) { + httpclient = HttpHelper.createStandardHttpClient(settings, !TextUtils.isEmpty(settings.getUsername())); + httpclient.addRequestInterceptor(HttpHelper.gzipRequestInterceptor); + httpclient.addResponseInterceptor(HttpHelper.gzipResponseInterceptor); + } + } + @Override public DaemonTaskResult executeTask(Log log, DaemonTask task) { @@ -282,13 +288,8 @@ public class Aria2Adapter implements IDaemonAdapter { private synchronized String makeRawRequest(Log log, String data) throws DaemonException { try { - // Initialise the HTTP client - if (httpclient == null) { - httpclient = HttpHelper.createStandardHttpClient(settings, !TextUtils.isEmpty(settings.getUsername())); - httpclient.addRequestInterceptor(HttpHelper.gzipRequestInterceptor); - httpclient.addResponseInterceptor(HttpHelper.gzipResponseInterceptor); - } + initialise(); // Set POST URL and data String url = diff --git a/app/src/main/java/org/transdroid/daemon/adapters/bitComet/BitCometAdapter.java b/app/src/main/java/org/transdroid/daemon/adapters/bitComet/BitCometAdapter.java index b19da394..3371f6b4 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/bitComet/BitCometAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/bitComet/BitCometAdapter.java @@ -19,7 +19,6 @@ package org.transdroid.daemon.adapters.bitComet; import com.android.internal.http.multipart.MultipartEntity; import com.android.internal.http.multipart.Part; - import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; @@ -253,8 +252,10 @@ public class BitCometAdapter implements IDaemonAdapter { * * @throws DaemonException On conflicting or missing settings */ - private void initialise() throws DaemonException { - httpclient = HttpHelper.createStandardHttpClient(settings, true); + private synchronized void initialise() throws DaemonException { + if(httpclient == null) { + httpclient = HttpHelper.createStandardHttpClient(settings, true); + } } /** @@ -271,9 +272,7 @@ public class BitCometAdapter implements IDaemonAdapter { try { // Initialize the HTTP client - if (httpclient == null) { - initialise(); - } + initialise(); // Add the parameters to the query string boolean first = true; diff --git a/app/src/main/java/org/transdroid/daemon/adapters/bitflu/BitfluAdapter.java b/app/src/main/java/org/transdroid/daemon/adapters/bitflu/BitfluAdapter.java index 7b43c1bd..3dd4f916 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/bitflu/BitfluAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/bitflu/BitfluAdapter.java @@ -140,9 +140,7 @@ public class BitfluAdapter implements IDaemonAdapter { try { // Initialise the HTTP client - if (httpclient == null) { - initialise(); - } + initialise(); // TLog.d(LOG_NAME, "Request to: "+ buildWebUIUrl() + addToUrl); @@ -268,9 +266,10 @@ public class BitfluAdapter implements IDaemonAdapter { * * @throws DaemonException On conflicting or missing settings */ - private void initialise() throws DaemonException { - - httpclient = HttpHelper.createStandardHttpClient(settings, true); + private synchronized void initialise() throws DaemonException { + if(httpclient == null) { + httpclient = HttpHelper.createStandardHttpClient(settings, true); + } } /** diff --git a/app/src/main/java/org/transdroid/daemon/adapters/buffaloNas/BuffaloNasAdapter.java b/app/src/main/java/org/transdroid/daemon/adapters/buffaloNas/BuffaloNasAdapter.java index a591ff71..4808ce9d 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/buffaloNas/BuffaloNasAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/buffaloNas/BuffaloNasAdapter.java @@ -20,7 +20,6 @@ package org.transdroid.daemon.adapters.buffaloNas; import com.android.internal.http.multipart.FilePart; import com.android.internal.http.multipart.MultipartEntity; import com.android.internal.http.multipart.Part; - import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; @@ -174,9 +173,7 @@ public class BuffaloNasAdapter implements IDaemonAdapter { try { // Initialise the HTTP client - if (httpclient == null) { - initialise(); - } + initialise(); // Add the parameters to the query string boolean first = true; @@ -251,9 +248,10 @@ public class BuffaloNasAdapter implements IDaemonAdapter { * * @throws DaemonException On conflicting or missing settings */ - private void initialise() throws DaemonException { - - httpclient = HttpHelper.createStandardHttpClient(settings, true); + private synchronized void initialise() throws DaemonException { + if(httpclient == null) { + httpclient = HttpHelper.createStandardHttpClient(settings, true); + } } diff --git a/app/src/main/java/org/transdroid/daemon/adapters/dLinkRouterBT/DLinkRouterBTAdapter.java b/app/src/main/java/org/transdroid/daemon/adapters/dLinkRouterBT/DLinkRouterBTAdapter.java index 8049aa08..a13ed17e 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/dLinkRouterBT/DLinkRouterBTAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/dLinkRouterBT/DLinkRouterBTAdapter.java @@ -20,7 +20,6 @@ package org.transdroid.daemon.adapters.dLinkRouterBT; import com.android.internal.http.multipart.FilePart; import com.android.internal.http.multipart.MultipartEntity; import com.android.internal.http.multipart.Part; - import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPost; @@ -234,9 +233,7 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter { try { // Initialise the HTTP client - if (httpclient == null) { - initialise(); - } + initialise(); // Setup request using POST stream with URL and data HttpPost httppost = new HttpPost(buildWebUIUrl() + requestUrl); @@ -304,8 +301,10 @@ public class DLinkRouterBTAdapter implements IDaemonAdapter { * * @throws DaemonException On conflicting or missing settings */ - private void initialise() throws DaemonException { - httpclient = HttpHelper.createStandardHttpClient(settings, true); + private synchronized void initialise() throws DaemonException { + if(httpclient == null) { + httpclient = HttpHelper.createStandardHttpClient(settings, true); + } } /** diff --git a/app/src/main/java/org/transdroid/daemon/adapters/deluge/DelugeAdapter.java b/app/src/main/java/org/transdroid/daemon/adapters/deluge/DelugeAdapter.java index d32bc984..42fdd5b2 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/deluge/DelugeAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/deluge/DelugeAdapter.java @@ -20,7 +20,6 @@ package org.transdroid.daemon.adapters.deluge; import com.android.internal.http.multipart.FilePart; import com.android.internal.http.multipart.MultipartEntity; import com.android.internal.http.multipart.Part; - import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; @@ -163,9 +162,7 @@ public class DelugeAdapter implements IDaemonAdapter { log.d(LOG_NAME, "Uploading a file to the Deluge daemon: " + url); // Initialise the HTTP client - if (httpclient == null) { - initialise(); - } + initialise(); // Setup client using POST HttpPost httppost = new HttpPost(url); @@ -437,9 +434,7 @@ public class DelugeAdapter implements IDaemonAdapter { // We still need to retrieve the version number from the server // Do this by getting the web interface main html page and trying to parse the version number // Format is something like 'Deluge: Web UI 1.3.6' - if (httpclient == null) { - initialise(); - } + initialise(); try { HttpResponse response = httpclient.execute(new HttpGet(buildWebUIUrl() + "/")); String main = HttpHelper.convertStreamToString(response.getEntity().getContent()); @@ -478,9 +473,7 @@ public class DelugeAdapter implements IDaemonAdapter { try { // Initialise the HTTP client - if (httpclient == null) { - initialise(); - } + initialise(); // Login first? if (sessionCookie == null) { @@ -582,11 +575,11 @@ public class DelugeAdapter implements IDaemonAdapter { * @throws DaemonException On missing settings */ private void initialise() throws DaemonException { - - httpclient = HttpHelper.createStandardHttpClient(settings, settings.getUsername() != null && !settings.getUsername().equals("")); - httpclient.addRequestInterceptor(HttpHelper.gzipRequestInterceptor); - httpclient.addResponseInterceptor(HttpHelper.gzipResponseInterceptor); - + if(httpclient == null) { + httpclient = HttpHelper.createStandardHttpClient(settings, settings.getUsername() != null && !settings.getUsername().equals("")); + httpclient.addRequestInterceptor(HttpHelper.gzipRequestInterceptor); + httpclient.addResponseInterceptor(HttpHelper.gzipResponseInterceptor); + } } /** diff --git a/app/src/main/java/org/transdroid/daemon/adapters/kTorrent/KTorrentAdapter.java b/app/src/main/java/org/transdroid/daemon/adapters/kTorrent/KTorrentAdapter.java index 05ea604f..6e2ccbd9 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/kTorrent/KTorrentAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/kTorrent/KTorrentAdapter.java @@ -20,7 +20,6 @@ package org.transdroid.daemon.adapters.kTorrent; import com.android.internal.http.multipart.FilePart; import com.android.internal.http.multipart.MultipartEntity; import com.android.internal.http.multipart.Part; - import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.ProtocolException; @@ -464,12 +463,10 @@ public class KTorrentAdapter implements IDaemonAdapter { * * @throws DaemonException Thrown on settings error */ - private void initialise() throws DaemonException { - - if (httpclient != null) { - httpclient = null; + private synchronized void initialise() throws DaemonException { + if (httpclient == null) { + httpclient = HttpHelper.createStandardHttpClient(settings, false); } - httpclient = HttpHelper.createStandardHttpClient(settings, false); } /** diff --git a/app/src/main/java/org/transdroid/daemon/adapters/qBittorrent/QBittorrentAdapter.java b/app/src/main/java/org/transdroid/daemon/adapters/qBittorrent/QBittorrentAdapter.java index 9d7602d9..51e030d7 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/qBittorrent/QBittorrentAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/qBittorrent/QBittorrentAdapter.java @@ -20,7 +20,6 @@ package org.transdroid.daemon.adapters.qBittorrent; import com.android.internal.http.multipart.FilePart; import com.android.internal.http.multipart.MultipartEntity; import com.android.internal.http.multipart.Part; - import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; @@ -587,7 +586,7 @@ public class QBittorrentAdapter implements IDaemonAdapter { * * @throws DaemonException On conflicting or missing settings */ - private void initialise() throws DaemonException { + private synchronized void initialise() throws DaemonException { if (httpclient == null) { httpclient = HttpHelper.createStandardHttpClient(settings, true); } diff --git a/app/src/main/java/org/transdroid/daemon/adapters/rTorrent/RTorrentAdapter.java b/app/src/main/java/org/transdroid/daemon/adapters/rTorrent/RTorrentAdapter.java index 512c43c4..5205367f 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/rTorrent/RTorrentAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/rTorrent/RTorrentAdapter.java @@ -18,7 +18,9 @@ package org.transdroid.daemon.adapters.rTorrent; import android.text.TextUtils; - +import de.timroes.axmlrpc.XMLRPCClient; +import de.timroes.axmlrpc.XMLRPCClient.UnauthorizdException; +import de.timroes.axmlrpc.XMLRPCException; import org.transdroid.core.gui.log.Log; import org.transdroid.daemon.Daemon; import org.transdroid.daemon.DaemonException; @@ -66,10 +68,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import de.timroes.axmlrpc.XMLRPCClient; -import de.timroes.axmlrpc.XMLRPCClient.UnauthorizdException; -import de.timroes.axmlrpc.XMLRPCException; - /** * An adapter that allows for easy access to rTorrent torrent data. Communication is handled via the XML-RPC protocol as * implemented by the aXMLRPC library. @@ -328,9 +326,7 @@ public class RTorrentAdapter implements IDaemonAdapter { throws DaemonException, MalformedURLException { // Initialise the HTTP client - if (rpcclient == null) { - initialise(); - } + initialise(); StringBuilder paramsBuilder = new StringBuilder(); for (Object arg : arguments) { @@ -365,14 +361,13 @@ public class RTorrentAdapter implements IDaemonAdapter { * Instantiates a XML-RPC client with proper credentials. * * @throws DaemonException On conflicting settings (i.e. user authentication but no password or username provided) - * @throws MalformedURLException Thrown when the URL could not be properly constructed */ - private void initialise() throws DaemonException, MalformedURLException { - - int flags = XMLRPCClient.FLAGS_8BYTE_INT; - this.rpcclient = new XMLRPCClient(HttpHelper.createStandardHttpClient(settings, true), - settings.getAddress(), buildWebUIUrl(), flags); - + private synchronized void initialise() throws DaemonException { + if(rpcclient == null) { + int flags = XMLRPCClient.FLAGS_8BYTE_INT; + this.rpcclient = new XMLRPCClient(HttpHelper.createStandardHttpClient(settings, true), + settings.getAddress(), buildWebUIUrl(), flags); + } } /** diff --git a/app/src/main/java/org/transdroid/daemon/adapters/synology/SynologyAdapter.java b/app/src/main/java/org/transdroid/daemon/adapters/synology/SynologyAdapter.java index 504c15ab..9655d69e 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/synology/SynologyAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/synology/SynologyAdapter.java @@ -20,7 +20,6 @@ package org.transdroid.daemon.adapters.synology; import com.android.internal.http.multipart.FilePart; import com.android.internal.http.multipart.MultipartEntity; import com.android.internal.http.multipart.Part; - import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; @@ -84,10 +83,17 @@ public class SynologyAdapter implements IDaemonAdapter { this.settings = settings; } + private synchronized void initialise() throws DaemonException { + if (httpClient == null) { + httpClient = HttpHelper.createStandardHttpClient(settings, true); + } + } + @Override public DaemonTaskResult executeTask(Log log, DaemonTask task) { String tid; try { + initialise(); switch (task.getMethod()) { case Retrieve: return new RetrieveTaskSuccessResult((RetrieveTask) task, tasksList(log), null); @@ -425,13 +431,6 @@ public class SynologyAdapter implements IDaemonAdapter { return new SynoRequest(path, api, version).post(sid, params); } - private DefaultHttpClient getHttpClient() throws DaemonException { - if (httpClient == null) { - httpClient = HttpHelper.createStandardHttpClient(settings, true); - } - return httpClient; - } - private static class SynoResponse { private final HttpResponse response; @@ -502,7 +501,7 @@ public class SynologyAdapter implements IDaemonAdapter { public SynoResponse get(String params) throws DaemonException { try { - return new SynoResponse(getHttpClient().execute(new HttpGet(buildURL(params)))); + return new SynoResponse(httpClient.execute(new HttpGet(buildURL(params)))); } catch (IOException e) { throw new DaemonException(ExceptionType.ConnectionError, e.toString()); } @@ -523,7 +522,7 @@ public class SynologyAdapter implements IDaemonAdapter { System.arraycopy(params, 0, allParams, baseParams.length, params.length); request.setEntity(new MultipartEntity(allParams)); - return new SynoResponse(getHttpClient().execute(request)); + return new SynoResponse(httpClient.execute(request)); } catch (IOException e) { throw new DaemonException(ExceptionType.ConnectionError, e.toString()); } diff --git a/app/src/main/java/org/transdroid/daemon/adapters/tTorrent/TTorrentAdapter.java b/app/src/main/java/org/transdroid/daemon/adapters/tTorrent/TTorrentAdapter.java index 1c573a77..4ab2bc77 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/tTorrent/TTorrentAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/tTorrent/TTorrentAdapter.java @@ -20,7 +20,6 @@ package org.transdroid.daemon.adapters.tTorrent; import com.android.internal.http.multipart.FilePart; import com.android.internal.http.multipart.MultipartEntity; import com.android.internal.http.multipart.Part; - import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; @@ -233,9 +232,7 @@ public class TTorrentAdapter implements IDaemonAdapter { try { // Initialise the HTTP client - if (httpclient == null) { - initialise(); - } + initialise(); // Execute HttpResponse response = httpclient.execute(httppost); @@ -267,8 +264,10 @@ public class TTorrentAdapter implements IDaemonAdapter { * * @throws DaemonException On conflicting or missing settings */ - private void initialise() throws DaemonException { - httpclient = HttpHelper.createStandardHttpClient(settings, true); + private synchronized void initialise() throws DaemonException { + if(httpclient == null) { + httpclient = HttpHelper.createStandardHttpClient(settings, true); + } } /** diff --git a/app/src/main/java/org/transdroid/daemon/adapters/tfb4rt/Tfb4rtAdapter.java b/app/src/main/java/org/transdroid/daemon/adapters/tfb4rt/Tfb4rtAdapter.java index 02c9ed79..f1326e82 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/tfb4rt/Tfb4rtAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/tfb4rt/Tfb4rtAdapter.java @@ -20,7 +20,6 @@ package org.transdroid.daemon.adapters.tfb4rt; import com.android.internal.http.multipart.FilePart; import com.android.internal.http.multipart.MultipartEntity; import com.android.internal.http.multipart.Part; - import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; @@ -176,9 +175,7 @@ public class Tfb4rtAdapter implements IDaemonAdapter { try { // Initialise the HTTP client - if (httpclient == null) { - initialise(); - } + initialise(); // Make request HttpGet httpget = new HttpGet(buildWebUIUrl(RPC_URL_STATS)); @@ -205,9 +202,7 @@ public class Tfb4rtAdapter implements IDaemonAdapter { try { // Initialise the HTTP client - if (httpclient == null) { - initialise(); - } + initialise(); // Make request HttpGet httpget = new HttpGet(buildWebUIUrl(RPC_URL_DISPATCH + action + RPC_URL_DISPATCH2 + RPC_URL_AID @@ -239,9 +234,7 @@ public class Tfb4rtAdapter implements IDaemonAdapter { try { // Initialise the HTTP client - if (httpclient == null) { - initialise(); - } + initialise(); // Make request HttpPost httppost = new HttpPost(buildWebUIUrl(RPC_URL_DISPATCH + action + RPC_URL_DISPATCH2 + RPC_URL_AID)); @@ -276,8 +269,10 @@ public class Tfb4rtAdapter implements IDaemonAdapter { * * @throws DaemonException On conflicting or missing settings */ - private void initialise() throws DaemonException { - httpclient = HttpHelper.createStandardHttpClient(settings, true); + private synchronized void initialise() throws DaemonException { + if(httpclient == null) { + httpclient = HttpHelper.createStandardHttpClient(settings, true); + } } /** diff --git a/app/src/main/java/org/transdroid/daemon/adapters/transmission/TransmissionAdapter.java b/app/src/main/java/org/transdroid/daemon/adapters/transmission/TransmissionAdapter.java index b03ef3d7..ca630802 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/transmission/TransmissionAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/transmission/TransmissionAdapter.java @@ -19,7 +19,6 @@ package org.transdroid.daemon.adapters.transmission; import net.iharder.Base64; import net.iharder.Base64.InputStream; - import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPost; @@ -403,9 +402,7 @@ public class TransmissionAdapter implements IDaemonAdapter { try { // Initialise the HTTP client - if (httpclient == null) { - initialise(); - } + initialise(); final String sessionHeader = "X-Transmission-Session-Id"; // Setup request using POST stream with URL and data @@ -477,8 +474,10 @@ public class TransmissionAdapter implements IDaemonAdapter { * * @throws DaemonException On conflicting or missing settings */ - private void initialise() throws DaemonException { - httpclient = HttpHelper.createStandardHttpClient(settings, true); + private synchronized void initialise() throws DaemonException { + if(httpclient == null) { + httpclient = HttpHelper.createStandardHttpClient(settings, true); + } } /** diff --git a/app/src/main/java/org/transdroid/daemon/adapters/uTorrent/UTorrentAdapter.java b/app/src/main/java/org/transdroid/daemon/adapters/uTorrent/UTorrentAdapter.java index 2d9e203d..e2c24237 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/uTorrent/UTorrentAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/uTorrent/UTorrentAdapter.java @@ -20,12 +20,9 @@ package org.transdroid.daemon.adapters.uTorrent; import com.android.internal.http.multipart.FilePart; import com.android.internal.http.multipart.MultipartEntity; import com.android.internal.http.multipart.Part; - import org.apache.http.HttpResponse; -import org.apache.http.client.CookieStore; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONArray; import org.json.JSONException; @@ -117,12 +114,10 @@ public class UTorrentAdapter implements IDaemonAdapter, RemoteRssSupplier { private static final int RPC_FILESIZE_IDX = 1; private static final int RPC_FILEDOWNLOADED_IDX = 2; private static final int RPC_FILEPRIORITY_IDX = 3; - private static String authtoken; + private String authtoken; private static ArrayList remoteRssChannels = new ArrayList<>(); private DaemonSettings settings; private DefaultHttpClient httpclient; - private static CookieStore cookieStore; - /** * Initialises an adapter that provides operations to the uTorrent web daemon @@ -368,11 +363,8 @@ public class UTorrentAdapter implements IDaemonAdapter, RemoteRssSupplier { try { // Initialise the HTTP client - if (httpclient == null) { - initialise(); - } - - ensureToken(); + initialise(); + ensureToken(retried > 0); // Make request HttpGet httpget = new HttpGet(buildWebUIUrl() + "?token=" + authtoken + addToUrl); @@ -383,7 +375,6 @@ public class UTorrentAdapter implements IDaemonAdapter, RemoteRssSupplier { String result = HttpHelper.convertStreamToString(instream); if ((result.equals("") || result.trim().equals("invalid request"))) { // Auth token was invalidated; retry at max 3 times - authtoken = null; // So that ensureToken() will request a new token on the next try if (retried < 2) { return makeUtorrentRequest(log, addToUrl, ++retried); } @@ -407,10 +398,10 @@ public class UTorrentAdapter implements IDaemonAdapter, RemoteRssSupplier { } - private synchronized void ensureToken() throws IOException, DaemonException { + private synchronized void ensureToken(boolean forceReload) throws IOException, DaemonException { - // Make sure we have a valid token - if (authtoken == null) { + // Make sure we have a valid token or we're regenerating it + if (authtoken == null || forceReload) { // Make a request to /gui/token.html // See https://github.com/bittorrent/webui/wiki/TokenSystem @@ -437,11 +428,8 @@ public class UTorrentAdapter implements IDaemonAdapter, RemoteRssSupplier { public JSONObject uploadTorrentFile(String file) throws DaemonException, IOException, JSONException { // Initialise the HTTP client - if (httpclient == null) { - initialise(); - } - - ensureToken(); + initialise(); + ensureToken(false); // Build and make request HttpPost httppost = new HttpPost(buildWebUIUrl() + "?token=" + authtoken + "&action=add-file"); @@ -464,13 +452,10 @@ public class UTorrentAdapter implements IDaemonAdapter, RemoteRssSupplier { * * @throws DaemonException On conflicting or missing settings */ - private void initialise() throws DaemonException { - if (this.cookieStore == null) { - this.cookieStore = new BasicCookieStore(); + private synchronized void initialise() throws DaemonException { + if(httpclient == null) { + httpclient = HttpHelper.createStandardHttpClient(settings, true); } - - this.httpclient = HttpHelper.createStandardHttpClient(settings, true); - this.httpclient.setCookieStore(this.cookieStore); } /** diff --git a/app/src/main/java/org/transdroid/daemon/adapters/vuze/VuzeAdapter.java b/app/src/main/java/org/transdroid/daemon/adapters/vuze/VuzeAdapter.java index 561afdb4..9207aa07 100644 --- a/app/src/main/java/org/transdroid/daemon/adapters/vuze/VuzeAdapter.java +++ b/app/src/main/java/org/transdroid/daemon/adapters/vuze/VuzeAdapter.java @@ -226,9 +226,7 @@ public class VuzeAdapter implements IDaemonAdapter { // TODO: It would be nicer to now split each of these steps into separate makeVuzeCalls when there are multiple logical steps such as stopping a torrent before removing it // Initialise the HTTP client - if (rpcclient == null) { - initialise(); - } + initialise(); if (settings.getAddress() == null || settings.getAddress().equals("")) { throw new DaemonException(DaemonException.ExceptionType.AuthenticationFailure, "No host name specified."); } @@ -329,10 +327,10 @@ public class VuzeAdapter implements IDaemonAdapter { * * @throws DaemonException On conflicting settings (i.e. user authentication but no password or username provided) */ - private void initialise() throws DaemonException { - - this.rpcclient = new VuzeXmlOverHttpClient(settings, buildWebUIUrl()); - + private synchronized void initialise() throws DaemonException { + if(rpcclient == null) { + rpcclient = new VuzeXmlOverHttpClient(settings, buildWebUIUrl()); + } } /**