Manage your torrents from your Android device
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
8.5 KiB

/*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.transdroid.core.widget;
import android.annotation.TargetApi;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import androidx.annotation.NonNull;
import android.widget.RemoteViews;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EReceiver;
import org.transdroid.R;
import org.transdroid.core.app.settings.ApplicationSettings;
import org.transdroid.core.app.settings.ApplicationSettings_;
import org.transdroid.core.app.settings.ServerSetting;
import org.transdroid.core.gui.TorrentsActivity_;
import org.transdroid.core.gui.log.Log_;
import org.transdroid.core.service.ControlService;
import org.transdroid.core.service.ControlService_;
/**
* The provider of a list-style Transdroid widget, which controls the general loading and (touch) event handling. The list rows' remote views are
* loaded in the accompanying {@link ListWidgetViewsService}.
* @author Eric Kok
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@EReceiver
public class ListWidgetProvider extends AppWidgetProvider {
public static final String INTENT_STARTSERVER = "org.transdroid.START_SERVER";
public static final String EXTRA_TORRENT = "extra_torrent";
public static final String EXTRA_SERVER = "extra_server";
public static final String EXTRA_REFRESH = "extra_refresh";
@Bean
protected ApplicationSettings applicationSettings;
/**
* Loads and sets up the layout for some specific app widget given the user's widget settings. Note that the views for the list view rows are
* loaded separately in the {@link WidgetViewsFactory}.
* @param context The app widget context, with access to resources
* @param appWidgetId The specific ID of the app widget to load
* @param config The user widget configuration, with filter and theme preferences
* @return A fully initialised set of remote views to update the widget with the AppWidgetManager
*/
@SuppressWarnings("deprecation")
public static RemoteViews buildRemoteViews(Context context, int appWidgetId, ListWidgetConfig config) {
// Does the server to show and its widget settings actually still exist?
if (context == null || config == null) {
return null;
}
ApplicationSettings appSettings = ApplicationSettings_.getInstance_(context);
if (config.getServerId() < 0 || config.getServerId() > appSettings.getMaxOfAllServers()) {
Log_.getInstance_(context)
.e("ListWidgetProvider", "Tried to set up widget " + appWidgetId + " but the bound server ID " + config.getServerId() +
" no longer exists.");
return null;
}
// Load the dark or light widget layout xml
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_torrents);
// Set up the widget's list view loading service which refers to the WidgetViewsFactory
Intent data = new Intent(context, ListWidgetViewsService_.class);
data.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
data.setData(Uri.parse(data.toUri(Intent.URI_INTENT_SCHEME)));
rv.setRemoteAdapter(appWidgetId, R.id.torrents_list, data);
Intent open = new Intent(context, TorrentsActivity_.class);
open.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
rv.setPendingIntentTemplate(R.id.torrents_list, PendingIntent.getActivity(context, appWidgetId, open, PendingIntent.FLAG_UPDATE_CURRENT));
rv.setEmptyView(R.id.torrents_list, R.id.error_text);
rv.setTextViewText(R.id.error_text, context.getString(R.string.widget_loading));
// Show the server and status type filter from the widget configuration in the 'action bar'
// NOTE: The ListWidgetViewsService will eventually decide to show these labels or the server status statistics
ServerSetting server = appSettings.getServerSetting(config.getServerId());
rv.setTextViewText(R.id.server_text, server.getName());
rv.setTextViewText(R.id.filter_text, config.getStatusType().getFilterItem(context).getName());
// Set up the START_SERVER intent for 'action bar' clicks to start Transdroid normally
Intent start = new Intent(context, TorrentsActivity_.class);
// start.setData(Uri.parse("intent://widget/" + appWidgetId + "/start/" + config.getServerId()));
start.setAction(INTENT_STARTSERVER);
start.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
start.putExtra(EXTRA_SERVER, config.getServerId());
rv.setOnClickPendingIntent(R.id.icon_image, PendingIntent.getActivity(context, appWidgetId, start, PendingIntent.FLAG_UPDATE_CURRENT));
rv.setOnClickPendingIntent(R.id.navigation_view, PendingIntent.getActivity(context, appWidgetId, start, PendingIntent.FLAG_UPDATE_CURRENT));
// Set up the widgets refresh button pending intent (calling this WidgetProvider itself)
// Make sure that the intent is unique using a custom data path (rather than just the extras)
Intent refresh = new Intent(context, ListWidgetProvider_.class);
refresh.setData(Uri.parse("intent://widget/" + appWidgetId + "/refresh"));
refresh.putExtra(EXTRA_REFRESH, appWidgetId);
refresh.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
rv.setOnClickPendingIntent(R.id.refresh_button, PendingIntent.getBroadcast(context, appWidgetId, refresh, PendingIntent.FLAG_UPDATE_CURRENT));
// Set up the control (pause and resume) buttons (calling the WidgetProvider itself)
Intent pauseall = new Intent(context, ListWidgetProvider_.class);
pauseall.setData(Uri.parse("intent://widget/" + appWidgetId + "/pauseall"));
pauseall.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
pauseall.setAction(ControlService.INTENT_PAUSEALL);
rv.setOnClickPendingIntent(R.id.pauseall_button,
PendingIntent.getBroadcast(context, appWidgetId, pauseall, PendingIntent.FLAG_UPDATE_CURRENT));
Intent resumeall = new Intent(context, ListWidgetProvider_.class);
resumeall.setData(Uri.parse("intent://widget/" + appWidgetId + "/resumeall"));
resumeall.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
resumeall.setAction(ControlService.INTENT_RESUMEALL);
rv.setOnClickPendingIntent(R.id.resumeall_button,
PendingIntent.getBroadcast(context, appWidgetId, resumeall, PendingIntent.FLAG_UPDATE_CURRENT));
return rv;
}
@Override
public void onReceive(Context context, @NonNull Intent intent) {
super.onReceive(context, intent);
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
// Refresh a specific app widget
if (intent.hasExtra(EXTRA_REFRESH)) {
// Manually requested a refresh for the app widget of which the ID was supplied
RemoteViews views = buildRemoteViews(context, appWidgetId, applicationSettings.getWidgetConfig(appWidgetId));
if (views != null) {
AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId, views);
AppWidgetManager.getInstance(context).notifyAppWidgetViewDataChanged(appWidgetId, R.id.torrents_list);
}
return;
}
// No refresh: this is a control intent: copy the action and EXTRA_APPWIDGET_ID to start the control service
if (intent.getAction().startsWith("org.transdroid.control.")) {
Intent action = new Intent(context, ControlService_.class);
action.setAction(intent.getAction());
action.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
context.startService(action);
}
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
appWidgetManager.updateAppWidget(appWidgetId, buildRemoteViews(context, appWidgetId, applicationSettings.getWidgetConfig(appWidgetId)));
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.torrents_list);
}
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
applicationSettings.removeWidgetConfig(appWidgetId);
}
}
}