/* * Copyright 2010-2018 Eric Kok et al. * * 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.core.gui; import android.annotation.TargetApi; import android.app.SearchManager; import android.content.ContentResolver; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.core.view.MenuItemCompat; import androidx.drawerlayout.widget.DrawerLayout; import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.ActionMenuView; import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; 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; import org.androidannotations.annotations.Click; import org.androidannotations.annotations.EActivity; import org.androidannotations.annotations.FragmentById; import org.androidannotations.annotations.InstanceState; import org.androidannotations.annotations.OnActivityResult; import org.androidannotations.annotations.OptionsItem; import org.androidannotations.annotations.SystemService; import org.androidannotations.annotations.UiThread; import org.androidannotations.annotations.ViewById; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.cookie.BasicClientCookie; import org.transdroid.R; import org.transdroid.core.app.search.SearchHelper_; import org.transdroid.core.app.settings.ApplicationSettings; import org.transdroid.core.app.settings.ServerSetting; import org.transdroid.core.app.settings.SettingsUtils; import org.transdroid.core.app.settings.SystemSettings; import org.transdroid.core.app.settings.WebsearchSetting; import org.transdroid.core.gui.lists.LocalTorrent; import org.transdroid.core.gui.lists.SimpleListItem; import org.transdroid.core.gui.log.Log; import org.transdroid.core.gui.log.LogUncaughtExceptionHandler; import org.transdroid.core.gui.navigation.FilterListAdapter; import org.transdroid.core.gui.navigation.FilterListAdapter_; import org.transdroid.core.gui.navigation.Label; import org.transdroid.core.gui.navigation.NavigationFilter; import org.transdroid.core.gui.navigation.NavigationHelper; import org.transdroid.core.gui.navigation.RefreshableActivity; import org.transdroid.core.gui.navigation.StatusType; import org.transdroid.core.gui.rss.RssFeedsActivity_; import org.transdroid.core.gui.search.FilePickerHelper; import org.transdroid.core.gui.search.UrlEntryDialog; import org.transdroid.core.gui.settings.MainSettingsActivity_; import org.transdroid.core.service.*; import org.transdroid.core.widget.ListWidgetProvider; import org.transdroid.daemon.Daemon; import org.transdroid.daemon.DaemonException; import org.transdroid.daemon.IDaemonAdapter; import org.transdroid.daemon.Priority; import org.transdroid.daemon.Torrent; import org.transdroid.daemon.TorrentDetails; import org.transdroid.daemon.TorrentFile; import org.transdroid.daemon.TorrentsSortBy; import org.transdroid.daemon.task.AddByFileTask; import org.transdroid.daemon.task.AddByMagnetUrlTask; import org.transdroid.daemon.task.AddByUrlTask; import org.transdroid.daemon.task.DaemonTaskFailureResult; import org.transdroid.daemon.task.DaemonTaskResult; import org.transdroid.daemon.task.DaemonTaskSuccessResult; import org.transdroid.daemon.task.ToggleSequentialDownloadTask; import org.transdroid.daemon.task.ToggleFirstLastPieceDownloadTask; import org.transdroid.daemon.task.ForceRecheckTask; import org.transdroid.daemon.task.GetFileListTask; import org.transdroid.daemon.task.GetFileListTaskSuccessResult; import org.transdroid.daemon.task.GetStatsTask; import org.transdroid.daemon.task.GetStatsTaskSuccessResult; import org.transdroid.daemon.task.GetTorrentDetailsTask; import org.transdroid.daemon.task.GetTorrentDetailsTaskSuccessResult; import org.transdroid.daemon.task.PauseTask; import org.transdroid.daemon.task.RemoveTask; import org.transdroid.daemon.task.ResumeTask; import org.transdroid.daemon.task.RetrieveTask; import org.transdroid.daemon.task.RetrieveTaskSuccessResult; import org.transdroid.daemon.task.SetAlternativeModeTask; import org.transdroid.daemon.task.SetDownloadLocationTask; import org.transdroid.daemon.task.SetFilePriorityTask; import org.transdroid.daemon.task.SetLabelTask; import org.transdroid.daemon.task.SetTrackersTask; import org.transdroid.daemon.task.SetTransferRatesTask; import org.transdroid.daemon.task.StartTask; import org.transdroid.daemon.task.StopTask; import org.transdroid.daemon.util.HttpHelper; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; /** * Main activity that holds the fragment that shows the torrents list, presents a way to filter the list (via an action bar spinner or list side list) * and potentially shows a torrent details fragment too, if there is room. Task execution such as loading of and adding torrents is performs in this * activity, using background methods. Finally, the activity offers navigation elements such as access to settings and showing connection issues. * @author Eric Kok */ @EActivity(R.layout.activity_torrents) public class TorrentsActivity extends AppCompatActivity implements TorrentTasksExecutor, RefreshableActivity { private static final int RESULT_DETAILS = 0; // Fragment uses this to pause the refresh across restarts public boolean stopRefresh = false; // Navigation components @SystemService protected SearchManager searchManager; @Bean protected Log log; @Bean protected NavigationHelper navigationHelper; @Bean protected ConnectivityHelper connectivityHelper; @ViewById protected Toolbar selectionToolbar; @ViewById protected Toolbar torrentsToolbar; @ViewById protected Toolbar actionsToolbar; @ViewById(R.id.contextual_menu) protected ActionMenuView contextualMenu; @ViewById protected FloatingActionsMenu addmenuButton; @ViewById protected FloatingActionButton addmenuFileButton; @ViewById protected DrawerLayout drawerLayout; @ViewById(R.id.drawer_container) protected ViewGroup drawerContainer; @ViewById protected ListView drawerList; @ViewById protected ListView filtersList; @ViewById protected SearchView filterSearch; private ListView navigationList; private FilterListAdapter navigationListAdapter; private ServerSelectionView serverSelectionView; private ServerStatusView serverStatusView; private ActionBarDrawerToggle drawerToggle; // Settings @Bean protected ApplicationSettings applicationSettings; @Bean protected SystemSettings systemSettings; @InstanceState protected NavigationFilter currentFilter = null; @InstanceState protected String preselectNavigationFilter = null; @InstanceState protected boolean turtleModeEnabled = false; @InstanceState protected ArrayList