Merge branch 'handle-low-storage' into 'master'
clean cache when the device has low storage; plus 1.2 bug fixes Closes #1139, #1395, and #1400 See merge request fdroid/fdroidclient!667
This commit is contained in:
		
						commit
						4fa86f548b
					
				| @ -251,6 +251,12 @@ | ||||
|             <!-- Doesn't require an intent-filter because it is explicitly invoked via Intent.setClass() --> | ||||
|         </receiver> | ||||
| 
 | ||||
|         <receiver android:name=".receiver.DeviceStorageReceiver"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.DEVICE_STORAGE_LOW"/> | ||||
|             </intent-filter> | ||||
|         </receiver> | ||||
| 
 | ||||
|         <service android:name=".UpdateService"/> | ||||
|         <service | ||||
|                 android:name=".net.DownloaderService" | ||||
| @ -261,6 +267,9 @@ | ||||
|         <service | ||||
|                 android:name=".CleanCacheService" | ||||
|                 android:exported="false"/> | ||||
|         <service | ||||
|                 android:name=".DeleteCacheService" | ||||
|                 android:exported="false"/> | ||||
|         <service android:name=".net.WifiStateChangeService"/> | ||||
|         <service android:name=".localrepo.SwapService"/> | ||||
|         <service | ||||
| @ -279,6 +288,7 @@ | ||||
|                 android:name=".AppUpdateStatusService" | ||||
|                 android:exported="false"/> | ||||
| 
 | ||||
| 
 | ||||
|         <!-- Warning: Please add all new services to HidingManager --> | ||||
| 
 | ||||
|         <activity | ||||
| @ -534,9 +544,11 @@ | ||||
|             <meta-data | ||||
|                     android:name="android.support.PARENT_ACTIVITY" | ||||
|                     android:value=".views.main.MainActivity"/> | ||||
| 
 | ||||
|             <intent-filter> | ||||
|                 <action android:name="info.guardianproject.panic.action.CONNECT"/> | ||||
|                 <action android:name="info.guardianproject.panic.action.DISCONNECT"/> | ||||
| 
 | ||||
|                 <category android:name="android.intent.category.DEFAULT"/> | ||||
|             </intent-filter> | ||||
|         </activity> | ||||
| @ -544,16 +556,17 @@ | ||||
|                 android:name=".views.panic.PanicResponderActivity" | ||||
|                 android:noHistory="true" | ||||
|                 android:theme="@android:style/Theme.NoDisplay"> | ||||
| 
 | ||||
|             <!-- this can never have launchMode singleTask or singleInstance! --> | ||||
|             <intent-filter> | ||||
|                 <action android:name="info.guardianproject.panic.action.TRIGGER"/> | ||||
| 
 | ||||
|                 <category android:name="android.intent.category.DEFAULT"/> | ||||
|             </intent-filter> | ||||
|         </activity> | ||||
|         <activity | ||||
|                 android:name=".views.panic.ExitActivity" | ||||
|                 android:theme="@android:style/Theme.NoDisplay"/> | ||||
| 
 | ||||
|         <activity | ||||
|                 android:name=".views.hiding.CalculatorActivity" | ||||
|                 android:enabled="false" | ||||
| @ -562,6 +575,7 @@ | ||||
|                 android:theme="@style/AppThemeLight"> | ||||
|             <intent-filter> | ||||
|                 <action android:name="android.intent.action.MAIN"/> | ||||
| 
 | ||||
|                 <category android:name="android.intent.category.LAUNCHER"/> | ||||
|             </intent-filter> | ||||
|         </activity> | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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"); | ||||
|     } | ||||
|  | ||||
							
								
								
									
										44
									
								
								app/src/main/java/org/fdroid/fdroid/DeleteCacheService.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/src/main/java/org/fdroid/fdroid/DeleteCacheService.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| package org.fdroid.fdroid; | ||||
| 
 | ||||
| import android.app.IntentService; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.os.Process; | ||||
| import android.support.v4.content.ContextCompat; | ||||
| import android.util.Log; | ||||
| import org.apache.commons.io.FileUtils; | ||||
| 
 | ||||
| import java.io.File; | ||||
| 
 | ||||
| /** | ||||
|  * An {@link IntentService} subclass for deleting the full cache for this app. | ||||
|  */ | ||||
| public class DeleteCacheService extends IntentService { | ||||
|     public static final String TAG = "DeleteCacheService"; | ||||
| 
 | ||||
|     public DeleteCacheService() { | ||||
|         super("DeleteCacheService"); | ||||
|     } | ||||
| 
 | ||||
|     public static void deleteAll(Context context) { | ||||
|         Intent intent = new Intent(context, DeleteCacheService.class); | ||||
|         context.startService(intent); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected void onHandleIntent(Intent intent) { | ||||
|         if (intent == null) { | ||||
|             return; | ||||
|         } | ||||
|         Process.setThreadPriority(Process.THREAD_PRIORITY_LOWEST); | ||||
|         Log.w(TAG, "Deleting all cached contents!"); | ||||
|         try { | ||||
|             FileUtils.deleteDirectory(getCacheDir()); | ||||
|             for (File dir : ContextCompat.getExternalCacheDirs(this)) { | ||||
|                 FileUtils.deleteDirectory(dir); | ||||
|             } | ||||
|         } catch (Exception e) { | ||||
|             // ignored | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -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) { | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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"; | ||||
| @ -178,7 +177,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)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -238,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); | ||||
| @ -448,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(); | ||||
| 
 | ||||
| @ -522,15 +522,17 @@ 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) { | ||||
|             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); | ||||
|     } | ||||
| @ -542,23 +544,28 @@ 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); | ||||
|         String message = context.getString(R.string.status_processing_xml_percent, | ||||
|                 updater.indexUrl, downloadedSize, totalSize, percent); | ||||
|         sendStatus(context, STATUS_INFO, message, percent); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 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); | ||||
|  | ||||
| @ -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) { | ||||
| @ -693,6 +727,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(); | ||||
|  | ||||
| @ -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<Apk>, Parcelable { | ||||
| 
 | ||||
|     private void setRequestedPermissions(Object[][] permissions, int minSdk) { | ||||
|         HashSet<String> set = new HashSet<>(); | ||||
|         if (requestedPermissions != null) { | ||||
|             Collections.addAll(set, requestedPermissions); | ||||
|         } | ||||
|         for (Object[] versions : permissions) { | ||||
|             int maxSdk = Integer.MAX_VALUE; | ||||
|             if (versions[1] != null) { | ||||
|  | ||||
| @ -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: | ||||
|  | ||||
| @ -0,0 +1,27 @@ | ||||
| package org.fdroid.fdroid.receiver; | ||||
| 
 | ||||
| import android.content.BroadcastReceiver; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import org.fdroid.fdroid.CleanCacheService; | ||||
| import org.fdroid.fdroid.DeleteCacheService; | ||||
| import org.fdroid.fdroid.Utils; | ||||
| 
 | ||||
| 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)) { | ||||
|             int percentageFree = Utils.getPercent(Utils.getImageCacheDirAvailableMemory(context), | ||||
|                     Utils.getImageCacheDirTotalMemory(context)); | ||||
|             if (percentageFree > 2) { | ||||
|                 CleanCacheService.start(context); | ||||
|             } else { | ||||
|                 DeleteCacheService.deleteAll(context); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -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)); | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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); | ||||
|                             } | ||||
|  | ||||
| @ -53,7 +53,7 @@ do | ||||
|             fi | ||||
|         fi | ||||
| 
 | ||||
|         gradle checkstyle pmd lint || exit 1 | ||||
|         ./gradlew checkstyle pmd lint || exit 1 | ||||
|     fi | ||||
| done | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Hans-Christoph Steiner
						Hans-Christoph Steiner