Skip to content

Commit

Permalink
add context menu data part selection, reduce code copying, ensure com…
Browse files Browse the repository at this point in the history
…mon names
  • Loading branch information
hg42 committed Oct 8, 2024
1 parent 0b52709 commit 582976b
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 154 deletions.
29 changes: 25 additions & 4 deletions src/main/java/com/machiav3lli/backup/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -197,17 +197,38 @@ const val ALT_MODE_DATA = 2
const val ALT_MODE_BOTH = 3

const val MODE_UNSET = 0b0000000
const val MODE_NONE = 0b0100000

const val MODE_APK = 0b0010000
const val MODE_DATA = 0b0001000
const val MODE_DATA_DE = 0b0000100
const val MODE_DATA_EXT = 0b0000010
const val MODE_DATA_OBB = 0b0000001
const val MODE_DATA_MEDIA = 0b1000000
const val BACKUP_FILTER_DEFAULT = 0b1111111
val possibleSchedModes =

const val MODE_NONE = 0b0100000 //TODO name? it's not a mode! BACKUP_FILTER_NONE?

val batchModes =
mapOf(
MODE_APK to "apk",
MODE_DATA to "data",
MODE_DATA_DE to "device-protected",
MODE_DATA_EXT to "external",
MODE_DATA_OBB to "obb",
MODE_DATA_MEDIA to "media"
)
val batchOperations = mapOf(
MODE_APK to "a",
MODE_DATA to "=d",
MODE_DATA_DE to "==p",
MODE_DATA_EXT to "===x",
MODE_DATA_OBB to "====o",
MODE_DATA_MEDIA to "=====m",
)
val batchModesSequence =
listOf(MODE_APK, MODE_DATA, MODE_DATA_DE, MODE_DATA_EXT, MODE_DATA_OBB, MODE_DATA_MEDIA)
val MODE_ALL = possibleSchedModes.reduce { a, b -> a.or(b) }

val MODE_ALL = batchModesSequence.reduce { a, b -> a.or(b) }
val BACKUP_FILTER_DEFAULT = MODE_ALL or MODE_NONE

val scheduleBackupModeChipItems = listOf(
ChipItem.Apk,
Expand Down
60 changes: 30 additions & 30 deletions src/main/java/com/machiav3lli/backup/actions/BackupAppAction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import com.machiav3lli.backup.MODE_DATA_EXT
import com.machiav3lli.backup.MODE_DATA_MEDIA
import com.machiav3lli.backup.MODE_DATA_OBB
import com.machiav3lli.backup.OABX
import com.machiav3lli.backup.batchModes
import com.machiav3lli.backup.batchOperations
import com.machiav3lli.backup.dbs.entity.Backup
import com.machiav3lli.backup.handler.BackupBuilder
import com.machiav3lli.backup.handler.LogsHandler
Expand Down Expand Up @@ -141,44 +143,42 @@ open class BackupAppAction(context: Context, work: AppActionWork?, shell: ShellH
pauseApp(type = "backup", wh = When.pre, packageName = app.packageName)

try {
if (backupMode and MODE_APK == MODE_APK) {
Timber.i("$app: Backing up package")
work?.setOperation("a")
fun doBackup(mode: Int, todo: () -> Unit) {
if ((backupMode and mode) != 0) {
Timber.i("$app: Backing up ${batchModes[mode]}")
work?.setOperation(batchOperations[mode]!!)
todo()
}
}
doBackup(MODE_APK) {
backupPackage(app, backupInstanceDir)
backupBuilder.setHasApk(true)
}
var backupCreated: Boolean
if (backupMode and MODE_DATA == MODE_DATA) {
Timber.i("$app: Backing up data")
work?.setOperation("=d")
backupCreated = backupData(app, backupInstanceDir, iv)
backupBuilder.setHasAppData(backupCreated)
doBackup(MODE_DATA) {
backupBuilder.setHasAppData(
backupData(app, backupInstanceDir, iv)
)
}
if (backupMode and MODE_DATA_DE == MODE_DATA_DE) {
Timber.i("$app: Backing up device's protected data")
work?.setOperation("==p")
backupCreated = backupDeviceProtectedData(app, backupInstanceDir, iv)
backupBuilder.setHasDevicesProtectedData(backupCreated)
doBackup(MODE_DATA_DE) {
backupBuilder.setHasDevicesProtectedData(
backupDeviceProtectedData(app, backupInstanceDir, iv)
)
}
if (backupMode and MODE_DATA_EXT == MODE_DATA_EXT) {
Timber.i("$app: Backing up external data")
work?.setOperation("===x")
backupCreated = backupExternalData(app, backupInstanceDir, iv)
backupBuilder.setHasExternalData(backupCreated)
doBackup(MODE_DATA_EXT) {
backupBuilder.setHasExternalData(
backupExternalData(app, backupInstanceDir, iv)
)
}
if (backupMode and MODE_DATA_OBB == MODE_DATA_OBB) {
Timber.i("$app: Backing up obb files")
work?.setOperation("====o")
backupCreated = backupObbData(app, backupInstanceDir, iv)
backupBuilder.setHasObbData(backupCreated)
doBackup(MODE_DATA_OBB) {
backupBuilder.setHasObbData(
backupObbData(app, backupInstanceDir, iv)
)
}
if (backupMode and MODE_DATA_MEDIA == MODE_DATA_MEDIA) {
Timber.i("$app: Backing up media files")
work?.setOperation("=====m")
backupCreated = backupMediaData(app, backupInstanceDir, iv)
backupBuilder.setHasMediaData(backupCreated)
doBackup(MODE_DATA_MEDIA) {
backupBuilder.setHasMediaData(
backupMediaData(app, backupInstanceDir, iv)
)
}

if (isCompressionEnabled()) {
Timber.i("$app: Compressing backup using ${getCompressionType()}")
backupBuilder.setCompressionType(getCompressionType())
Expand Down
184 changes: 86 additions & 98 deletions src/main/java/com/machiav3lli/backup/actions/RestoreAppAction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import com.machiav3lli.backup.MODE_DATA_MEDIA
import com.machiav3lli.backup.MODE_DATA_OBB
import com.machiav3lli.backup.OABX
import com.machiav3lli.backup.R
import com.machiav3lli.backup.batchModes
import com.machiav3lli.backup.batchOperations
import com.machiav3lli.backup.dbs.entity.Backup
import com.machiav3lli.backup.handler.ShellCommands
import com.machiav3lli.backup.handler.ShellHandler
Expand Down Expand Up @@ -107,14 +109,11 @@ open class RestoreAppAction(context: Context, work: AppActionWork?, shell: Shell
found?.dir
}
if (backupDir != null) {
if (backupMode and MODE_APK == MODE_APK) {
work?.setOperation("a")
restorePackage(backupDir, backup)
refreshAppInfo(context, app) // also waits for valid paths
}
if (backupMode != MODE_APK) {
restoreAllData(work, app, backup, backupDir, backupMode)
}

//==================================================
restoreAll(work, app, backup, backupDir, backupMode)
//==================================================

} else return ActionResult(
app,
null,
Expand Down Expand Up @@ -160,49 +159,38 @@ open class RestoreAppAction(context: Context, work: AppActionWork?, shell: Shell
}

@Throws(CryptoSetupException::class, RestoreFailedException::class)
protected open fun restoreAllData(
protected open fun restoreAll(
work: AppActionWork?,
app: Package,
backup: Backup,
backupDir: StorageFile,
backupMode: Int,
) {
if (!isPlausiblePath(app.dataPath, app.packageName))
refreshAppInfo(context, app) // wait for valid paths
if (backup.hasAppData && backupMode and MODE_DATA == MODE_DATA) {
Timber.i("<${backup.packageName}> Restoring app's data")
work?.setOperation("=d")
fun doRestore(mode: Int, cond: Boolean, todo: () -> Unit) {
if (cond && (backupMode and mode) != 0) {
Timber.i("$app: Restoring ${batchModes[mode]}")
work?.setOperation(batchOperations[mode]!!)
todo()
}
}
doRestore(MODE_APK, backup.hasApk) {
restorePackage(backupDir, backup)
}
refreshAppInfo(context, app) // also waits for valid paths
doRestore(MODE_DATA, backup.hasAppData) {
restoreData(app, backup, backupDir)
} else {
Timber.i("<${backup.packageName}> Skip restoring app's data; not part of the backup or restore mode")
}
if (backup.hasDevicesProtectedData && backupMode and MODE_DATA_DE == MODE_DATA_DE) {
Timber.i("<${backup.packageName}> Restoring app's device-protected data")
work?.setOperation("==p")
doRestore(MODE_DATA_DE, backup.hasDevicesProtectedData) {
restoreDeviceProtectedData(app, backup, backupDir)
} else {
Timber.i("<${backup.packageName}> Skip restoring app's device protected data; not part of the backup or restore mode")
}
if (backup.hasExternalData && backupMode and MODE_DATA_EXT == MODE_DATA_EXT) {
Timber.i("<${backup.packageName}> Restoring app's external data")
work?.setOperation("===x")
doRestore(MODE_DATA_EXT, backup.hasExternalData) {
restoreExternalData(app, backup, backupDir)
} else {
Timber.i("<${backup.packageName}> Skip restoring app's external data; not part of the backup or restore mode")
}
if (backup.hasObbData && backupMode and MODE_DATA_OBB == MODE_DATA_OBB) {
Timber.i("<${backup.packageName}> Restoring app's obb files")
work?.setOperation("====o")
doRestore(MODE_DATA_OBB, backup.hasObbData) {
restoreObbData(app, backup, backupDir)
} else {
Timber.i("<${backup.packageName}> Skip restoring app's obb files; not part of the backup or restore mode")
}
if (backup.hasMediaData && backupMode and MODE_DATA_MEDIA == MODE_DATA_MEDIA) {
Timber.i("<${backup.packageName}> Restoring app's media files")
work?.setOperation("=====m")
doRestore(MODE_DATA_MEDIA, backup.hasMediaData) {
restoreMediaData(app, backup, backupDir)
} else {
Timber.i("<${backup.packageName}> Skip restoring app's media files; not part of the backup or restore mode")
}
}

Expand Down Expand Up @@ -422,32 +410,32 @@ open class RestoreAppAction(context: Context, work: AppActionWork?, shell: Shell
}
}

//TODO wech
//@Throws(RestoreFailedException::class)
//private fun genericRestoreDataByCopying(
// targetPath: String,
// backupInstanceDir: StorageFile,
// what: String,
//) {
// try {
// val backupDirToRestore = backupInstanceDir.findFile(what)
// ?: throw RestoreFailedException(
// String.format(
// LOG_DIR_IS_MISSING_CANNOT_RESTORE,
// what
// )
// )
// suRecursiveCopyFileFromDocument(backupDirToRestore, targetPath)
// } catch (e: IOException) {
// throw RestoreFailedException("Could not read the input file due to IOException", e)
// } catch (e: ShellCommandFailedException) {
// val error = extractErrorMessage(e.shellResult)
// throw RestoreFailedException(
// "Shell command failed: ${e.command}\n$error",
// e
// )
// }
//}
//TODO wech
//@Throws(RestoreFailedException::class)
//private fun genericRestoreDataByCopying(
// targetPath: String,
// backupInstanceDir: StorageFile,
// what: String,
//) {
// try {
// val backupDirToRestore = backupInstanceDir.findFile(what)
// ?: throw RestoreFailedException(
// String.format(
// LOG_DIR_IS_MISSING_CANNOT_RESTORE,
// what
// )
// )
// suRecursiveCopyFileFromDocument(backupDirToRestore, targetPath)
// } catch (e: IOException) {
// throw RestoreFailedException("Could not read the input file due to IOException", e)
// } catch (e: ShellCommandFailedException) {
// val error = extractErrorMessage(e.shellResult)
// throw RestoreFailedException(
// "Shell command failed: ${e.command}\n$error",
// e
// )
// }
//}

@Throws(RestoreFailedException::class, CryptoSetupException::class, IOException::class)
protected fun openArchiveFile(
Expand Down Expand Up @@ -963,25 +951,25 @@ open class RestoreAppAction(context: Context, work: AppActionWork?, shell: Shell
//
//} else {

val dataType = BACKUP_DIR_OBB_FILES
val backupArchive = findBackupArchive(dataType, backup, backupDir)
val dataType = BACKUP_DIR_OBB_FILES
val backupArchive = findBackupArchive(dataType, backup, backupDir)

val uidgidcon = getOwnerGroupContextWithWorkaround(app, extractTo)
genericRestoreFromArchive(
dataType,
backupArchive.file,
extractTo,
backupArchive.isCompressed,
backupArchive.compressionType,
backupArchive.isEncrypted,
backup.iv,
context.externalCacheDir?.let { RootFile(it) },
)
genericRestorePermissions(
dataType,
extractTo,
uidgidcon
)
val uidgidcon = getOwnerGroupContextWithWorkaround(app, extractTo)
genericRestoreFromArchive(
dataType,
backupArchive.file,
extractTo,
backupArchive.isCompressed,
backupArchive.compressionType,
backupArchive.isEncrypted,
backup.iv,
context.externalCacheDir?.let { RootFile(it) },
)
genericRestorePermissions(
dataType,
extractTo,
uidgidcon
)
//}
}

Expand All @@ -1008,25 +996,25 @@ open class RestoreAppAction(context: Context, work: AppActionWork?, shell: Shell
//
//} else {

val dataType = BACKUP_DIR_MEDIA_FILES
val backupArchive = findBackupArchive(dataType, backup, backupDir)
val dataType = BACKUP_DIR_MEDIA_FILES
val backupArchive = findBackupArchive(dataType, backup, backupDir)

val uidgidcon = getOwnerGroupContextWithWorkaround(app, extractTo)
genericRestoreFromArchive(
dataType,
backupArchive.file,
extractTo,
backupArchive.isCompressed,
backupArchive.compressionType,
backupArchive.isEncrypted,
backup.iv,
context.externalCacheDir?.let { RootFile(it) }
)
genericRestorePermissions(
dataType,
extractTo,
uidgidcon
)
val uidgidcon = getOwnerGroupContextWithWorkaround(app, extractTo)
genericRestoreFromArchive(
dataType,
backupArchive.file,
extractTo,
backupArchive.isCompressed,
backupArchive.compressionType,
backupArchive.isEncrypted,
backup.iv,
context.externalCacheDir?.let { RootFile(it) }
)
genericRestorePermissions(
dataType,
extractTo,
uidgidcon
)
//}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class RestoreSpecialAction(context: Context, work: AppActionWork?, shell: ShellH
RestoreAppAction(context, work, shell) {

@Throws(CryptoSetupException::class, RestoreFailedException::class)
override fun restoreAllData(
override fun restoreAll(
work: AppActionWork?,
app: Package,
backup: Backup,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import com.machiav3lli.backup.MODE_UNSET
import com.machiav3lli.backup.R
import com.machiav3lli.backup.dbs.entity.AppInfo
import com.machiav3lli.backup.items.Package
import com.machiav3lli.backup.possibleSchedModes
import com.machiav3lli.backup.batchModesSequence
import com.machiav3lli.backup.utils.backupModeIfActive

@Composable
Expand All @@ -43,7 +43,7 @@ fun BackupDialogUI(
val context = LocalContext.current

val modePairs = mutableMapOf<Int, String>()
val possibleModes = possibleSchedModes.toMutableList()
val possibleModes = batchModesSequence.toMutableList()

val selectedMode = mutableSetOf<Int>()

Expand Down
Loading

0 comments on commit 582976b

Please sign in to comment.