diff --git a/OsmAnd/res/xml/data_storage.xml b/OsmAnd/res/xml/data_storage.xml
index a153ec4cd1..95168ac3ce 100644
--- a/OsmAnd/res/xml/data_storage.xml
+++ b/OsmAnd/res/xml/data_storage.xml
@@ -14,7 +14,7 @@
android:title="@string/shared_string_maps"/>
diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java
index 96a939eae3..fd66cd3e58 100644
--- a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java
+++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java
@@ -39,7 +39,7 @@ public class DataStorageHelper {
public final static String MANUALLY_SPECIFIED = "manually_specified";
public final static String MAPS_MEMORY = "maps_memory_used";
- public final static String SRTM_AND_HILLSHADE_MEMORY = "contour_lines_and_hillshade_memory";
+ public final static String TERRAIN_MEMORY = "terrain_memory_used";
public final static String TRACKS_MEMORY = "tracks_memory_used";
public final static String NOTES_MEMORY = "notes_memory_used";
public final static String TILES_MEMORY = "tiles_memory_used";
@@ -52,7 +52,7 @@ public class DataStorageHelper {
private ArrayList memoryItems = new ArrayList<>();
private MemoryItem mapsMemory;
- private MemoryItem srtmAndHillshadeMemory;
+ private MemoryItem terrainMemory;
private MemoryItem tracksMemory;
private MemoryItem notesMemory;
private MemoryItem tilesMemory;
@@ -186,15 +186,15 @@ public class DataStorageHelper {
.createItem();
memoryItems.add(mapsMemory);
- srtmAndHillshadeMemory = MemoryItem.builder()
- .setKey(SRTM_AND_HILLSHADE_MEMORY)
+ terrainMemory = MemoryItem.builder()
+ .setKey(TERRAIN_MEMORY)
.setExtensions(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT)
.setDirectories(
createDirectory((SRTM_INDEX_DIR), true, EXTENSIONS, false),
createDirectory((TILES_INDEX_DIR), false, PREFIX, true))
.setPrefixes("Hillshade")
.createItem();
- memoryItems.add(srtmAndHillshadeMemory);
+ memoryItems.add(terrainMemory);
tracksMemory = MemoryItem.builder()
.setKey(TRACKS_MEMORY)
@@ -267,13 +267,13 @@ public class DataStorageHelper {
public RefreshUsedMemoryTask calculateMemoryUsedInfo(UpdateMemoryInfoUIAdapter listener) {
File rootDir = new File(currentStoragePath);
RefreshUsedMemoryTask task = new RefreshUsedMemoryTask(listener, otherMemory, rootDir, null, null, OTHER_MEMORY);
- task.execute(mapsMemory, srtmAndHillshadeMemory, tracksMemory, notesMemory);
+ task.execute(mapsMemory, terrainMemory, tracksMemory, notesMemory);
return task;
}
public RefreshUsedMemoryTask calculateTilesMemoryUsed(UpdateMemoryInfoUIAdapter listener) {
File rootDir = new File(tilesMemory.getDirectories()[0].getAbsolutePath());
- RefreshUsedMemoryTask task = new RefreshUsedMemoryTask(listener, otherMemory, rootDir, null, srtmAndHillshadeMemory.getPrefixes(), TILES_MEMORY);
+ RefreshUsedMemoryTask task = new RefreshUsedMemoryTask(listener, otherMemory, rootDir, null, terrainMemory.getPrefixes(), TILES_MEMORY);
task.execute(tilesMemory);
return task;
}
@@ -290,11 +290,11 @@ public class DataStorageHelper {
}
public DirectoryItem createDirectory(@NonNull String relativePath,
- boolean goDeeper,
+ boolean processInternalDirectories,
CheckingType checkingType,
- boolean skipOther) {
+ boolean skipUnmatchedInDirectory) {
String path = app.getAppPath(relativePath).getAbsolutePath();
- return new DirectoryItem(path, goDeeper, checkingType, skipOther);
+ return new DirectoryItem(path, processInternalDirectories, checkingType, skipUnmatchedInDirectory);
}
public static String getFormattedMemoryInfo(long bytes, String[] formatStrings) {
diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java
index e1d7e1cad4..0f15e39f58 100644
--- a/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java
+++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/item/DirectoryItem.java
@@ -3,9 +3,9 @@ package net.osmand.plus.settings.datastorage.item;
public class DirectoryItem {
private final String absolutePath;
- private final boolean goDeeper;
+ private final boolean processInternalDirectories;
private final CheckingType checkingType;
- private final boolean skipOther;
+ private final boolean skipUnmatchedInDirectory;
public enum CheckingType {
EXTENSIONS,
@@ -13,28 +13,28 @@ public class DirectoryItem {
}
public DirectoryItem(String absolutePath,
- boolean goDeeper,
+ boolean processInternalDirectories,
CheckingType checkingType,
- boolean skipOther) {
+ boolean skipUnmatchedInDirectory) {
this.absolutePath = absolutePath;
- this.goDeeper = goDeeper;
+ this.processInternalDirectories = processInternalDirectories;
this.checkingType = checkingType;
- this.skipOther = skipOther;
+ this.skipUnmatchedInDirectory = skipUnmatchedInDirectory;
}
public String getAbsolutePath() {
return absolutePath;
}
- public boolean isGoDeeper() {
- return goDeeper;
+ public boolean shouldProcessInternalDirectories() {
+ return processInternalDirectories;
}
public CheckingType getCheckingType() {
return checkingType;
}
- public boolean isSkipOther() {
- return skipOther;
+ public boolean shouldSkipUnmatchedInDirectory() {
+ return skipUnmatchedInDirectory;
}
}
diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java
index ad1dbb4bf5..dc84c97dbc 100644
--- a/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java
+++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/task/RefreshUsedMemoryTask.java
@@ -2,6 +2,8 @@ package net.osmand.plus.settings.datastorage.task;
import android.os.AsyncTask;
+import androidx.annotation.NonNull;
+
import net.osmand.plus.settings.datastorage.DataStorageHelper.UpdateMemoryInfoUIAdapter;
import net.osmand.plus.settings.datastorage.item.DirectoryItem;
import net.osmand.plus.settings.datastorage.item.DirectoryItem.CheckingType;
@@ -10,146 +12,189 @@ import net.osmand.plus.settings.datastorage.item.MemoryItem;
import java.io.File;
import static net.osmand.plus.settings.datastorage.DataStorageFragment.UI_REFRESH_TIME_MS;
+import static net.osmand.util.Algorithms.objectEquals;
public class RefreshUsedMemoryTask extends AsyncTask {
- private UpdateMemoryInfoUIAdapter listener;
- private File rootDir;
- private MemoryItem otherMemory;
- private String[] directoriesToAvoid;
- private String[] prefixesToAvoid;
- private String taskKey;
+ private final UpdateMemoryInfoUIAdapter uiAdapter;
+ private final File root;
+ private final MemoryItem otherMemoryItem;
+ private final String[] directoriesToSkip;
+ private final String[] filePrefixesToSkip;
+ private final String tag;
private long lastRefreshTime;
- public RefreshUsedMemoryTask(UpdateMemoryInfoUIAdapter listener, MemoryItem otherMemory, File rootDir, String[] directoriesToAvoid, String[] prefixesToAvoid, String taskKey) {
- this.listener = listener;
- this.otherMemory = otherMemory;
- this.rootDir = rootDir;
- this.directoriesToAvoid = directoriesToAvoid;
- this.prefixesToAvoid = prefixesToAvoid;
- this.taskKey = taskKey;
+ public RefreshUsedMemoryTask(UpdateMemoryInfoUIAdapter uiAdapter,
+ MemoryItem otherMemoryItem,
+ File root,
+ String[] directoriesToSkip,
+ String[] filePrefixesToSkip,
+ String tag) {
+ this.uiAdapter = uiAdapter;
+ this.otherMemoryItem = otherMemoryItem;
+ this.root = root;
+ this.directoriesToSkip = directoriesToSkip;
+ this.filePrefixesToSkip = filePrefixesToSkip;
+ this.tag = tag;
}
@Override
protected Void doInBackground(MemoryItem... items) {
lastRefreshTime = System.currentTimeMillis();
- if (rootDir.canRead()) {
- calculateMultiTypes(rootDir, items);
+ if (root.canRead()) {
+ calculateMultiTypes(root, items);
}
return null;
}
- private void calculateMultiTypes(File rootDir, MemoryItem... items) {
+ private void calculateMultiTypes(File rootDir,
+ MemoryItem... items) {
File[] subFiles = rootDir.listFiles();
+ if (subFiles != null) {
+ for (File file : subFiles) {
+ if (isCancelled()) break;
- for (File file : subFiles) {
- if (isCancelled()) {
- break;
- }
- nextFile : {
if (file.isDirectory()) {
- //check current directory should be avoid
- if (directoriesToAvoid != null) {
- for (String directoryToAvoid : directoriesToAvoid) {
- if (file.getAbsolutePath().equals(directoryToAvoid)) {
- break nextFile;
- }
- }
+ if (!shouldSkipDirectory(file)) {
+ processDirectory(file, items);
}
- //check current directory matched items type
- for (MemoryItem item : items) {
- DirectoryItem[] directories = item.getDirectories();
- if (directories == null) {
- continue;
- }
- for (DirectoryItem dir : directories) {
- if (file.getAbsolutePath().equals(dir.getAbsolutePath())
- || (file.getAbsolutePath().startsWith(dir.getAbsolutePath()))) {
- if (dir.isGoDeeper()) {
- calculateMultiTypes(file, items);
- break nextFile;
- } else if (dir.isSkipOther()) {
- break nextFile;
- }
- }
- }
- }
- //current directory did not match to any type
- otherMemory.addBytes(getDirectorySize(file));
+
} else if (file.isFile()) {
- //check current file should be avoid
- if (prefixesToAvoid != null) {
- for (String prefixToAvoid : prefixesToAvoid) {
- if (file.getName().toLowerCase().startsWith(prefixToAvoid.toLowerCase())) {
- break nextFile;
- }
- }
+ if (!shouldSkipFile(file)) {
+ processFile(rootDir, file, items);
}
- //check current file matched items type
- for (MemoryItem item : items) {
- DirectoryItem[] directories = item.getDirectories();
- if (directories == null) {
- continue;
- }
- for (DirectoryItem dir : directories) {
- if (rootDir.getAbsolutePath().equals(dir.getAbsolutePath())
- || (rootDir.getAbsolutePath().startsWith(dir.getAbsolutePath()) && dir.isGoDeeper())) {
- CheckingType checkingType = dir.getCheckingType();
- switch (checkingType) {
- case EXTENSIONS : {
- String[] extensions = item.getExtensions();
- if (extensions != null) {
- for (String extension : extensions) {
- if (file.getAbsolutePath().endsWith(extension)) {
- item.addBytes(file.length());
- break nextFile;
- }
- }
- } else {
- item.addBytes(file.length());
- break nextFile;
- }
- break ;
- }
- case PREFIX : {
- String[] prefixes = item.getPrefixes();
- if (prefixes != null) {
- for (String prefix : prefixes) {
- if (file.getName().toLowerCase().startsWith(prefix.toLowerCase())) {
- item.addBytes(file.length());
- break nextFile;
- }
- }
- } else {
- item.addBytes(file.length());
- break nextFile;
- }
- break ;
- }
- }
- if (dir.isSkipOther()) {
- break nextFile;
- }
- }
- }
- }
- //current file did not match any type
- otherMemory.addBytes(file.length());
}
+ refreshUI();
}
- refreshUI();
}
}
- private long getDirectorySize(File dir) {
+ private boolean shouldSkipDirectory(@NonNull File dir) {
+ if (directoriesToSkip != null) {
+ for (String dirToSkipPath : directoriesToSkip) {
+ String dirPath = dir.getAbsolutePath();
+ if (objectEquals(dirPath, dirToSkipPath)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean shouldSkipFile(@NonNull File file) {
+ if (filePrefixesToSkip != null) {
+ String fileName = file.getName().toLowerCase();
+ for (String prefixToAvoid : filePrefixesToSkip) {
+ String prefix = prefixToAvoid.toLowerCase();
+ if (fileName.startsWith(prefix)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private void processDirectory(@NonNull File directory,
+ @NonNull MemoryItem... items) {
+ String directoryPath = directory.getAbsolutePath();
+ for (MemoryItem memoryItem : items) {
+ DirectoryItem[] allowedDirectories = memoryItem.getDirectories();
+ if (allowedDirectories != null) {
+ for (DirectoryItem allowedDir : allowedDirectories) {
+ String allowedDirPath = allowedDir.getAbsolutePath();
+ if (objectEquals(directoryPath, allowedDirPath)
+ || (directoryPath.startsWith(allowedDirPath))) {
+ if (allowedDir.shouldProcessInternalDirectories()) {
+ calculateMultiTypes(directory, items);
+ return;
+ } else if (allowedDir.shouldSkipUnmatchedInDirectory()) {
+ return;
+ }
+ }
+ }
+ }
+ }
+ // Current directory did not match to any type
+ otherMemoryItem.addBytes(calculateFolderSize(directory));
+ }
+
+ private void processFile(@NonNull File rootDir,
+ @NonNull File file,
+ @NonNull MemoryItem... items) {
+ for (MemoryItem item : items) {
+ DirectoryItem[] allowedDirectories = item.getDirectories();
+ if (allowedDirectories == null) continue;
+ String rootDirPath = rootDir.getAbsolutePath();
+
+ for (DirectoryItem allowedDir : allowedDirectories) {
+ String allowedDirPath = allowedDir.getAbsolutePath();
+ boolean processInternal = allowedDir.shouldProcessInternalDirectories();
+ if (objectEquals(rootDirPath, allowedDirPath)
+ || (rootDirPath.startsWith(allowedDirPath) && processInternal)) {
+ CheckingType checkingType = allowedDir.getCheckingType();
+ switch (checkingType) {
+ case EXTENSIONS: {
+ if (isSuitableExtension(file, item)) {
+ item.addBytes(file.length());
+ return;
+ }
+ break;
+ }
+ case PREFIX: {
+ if (isSuitablePrefix(file, item)) {
+ item.addBytes(file.length());
+ return;
+ }
+ break;
+ }
+ }
+ if (allowedDir.shouldSkipUnmatchedInDirectory()) {
+ return;
+ }
+ }
+ }
+ }
+ // Current file did not match any type
+ otherMemoryItem.addBytes(file.length());
+ }
+
+ private boolean isSuitableExtension(@NonNull File file,
+ @NonNull MemoryItem item) {
+ String[] extensions = item.getExtensions();
+ if (extensions != null) {
+ for (String extension : extensions) {
+ if (file.getAbsolutePath().endsWith(extension)) {
+ return true;
+ }
+ }
+ }
+ return extensions == null;
+ }
+
+ private boolean isSuitablePrefix(@NonNull File file,
+ @NonNull MemoryItem item) {
+ String[] prefixes = item.getPrefixes();
+ if (prefixes != null) {
+ for (String prefix : prefixes) {
+ if (file.getName().toLowerCase().startsWith(prefix.toLowerCase())) {
+ return true;
+ }
+ }
+ }
+ return prefixes == null;
+ }
+
+ private long calculateFolderSize(@NonNull File dir) {
long bytes = 0;
if (dir.isDirectory()) {
File[] files = dir.listFiles();
+ if (files == null) return 0;
+
for (File file : files) {
if (isCancelled()) {
break;
}
if (file.isDirectory()) {
- bytes += getDirectorySize(file);
+ bytes += calculateFolderSize(file);
} else if (file.isFile()) {
bytes += file.length();
}
@@ -161,16 +206,16 @@ public class RefreshUsedMemoryTask extends AsyncTask {
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
- if (listener != null) {
- listener.onMemoryInfoUpdate();
+ if (uiAdapter != null) {
+ uiAdapter.onMemoryInfoUpdate();
}
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
- if (listener != null) {
- listener.onFinishUpdating(taskKey);
+ if (uiAdapter != null) {
+ uiAdapter.onFinishUpdating(tag);
}
}