diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index eadc02d3..eb854a97 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -67,6 +67,12 @@ android:name="android.permission.INTERACT_ACROSS_USERS_FULL" tools:ignore="ProtectedPermissions" /> + + + + + + +// isAppEligibleForBackup(packageInfo, +// if (packageInfo.applicationInfo.backupAgentName != null) +// pkg.applicationInfo.flags and FLAG_FULL_BACKUP_ONLY != 0 else true) +// } // add magic @pm@ package (PACKAGE_MANAGER_SENTINEL) which holds package manager data - val packageArray = eligibleApps.toMutableList() + val packageArray = packages.toMutableList() packageArray.add(MAGIC_PACKAGE_MANAGER) return packageArray.toTypedArray() @@ -73,7 +73,7 @@ internal class PackageService( // because the package info is used by [ApkBackup] which needs signing info. return packageManager.getInstalledPackages(GET_SIGNING_CERTIFICATES) .filter { packageInfo -> - packageInfo.doesNotGetBackedUp() && // only apps that do not allow backup + packageInfo.doesNotGetBackedUp(context, myUserId) && // only apps that do not allow backup !packageInfo.isNotUpdatedSystemApp() && // and are not vanilla system apps packageInfo.packageName != context.packageName // not this app }.sortedBy { packageInfo -> @@ -94,7 +94,7 @@ internal class PackageService( val userApps: List @WorkerThread get() = packageManager.getInstalledPackages(GET_INSTRUMENTATION).filter { packageInfo -> - packageInfo.isUserVisible(context) && packageInfo.allowsBackup() + packageInfo.isUserVisible(context) && packageInfo.allowsBackup(context, myUserId) } /** @@ -103,7 +103,7 @@ internal class PackageService( val userNotAllowedApps: List @WorkerThread get() = packageManager.getInstalledPackages(0).filter { packageInfo -> - !packageInfo.allowsBackup() && !packageInfo.isSystemApp() + !packageInfo.allowsBackup(context, myUserId) && !packageInfo.isSystemApp() } val expectedAppTotals: ExpectedAppTotals @@ -114,7 +114,7 @@ internal class PackageService( packageManager.getInstalledPackages(GET_INSTRUMENTATION).forEach { packageInfo -> if (packageInfo.isUserVisible(context)) { appsTotal++ - if (packageInfo.doesNotGetBackedUp()) { + if (packageInfo.doesNotGetBackedUp(context, myUserId)) { appsOptOut++ } } @@ -157,9 +157,20 @@ internal fun PackageInfo.isSystemApp(): Boolean { return applicationInfo.flags and FLAG_SYSTEM != 0 } -internal fun PackageInfo.allowsBackup(): Boolean { +internal fun PackageInfo.allowsBackup(context: Context, userId: Int): Boolean { if (packageName == MAGIC_PACKAGE_MANAGER || applicationInfo == null) return false - return applicationInfo.flags and FLAG_ALLOW_BACKUP != 0 + + // This must be kept in sync with frameworks/base/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java + val isSystemApp = applicationInfo.flags and FLAG_SYSTEM != 0 + val ignoreAllowBackup = !isSystemApp + && (context.checkSelfPermission(Manifest.permission.LOG_COMPAT_CHANGE) + == PackageManager.PERMISSION_GRANTED) + && (context.checkSelfPermission(Manifest.permission.READ_COMPAT_CHANGE_CONFIG) + == PackageManager.PERMISSION_GRANTED) + && CompatChanges.isChangeEnabled(IGNORE_ALLOW_BACKUP_IN_D2D, packageName, + UserHandle.of(userId)) + val allowBackup = applicationInfo.flags and FLAG_ALLOW_BACKUP != 0 + return ignoreAllowBackup || allowBackup } /** @@ -173,10 +184,21 @@ internal fun PackageInfo.isNotUpdatedSystemApp(): Boolean { return isSystemApp && !isUpdatedSystemApp } -internal fun PackageInfo.doesNotGetBackedUp(): Boolean { +internal fun PackageInfo.doesNotGetBackedUp(context: Context, userId: Int): Boolean { if (packageName == MAGIC_PACKAGE_MANAGER || applicationInfo == null) return true - return applicationInfo.flags and FLAG_ALLOW_BACKUP == 0 || // does not allow backup - applicationInfo.flags and FLAG_STOPPED != 0 // is stopped + + // This must be kept in sync with frameworks/base/services/backup/java/com/android/server/backup/utils/BackupEligibilityRules.java + val isSystemApp = applicationInfo.flags and FLAG_SYSTEM != 0 + val ignoreAllowBackup = !isSystemApp + && (context.checkSelfPermission(Manifest.permission.LOG_COMPAT_CHANGE) + == PackageManager.PERMISSION_GRANTED) + && (context.checkSelfPermission(Manifest.permission.READ_COMPAT_CHANGE_CONFIG) + == PackageManager.PERMISSION_GRANTED) + && CompatChanges.isChangeEnabled(IGNORE_ALLOW_BACKUP_IN_D2D, packageName, + UserHandle.of(userId)) + val allowBackup = applicationInfo.flags and FLAG_ALLOW_BACKUP != 0 + val stopped = applicationInfo.flags and FLAG_STOPPED != 0 + return (!ignoreAllowBackup && !allowBackup) || stopped } internal fun PackageInfo.isStopped(): Boolean { diff --git a/permissions_com.stevesoltys.seedvault.xml b/permissions_com.stevesoltys.seedvault.xml index 43cc5c5d..1f3204e7 100644 --- a/permissions_com.stevesoltys.seedvault.xml +++ b/permissions_com.stevesoltys.seedvault.xml @@ -5,6 +5,8 @@ + +