diff --git a/app/src/main/java/org/fdroid/fdroid/UpdateService.java b/app/src/main/java/org/fdroid/fdroid/UpdateService.java index 2a8ee528c..b30cbc13d 100644 --- a/app/src/main/java/org/fdroid/fdroid/UpdateService.java +++ b/app/src/main/java/org/fdroid/fdroid/UpdateService.java @@ -27,6 +27,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; +import android.os.AsyncTask; import android.os.Build; import android.os.Handler; import android.os.Looper; @@ -51,6 +52,7 @@ import org.fdroid.fdroid.net.BluetoothDownloader; import org.fdroid.fdroid.net.ConnectivityMonitorService; import org.fdroid.fdroid.views.main.MainActivity; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; @@ -147,6 +149,51 @@ public class UpdateService extends IntentService { return updating; } + private static volatile boolean isScheduleIfStillOnWifiRunning; + + /** + * Waits for a period of time for the WiFi to settle, then if the WiFi is + * still active, it schedules an update. This is to encourage the use of + * unlimited networks over metered networks for index updates and auto + * downloads of app updates. Starting with {@code android-21}, this uses + * {@link android.app.job.JobScheduler} instead. + */ + public static void scheduleIfStillOnWifi(Context context) { + if (Build.VERSION.SDK_INT >= 21) { + throw new IllegalStateException("This should never be used on android-21 or newer!"); + } + if (isScheduleIfStillOnWifiRunning || !Preferences.get().isBackgroundDownloadAllowed()) { + return; + } + isScheduleIfStillOnWifiRunning = true; + new StillOnWifiAsyncTask(context).execute(); + } + + private static final class StillOnWifiAsyncTask extends AsyncTask { + + private final WeakReference contextWeakReference; + + private StillOnWifiAsyncTask(Context context) { + this.contextWeakReference = new WeakReference<>(context); + } + + @Override + protected Void doInBackground(Void... voids) { + Context context = contextWeakReference.get(); + try { + Thread.sleep(120000); + if (Preferences.get().isBackgroundDownloadAllowed()) { + Utils.debugLog(TAG, "scheduling update because there is good internet"); + schedule(context); + } + } catch (Exception e) { + Utils.debugLog(TAG, e.getMessage()); + } + isScheduleIfStillOnWifiRunning = false; + return null; + } + } + @Override public void onCreate() { super.onCreate(); diff --git a/app/src/main/java/org/fdroid/fdroid/net/WifiStateChangeService.java b/app/src/main/java/org/fdroid/fdroid/net/WifiStateChangeService.java index c4280c3cc..cdc99524f 100644 --- a/app/src/main/java/org/fdroid/fdroid/net/WifiStateChangeService.java +++ b/app/src/main/java/org/fdroid/fdroid/net/WifiStateChangeService.java @@ -8,6 +8,7 @@ import android.net.DhcpInfo; import android.net.NetworkInfo; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; +import android.os.Build; import android.support.annotation.Nullable; import android.support.v4.content.LocalBroadcastManager; import android.text.TextUtils; @@ -15,6 +16,7 @@ import android.util.Log; import org.apache.commons.net.util.SubnetUtils; import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.Preferences; +import org.fdroid.fdroid.UpdateService; import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.Repo; import org.fdroid.fdroid.localrepo.LocalRepoKeyStore; @@ -42,6 +44,11 @@ import java.util.Locale; * changed. Having the {@code Thread} also makes it easy to kill work * that is in progress. *

+ * This also schedules an update to encourage updates happening on + * unmetered networks like typical WiFi rather than networks that can + * cost money or have caps. The logic for checking the state of the + * internet connection is in {@link org.fdroid.fdroid.UpdateService#onHandleIntent(Intent)} + *

* Some devices send multiple copies of given events, like a Moto G often * sends three {@code CONNECTED} events. So they have to be debounced to * keep the {@link #BROADCAST} useful. @@ -92,6 +99,10 @@ public class WifiStateChangeService extends IntentService { wifiInfoThread = new WifiInfoThread(); wifiInfoThread.start(); } + + if (Build.VERSION.SDK_INT < 21 && wifiState == WifiManager.WIFI_STATE_ENABLED) { + UpdateService.scheduleIfStillOnWifi(this); + } } }