Cleaned up backup status list by separating system data and apps
This commit is contained in:
parent
1ac613f588
commit
a447895079
3 changed files with 63 additions and 49 deletions
|
@ -11,7 +11,7 @@ import android.content.pm.PackageManager
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
import com.stevesoltys.seedvault.MAGIC_PACKAGE_MANAGER
|
import androidx.appcompat.content.res.AppCompatResources.getDrawable
|
||||||
import com.stevesoltys.seedvault.R
|
import com.stevesoltys.seedvault.R
|
||||||
import com.stevesoltys.seedvault.metadata.MetadataManager
|
import com.stevesoltys.seedvault.metadata.MetadataManager
|
||||||
import com.stevesoltys.seedvault.metadata.PackageState
|
import com.stevesoltys.seedvault.metadata.PackageState
|
||||||
|
@ -25,16 +25,13 @@ import com.stevesoltys.seedvault.ui.AppBackupState.FAILED_QUOTA_EXCEEDED
|
||||||
import com.stevesoltys.seedvault.ui.AppBackupState.FAILED_WAS_STOPPED
|
import com.stevesoltys.seedvault.ui.AppBackupState.FAILED_WAS_STOPPED
|
||||||
import com.stevesoltys.seedvault.ui.AppBackupState.NOT_YET_BACKED_UP
|
import com.stevesoltys.seedvault.ui.AppBackupState.NOT_YET_BACKED_UP
|
||||||
import com.stevesoltys.seedvault.ui.AppBackupState.SUCCEEDED
|
import com.stevesoltys.seedvault.ui.AppBackupState.SUCCEEDED
|
||||||
|
import com.stevesoltys.seedvault.ui.PACKAGE_NAME_CONTACTS
|
||||||
import com.stevesoltys.seedvault.ui.notification.getAppName
|
import com.stevesoltys.seedvault.ui.notification.getAppName
|
||||||
|
import com.stevesoltys.seedvault.ui.systemData
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
private const val TAG = "AppListRetriever"
|
private const val TAG = "AppListRetriever"
|
||||||
|
|
||||||
private const val PACKAGE_NAME_SMS = "com.android.providers.telephony"
|
|
||||||
private const val PACKAGE_NAME_SETTINGS = "com.android.providers.settings"
|
|
||||||
private const val PACKAGE_NAME_CALL_LOG = "com.android.calllogbackup"
|
|
||||||
private const val PACKAGE_NAME_CONTACTS = "org.calyxos.backup.contacts"
|
|
||||||
|
|
||||||
sealed class AppListItem
|
sealed class AppListItem
|
||||||
|
|
||||||
data class AppStatus(
|
data class AppStatus(
|
||||||
|
@ -64,7 +61,7 @@ internal class AppListRetriever(
|
||||||
|
|
||||||
val appListSections = linkedMapOf(
|
val appListSections = linkedMapOf(
|
||||||
AppSectionTitle(R.string.backup_section_system) to getSpecialApps(),
|
AppSectionTitle(R.string.backup_section_system) to getSpecialApps(),
|
||||||
AppSectionTitle(R.string.backup_section_user) to getUserApps(),
|
AppSectionTitle(R.string.backup_section_user) to getApps(),
|
||||||
AppSectionTitle(R.string.backup_section_not_allowed) to getNotAllowedApps()
|
AppSectionTitle(R.string.backup_section_not_allowed) to getNotAllowedApps()
|
||||||
).filter { it.value.isNotEmpty() }
|
).filter { it.value.isNotEmpty() }
|
||||||
|
|
||||||
|
@ -74,13 +71,7 @@ internal class AppListRetriever(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSpecialApps(): List<AppListItem> {
|
private fun getSpecialApps(): List<AppListItem> {
|
||||||
val specialPackages = listOf(
|
return systemData.map { (packageName, data) ->
|
||||||
Pair(PACKAGE_NAME_SMS, R.string.backup_sms),
|
|
||||||
Pair(PACKAGE_NAME_SETTINGS, R.string.backup_settings),
|
|
||||||
Pair(PACKAGE_NAME_CALL_LOG, R.string.backup_call_log),
|
|
||||||
Pair(PACKAGE_NAME_CONTACTS, R.string.backup_contacts)
|
|
||||||
)
|
|
||||||
return specialPackages.map { (packageName, stringId) ->
|
|
||||||
val metadata = metadataManager.getPackageMetadata(packageName)
|
val metadata = metadataManager.getPackageMetadata(packageName)
|
||||||
val status = if (packageName == PACKAGE_NAME_CONTACTS && metadata?.state == null) {
|
val status = if (packageName == PACKAGE_NAME_CONTACTS && metadata?.state == null) {
|
||||||
// handle local contacts backup specially as it might not be installed
|
// handle local contacts backup specially as it might not be installed
|
||||||
|
@ -90,31 +81,21 @@ internal class AppListRetriever(
|
||||||
AppStatus(
|
AppStatus(
|
||||||
packageName = packageName,
|
packageName = packageName,
|
||||||
enabled = settingsManager.isBackupEnabled(packageName),
|
enabled = settingsManager.isBackupEnabled(packageName),
|
||||||
icon = getIcon(packageName),
|
icon = data.iconRes?.let { getDrawable(context, it) }
|
||||||
name = context.getString(stringId),
|
?: getIconFromPackageManager(packageName),
|
||||||
|
name = context.getString(data.nameRes),
|
||||||
time = metadata?.time ?: 0,
|
time = metadata?.time ?: 0,
|
||||||
size = metadata?.size,
|
size = metadata?.size,
|
||||||
status = status,
|
status = status,
|
||||||
isSpecial = true
|
isSpecial = true,
|
||||||
)
|
|
||||||
} + packageService.launchableSystemApps.map {
|
|
||||||
val packageName = it.activityInfo.packageName
|
|
||||||
val metadata = metadataManager.getPackageMetadata(packageName)
|
|
||||||
AppStatus(
|
|
||||||
packageName = packageName,
|
|
||||||
enabled = settingsManager.isBackupEnabled(packageName),
|
|
||||||
icon = getIcon(packageName),
|
|
||||||
name = it.loadLabel(context.packageManager).toString(),
|
|
||||||
time = metadata?.time ?: 0,
|
|
||||||
size = metadata?.size,
|
|
||||||
status = metadata?.state.toAppBackupState(),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getUserApps(): List<AppStatus> {
|
private fun getApps(): List<AppStatus> {
|
||||||
val locale = Locale.getDefault()
|
val userPackages = mutableSetOf<String>()
|
||||||
return packageService.userApps.map {
|
val userApps = packageService.userApps.map {
|
||||||
|
userPackages.add(it.packageName)
|
||||||
val metadata = metadataManager.getPackageMetadata(it.packageName)
|
val metadata = metadataManager.getPackageMetadata(it.packageName)
|
||||||
val time = metadata?.time ?: 0
|
val time = metadata?.time ?: 0
|
||||||
val status = metadata?.state.toAppBackupState()
|
val status = metadata?.state.toAppBackupState()
|
||||||
|
@ -124,13 +105,28 @@ internal class AppListRetriever(
|
||||||
AppStatus(
|
AppStatus(
|
||||||
packageName = it.packageName,
|
packageName = it.packageName,
|
||||||
enabled = settingsManager.isBackupEnabled(it.packageName),
|
enabled = settingsManager.isBackupEnabled(it.packageName),
|
||||||
icon = getIcon(it.packageName),
|
icon = getIconFromPackageManager(it.packageName),
|
||||||
name = getAppName(context, it.packageName).toString(),
|
name = getAppName(context, it.packageName).toString(),
|
||||||
time = time,
|
time = time,
|
||||||
size = metadata?.size,
|
size = metadata?.size,
|
||||||
status = status
|
status = status,
|
||||||
)
|
)
|
||||||
}.sortedBy { it.name.lowercase(locale) }
|
}
|
||||||
|
val locale = Locale.getDefault()
|
||||||
|
return (userApps + packageService.launchableSystemApps.mapNotNull {
|
||||||
|
val packageName = it.activityInfo.packageName
|
||||||
|
if (packageName in userPackages) return@mapNotNull null
|
||||||
|
val metadata = metadataManager.getPackageMetadata(packageName)
|
||||||
|
AppStatus(
|
||||||
|
packageName = packageName,
|
||||||
|
enabled = settingsManager.isBackupEnabled(packageName),
|
||||||
|
icon = getIconFromPackageManager(packageName),
|
||||||
|
name = it.loadLabel(context.packageManager).toString(),
|
||||||
|
time = metadata?.time ?: 0,
|
||||||
|
size = metadata?.size,
|
||||||
|
status = metadata?.state.toAppBackupState(),
|
||||||
|
)
|
||||||
|
}).sortedBy { it.name.lowercase(locale) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getNotAllowedApps(): List<AppStatus> {
|
private fun getNotAllowedApps(): List<AppStatus> {
|
||||||
|
@ -139,28 +135,19 @@ internal class AppListRetriever(
|
||||||
AppStatus(
|
AppStatus(
|
||||||
packageName = it.packageName,
|
packageName = it.packageName,
|
||||||
enabled = settingsManager.isBackupEnabled(it.packageName),
|
enabled = settingsManager.isBackupEnabled(it.packageName),
|
||||||
icon = getIcon(it.packageName),
|
icon = getIconFromPackageManager(it.packageName),
|
||||||
name = getAppName(context, it.packageName).toString(),
|
name = getAppName(context, it.packageName).toString(),
|
||||||
time = 0,
|
time = 0,
|
||||||
size = null,
|
size = null,
|
||||||
status = FAILED_NOT_ALLOWED
|
status = FAILED_NOT_ALLOWED,
|
||||||
)
|
)
|
||||||
}.sortedBy { it.name.lowercase(locale) }
|
}.sortedBy { it.name.lowercase(locale) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getIcon(packageName: String): Drawable = when (packageName) {
|
|
||||||
MAGIC_PACKAGE_MANAGER -> context.getDrawable(R.drawable.ic_launcher_default)!!
|
|
||||||
PACKAGE_NAME_SMS -> context.getDrawable(R.drawable.ic_message)!!
|
|
||||||
PACKAGE_NAME_SETTINGS -> context.getDrawable(R.drawable.ic_settings)!!
|
|
||||||
PACKAGE_NAME_CALL_LOG -> context.getDrawable(R.drawable.ic_call)!!
|
|
||||||
PACKAGE_NAME_CONTACTS -> context.getDrawable(R.drawable.ic_contacts)!!
|
|
||||||
else -> getIconFromPackageManager(packageName)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getIconFromPackageManager(packageName: String): Drawable = try {
|
private fun getIconFromPackageManager(packageName: String): Drawable = try {
|
||||||
pm.getApplicationIcon(packageName)
|
pm.getApplicationIcon(packageName)
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
context.getDrawable(R.drawable.ic_launcher_default)!!
|
getDrawable(context, R.drawable.ic_launcher_default)!!
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun PackageState?.toAppBackupState(): AppBackupState = when (this) {
|
private fun PackageState?.toAppBackupState(): AppBackupState = when (this) {
|
||||||
|
|
27
app/src/main/java/com/stevesoltys/seedvault/ui/SystemData.kt
Normal file
27
app/src/main/java/com/stevesoltys/seedvault/ui/SystemData.kt
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 The Calyx Institute
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.stevesoltys.seedvault.ui
|
||||||
|
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import com.stevesoltys.seedvault.R
|
||||||
|
|
||||||
|
internal const val PACKAGE_NAME_SMS = "com.android.providers.telephony"
|
||||||
|
internal const val PACKAGE_NAME_SETTINGS = "com.android.providers.settings"
|
||||||
|
internal const val PACKAGE_NAME_CALL_LOG = "com.android.calllogbackup"
|
||||||
|
internal const val PACKAGE_NAME_CONTACTS = "org.calyxos.backup.contacts"
|
||||||
|
|
||||||
|
val systemData = mapOf(
|
||||||
|
PACKAGE_NAME_SMS to SystemData(R.string.backup_sms, R.drawable.ic_message),
|
||||||
|
PACKAGE_NAME_SETTINGS to SystemData(R.string.backup_settings, R.drawable.ic_settings),
|
||||||
|
PACKAGE_NAME_CALL_LOG to SystemData(R.string.backup_call_log, R.drawable.ic_call),
|
||||||
|
PACKAGE_NAME_CONTACTS to SystemData(R.string.backup_contacts, R.drawable.ic_contacts),
|
||||||
|
)
|
||||||
|
|
||||||
|
data class SystemData(
|
||||||
|
@StringRes val nameRes: Int,
|
||||||
|
@DrawableRes val iconRes: Int?,
|
||||||
|
)
|
|
@ -177,12 +177,12 @@
|
||||||
|
|
||||||
<!-- App Backup and Restore State -->
|
<!-- App Backup and Restore State -->
|
||||||
|
|
||||||
<string name="backup_section_system">System apps</string>
|
<string name="backup_section_system">System data</string>
|
||||||
<string name="backup_sms">SMS text messages</string>
|
<string name="backup_sms">SMS text messages</string>
|
||||||
<string name="backup_settings">Device settings</string>
|
<string name="backup_settings">Device settings</string>
|
||||||
<string name="backup_call_log">Call history</string>
|
<string name="backup_call_log">Call history</string>
|
||||||
<string name="backup_contacts">Local contacts</string>
|
<string name="backup_contacts">Local contacts</string>
|
||||||
<string name="backup_section_user">Installed apps</string>
|
<string name="backup_section_user">Apps</string>
|
||||||
<!-- This text gets shown for apps that the OS did not try to backup for whatever reason e.g. no backup was run yet -->
|
<!-- This text gets shown for apps that the OS did not try to backup for whatever reason e.g. no backup was run yet -->
|
||||||
<string name="backup_app_not_yet_backed_up">Waiting to back up…</string>
|
<string name="backup_app_not_yet_backed_up">Waiting to back up…</string>
|
||||||
<string name="restore_app_not_yet_backed_up">Was not yet backed up</string>
|
<string name="restore_app_not_yet_backed_up">Was not yet backed up</string>
|
||||||
|
|
Loading…
Add table
Reference in a new issue