Skip to content

Commit

Permalink
Delete files using JobService working
Browse files Browse the repository at this point in the history
- the service will first delete invalid event triggers. Invalid event
  triggers correspond to triggers whose event is deleted.
- the service will delete all files in the storage directory which is
  not kept in the database
- it will then clear out any empty directory in the storage directory
- the storage directory is pulled from preferences
- constraint on network removed; the service can be run when the
  device is charging

Signed-off-by: Arka Prava Basu <[email protected]>
  • Loading branch information
archie94 committed Nov 4, 2018
1 parent d10bcdb commit 6be6b28
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 14 deletions.
5 changes: 3 additions & 2 deletions src/main/java/org/havenapp/main/ListActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import com.firebase.jobdispatcher.Lifetime;
import com.firebase.jobdispatcher.RetryStrategy;
import com.firebase.jobdispatcher.Trigger;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.mikepenz.aboutlibraries.Libs;
import com.mikepenz.aboutlibraries.LibsBuilder;
Expand Down Expand Up @@ -247,7 +248,7 @@ private void fetchEventList() {
}

private static void scheduleCleanupJob(Context context) {
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == 0) {
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) != ConnectionResult.SUCCESS) {
return;
}

Expand All @@ -265,7 +266,7 @@ private static Job createJob(FirebaseJobDispatcher dispatcher) {
.setRecurring(true)
.setTrigger(Trigger.executionWindow(0, 24 * 60 * 60))
.setRetryStrategy(RetryStrategy.DEFAULT_LINEAR)
.setConstraints(Constraint.ON_ANY_NETWORK, Constraint.DEVICE_CHARGING)
.setConstraints(Constraint.DEVICE_CHARGING)
.build();
}

Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/havenapp/main/PreferenceManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,10 @@ public int getMaxImages ()
return 10;
}

public String getBaseStoragePath() {
return appSharedPrefs.getString(CONFIG_BASE_STORAGE,CONFIG_BASE_STORAGE_DEFAULT);
}

public String getDefaultMediaStoragePath() {
return appSharedPrefs.getString(CONFIG_BASE_STORAGE,CONFIG_BASE_STORAGE_DEFAULT) + File.separator + getCurrentSession(); //phoneypot is the old code name for Haven
}
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/havenapp/main/dao/EventTriggerDAO.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ interface EventTriggerDAO {
@Delete
fun delete(eventTrigger: EventTrigger)

@Delete
fun deleteAll(eventTriggerList: List<EventTrigger>)

@Update
fun update(eventTrigger: EventTrigger)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.havenapp.main.service

import android.os.Environment
import android.util.Log
import com.firebase.jobdispatcher.JobParameters
import com.firebase.jobdispatcher.JobService
Expand Down Expand Up @@ -29,7 +30,7 @@ class RemoveDeletedFilesService: JobService() {
removeDeletedLogsFromDisk()
jobFinished(job, true)
Log.d(SERVICE_TAG, "Stopping Cleanup service")
}
}.start()

return true
}
Expand All @@ -40,25 +41,81 @@ class RemoveDeletedFilesService: JobService() {
val eventList = database.getEventDAO().getAllEvent()
val eventTriggerList = database.getEventTriggerDAO().getAllEventTriggers()

// keep a list of all invalid event triggers
// delete all invalid event triggers
val inValidEventTriggerList = mutableListOf<EventTrigger>()
eventTriggerList.filter { it.mEventId !in eventList.map { it.id } }.mapTo(inValidEventTriggerList) { it }

val currentFileList = mutableListOf<File>()
val storageDir = File(PreferenceManager(this).defaultMediaStoragePath)
currentFileList.addAll(storageDir.listFiles())
database.getEventTriggerDAO().deleteAll(inValidEventTriggerList)

val targetFileList = mutableListOf<File>()
currentFileList.filter { it.absolutePath in inValidEventTriggerList.map { it.mPath } }.mapTo(targetFileList) { it }
getAllFilesToBeDeleted(targetFileList)

Log.d(SERVICE_TAG, targetFileList.toString())

// delete these files from disk
for (file in targetFileList) {
file.delete()
targetFileList.filter { !it.isDirectory }.forEach { it.delete() }

// delete empty directories remaining in our storage directory
deleteEmptyDirs()
}

private fun getAllFilesToBeDeleted(targetFileList: MutableList<File>) {
val storageDir = File(Environment.getExternalStorageDirectory(),
PreferenceManager(this).baseStoragePath)

if (!storageDir.exists())
return

val allFilePaths = getAllFilePathInStorage(storageDir)
val eventTriggerPaths = getAllEventTriggerPath()

allFilePaths.filter { it !in eventTriggerPaths }.mapTo(targetFileList) { File(it) }
}

private fun deleteEmptyDirs() {
val storageDir = File(Environment.getExternalStorageDirectory(),
PreferenceManager(this).baseStoragePath)

if (!storageDir.exists())
return

val subDir = storageDir.list { dir, name -> File(dir, name).isDirectory }
subDir.filter { it != null }.forEach {
val dir = File(storageDir, it)
if (dir.exists() && dir.isDirectory && dir.list().isEmpty())
dir.delete()
}
}

private fun getAllFilePathInStorage(storageDir: File): List<String> {
val filePaths = mutableListOf<String>()

val currentFileList = mutableListOf<File>()

// remove entry of all invalid event triggers from database
for (inValidEventTrigger in inValidEventTriggerList) {
database.getEventTriggerDAO().delete(inValidEventTrigger)
getAllFileInStorageDir(storageDir, currentFileList)
currentFileList.addAll(storageDir.listFiles())

currentFileList.mapTo(filePaths) {
it.absolutePath
}

return filePaths
}

private fun getAllFileInStorageDir(storageDir: File, currentFileList: MutableList<File>) {
if (!storageDir.exists() || !storageDir.isDirectory)
return

currentFileList.addAll(storageDir.listFiles())

val subDir = storageDir.list { dir, name -> File(dir, name).isDirectory }
subDir.filter { it != null }.forEach { getAllFileInStorageDir(File(storageDir, it), currentFileList) }
}

private fun getAllEventTriggerPath(): List<String> {
val database = HavenEventDB.getDatabase(this)
val eventTriggerPathList = mutableListOf<String>()
database.getEventTriggerDAO().getAllEventTriggers().filter { it.mPath != null }
.mapTo(eventTriggerPathList) { it.mPath!! }
return eventTriggerPathList
}
}

0 comments on commit 6be6b28

Please sign in to comment.