|
|
|
/*
|
|
|
|
* 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 android.widget.RemoteViews;
|
|
|
|
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
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(),
|
|
|
|
config.shouldUseDarkTheme() ? R.layout.widget_torrents_dark : 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 | PendingIntent.FLAG_IMMUTABLE));
|
|
|
|
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 | PendingIntent.FLAG_IMMUTABLE));
|
|
|
|
rv.setOnClickPendingIntent(R.id.navigation_view, PendingIntent.getActivity(context, appWidgetId, start,
|
|
|
|
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE));
|
|
|
|
|
|
|
|
// 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 | PendingIntent.FLAG_IMMUTABLE));
|
|
|
|
|
|
|
|
// 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 | PendingIntent.FLAG_IMMUTABLE));
|
|
|
|
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 | PendingIntent.FLAG_IMMUTABLE));
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|