Show when launchable system apps do not allow backup

Even though we use d2d, backup is only forced for user apps.
This commit is contained in:
Torsten Grote 2024-09-27 16:31:15 -03:00
parent 751504c214
commit f7354a3d79
No known key found for this signature in database
GPG key ID: 3E5F77D92CF891FF
6 changed files with 24 additions and 13 deletions

View file

@ -196,6 +196,7 @@ const val ANCESTRAL_RECORD_KEY = "@ancestral_record@"
const val NO_DATA_END_SENTINEL = "@end@" const val NO_DATA_END_SENTINEL = "@end@"
const val GLOBAL_METADATA_KEY = "@meta@" const val GLOBAL_METADATA_KEY = "@meta@"
const val ERROR_BACKUP_CANCELLED: Int = BackupManager.ERROR_BACKUP_CANCELLED const val ERROR_BACKUP_CANCELLED: Int = BackupManager.ERROR_BACKUP_CANCELLED
const val ERROR_BACKUP_NOT_ALLOWED: Int = BackupManager.ERROR_BACKUP_NOT_ALLOWED
// TODO this doesn't work for LineageOS as they do public debug builds // TODO this doesn't work for LineageOS as they do public debug builds
fun isDebugBuild() = Build.TYPE == "userdebug" fun isDebugBuild() = Build.TYPE == "userdebug"

View file

@ -98,7 +98,7 @@ internal class AppListRetriever(
packageName = it.packageName, packageName = it.packageName,
enabled = settingsManager.isBackupEnabled(it.packageName), enabled = settingsManager.isBackupEnabled(it.packageName),
icon = getIconFromPackageManager(it.packageName), icon = getIconFromPackageManager(it.packageName),
name = getAppName(context, it.packageName).toString(), name = metadata?.name?.toString() ?: getAppName(context, it.packageName).toString(),
time = time, time = time,
size = metadata?.size, size = metadata?.size,
status = status, status = status,
@ -113,7 +113,8 @@ internal class AppListRetriever(
packageName = packageName, packageName = packageName,
enabled = settingsManager.isBackupEnabled(packageName), enabled = settingsManager.isBackupEnabled(packageName),
icon = getIconFromPackageManager(packageName), icon = getIconFromPackageManager(packageName),
name = it.loadLabel(context.packageManager).toString(), name = metadata?.name?.toString()
?: it.loadLabel(context.packageManager).toString(),
time = metadata?.time ?: 0, time = metadata?.time ?: 0,
size = metadata?.size, size = metadata?.size,
status = metadata?.state.toAppBackupState(), status = metadata?.state.toAppBackupState(),

View file

@ -24,7 +24,6 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.Adapter import androidx.recyclerview.widget.RecyclerView.Adapter
import androidx.recyclerview.widget.RecyclerView.NO_POSITION import androidx.recyclerview.widget.RecyclerView.NO_POSITION
import com.stevesoltys.seedvault.R import com.stevesoltys.seedvault.R
import com.stevesoltys.seedvault.ui.AppBackupState.FAILED_NOT_ALLOWED
import com.stevesoltys.seedvault.ui.AppBackupState.SUCCEEDED import com.stevesoltys.seedvault.ui.AppBackupState.SUCCEEDED
import com.stevesoltys.seedvault.ui.AppViewHolder import com.stevesoltys.seedvault.ui.AppViewHolder
import com.stevesoltys.seedvault.ui.toRelativeTime import com.stevesoltys.seedvault.ui.toRelativeTime
@ -114,13 +113,7 @@ internal class AppStatusAdapter(private val toggleListener: AppStatusToggleListe
startActivity(context, intent, null) startActivity(context, intent, null)
true true
} }
if (item.status == FAILED_NOT_ALLOWED) {
appStatus.visibility = INVISIBLE
progressBar.visibility = INVISIBLE
appInfo.visibility = GONE
} else {
setState(item.status, false) setState(item.status, false)
}
if (item.status == SUCCEEDED) { if (item.status == SUCCEEDED) {
appInfo.text = if (item.size == null) { appInfo.text = if (item.size == null) {
item.time.toRelativeTime(context) item.time.toRelativeTime(context)

View file

@ -28,7 +28,7 @@ enum class AppBackupState {
FAILED -> notShownString FAILED -> notShownString
FAILED_NO_DATA -> context.getString(R.string.backup_app_no_data) FAILED_NO_DATA -> context.getString(R.string.backup_app_no_data)
FAILED_WAS_STOPPED -> context.getString(R.string.backup_app_was_stopped) FAILED_WAS_STOPPED -> context.getString(R.string.backup_app_was_stopped)
FAILED_NOT_ALLOWED -> notShownString FAILED_NOT_ALLOWED -> context.getString(R.string.restore_app_not_allowed)
FAILED_NOT_INSTALLED -> context.getString(R.string.restore_app_not_installed) FAILED_NOT_INSTALLED -> context.getString(R.string.restore_app_not_installed)
FAILED_QUOTA_EXCEEDED -> context.getString(R.string.backup_app_quota_exceeded) FAILED_QUOTA_EXCEEDED -> context.getString(R.string.backup_app_quota_exceeded)
} }

View file

@ -16,8 +16,11 @@ import android.util.Log
import android.util.Log.INFO import android.util.Log.INFO
import android.util.Log.isLoggable import android.util.Log.isLoggable
import com.stevesoltys.seedvault.ERROR_BACKUP_CANCELLED import com.stevesoltys.seedvault.ERROR_BACKUP_CANCELLED
import com.stevesoltys.seedvault.ERROR_BACKUP_NOT_ALLOWED
import com.stevesoltys.seedvault.MAGIC_PACKAGE_MANAGER import com.stevesoltys.seedvault.MAGIC_PACKAGE_MANAGER
import com.stevesoltys.seedvault.R import com.stevesoltys.seedvault.R
import com.stevesoltys.seedvault.metadata.MetadataManager
import com.stevesoltys.seedvault.metadata.PackageState.NOT_ALLOWED
import com.stevesoltys.seedvault.repo.AppBackupManager import com.stevesoltys.seedvault.repo.AppBackupManager
import com.stevesoltys.seedvault.repo.hexFromProto import com.stevesoltys.seedvault.repo.hexFromProto
import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.settings.SettingsManager
@ -39,6 +42,7 @@ internal class NotificationBackupObserver(
private val nm: BackupNotificationManager by inject() private val nm: BackupNotificationManager by inject()
private val packageService: PackageService by inject() private val packageService: PackageService by inject()
private val settingsManager: SettingsManager by inject() private val settingsManager: SettingsManager by inject()
private val metadataManager: MetadataManager by inject()
private val appBackupManager: AppBackupManager by inject() private val appBackupManager: AppBackupManager by inject()
private var currentPackage: String? = null private var currentPackage: String? = null
private var numPackages: Int = 0 private var numPackages: Int = 0
@ -46,6 +50,9 @@ internal class NotificationBackupObserver(
private var pmCounted: Boolean = false private var pmCounted: Boolean = false
private var errorPackageName: String? = null private var errorPackageName: String? = null
private val launchableSystemApps by lazy {
packageService.launchableSystemApps.map { it.activityInfo.packageName }.toSet()
}
init { init {
// Inform the notification manager that a backup has started // Inform the notification manager that a backup has started
@ -77,7 +84,7 @@ internal class NotificationBackupObserver(
* that was initialized * that was initialized
* @param status Zero on success; a nonzero error code if the backup operation failed. * @param status Zero on success; a nonzero error code if the backup operation failed.
*/ */
override fun onResult(target: String?, status: Int) { override fun onResult(target: String, status: Int) {
if (isLoggable(TAG, INFO)) { if (isLoggable(TAG, INFO)) {
Log.i(TAG, "Completed. Target: $target, status: $status") Log.i(TAG, "Completed. Target: $target, status: $status")
} }
@ -91,7 +98,7 @@ internal class NotificationBackupObserver(
numPackages += 1 numPackages += 1
} }
// count package if success and not a system app // count package if success and not a system app
if (status == 0 && target != null && target != MAGIC_PACKAGE_MANAGER) try { if (status == 0 && target != MAGIC_PACKAGE_MANAGER) try {
val appInfo = context.packageManager.getApplicationInfo(target, 0) val appInfo = context.packageManager.getApplicationInfo(target, 0)
// exclude system apps from final count for now // exclude system apps from final count for now
if (appInfo.flags and FLAG_SYSTEM == 0) { if (appInfo.flags and FLAG_SYSTEM == 0) {
@ -101,6 +108,14 @@ internal class NotificationBackupObserver(
// should only happen for MAGIC_PACKAGE_MANAGER, but better save than sorry // should only happen for MAGIC_PACKAGE_MANAGER, but better save than sorry
Log.e(TAG, "Error getting ApplicationInfo: ", e) Log.e(TAG, "Error getting ApplicationInfo: ", e)
} }
// record status for not-allowed apps visible in UI
if (status == ERROR_BACKUP_NOT_ALLOWED) {
// this should only ever happen for system apps, as we use only d2d now
if (target in launchableSystemApps) {
val packageInfo = context.packageManager.getPackageInfo(target, 0)
metadataManager.onPackageBackupError(packageInfo, NOT_ALLOWED)
}
}
// Apps that get killed while interacting with their [BackupAgent] cancel the entire backup. // Apps that get killed while interacting with their [BackupAgent] cancel the entire backup.
// In order to prevent them from DoSing us, we remember them here to auto-disable them. // In order to prevent them from DoSing us, we remember them here to auto-disable them.

View file

@ -12,4 +12,5 @@ adb shell setprop log.tag.BackupTransportManager VERBOSE
adb shell setprop log.tag.KeyValueBackupJob VERBOSE adb shell setprop log.tag.KeyValueBackupJob VERBOSE
adb shell setprop log.tag.KeyValueBackupTask VERBOSE adb shell setprop log.tag.KeyValueBackupTask VERBOSE
adb shell setprop log.tag.TransportClient VERBOSE adb shell setprop log.tag.TransportClient VERBOSE
adb shell setprop log.tag.BackupAgent VERBOSE
adb shell setprop log.tag.PMBA VERBOSE adb shell setprop log.tag.PMBA VERBOSE