Skip to content

Commit

Permalink
Workaround: Request non-incremental backup to include @pm@
Browse files Browse the repository at this point in the history
The fake package manager package is essential for the backup, but when its data doesn't change and we request a normal incremental backup, it doesn't get included, because our transport doesn't even get called for it. Only the BackupMonitor gets a hint that it had no (new?) data via LOG_EVENT_ID_NO_DATA_TO_SEND.
This behavior started with Android 15.
  • Loading branch information
grote committed Oct 2, 2024
1 parent 1dee14f commit a406e18
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import android.provider.Settings
import android.provider.Settings.Secure.ANDROID_ID
import com.google.protobuf.ByteString
import com.stevesoltys.seedvault.Clock
import com.stevesoltys.seedvault.MAGIC_PACKAGE_MANAGER
import com.stevesoltys.seedvault.header.VERSION
import com.stevesoltys.seedvault.metadata.BackupType
import com.stevesoltys.seedvault.metadata.MetadataManager
Expand Down Expand Up @@ -134,6 +135,8 @@ internal class SnapshotCreator(
putAllApps(appBuilderMap.mapValues { it.value.build() })
putAllBlobs(this@SnapshotCreator.blobsMap)
}.build()
// may as well fail the backup, if @pm@ isn't in it
check(MAGIC_PACKAGE_MANAGER in snapshot.appsMap) { "No metadata for @pm@" }
appBuilderMap.clear()
snapshotBuilder.clear()
blobsMap.clear()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import android.app.backup.BackupTransport.TRANSPORT_OK
import android.content.pm.PackageInfo
import android.os.ParcelFileDescriptor
import android.util.Log
import com.stevesoltys.seedvault.NO_DATA_END_SENTINEL
import com.stevesoltys.seedvault.repo.BackupData
import com.stevesoltys.seedvault.repo.BackupReceiver
import java.io.IOException
Expand Down Expand Up @@ -52,6 +53,8 @@ internal class KVBackup(
else -> Log.i(TAG, "Performing K/V backup for $packageName")
}
check(state == null) { "Have unexpected state for ${state?.packageInfo?.packageName}" }
// This fake package name just signals that we've seen all packages without new data
if (packageName == NO_DATA_END_SENTINEL) return TRANSPORT_OK

// initialize state
state = KVBackupState(packageInfo = packageInfo, db = dbManager.getDb(packageName))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,17 @@ internal class PackageService(
logPackages(packages)
}

val eligibleApps = packages.filter(::shouldIncludeAppInBackup).toTypedArray()
val eligibleApps = packages.filter(::shouldIncludeAppInBackup).toMutableList()
// log eligible packages
if (Log.isLoggable(TAG, INFO)) {
Log.i(TAG, "Filtering left ${eligibleApps.size} eligible packages:")
logPackages(eligibleApps.toList())
logPackages(eligibleApps)
}

// add magic @pm@ package (PACKAGE_MANAGER_SENTINEL) which holds package manager data
val packageArray = eligibleApps.toMutableList()
packageArray.add(MAGIC_PACKAGE_MANAGER)
eligibleApps.add(0, MAGIC_PACKAGE_MANAGER)

return packageArray
return eligibleApps
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package com.stevesoltys.seedvault.worker

import android.app.backup.BackupManager
import android.app.backup.BackupManager.FLAG_NON_INCREMENTAL_BACKUP
import android.app.backup.IBackupManager
import android.content.Context
import android.os.RemoteException
Expand Down Expand Up @@ -82,7 +83,7 @@ internal class BackupRequester(
private fun request(chunk: Array<String>): Boolean {
Log.i(TAG, "${chunk.toList()}")
val result = try {
backupManager.requestBackup(chunk, observer, monitor, 0)
backupManager.requestBackup(chunk, observer, monitor, FLAG_NON_INCREMENTAL_BACKUP)
} catch (e: RemoteException) {
Log.e(TAG, "Error during backup: ", e)
val nm: BackupNotificationManager = GlobalContext.get().get()
Expand Down

0 comments on commit a406e18

Please sign in to comment.