Loading core/java/android/app/backup/BackupManagerMonitor.java +6 −0 Original line number Diff line number Diff line Loading @@ -172,6 +172,12 @@ public class BackupManagerMonitor { public static final int LOG_EVENT_ID_NO_PACKAGES = 49; public static final int LOG_EVENT_ID_TRANSPORT_IS_NULL = 50; /** * The transport returned {@link BackupTransport#TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED}. * @hide */ public static final int LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED = 51; Loading core/java/android/app/backup/BackupTransport.java +26 −3 Original line number Diff line number Diff line Loading @@ -51,6 +51,20 @@ public class BackupTransport { public static final int AGENT_UNKNOWN = -1004; public static final int TRANSPORT_QUOTA_EXCEEDED = -1005; /** * Indicates that the transport cannot accept a diff backup for this package. * * <p>Backup manager should clear its state for this package and immediately retry a * non-incremental backup. This might be used if the transport no longer has data for this * package in its backing store. * * <p>This is only valid when backup manager called {@link * #performBackup(PackageInfo, ParcelFileDescriptor, int)} with {@link #FLAG_INCREMENTAL}. * * @hide */ public static final int TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED = -1006; // Indicates that operation was initiated by user, not a scheduled one. // Transport should ignore its own moratoriums for call with this flag set. public static final int FLAG_USER_INITIATED = 1; Loading Loading @@ -252,6 +266,13 @@ public class BackupTransport { * set then {@link BackupTransport#FLAG_NON_INCREMENTAL} will be set. Before P neither flag will * be set regardless of whether the backup is incremental or not. * * <p>If {@link BackupTransport#FLAG_INCREMENTAL} is set and the transport does not have data * for this package in its storage backend then it cannot apply the incremental diff. Thus it * should return {@link BackupTransport#TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED} to indicate * that backup manager should delete its state and retry the package as a non-incremental * backup. Before P, or if this is a non-incremental backup, then this return code is equivalent * to {@link BackupTransport#TRANSPORT_ERROR}. * * @param packageInfo The identity of the application whose data is being backed up. * This specifically includes the signature list for the package. * @param inFd Descriptor of file with data that resulted from invoking the application's Loading @@ -262,9 +283,11 @@ public class BackupTransport { * @return one of {@link BackupTransport#TRANSPORT_OK} (OK so far), * {@link BackupTransport#TRANSPORT_PACKAGE_REJECTED} (to suppress backup of this * specific package, but allow others to proceed), * {@link BackupTransport#TRANSPORT_ERROR} (on network error or other failure), or * {@link BackupTransport#TRANSPORT_NOT_INITIALIZED} (if the backend dataset has * become lost due to inactivity purge or some other reason and needs re-initializing) * {@link BackupTransport#TRANSPORT_ERROR} (on network error or other failure), {@link * BackupTransport#TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED} (if the transport cannot accept * an incremental backup for this package), or {@link * BackupTransport#TRANSPORT_NOT_INITIALIZED} (if the backend dataset has become lost due to * inactivity purge or some other reason and needs re-initializing) */ public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd, int flags) { return performBackup(packageInfo, inFd); Loading services/backup/java/com/android/server/backup/internal/PerformBackupTask.java +51 −1 Original line number Diff line number Diff line Loading @@ -930,6 +930,7 @@ public class PerformBackupTask implements BackupRestoreTask { TransportUtils.checkTransportNotNull(transport); size = mBackupDataName.length(); if (size > 0) { boolean isNonIncremental = mSavedStateName.length() == 0; if (mStatus == BackupTransport.TRANSPORT_OK) { backupData = ParcelFileDescriptor.open(mBackupDataName, ParcelFileDescriptor.MODE_READ_ONLY); Loading @@ -938,7 +939,7 @@ public class PerformBackupTask implements BackupRestoreTask { int userInitiatedFlag = mUserInitiated ? BackupTransport.FLAG_USER_INITIATED : 0; int incrementalFlag = mSavedStateName.length() == 0 isNonIncremental ? BackupTransport.FLAG_NON_INCREMENTAL : BackupTransport.FLAG_INCREMENTAL; int flags = userInitiatedFlag | incrementalFlag; Loading @@ -946,6 +947,19 @@ public class PerformBackupTask implements BackupRestoreTask { mStatus = transport.performBackup(mCurrentPackage, backupData, flags); } if (isNonIncremental && mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) { // TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED is only valid if the backup was // incremental, as if the backup is non-incremental there is no state to // clear. This avoids us ending up in a retry loop if the transport always // returns this code. Slog.w(TAG, "Transport requested non-incremental but already the case, error"); backupManagerService.addBackupTrace( "Transport requested non-incremental but already the case, error"); mStatus = BackupTransport.TRANSPORT_ERROR; } // TODO - We call finishBackup() for each application backed up, because // we need to know now whether it succeeded or failed. Instead, we should // hold off on finishBackup() until the end, which implies holding off on Loading Loading @@ -993,6 +1007,31 @@ public class PerformBackupTask implements BackupRestoreTask { BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName, BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED); EventLog.writeEvent(EventLogTags.BACKUP_QUOTA_EXCEEDED, pkgName); } else if (mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) { Slog.i(TAG, "Transport lost data, retrying package"); backupManagerService.addBackupTrace( "Transport lost data, retrying package:" + pkgName); BackupManagerMonitorUtils.monitorEvent( mMonitor, BackupManagerMonitor .LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED, mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, /*extras=*/ null); mBackupDataName.delete(); mSavedStateName.delete(); mNewStateName.delete(); // Immediately retry the package by adding it back to the front of the queue. // We cannot add @pm@ to the queue because we back it up separately at the start // of the backup pass in state BACKUP_PM. Instead we retry this state (see // below). if (!PACKAGE_MANAGER_SENTINEL.equals(pkgName)) { mQueue.add(0, new BackupRequest(pkgName)); } } else { // Actual transport-level failure to communicate the data to the backend BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName, Loading @@ -1018,6 +1057,17 @@ public class PerformBackupTask implements BackupRestoreTask { // Success or single-package rejection. Proceed with the next app if any, // otherwise we're done. nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE; } else if (mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) { // We want to immediately retry the current package. if (PACKAGE_MANAGER_SENTINEL.equals(pkgName)) { nextState = BackupState.BACKUP_PM; } else { // This is an ordinary package so we will have added it back into the queue // above. Thus, we proceed processing the queue. nextState = BackupState.RUNNING_QUEUE; } } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) { if (MORE_DEBUG) { Slog.d(TAG, "Package " + mCurrentPackage.packageName + Loading Loading
core/java/android/app/backup/BackupManagerMonitor.java +6 −0 Original line number Diff line number Diff line Loading @@ -172,6 +172,12 @@ public class BackupManagerMonitor { public static final int LOG_EVENT_ID_NO_PACKAGES = 49; public static final int LOG_EVENT_ID_TRANSPORT_IS_NULL = 50; /** * The transport returned {@link BackupTransport#TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED}. * @hide */ public static final int LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED = 51; Loading
core/java/android/app/backup/BackupTransport.java +26 −3 Original line number Diff line number Diff line Loading @@ -51,6 +51,20 @@ public class BackupTransport { public static final int AGENT_UNKNOWN = -1004; public static final int TRANSPORT_QUOTA_EXCEEDED = -1005; /** * Indicates that the transport cannot accept a diff backup for this package. * * <p>Backup manager should clear its state for this package and immediately retry a * non-incremental backup. This might be used if the transport no longer has data for this * package in its backing store. * * <p>This is only valid when backup manager called {@link * #performBackup(PackageInfo, ParcelFileDescriptor, int)} with {@link #FLAG_INCREMENTAL}. * * @hide */ public static final int TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED = -1006; // Indicates that operation was initiated by user, not a scheduled one. // Transport should ignore its own moratoriums for call with this flag set. public static final int FLAG_USER_INITIATED = 1; Loading Loading @@ -252,6 +266,13 @@ public class BackupTransport { * set then {@link BackupTransport#FLAG_NON_INCREMENTAL} will be set. Before P neither flag will * be set regardless of whether the backup is incremental or not. * * <p>If {@link BackupTransport#FLAG_INCREMENTAL} is set and the transport does not have data * for this package in its storage backend then it cannot apply the incremental diff. Thus it * should return {@link BackupTransport#TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED} to indicate * that backup manager should delete its state and retry the package as a non-incremental * backup. Before P, or if this is a non-incremental backup, then this return code is equivalent * to {@link BackupTransport#TRANSPORT_ERROR}. * * @param packageInfo The identity of the application whose data is being backed up. * This specifically includes the signature list for the package. * @param inFd Descriptor of file with data that resulted from invoking the application's Loading @@ -262,9 +283,11 @@ public class BackupTransport { * @return one of {@link BackupTransport#TRANSPORT_OK} (OK so far), * {@link BackupTransport#TRANSPORT_PACKAGE_REJECTED} (to suppress backup of this * specific package, but allow others to proceed), * {@link BackupTransport#TRANSPORT_ERROR} (on network error or other failure), or * {@link BackupTransport#TRANSPORT_NOT_INITIALIZED} (if the backend dataset has * become lost due to inactivity purge or some other reason and needs re-initializing) * {@link BackupTransport#TRANSPORT_ERROR} (on network error or other failure), {@link * BackupTransport#TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED} (if the transport cannot accept * an incremental backup for this package), or {@link * BackupTransport#TRANSPORT_NOT_INITIALIZED} (if the backend dataset has become lost due to * inactivity purge or some other reason and needs re-initializing) */ public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd, int flags) { return performBackup(packageInfo, inFd); Loading
services/backup/java/com/android/server/backup/internal/PerformBackupTask.java +51 −1 Original line number Diff line number Diff line Loading @@ -930,6 +930,7 @@ public class PerformBackupTask implements BackupRestoreTask { TransportUtils.checkTransportNotNull(transport); size = mBackupDataName.length(); if (size > 0) { boolean isNonIncremental = mSavedStateName.length() == 0; if (mStatus == BackupTransport.TRANSPORT_OK) { backupData = ParcelFileDescriptor.open(mBackupDataName, ParcelFileDescriptor.MODE_READ_ONLY); Loading @@ -938,7 +939,7 @@ public class PerformBackupTask implements BackupRestoreTask { int userInitiatedFlag = mUserInitiated ? BackupTransport.FLAG_USER_INITIATED : 0; int incrementalFlag = mSavedStateName.length() == 0 isNonIncremental ? BackupTransport.FLAG_NON_INCREMENTAL : BackupTransport.FLAG_INCREMENTAL; int flags = userInitiatedFlag | incrementalFlag; Loading @@ -946,6 +947,19 @@ public class PerformBackupTask implements BackupRestoreTask { mStatus = transport.performBackup(mCurrentPackage, backupData, flags); } if (isNonIncremental && mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) { // TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED is only valid if the backup was // incremental, as if the backup is non-incremental there is no state to // clear. This avoids us ending up in a retry loop if the transport always // returns this code. Slog.w(TAG, "Transport requested non-incremental but already the case, error"); backupManagerService.addBackupTrace( "Transport requested non-incremental but already the case, error"); mStatus = BackupTransport.TRANSPORT_ERROR; } // TODO - We call finishBackup() for each application backed up, because // we need to know now whether it succeeded or failed. Instead, we should // hold off on finishBackup() until the end, which implies holding off on Loading Loading @@ -993,6 +1007,31 @@ public class PerformBackupTask implements BackupRestoreTask { BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName, BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED); EventLog.writeEvent(EventLogTags.BACKUP_QUOTA_EXCEEDED, pkgName); } else if (mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) { Slog.i(TAG, "Transport lost data, retrying package"); backupManagerService.addBackupTrace( "Transport lost data, retrying package:" + pkgName); BackupManagerMonitorUtils.monitorEvent( mMonitor, BackupManagerMonitor .LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED, mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, /*extras=*/ null); mBackupDataName.delete(); mSavedStateName.delete(); mNewStateName.delete(); // Immediately retry the package by adding it back to the front of the queue. // We cannot add @pm@ to the queue because we back it up separately at the start // of the backup pass in state BACKUP_PM. Instead we retry this state (see // below). if (!PACKAGE_MANAGER_SENTINEL.equals(pkgName)) { mQueue.add(0, new BackupRequest(pkgName)); } } else { // Actual transport-level failure to communicate the data to the backend BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName, Loading @@ -1018,6 +1057,17 @@ public class PerformBackupTask implements BackupRestoreTask { // Success or single-package rejection. Proceed with the next app if any, // otherwise we're done. nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE; } else if (mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) { // We want to immediately retry the current package. if (PACKAGE_MANAGER_SENTINEL.equals(pkgName)) { nextState = BackupState.BACKUP_PM; } else { // This is an ordinary package so we will have added it back into the queue // above. Thus, we proceed processing the queue. nextState = BackupState.RUNNING_QUEUE; } } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) { if (MORE_DEBUG) { Slog.d(TAG, "Package " + mCurrentPackage.packageName + Loading