aboutsummaryrefslogtreecommitdiff
path: root/subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java
diff options
context:
space:
mode:
Diffstat (limited to 'subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java')
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java239
1 files changed, 0 insertions, 239 deletions
diff --git a/subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java b/subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java
deleted file mode 100644
index 62204c76..00000000
--- a/subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java
+++ /dev/null
@@ -1,239 +0,0 @@
-package github.daneren2005.dsub.util;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import android.content.Context;
-import android.os.AsyncTask;
-import android.util.Log;
-import android.os.StatFs;
-import github.daneren2005.dsub.domain.Playlist;
-import github.daneren2005.dsub.service.DownloadFile;
-import github.daneren2005.dsub.service.DownloadService;
-import java.util.*;
-
-/**
- * @author Sindre Mehus
- * @version $Id$
- */
-public class CacheCleaner {
-
- private static final String TAG = CacheCleaner.class.getSimpleName();
- private static final long MIN_FREE_SPACE = 500 * 1024L * 1024L;
-
- private final Context context;
- private final DownloadService downloadService;
-
- public CacheCleaner(Context context, DownloadService downloadService) {
- this.context = context;
- this.downloadService = downloadService;
- }
-
- public void clean() {
- new BackgroundCleanup().execute();
- }
- public void cleanSpace() {
- new BackgroundSpaceCleanup().execute();
- }
- public void cleanPlaylists(List<Playlist> playlists) {
- new BackgroundPlaylistsCleanup().execute(playlists);
- }
-
- private void deleteEmptyDirs(List<File> dirs, Set<File> undeletable) {
- for (File dir : dirs) {
- if (undeletable.contains(dir)) {
- continue;
- }
-
- File[] children = dir.listFiles();
-
- // No songs left in the folder
- if(children.length == 1 && children[0].getPath().equals(FileUtil.getAlbumArtFile(dir).getPath())) {
- Util.delete(children[0]);
- children = dir.listFiles();
- }
-
- // Delete empty directory
- if (children.length == 0) {
- Util.delete(dir);
- }
- }
- }
-
- private long getMinimumDelete(List<File> files) {
- if(files.size() == 0) {
- return 0L;
- }
-
- long cacheSizeBytes = Util.getCacheSizeMB(context) * 1024L * 1024L;
-
- long bytesUsedBySubsonic = 0L;
- for (File file : files) {
- bytesUsedBySubsonic += file.length();
- }
-
- // Ensure that file system is not more than 95% full.
- StatFs stat = new StatFs(files.get(0).getPath());
- long bytesTotalFs = (long) stat.getBlockCount() * (long) stat.getBlockSize();
- long bytesAvailableFs = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
- long bytesUsedFs = bytesTotalFs - bytesAvailableFs;
- long minFsAvailability = bytesTotalFs - MIN_FREE_SPACE;
-
- long bytesToDeleteCacheLimit = Math.max(bytesUsedBySubsonic - cacheSizeBytes, 0L);
- long bytesToDeleteFsLimit = Math.max(bytesUsedFs - minFsAvailability, 0L);
- long bytesToDelete = Math.max(bytesToDeleteCacheLimit, bytesToDeleteFsLimit);
-
- Log.i(TAG, "File system : " + Util.formatBytes(bytesAvailableFs) + " of " + Util.formatBytes(bytesTotalFs) + " available");
- Log.i(TAG, "Cache limit : " + Util.formatBytes(cacheSizeBytes));
- Log.i(TAG, "Cache size before : " + Util.formatBytes(bytesUsedBySubsonic));
- Log.i(TAG, "Minimum to delete : " + Util.formatBytes(bytesToDelete));
-
- return bytesToDelete;
- }
-
- private void deleteFiles(List<File> files, Set<File> undeletable, long bytesToDelete, boolean deletePartials) {
- if (files.isEmpty()) {
- return;
- }
-
- long bytesDeleted = 0L;
- for (File file : files) {
- if(!deletePartials && bytesDeleted > bytesToDelete) break;
-
- if (bytesToDelete > bytesDeleted || (deletePartials && (file.getName().endsWith(".partial") || file.getName().contains(".partial.")))) {
- if (!undeletable.contains(file) && !file.getName().equals(Constants.ALBUM_ART_FILE)) {
- long size = file.length();
- if (Util.delete(file)) {
- bytesDeleted += size;
- }
- }
- }
- }
-
- Log.i(TAG, "Deleted : " + Util.formatBytes(bytesDeleted));
- }
-
- private void findCandidatesForDeletion(File file, List<File> files, List<File> dirs) {
- if (file.isFile()) {
- String name = file.getName();
- boolean isCacheFile = name.endsWith(".partial") || name.contains(".partial.") || name.endsWith(".complete") || name.contains(".complete.");
- if (isCacheFile) {
- files.add(file);
- }
- } else {
- // Depth-first
- for (File child : FileUtil.listFiles(file)) {
- findCandidatesForDeletion(child, files, dirs);
- }
- dirs.add(file);
- }
- }
-
- private void sortByAscendingModificationTime(List<File> files) {
- Collections.sort(files, new Comparator<File>() {
- @Override
- public int compare(File a, File b) {
- if (a.lastModified() < b.lastModified()) {
- return -1;
- }
- if (a.lastModified() > b.lastModified()) {
- return 1;
- }
- return 0;
- }
- });
- }
-
- private Set<File> findUndeletableFiles() {
- Set<File> undeletable = new HashSet<File>(5);
-
- for (DownloadFile downloadFile : downloadService.getDownloads()) {
- undeletable.add(downloadFile.getPartialFile());
- undeletable.add(downloadFile.getCompleteFile());
- }
-
- undeletable.add(FileUtil.getMusicDirectory(context));
- return undeletable;
- }
-
- private class BackgroundCleanup extends AsyncTask<Void, Void, Void> {
- @Override
- protected Void doInBackground(Void... params) {
- if (downloadService == null) {
- Log.e(TAG, "DownloadService not set. Aborting cache cleaning.");
- return null;
- }
-
- try {
- List<File> files = new ArrayList<File>();
- List<File> dirs = new ArrayList<File>();
-
- findCandidatesForDeletion(FileUtil.getMusicDirectory(context), files, dirs);
- sortByAscendingModificationTime(files);
-
- Set<File> undeletable = findUndeletableFiles();
-
- deleteFiles(files, undeletable, getMinimumDelete(files), true);
- deleteEmptyDirs(dirs, undeletable);
- } catch (RuntimeException x) {
- Log.e(TAG, "Error in cache cleaning.", x);
- }
-
- return null;
- }
- }
-
- private class BackgroundSpaceCleanup extends AsyncTask<Void, Void, Void> {
- @Override
- protected Void doInBackground(Void... params) {
- if (downloadService == null) {
- Log.e(TAG, "DownloadService not set. Aborting cache cleaning.");
- return null;
- }
-
- try {
- List<File> files = new ArrayList<File>();
- List<File> dirs = new ArrayList<File>();
- findCandidatesForDeletion(FileUtil.getMusicDirectory(context), files, dirs);
-
- long bytesToDelete = getMinimumDelete(files);
- if(bytesToDelete > 0L) {
- sortByAscendingModificationTime(files);
- Set<File> undeletable = findUndeletableFiles();
- deleteFiles(files, undeletable, bytesToDelete, false);
- }
- } catch (RuntimeException x) {
- Log.e(TAG, "Error in cache cleaning.", x);
- }
-
- return null;
- }
- }
-
- private class BackgroundPlaylistsCleanup extends AsyncTask<List<Playlist>, Void, Void> {
- @Override
- protected Void doInBackground(List<Playlist>... params) {
- try {
- String server = Util.getServerName(context);
- SortedSet<File> playlistFiles = FileUtil.listFiles(FileUtil.getPlaylistDirectory(server));
- List<Playlist> playlists = params[0];
- for (Playlist playlist : playlists) {
- playlistFiles.remove(FileUtil.getPlaylistFile(server, playlist.getName()));
- }
-
- for(File playlist : playlistFiles) {
- playlist.delete();
- }
- } catch (RuntimeException x) {
- Log.e(TAG, "Error in playlist cache cleaning.", x);
- }
-
- return null;
- }
- }
-}