diff --git a/vector/src/main/java/im/vector/riotx/core/utils/FileUtils.kt b/vector/src/main/java/im/vector/riotx/core/utils/FileUtils.kt index 3c39362ae6..4b2d0682d2 100644 --- a/vector/src/main/java/im/vector/riotx/core/utils/FileUtils.kt +++ b/vector/src/main/java/im/vector/riotx/core/utils/FileUtils.kt @@ -28,12 +28,9 @@ typealias ActionOnFile = (file: File) -> Boolean * Delete * ========================================================================================== */ -fun deleteAllFiles(context: Context) { - Timber.v("Delete cache dir:") - recursiveActionOnFile(context.cacheDir, ::deleteAction) - - Timber.v("Delete files dir:") - recursiveActionOnFile(context.filesDir, ::deleteAction) +fun deleteAllFiles(root: File) { + Timber.v("Delete ${root.absolutePath}") + recursiveActionOnFile(root, ::deleteAction) } private fun deleteAction(file: File): Boolean { @@ -130,4 +127,21 @@ fun getFileExtension(fileUri: String): String? { } return null -} \ No newline at end of file +} + +/* ========================================================================================== + * Size + * ========================================================================================== */ + +fun getSizeOfFiles(context: Context, root: File): Int { + Timber.v("Get size of " + root.absolutePath) + return if (root.isDirectory) { + root.list() + .map { + getSizeOfFiles(context, File(root, it)) + } + .fold(0, { acc, other -> acc + other }) + } else { + root.length().toInt() + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/MainActivity.kt b/vector/src/main/java/im/vector/riotx/features/MainActivity.kt index f8610c29eb..8ef3f0adcb 100644 --- a/vector/src/main/java/im/vector/riotx/features/MainActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/MainActivity.kt @@ -19,14 +19,20 @@ package im.vector.riotx.features import android.app.Activity import android.content.Intent import android.os.Bundle +import com.bumptech.glide.Glide import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.auth.Authenticator import im.vector.riotx.core.di.ActiveSessionHolder import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.platform.VectorBaseActivity +import im.vector.riotx.core.utils.deleteAllFiles import im.vector.riotx.features.home.HomeActivity import im.vector.riotx.features.login.LoginActivity +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import timber.log.Timber import javax.inject.Inject @@ -60,7 +66,22 @@ class MainActivity : VectorBaseActivity() { super.onCreate(savedInstanceState) val clearCache = intent.getBooleanExtra(EXTRA_CLEAR_CACHE, false) val clearCredentials = intent.getBooleanExtra(EXTRA_CLEAR_CREDENTIALS, false) + // Handle some wanted cleanup + if (clearCache || clearCredentials) { + GlobalScope.launch(Dispatchers.Main) { + // On UI Thread + Glide.get(this@MainActivity).clearMemory() + withContext(Dispatchers.IO) { + // On BG thread + Glide.get(this@MainActivity).clearDiskCache() + + // Also clear cache (Logs, etc...) + deleteAllFiles(this@MainActivity.cacheDir) + } + } + } + when { clearCredentials -> sessionHolder.getActiveSession().signOut(object : MatrixCallback { override fun onSuccess(data: Unit) { diff --git a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt index 0e1c448cf6..353884f462 100644 --- a/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/settings/VectorSettingsGeneralFragment.kt @@ -19,7 +19,6 @@ package im.vector.riotx.features.settings import android.app.Activity import android.content.Context import android.content.Intent -import android.os.AsyncTask import android.text.Editable import android.text.TextUtils import android.view.View @@ -33,6 +32,7 @@ import androidx.preference.EditTextPreference import androidx.preference.Preference import androidx.preference.PreferenceCategory import com.bumptech.glide.Glide +import com.bumptech.glide.load.engine.cache.DiskCache import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout import im.vector.riotx.R @@ -40,10 +40,7 @@ import im.vector.riotx.core.extensions.showPassword import im.vector.riotx.core.platform.SimpleTextWatcher import im.vector.riotx.core.preference.UserAvatarPreference import im.vector.riotx.core.preference.VectorPreference -import im.vector.riotx.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_CAMERA -import im.vector.riotx.core.utils.allGranted -import im.vector.riotx.core.utils.copyToClipboard -import im.vector.riotx.core.utils.toast +import im.vector.riotx.core.utils.* import im.vector.riotx.features.MainActivity import im.vector.riotx.features.themes.ThemeUtils import im.vector.riotx.features.workers.signout.SignOutUiWorker @@ -51,7 +48,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import java.lang.ref.WeakReference +import java.io.File import java.util.* class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { @@ -189,58 +186,32 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { // clear medias cache findPreference(PreferencesManager.SETTINGS_CLEAR_MEDIA_CACHE_PREFERENCE_KEY).let { - /* - TODO - MXMediaCache.getCachesSize(activity, object : SimpleApiCallback() { - override fun onSuccess(size: Long) { - if (null != activity) { - it.summary = android.text.format.Formatter.formatFileSize(activity, size) - } - } - }) - */ + val size = getSizeOfFiles(requireContext(), + File(requireContext().cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR)) + + it.summary = android.text.format.Formatter.formatFileSize(activity, size.toLong()) it.onPreferenceClickListener = Preference.OnPreferenceClickListener { - notImplemented() - - // TODO DECRYPT_FILE Quick implementation of clear cache, finish this GlobalScope.launch(Dispatchers.Main) { // On UI Thread + displayLoadingView() + Glide.get(requireContext()).clearMemory() + var newSize = 0 + withContext(Dispatchers.IO) { // On BG thread Glide.get(requireContext()).clearDiskCache() + + newSize = getSizeOfFiles(requireContext(), + File(requireContext().cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR)) } - } - /* TODO - displayLoadingView() + it.summary = android.text.format.Formatter.formatFileSize(activity, newSize.toLong()) - val task = ClearMediaCacheAsyncTask( - backgroundTask = { - session.mediaCache.clear() - activity?.let { it -> Glide.get(it).clearDiskCache() } - }, - onCompleteTask = { - hideLoadingView() - - MXMediaCache.getCachesSize(activity, object : SimpleApiCallback() { - override fun onSuccess(size: Long) { - it.summary = Formatter.formatFileSize(activity, size) - } - }) - } - ) - - try { - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) - } catch (e: Exception) { - Timber.e(e, "## session.getMediaCache().clear() failed " + e.message) - task.cancel(true) hideLoadingView() } - */ false } @@ -894,23 +865,6 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() { */ } - private class ClearMediaCacheAsyncTask internal constructor( - backgroundTask: () -> Unit, - onCompleteTask: () -> Unit - ) : AsyncTask() { - - private val backgroundTaskReference = WeakReference(backgroundTask) - private val onCompleteTaskReference = WeakReference(onCompleteTask) - override fun doInBackground(vararg params: Unit?) { - backgroundTaskReference.get()?.invoke() - } - - override fun onPostExecute(result: Unit?) { - super.onPostExecute(result) - onCompleteTaskReference.get()?.invoke() - } - } - companion object { private const val ADD_EMAIL_PREFERENCE_KEY = "ADD_EMAIL_PREFERENCE_KEY" private const val ADD_PHONE_NUMBER_PREFERENCE_KEY = "ADD_PHONE_NUMBER_PREFERENCE_KEY"