From 2c6ed51a35ccdf644f438c406983c209aadcedb2 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 5 Apr 2018 23:24:39 +0200 Subject: [PATCH 1/7] fix last long lines in UpdateService --- .../main/java/org/fdroid/fdroid/UpdateService.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/UpdateService.java b/app/src/main/java/org/fdroid/fdroid/UpdateService.java index 5b233046f..1b3e4357c 100644 --- a/app/src/main/java/org/fdroid/fdroid/UpdateService.java +++ b/app/src/main/java/org/fdroid/fdroid/UpdateService.java @@ -178,7 +178,8 @@ public class UpdateService extends IntentService { if (Build.VERSION.SDK_INT <= 10) { Intent pendingIntent = new Intent(this, MainActivity.class); pendingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - notificationBuilder.setContentIntent(PendingIntent.getActivity(this, 0, pendingIntent, PendingIntent.FLAG_UPDATE_CURRENT)); + notificationBuilder.setContentIntent( + PendingIntent.getActivity(this, 0, pendingIntent, PendingIntent.FLAG_UPDATE_CURRENT)); } } @@ -526,11 +527,13 @@ public class UpdateService extends IntentService { } String message; if (totalBytes == -1) { - message = context.getString(R.string.status_download_unknown_size, updater.indexUrl, downloadedSizeFriendly); + message = context.getString(R.string.status_download_unknown_size, + updater.indexUrl, downloadedSizeFriendly); percent = -1; } else { String totalSizeFriendly = Utils.getFriendlySize(totalBytes); - message = context.getString(R.string.status_download, updater.indexUrl, downloadedSizeFriendly, totalSizeFriendly, percent); + message = context.getString(R.string.status_download, + updater.indexUrl, downloadedSizeFriendly, totalSizeFriendly, percent); } sendStatus(context, STATUS_INFO, message, percent); } @@ -544,7 +547,8 @@ public class UpdateService extends IntentService { if (totalBytes > 0) { percent = (int) (bytesRead / (totalBytes * 100L)); } - String message = context.getString(R.string.status_processing_xml_percent, updater.indexUrl, downloadedSize, totalSize, percent); + String message = context.getString(R.string.status_processing_xml_percent, + updater.indexUrl, downloadedSize, totalSize, percent); sendStatus(context, STATUS_INFO, message, percent); } From 688057b3e7e214db49566b84d5b3dcd0db30dc2b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 5 Apr 2018 23:28:49 +0200 Subject: [PATCH 2/7] fix some progress vars that were still int rather than long This completes the work started in 195aaae7e52dc1c47741965904ed17bdc816a71c closes #1395 closes #1400 # Conflicts: # app/src/main/java/org/fdroid/fdroid/UpdateService.java --- .../fdroid/fdroid/AppUpdateStatusManager.java | 14 +++++----- .../org/fdroid/fdroid/NotificationHelper.java | 3 ++- .../java/org/fdroid/fdroid/UpdateService.java | 27 ++++++++++--------- .../main/java/org/fdroid/fdroid/Utils.java | 21 +++++++++++++++ .../installer/InstallManagerService.java | 8 +++--- .../views/AppDetailsRecyclerViewAdapter.java | 21 +++++++-------- .../views/apps/AppListItemController.java | 3 ++- .../fdroid/views/swap/SwapAppsView.java | 7 +++-- 8 files changed, 64 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java index 22d9590b0..a270ee4d6 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java +++ b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java @@ -115,8 +115,8 @@ public final class AppUpdateStatusManager { public final Apk apk; public Status status; public PendingIntent intent; - public int progressCurrent; - public int progressMax; + public long progressCurrent; + public long progressMax; public String errorText; AppUpdateStatus(App app, Apk apk, Status status, PendingIntent intent) { @@ -143,8 +143,8 @@ public final class AppUpdateStatusManager { apk = in.readParcelable(getClass().getClassLoader()); intent = in.readParcelable(getClass().getClassLoader()); status = (Status) in.readSerializable(); - progressCurrent = in.readInt(); - progressMax = in.readInt(); + progressCurrent = in.readLong(); + progressMax = in.readLong(); errorText = in.readString(); } @@ -154,8 +154,8 @@ public final class AppUpdateStatusManager { dest.writeParcelable(apk, 0); dest.writeParcelable(intent, 0); dest.writeSerializable(status); - dest.writeInt(progressCurrent); - dest.writeInt(progressMax); + dest.writeLong(progressCurrent); + dest.writeLong(progressMax); dest.writeString(errorText); } @@ -391,7 +391,7 @@ public final class AppUpdateStatusManager { } } - public void updateApkProgress(String key, int max, int current) { + public void updateApkProgress(String key, long max, long current) { synchronized (appMapping) { AppUpdateStatus entry = appMapping.get(key); if (entry != null) { diff --git a/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java b/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java index 927b5626b..653f5fbba 100644 --- a/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java @@ -327,7 +327,8 @@ class NotificationHelper { if (entry.progressMax == 0) { builder.setProgress(100, 0, true); } else { - builder.setProgress(entry.progressMax, entry.progressCurrent, false); + builder.setProgress(Utils.bytesToKb(entry.progressMax), + Utils.bytesToKb(entry.progressCurrent), false); } } else if (status == AppUpdateStatusManager.Status.Installing) { builder.setProgress(100, 0, true); // indeterminate bar diff --git a/app/src/main/java/org/fdroid/fdroid/UpdateService.java b/app/src/main/java/org/fdroid/fdroid/UpdateService.java index 1b3e4357c..0cb2c00ad 100644 --- a/app/src/main/java/org/fdroid/fdroid/UpdateService.java +++ b/app/src/main/java/org/fdroid/fdroid/UpdateService.java @@ -54,7 +54,6 @@ import org.fdroid.fdroid.views.main.MainActivity; import java.util.ArrayList; import java.util.List; -@SuppressWarnings("LineLength") public class UpdateService extends IntentService { private static final String TAG = "UpdateService"; @@ -239,7 +238,7 @@ public class UpdateService extends IntentService { case STATUS_INFO: notificationBuilder.setContentText(message) .setCategory(NotificationCompat.CATEGORY_SERVICE); - if (progress != -1) { + if (progress > -1) { notificationBuilder.setProgress(100, progress, false); } else { notificationBuilder.setProgress(100, 0, true); @@ -449,7 +448,7 @@ public class UpdateService extends IntentService { } if (!changes) { - Utils.debugLog(TAG, "Not checking app details or compatibility, because all repos were up to date."); + Utils.debugLog(TAG, "Not checking app details or compatibility, because repos were up to date."); } else { notifyContentProviders(); @@ -523,7 +522,7 @@ public class UpdateService extends IntentService { String downloadedSizeFriendly = Utils.getFriendlySize(bytesRead); int percent = -1; if (totalBytes > 0) { - percent = (int) (bytesRead / (totalBytes * 100L)); + percent = Utils.getPercent(bytesRead, totalBytes); } String message; if (totalBytes == -1) { @@ -545,7 +544,7 @@ public class UpdateService extends IntentService { String totalSize = Utils.getFriendlySize(totalBytes); int percent = -1; if (totalBytes > 0) { - percent = (int) (bytesRead / (totalBytes * 100L)); + percent = Utils.getPercent(bytesRead, totalBytes); } String message = context.getString(R.string.status_processing_xml_percent, updater.indexUrl, downloadedSize, totalSize, percent); @@ -553,16 +552,20 @@ public class UpdateService extends IntentService { } /** - * If an updater is unable to know how many apps it has to process (i.e. it is streaming apps to the database or - * performing a large database query which touches all apps, but is unable to report progress), then it call this - * listener with `totalBytes = 0`. Doing so will result in a message of "Saving app details" sent to the user. If - * you know how many apps you have processed, then a message of "Saving app details (x/total)" is displayed. + * If an updater is unable to know how many apps it has to process (i.e. it + * is streaming apps to the database or performing a large database query + * which touches all apps, but is unable to report progress), then it call + * this listener with `totalBytes = 0`. Doing so will result in a message of + * "Saving app details" sent to the user. If you know how many apps you have + * processed, then a message of "Saving app details (x/total)" is displayed. */ - public static void reportProcessingAppsProgress(Context context, RepoUpdater updater, int appsSaved, int totalApps) { + public static void reportProcessingAppsProgress(Context context, RepoUpdater updater, + int appsSaved, int totalApps) { Utils.debugLog(TAG, "Committing " + updater.indexUrl + "(" + appsSaved + "/" + totalApps + ")"); if (totalApps > 0) { - String message = context.getString(R.string.status_inserting_x_apps, appsSaved, totalApps, updater.indexUrl); - sendStatus(context, STATUS_INFO, message, (int) ((double) appsSaved / totalApps * 100)); + String message = context.getString(R.string.status_inserting_x_apps, + appsSaved, totalApps, updater.indexUrl); + sendStatus(context, STATUS_INFO, message, Utils.getPercent(appsSaved, totalApps)); } else { String message = context.getString(R.string.status_inserting_apps); sendStatus(context, STATUS_INFO, message); diff --git a/app/src/main/java/org/fdroid/fdroid/Utils.java b/app/src/main/java/org/fdroid/fdroid/Utils.java index c9a5258c8..682135a18 100644 --- a/app/src/main/java/org/fdroid/fdroid/Utils.java +++ b/app/src/main/java/org/fdroid/fdroid/Utils.java @@ -693,6 +693,27 @@ public final class Utils { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()); } + /** + * Converts a {@code long} bytes value, like from {@link File#length()}, to + * an {@code int} value that is kilobytes, suitable for things like + * {@link android.widget.ProgressBar#setMax(int)} or + * {@link android.support.v4.app.NotificationCompat.Builder#setProgress(int, int, boolean)} + */ + public static int bytesToKb(long bytes) { + return (int) (bytes / 1024); + } + + /** + * Converts two {@code long} bytes values, like from {@link File#length()}, to + * an {@code int} value that is a percentage, suitable for things like + * {@link android.widget.ProgressBar#setMax(int)} or + * {@link android.support.v4.app.NotificationCompat.Builder#setProgress(int, int, boolean)}. + * {@code total} must never be zero! + */ + public static int getPercent(long current, long total) { + return (int) ((100L * current + total / 2) / total); + } + @SuppressWarnings("unused") public static class Profiler { public final long startTime = System.currentTimeMillis(); diff --git a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java index f10754362..0b8a54de3 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java @@ -238,8 +238,8 @@ public class InstallManagerService extends Service { Utils.debugLog(TAG, action + " " + intent); } else if (Downloader.ACTION_PROGRESS.equals(action)) { - int bytesRead = intent.getIntExtra(Downloader.EXTRA_BYTES_READ, 0); - int totalBytes = intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, 0); + long bytesRead = intent.getLongExtra(Downloader.EXTRA_BYTES_READ, 0); + long totalBytes = intent.getLongExtra(Downloader.EXTRA_TOTAL_BYTES, 0); appUpdateStatusManager.updateApkProgress(urlString, totalBytes, bytesRead); } else if (Downloader.ACTION_COMPLETE.equals(action)) { localBroadcastManager.unregisterReceiver(this); @@ -307,8 +307,8 @@ public class InstallManagerService extends Service { appUpdateStatusManager.updateApk(urlString, AppUpdateStatusManager.Status.Downloading, action); break; case Downloader.ACTION_PROGRESS: - int bytesRead = intent.getIntExtra(Downloader.EXTRA_BYTES_READ, 0); - int totalBytes = intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, 0); + long bytesRead = intent.getLongExtra(Downloader.EXTRA_BYTES_READ, 0); + long totalBytes = intent.getLongExtra(Downloader.EXTRA_TOTAL_BYTES, 0); appUpdateStatusManager.updateApkProgress(urlString, totalBytes, bytesRead); break; case Downloader.ACTION_COMPLETE: diff --git a/app/src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java b/app/src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java index e31f174c1..110a622ba 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java +++ b/app/src/main/java/org/fdroid/fdroid/views/AppDetailsRecyclerViewAdapter.java @@ -46,7 +46,6 @@ import org.fdroid.fdroid.privileged.views.AppDiff; import org.fdroid.fdroid.privileged.views.AppSecurityPermissions; import org.fdroid.fdroid.views.main.MainActivity; -import java.text.NumberFormat; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -205,7 +204,7 @@ public class AppDetailsRecyclerViewAdapter setProgress(0, 0, 0); } - public void setProgress(int bytesDownloaded, int totalBytes, int resIdString) { + public void setProgress(long bytesDownloaded, long totalBytes, int resIdString) { if (headerView != null) { headerView.setProgress(bytesDownloaded, totalBytes, resIdString); } @@ -358,14 +357,14 @@ public class AppDetailsRecyclerViewAdapter }); } - public void setProgress(int bytesDownloaded, int totalBytes, int resIdString) { + public void setProgress(long bytesDownloaded, long totalBytes, int resIdString) { if (bytesDownloaded == 0 && totalBytes == 0) { // Remove progress bar progressLayout.setVisibility(View.GONE); buttonLayout.setVisibility(View.VISIBLE); } else { - progressBar.setMax(totalBytes); - progressBar.setProgress(bytesDownloaded); + progressBar.setMax(Utils.bytesToKb(totalBytes)); + progressBar.setProgress(Utils.bytesToKb(bytesDownloaded)); progressBar.setIndeterminate(totalBytes == -1); progressLabel.setContentDescription(""); if (resIdString != 0) { @@ -373,12 +372,12 @@ public class AppDetailsRecyclerViewAdapter progressLabel.setContentDescription(context.getString(R.string.downloading)); progressPercent.setText(""); } else if (totalBytes > 0 && bytesDownloaded >= 0) { - float percent = (float) bytesDownloaded / totalBytes; - progressLabel.setText(Utils.getFriendlySize(bytesDownloaded) + " / " + Utils.getFriendlySize(totalBytes)); - progressLabel.setContentDescription(context.getString(R.string.app__tts__downloading_progress, (int) percent)); - NumberFormat format = NumberFormat.getPercentInstance(); - format.setMaximumFractionDigits(0); - progressPercent.setText(format.format(percent)); + int percent = Utils.getPercent(bytesDownloaded, totalBytes); + progressLabel.setText(Utils.getFriendlySize(bytesDownloaded) + + " / " + Utils.getFriendlySize(totalBytes)); + progressLabel.setContentDescription(context.getString(R.string.app__tts__downloading_progress, + percent)); + progressPercent.setText(String.format(Locale.ENGLISH, "%d%%", percent)); } else if (bytesDownloaded >= 0) { progressLabel.setText(Utils.getFriendlySize(bytesDownloaded)); progressLabel.setContentDescription(context.getString(R.string.downloading)); diff --git a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java index db6ef08f0..1e110ffd3 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java +++ b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java @@ -365,7 +365,8 @@ public abstract class AppListItemController extends RecyclerView.ViewHolder { return new AppListItemState(app) .setMainText(mainText) - .setProgress(currentStatus.progressCurrent, currentStatus.progressMax); + .setProgress(Utils.bytesToKb(currentStatus.progressCurrent), + Utils.bytesToKb(currentStatus.progressMax)); } protected AppListItemState getViewStateReadyToInstall(@NonNull App app) { diff --git a/app/src/main/java/org/fdroid/fdroid/views/swap/SwapAppsView.java b/app/src/main/java/org/fdroid/fdroid/views/swap/SwapAppsView.java index 143f067a0..839cf8c5b 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/swap/SwapAppsView.java +++ b/app/src/main/java/org/fdroid/fdroid/views/swap/SwapAppsView.java @@ -253,13 +253,12 @@ public class SwapAppsView extends ListView implements if (progressView.getVisibility() != View.VISIBLE) { showProgress(); } - int read = intent.getIntExtra(Downloader.EXTRA_BYTES_READ, 0); - int total = intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, 0); + long read = intent.getLongExtra(Downloader.EXTRA_BYTES_READ, 0); + long total = intent.getLongExtra(Downloader.EXTRA_TOTAL_BYTES, 0); if (total > 0) { - int progress = (int) ((double) read / total * 100); progressView.setIndeterminate(false); progressView.setMax(100); - progressView.setProgress(progress); + progressView.setProgress(Utils.getPercent(read, total)); } else { progressView.setIndeterminate(true); } From 661aebb75fa27941f0d9acc3bcca7605b53ec41a Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 5 Apr 2018 21:58:33 +0200 Subject: [PATCH 3/7] properly gather all requested permissions from index-v1.json The permissions from uses-permission and uses-permission-sdk-23 should be combined into a single list of permissions that are being requested for the current SDK version. The previous code was overwriting one or the other, based on the order that Jackson happen to call setRequestedPermissions(). closes #1139 #890 #1394 admin#65 --- app/src/main/java/org/fdroid/fdroid/data/Apk.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/org/fdroid/fdroid/data/Apk.java b/app/src/main/java/org/fdroid/fdroid/data/Apk.java index 77747d289..73b0993fe 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/Apk.java +++ b/app/src/main/java/org/fdroid/fdroid/data/Apk.java @@ -20,6 +20,7 @@ import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.Schema.ApkTable.Cols; import java.io.File; +import java.util.Collections; import java.util.Date; import java.util.HashSet; @@ -467,6 +468,9 @@ public class Apk extends ValueObject implements Comparable, Parcelable { private void setRequestedPermissions(Object[][] permissions, int minSdk) { HashSet set = new HashSet<>(); + if (requestedPermissions != null) { + Collections.addAll(set, requestedPermissions); + } for (Object[] versions : permissions) { int maxSdk = Integer.MAX_VALUE; if (versions[1] != null) { From af32e4ac858f3e1843556efff9bbcbefec05099b Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 5 Apr 2018 23:09:40 +0200 Subject: [PATCH 4/7] trigger CleanCacheService if device storage is low --- app/src/main/AndroidManifest.xml | 13 ++++++- .../org/fdroid/fdroid/CleanCacheService.java | 5 ++- .../main/java/org/fdroid/fdroid/Utils.java | 34 +++++++++++++++++++ .../receiver/DeviceStorageReceiver.java | 19 +++++++++++ 4 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/org/fdroid/fdroid/receiver/DeviceStorageReceiver.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d6dede04c..cdfa9cffb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -251,6 +251,12 @@ + + + + + + + + + @@ -544,16 +553,17 @@ android:name=".views.panic.PanicResponderActivity" android:noHistory="true" android:theme="@android:style/Theme.NoDisplay"> + + - + diff --git a/app/src/main/java/org/fdroid/fdroid/CleanCacheService.java b/app/src/main/java/org/fdroid/fdroid/CleanCacheService.java index ce464991e..da887eb00 100644 --- a/app/src/main/java/org/fdroid/fdroid/CleanCacheService.java +++ b/app/src/main/java/org/fdroid/fdroid/CleanCacheService.java @@ -8,7 +8,6 @@ import android.content.Intent; import android.os.Build; import android.os.Process; import android.os.SystemClock; - import org.apache.commons.io.FileUtils; import org.fdroid.fdroid.installer.ApkCache; @@ -51,6 +50,10 @@ public class CleanCacheService extends IntentService { SystemClock.elapsedRealtime() + 5000, interval, pending); } + public static void start(Context context) { + context.startService(new Intent(context, CleanCacheService.class)); + } + public CleanCacheService() { super("CleanCacheService"); } diff --git a/app/src/main/java/org/fdroid/fdroid/Utils.java b/app/src/main/java/org/fdroid/fdroid/Utils.java index 682135a18..9ca43a347 100644 --- a/app/src/main/java/org/fdroid/fdroid/Utils.java +++ b/app/src/main/java/org/fdroid/fdroid/Utils.java @@ -24,6 +24,8 @@ import android.content.res.Resources; import android.database.Cursor; import android.graphics.Bitmap; import android.net.Uri; +import android.os.Build; +import android.os.StatFs; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.RequiresApi; @@ -133,6 +135,38 @@ public final class Utils { return new File(cacheDir, "icons"); } + public static long getImageCacheDirAvailableMemory(Context context) { + File statDir = getImageCacheDir(context); + while (statDir != null && !statDir.exists()) { + statDir = statDir.getParentFile(); + } + if (statDir == null) { + return 50 * 1024 * 1024; // just return a minimal amount + } + StatFs stat = new StatFs(statDir.getPath()); + if (Build.VERSION.SDK_INT < 18) { + return stat.getAvailableBlocks() * stat.getBlockSize(); + } else { + return stat.getAvailableBlocksLong() * stat.getBlockSizeLong(); + } + } + + public static long getImageCacheDirTotalMemory(Context context) { + File statDir = getImageCacheDir(context); + while (statDir != null && !statDir.exists()) { + statDir = statDir.getParentFile(); + } + if (statDir == null) { + return 100 * 1024 * 1024; // just return a minimal amount + } + StatFs stat = new StatFs(statDir.getPath()); + if (Build.VERSION.SDK_INT < 18) { + return stat.getBlockCount() * stat.getBlockSize(); + } else { + return stat.getBlockCountLong() * stat.getBlockSizeLong(); + } + } + public static void copy(InputStream input, OutputStream output) throws IOException { byte[] buffer = new byte[BUFFER_SIZE]; while (true) { diff --git a/app/src/main/java/org/fdroid/fdroid/receiver/DeviceStorageReceiver.java b/app/src/main/java/org/fdroid/fdroid/receiver/DeviceStorageReceiver.java new file mode 100644 index 000000000..2beef8404 --- /dev/null +++ b/app/src/main/java/org/fdroid/fdroid/receiver/DeviceStorageReceiver.java @@ -0,0 +1,19 @@ +package org.fdroid.fdroid.receiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import org.fdroid.fdroid.CleanCacheService; + +public class DeviceStorageReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + if (intent == null) { + return; + } + String action = intent.getAction(); + if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(action)) { + CleanCacheService.schedule(context); + } + } +} From c1656f61a7b58a9e8ca6433df42341d8a6806dbf Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 5 Apr 2018 23:02:23 +0200 Subject: [PATCH 5/7] if device storage is really low, delete the entire cache --- app/src/main/AndroidManifest.xml | 3 ++ .../org/fdroid/fdroid/DeleteCacheService.java | 44 +++++++++++++++++++ .../receiver/DeviceStorageReceiver.java | 10 ++++- 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/org/fdroid/fdroid/DeleteCacheService.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cdfa9cffb..a8e9d7557 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -267,6 +267,9 @@ + 2) { + CleanCacheService.start(context); + } else { + DeleteCacheService.deleteAll(context); + } } } } From 4a0dd8abe7094c67c993544d1b04015516477223 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 5 Apr 2018 23:07:44 +0200 Subject: [PATCH 6/7] when storage is low, make UIL limit cache based on available size --- .../java/org/fdroid/fdroid/FDroidApp.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/src/main/java/org/fdroid/fdroid/FDroidApp.java b/app/src/main/java/org/fdroid/fdroid/FDroidApp.java index aa9ae58fb..879687bb1 100644 --- a/app/src/main/java/org/fdroid/fdroid/FDroidApp.java +++ b/app/src/main/java/org/fdroid/fdroid/FDroidApp.java @@ -41,6 +41,10 @@ import android.util.Log; import android.view.Display; import android.view.WindowManager; import android.widget.Toast; +import com.nostra13.universalimageloader.cache.disc.DiskCache; +import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache; +import com.nostra13.universalimageloader.cache.disc.impl.ext.LruDiskCache; +import com.nostra13.universalimageloader.core.DefaultConfigurationFactory; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.core.process.BitmapProcessor; @@ -399,9 +403,26 @@ public class FDroidApp extends Application { if (height > maxSize) { maxSize = height; } + + DiskCache diskCache; + long available = Utils.getImageCacheDirAvailableMemory(this); + int percentageFree = Utils.getPercent(available, Utils.getImageCacheDirTotalMemory(this)); + if (percentageFree > 5) { + diskCache = new UnlimitedDiskCache(Utils.getImageCacheDir(this)); + } else { + Log.i(TAG, "Switching to LruDiskCache(" + available / 2L + ") to save disk space!"); + try { + diskCache = new LruDiskCache(Utils.getImageCacheDir(this), + DefaultConfigurationFactory.createFileNameGenerator(), + available / 2L); + } catch (IOException e) { + diskCache = new UnlimitedDiskCache(Utils.getImageCacheDir(this)); + } + } ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()) .imageDownloader(new ImageLoaderForUIL(getApplicationContext())) .defaultDisplayImageOptions(Utils.getDefaultDisplayImageOptionsBuilder().build()) + .diskCache(diskCache) .diskCacheExtraOptions(maxSize, maxSize, new BitmapProcessor() { @Override public Bitmap process(Bitmap bitmap) { From d06630f2876b7ffa5190840108735a22ba5289f4 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 5 Apr 2018 23:22:20 +0200 Subject: [PATCH 7/7] git hooks: use ./gradlew to ensure the right gradle version is used --- hooks/pre-push | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/pre-push b/hooks/pre-push index e75b891a3..c7612f4e5 100755 --- a/hooks/pre-push +++ b/hooks/pre-push @@ -53,7 +53,7 @@ do fi fi - gradle checkstyle pmd lint || exit 1 + ./gradlew checkstyle pmd lint || exit 1 fi done